X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=aa692842ed4a5c8d919080336292528d33dbcbd2;hp=f2b97209cfb820a557687568295b6b768da7d2c9;hb=a3e43549642d11f4bc86324f9a09c294f6a3f74b;hpb=6dcaba1d633e3cfa96243c62ad8399f7e5558c48 diff --git a/etc/afpd/file.c b/etc/afpd/file.c index f2b97209..aa692842 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.111 2009-10-02 09:32:40 franklahm Exp $ + * $Id: file.c,v 1.141 2010-03-12 15:16:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -29,7 +29,6 @@ char *strchr (), *strrchr (); #endif /* STDC_HEADERS */ #include -#include #include #include @@ -39,6 +38,8 @@ char *strchr (), *strrchr (); #include #include #include +#include + #include "directory.h" #include "desktop.h" #include "volume.h" @@ -88,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 struct vol *vol, const char *upath, struct adouble *adp, void *data) +void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink) { struct extmap *em; void *ad_finder = NULL; @@ -113,6 +114,17 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); } } + + if (islink){ + u_int16_t linkflag; + memcpy(&linkflag, (char *)data + FINDERINFO_FRFLAGOFF, 2); + linkflag |= htons(FINDERINFO_ISALIAS); + memcpy((char *)data + FINDERINFO_FRFLAGOFF, &linkflag, 2); + memcpy((char *)data + FINDERINFO_FRTYPEOFF,"slnk",4); + memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4); + chk_ext = 0; + } + /** Only enter if no appledouble information and no finder information found. */ if (chk_ext && (em = getextmap( upath ))) { memcpy(data, em->em_type, sizeof( em->em_type )); @@ -157,7 +169,7 @@ char *set_name(const struct vol *vol, char *data, cnid_t pid, char *name, cnid_t if (aint > 255) /* FIXME safeguard, anyway if no ascii char it's game over*/ aint = 255; - utf8 = vol->v_mac?htonl(vol->v_mac->kTextEncoding):0; /* htonl(utf8) */ + utf8 = vol->v_kTextEncoding; memcpy(data, &utf8, sizeof(utf8)); data += sizeof(utf8); @@ -186,25 +198,24 @@ char *set_name(const struct vol *vol, char *data, cnid_t pid, char *name, cnid_t (1 << FILPBIT_RFLEN) |\ (1 << FILPBIT_EXTRFLEN) |\ (1 << FILPBIT_PDINFO) |\ + (1 << FILPBIT_FNUM) |\ (1 << FILPBIT_UNIXPR))) /* -------------------------- */ u_int32_t get_id(struct vol *vol, struct adouble *adp, const struct stat *st, - const cnid_t did, char *upath, const int len) + const cnid_t did, char *upath, const int len) { -u_int32_t aint = 0; - -#if AD_VERSION > AD_VERSION1 - - if ((aint = ad_getid(adp, st->st_dev, st->st_ino, did, vol->v_stamp))) { - return aint; - } -#endif + u_int32_t adcnid; + u_int32_t dbcnid = CNID_INVALID; if (vol->v_cdb != NULL) { - aint = cnid_add(vol->v_cdb, st, did, upath, len, aint); + /* prime aint with what we think is the cnid, set did to zero for + catching moved files */ + adcnid = ad_getid(adp, st->st_dev, st->st_ino, 0, vol->v_stamp); + + dbcnid = cnid_add(vol->v_cdb, st, did, upath, len, adcnid); /* Throw errors if cnid_add fails. */ - if (aint == CNID_INVALID) { + if (dbcnid == CNID_INVALID) { switch (errno) { case CNID_ERR_CLOSE: /* the db is closed */ break; @@ -220,25 +231,22 @@ u_int32_t aint = 0; return CNID_INVALID; } } -#if AD_VERSION > AD_VERSION1 - else if (adp ) { - /* update the ressource fork - * for a folder adp is always null - */ - if (ad_setid(adp, st->st_dev, st->st_ino, aint, did, vol->v_stamp)) { + else if (adp && (adcnid != dbcnid)) { + /* Update the ressource fork. For a folder adp is always null */ + LOG(log_debug, logtype_afpd, "get_id: calling ad_setid. adcnid: %u, dbcnid: %u", htonl(adcnid), htonl(dbcnid)); + if (ad_setid(adp, st->st_dev, st->st_ino, dbcnid, did, vol->v_stamp)) { ad_flush(adp); } } -#endif } - return aint; + return dbcnid; } /* -------------------------- */ int getmetadata(struct vol *vol, u_int16_t bitmap, struct path *path, struct dir *dir, - char *buf, int *buflen, struct adouble *adp) + char *buf, size_t *buflen, struct adouble *adp) { char *data, *l_nameoff = NULL, *upath; char *utf_nameoff = NULL; @@ -252,7 +260,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; @@ -267,7 +275,7 @@ int getmetadata(struct vol *vol, id = get_id(vol, adp, st, dir->d_did, upath, strlen(upath)); else id = path->id; - if (id == 0) + if (id == CNID_INVALID) return afp_errno; if (!path->m_name) { path->m_name = utompath(vol, upath, id, utf8_encoding()); @@ -335,7 +343,7 @@ int getmetadata(struct vol *vol, break; case FILPBIT_FINFO : - get_finderinfo(vol, upath, adp, (char *)data); + get_finderinfo(vol, upath, adp, (char *)data,S_ISLNK(st->st_mode)); data += ADEDLEN_FINDERI; break; @@ -510,32 +518,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; 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) { - int flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0; + 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; - } else { - ad_init(&ad, vol->v_adouble, vol->v_ad_options); - adp = &ad; - } - if ( ad_metadata( upath, flags, adp) < 0 ) { + if ( ad_metadata( upath, flags|ADFLAGS_CREATE, adp) < 0 ) { switch (errno) { case EACCES: LOG(log_error, logtype_afpd, "getfilparams(%s): %s: check resource fork permission?", @@ -556,17 +559,14 @@ int getfilparams(struct vol *vol, 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; @@ -577,10 +577,6 @@ int ibuflen _U_, *rbuflen; u_int16_t vid; struct path *s_path; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_createfile:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf++; creatf = (unsigned char) *ibuf++; @@ -634,7 +630,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|ADFLAGS_CREATE, + if ( ad_open( upath, ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF|ADFLAGS_CREATE, openf, 0666, adp) < 0 ) { switch ( errno ) { case EROFS: @@ -682,17 +678,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; @@ -700,10 +689,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; @@ -746,10 +731,6 @@ int ibuflen _U_, *rbuflen; setvoltime(obj, vol ); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_setfilparams:"); -#endif /* DEBUG */ - return( rc ); } @@ -767,7 +748,7 @@ int setfilparams(struct vol *vol, int bit, isad = 1, err = AFP_OK; char *upath; u_char achar, *fdType, xyy[4]; /* uninitialized, OK 310105 */ - u_int16_t ashort, bshort; + u_int16_t ashort, bshort, oshort; u_int32_t aint; u_int32_t upriv; u_int16_t upriv_bit = 0; @@ -785,12 +766,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; @@ -826,6 +806,28 @@ int setfilparams(struct vol *vol, case FILPBIT_FINFO : change_mdate = 1; memcpy(finder_buf, buf, 32 ); + if (memcmp(buf,"slnkrhap",8)==0 && !S_ISLNK(path->st.st_mode)){ + // SLFINFO + int fp; + ssize_t len; + int erc=1; + char buf[PATH_MAX+1]; + if ((fp=open(path->u_name,O_RDONLY))>=0){ + if ((len=read(fp,buf,PATH_MAX+1))){ + if (unlink(path->u_name)==0){ + buf[len]=0; + erc = symlink(buf, path->u_name); + if (!erc) + of_stat(path); + } + } + close(fp); + } + if (erc!=0){ + err=AFPERR_BITMAP; + goto setfilparam_done; + } + } buf += 32; break; case FILPBIT_UNIXPR : @@ -888,16 +890,16 @@ int setfilparams(struct vol *vol, /* second try with adouble open */ - if ( ad_open_metadata( upath, vol_noadouble(vol), O_CREAT, adp) < 0) { + if ( ad_open_metadata( upath, 0, O_CREAT, adp) < 0) { LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error"); /* * For some things, we don't need an adouble header: * - change of modification date * - UNIX privs (Bug-ID #2863424) */ - if ( (f_bitmap & ~(1<vfs->rf_renamefile(vol, src, dst) < 0 ) { + if (vol->vfs->vfs_renamefile(vol, sdir_fd, src, dst) < 0 ) { int err; err = errno; @@ -1054,7 +1051,7 @@ struct adouble *adp; * we know we are on the same device */ if (err) { - unix_rename( dst, src ); + unix_rename(-1, dst, sdir_fd, src ); /* return the first error */ switch ( err) { case ENOENT : @@ -1077,9 +1074,6 @@ struct adouble *adp; ad_flush( adp ); ad_close( adp, ADFLAGS_HF ); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end renamefile:"); -#endif /* DEBUG */ return( AFP_OK ); } @@ -1155,10 +1149,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; @@ -1171,10 +1162,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; @@ -1215,9 +1202,10 @@ int ibuflen _U_, *rbuflen; } denyreadset = (getforkmode(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 || getforkmode(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 ); - ad_close( adp, ADFLAGS_DF |ADFLAGS_HF ); + if (denyreadset) { - return AFPERR_DENYCONF; + retvalue = AFPERR_DENYCONF; + goto copy_exit; } newname = obj->newtmp; @@ -1225,42 +1213,54 @@ int ibuflen _U_, *rbuflen; p = ctoupath( s_vol, curdir, newname ); if (!p) { - return AFPERR_PARAM; - + retvalue = AFPERR_PARAM; + goto copy_exit; } + #ifdef FORCE_UIDGID /* FIXME svid != dvid && dvid's user can't read svid */ #endif if (NULL == ( d_vol = getvolbyvid( dvid )) ) { - return( AFPERR_PARAM ); + retvalue = AFPERR_PARAM; + goto copy_exit; } - if (d_vol->v_flags & AFPVOL_RO) - return AFPERR_VLOCK; + if (d_vol->v_flags & AFPVOL_RO) { + retvalue = AFPERR_VLOCK; + goto copy_exit; + } if (NULL == ( dir = dirlookup( d_vol, ddid )) ) { - return afp_errno; + retvalue = afp_errno; + goto copy_exit; } if (( s_path = cname( d_vol, dir, &ibuf )) == NULL ) { - return get_afp_errno(AFPERR_NOOBJ); + retvalue = get_afp_errno(AFPERR_NOOBJ); + goto copy_exit; } + if ( *s_path->m_name != '\0' ) { - path_error(s_path, AFPERR_PARAM); + retvalue =path_error(s_path, AFPERR_NOOBJ); + goto copy_exit; } /* one of the handful of places that knows about the path type */ if (copy_path_name(d_vol, newname, ibuf) < 0) { - return( AFPERR_PARAM ); + retvalue = AFPERR_PARAM; + goto copy_exit; } /* newname is always only a filename so curdir *is* its * parent folder */ if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) { - return( AFPERR_PARAM ); + retvalue =AFPERR_PARAM; + goto copy_exit; } - if ( (err = copyfile(s_vol, d_vol, p, upath , newname, adp)) < 0 ) { - return err; + + if ( (err = copyfile(s_vol, d_vol, -1, p, upath , newname, adp)) < 0 ) { + retvalue = err; + goto copy_exit; } curdir->offcnt++; @@ -1272,10 +1272,8 @@ int ibuflen _U_, *rbuflen; setvoltime(obj, d_vol ); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_copyfile:"); -#endif /* DEBUG */ - +copy_exit: + ad_close( adp, ADFLAGS_DF |ADFLAGS_HF ); return( retvalue ); } @@ -1286,7 +1284,7 @@ static int copy_all(const int dfd, const void *buf, 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) { @@ -1302,7 +1300,7 @@ static 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; @@ -1382,10 +1380,13 @@ static int copy_fork(int eid, struct adouble *add, struct adouble *ads) * 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, + int sfd, + char *src, + char *dst, + char *newname, + struct adouble *adp) { struct adouble ads, add; int err = 0; @@ -1394,21 +1395,20 @@ struct adouble *adp; int stat_result; struct stat st; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin copyfile:"); -#endif /* DEBUG */ + LOG(log_debug, logtype_afpd, "copyfile(sfd:%d,s:'%s',d:'%s',n:'%s')", + sfd, src, dst, newname); if (adp == NULL) { ad_init(&ads, s_vol->v_adouble, s_vol->v_ad_options); adp = &ads; } - ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options); + adflags = ADFLAGS_DF; if (newname) { adflags |= ADFLAGS_HF; } - if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) { + if (ad_openat(sfd, src, adflags | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) { ret_err = errno; goto done; } @@ -1425,20 +1425,25 @@ struct adouble *adp; st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; } + ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options); 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) { - deletefile(d_vol, dst, 0); + deletefile(d_vol, -1, dst, 0); goto done; } return AFPERR_EXIST; } - /* XXX if the source and the dest don't use the same resource type it's broken - */ + + /* + * 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_fork(ADEID_DFORK, &add, adp); + if ((err = copy_fork(ADEID_DFORK, &add, adp)) == 0) { + err = d_vol->vfs->vfs_copyfile(d_vol, sfd, src, dst); + } } if (err < 0) { @@ -1458,7 +1463,7 @@ struct adouble *adp; } if (ret_err) { - deletefile(d_vol, dst, 0); + deletefile(d_vol, -1, dst, 0); } else if (stat_result == 0) { /* set dest modification date to src date */ @@ -1471,10 +1476,6 @@ struct adouble *adp; */ } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end copyfile:"); -#endif /* DEBUG */ - done: switch ( ret_err ) { case 0: @@ -1521,58 +1522,57 @@ u_int16_t bshort = 0; } return 0; } - -int deletefile( vol, file, checkAttrib ) -const struct vol *vol; -char *file; -int checkAttrib; +/* + * dirfd can be used for unlinkat semantics + */ +int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib) { struct adouble ad; - struct adouble *adp = &ad; + struct adouble *adp = NULL; int adflags, err = AFP_OK; + int meta = 0; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin deletefile:"); -#endif /* DEBUG */ + LOG(log_debug, logtype_afpd, "deletefile('%s')", file); - /* try to open both forks at once */ - adflags = ADFLAGS_DF|ADFLAGS_HF; + ad_init(&ad, vol->v_adouble, vol->v_ad_options); 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 ); + /* we never want to create a resource fork here, we are going to delete it + * moreover sometimes deletefile is called with a no existent file and + * ad_open would create a 0 byte resource fork + */ + if ( ad_metadataat(dirfd, file, ADFLAGS_OPENFORKS, &ad) == 0 ) { if ((err = check_attrib(&ad))) { + ad_close_metadata(&ad); return err; } + meta = 1; } } - 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: - if (adflags == ADFLAGS_DF) - return AFPERR_NOOBJ; - - /* that failed. now try to open just the data fork */ - adflags = ADFLAGS_DF; - continue; - - case EACCES: - adp = NULL; /* maybe it's a file with no write mode for us */ - break; /* was return AFPERR_ACCESS;*/ - case EROFS: - return AFPERR_VLOCK; - default: - return( AFPERR_PARAM ); - } + /* try to open both forks at once */ + adflags = ADFLAGS_DF; + if ( ad_openat(dirfd, file, adflags |ADFLAGS_HF|ADFLAGS_NOHF, O_RDONLY, 0, &ad ) < 0 ) { + switch (errno) { + case ENOENT: + err = AFPERR_NOOBJ; + goto end; + case EACCES: /* maybe it's a file with no write mode for us */ + break; /* was return AFPERR_ACCESS;*/ + case EROFS: + err = AFPERR_VLOCK; + goto end; + default: + err = AFPERR_PARAM; + goto end; } - break; /* from the while */ + } + else { + adp = &ad; } - if (adp && (adflags & ADFLAGS_HF) ) { + if ( adp && ad_reso_fileno( adp ) != -1 ) { /* there's a resource fork */ + 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. @@ -1583,37 +1583,33 @@ int checkAttrib; * FIXME it doesn't work for RFORK open read only and fork open without deny mode */ if (ad_tmplock(&ad, ADEID_RFORK, ADLOCK_WR |ADLOCK_FILELOCK, 0, 0, 0) < 0 ) { - ad_close( &ad, adflags ); - return( AFPERR_BUSY ); + err = AFPERR_BUSY; + goto end; } } 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, dirfd, file)) && !(err = netatalk_unlinkat(dirfd, file )) ) { cnid_t id; - if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) - { + if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) { cnid_delete(vol->v_cdb, id); } } + +end: + if (meta) + ad_close_metadata(&ad); + if (adp) ad_close( &ad, adflags ); /* ad_close removes locks if any */ -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end deletefile:"); -#endif /* DEBUG */ - return err; } /* ------------------------------------ */ /* 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; @@ -1624,10 +1620,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; @@ -1686,9 +1678,6 @@ int ibuflen _U_, *rbuflen; return AFP_OK; } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "ending afp_createid...:"); -#endif /* DEBUG */ return afp_errno; } @@ -1706,9 +1695,7 @@ 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 ) + if ( lstat(de->d_name, &path.st)<0 ) return 0; /* update or add to cnid */ @@ -1753,7 +1740,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir) } /* FIXME use of_statdir ? */ - if (stat(name, &st)) { + if (lstat(name, &st)) { return -1; } @@ -1774,26 +1761,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; @@ -1817,7 +1798,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 */ } @@ -1825,7 +1805,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: @@ -1838,6 +1817,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 */ @@ -1882,18 +1863,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; @@ -1906,10 +1880,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; @@ -1940,7 +1910,7 @@ int ibuflen _U_, *rbuflen; } err = AFP_OK; - if ((movecwd(vol, dir) < 0) || (stat(upath, &st) < 0)) { + if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) { switch (errno) { case EACCES: case EPERM: @@ -1971,10 +1941,6 @@ int ibuflen _U_, *rbuflen; } } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_deleteid:"); -#endif /* DEBUG */ - return err; } @@ -2027,10 +1993,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; @@ -2054,10 +2017,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; @@ -2173,17 +2132,17 @@ int ibuflen _U_, *rbuflen; } /* now, quickly rename the file. we error if we can't. */ - if ((err = renamefile(vol, p, temp, temp, adsp)) != AFP_OK) + if ((err = renamefile(vol, -1, p, temp, temp, adsp)) != AFP_OK) goto err_exchangefile; of_rename(vol, s_of, sdir, spath, curdir, temp); /* rename destination to source */ - if ((err = renamefile(vol, upath, p, spath, addp)) != AFP_OK) + if ((err = renamefile(vol, -1, upath, p, spath, addp)) != AFP_OK) goto err_src_to_tmp; of_rename(vol, d_of, curdir, path->m_name, sdir, spath); /* rename temp to destination */ - if ((err = renamefile(vol, temp, upath, path->m_name, adsp)) != AFP_OK) + if ((err = renamefile(vol, -1, temp, upath, path->m_name, adsp)) != AFP_OK) goto err_dest_to_src; of_rename(vol, s_of, curdir, temp, curdir, path->m_name); @@ -2196,10 +2155,10 @@ int ibuflen _U_, *rbuflen; if (did) { cnid_delete(vol->v_cdb, did); } - if ((did && ( (crossdev && stat( upath, &srcst) < 0) || + if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0)) || - (sid && ( (crossdev && stat(p, &destst) < 0) || + (sid && ( (crossdev && lstat(p, &destst) < 0) || cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0)) ) { switch (errno) { @@ -2261,10 +2220,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; @@ -2272,17 +2227,17 @@ int ibuflen _U_, *rbuflen; * properly. */ err_temp_to_dest: /* rename dest to temp */ - renamefile(vol, upath, temp, temp, adsp); + renamefile(vol, -1, upath, temp, temp, adsp); of_rename(vol, s_of, curdir, upath, curdir, temp); err_dest_to_src: /* rename source back to dest */ - renamefile(vol, p, upath, path->m_name, addp); + renamefile(vol, -1, p, upath, path->m_name, addp); of_rename(vol, d_of, sdir, spath, curdir, path->m_name); err_src_to_tmp: /* rename temp back to source */ - renamefile(vol, temp, p, spath, adsp); + renamefile(vol, -1, temp, p, spath, adsp); of_rename(vol, s_of, curdir, temp, sdir, spath); err_exchangefile: