2 * $Id: ad_attr.c,v 1.8 2009-06-10 08:37:25 franklahm Exp $
7 #endif /* HAVE_CONFIG_H */
10 #include <atalk/adouble.h>
12 #define FILEIOFF_ATTR 14
13 #define AFPFILEIOFF_ATTR 2
17 the "shared" and "invisible" attributes are opaque and stored and
18 retrieved from the FinderFlags. This fixes Bug #2802236:
19 <https://sourceforge.net/tracker/?func=detail&aid=2802236&group_id=8642&atid=108642>
21 int ad_getattr(const struct adouble *ad, u_int16_t *attr)
26 if (ad->ad_version == AD_VERSION1) {
27 if (ad_getentryoff(ad, ADEID_FILEI)) {
28 memcpy(attr, ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR,
32 #if AD_VERSION == AD_VERSION2
33 else if (ad->ad_version == AD_VERSION2) {
34 if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
35 memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, 2);
37 /* Now get opaque flags from FinderInfo */
38 memcpy(&fflags, ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, 2);
39 if (fflags & htons(FINDERINFO_INVISIBLE))
40 *attr |= htons(ATTRBIT_INVISIBLE);
42 *attr &= htons(~ATTRBIT_INVISIBLE);
44 Although technically correct to check if its a directory because FINDERINFO_ISHARED and
45 ATTRBIT_MULTIUSER are only valid then, at least 10.4 doesn't mind and sets FINDERINFO_ISHARED
46 for directories if told so with e.g. SetFile -a M <directory>. The check would cause an
47 out of sync, so I disabled it.
50 if ( ! (ad->ad_flags & ADFLAGS_DIR) ) {
52 if (fflags & htons(FINDERINFO_ISHARED))
53 *attr |= htons(ATTRBIT_MULTIUSER);
55 *attr &= htons(~ATTRBIT_MULTIUSER);
65 *attr |= htons(ad->ad_open_forks);
70 /* ----------------- */
71 int ad_setattr(const struct adouble *ad, const u_int16_t attribute)
76 /* we don't save open forks indicator */
77 u_int16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
79 if (ad->ad_version == AD_VERSION1) {
80 if (ad_getentryoff(ad, ADEID_FILEI)) {
81 memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
85 #if AD_VERSION == AD_VERSION2
86 else if (ad->ad_version == AD_VERSION2) {
87 if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
88 memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr, sizeof(attr));
90 /* Now set opaque flags in FinderInfo too */
91 fflags = (u_int16_t *)ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF;
92 if (hostattr & htons(ATTRBIT_INVISIBLE))
93 *fflags |= htons(FINDERINFO_INVISIBLE);
95 *fflags &= htons(~FINDERINFO_INVISIBLE);
97 See above comment at ad_getattr()
100 if ( ! (ad->ad_flags & ADFLAGS_DIR) ) {
102 if (hostattr & htons(ATTRBIT_MULTIUSER))
103 *fflags |= htons(FINDERINFO_ISHARED);
105 *fflags &= htons(~FINDERINFO_ISHARED);
119 * save file/folder ID in AppleDoubleV2 netatalk private parameters
120 * return 1 if resource fork has been modified
122 #if AD_VERSION == AD_VERSION2
123 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)
125 if (adp->ad_flags == AD_VERSION2 && ( adp->ad_options & ADVOL_CACHE) &&
126 ad_getentryoff(adp, ADEID_PRIVDEV) &&
127 sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO)
129 ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t));
130 if ((adp->ad_options & ADVOL_NODEV)) {
131 memset(ad_entry( adp, ADEID_PRIVDEV ), 0, sizeof(dev_t));
134 memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t));
137 ad_setentrylen( adp, ADEID_PRIVINO, sizeof(ino_t));
138 memcpy(ad_entry( adp, ADEID_PRIVINO ), &ino, sizeof(ino_t));
140 ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
141 memcpy(ad_entry( adp, ADEID_PRIVID ), &id, sizeof(id));
143 ad_setentrylen( adp, ADEID_DID, sizeof(did));
144 memcpy(ad_entry( adp, ADEID_DID ), &did, sizeof(did));
146 ad_setentrylen( adp, ADEID_PRIVSYN, ADEDLEN_PRIVSYN);
147 memcpy(ad_entry( adp, ADEID_PRIVSYN ), stamp, ADEDLEN_PRIVSYN);
153 /* ----------------------------- */
154 u_int32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp)
160 char temp[ADEDLEN_PRIVSYN];
162 /* look in AD v2 header
163 * note inode and device are opaques and not in network order
164 * only use the ID if adouble is writable for us.
166 if (adp && ( adp->ad_options & ADVOL_CACHE) && ( adp->ad_md->adf_flags & O_RDWR )
167 && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
168 && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
169 && sizeof(temp) == ad_getentrylen(adp,ADEID_PRIVSYN)
170 && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
171 && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
173 memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
174 memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t));
175 memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp));
176 memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t));
178 if ( ((adp->ad_options & ADVOL_NODEV) || dev == st_dev)
179 && ino == st_ino && a_did == did
180 && !memcmp(stamp, temp, sizeof(temp))) {
181 memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
188 /* ----------------------------- */
189 u_int32_t ad_forcegetid (struct adouble *adp)
193 if (adp && ( adp->ad_options & ADVOL_CACHE)
194 && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
195 && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
196 && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
197 && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
199 memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
207 * set resource fork filename attribute.
209 int ad_setname(struct adouble *ad, const char *path)
211 if (ad_getentryoff(ad, ADEID_NAME)) {
212 ad_setentrylen( ad, ADEID_NAME, strlen( path ));
213 memcpy(ad_entry( ad, ADEID_NAME ), path, ad_getentrylen( ad, ADEID_NAME ));