X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fofork.c;h=59e9f153041d4da0768055a9f548ada9dd594171;hb=d3dff4ba4b8db3131a16641d35a6554be5fb5160;hp=7c975c38f9ed581702e74827aaaf2c2d863e8ce7;hpb=40ec4cf6aa9f58d91a7b11f562163b0ffb3b86f4;p=netatalk.git diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 7c975c38..59e9f153 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -23,10 +23,12 @@ #include #include #include +#include #include "volume.h" #include "directory.h" #include "fork.h" +#include "desktop.h" /* we need to have a hashed list of oforks (by dev inode) */ #define OFORK_HASHSIZE 64 @@ -389,6 +391,8 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork) struct timeval tv; int adflags = 0; int ret; + struct dir *dir; + bstring forkpath = NULL; adflags = 0; if (ofork->of_flags & AFPFORK_DATA) @@ -405,14 +409,18 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork) } } + dir = dirlookup(ofork->of_vol, ofork->of_did); + if (dir == NULL) { + LOG(log_debug, logtype_afpd, "dirlookup failed for %ju", (uintmax_t)ofork->of_did); + } + + if (dir) { + forkpath = bformat("%s/%s", bdata(dir->d_fullpath), of_name(ofork)); + } + /* Somone has used write_fork, we assume file was changed, register it to file change event api */ - if (ofork->of_flags & AFPFORK_MODIFIED) { - struct dir *dir = dirlookup(ofork->of_vol, ofork->of_did); - if (dir) { - bstring forkpath = bformat("%s/%s", bdata(dir->d_fullpath), of_name(ofork)); - fce_register(FCE_FILE_MODIFY, bdata(forkpath), NULL, fce_file); - bdestroy(forkpath); - } + if ((ofork->of_flags & AFPFORK_MODIFIED) && (forkpath)) { + fce_register(obj, FCE_FILE_MODIFY, bdata(forkpath), NULL); } ad_unlock(ofork->of_ad, ofork->of_refnum, ofork->of_flags & AFPFORK_ERROR ? 0 : 1); @@ -429,12 +437,46 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork) #endif ret = 0; + + /* + * Check for 0 byte size resource forks, delete them. + * Here's the deal: + * (1) the size must be 0 + * (2) the fork must refer to a resource fork + * (3) the refcount must be 1 which means this fork has the last + * reference to the adouble struct and the subsequent + * ad_close() will close the assoiciated fd. + * (4) nobody else has the resource fork open + * + * We only do this for ._ AppleDouble resource forks, not for + * xattr resource forks, because the test-suite then fails several + * tests on Solaris, the reason for that still needs to be + * determined. + */ + if ((ofork->of_ad->ad_rlen == 0) + && (ofork->of_flags & AFPFORK_RSRC) + && (ofork->of_ad->ad_rfp->adf_refcount == 1) + && (ad_openforks(ofork->of_ad, ATTRBIT_DOPEN) == 0)) { + +#ifndef HAVE_EAFD + (void)unlink(ofork->of_ad->ad_ops->ad_path( + mtoupath(ofork->of_vol, + of_name(ofork), + ofork->of_did, + utf8_encoding(obj)), + 0)); +#endif + } + if ( ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD) < 0 ) { ret = -1; } of_dealloc(ofork); + if (forkpath) + bdestroy(forkpath); + return ret; }