2 Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
17 #endif /* HAVE_CONFIG_H */
20 #include <sys/types.h>
34 #include <atalk/adouble.h>
35 #include <atalk/cnid.h>
38 #define ADv2_DIRNAME ".AppleDouble"
40 #define DIR_DOT_OR_DOTDOT(a) \
41 ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
43 static const char *labels[] = {
55 static char *new_label;
56 static char *new_type;
57 static char *new_creator;
58 static char *new_flags;
59 static char *new_attributes;
61 static void usage_set(void)
64 "Usage: ad set [-t TYPE] [-c CREATOR] [-l label] [-f flags] [-a attributes] file|dir \n\n"
66 " none | grey | green | violet | blue | yellow | red | orange\n\n"
68 " d = On Desktop (f/d)\n"
69 " e = Hidden extension (f/d)\n"
70 " m = Shared (can run multiple times) (f)\n"
71 " n = No INIT resources (f)\n"
73 " c = Custom icon (f/d)\n"
74 " t = Stationery (f)\n"
75 " s = Name locked (f/d)\n"
77 " v = Invisible (f/d)\n"
78 " a = Alias file (f/d)\n\n"
82 " p = Needs backup (f/d)\n"
83 " r = No rename (f/d)\n"
84 " l = No delete (f/d)\n"
85 " o = No copy (f)\n\n"
86 " Uppercase letter sets the flag, lowercase removes the flag\n"
87 " f = valid for files\n"
88 " d = valid for directories\n"
93 static void change_type(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_type)
97 if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
98 memcpy(FinderInfo, new_type, 4);
101 static void change_creator(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_creator)
105 if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
106 memcpy(FinderInfo + 4, new_creator, 4);
110 static void change_label(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_label)
113 const char **color = &labels[0];
114 uint16_t FinderFlags;
115 unsigned char color_count = 0;
117 if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
121 if (strcasecmp(*color, new_label) == 0) {
123 memcpy(&FinderFlags, FinderInfo + 8, 2);
124 FinderFlags = ntohs(FinderFlags);
127 FinderFlags &= ~FINDERINFO_COLOR;
128 FinderFlags |= color_count << 1;
131 FinderFlags = ntohs(FinderFlags);
132 memcpy(FinderInfo + 8, &FinderFlags, 2);
141 static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes)
144 uint16_t AFPattributes;
146 ad_getattr(ad, &AFPattributes);
147 AFPattributes = ntohs(AFPattributes);
149 if (S_ISREG(st->st_mode)) {
150 if (strchr(new_attributes, 'W'))
151 AFPattributes |= ATTRBIT_NOWRITE;
152 if (strchr(new_attributes, 'w'))
153 AFPattributes &= ~ATTRBIT_NOWRITE;
155 if (strchr(new_attributes, 'O'))
156 AFPattributes |= ATTRBIT_NOCOPY;
157 if (strchr(new_attributes, 'o'))
158 AFPattributes &= ~ATTRBIT_NOCOPY;
161 if (strchr(new_attributes, 'Y'))
162 AFPattributes |= ATTRBIT_SYSTEM;
163 if (strchr(new_attributes, 'y'))
164 AFPattributes &= ~ATTRBIT_SYSTEM;
166 if (strchr(new_attributes, 'P'))
167 AFPattributes |= ATTRBIT_BACKUP;
168 if (strchr(new_attributes, 'p'))
169 AFPattributes &= ~ATTRBIT_BACKUP;
171 if (strchr(new_attributes, 'R'))
172 AFPattributes |= ATTRBIT_NORENAME;
173 if (strchr(new_attributes, 'r'))
174 AFPattributes &= ~ATTRBIT_NORENAME;
176 if (strchr(new_attributes, 'L'))
177 AFPattributes |= ATTRBIT_NODELETE;
178 if (strchr(new_attributes, 'l'))
179 AFPattributes &= ~ATTRBIT_NODELETE;
181 AFPattributes = ntohs(AFPattributes);
182 ad_setattr(ad, AFPattributes);
185 static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_flags)
188 uint16_t FinderFlags;
190 if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
193 memcpy(&FinderFlags, FinderInfo + 8, 2);
194 FinderFlags = ntohs(FinderFlags);
196 if (S_ISREG(st->st_mode)) {
197 if (strchr(new_flags, 'M'))
198 FinderFlags |= FINDERINFO_ISHARED;
199 if (strchr(new_flags, 'm'))
200 FinderFlags &= ~FINDERINFO_ISHARED;
202 if (strchr(new_flags, 'N'))
203 FinderFlags |= FINDERINFO_HASNOINITS;
204 if (strchr(new_flags, 'n'))
205 FinderFlags &= ~FINDERINFO_HASNOINITS;
207 if (strchr(new_flags, 'T'))
208 FinderFlags |= FINDERINFO_ISSTATIONNERY;
209 if (strchr(new_flags, 't'))
210 FinderFlags &= ~FINDERINFO_ISSTATIONNERY;
213 if (strchr(new_flags, 'D'))
214 FinderFlags |= FINDERINFO_ISONDESK;
215 if (strchr(new_flags, 'd'))
216 FinderFlags &= ~FINDERINFO_ISONDESK;
218 if (strchr(new_flags, 'E'))
219 FinderFlags |= FINDERINFO_HIDEEXT;
220 if (strchr(new_flags, 'e'))
221 FinderFlags &= ~FINDERINFO_HIDEEXT;
223 if (strchr(new_flags, 'I'))
224 FinderFlags |= FINDERINFO_HASBEENINITED;
225 if (strchr(new_flags, 'i'))
226 FinderFlags &= ~FINDERINFO_HASBEENINITED;
228 if (strchr(new_flags, 'C'))
229 FinderFlags |= FINDERINFO_HASCUSTOMICON;
230 if (strchr(new_flags, 'c'))
231 FinderFlags &= ~FINDERINFO_HASCUSTOMICON;
233 if (strchr(new_flags, 'S'))
234 FinderFlags |= FINDERINFO_NAMELOCKED;
235 if (strchr(new_flags, 's'))
236 FinderFlags &= ~FINDERINFO_NAMELOCKED;
238 if (strchr(new_flags, 'B'))
239 FinderFlags |= FINDERINFO_HASBUNDLE;
240 if (strchr(new_flags, 'b'))
241 FinderFlags &= ~FINDERINFO_HASBUNDLE;
243 if (strchr(new_flags, 'V'))
244 FinderFlags |= FINDERINFO_INVISIBLE;
245 if (strchr(new_flags, 'v'))
246 FinderFlags &= ~FINDERINFO_INVISIBLE;
248 if (strchr(new_flags, 'A'))
249 FinderFlags |= FINDERINFO_ISALIAS;
250 if (strchr(new_flags, 'a'))
251 FinderFlags &= ~FINDERINFO_ISALIAS;
253 FinderFlags = ntohs(FinderFlags);
254 memcpy(FinderInfo + 8, &FinderFlags, 2);
257 int ad_set(int argc, char **argv, AFPObj *obj)
265 while ((c = getopt(argc, argv, ":l:t:c:f:a:")) != -1) {
268 new_label = strdup(optarg);
271 new_type = strdup(optarg);
274 new_creator = strdup(optarg);
277 new_flags = strdup(optarg);
280 new_attributes = strdup(optarg);
296 openvol(obj, argv[optind], &vol);
297 if (vol.vol->v_path == NULL)
300 if (stat(argv[optind], &st) != 0) {
305 if (S_ISDIR(st.st_mode))
306 adflags = ADFLAGS_DIR;
308 ad_init(&ad, vol.vol);
310 if (ad_open(&ad, argv[optind], adflags | ADFLAGS_HF | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666) < 0)
314 change_label(argv[optind], &vol, &st, &ad, new_label);
316 change_type(argv[optind], &vol, &st, &ad, new_type);
318 change_creator(argv[optind], &vol, &st, &ad, new_creator);
320 change_flags(argv[optind], &vol, &st, &ad, new_flags);
322 change_attributes(argv[optind], &vol, &st, &ad, new_attributes);
325 ad_close(&ad, ADFLAGS_HF);