• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/netatalk-3.0.5/bin/ad/
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
43static const char *labels[] = {
44    "none",
45    "grey",
46    "green",
47    "violet",
48    "blue",
49    "yellow",
50    "red",
51    "orange",
52    NULL
53};
54
55static char *new_label;
56static char *new_type;
57static char *new_creator;
58static char *new_flags;
59static char *new_attributes;
60
61static 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
93static 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
101static 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
110static 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
141static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes)
142{
143    uint16_t AFPattributes;
144
145    ad_getattr(ad, &AFPattributes);
146    AFPattributes = ntohs(AFPattributes);
147
148    if (S_ISREG(st->st_mode)) {
149        if (strchr(new_attributes, 'W'))
150            AFPattributes |= ATTRBIT_NOWRITE;
151        if (strchr(new_attributes, 'w'))
152            AFPattributes &= ~ATTRBIT_NOWRITE;
153
154        if (strchr(new_attributes, 'O'))
155            AFPattributes |= ATTRBIT_NOCOPY;
156        if (strchr(new_attributes, 'o'))
157            AFPattributes &= ~ATTRBIT_NOCOPY;
158    }
159
160    if (strchr(new_attributes, 'Y'))
161        AFPattributes |= ATTRBIT_SYSTEM;
162    if (strchr(new_attributes, 'y'))
163        AFPattributes &= ~ATTRBIT_SYSTEM;
164
165    if (strchr(new_attributes, 'P'))
166        AFPattributes |= ATTRBIT_BACKUP;
167    if (strchr(new_attributes, 'p'))
168        AFPattributes &= ~ATTRBIT_BACKUP;
169
170    if (strchr(new_attributes, 'R'))
171        AFPattributes |= ATTRBIT_NORENAME;
172    if (strchr(new_attributes, 'r'))
173        AFPattributes &= ~ATTRBIT_NORENAME;
174
175    if (strchr(new_attributes, 'L'))
176        AFPattributes |= ATTRBIT_NODELETE;
177    if (strchr(new_attributes, 'l'))
178        AFPattributes &= ~ATTRBIT_NODELETE;
179
180    AFPattributes = ntohs(AFPattributes);
181    ad_setattr(ad, AFPattributes);
182}
183
184static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_flags)
185{
186    char *FinderInfo;
187    uint16_t FinderFlags;
188
189    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
190        return;
191
192    memcpy(&FinderFlags, FinderInfo + 8, 2);
193    FinderFlags = ntohs(FinderFlags);
194
195    if (S_ISREG(st->st_mode)) {
196        if (strchr(new_flags, 'M'))
197            FinderFlags |= FINDERINFO_ISHARED;
198        if (strchr(new_flags, 'm'))
199            FinderFlags &= ~FINDERINFO_ISHARED;
200
201        if (strchr(new_flags, 'N'))
202            FinderFlags |= FINDERINFO_HASNOINITS;
203        if (strchr(new_flags, 'n'))
204            FinderFlags &= ~FINDERINFO_HASNOINITS;
205
206        if (strchr(new_flags, 'T'))
207            FinderFlags |= FINDERINFO_ISSTATIONNERY;
208        if (strchr(new_flags, 't'))
209            FinderFlags &= ~FINDERINFO_ISSTATIONNERY;
210    }
211
212    if (strchr(new_flags, 'D'))
213        FinderFlags |= FINDERINFO_ISONDESK;
214    if (strchr(new_flags, 'd'))
215        FinderFlags &= ~FINDERINFO_ISONDESK;
216
217    if (strchr(new_flags, 'E'))
218        FinderFlags |= FINDERINFO_HIDEEXT;
219    if (strchr(new_flags, 'e'))
220        FinderFlags &= ~FINDERINFO_HIDEEXT;
221
222    if (strchr(new_flags, 'I'))
223        FinderFlags |= FINDERINFO_HASBEENINITED;
224    if (strchr(new_flags, 'i'))
225        FinderFlags &= ~FINDERINFO_HASBEENINITED;
226
227    if (strchr(new_flags, 'C'))
228        FinderFlags |= FINDERINFO_HASCUSTOMICON;
229    if (strchr(new_flags, 'c'))
230        FinderFlags &= ~FINDERINFO_HASCUSTOMICON;
231
232    if (strchr(new_flags, 'S'))
233        FinderFlags |= FINDERINFO_NAMELOCKED;
234    if (strchr(new_flags, 's'))
235        FinderFlags &= ~FINDERINFO_NAMELOCKED;
236
237    if (strchr(new_flags, 'B'))
238        FinderFlags |= FINDERINFO_HASBUNDLE;
239    if (strchr(new_flags, 'b'))
240        FinderFlags &= ~FINDERINFO_HASBUNDLE;
241
242    if (strchr(new_flags, 'V'))
243        FinderFlags |= FINDERINFO_INVISIBLE;
244    if (strchr(new_flags, 'v'))
245        FinderFlags &= ~FINDERINFO_INVISIBLE;
246
247    if (strchr(new_flags, 'A'))
248        FinderFlags |= FINDERINFO_ISALIAS;
249    if (strchr(new_flags, 'a'))
250        FinderFlags &= ~FINDERINFO_ISALIAS;
251
252    FinderFlags = ntohs(FinderFlags);
253    memcpy(FinderInfo + 8, &FinderFlags, 2);
254}
255
256int ad_set(int argc, char **argv, AFPObj *obj)
257{
258    int c;
259    afpvol_t vol;
260    struct stat st;
261    int adflags = 0;
262    struct adouble ad;
263
264    while ((c = getopt(argc, argv, ":l:t:c:f:a:")) != -1) {
265        switch(c) {
266        case 'l':
267            new_label = strdup(optarg);
268            break;
269        case 't':
270            new_type = strdup(optarg);
271            break;
272        case 'c':
273            new_creator = strdup(optarg);
274            break;
275        case 'f':
276            new_flags = strdup(optarg);
277            break;
278        case 'a':
279            new_attributes = strdup(optarg);
280            break;
281        case ':':
282        case '?':
283            usage_set();
284            return -1;
285            break;
286        }
287
288    }
289
290    if (argc <= optind)
291        exit(1);
292
293    cnid_init();
294
295    openvol(obj, argv[optind], &vol);
296    if (vol.vol->v_path == NULL)
297        exit(1);
298
299    if (stat(argv[optind], &st) != 0) {
300        perror("stat");
301        exit(1);
302    }
303
304    if (S_ISDIR(st.st_mode))
305        adflags = ADFLAGS_DIR;
306
307    ad_init(&ad, vol.vol);
308
309    if (ad_open(&ad, argv[optind], adflags | ADFLAGS_HF | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666) < 0)
310        goto exit;
311
312    if (new_label)
313        change_label(argv[optind], &vol, &st, &ad, new_label);
314    if (new_type)
315        change_type(argv[optind], &vol, &st, &ad, new_type);
316    if (new_creator)
317        change_creator(argv[optind], &vol, &st, &ad, new_creator);
318    if (new_flags)
319        change_flags(argv[optind], &vol, &st, &ad, new_flags);
320    if (new_attributes)
321        change_attributes(argv[optind], &vol, &st, &ad, new_attributes);
322
323    ad_flush(&ad);
324    ad_close(&ad, ADFLAGS_HF);
325
326exit:
327    closevol(&vol);
328
329    return 0;
330}
331