X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fadouble%2Fad_write.c;h=4ae1cf60adf1cfcbd61907d20a5fc430c1f4d31a;hb=ab6e6f8ed24667ced438afe4df5997469a2ff53b;hp=a142ef00fa47ac954beb6765e164085298b1123d;hpb=cf3e505e21e9c7ffba3a048ced9b772be8301e98;p=netatalk.git diff --git a/libatalk/adouble/ad_write.c b/libatalk/adouble/ad_write.c index a142ef00..4ae1cf60 100644 --- a/libatalk/adouble/ad_write.c +++ b/libatalk/adouble/ad_write.c @@ -52,16 +52,14 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha EC_INIT; struct stat st; ssize_t cc; - size_t roundup; off_t r_off; - if (ad_data_fileno(ad) == -2) { - /* It's a symlink */ + if (ad_data_fileno(ad) == AD_SYMLINK) { errno = EACCES; return -1; } - LOG(log_debug, logtype_default, "ad_write: off: %ju, size: %zu, eabuflen: %zu", + LOG(log_debug, logtype_ad, "ad_write: off: %ju, size: %zu, eabuflen: %zu", (uintmax_t)off, buflen, ad->ad_rlen); if ( eid == ADEID_DFORK ) { @@ -95,7 +93,6 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha return -1; /* we don't know how to write if it's not a ressource or data fork */ } -EC_CLEANUP: if (ret != 0) return ret; return( cc ); @@ -160,22 +157,35 @@ char c = 0; } /* ------------------------ */ -int ad_rtruncate( struct adouble *ad, const off_t size) +int ad_rtruncate(struct adouble *ad, const char *uname, const off_t size) { - if (sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 ) { - LOG(log_error, logtype_default, "sys_ftruncate: %s", strerror(errno)); - return -1; - } + EC_INIT; - ad->ad_rlen = size; + /* + * We can't delete 0 byte size resource forks either, because a + * fork may reference the adouble handle with an open fd for the + * file, which means we would only delete the directory entry, not + * the file. Subsequently all code that works with fork handles + * finds the fork open, so eg flushing a fork (ad_flush()) will + * recreate ._ files. The correct place to delete 0 byte sized + * resource forks is in of_closefork(). + */ - return 0; + EC_NEG1( sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off) ); + + ad->ad_rlen = size; + +EC_CLEANUP: + if (ret != 0) + LOG(log_error, logtype_ad, "ad_rtruncate(\"%s\"): %s", + fullpathname(uname), strerror(errno)); + EC_EXIT; } int ad_dtruncate(struct adouble *ad, const off_t size) { if (sys_ftruncate(ad_data_fileno(ad), size) < 0) { - LOG(log_error, logtype_default, "sys_ftruncate(fd: %d): %s", + LOG(log_error, logtype_ad, "sys_ftruncate(fd: %d): %s", ad_data_fileno(ad), strerror(errno)); return -1; }