getextattr.c revision 1.7 1 1.5 manu /* $NetBSD: getextattr.c,v 1.7 2011/07/04 08:07:32 manu Exp $ */
2 1.1 thorpej
3 1.1 thorpej /*-
4 1.1 thorpej * Copyright (c) 2002, 2003 Networks Associates Technology, Inc.
5 1.1 thorpej * Copyright (c) 2002 Poul-Henning Kamp.
6 1.1 thorpej * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
7 1.1 thorpej * All rights reserved.
8 1.1 thorpej *
9 1.1 thorpej * This software was developed for the FreeBSD Project by Poul-Henning
10 1.1 thorpej * Kamp and Network Associates Laboratories, the Security Research Division
11 1.1 thorpej * of Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
12 1.1 thorpej * ("CBOSS"), as part of the DARPA CHATS research program
13 1.1 thorpej *
14 1.1 thorpej * Redistribution and use in source and binary forms, with or without
15 1.1 thorpej * modification, are permitted provided that the following conditions
16 1.1 thorpej * are met:
17 1.1 thorpej * 1. Redistributions of source code must retain the above copyright
18 1.1 thorpej * notice, this list of conditions and the following disclaimer.
19 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright
20 1.1 thorpej * notice, this list of conditions and the following disclaimer in the
21 1.1 thorpej * documentation and/or other materials provided with the distribution.
22 1.1 thorpej * 3. The names of the authors may not be used to endorse or promote
23 1.1 thorpej * products derived from this software without specific prior written
24 1.1 thorpej * permission.
25 1.1 thorpej *
26 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 1.1 thorpej * SUCH DAMAGE.
37 1.1 thorpej *
38 1.1 thorpej * FreeBSD: src/usr.sbin/extattr/rmextattr.c,v 1.6 2003/06/05 04:30:00 rwatson Exp
39 1.1 thorpej */
40 1.1 thorpej
41 1.1 thorpej #include <sys/types.h>
42 1.1 thorpej #include <sys/uio.h>
43 1.1 thorpej #include <sys/extattr.h>
44 1.1 thorpej
45 1.1 thorpej #include <err.h>
46 1.1 thorpej #include <errno.h>
47 1.1 thorpej //#include <libgen.h>
48 1.1 thorpej #include <stdio.h>
49 1.1 thorpej #include <stdlib.h>
50 1.1 thorpej #include <string.h>
51 1.1 thorpej #include <unistd.h>
52 1.1 thorpej #include <vis.h>
53 1.1 thorpej //#include <util.h>
54 1.1 thorpej
55 1.1 thorpej static enum { EADUNNO, EAGET, EASET, EARM, EALS } what = EADUNNO;
56 1.1 thorpej
57 1.1 thorpej static void
58 1.1 thorpej usage(void)
59 1.1 thorpej {
60 1.1 thorpej
61 1.1 thorpej switch (what) {
62 1.1 thorpej case EAGET:
63 1.1 thorpej fprintf(stderr, "usage: %s [-fhqsx] "
64 1.1 thorpej "attrnamespace attrname filename ...\n", getprogname());
65 1.1 thorpej exit(1);
66 1.1 thorpej
67 1.1 thorpej case EASET:
68 1.1 thorpej fprintf(stderr, "usage: %s [-fhnq] "
69 1.1 thorpej "attrnamespace attrname attrvalue filename ...\n",
70 1.1 thorpej getprogname());
71 1.1 thorpej exit(1);
72 1.1 thorpej
73 1.1 thorpej case EARM:
74 1.1 thorpej fprintf(stderr, "usage: %s [-fhq] "
75 1.1 thorpej "attrnamespace attrname filename ...\n", getprogname());
76 1.1 thorpej exit(1);
77 1.1 thorpej
78 1.1 thorpej case EALS:
79 1.1 thorpej fprintf(stderr, "usage: %s [-fhq] "
80 1.1 thorpej "attrnamespace filename ...\n", getprogname());
81 1.1 thorpej exit(1);
82 1.1 thorpej
83 1.1 thorpej case EADUNNO:
84 1.1 thorpej default:
85 1.1 thorpej fprintf(stderr,
86 1.1 thorpej "usage: (getextattr|lsextattr|rmextattr|setextattr)\n");
87 1.1 thorpej exit (1);
88 1.1 thorpej }
89 1.1 thorpej }
90 1.1 thorpej
91 1.1 thorpej static void
92 1.1 thorpej mkbuf(char **buf, int *oldlen, int newlen)
93 1.1 thorpej {
94 1.1 thorpej
95 1.1 thorpej if (*oldlen >= newlen)
96 1.1 thorpej return;
97 1.1 thorpej if (*buf != NULL)
98 1.1 thorpej free(*buf);
99 1.1 thorpej *buf = malloc(newlen);
100 1.1 thorpej if (*buf == NULL)
101 1.1 thorpej err(1, "malloc");
102 1.1 thorpej *oldlen = newlen;
103 1.1 thorpej return;
104 1.1 thorpej }
105 1.1 thorpej
106 1.1 thorpej int
107 1.1 thorpej main(int argc, char *argv[])
108 1.1 thorpej {
109 1.1 thorpej char *buf, *visbuf;
110 1.1 thorpej const char *p;
111 1.1 thorpej
112 1.1 thorpej const char *options, *attrname;
113 1.1 thorpej int buflen, visbuflen, ch, error, i, arg_counter, attrnamespace,
114 1.1 thorpej minargc;
115 1.1 thorpej
116 1.1 thorpej int flag_force = 0;
117 1.1 thorpej int flag_nofollow = 0;
118 1.1 thorpej int flag_null = 0;
119 1.1 thorpej int flag_quiet = 0;
120 1.1 thorpej int flag_string = 0;
121 1.1 thorpej int flag_hex = 0;
122 1.1 thorpej
123 1.2 lukem options = NULL;
124 1.2 lukem minargc = 0;
125 1.1 thorpej visbuflen = buflen = 0;
126 1.1 thorpej visbuf = buf = NULL;
127 1.1 thorpej
128 1.1 thorpej p = getprogname();
129 1.1 thorpej if (strcmp(p, "getextattr") == 0) {
130 1.1 thorpej what = EAGET;
131 1.1 thorpej options = "fhqsx";
132 1.1 thorpej minargc = 3;
133 1.1 thorpej } else if (strcmp(p, "setextattr") == 0) {
134 1.1 thorpej what = EASET;
135 1.1 thorpej options = "fhnq";
136 1.1 thorpej minargc = 4;
137 1.1 thorpej } else if (strcmp(p, "rmextattr") == 0) {
138 1.1 thorpej what = EARM;
139 1.1 thorpej options = "fhq";
140 1.1 thorpej minargc = 3;
141 1.1 thorpej } else if (strcmp(p, "lsextattr") == 0) {
142 1.1 thorpej what = EALS;
143 1.1 thorpej options = "fhq";
144 1.1 thorpej minargc = 2;
145 1.1 thorpej } else
146 1.1 thorpej usage();
147 1.1 thorpej
148 1.1 thorpej while ((ch = getopt(argc, argv, options)) != -1) {
149 1.1 thorpej switch (ch) {
150 1.1 thorpej case 'f':
151 1.1 thorpej flag_force = 1;
152 1.1 thorpej break;
153 1.1 thorpej case 'h':
154 1.1 thorpej flag_nofollow = 1;
155 1.1 thorpej break;
156 1.1 thorpej case 'n':
157 1.1 thorpej flag_null = 1;
158 1.1 thorpej break;
159 1.1 thorpej case 'q':
160 1.1 thorpej flag_quiet = 1;
161 1.1 thorpej break;
162 1.1 thorpej case 's':
163 1.1 thorpej flag_string = 1;
164 1.1 thorpej break;
165 1.1 thorpej case 'x':
166 1.1 thorpej flag_hex = 1;
167 1.1 thorpej break;
168 1.1 thorpej default:
169 1.1 thorpej usage();
170 1.1 thorpej }
171 1.1 thorpej }
172 1.1 thorpej
173 1.1 thorpej argc -= optind;
174 1.1 thorpej argv += optind;
175 1.1 thorpej
176 1.1 thorpej if (argc < minargc)
177 1.1 thorpej usage();
178 1.1 thorpej
179 1.1 thorpej error = extattr_string_to_namespace(argv[0], &attrnamespace);
180 1.1 thorpej if (error)
181 1.4 joerg err(1, "%s", argv[0]);
182 1.1 thorpej argc--; argv++;
183 1.1 thorpej
184 1.1 thorpej if (what != EALS) {
185 1.1 thorpej attrname = argv[0];
186 1.1 thorpej argc--; argv++;
187 1.1 thorpej } else
188 1.1 thorpej attrname = NULL;
189 1.1 thorpej
190 1.1 thorpej if (what == EASET) {
191 1.1 thorpej mkbuf(&buf, &buflen, strlen(argv[0]) + 1);
192 1.3 elad strcpy(buf, argv[0]); /* safe */
193 1.1 thorpej argc--; argv++;
194 1.1 thorpej }
195 1.1 thorpej
196 1.1 thorpej for (arg_counter = 0; arg_counter < argc; arg_counter++) {
197 1.1 thorpej switch (what) {
198 1.1 thorpej case EARM:
199 1.1 thorpej if (flag_nofollow)
200 1.1 thorpej error = extattr_delete_link(argv[arg_counter],
201 1.1 thorpej attrnamespace, attrname);
202 1.1 thorpej else
203 1.1 thorpej error = extattr_delete_file(argv[arg_counter],
204 1.1 thorpej attrnamespace, attrname);
205 1.1 thorpej if (error >= 0)
206 1.1 thorpej continue;
207 1.1 thorpej break;
208 1.1 thorpej case EASET:
209 1.1 thorpej if (flag_nofollow)
210 1.1 thorpej error = extattr_set_link(argv[arg_counter],
211 1.1 thorpej attrnamespace, attrname, buf,
212 1.1 thorpej strlen(buf) + flag_null);
213 1.1 thorpej else
214 1.1 thorpej error = extattr_set_file(argv[arg_counter],
215 1.1 thorpej attrnamespace, attrname, buf,
216 1.1 thorpej strlen(buf) + flag_null);
217 1.1 thorpej if (error >= 0)
218 1.1 thorpej continue;
219 1.1 thorpej break;
220 1.1 thorpej case EALS:
221 1.1 thorpej if (flag_nofollow)
222 1.1 thorpej error = extattr_list_link(argv[arg_counter],
223 1.1 thorpej attrnamespace, NULL, 0);
224 1.1 thorpej else
225 1.1 thorpej error = extattr_list_file(argv[arg_counter],
226 1.1 thorpej attrnamespace, NULL, 0);
227 1.1 thorpej if (error < 0)
228 1.1 thorpej break;
229 1.1 thorpej mkbuf(&buf, &buflen, error);
230 1.1 thorpej if (flag_nofollow)
231 1.1 thorpej error = extattr_list_link(argv[arg_counter],
232 1.1 thorpej attrnamespace, buf, buflen);
233 1.1 thorpej else
234 1.1 thorpej error = extattr_list_file(argv[arg_counter],
235 1.1 thorpej attrnamespace, buf, buflen);
236 1.1 thorpej if (error < 0)
237 1.1 thorpej break;
238 1.1 thorpej if (!flag_quiet)
239 1.1 thorpej printf("%s\t", argv[arg_counter]);
240 1.7 manu for (i = 0; i < error; i += buf[i] + 1)
241 1.7 manu printf("%s%*.*s", i ? "\t" : "",
242 1.7 manu buf[i], buf[i], buf + i + 1);
243 1.1 thorpej printf("\n");
244 1.1 thorpej continue;
245 1.1 thorpej case EAGET:
246 1.1 thorpej if (flag_nofollow)
247 1.1 thorpej error = extattr_get_link(argv[arg_counter],
248 1.1 thorpej attrnamespace, attrname, NULL, 0);
249 1.1 thorpej else
250 1.1 thorpej error = extattr_get_file(argv[arg_counter],
251 1.1 thorpej attrnamespace, attrname, NULL, 0);
252 1.1 thorpej if (error < 0)
253 1.1 thorpej break;
254 1.1 thorpej mkbuf(&buf, &buflen, error);
255 1.1 thorpej if (flag_nofollow)
256 1.1 thorpej error = extattr_get_link(argv[arg_counter],
257 1.1 thorpej attrnamespace, attrname, buf, buflen);
258 1.1 thorpej else
259 1.1 thorpej error = extattr_get_file(argv[arg_counter],
260 1.1 thorpej attrnamespace, attrname, buf, buflen);
261 1.1 thorpej if (error < 0)
262 1.1 thorpej break;
263 1.1 thorpej if (!flag_quiet)
264 1.1 thorpej printf("%s\t", argv[arg_counter]);
265 1.1 thorpej if (flag_string) {
266 1.1 thorpej mkbuf(&visbuf, &visbuflen, error * 4 + 1);
267 1.1 thorpej strvisx(visbuf, buf, error,
268 1.1 thorpej VIS_SAFE | VIS_WHITE);
269 1.1 thorpej printf("\"%s\"\n", visbuf);
270 1.1 thorpej continue;
271 1.1 thorpej } else if (flag_hex) {
272 1.1 thorpej for (i = 0; i < error; i++)
273 1.1 thorpej printf("%s%02x", i ? " " : "",
274 1.1 thorpej buf[i]);
275 1.1 thorpej printf("\n");
276 1.1 thorpej continue;
277 1.1 thorpej } else {
278 1.1 thorpej fwrite(buf, buflen, 1, stdout);
279 1.1 thorpej printf("\n");
280 1.1 thorpej continue;
281 1.1 thorpej }
282 1.1 thorpej default:
283 1.1 thorpej break;
284 1.1 thorpej }
285 1.1 thorpej if (!flag_quiet)
286 1.1 thorpej warn("%s: failed", argv[arg_counter]);
287 1.1 thorpej if (flag_force)
288 1.1 thorpej continue;
289 1.1 thorpej return(1);
290 1.1 thorpej }
291 1.1 thorpej return (0);
292 1.1 thorpej }
293