From 83d6d78f80feac85b881fc9aea34244571fa4d39 Mon Sep 17 00:00:00 2001 From: franklahm Date: Fri, 11 Sep 2009 09:14:16 +0000 Subject: [PATCH] Time Machine support. Merge from branch-2-0 --- config/AppleVolumes.default.tmpl | 1 + etc/afpd/directory.c | 98 ++++++++++++++++++-------------- etc/afpd/directory.h | 4 +- etc/afpd/fork.c | 3 +- etc/afpd/fork.h | 4 +- etc/afpd/switch.c | 4 +- etc/afpd/volume.c | 11 +++- etc/afpd/volume.h | 5 +- include/atalk/afp.h | 4 +- include/atalk/volinfo.h | 3 +- libatalk/util/volinfo.c | 1 + 11 files changed, 80 insertions(+), 58 deletions(-) diff --git a/config/AppleVolumes.default.tmpl b/config/AppleVolumes.default.tmpl index 74a5c350..99c1560f 100644 --- a/config/AppleVolumes.default.tmpl +++ b/config/AppleVolumes.default.tmpl @@ -72,6 +72,7 @@ # requested perm # # miscellaneous options [syntax: options:option1,option2]: +# tm -> enable TimeMachine support # prodos -> make compatible with appleII clients. # crlf -> enable crlf translation for TEXT files. # noadouble -> don't create .AppleDouble unless a resource diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index b3a36367..f59cf693 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $Id: directory.c,v 1.102 2009-09-01 13:55:55 franklahm Exp $ + * $Id: directory.c,v 1.103 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -2302,7 +2302,6 @@ setdirparam_done: return err; } - int afp_syncdir(obj, ibuf, ibuflen, rbuf, rbuflen ) AFPObj *obj _U_; char *ibuf, *rbuf _U_; @@ -2328,58 +2327,71 @@ int ibuflen _U_, *rbuflen; memcpy( &did, ibuf, sizeof( did )); ibuf += sizeof( did ); - if (NULL == ( dir = dirlookup( vol, did )) ) { - return afp_errno; /* was AFPERR_NOOBJ */ - } - if (movecwd( vol, dir ) < 0 ) - return ( AFPERR_NOOBJ ); + /* + * Here's the deal: + * if it's CNID 2 our only choice to meet the specs is call sync. + * For any other CNID just sync that dir. To my knowledge the + * intended use of FPSyncDir is to sync the volume so all we're + * ever going to see here is probably CNID 2. Anyway, we' prepared. + */ -/* - Assuming only OSens that have dirfd also may require fsyncing directories - in order to flush metadata e.g. Linux. -*/ + if ( ntohl(did) == 2 ) { + sync(); + } else { + if (NULL == ( dir = dirlookup( vol, did )) ) { + return afp_errno; /* was AFPERR_NOOBJ */ + } + + if (movecwd( vol, dir ) < 0 ) + return ( AFPERR_NOOBJ ); + + /* + * Assuming only OSens that have dirfd also may require fsyncing directories + * in order to flush metadata e.g. Linux. + */ #ifdef HAVE_DIRFD - if (NULL == ( dp = opendir( "." )) ) { - switch( errno ) { - case ENOENT : - return( AFPERR_NOOBJ ); - case EACCES : + if (NULL == ( dp = opendir( "." )) ) { + switch( errno ) { + case ENOENT : + return( AFPERR_NOOBJ ); + case EACCES : return( AFPERR_ACCESS ); - default : - return( AFPERR_PARAM ); + default : + return( AFPERR_PARAM ); + } } - } - - LOG(log_debug, logtype_afpd, "afp_syncdir: dir: '%s'", dir->d_u_name); - - dfd = dirfd( dp ); - if ( fsync ( dfd ) < 0 ) - LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s", - dir->d_u_name, strerror(errno) ); - closedir(dp); /* closes dfd too */ + + LOG(log_debug, logtype_afpd, "afp_syncdir: dir: '%s'", dir->d_u_name); + + dfd = dirfd( dp ); + if ( fsync ( dfd ) < 0 ) + LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s", + dir->d_u_name, strerror(errno) ); + closedir(dp); /* closes dfd too */ #endif - - if ( -1 == (dfd = open(vol->vfs->ad_path(".", ADFLAGS_DIR), O_RDWR))) { - switch( errno ) { - case ENOENT: - return( AFPERR_NOOBJ ); + + if ( -1 == (dfd = open(vol->ad_path(".", ADFLAGS_DIR), O_RDWR))) { + switch( errno ) { + case ENOENT: + return( AFPERR_NOOBJ ); case EACCES: return( AFPERR_ACCESS ); - default: - return( AFPERR_PARAM ); - } + default: + return( AFPERR_PARAM ); + } + } + + LOG(log_debug, logtype_afpd, "afp_syncdir: ad-file: '%s'", + vol->ad_path(".", ADFLAGS_DIR) ); + + if ( fsync(dfd) < 0 ) + LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s", + vol->ad_path(dir->d_u_name, ADFLAGS_DIR), strerror(errno) ); + close(dfd); } - LOG(log_debug, logtype_afpd, "afp_syncdir: ad-file: '%s'", - vol->vfs->ad_path(".", ADFLAGS_DIR) ); - - if ( fsync(dfd) < 0 ) - LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s", - vol->vfs->ad_path(dir->d_u_name, ADFLAGS_DIR), strerror(errno) ); - close(dfd); - return ( AFP_OK ); } diff --git a/etc/afpd/directory.h b/etc/afpd/directory.h index aae48aec..1c7ef5e4 100644 --- a/etc/afpd/directory.h +++ b/etc/afpd/directory.h @@ -1,5 +1,5 @@ /* - * $Id: directory.h,v 1.25 2009-06-19 13:38:33 franklahm Exp $ + * $Id: directory.h,v 1.26 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -214,7 +214,7 @@ extern int afp_setdirparams __P((AFPObj *, char *, int, char *, int *)); extern int afp_closedir __P((AFPObj *, char *, int, char *, int *)); extern int afp_mapid __P((AFPObj *, char *, int, char *, int *)); extern int afp_mapname __P((AFPObj *, char *, int, char *, int *)); -extern int afp_syncdir __P((AFPObj *, char *, int, char *, int *)); +extern int afp_syncdir __P((AFPObj *, char *, int, char *, int *)); /* from enumerate.c */ extern int afp_enumerate __P((AFPObj *, char *, unsigned int, char *, unsigned int *)); diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 777f9a60..0374601a 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,5 +1,5 @@ /* - * $Id: fork.c,v 1.61 2009-07-21 13:41:16 didg Exp $ + * $Id: fork.c,v 1.62 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -1131,7 +1131,6 @@ int afp_syncfork(obj, ibuf, ibuflen, rbuf, rbuflen ) return( AFP_OK ); } - /* this is very similar to closefork */ int flushfork( ofork ) struct ofork *ofork; diff --git a/etc/afpd/fork.h b/etc/afpd/fork.h index a63073d6..3804f742 100644 --- a/etc/afpd/fork.h +++ b/etc/afpd/fork.h @@ -1,5 +1,5 @@ /* - * $Id: fork.h,v 1.12 2009-02-25 16:14:08 franklahm Exp $ + * $Id: fork.h,v 1.13 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -89,5 +89,5 @@ extern int afp_closefork __P((AFPObj *, char *, int, char *, int *)); extern int afp_bytelock_ext __P((AFPObj *, char *, int, char *, int *)); extern int afp_read_ext __P((AFPObj *, char *, int, char *, int *)); extern int afp_write_ext __P((AFPObj *, char *, int, char *, int *)); -extern int afp_syncfork __P((AFPObj *, char *, int, char *, int *)); +extern int afp_syncfork __P((AFPObj *, char *, int, char *, int *)); #endif diff --git a/etc/afpd/switch.c b/etc/afpd/switch.c index 09f97d03..9e286c72 100644 --- a/etc/afpd/switch.c +++ b/etc/afpd/switch.c @@ -1,5 +1,5 @@ /* - * $Id: switch.c,v 1.16 2009-02-25 16:14:08 franklahm Exp $ + * $Id: switch.c,v 1.17 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -155,7 +155,7 @@ int (*postauth_switch[])() = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 64 - 71 */ NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, /* 72 - 79 */ + NULL, NULL, afp_syncdir, afp_syncfork, /* 72 - 79 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 80 - 87 */ NULL, NULL, NULL, NULL, diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 04f53f75..979a2e29 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $Id: volume.c,v 1.89 2009-09-04 07:59:50 franklahm Exp $ + * $Id: volume.c,v 1.90 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -183,6 +183,7 @@ static const _vol_opt_name vol_opt_names[] = { {AFPVOL_CACHE, "CACHEID"}, /* Use adouble v2 CNID caching. Default: yes */ {AFPVOL_EXT_ATTRS, "EXT_ATTRS"}, /* Vol supports Extened Attributes */ {AFPVOL_ACLS, "ACLS"}, /* Vol supports ACLs */ + {AFPVOL_TM, "TM"}, /* Set "kSupportsTMLockSteal" is volume attributes */ {0, NULL} }; @@ -502,6 +503,8 @@ static void volset(struct vol_option *options, struct vol_option *save, options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ; else if (strcasecmp(p, "nocnidcache") == 0) options[VOLOPT_FLAGS].i_value &= ~AFPVOL_CACHE; + else if (strcasecmp(p, "tm") == 0) + options[VOLOPT_FLAGS].i_value |= AFPVOL_TM; p = strtok(NULL, ","); } @@ -1462,8 +1465,10 @@ int *buflen; ashort |= VOLPBIT_ATTR_CATSEARCH; if (afp_version >= 30) { ashort |= VOLPBIT_ATTR_UTF8; - if (vol->v_flags & AFPVOL_UNIX_PRIV) - ashort |= VOLPBIT_ATTR_UNIXPRIV; + if (vol->v_flags & AFPVOL_UNIX_PRIV) + ashort |= VOLPBIT_ATTR_UNIXPRIV; + if (vol->v_flags & AFPVOL_TM) + ashort |= VOLPBIT_ATTR_TM; } if (afp_version >= 32) { if (vol->v_flags & AFPVOL_EXT_ATTRS) diff --git a/etc/afpd/volume.h b/etc/afpd/volume.h index 03a66c3e..b579362b 100644 --- a/etc/afpd/volume.h +++ b/etc/afpd/volume.h @@ -1,5 +1,5 @@ /* - * $Id: volume.h,v 1.32 2009-09-11 07:46:30 franklahm Exp $ + * $Id: volume.h,v 1.33 2009-09-11 09:14:16 franklahm Exp $ * * Copyright (c) 1990,1994 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -138,6 +138,7 @@ this is going away. */ #define AFPVOL_CACHE (1 << 21) /* Use adouble v2 CNID caching. Default: yes */ #define AFPVOL_INV_DOTS (1 << 22) /* dots files are invisible */ #define AFPVOL_EXT_ATTRS (1 << 23) /* Volume supports Extended Attributes */ +#define AFPVOL_TM (1 << 24) /* Supports TimeMachine */ #define AFPVOL_ACLS (1 << 25) /* Volume supports ACLS */ /* FPGetSrvrParms options */ @@ -174,6 +175,8 @@ int wincheck(const struct vol *vol, const char *path); #define VOLPBIT_ATTR_NONETUID (1 << 7) #define VOLPBIT_ATTR_EXT_ATTRS (1 << 10) #define VOLPBIT_ATTR_ACLS (1 << 11) +#define VOLPBIT_ATTR_TM (1 << 13) + #define VOLPBIT_ATTR 0 #define VOLPBIT_SIG 1 #define VOLPBIT_CDATE 2 diff --git a/include/atalk/afp.h b/include/atalk/afp.h index 6dfa93ef..fff1f41a 100644 --- a/include/atalk/afp.h +++ b/include/atalk/afp.h @@ -199,6 +199,8 @@ typedef enum { /* version 3.1 */ #define AFP_ENUMERATE_EXT2 68 +#define AFP_SYNCDIR 78 +#define AFP_SYNCFORK 79 #define AFP_ZZZ 122 /* version 3.2 */ @@ -210,7 +212,5 @@ typedef enum { #define AFP_SETACL 74 #define AFP_ACCESS 75 #define AFP_SPOTLIGHT_PRIVATE 76 -#define AFP_SYNCDIR 78 -#define AFP_SYNCFORK 79 #endif diff --git a/include/atalk/volinfo.h b/include/atalk/volinfo.h index fcf3a48d..73bc29f5 100644 --- a/include/atalk/volinfo.h +++ b/include/atalk/volinfo.h @@ -1,5 +1,5 @@ /* - * $Id: volinfo.h,v 1.6 2009-09-01 14:28:07 franklahm Exp $ + * $Id: volinfo.h,v 1.7 2009-09-11 09:14:16 franklahm Exp $ */ #ifndef _ATALK_VOLINFO_H @@ -33,6 +33,7 @@ #define AFPVOL_CACHE (1 << 21) /* Use adouble v2 CNID caching, default don't use it */ #define AFPVOL_INV_DOTS (1 << 22) /* dots files are invisible */ #define AFPVOL_EXT_ATTRS (1 << 23) /* Volume supports Extended Attributes */ +#define AFPVOL_TM (1 << 24) /* Supports TimeMachine */ #define AFPVOL_ACLS (1 << 25) /* Volume supports ACLS */ /* handle casefolding */ diff --git a/libatalk/util/volinfo.c b/libatalk/util/volinfo.c index 8ba6b00a..dbb44e10 100644 --- a/libatalk/util/volinfo.c +++ b/libatalk/util/volinfo.c @@ -98,6 +98,7 @@ static const _vol_opt_name vol_opt_names[] = { {AFPVOL_INV_DOTS, "INVISIBLEDOTS"}, {AFPVOL_EXT_ATTRS, "EXT_ATTRS"}, /* Vol supports Extened Attributes */ {AFPVOL_ACLS, "ACLS"}, /* Vol supports ACLs */ + {AFPVOL_TM, "TM"}, /* Set "kSupportsTMLockSteal" is volume attributes */ {0, NULL} }; -- 2.39.2