X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=cb8a968af09ddf491721b18b6b691f0fa97b62ce;hb=f254fd618b53e97cc5382b23709d4f3de1e70b41;hp=307f6204f02d7155c2c6aa4dfe8293522f53cda1;hpb=42eb54de3f6373cd394fbd6abfb86d85c8dde935;p=netatalk.git diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 307f6204..cb8a968a 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->v_path, vol->v_umask, "tdb", flags, NULL, NULL, NULL, NULL); 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 */ @@ -460,18 +461,23 @@ int getmetadata(const AFPObj *obj, data += sizeof( aint ); break; - case FILPBIT_RFLEN : - if ( adp ) { + case FILPBIT_RFLEN: { + off_t rlen; + if (adp) { if (adp->ad_rlen > 0xffffffff) aint = 0xffffffff; else aint = htonl( adp->ad_rlen); } else { - aint = 0; + rlen = ad_reso_size(path->u_name, 0, NULL); + if (rlen > 0xffffffff) + rlen = 0xffffffff; + aint = htonl(rlen); } memcpy(data, &aint, sizeof( aint )); data += sizeof( aint ); break; + } /* Current client needs ProDOS info block for this file. Use simple heuristic and let the Mac "type" string tell @@ -539,15 +545,18 @@ int getmetadata(const AFPObj *obj, data += sizeof( aint ); break; case FILPBIT_EXTRFLEN: - aint = 0; - if (adp) + if (adp) { aint = htonl(adp->ad_rlen >> 32); - memcpy(data, &aint, sizeof( aint )); - data += sizeof( aint ); - if (adp) + memcpy(data, &aint, sizeof( aint )); + data += sizeof( aint ); aint = htonl(adp->ad_rlen); - memcpy(data, &aint, sizeof( aint )); - data += sizeof( aint ); + memcpy(data, &aint, sizeof( aint )); + data += sizeof( aint ); + } else { + int64_t rlen = hton64(ad_reso_size(path->u_name, 0, NULL)); + memcpy(data, &rlen, sizeof(rlen)); + data += sizeof(rlen); + } break; case FILPBIT_UNIXPR : /* accessmode may change st_mode with ACLs */ @@ -1015,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; @@ -1519,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; @@ -1527,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; @@ -1555,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; } @@ -2199,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))