X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=fac35b7fa71a1e282d92dcb28a30f1b2f75e3f5c;hp=96970807805b98ff327650f1ca6ea218d4611f43;hb=21b17908047ad4f3b00a9f6a4655494d874390b0;hpb=ecfc96169ab669b578e53fa8e13592934fe37788 diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 96970807..fac35b7f 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.96 2005-04-28 20:49:41 bfernhomberg Exp $ + * $Id: file.c,v 1.120 2009-11-02 14:35:27 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -28,18 +28,18 @@ char *strchr (), *strrchr (); #endif /* ! HAVE_MEMCPY */ #endif /* STDC_HEADERS */ -#include #include -#include #include - -#include #include - +#include +#include +#include #include #include #include +#include + #include "directory.h" #include "desktop.h" #include "volume.h" @@ -89,7 +89,7 @@ static int default_type(void *finder) } /* FIXME path : unix or mac name ? (for now it's unix name ) */ -void *get_finderinfo(const char *upath, struct adouble *adp, void *data) +void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data) { struct extmap *em; void *ad_finder = NULL; @@ -107,11 +107,11 @@ void *get_finderinfo(const char *upath, struct adouble *adp, void *data) else { memcpy(data, ufinderi, ADEDLEN_FINDERI); chk_ext = 1; - if (*upath == '.') { /* make it invisible */ + if (vol_inv_dots(vol) && *upath == '.') { /* make it invisible */ u_int16_t ashort; ashort = htons(FINDERINFO_INVISIBLE); - memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); + memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); } } /** Only enter if no appledouble information and no finder information found. */ @@ -227,7 +227,7 @@ u_int32_t aint = 0; * for a folder adp is always null */ if (ad_setid(adp, st->st_dev, st->st_ino, aint, did, vol->v_stamp)) { - ad_flush(adp, ADFLAGS_HF); + ad_flush(adp); } } #endif @@ -239,7 +239,7 @@ u_int32_t aint = 0; int getmetadata(struct vol *vol, u_int16_t bitmap, struct path *path, struct dir *dir, - char *buf, int *buflen, struct adouble *adp, int attrbits ) + char *buf, size_t *buflen, struct adouble *adp) { char *data, *l_nameoff = NULL, *upath; char *utf_nameoff = NULL; @@ -253,7 +253,7 @@ int getmetadata(struct vol *vol, struct maccess ma; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin getmetadata:"); + LOG(log_debug9, logtype_afpd, "begin getmetadata:"); #endif /* DEBUG */ upath = path->u_name; @@ -284,7 +284,7 @@ int getmetadata(struct vol *vol, case FILPBIT_ATTR : if ( adp ) { ad_getattr(adp, &ashort); - } else if (*upath == '.') { + } else if (vol_inv_dots(vol) && *upath == '.') { ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; @@ -296,12 +296,10 @@ int getmetadata(struct vol *vol, if ((ma.ma_user & AR_UWRITE)) { accessmode( upath, &ma, dir , st); if (!(ma.ma_user & AR_UWRITE)) { - attrbits |= ATTRBIT_NOWRITE; + ashort |= htons(ATTRBIT_NOWRITE); } } #endif - if (attrbits) - ashort = htons(ntohs(ashort) | attrbits); memcpy(data, &ashort, sizeof( ashort )); data += sizeof( ashort ); break; @@ -338,7 +336,7 @@ int getmetadata(struct vol *vol, break; case FILPBIT_FINFO : - get_finderinfo(upath, adp, (char *)data); + get_finderinfo(vol, upath, adp, (char *)data); data += ADEDLEN_FINDERI; break; @@ -513,33 +511,27 @@ int getmetadata(struct vol *vol, int getfilparams(struct vol *vol, u_int16_t bitmap, struct path *path, struct dir *dir, - char *buf, int *buflen ) + char *buf, size_t *buflen ) { struct adouble ad, *adp; - struct ofork *of; - char *upath; - u_int16_t attrbits = 0; int opened = 0; int rc; #ifdef DEBUG - LOG(log_info, logtype_default, "begin getfilparams:"); + LOG(log_debug9, logtype_default, "begin getfilparams:"); #endif /* DEBUG */ opened = PARAM_NEED_ADP(bitmap); adp = NULL; + if (opened) { + char *upath; + int flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0; + + adp = of_ad(vol, path, &ad); upath = path->u_name; - if ((of = of_findname(path))) { - 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 { - ad_init(&ad, vol->v_adouble, vol->v_ad_options); - adp = &ad; - } - if ( ad_metadata( upath, 0, adp) < 0 ) { + if ( ad_metadata( upath, flags, adp) < 0 ) { switch (errno) { case EACCES: LOG(log_error, logtype_afpd, "getfilparams(%s): %s: check resource fork permission?", @@ -554,41 +546,20 @@ int getfilparams(struct vol *vol, break; } } - if (adp) { - /* 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)) { - attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_ROPEN : 0; - attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_ROPEN : 0; - } - if (!(attrbits & ATTRBIT_DOPEN)) { - attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_DOPEN : 0; - attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_DOPEN : 0; - } - } - } } - rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp, attrbits); + rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp); if ( adp ) { - ad_close( adp, ADFLAGS_HF ); + ad_close_metadata( adp); } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end getfilparams:"); + LOG(log_debug9, logtype_afpd, "end getfilparams:"); #endif /* DEBUG */ return( rc ); } /* ----------------------------- */ -int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf _U_; -int ibuflen _U_, *rbuflen; +int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct adouble ad, *adp; struct vol *vol; @@ -597,13 +568,8 @@ int ibuflen _U_, *rbuflen; char *path, *upath; int creatf, did, openf, retvalue = AFP_OK; u_int16_t vid; - int ret; struct path *s_path; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_createfile:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf++; creatf = (unsigned char) *ibuf++; @@ -634,8 +600,6 @@ int ibuflen _U_, *rbuflen; } upath = s_path->u_name; - if (0 != (ret = check_name(vol, upath))) - return ret; /* if upath is deleted we already in trouble anyway */ if ((of = of_findname(s_path))) { @@ -659,7 +623,7 @@ int ibuflen _U_, *rbuflen; openf = O_RDWR|O_CREAT|O_EXCL; } - if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF, + if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF|ADFLAGS_CREATE, openf, 0666, adp) < 0 ) { switch ( errno ) { case EROFS: @@ -670,11 +634,14 @@ int ibuflen _U_, *rbuflen; return( AFPERR_EXIST ); case EACCES : return( AFPERR_ACCESS ); + case EDQUOT: + case ENOSPC : + return( AFPERR_DFULL ); default : return( AFPERR_PARAM ); } } - if ( ad_hfileno( adp ) == -1 ) { + if ( ad_reso_fileno( adp ) == -1 ) { /* Hard META / HF */ /* on noadouble volumes, just creating the data fork is ok */ if (vol_noadouble(vol)) { ad_close( adp, ADFLAGS_DF ); @@ -690,7 +657,7 @@ int ibuflen _U_, *rbuflen; path = s_path->m_name; ad_setname(adp, path); - ad_flush( adp, ADFLAGS_DF|ADFLAGS_HF ); + ad_flush( adp); ad_close( adp, ADFLAGS_DF|ADFLAGS_HF ); createfile_done: @@ -704,17 +671,10 @@ createfile_done: setvoltime(obj, vol ); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_createfile"); -#endif /* DEBUG */ - return (retvalue); } -int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf _U_; -int ibuflen _U_, *rbuflen; +int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct vol *vol; struct dir *dir; @@ -722,10 +682,6 @@ int ibuflen _U_, *rbuflen; int did, rc; u_int16_t vid, bitmap; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_setfilparams:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -768,10 +724,6 @@ int ibuflen _U_, *rbuflen; setvoltime(obj, vol ); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_setfilparams:"); -#endif /* DEBUG */ - return( rc ); } @@ -807,12 +759,11 @@ int setfilparams(struct vol *vol, u_char finder_buf[32]; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin setfilparams:"); + LOG(log_debug9, logtype_afpd, "begin setfilparams:"); #endif /* DEBUG */ - upath = path->u_name; adp = of_ad(vol, path, &ad); - + upath = path->u_name; if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) { return AFPERR_ACCESS; @@ -910,12 +861,18 @@ int setfilparams(struct vol *vol, /* second try with adouble open */ - 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 (f_bitmap & ~(1<m_name); @@ -996,8 +953,8 @@ setfilparam_done: } if (isad) { - ad_flush( adp, ADFLAGS_HF ); - ad_close( adp, ADFLAGS_HF ); + ad_flush( adp); + ad_close_metadata( adp); } @@ -1008,7 +965,7 @@ setfilparam_done: } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end setfilparams:"); + LOG(log_debug9, logtype_afpd, "end setfilparams:"); #endif /* DEBUG */ return err; } @@ -1023,15 +980,12 @@ setfilparam_done: * adp adouble struct of src file, if open, or & zeroed one * */ -int renamefile(vol, src, dst, newname, adp ) -const struct vol *vol; -char *src, *dst, *newname; -struct adouble *adp; +int renamefile(const struct vol *vol, char *src, char *dst, char *newname, struct adouble *adp) { int rc; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin renamefile:"); + LOG(log_debug9, logtype_afpd, "begin renamefile:"); #endif /* DEBUG */ if ( unix_rename( src, dst ) < 0 ) { @@ -1048,7 +1002,7 @@ struct adouble *adp; * get two files, it's fixable for our process (eg reopen the new file, get the * locks, and so on. But it doesn't solve the case with a second process */ - if (adp->ad_df.adf_refcount || adp->ad_hf.adf_refcount) { + if (adp->ad_open_forks) { /* FIXME warning in syslog so admin'd know there's a conflict ?*/ return AFPERR_OLOCK; /* little lie */ } @@ -1062,7 +1016,7 @@ struct adouble *adp; } } - if (vol->vfs->rf_renamefile(vol, src, dst) < 0 ) { + if (vol->vfs->vfs_renamefile(vol, src, dst) < 0 ) { int err; err = errno; @@ -1090,11 +1044,11 @@ struct adouble *adp; */ if (!ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp)) { ad_setname(adp, newname); - ad_flush( adp, ADFLAGS_HF ); + ad_flush( adp ); ad_close( adp, ADFLAGS_HF ); } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end renamefile:"); + LOG(log_debug9, logtype_afpd, "end renamefile:"); #endif /* DEBUG */ return( AFP_OK ); @@ -1171,10 +1125,7 @@ u_int32_t hint; /* ----------------------------------- */ -int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf _U_; -int ibuflen _U_, *rbuflen; +int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct vol *s_vol, *d_vol; struct dir *dir; @@ -1187,10 +1138,6 @@ int ibuflen _U_, *rbuflen; struct adouble ad, *adp; int denyreadset; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_copyfile:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1288,21 +1235,17 @@ int ibuflen _U_, *rbuflen; setvoltime(obj, d_vol ); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_copyfile:"); -#endif /* DEBUG */ - return( retvalue ); } /* ----------------------- */ -static __inline__ int copy_all(const int dfd, const void *buf, +static int copy_all(const int dfd, const void *buf, size_t buflen) { ssize_t cc; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin copy_all:"); + LOG(log_debug9, logtype_afpd, "begin copy_all:"); #endif /* DEBUG */ while (buflen > 0) { @@ -1318,19 +1261,37 @@ static __inline__ int copy_all(const int dfd, const void *buf, } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end copy_all:"); + LOG(log_debug9, logtype_afpd, "end copy_all:"); #endif /* DEBUG */ return 0; } -/* -------------------------- */ -static int copy_fd(int dfd, int sfd) +/* -------------------------- + * copy only the fork data stream +*/ +static int copy_fork(int eid, struct adouble *add, struct adouble *ads) { ssize_t cc; int err = 0; char filebuf[8192]; + int sfd, dfd; + if (eid == ADEID_DFORK) { + sfd = ad_data_fileno(ads); + dfd = ad_data_fileno(add); + } + else { + sfd = ad_reso_fileno(ads); + dfd = ad_reso_fileno(add); + } + + if ((off_t)-1 == lseek(sfd, ad_getentryoff(ads, eid), SEEK_SET)) + return -1; + + if ((off_t)-1 == lseek(dfd, ad_getentryoff(add, eid), SEEK_SET)) + return -1; + #if 0 /* ifdef SENDFILE_FLAVOR_LINUX */ /* doesn't work With 2.6 FIXME, only check for EBADFD ? */ off_t offset = 0; @@ -1376,23 +1337,22 @@ static int copy_fd(int dfd, int sfd) } /* ---------------------------------- - * if newname is NULL (from directory.c) we don't want to copy ressource fork. + * if newname is NULL (from directory.c) we don't want to copy the resource fork. * because we are doing it elsewhere. + * currently if newname is NULL then adp is NULL. */ -int copyfile(s_vol, d_vol, src, dst, newname, adp ) -const struct vol *s_vol, *d_vol; -char *src, *dst, *newname; -struct adouble *adp; +int copyfile(const struct vol *s_vol, const struct vol*d_vol, + char *src, char *dst, char *newname, struct adouble *adp) { struct adouble ads, add; int err = 0; int ret_err = 0; int adflags; - int noadouble = vol_noadouble(d_vol); + int stat_result; struct stat st; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin copyfile:"); + LOG(log_debug9, logtype_afpd, "begin copyfile:"); #endif /* DEBUG */ if (adp == NULL) { @@ -1410,12 +1370,19 @@ struct adouble *adp; goto done; } - if (ad_hfileno(adp) == -1) { + if (ad_meta_fileno(adp) == -1 && ad_reso_fileno(adp) == -1) { /* META / HF */ /* no resource fork, don't create one for dst file */ adflags &= ~ADFLAGS_HF; } - if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, 0666, &add) < 0) { + stat_result = fstat(ad_data_fileno(adp), &st); /* saving stat exit code, thus saving us on one more stat later on */ + + if (stat_result < 0) { + /* unlikely but if fstat fails, the default file mode will be 0666. */ + st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + } + + if (ad_open(dst , adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) { ret_err = errno; ad_close( adp, adflags ); if (EEXIST != ret_err) { @@ -1424,45 +1391,40 @@ struct adouble *adp; } return AFPERR_EXIST; } - if (ad_hfileno(adp) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(adp)))){ + + /* + * XXX if the source and the dest don't use the same resource type it's broken + */ + if (ad_reso_fileno(adp) == -1 || 0 == (err = copy_fork(ADEID_RFORK, &add, adp))){ /* copy the data fork */ - err = copy_fd(ad_dfileno(&add), ad_dfileno(adp)); + if ((err = copy_fork(ADEID_DFORK, &add, adp)) == 0) { + err = d_vol->vfs->vfs_copyfile(d_vol, src, dst); + } } - /* Now, reopen destination file */ if (err < 0) { ret_err = errno; } - ad_close( adp, adflags ); - if (ad_close( &add, adflags ) <0) { - deletefile(d_vol, dst, 0); - ret_err = errno; - goto done; - } - else { - ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options); - if (ad_open(dst , adflags | noadouble, O_RDWR, 0666, &add) < 0) { - ret_err = errno; - } - } - - if (!ret_err && newname) { + if (!ret_err && newname && (adflags & ADFLAGS_HF)) { + /* set the new name in the resource fork */ + ad_copy_header(&add, adp); ad_setname(&add, newname); + ad_flush( &add ); } + ad_close( adp, adflags ); - ad_flush( &add, adflags ); if (ad_close( &add, adflags ) <0) { ret_err = errno; - } + } + if (ret_err) { deletefile(d_vol, dst, 0); } - else if (!stat(src, &st)) { + else if (stat_result == 0) { /* set dest modification date to src date */ struct utimbuf ut; - /* ADS here ? */ ut.actime = ut.modtime = st.st_mtime; utime(dst, &ut); /* FIXME netatalk doesn't use resource fork file date @@ -1471,7 +1433,7 @@ struct adouble *adp; } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end copyfile:"); + LOG(log_debug9, logtype_afpd, "end copyfile:"); #endif /* DEBUG */ done: @@ -1503,23 +1465,49 @@ done: ad_open always try to open file RDWR first and ad_lock takes care of WRITE lock on read only file. */ -int deletefile( vol, file, checkAttrib ) -const struct vol *vol; -char *file; -int checkAttrib; + +static int check_attrib(struct adouble *adp) +{ +u_int16_t bshort = 0; + + ad_getattr(adp, &bshort); + /* + * Does kFPDeleteInhibitBit (bit 8) set? + */ + if ((bshort & htons(ATTRBIT_NODELETE))) { + return AFPERR_OLOCK; + } + if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) { + return AFPERR_BUSY; + } + return 0; +} + +int deletefile(const struct vol *vol, char *file, int checkAttrib) { struct adouble ad; struct adouble *adp = &ad; int adflags, err = AFP_OK; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin deletefile:"); + LOG(log_debug9, logtype_afpd, "begin deletefile:"); #endif /* DEBUG */ /* try to open both forks at once */ adflags = ADFLAGS_DF|ADFLAGS_HF; - ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */ + if (checkAttrib) { + /* was EACCESS error try to get only metadata */ + ad_init(&ad, vol->v_adouble, vol->v_ad_options); + if ( ad_metadata( file , ADFLAGS_OPENFORKS, &ad) == 0 ) { + ad_close( &ad, adflags ); + if ((err = check_attrib(&ad))) { + return err; + } + } + } + while(1) { + ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */ if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) { switch (errno) { case ENOENT: @@ -1531,7 +1519,7 @@ int checkAttrib; continue; case EACCES: - adp = NULL; /* maybe it's a file we no rw mode for us */ + adp = NULL; /* maybe it's a file with no write mode for us */ break; /* was return AFPERR_ACCESS;*/ case EROFS: return AFPERR_VLOCK; @@ -1541,33 +1529,7 @@ int checkAttrib; } break; /* from the while */ } - /* - * Does kFPDeleteInhibitBit (bit 8) set? - */ - if (checkAttrib) { - u_int16_t bshort; - - if (adp && (adflags & ADFLAGS_HF)) { - ad_getattr(&ad, &bshort); - if ((bshort & htons(ATTRBIT_NODELETE))) { - ad_close( &ad, adflags ); - return(AFPERR_OLOCK); - } - } - else if (!adp) { - /* was EACCESS error try to get only metadata */ - ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */ - if ( ad_metadata( file , 0, &ad) == 0 ) { - ad_getattr(&ad, &bshort); - ad_close( &ad, ADFLAGS_HF ); - if ((bshort & htons(ATTRBIT_NODELETE))) { - return AFPERR_OLOCK; - } - } - } - } - if (adp && (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 @@ -1587,7 +1549,7 @@ int checkAttrib; if (adp && ad_tmplock( &ad, ADEID_DFORK, ADLOCK_WR, 0, 0, 0 ) < 0) { err = AFPERR_BUSY; } - else if (!(err = vol->vfs->rf_deletefile(vol, file)) && !(err = netatalk_unlink( file )) ) { + else if (!(err = vol->vfs->vfs_deletefile(vol, file)) && !(err = netatalk_unlink( file )) ) { cnid_t id; if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) { @@ -1598,7 +1560,7 @@ int checkAttrib; ad_close( &ad, adflags ); /* ad_close removes locks if any */ #ifdef DEBUG - LOG(log_info, logtype_afpd, "end deletefile:"); + LOG(log_debug9, logtype_afpd, "end deletefile:"); #endif /* DEBUG */ return err; @@ -1606,10 +1568,7 @@ int checkAttrib; /* ------------------------------------ */ /* return a file id */ -int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj _U_; -char *ibuf, *rbuf; -int ibuflen _U_, *rbuflen; +int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct stat *st; struct vol *vol; @@ -1620,10 +1579,6 @@ int ibuflen _U_, *rbuflen; u_short vid; struct path *s_path; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_createid:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1682,9 +1637,6 @@ int ibuflen _U_, *rbuflen; return AFP_OK; } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "ending afp_createid...:"); -#endif /* DEBUG */ return afp_errno; } @@ -1702,8 +1654,6 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data) cnid_t did = param->did; cnid_t aint; - memset(&path, 0, sizeof(path)); - if ( stat(de->d_name, &path.st)<0 ) return 0; @@ -1720,13 +1670,13 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data) adp = of_ad(vol, &path, &ad); - if ( ad_open( de->d_name, ADFLAGS_HF, O_RDWR, 0, adp ) < 0 ) { + if ( ad_open_metadata( de->d_name, 0, 0, adp ) < 0 ) { return 0; } if (ad_setid(adp, path.st.st_dev, path.st.st_ino, aint, did, vol->v_stamp)) { - ad_flush(adp, ADFLAGS_HF); + ad_flush(adp); } - ad_close(adp, ADFLAGS_HF); + ad_close_metadata(adp); } #endif /* AD_VERSION > AD_VERSION1 */ @@ -1770,26 +1720,20 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir) /* ------------------------------ resolve a file id */ -int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj _U_; -char *ibuf, *rbuf; -int ibuflen _U_, *rbuflen; +int afp_resolveid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct vol *vol; struct dir *dir; char *upath; struct path path; - int err, buflen, retry=0; + int err, retry=0; + size_t buflen; cnid_t id, cnid; u_int16_t vid, bitmap; static char buffer[12 + MAXPATHLEN + 1]; int len = 12 + MAXPATHLEN + 1; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_resolveid:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1813,7 +1757,6 @@ int ibuflen _U_, *rbuflen; return AFPERR_NOID; } retry: - memset(&path, 0, sizeof(path)); if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) { return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */ } @@ -1821,7 +1764,6 @@ retry: if (NULL == ( dir = dirlookup( vol, id )) ) { return AFPERR_NOID; /* idem AFPERR_PARAM */ } - path.u_name = upath; if (movecwd(vol, dir) < 0) { switch (errno) { case EACCES: @@ -1834,6 +1776,8 @@ retry: } } + memset(&path, 0, sizeof(path)); + path.u_name = upath; if ( of_stat(&path) < 0 ) { #ifdef ESTALE /* with nfs and our working directory is deleted */ @@ -1860,8 +1804,10 @@ retry: } /* directories are bad */ - if (S_ISDIR(path.st.st_mode)) - return AFPERR_BADTYPE; + if (S_ISDIR(path.st.st_mode)) { + /* OS9 and OSX don't return the same error code */ + return (afp_version >=30)?AFPERR_NOID:AFPERR_BADTYPE; + } memcpy(&bitmap, ibuf, sizeof(bitmap)); bitmap = ntohs( bitmap ); @@ -1876,18 +1822,11 @@ retry: *rbuflen = buflen + sizeof(bitmap); memcpy(rbuf, ibuf, sizeof(bitmap)); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_resolveid:"); -#endif /* DEBUG */ - return AFP_OK; } /* ------------------------------ */ -int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj _U_; -char *ibuf, *rbuf _U_; -int ibuflen _U_, *rbuflen; +int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct stat st; struct vol *vol; @@ -1900,10 +1839,6 @@ int ibuflen _U_, *rbuflen; static char buffer[12 + MAXPATHLEN + 1]; int len = 12 + MAXPATHLEN + 1; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_deleteid:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1965,10 +1900,6 @@ int ibuflen _U_, *rbuflen; } } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_deleteid:"); -#endif /* DEBUG */ - return err; } @@ -2006,7 +1937,8 @@ static struct adouble *find_adouble(struct path *path, struct ofork **of, struct } else { ret = ad_open( path->u_name, ADFLAGS_HF, O_RDONLY, 0, adp); - if ( !ret && ad_hfileno(adp) != -1 && !(adp->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) { + /* META and HF */ + if ( !ret && ad_reso_fileno(adp) != -1 && !(adp->ad_resource_fork.adf_flags & ( O_RDWR | O_WRONLY))) { /* from AFP spec. * The user must have the Read & Write privilege for both files in order to use this command. */ @@ -2020,10 +1952,7 @@ static struct adouble *find_adouble(struct path *path, struct ofork **of, struct #define APPLETEMP ".AppleTempXXXXXX" -int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf _U_ ; -int ibuflen _U_, *rbuflen; +int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct stat srcst, destst; struct vol *vol; @@ -2047,10 +1976,6 @@ int ibuflen _U_, *rbuflen; uid_t uid; gid_t gid; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_exchangefiles:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -2209,12 +2134,12 @@ int ibuflen _U_, *rbuflen; /* here we need to reopen if crossdev */ if (sid && ad_setid(addp, destst.st_dev, destst.st_ino, sid, sdir->d_did, vol->v_stamp)) { - ad_flush( addp, ADFLAGS_HF ); + ad_flush( addp ); } if (did && ad_setid(adsp, srcst.st_dev, srcst.st_ino, did, curdir->d_did, vol->v_stamp)) { - ad_flush( adsp, ADFLAGS_HF ); + ad_flush( adsp ); } /* change perms, src gets dest perm and vice versa */ @@ -2254,10 +2179,6 @@ int ibuflen _U_, *rbuflen; exit(EXITERR_SYS); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "ending afp_exchangefiles:"); -#endif /* DEBUG */ - err = AFP_OK; goto err_exchangefile; @@ -2279,10 +2200,10 @@ err_src_to_tmp: of_rename(vol, s_of, curdir, temp, sdir, spath); err_exchangefile: - if ( !s_of && adsp && ad_hfileno(adsp) != -1 ) { + if ( !s_of && adsp && ad_meta_fileno(adsp) != -1 ) { /* META */ ad_close(adsp, ADFLAGS_HF); } - if ( !d_of && addp && ad_hfileno(addp) != -1 ) { + if ( !d_of && addp && ad_meta_fileno(addp) != -1 ) {/* META */ ad_close(addp, ADFLAGS_HF); }