X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=9c78b1b2f3f4baaf1ade8e468ab65f584a42ece0;hp=9e77cae3872a1c738459f46d28e3f5d6d73e226d;hb=5eb3b5ac51c8221009041928a5a08c101d2be743;hpb=9b34bfcf9852eb6aaeeff55dca4b14cdf66b2dfd diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 9e77cae3..9c78b1b2 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -252,7 +252,7 @@ restart: } LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.", vol->v_path); - vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL); + vol->v_cdb = cnid_open(vol, "tdb", flags); if (vol->v_cdb) { if (!(vol->v_flags & AFPVOL_TM)) { vol->v_flags |= AFPVOL_RO; @@ -378,6 +378,7 @@ int getmetadata(const AFPObj *obj, ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; + ashort &= ~htons(vol->v_ignattr); #if 0 /* FIXME do we want a visual clue if the file is read only */ @@ -1023,6 +1024,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, ad_getattr(adp, &bshort); oshort = bshort; if ( ntohs( ashort ) & ATTRBIT_SETCLR ) { + ashort &= ~htons(vol->v_ignattr); bshort |= htons( ntohs( ashort ) & ~ATTRBIT_SETCLR ); } else { bshort &= ~ashort; @@ -1527,7 +1529,7 @@ done: WRITE lock on read only file. */ -static int check_attrib(struct adouble *adp) +static int check_attrib(const struct vol *vol, struct adouble *adp) { uint16_t bshort = 0; @@ -1535,10 +1537,10 @@ uint16_t bshort = 0; /* * Does kFPDeleteInhibitBit (bit 8) set? */ - if ((bshort & htons(ATTRBIT_NODELETE))) { + if (!(vol->v_ignattr & ATTRBIT_NODELETE) && (bshort & htons(ATTRBIT_NODELETE))) { return AFPERR_OLOCK; } - if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) { + if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) { return AFPERR_BUSY; } return 0; @@ -1563,7 +1565,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib) * ad_open would create a 0 byte resource fork */ if ( ad_metadataat(dirfd, file, ADFLAGS_CHECK_OF, &ad) == 0 ) { - if ((err = check_attrib(&ad))) { + if ((err = check_attrib(vol, &ad))) { ad_close(&ad, ADFLAGS_HF | ADFLAGS_CHECK_OF); return err; } @@ -1660,7 +1662,7 @@ int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return( AFPERR_PARAM); } - if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) { + if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) { return AFPERR_NOOP; } @@ -1799,7 +1801,7 @@ int afp_resolveid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ return( AFPERR_PARAM); } - if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) { + if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) { return AFPERR_NOOP; } @@ -1907,7 +1909,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ return( AFPERR_PARAM); } - if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) { + if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) { return AFPERR_NOOP; } @@ -2207,6 +2209,42 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U } goto err_temp_to_dest; } + + if (AD_META_OPEN(adsp) || AD_META_OPEN(addp)) { + struct adouble adtmp; + bool opened_ads, opened_add; + + ad_init(&adtmp, vol); + ad_init_offsets(&adtmp); + + if (!AD_META_OPEN(adsp)) { + if (ad_open(adsp, p, ADFLAGS_HF) != 0) + return -1; + opened_ads = true; + } + + if (!AD_META_OPEN(addp)) { + if (ad_open(addp, upath, ADFLAGS_HF) != 0) + return -1; + opened_add = true; + } + + if (ad_copy_header(&adtmp, adsp) != 0) + goto err_temp_to_dest; + if (ad_copy_header(adsp, addp) != 0) + goto err_temp_to_dest; + if (ad_copy_header(addp, &adtmp) != 0) + goto err_temp_to_dest; + ad_flush(adsp); + ad_flush(addp); + + if (opened_ads) + ad_close(adsp, ADFLAGS_HF); + if (opened_add) + ad_close(addp, ADFLAGS_HF); + } + + /* FIXME: we should switch ressource fork too */ /* here we need to reopen if crossdev */ if (sid && ad_setid(addp, destst.st_dev, destst.st_ino, sid, sdir->d_did, vol->v_stamp))