X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=1e45f19182321f3468357b28170a0077979b5eca;hb=6f3a5b930085e56f39b415f20db02df98dbecfff;hp=6adafe1798d23f29c8d31da16a5a163bc0dac4d5;hpb=be4c7009bc01f39e8b256ff05045871f55df61e1;p=netatalk.git diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 6adafe17..1e45f191 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.104 2006-09-29 09:44:58 didg Exp $ + * $Id: file.c,v 1.130 2010-01-06 14:05:15 franklahm 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" @@ -111,7 +111,7 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a 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. */ @@ -158,7 +158,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); @@ -187,25 +187,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; @@ -221,25 +220,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; @@ -253,7 +249,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; @@ -268,7 +264,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()); @@ -511,32 +507,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?", @@ -557,17 +548,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; @@ -576,13 +564,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++; @@ -613,8 +596,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))) { @@ -638,7 +619,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: @@ -686,17 +667,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; @@ -704,10 +678,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; @@ -750,10 +720,6 @@ int ibuflen _U_, *rbuflen; setvoltime(obj, vol ); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_setfilparams:"); -#endif /* DEBUG */ - return( rc ); } @@ -789,12 +755,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; @@ -892,11 +857,18 @@ int setfilparams(struct vol *vol, /* second try with adouble open */ - if ( ad_open_metadata( upath, vol_noadouble(vol), O_CREAT, adp) < 0) { - /* for some things, we don't need an adouble header */ - if (f_bitmap & ~(1<m_name); @@ -989,7 +961,7 @@ setfilparam_done: } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end setfilparams:"); + LOG(log_debug9, logtype_afpd, "end setfilparams:"); #endif /* DEBUG */ return err; } @@ -1004,15 +976,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 ) { @@ -1043,7 +1012,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; @@ -1075,7 +1044,7 @@ struct adouble *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 ); @@ -1152,10 +1121,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; @@ -1168,10 +1134,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; @@ -1269,21 +1231,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) { @@ -1299,7 +1257,7 @@ 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; @@ -1379,21 +1337,18 @@ 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, + 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) { @@ -1423,7 +1378,7 @@ struct adouble *adp; st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; } - if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) { + 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) { @@ -1432,11 +1387,15 @@ struct adouble *adp; } 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, src, dst); + } } if (err < 0) { @@ -1470,7 +1429,7 @@ struct adouble *adp; } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end copyfile:"); + LOG(log_debug9, logtype_afpd, "end copyfile:"); #endif /* DEBUG */ done: @@ -1520,17 +1479,14 @@ u_int16_t bshort = 0; return 0; } -int deletefile( vol, file, checkAttrib ) -const struct vol *vol; -char *file; -int checkAttrib; +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 */ @@ -1538,7 +1494,11 @@ int checkAttrib; 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 ) { + /* 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_metadata( file, ADFLAGS_OPENFORKS, &ad) == 0 ) { ad_close( &ad, adflags ); if ((err = check_attrib(&ad))) { return err; @@ -1589,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)))) { @@ -1600,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; @@ -1608,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; @@ -1622,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; @@ -1684,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; } @@ -1704,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; @@ -1772,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; @@ -1815,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 */ } @@ -1823,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: @@ -1836,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 */ @@ -1862,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 ); @@ -1878,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; @@ -1902,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; @@ -1967,10 +1900,6 @@ int ibuflen _U_, *rbuflen; } } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_deleteid:"); -#endif /* DEBUG */ - return err; } @@ -2023,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; @@ -2050,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; @@ -2257,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;