]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_attr.c
Convert all u_int to ISO uint
[netatalk.git] / libatalk / adouble / ad_attr.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif /* HAVE_CONFIG_H */
4
5 #include <string.h>
6 #include <arpa/inet.h>
7 #include <atalk/adouble.h>
8
9 #define FILEIOFF_ATTR 14
10 #define AFPFILEIOFF_ATTR 2
11
12 /* 
13    Note:
14    the "shared" and "invisible" attributes are opaque and stored and
15    retrieved from the FinderFlags. This fixes Bug #2802236:
16    <https://sourceforge.net/tracker/?func=detail&aid=2802236&group_id=8642&atid=108642>
17  */
18 int ad_getattr(const struct adouble *ad, uint16_t *attr)
19 {
20     uint16_t fflags;
21     *attr = 0;
22
23     if (ad->ad_version == AD_VERSION2) {
24         if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
25             memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, 2);
26
27             /* Now get opaque flags from FinderInfo */
28             memcpy(&fflags, ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, 2);
29             if (fflags & htons(FINDERINFO_INVISIBLE))
30                 *attr |= htons(ATTRBIT_INVISIBLE);
31             else
32                 *attr &= htons(~ATTRBIT_INVISIBLE);
33  /*
34    This one is tricky, I actually got it wrong the first time:
35    for directories bit 1<<1 is ATTRBIT_EXPFLDR and is NOT opaque !
36  */
37             if ( ! (ad->ad_adflags & ADFLAGS_DIR)) {
38                 if (fflags & htons(FINDERINFO_ISHARED))
39                     *attr |= htons(ATTRBIT_MULTIUSER);
40                 else
41                     *attr &= htons(~ATTRBIT_MULTIUSER);
42             }
43         }
44     }
45
46     *attr |= htons(ad->ad_open_forks);
47
48     return 0;
49 }
50
51 /* ----------------- */
52 int ad_setattr(const struct adouble *ad, const uint16_t attribute)
53 {
54     uint16_t fflags;
55
56     /* we don't save open forks indicator */
57     uint16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
58
59     /* Proactively (10.4 does indeed try to set ATTRBIT_MULTIUSER (=ATTRBIT_EXPFLDR)
60        for dirs with SetFile -a M <dir> ) disable all flags not defined for dirs. */
61     if (ad->ad_adflags & ADFLAGS_DIR)
62         attr &= ~(ATTRBIT_MULTIUSER | ATTRBIT_NOWRITE | ATTRBIT_NOCOPY);
63
64     if (ad->ad_version == AD_VERSION2) {
65         if (ad_getentryoff(ad, ADEID_AFPFILEI) && ad_getentryoff(ad, ADEID_FINDERI)) {
66             memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr, sizeof(attr));
67             
68             /* Now set opaque flags in FinderInfo too */
69             memcpy(&fflags, ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, 2);
70             if (attr & htons(ATTRBIT_INVISIBLE))
71                 fflags |= htons(FINDERINFO_INVISIBLE);
72             else
73                 fflags &= htons(~FINDERINFO_INVISIBLE);
74
75             /* See above comment in ad_getattr() */
76             if (attr & htons(ATTRBIT_MULTIUSER)) {
77                 if ( ! (ad->ad_adflags & ADFLAGS_DIR) )
78                     fflags |= htons(FINDERINFO_ISHARED);
79             } else
80                     fflags &= htons(~FINDERINFO_ISHARED);
81
82             memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &fflags, 2);
83         }
84     }
85
86     return 0;
87 }
88
89 /* --------------
90  * save file/folder ID in AppleDoubleV2 netatalk private parameters
91  * return 1 if resource fork has been modified
92  */
93 int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint32_t id, const cnid_t did, const void *stamp)
94 {
95     if ((adp->ad_flags == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) {
96
97         /* ad_getid depends on this to detect presence of ALL entries */
98         ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
99         memcpy(ad_entry( adp, ADEID_PRIVID ), &id, sizeof(id));
100
101         ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t));
102         if ((adp->ad_options & ADVOL_NODEV)) {
103             memset(ad_entry( adp, ADEID_PRIVDEV ), 0, sizeof(dev_t));
104         } else {
105             memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t));
106         }
107
108         ad_setentrylen( adp, ADEID_PRIVINO, sizeof(ino_t));
109         memcpy(ad_entry( adp, ADEID_PRIVINO ), &ino, sizeof(ino_t));
110
111         ad_setentrylen( adp, ADEID_DID, sizeof(did));
112         memcpy(ad_entry( adp, ADEID_DID ), &did, sizeof(did));
113
114         ad_setentrylen( adp, ADEID_PRIVSYN, ADEDLEN_PRIVSYN);
115         memcpy(ad_entry( adp, ADEID_PRIVSYN ), stamp, ADEDLEN_PRIVSYN);
116         return 1;
117     }
118     return 0;
119 }
120
121 /* ----------------------------- */
122 uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp)
123 {
124     uint32_t aint = 0;
125     dev_t  dev;
126     ino_t  ino;
127     cnid_t a_did;
128     char   temp[ADEDLEN_PRIVSYN];
129
130     /* look in AD v2 header
131      * note inode and device are opaques and not in network order
132      * only use the ID if adouble is writable for us.
133      */
134     if (adp
135         && (adp->ad_options & ADVOL_CACHE)
136         && (adp->ad_md->adf_flags & O_RDWR )
137         && (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) /* One check to ensure ALL values are there */
138         ) {
139         memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
140         memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t));
141         memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp));
142         memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t));
143
144         if ( ((adp->ad_options & ADVOL_NODEV) || dev == st_dev)
145              && ino == st_ino
146              && (!did || a_did == did)
147              && (memcmp(stamp, temp, sizeof(temp)) == 0) ) {
148             memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
149             return aint;
150         }
151     }
152     return 0;
153 }
154
155 /* ----------------------------- */
156 uint32_t ad_forcegetid (struct adouble *adp)
157 {
158     uint32_t aint = 0;
159
160     if (adp && (adp->ad_options & ADVOL_CACHE)) {
161         memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
162         return aint;
163     }
164     return 0;
165 }
166
167 /* -----------------
168  * set resource fork filename attribute.
169  */
170 int ad_setname(struct adouble *ad, const char *path)
171 {
172     int len;
173     if ((len = strlen(path)) > ADEDLEN_NAME)
174         len = ADEDLEN_NAME;
175     if (path && ad_getentryoff(ad, ADEID_NAME)) {
176         ad_setentrylen( ad, ADEID_NAME, len);
177         memcpy(ad_entry( ad, ADEID_NAME ), path, len);
178         return 1;
179     }
180     return 0;
181 }