X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=b12c723f70e8789484784b2ad1653dc9f695e326;hb=b379fad7481bf63c88619334a45e88611a4d08fa;hp=de4ee8a15c35b4edfb8f62035f083b1cca9d9633;hpb=a7349ad51dd4d6e119ab7414fd19d6a8467f3f35;p=netatalk.git diff --git a/etc/afpd/file.c b/etc/afpd/file.c index de4ee8a1..b12c723f 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.30 2001-12-03 05:03:38 jmarcus Exp $ + * $Id: file.c,v 1.56 2002-09-06 02:57:49 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -38,7 +38,7 @@ char *strchr (), *strrchr (); #include #include -#include +#include #include #include #include @@ -64,11 +64,6 @@ char *strchr (), *strrchr (); #include "parse_mtab.h" #endif /* DID_MTAB */ -#ifdef FORCE_UIDGID -#warning UIDGID -#include "uid.h" -#endif /* FORCE_UIDGID */ - /* the format for the finderinfo fields (from IM: Toolbox Essentials): * field bytes subfield bytes * @@ -89,48 +84,34 @@ char *strchr (), *strrchr (); */ const u_char ufinderi[] = { - 'T', 'E', 'X', 'T', 'U', 'N', 'I', 'X', - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; + 'T', 'E', 'X', 'T', 'U', 'N', 'I', 'X', + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; -int getfilparams(struct vol *vol, +int getmetadata(struct vol *vol, u_int16_t bitmap, char *path, struct dir *dir, struct stat *st, - char *buf, int *buflen ) + char *buf, int *buflen, struct adouble *adp, int attrbits ) { #ifndef USE_LASTDID - struct stat hst, lst, *lstp; -#else /* USE_LASTDID */ - struct stat hst; + struct stat lst, *lstp; #endif /* USE_LASTDID */ - struct adouble ad, *adp; - struct ofork *of; + struct stat hst; struct extmap *em; char *data, *nameoff = NULL, *upath; - int bit = 0, isad = 1; + int bit = 0; u_int32_t aint; u_int16_t ashort; u_char achar, fdType[4]; + struct maccess ma; #ifdef DEBUG - syslog(LOG_INFO, "begin getfilparams:"); + LOG(log_info, logtype_afpd, "begin getmetadata:"); #endif /* DEBUG */ upath = mtoupath(vol, path); - if ((of = of_findname(vol, curdir, path))) { - adp = of->of_ad; - } else { - memset(&ad, 0, sizeof(ad)); - adp = &ad; - } - - if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) { - isad = 0; - } else if ( fstat( ad_hfileno( adp ), &hst ) < 0 ) { - syslog( LOG_ERR, "getfilparams fstat: %s", strerror(errno) ); - } data = buf; while ( bitmap != 0 ) { @@ -141,14 +122,27 @@ int getfilparams(struct vol *vol, switch ( bit ) { case FILPBIT_ATTR : - if ( isad ) { + if ( adp ) { ad_getattr(adp, &ashort); } else if (*upath == '.') { ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; +#if 0 + /* FIXME do we want a visual clue if the file is read only + */ + accessmode( ".", &ma, dir , NULL); + if ((ma.ma_user & AR_UWRITE)) { + accessmode( upath, &ma, dir , st); + if (!(ma.ma_user & AR_UWRITE)) { + attrbits |= ATTRBIT_NOWRITE; + } + } +#endif + if (attrbits) + ashort = htons(ntohs(ashort) | attrbits); memcpy(data, &ashort, sizeof( ashort )); - data += sizeof( u_short ); + data += sizeof( ashort ); break; case FILPBIT_PDID : @@ -157,17 +151,16 @@ int getfilparams(struct vol *vol, break; case FILPBIT_CDATE : - if (!isad || (ad_getdate(adp, AD_DATE_CREATE, &aint) < 0)) + if (!adp || (ad_getdate(adp, AD_DATE_CREATE, &aint) < 0)) aint = AD_DATE_FROM_UNIX(st->st_mtime); memcpy(data, &aint, sizeof( aint )); data += sizeof( aint ); break; case FILPBIT_MDATE : - if ( isad && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) { - if ((st->st_mtime > AD_DATE_TO_UNIX(aint)) && - (hst.st_mtime < st->st_mtime)) { - aint = AD_DATE_FROM_UNIX(st->st_mtime); + if ( adp && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) { + if ((st->st_mtime > AD_DATE_TO_UNIX(aint))) { + aint = AD_DATE_FROM_UNIX(st->st_mtime); } } else { aint = AD_DATE_FROM_UNIX(st->st_mtime); @@ -177,14 +170,14 @@ int getfilparams(struct vol *vol, break; case FILPBIT_BDATE : - if (!isad || (ad_getdate(adp, AD_DATE_BACKUP, &aint) < 0)) + if (!adp || (ad_getdate(adp, AD_DATE_BACKUP, &aint) < 0)) aint = AD_DATE_START; memcpy(data, &aint, sizeof( int )); data += sizeof( int ); break; case FILPBIT_FINFO : - if (isad) + if (adp) memcpy(data, ad_entry(adp, ADEID_FINDERI), 32); else { memcpy(data, ufinderi, 32); @@ -194,9 +187,9 @@ int getfilparams(struct vol *vol, } } - if ((!isad || (memcmp(ad_entry(adp, ADEID_FINDERI), - ufinderi, 8 ) == 0)) && - (em = getextmap( path ))) { + if ((!adp || !memcmp(ad_entry(adp, ADEID_FINDERI),ufinderi , 8 )) + && (em = getextmap( path )) + ) { memcpy(data, em->em_type, sizeof( em->em_type )); memcpy(data + 4, em->em_creator, sizeof(em->em_creator)); } @@ -217,13 +210,26 @@ int getfilparams(struct vol *vol, aint = 0; #if AD_VERSION > AD_VERSION1 /* look in AD v2 header */ - if (isad) + if (adp) memcpy(&aint, ad_entry(adp, ADEID_DID), sizeof(aint)); #endif /* AD_VERSION > AD_VERSION1 */ #ifdef CNID_DB aint = cnid_add(vol->v_db, st, dir->d_did, upath, strlen(upath), aint); + /* Throw errors if cnid_add fails. */ + if (aint == CNID_INVALID) { + switch (errno) { + case CNID_ERR_PARAM: + LOG(log_error, logtype_afpd, "getfilparams: Incorrect parameters passed to cnid_add"); + return(AFPERR_PARAM); + case CNID_ERR_PATH: + return(AFPERR_PARAM); + case CNID_ERR_DB: + case CNID_ERR_MAX: + return(AFPERR_MISC); + } + } #endif /* CNID_DB */ if (aint == 0) { @@ -276,7 +282,7 @@ int getfilparams(struct vol *vol, break; case FILPBIT_RFLEN : - if ( isad ) { + if ( adp ) { aint = htonl( ad_getentrylen( adp, ADEID_RFORK )); } else { aint = 0; @@ -292,7 +298,7 @@ int getfilparams(struct vol *vol, to "pXYZ" when we created it. See IA, Ver 2. */ case FILPBIT_PDINFO : - if ( isad ) { + if ( adp ) { memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 ); if ( memcmp( fdType, "TEXT", 4 ) == 0 ) { @@ -334,9 +340,6 @@ int getfilparams(struct vol *vol, break; default : - if ( isad ) { - ad_close( adp, ADFLAGS_HF ); - } return( AFPERR_BITMAP ); } bitmap = bitmap>>1; @@ -351,18 +354,67 @@ int getfilparams(struct vol *vol, memcpy(data, path, aint ); data += aint; } - if ( isad ) { - ad_close( adp, ADFLAGS_HF ); - } *buflen = data - buf; + return (AFP_OK); +} + +/* ----------------------- */ +int getfilparams(struct vol *vol, + u_int16_t bitmap, + char *path, struct dir *dir, struct stat *st, + char *buf, int *buflen ) +{ + struct adouble ad, *adp; + struct ofork *of; + char *upath; + u_int16_t attrbits = 0; + int rc; +#ifdef DEBUG + LOG(log_info, logtype_default, "begin getfilparams:"); +#endif /* DEBUG */ + upath = mtoupath(vol, path); + if ((of = of_findname(upath, st))) { + adp = of->of_ad; + attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0); + attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0); + + } else { + memset(&ad, 0, sizeof(ad)); + adp = &ad; + } + + if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) { + adp = NULL; + } + else { +#if 0 + /* FIXME + we need to check if the file is open by another process. + it's slow so we only do it if we have to: + - bitmap is requested. + - we don't already have the answer! + */ + if ((bitmap & (1 << FILPBIT_ATTR))) { + if (!(attrbits & ATTRBIT_ROPEN)) { + } + if (!(attrbits & ATTRBIT_DOPEN)) { + } + } +#endif + } + rc = getmetadata(vol, bitmap, path, dir, st, buf, buflen, adp, attrbits); + if ( adp ) { + ad_close( adp, ADFLAGS_HF ); + } #ifdef DEBUG - syslog(LOG_INFO, "end getfilparams:"); + LOG(log_info, logtype_afpd, "end getfilparams:"); #endif /* DEBUG */ - return( AFP_OK ); + return( rc ); } +/* ----------------------------- */ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen ) AFPObj *obj; char *ibuf, *rbuf; @@ -376,12 +428,9 @@ int ibuflen, *rbuflen; char *path, *upath; int creatf, did, openf, retvalue = AFP_OK; u_int16_t vid; -#ifdef FORCE_UIDGID - uidgidset *uidgid; -#endif /* FORCE_UIDGID */ - + int ret; #ifdef DEBUG - syslog(LOG_INFO, "begin afp_createfile:"); + LOG(log_info, logtype_afpd, "begin afp_createfile:"); #endif /* DEBUG */ *rbuflen = 0; @@ -409,23 +458,13 @@ int ibuflen, *rbuflen; return( AFPERR_NOOBJ ); } - if ((vol->v_flags & AFPVOL_MSWINDOWS) && - strpbrk(path, MSWINDOWS_BADCHARS)) - return AFPERR_PARAM; - upath = mtoupath(vol, path); + if (0 != (ret = check_name(vol, upath))) + return ret; - if ((vol->v_flags & AFPVOL_NOHEX) && strchr(upath, '/')) - return AFPERR_PARAM; - - if (!validupath(vol, upath)) - return AFPERR_EXIST; - - /* check for vetoed filenames */ - if (veto_file(vol->v_veto, upath)) - return AFPERR_EXIST; - - if ((of = of_findname(vol, curdir, path))) { + ret = stat(upath, &st); + /* if upath is deleted we already in trouble anyway */ + if (!ret && (of = of_findname(upath, &st))) { adp = of->of_ad; } else { memset(&ad, 0, sizeof(ad)); @@ -433,37 +472,25 @@ int ibuflen, *rbuflen; } if ( creatf) { /* on a hard create, fail if file exists and is open */ - if ((stat(upath, &st) == 0) && of) + if (!ret && of) return AFPERR_BUSY; openf = O_RDWR|O_CREAT|O_TRUNC; } else { + /* on a soft create, if the file is open then ad_open won't fail + because open syscall is not called + */ + if (of) { + return AFPERR_EXIST; + } openf = O_RDWR|O_CREAT|O_EXCL; } -#ifdef FORCE_UIDGID - - /* preserve current euid, egid */ - save_uidgid ( uidgid ); - - /* perform all switching of users */ - set_uidgid ( vol ); - -#endif /* FORCE_UIDGID */ - if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF, openf, 0666, adp) < 0 ) { switch ( errno ) { case EEXIST : -#ifdef FORCE_UIDGID - /* bring everything back to old euid, egid */ - restore_uidgid ( uidgid ); -#endif /* FORCE_UIDGID */ return( AFPERR_EXIST ); case EACCES : -#ifdef FORCE_UIDGID - /* bring everything back to old euid, egid */ - restore_uidgid ( uidgid ); -#endif /* FORCE_UIDGID */ return( AFPERR_ACCESS ); case ENOENT: /* on noadouble volumes, just creating the data fork is ok */ @@ -471,10 +498,6 @@ int ibuflen, *rbuflen; goto createfile_done; /* fallthrough */ default : -#ifdef FORCE_UIDGID - /* bring everything back to old euid, egid */ - restore_uidgid ( uidgid ); -#endif /* FORCE_UIDGID */ return( AFPERR_PARAM ); } } @@ -496,14 +519,9 @@ createfile_done: setvoltime(obj, vol ); #ifdef DEBUG - syslog(LOG_INFO, "end afp_createfile"); + LOG(log_info, logtype_afpd, "end afp_createfile"); #endif /* DEBUG */ -#ifdef FORCE_UIDGID - /* bring everything back to old euid, egid */ - restore_uidgid ( uidgid ); -#endif /* FORCE_UIDGID */ - return (retvalue); } @@ -519,7 +537,7 @@ int ibuflen, *rbuflen; u_int16_t vid, bitmap; #ifdef DEBUG - syslog(LOG_INFO, "begin afp_setfilparams:"); + LOG(log_info, logtype_afpd, "begin afp_setfilparams:"); #endif /* DEBUG */ *rbuflen = 0; @@ -548,6 +566,10 @@ int ibuflen, *rbuflen; return( AFPERR_NOOBJ ); } + if ( *path == '\0' ) { + return( AFPERR_BADTYPE ); /* it's a directory */ + } + if ((u_long)ibuf & 1 ) { ibuf++; } @@ -557,12 +579,16 @@ int ibuflen, *rbuflen; } #ifdef DEBUG - syslog(LOG_INFO, "end afp_setfilparams:"); + LOG(log_info, logtype_afpd, "end afp_setfilparams:"); #endif /* DEBUG */ 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 ) @@ -577,36 +603,32 @@ int setfilparams(struct vol *vol, u_int32_t aint; struct utimbuf ut; -#ifdef FORCE_UIDGID - uidgidset *uidgid; + int change_mdate = 0; + int change_parent_mdate = 0; + int newdate = 0; + struct timeval tv; - uidgid = malloc(sizeof(uidgidset)); -#endif /* FORCE_UIDGID */ #ifdef DEBUG - syslog(LOG_INFO, "begin setfilparams:"); + LOG(log_info, logtype_afpd, "begin setfilparams:"); #endif /* DEBUG */ upath = mtoupath(vol, path); - if ((of = of_findname(vol, curdir, path))) { + if ((of = of_findname(upath, NULL))) { adp = of->of_ad; } else { memset(&ad, 0, sizeof(ad)); adp = &ad; } -#ifdef FORCE_UIDGID - save_uidgid ( uidgid ); - set_uidgid ( vol ); -#endif /* FORCE_UIDGID */ + if (check_access(upath, OPENACC_WR ) < 0) { + return AFPERR_ACCESS; + } if (ad_open( upath, vol_noadouble(vol) | ADFLAGS_HF, O_RDWR|O_CREAT, 0666, adp) < 0) { /* for some things, we don't need an adouble header */ if (bitmap & ~(1<em_type, sizeof( em->em_type )) == 0) && - (memcmp(buf + 4, em->em_creator, - sizeof( em->em_creator )) == 0)) { + change_mdate = 1; + + if (!memcmp( ad_entry( adp, ADEID_FINDERI ), ufinderi, 8 ) + && ( + ((em = getextmap( path )) && + !memcmp(buf, em->em_type, sizeof( em->em_type )) && + !memcmp(buf + 4, em->em_creator,sizeof( em->em_creator))) + || ((em = getdefextmap()) && + !memcmp(buf, em->em_type, sizeof( em->em_type )) && + !memcmp(buf + 4, em->em_creator,sizeof( em->em_creator))) + )) { memcpy(buf, ufinderi, 8 ); } + memcpy(ad_entry( adp, ADEID_FINDERI ), buf, 32 ); buf += 32; break; @@ -721,20 +751,31 @@ 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 ); -#ifdef FORCE_UIDGID - restore_uidgid ( uidgid ); -#endif /* FORCE_UIDGID */ + } + if (change_parent_mdate && gettimeofday(&tv, NULL) == 0) { + newdate = AD_DATE_FROM_UNIX(tv.tv_sec); + bitmap = 1<newtmp; strcpy( newname, path ); p = ctoupath( vol, curdir, newname ); - +#ifdef FORCE_UIDGID + /* FIXME svid != dvid && dvid's user can't read svid */ +#endif if (( vol = getvolbyvid( dvid )) == NULL ) { return( AFPERR_PARAM ); } @@ -910,7 +959,7 @@ int ibuflen, *rbuflen; return( AFPERR_NOOBJ ); } if ( *path != '\0' ) { - return( AFPERR_BADTYPE ); + return( AFPERR_BADTYPE ); /* not a directory. AFPERR_PARAM? */ } /* one of the handful of places that knows about the path type */ @@ -920,23 +969,29 @@ int ibuflen, *rbuflen; if (( plen = (unsigned char)*ibuf++ ) != 0 ) { strncpy( newname, ibuf, plen ); newname[ plen ] = '\0'; + if (strlen(newname) != plen) { + /* there's \0 in newname, e.g. it's a pathname not + * only a filename. + */ + return( AFPERR_PARAM ); + } } - if ( (err = copyfile(p, mtoupath(vol, newname ), newname, - vol_noadouble(vol))) < 0 ) { + if ( (err = copyfile(p, mtoupath(vol, newname), + newname, vol_noadouble(vol))) < 0 ) { return err; } - setvoltime(obj, vol ); - #ifdef DROPKLUDGE if (vol->v_flags & AFPVOL_DROPBOX) { retvalue=matchfile2dirperms(newname, vol, sdid); } #endif /* DROPKLUDGE */ + setvoltime(obj, vol ); + #ifdef DEBUG - syslog (LOG_INFO, "end afp_copyfile:"); + LOG(log_info, logtype_afpd, "end afp_copyfile:"); #endif /* DEBUG */ return( retvalue ); @@ -949,7 +1004,7 @@ static __inline__ int copy_all(const int dfd, const void *buf, ssize_t cc; #ifdef DEBUG - syslog(LOG_INFO, "begin copy_all:"); + LOG(log_info, logtype_afpd, "begin copy_all:"); #endif /* DEBUG */ while (buflen > 0) { @@ -971,7 +1026,7 @@ static __inline__ int copy_all(const int dfd, const void *buf, } #ifdef DEBUG - syslog(LOG_INFO, "end copy_all:"); + LOG(log_info, logtype_afpd, "end copy_all:"); #endif /* DEBUG */ return AFP_OK; @@ -988,11 +1043,14 @@ const int noadouble; char filebuf[8192]; int sfd, dfd, len, err = AFP_OK; ssize_t cc; - + char *dpath; + int admode; #ifdef DEBUG - syslog(LOG_INFO, "begin copyfile:"); + LOG(log_info, logtype_afpd, "begin copyfile:"); #endif /* DEBUG */ + dpath = ad_path( dst, ADFLAGS_HF ); + admode = ad_mode( dst, 0666 ); if (newname) { if ((sfd = open( ad_path( src, ADFLAGS_HF ), O_RDONLY, 0 )) < 0 ) { switch ( errno ) { @@ -1004,8 +1062,7 @@ const int noadouble; return( AFPERR_PARAM ); } } else { - if (( dfd = open( ad_path( dst, ADFLAGS_HF ), O_WRONLY|O_CREAT, - ad_mode( ad_path( dst, ADFLAGS_HF ), 0666 ))) < 0 ) { + if (( dfd = open( dpath, O_WRONLY|O_CREAT,ad_hf_mode(admode))) < 0 ) { close( sfd ); switch ( errno ) { case ENOENT : @@ -1055,7 +1112,7 @@ copyheader_done: close(sfd); close(dfd); if (err < 0) { - unlink(ad_path(dst, ADFLAGS_HF)); + unlink(dpath); return err; } } @@ -1073,7 +1130,7 @@ copyheader_done: } } - if (( dfd = open( dst, O_WRONLY|O_CREAT, ad_mode( dst, 0666 ))) < 0 ) { + if (( dfd = open( dst, O_WRONLY|O_CREAT, admode)) < 0 ) { close( sfd ); switch ( errno ) { case ENOENT : @@ -1122,7 +1179,7 @@ copydata_done: close(sfd); close(dfd); if (err < 0) { - unlink(ad_path(dst, ADFLAGS_HF)); + unlink(dpath); unlink(dst); return err; } @@ -1151,15 +1208,23 @@ copydata_done: } #ifdef DEBUG - syslog(LOG_INFO, "end copyfile:"); + LOG(log_info, logtype_afpd, "end copyfile:"); #endif /* DEBUG */ return( AFP_OK ); } -int deletefile( file ) +/* ----------------------------------- + checkAttrib: 1 check kFPDeleteInhibitBit + ie deletfile called by afp_delete + + when deletefile is called we don't have lock on it, file is closed (for us) + untrue if called by renamefile +*/ +int deletefile( file, checkAttrib ) char *file; +int checkAttrib; { struct adouble ad; int adflags, err = AFP_OK; @@ -1167,7 +1232,7 @@ char *file; int openmode = O_RDWR; #ifdef DEBUG - syslog(LOG_INFO, "begin deletefile:"); + LOG(log_info, logtype_afpd, "begin deletefile:"); #endif /* DEBUG */ while(1) { @@ -1220,11 +1285,33 @@ char *file; } break; /* from the while */ } + /* + * Does kFPDeleteInhibitBit (bit 8) set? + */ + if (checkAttrib && (adflags & ADFLAGS_HF)) { + u_int16_t bshort; - if ((adflags & ADFLAGS_HF) && - (ad_tmplock(&ad, ADEID_RFORK, locktype, 0, 0) < 0 )) { - ad_close( &ad, adflags ); - return( AFPERR_BUSY ); + ad_getattr(&ad, &bshort); + if ((bshort & htons(ATTRBIT_NODELETE))) { + ad_close( &ad, adflags ); + return(AFPERR_OLOCK); + } + } + + if ((adflags & ADFLAGS_HF) ) { + /* FIXME we have a pb here because we want to know if a file is open + * there's a 'priority inversion' if you can't open the ressource fork RW + * you can delete it if it's open because you can't get a write lock. + * + * ADLOCK_FILELOCK means the whole ressource fork, not only after the + * metadatas + * + * FIXME it doesn't for RFORK open read only and fork open without deny mode + */ + if (ad_tmplock(&ad, ADEID_RFORK, locktype |ADLOCK_FILELOCK, 0, 0) < 0 ) { + ad_close( &ad, adflags ); + return( AFPERR_BUSY ); + } } if (ad_tmplock( &ad, ADEID_DFORK, locktype, 0, 0 ) < 0) { @@ -1268,12 +1355,12 @@ char *file; delete_unlock: if (adflags & ADFLAGS_HF) - ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR, 0, 0); + ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR |ADLOCK_FILELOCK, 0, 0); ad_tmplock(&ad, ADEID_DFORK, ADLOCK_CLR, 0, 0); ad_close( &ad, adflags ); #ifdef DEBUG - syslog(LOG_INFO, "end deletefile:"); + LOG(log_info, logtype_afpd, "end deletefile:"); #endif /* DEBUG */ return err; @@ -1297,7 +1384,7 @@ int ibuflen, *rbuflen; u_short vid; #ifdef DEBUG - syslog(LOG_INFO, "begin afp_createid:"); + LOG(log_info, logtype_afpd, "begin afp_createid:"); #endif /* DEBUG */ *rbuflen = 0; @@ -1355,14 +1442,14 @@ int ibuflen, *rbuflen; } #endif /* AD_VERSION > AD_VERSION1 */ - if (id = cnid_add(vol->v_db, &st, did, upath, len, id)) { + if (id = cnid_add(vol->v_db, &st, did, upath, len, id) != CNID_INVALID) { memcpy(rbuf, &id, sizeof(id)); *rbuflen = sizeof(id); return AFP_OK; } #ifdef DEBUG - syslog(LOG_INFO, "ending afp_createid...:"); + LOG(log_info, logtype_afpd, "ending afp_createid...:"); #endif /* DEBUG */ switch (errno) { @@ -1374,7 +1461,7 @@ int ibuflen, *rbuflen; return AFPERR_ACCESS; break; default: - syslog(LOG_ERR, "afp_createid: cnid_add: %m"); + LOG(log_error, logtype_afpd, "afp_createid: cnid_add: %s", strerror(errno)); return AFPERR_PARAM; } } @@ -1393,8 +1480,11 @@ int ibuflen, *rbuflen; cnid_t id; u_int16_t vid, bitmap; + static char buffer[12 + MAXPATHLEN + 1]; + int len = 12 + MAXPATHLEN + 1; + #ifdef DEBUG - syslog(LOG_INFO, "begin afp_resolveid:"); + LOG(log_info, logtype_afpd, "begin afp_resolveid:"); #endif /* DEBUG */ *rbuflen = 0; @@ -1410,12 +1500,12 @@ int ibuflen, *rbuflen; memcpy(&id, ibuf, sizeof( id )); ibuf += sizeof(id); - if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) { - return AFPERR_BADID; + if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) { + return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */ } - if (( dir = dirsearch( vol, id )) == NULL ) { - return( AFPERR_PARAM ); + if (( dir = dirlookup( vol, id )) == NULL ) { + return AFPERR_NOID; /* idem AFPERR_PARAM */ } if ((movecwd(vol, dir) < 0) || (stat(upath, &st) < 0)) { @@ -1445,7 +1535,7 @@ int ibuflen, *rbuflen; memcpy(rbuf, ibuf, sizeof(bitmap)); #ifdef DEBUG - syslog(LOG_INFO, "end afp_resolveid:"); + LOG(log_info, logtype_afpd, "end afp_resolveid:"); #endif /* DEBUG */ return AFP_OK; @@ -1462,10 +1552,13 @@ int ibuflen, *rbuflen; char *upath; int err; cnid_t id; + cnid_t fileid; u_short vid; + static char buffer[12 + MAXPATHLEN + 1]; + int len = 12 + MAXPATHLEN + 1; #ifdef DEBUG - syslog(LOG_INFO, "begin afp_deleteid:"); + LOG(log_info, logtype_afpd, "begin afp_deleteid:"); #endif /* DEBUG */ *rbuflen = 0; @@ -1483,12 +1576,13 @@ int ibuflen, *rbuflen; memcpy(&id, ibuf, sizeof( id )); ibuf += sizeof(id); + fileid = id; - if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) { + if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) { return AFPERR_NOID; } - if (( dir = dirsearch( vol, id )) == NULL ) { + if (( dir = dirlookup( vol, id )) == NULL ) { return( AFPERR_PARAM ); } @@ -1511,7 +1605,7 @@ int ibuflen, *rbuflen; if (S_ISDIR(st.st_mode)) return AFPERR_BADTYPE; - if (cnid_delete(vol->v_db, id)) { + if (cnid_delete(vol->v_db, fileid)) { switch (errno) { case EROFS: return AFPERR_VLOCK; @@ -1524,7 +1618,7 @@ int ibuflen, *rbuflen; } #ifdef DEBUG - syslog(LOG_INFO, "end afp_deleteid:"); + LOG(log_info, logtype_afpd, "end afp_deleteid:"); #endif /* DEBUG */ return err; @@ -1544,6 +1638,13 @@ int ibuflen, *rbuflen; char *spath, temp[17], *path, *p; char *supath, *upath; int err; + struct adouble ads; + struct adouble add; + struct adouble *adsp; + struct adouble *addp; + struct ofork *s_of; + struct ofork *d_of; + #ifdef CNID_DB int slen, dlen; #endif /* CNID_DB */ @@ -1551,7 +1652,7 @@ int ibuflen, *rbuflen; u_int16_t vid; #ifdef DEBUG - syslog(LOG_INFO, "begin afp_exchangefiles:"); + LOG(log_info, logtype_afpd, "begin afp_exchangefiles:"); #endif /* DEBUG */ *rbuflen = 0; @@ -1583,7 +1684,7 @@ int ibuflen, *rbuflen; } if ( *path == '\0' ) { - return( AFPERR_BADTYPE ); + return( AFPERR_BADTYPE ); /* it's a dir */ } upath = mtoupath(vol, path); @@ -1598,7 +1699,12 @@ int ibuflen, *rbuflen; return AFPERR_PARAM; } } - + memset(&ads, 0, sizeof(ads)); + adsp = &ads; + if ((s_of = of_findname(upath, &srcst))) { + /* reuse struct adouble so it won't break locks */ + adsp = s_of->of_ad; + } /* save some stuff */ sdir = curdir; spath = obj->oldtmp; @@ -1643,7 +1749,18 @@ int ibuflen, *rbuflen; return AFPERR_PARAM; } } + memset(&add, 0, sizeof(add)); + addp = &add; + if ((d_of = of_findname( upath, &destst))) { + /* reuse struct adouble so it won't break locks */ + addp = d_of->of_ad; + } + /* they are not on the same device and at least one is open + */ + if ((d_of || s_of) && srcst.st_dev != destst.st_dev) + return AFPERR_MISC; + #ifdef CNID_DB /* look for destination id. */ did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath, @@ -1658,19 +1775,19 @@ int ibuflen, *rbuflen; return AFPERR_MISC; /* now, quickly rename the file. we error if we can't. */ - if ((err = renamefile(p, temp, temp, vol_noadouble(vol))) < 0) + if ((err = renamefile(p, temp, temp, vol_noadouble(vol), adsp)) < 0) goto err_exchangefile; - of_rename(vol, sdir, spath, curdir, temp); + of_rename(vol, s_of, sdir, spath, curdir, temp); /* rename destination to source */ - if ((err = renamefile(path, p, spath, vol_noadouble(vol))) < 0) + if ((err = renamefile(upath, p, spath, vol_noadouble(vol), addp)) < 0) goto err_src_to_tmp; - of_rename(vol, curdir, path, sdir, spath); + of_rename(vol, d_of, curdir, path, sdir, spath); /* rename temp to destination */ - if ((err = renamefile(temp, upath, path, vol_noadouble(vol))) < 0) + if ((err = renamefile(temp, upath, path, vol_noadouble(vol), adsp)) < 0) goto err_dest_to_src; - of_rename(vol, curdir, temp, curdir, path); + of_rename(vol, s_of, curdir, temp, curdir, path); #ifdef CNID_DB /* id's need switching. src -> dest and dest -> src. */ @@ -1680,6 +1797,7 @@ int ibuflen, *rbuflen; case EPERM: case EACCES: err = AFPERR_ACCESS; + break; default: err = AFPERR_PARAM; } @@ -1692,6 +1810,7 @@ int ibuflen, *rbuflen; case EPERM: case EACCES: err = AFPERR_ACCESS; + break; default: err = AFPERR_PARAM; } @@ -1703,7 +1822,7 @@ int ibuflen, *rbuflen; #endif /* CNID_DB */ #ifdef DEBUG - syslog(LOG_INFO, "ending afp_exchangefiles:"); + LOG(log_info, logtype_afpd, "ending afp_exchangefiles:"); #endif /* DEBUG */ return AFP_OK; @@ -1711,20 +1830,22 @@ int ibuflen, *rbuflen; /* all this stuff is so that we can unwind a failed operation * properly. */ +#ifdef CNID_DB err_temp_to_dest: +#endif /* rename dest to temp */ - renamefile(upath, temp, temp, vol_noadouble(vol)); - of_rename(vol, curdir, upath, curdir, temp); + renamefile(upath, temp, temp, vol_noadouble(vol), adsp); + of_rename(vol, s_of, curdir, upath, curdir, temp); err_dest_to_src: /* rename source back to dest */ - renamefile(p, upath, path, vol_noadouble(vol)); - of_rename(vol, sdir, spath, curdir, path); + renamefile(p, upath, path, vol_noadouble(vol), addp); + of_rename(vol, d_of, sdir, spath, curdir, path); err_src_to_tmp: /* rename temp back to source */ - renamefile(temp, p, spath, vol_noadouble(vol)); - of_rename(vol, curdir, temp, sdir, spath); + renamefile(temp, p, spath, vol_noadouble(vol), adsp); + of_rename(vol, s_of, curdir, temp, sdir, spath); err_exchangefile: return err;