]> arthur.barton.de Git - netatalk.git/blob - bin/ad/ad_set.c
Merge 2-2
[netatalk.git] / bin / ad / ad_set.c
1 /* 
2    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
3    
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.
8  
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.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif /* HAVE_CONFIG_H */
18
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <dirent.h>
28 #include <fcntl.h>
29 #include <ctype.h>
30 #include <pwd.h>
31 #include <grp.h>
32 #include <time.h>
33
34 #include <atalk/adouble.h>
35 #include <atalk/cnid.h>
36 #include "ad.h"
37
38 #define ADv2_DIRNAME ".AppleDouble"
39
40 #define DIR_DOT_OR_DOTDOT(a)                            \
41     ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
42
43 static const char *labels[] = {
44     "none",
45     "grey",
46     "green",
47     "violet",
48     "blue",
49     "yellow",
50     "red",
51     "orange",
52     NULL
53 };
54
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;
60
61 static void usage_set(void)
62 {
63     printf(
64         "Usage: ad set [-t TYPE] [-c CREATOR] [-l label] [-f flags] [-a attributes] file|dir \n\n"
65         "     Color Label:\n"
66         "       none | grey | green | violet | blue | yellow | red | orange\n\n"
67         "     FinderFlags:\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"
72         "       i = Inited (f/d)\n"
73         "       c = Custom icon (f/d)\n"
74         "       t = Stationery (f)\n"
75         "       s = Name locked (f/d)\n"
76         "       b = Bundle (f/d)\n"
77         "       v = Invisible (f/d)\n"
78         "       a = Alias file (f/d)\n\n"
79         "     AFPAttributes:\n"
80         "       y = System (f/d)\n"
81         "       w = No write (f)\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"
89
90         );
91 }
92
93 static void change_type(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_type)
94 {
95     char *FinderInfo;
96
97     if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
98         memcpy(FinderInfo, new_type, 4);
99 }
100
101 static void change_creator(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_creator)
102 {
103     char *FinderInfo;
104
105     if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
106         memcpy(FinderInfo + 4, new_creator, 4);
107
108 }
109
110 static void change_label(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_label)
111 {
112     char *FinderInfo;
113     const char **color = &labels[0];
114     uint16_t FinderFlags;
115     unsigned char color_count = 0;
116
117     if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
118         return;
119
120     while (*color) {
121         if (strcasecmp(*color, new_label) == 0) {
122             /* get flags */
123             memcpy(&FinderFlags, FinderInfo + 8, 2);
124             FinderFlags = ntohs(FinderFlags);
125
126             /* change value */
127             FinderFlags &= ~FINDERINFO_COLOR;
128             FinderFlags |= color_count << 1;
129
130             /* copy it back */
131             FinderFlags = ntohs(FinderFlags);
132             memcpy(FinderInfo + 8, &FinderFlags, 2);
133
134             break;
135         }
136         color++;
137         color_count++;
138     }
139 }
140
141 static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes)
142 {
143     char *FinderInfo;
144     uint16_t AFPattributes;
145
146     ad_getattr(ad, &AFPattributes);
147     AFPattributes = ntohs(AFPattributes);
148
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;
154
155         if (strchr(new_attributes, 'O'))
156             AFPattributes |= ATTRBIT_NOCOPY;
157         if (strchr(new_attributes, 'o'))
158             AFPattributes &= ~ATTRBIT_NOCOPY;
159     }
160
161     if (strchr(new_attributes, 'Y'))
162         AFPattributes |= ATTRBIT_SYSTEM;
163     if (strchr(new_attributes, 'y'))
164         AFPattributes &= ~ATTRBIT_SYSTEM;
165
166     if (strchr(new_attributes, 'P'))
167         AFPattributes |= ATTRBIT_BACKUP;
168     if (strchr(new_attributes, 'p'))
169         AFPattributes &= ~ATTRBIT_BACKUP;
170
171     if (strchr(new_attributes, 'R'))
172         AFPattributes |= ATTRBIT_NORENAME;
173     if (strchr(new_attributes, 'r'))
174         AFPattributes &= ~ATTRBIT_NORENAME;
175
176     if (strchr(new_attributes, 'L'))
177         AFPattributes |= ATTRBIT_NODELETE;
178     if (strchr(new_attributes, 'l'))
179         AFPattributes &= ~ATTRBIT_NODELETE;
180
181     AFPattributes = ntohs(AFPattributes);
182     ad_setattr(ad, AFPattributes);
183 }
184
185 static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_flags)
186 {
187     char *FinderInfo;
188     uint16_t FinderFlags;
189
190     if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
191         return;
192
193     memcpy(&FinderFlags, FinderInfo + 8, 2);
194     FinderFlags = ntohs(FinderFlags);
195
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;
201
202         if (strchr(new_flags, 'N'))
203             FinderFlags |= FINDERINFO_HASNOINITS;
204         if (strchr(new_flags, 'n'))
205             FinderFlags &= ~FINDERINFO_HASNOINITS;
206
207         if (strchr(new_flags, 'T'))
208             FinderFlags |= FINDERINFO_ISSTATIONNERY;
209         if (strchr(new_flags, 't'))
210             FinderFlags &= ~FINDERINFO_ISSTATIONNERY;
211     }
212
213     if (strchr(new_flags, 'D'))
214         FinderFlags |= FINDERINFO_ISONDESK;
215     if (strchr(new_flags, 'd'))
216         FinderFlags &= ~FINDERINFO_ISONDESK;
217
218     if (strchr(new_flags, 'E'))
219         FinderFlags |= FINDERINFO_HIDEEXT;
220     if (strchr(new_flags, 'e'))
221         FinderFlags &= ~FINDERINFO_HIDEEXT;
222
223     if (strchr(new_flags, 'I'))
224         FinderFlags |= FINDERINFO_HASBEENINITED;
225     if (strchr(new_flags, 'i'))
226         FinderFlags &= ~FINDERINFO_HASBEENINITED;
227
228     if (strchr(new_flags, 'C'))
229         FinderFlags |= FINDERINFO_HASCUSTOMICON;
230     if (strchr(new_flags, 'c'))
231         FinderFlags &= ~FINDERINFO_HASCUSTOMICON;
232
233     if (strchr(new_flags, 'S'))
234         FinderFlags |= FINDERINFO_NAMELOCKED;
235     if (strchr(new_flags, 's'))
236         FinderFlags &= ~FINDERINFO_NAMELOCKED;
237
238     if (strchr(new_flags, 'B'))
239         FinderFlags |= FINDERINFO_HASBUNDLE;
240     if (strchr(new_flags, 'b'))
241         FinderFlags &= ~FINDERINFO_HASBUNDLE;
242
243     if (strchr(new_flags, 'V'))
244         FinderFlags |= FINDERINFO_INVISIBLE;
245     if (strchr(new_flags, 'v'))
246         FinderFlags &= ~FINDERINFO_INVISIBLE;
247
248     if (strchr(new_flags, 'A'))
249         FinderFlags |= FINDERINFO_ISALIAS;
250     if (strchr(new_flags, 'a'))
251         FinderFlags &= ~FINDERINFO_ISALIAS;
252
253     FinderFlags = ntohs(FinderFlags);
254     memcpy(FinderInfo + 8, &FinderFlags, 2);
255 }
256
257 int ad_set(int argc, char **argv, AFPObj *obj)
258 {
259     int c, firstarg;
260     afpvol_t vol;
261     struct stat st;
262     int adflags = 0;
263     struct adouble ad;
264
265     while ((c = getopt(argc, argv, ":l:t:c:f:a:")) != -1) {
266         switch(c) {
267         case 'l':
268             new_label = strdup(optarg);
269             break;
270         case 't':
271             new_type = strdup(optarg);
272             break;
273         case 'c':
274             new_creator = strdup(optarg);
275             break;
276         case 'f':
277             new_flags = strdup(optarg);
278             break;
279         case 'a':
280             new_attributes = strdup(optarg);
281             break;
282         case ':':
283         case '?':
284             usage_set();
285             return -1;
286             break;
287         }
288
289     }
290
291     if (argc <= optind)
292         exit(1);
293
294     cnid_init();
295
296     openvol(obj, argv[optind], &vol);
297     if (vol.vol->v_path == NULL)
298         exit(1);
299
300     if (stat(argv[optind], &st) != 0) {
301         perror("stat");
302         exit(1);
303     }
304
305     if (S_ISDIR(st.st_mode))
306         adflags = ADFLAGS_DIR;
307
308     ad_init(&ad, vol.vol);
309
310     if (ad_open(&ad, argv[optind], adflags | ADFLAGS_HF | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666) < 0)
311         goto exit;
312
313     if (new_label)
314         change_label(argv[optind], &vol, &st, &ad, new_label);
315     if (new_type)
316         change_type(argv[optind], &vol, &st, &ad, new_type);
317     if (new_creator)
318         change_creator(argv[optind], &vol, &st, &ad, new_creator);
319     if (new_flags)
320         change_flags(argv[optind], &vol, &st, &ad, new_flags);
321     if (new_attributes)
322         change_attributes(argv[optind], &vol, &st, &ad, new_attributes);
323
324     ad_flush(&ad);
325     ad_close(&ad, ADFLAGS_HF);
326
327 exit:
328     closevol(&vol);
329
330     return 0;
331 }