/*
- * $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.
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;
#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) {
/*
switch( bit ) {
case DIRPBIT_ATTR :
+ change_mdate = 1;
if (isad) {
memcpy( &ashort, buf, sizeof( ashort ));
ad_getattr(&ad, &bshort);
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);
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);
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
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) &&
}
break;
case DIRPBIT_GID :
+ change_parent_mdate = 1;
memcpy( &aint, buf, sizeof( aint ));
buf += sizeof( aint );
if (curdir->d_did == DIRDID_ROOT)
break;
case DIRPBIT_ACCESS :
+ change_mdate = 1;
+ change_parent_mdate = 1;
ma.ma_user = *buf++;
ma.ma_world = *buf++;
ma.ma_group = *buf++;
}
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 );
#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;
}
/*
- * $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.
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);
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 )
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;
switch( bit ) {
case FILPBIT_ATTR :
+ change_mdate = 1;
memcpy(&ashort, buf, sizeof( ashort ));
ad_getattr(adp, &bshort);
if ( ntohs( ashort ) & ATTRBIT_SETCLR ) {
} 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 )) &&
}
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 );
}
+ 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;
}
* 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
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 );