]> arthur.barton.de Git - netatalk.git/commitdiff
full AFP spec for directories/files modification date.
authordidg <didg>
Thu, 22 Aug 2002 13:41:19 +0000 (13:41 +0000)
committerdidg <didg>
Thu, 22 Aug 2002 13:41:19 +0000 (13:41 +0000)
etc/afpd/directory.c
etc/afpd/file.c

index c27aef88151d8a678110a485f09cfd9f1520ac0c..0ef58ce026856887e7c3a23ecd669289cfec2f2e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.36 2002-08-16 00:42:56 didg Exp $
+ * $Id: directory.c,v 1.37 2002-08-22 13:41:19 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -1223,16 +1223,26 @@ int             ibuflen, *rbuflen;
     return( rc );
 }
 
-int setdirparams(const struct vol *vol,
+/*
+ * cf AFP3.0.pdf page 244 for change_mdate and change_parent_mdate logic  
+ *
+ * assume path == '\0' eg. it's a directory in canonical form
+*/
+int setdirparams(const struct vol *vol, 
                  char *path, u_int16_t bitmap, char *buf )
 {
     struct maccess     ma;
     struct adouble     ad;
     struct utimbuf      ut;
+    struct timeval      tv;
+
     char                *upath;
     int                        bit = 0, aint, isad = 1;
     u_int16_t          ashort, bshort;
     int                 err = AFP_OK;
+    int                 change_mdate = 0;
+    int                 change_parent_mdate = 0;
+    int                 newdate = 0;
 #ifdef FORCE_UIDGID
     uidgidset          *uidgid;
 
@@ -1244,6 +1254,7 @@ int setdirparams(const struct vol *vol,
 #ifdef FORCE_UIDGID
     save_uidgid ( &uidgid );
 #endif /* FORCE_UIDGID */
+
     if (ad_open( upath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
                  O_RDWR|O_CREAT, 0666, &ad) < 0) {
         /*
@@ -1284,6 +1295,7 @@ int setdirparams(const struct vol *vol,
 
         switch( bit ) {
         case DIRPBIT_ATTR :
+            change_mdate = 1;
             if (isad) {
                 memcpy( &ashort, buf, sizeof( ashort ));
                 ad_getattr(&ad, &bshort);
@@ -1293,11 +1305,14 @@ int setdirparams(const struct vol *vol,
                     bshort &= ~ashort;
                 }
                 ad_setattr(&ad, bshort);
+                if ((ashort & htons(ATTRBIT_INVISIBLE)))
+                  change_parent_mdate = 1;
             }
             buf += sizeof( ashort );
             break;
 
         case DIRPBIT_CDATE :
+            change_mdate = 1;
             if (isad) {
                 memcpy(&aint, buf, sizeof(aint));
                 ad_setdate(&ad, AD_DATE_CREATE, aint);
@@ -1306,15 +1321,12 @@ int setdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_MDATE :
-            memcpy(&aint, buf, sizeof(aint));
-            if (isad)
-                ad_setdate(&ad, AD_DATE_MODIFY, aint);
-            ut.actime = ut.modtime = AD_DATE_TO_UNIX(aint);
-            utime(upath, &ut);
-            buf += sizeof( aint );
+            memcpy(&newdate, buf, sizeof(newdate));
+            buf += sizeof( newdate );
             break;
 
         case DIRPBIT_BDATE :
+            change_mdate = 1;
             if (isad) {
                 memcpy(&aint, buf, sizeof(aint));
                 ad_setdate(&ad, AD_DATE_BACKUP, aint);
@@ -1323,6 +1335,7 @@ int setdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_FINFO :
+            change_mdate = 1;
             /*
              * Alright, we admit it, this is *really* sick!
              * The 4 bytes that we don't copy, when we're dealing
@@ -1343,6 +1356,7 @@ int setdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_UID :     /* What kind of loser mounts as root? */
+            change_parent_mdate = 1;
             memcpy( &aint, buf, sizeof(aint));
             buf += sizeof( aint );
             if ( (curdir->d_did == DIRDID_ROOT) &&
@@ -1386,6 +1400,7 @@ int setdirparams(const struct vol *vol,
             }
             break;
         case DIRPBIT_GID :
+            change_parent_mdate = 1;
             memcpy( &aint, buf, sizeof( aint ));
             buf += sizeof( aint );
             if (curdir->d_did == DIRDID_ROOT)
@@ -1432,6 +1447,8 @@ int setdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_ACCESS :
+            change_mdate = 1;
+            change_parent_mdate = 1;
             ma.ma_user = *buf++;
             ma.ma_world = *buf++;
             ma.ma_group = *buf++;
@@ -1494,6 +1511,16 @@ int setdirparams(const struct vol *vol,
     }
 
 setdirparam_done:
+    if (change_mdate && newdate == 0 && gettimeofday(&tv, NULL) == 0) {
+       newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
+    }
+    if (newdate) {
+       if (isad)
+          ad_setdate(&ad, AD_DATE_MODIFY, newdate);
+       ut.actime = ut.modtime = AD_DATE_TO_UNIX(newdate);
+       utime(upath, &ut);
+    }
+
     if ( isad ) {
         ad_flush( &ad, ADFLAGS_HF );
         ad_close( &ad, ADFLAGS_HF );
@@ -1502,6 +1529,17 @@ setdirparam_done:
 #ifdef FORCE_UIDGID
     restore_uidgid ( &uidgid );
 #endif /* FORCE_UIDGID */
+
+    if (change_parent_mdate && curdir->d_did != DIRDID_ROOT
+            && gettimeofday(&tv, NULL) == 0) {
+       if (!movecwd(vol, curdir->d_parent)) {
+           newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
+           bitmap = 1<<DIRPBIT_MDATE;
+           setdirparams(vol, "", bitmap, (char *)&newdate);
+           /* should we reset curdir ?*/
+       }
+    }
+
     return err;
 }
 
index 0853939ce0cf4c53ab759fd251b1e9d7eeb54fd9..35bfc7eaed59d188ef3b45a57c79fa4cf91a8769 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.49 2002-08-21 07:52:04 didg Exp $
+ * $Id: file.c,v 1.50 2002-08-22 13:41:20 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -153,13 +153,7 @@ int getmetadata(struct vol *vol,
         case FILPBIT_MDATE :
             if ( adp && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) {
                 if ((st->st_mtime > AD_DATE_TO_UNIX(aint))) {
-                        if ( fstat( ad_hfileno( adp ), &hst ) < 0 ) {
-                            LOG(log_error, logtype_default, "getfilparams fstat: %s", strerror(errno) );
-                        }
-                        else if (hst.st_mtime < st->st_mtime) 
-                            aint = AD_DATE_FROM_UNIX(st->st_mtime);
-                        else 
-                            aint = AD_DATE_FROM_UNIX(hst.st_mtime);
+                   aint = AD_DATE_FROM_UNIX(st->st_mtime);
                 }
             } else {
                 aint = AD_DATE_FROM_UNIX(st->st_mtime);
@@ -615,6 +609,10 @@ int                ibuflen, *rbuflen;
     return( rc );
 }
 
+/*
+ * cf AFP3.0.pdf page 252 for change_mdate and change_parent_mdate logic  
+ *
+*/
 
 int setfilparams(struct vol *vol,
                  char *path, u_int16_t bitmap, char *buf )
@@ -629,6 +627,11 @@ int setfilparams(struct vol *vol,
     u_int32_t          aint;
     struct utimbuf     ut;
 
+    int                 change_mdate = 0;
+    int                 change_parent_mdate = 0;
+    int                 newdate = 0;
+    struct timeval      tv;
+
 #ifdef FORCE_UIDGID
     uidgidset          *uidgid;
 
@@ -676,6 +679,7 @@ int setfilparams(struct vol *vol,
 
         switch(  bit ) {
         case FILPBIT_ATTR :
+            change_mdate = 1;
             memcpy(&ashort, buf, sizeof( ashort ));
             ad_getattr(adp, &bshort);
             if ( ntohs( ashort ) & ATTRBIT_SETCLR ) {
@@ -683,32 +687,34 @@ int setfilparams(struct vol *vol,
             } else {
                 bshort &= ~ashort;
             }
+            if ((ashort & htons(ATTRBIT_INVISIBLE)))
+                change_parent_mdate = 1;
             ad_setattr(adp, bshort);
             buf += sizeof( ashort );
             break;
 
         case FILPBIT_CDATE :
+            change_mdate = 1;
             memcpy(&aint, buf, sizeof(aint));
             ad_setdate(adp, AD_DATE_CREATE, aint);
             buf += sizeof( aint );
             break;
 
         case FILPBIT_MDATE :
-            memcpy(&aint, buf, sizeof( aint ));
-            if (isad)
-                ad_setdate(adp, AD_DATE_MODIFY, aint);
-            ut.actime = ut.modtime = AD_DATE_TO_UNIX(aint);
-            utime(upath, &ut);
-            buf += sizeof( aint );
+            memcpy(&newdate, buf, sizeof( newdate ));
+            buf += sizeof( newdate );
             break;
 
         case FILPBIT_BDATE :
+            change_mdate = 1;
             memcpy(&aint, buf, sizeof(aint));
             ad_setdate(adp, AD_DATE_BACKUP, aint);
             buf += sizeof( aint );
             break;
 
         case FILPBIT_FINFO :
+            change_mdate = 1;
+
             if (!memcmp( ad_entry( adp, ADEID_FINDERI ), ufinderi, 8 )
                     && ( 
                      ((em = getextmap( path )) &&
@@ -778,6 +784,16 @@ int setfilparams(struct vol *vol,
     }
 
 setfilparam_done:
+    if (change_mdate && newdate == 0 && gettimeofday(&tv, NULL) == 0) {
+       newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
+    }
+    if (newdate) {
+       if (isad)
+          ad_setdate(adp, AD_DATE_MODIFY, newdate);
+       ut.actime = ut.modtime = AD_DATE_TO_UNIX(newdate);
+       utime(upath, &ut);
+    }
+
     if (isad) {
         ad_flush( adp, ADFLAGS_HF );
         ad_close( adp, ADFLAGS_HF );
@@ -788,10 +804,15 @@ setfilparam_done:
 
     }
 
+    if (change_parent_mdate && gettimeofday(&tv, NULL) == 0) {
+        newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
+        bitmap = 1<<FILPBIT_MDATE;
+        setdirparams(vol, "", bitmap, (char *)&newdate);
+    }
+
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "end setfilparams:");
 #endif /* DEBUG */
-
     return err;
 }
 
@@ -799,7 +820,7 @@ setfilparam_done:
  * renamefile and copyfile take the old and new unix pathnames
  * and the new mac name.
  * NOTE: if we have to copy a file instead of renaming it, locks
- *       will break.
+ *       will break. Anyway it's an error because then we have 2 files.
  * FIXME: locks on ressource fork will always break thanks to ad_close, done ?
  *
  * src         the full source absolute path 
@@ -839,6 +860,7 @@ struct adouble    *adp;
         case EROFS:
             return AFPERR_VLOCK;
         case EXDEV :                   /* Cross device move -- try copy */
+            /* if source is open bail out */
             if (( rc = copyfile(src, dst, newname, noadouble )) != AFP_OK ) {
                 deletefile( dst, 0 );
                 return( rc );