X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fadouble%2Fad_attr.c;h=e90b6b8e0268c9ff41dc7c23e14ae5198fe49f87;hb=6f3a5b930085e56f39b415f20db02df98dbecfff;hp=7a4ff2e37b8cd585d065bd6e7bbaddf5fa2ce573;hpb=1ac3841619c70992db91353e1a7cee61c94fbb83;p=netatalk.git diff --git a/libatalk/adouble/ad_attr.c b/libatalk/adouble/ad_attr.c index 7a4ff2e3..e90b6b8e 100644 --- a/libatalk/adouble/ad_attr.c +++ b/libatalk/adouble/ad_attr.c @@ -1,5 +1,5 @@ /* - * $Id: ad_attr.c,v 1.8 2009-06-10 08:37:25 franklahm Exp $ + * $Id: ad_attr.c,v 1.14 2010-01-06 14:05:15 franklahm Exp $ */ #ifdef HAVE_CONFIG_H @@ -20,8 +20,8 @@ */ int ad_getattr(const struct adouble *ad, u_int16_t *attr) { - *attr = 0; u_int16_t fflags; + *attr = 0; if (ad->ad_version == AD_VERSION1) { if (ad_getentryoff(ad, ADEID_FILEI)) { @@ -41,21 +41,15 @@ int ad_getattr(const struct adouble *ad, u_int16_t *attr) else *attr &= htons(~ATTRBIT_INVISIBLE); /* - Although technically correct to check if its a directory because FINDERINFO_ISHARED and - ATTRBIT_MULTIUSER are only valid then, at least 10.4 doesn't mind and sets FINDERINFO_ISHARED - for directories if told so with e.g. SetFile -a M . The check would cause an - out of sync, so I disabled it. + This one is tricky, I actually got it wrong the first time: + for directories bit 1<<1 is ATTRBIT_EXPFLDR and is NOT opaque ! */ -#if 0 - if ( ! (ad->ad_flags & ADFLAGS_DIR) ) { -#endif + if ( ! (ad->ad_adflags & ADFLAGS_DIR)) { if (fflags & htons(FINDERINFO_ISHARED)) *attr |= htons(ATTRBIT_MULTIUSER); else *attr &= htons(~ATTRBIT_MULTIUSER); -#if 0 } -#endif } } #endif @@ -71,11 +65,15 @@ int ad_getattr(const struct adouble *ad, u_int16_t *attr) int ad_setattr(const struct adouble *ad, const u_int16_t attribute) { u_int16_t *fflags; - u_int16_t hostattr; /* we don't save open forks indicator */ u_int16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN); + /* Proactively (10.4 does indeed try to set ATTRBIT_MULTIUSER (=ATTRBIT_EXPFLDR) + for dirs with SetFile -a M ) disable all flags not defined for dirs. */ + if (ad->ad_adflags & ADFLAGS_DIR) + attr &= ~(ATTRBIT_MULTIUSER | ATTRBIT_NOWRITE | ATTRBIT_NOCOPY); + if (ad->ad_version == AD_VERSION1) { if (ad_getentryoff(ad, ADEID_FILEI)) { memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr, @@ -89,23 +87,17 @@ int ad_setattr(const struct adouble *ad, const u_int16_t attribute) /* Now set opaque flags in FinderInfo too */ fflags = (u_int16_t *)ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF; - if (hostattr & htons(ATTRBIT_INVISIBLE)) + if (attr & htons(ATTRBIT_INVISIBLE)) *fflags |= htons(FINDERINFO_INVISIBLE); else *fflags &= htons(~FINDERINFO_INVISIBLE); -/* - See above comment at ad_getattr() -*/ -#if 0 - if ( ! (ad->ad_flags & ADFLAGS_DIR) ) { -#endif - if (hostattr & htons(ATTRBIT_MULTIUSER)) + + /* See above comment in ad_getattr() */ + if (attr & htons(ATTRBIT_MULTIUSER)) { + if ( ! (ad->ad_adflags & ADFLAGS_DIR) ) *fflags |= htons(FINDERINFO_ISHARED); - else + } else *fflags &= htons(~FINDERINFO_ISHARED); -#if 0 - } -#endif } } #endif @@ -122,24 +114,22 @@ int ad_setattr(const struct adouble *ad, const u_int16_t attribute) #if AD_VERSION == AD_VERSION2 int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const u_int32_t id, const cnid_t did, const void *stamp) { - if (adp->ad_flags == AD_VERSION2 && ( adp->ad_options & ADVOL_CACHE) && - ad_getentryoff(adp, ADEID_PRIVDEV) && - sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO) - { + if ((adp->ad_flags == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) { + + /* ad_getid depends on this to detect presence of ALL entries */ + ad_setentrylen( adp, ADEID_PRIVID, sizeof(id)); + memcpy(ad_entry( adp, ADEID_PRIVID ), &id, sizeof(id)); + ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t)); if ((adp->ad_options & ADVOL_NODEV)) { memset(ad_entry( adp, ADEID_PRIVDEV ), 0, sizeof(dev_t)); - } - else { + } else { memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t)); } ad_setentrylen( adp, ADEID_PRIVINO, sizeof(ino_t)); memcpy(ad_entry( adp, ADEID_PRIVINO ), &ino, sizeof(ino_t)); - ad_setentrylen( adp, ADEID_PRIVID, sizeof(id)); - memcpy(ad_entry( adp, ADEID_PRIVID ), &id, sizeof(id)); - ad_setentrylen( adp, ADEID_DID, sizeof(did)); memcpy(ad_entry( adp, ADEID_DID ), &did, sizeof(did)); @@ -163,21 +153,20 @@ u_int32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino * note inode and device are opaques and not in network order * only use the ID if adouble is writable for us. */ - if (adp && ( adp->ad_options & ADVOL_CACHE) && ( adp->ad_md->adf_flags & O_RDWR ) - && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV) - && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO) - && sizeof(temp) == ad_getentrylen(adp,ADEID_PRIVSYN) - && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID) - && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID) + if (adp + && (adp->ad_options & ADVOL_CACHE) + && (adp->ad_md->adf_flags & O_RDWR ) + && (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) /* One check to ensure ALL values are there */ ) { memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t)); memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t)); memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp)); memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t)); - if ( ((adp->ad_options & ADVOL_NODEV) || dev == st_dev) - && ino == st_ino && a_did == did - && !memcmp(stamp, temp, sizeof(temp))) { + if ( ((adp->ad_options & ADVOL_NODEV) || dev == st_dev) + && ino == st_ino + && (!did || a_did == did) + && (memcmp(stamp, temp, sizeof(temp)) == 0) ) { memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint)); return aint; } @@ -190,12 +179,7 @@ u_int32_t ad_forcegetid (struct adouble *adp) { u_int32_t aint = 0; - if (adp && ( adp->ad_options & ADVOL_CACHE) - && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV) - && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO) - && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID) - && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID) - ) { + if (adp && (adp->ad_options & ADVOL_CACHE)) { memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint)); return aint; }