X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=915219f595d11d7ea53876adc269a26a8b484b0b;hp=e08a40682f1ef82aba8fb6e6529d47b36ca79933;hb=2bf71d3ccf20c072bc67a9d075b6ac8b0798021e;hpb=dbf558207127d21596b307d388a90df42d7a218e diff --git a/etc/afpd/file.c b/etc/afpd/file.c index e08a4068..915219f5 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.115 2009-10-15 12:06:07 franklahm Exp $ + * $Id: file.c,v 1.134 2010-02-10 14:05:37 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 @@ -90,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; @@ -115,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 )); @@ -159,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); @@ -188,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; @@ -222,18 +231,15 @@ 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; } /* -------------------------- */ @@ -254,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; @@ -269,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()); @@ -337,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; @@ -515,29 +521,24 @@ int getfilparams(struct vol *vol, 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?", @@ -558,7 +559,7 @@ 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 ); @@ -576,10 +577,6 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, 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++; @@ -633,7 +630,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, 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: @@ -681,10 +678,6 @@ createfile_done: setvoltime(obj, vol ); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_createfile"); -#endif /* DEBUG */ - return (retvalue); } @@ -696,10 +689,6 @@ int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ int did, rc; u_int16_t vid, bitmap; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_setfilparams:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -742,10 +731,6 @@ int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ setvoltime(obj, vol ); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_setfilparams:"); -#endif /* DEBUG */ - return( rc ); } @@ -763,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; @@ -781,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; @@ -822,6 +806,27 @@ 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); + lstat(path->u_name,&(path->st)); + } + } + close(fp); + } + if (erc!=0){ + err=AFPERR_BITMAP; + goto setfilparam_done; + } + } buf += 32; break; case FILPBIT_UNIXPR : @@ -884,7 +889,7 @@ 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: @@ -912,14 +917,14 @@ int setfilparams(struct vol *vol, switch( bit ) { case FILPBIT_ATTR : ad_getattr(adp, &bshort); - if ((bshort & htons(ATTRBIT_INVISIBLE)) != - (ashort & htons(ATTRBIT_INVISIBLE) & htons(ATTRBIT_SETCLR)) ) - change_parent_mdate = 1; + oshort = bshort; if ( ntohs( ashort ) & ATTRBIT_SETCLR ) { bshort |= htons( ntohs( ashort ) & ~ATTRBIT_SETCLR ); } else { bshort &= ~ashort; } + if ((bshort & htons(ATTRBIT_INVISIBLE)) != (oshort & htons(ATTRBIT_INVISIBLE))) + change_parent_mdate = 1; ad_setattr(adp, bshort); break; case FILPBIT_CDATE : @@ -988,7 +993,7 @@ setfilparam_done: } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end setfilparams:"); + LOG(log_debug9, logtype_afpd, "end setfilparams:"); #endif /* DEBUG */ return err; } @@ -1008,7 +1013,7 @@ int renamefile(const struct vol *vol, char *src, char *dst, char *newname, struc 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 ) { @@ -1071,7 +1076,7 @@ int renamefile(const struct vol *vol, char *src, char *dst, char *newname, struc 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 ); @@ -1161,10 +1166,6 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si struct adouble ad, *adp; int denyreadset; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_copyfile:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1262,10 +1263,6 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si setvoltime(obj, d_vol ); -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_copyfile:"); -#endif /* DEBUG */ - return( retvalue ); } @@ -1276,7 +1273,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) { @@ -1292,7 +1289,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; @@ -1383,7 +1380,7 @@ int copyfile(const struct vol *s_vol, const struct vol*d_vol, struct stat st; #ifdef DEBUG - LOG(log_info, logtype_afpd, "begin copyfile:"); + LOG(log_debug9, logtype_afpd, "begin copyfile:"); #endif /* DEBUG */ if (adp == NULL) { @@ -1464,7 +1461,7 @@ int copyfile(const struct vol *s_vol, const struct vol*d_vol, } #ifdef DEBUG - LOG(log_info, logtype_afpd, "end copyfile:"); + LOG(log_debug9, logtype_afpd, "end copyfile:"); #endif /* DEBUG */ done: @@ -1521,7 +1518,7 @@ int deletefile(const struct vol *vol, char *file, int checkAttrib) 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 */ @@ -1529,7 +1526,11 @@ int deletefile(const struct vol *vol, char *file, 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; @@ -1591,7 +1592,7 @@ int deletefile(const struct vol *vol, char *file, 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; @@ -1610,10 +1611,6 @@ int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si u_short vid; struct path *s_path; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_createid:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -1672,9 +1669,6 @@ int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return AFP_OK; } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "ending afp_createid...:"); -#endif /* DEBUG */ return afp_errno; } @@ -1692,9 +1686,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 */ @@ -1739,7 +1731,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,10 +1766,6 @@ int afp_resolveid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, s 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; @@ -1801,7 +1789,6 @@ int afp_resolveid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, s 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 */ } @@ -1809,7 +1796,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: @@ -1822,6 +1808,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 */ @@ -1866,10 +1854,6 @@ 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; } @@ -1887,10 +1871,6 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ 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; @@ -1921,7 +1901,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } 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: @@ -1952,10 +1932,6 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "end afp_deleteid:"); -#endif /* DEBUG */ - return err; } @@ -2032,10 +2008,6 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U uid_t uid; gid_t gid; -#ifdef DEBUG - LOG(log_info, logtype_afpd, "begin afp_exchangefiles:"); -#endif /* DEBUG */ - *rbuflen = 0; ibuf += 2; @@ -2174,10 +2146,10 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U 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) { @@ -2239,10 +2211,6 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U exit(EXITERR_SYS); } -#ifdef DEBUG - LOG(log_info, logtype_afpd, "ending afp_exchangefiles:"); -#endif /* DEBUG */ - err = AFP_OK; goto err_exchangefile;