Imported Upstream version 2.4.46
[platform/upstream/attr.git] / attr / attr.c
1 /*
2  * Copyright (c) 2000-2002,2004 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/stat.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <locale.h>
29
30 #include <attr/attributes.h>
31 #include "config.h"
32
33 #define SETOP           1               /* do a SET operation */
34 #define GETOP           2               /* do a GET operation */
35 #define REMOVEOP        3               /* do a REMOVE operation */
36 #define LISTOP          4               /* do a LIST operation */
37
38 #define BUFSIZE         (60*1024)       /* buffer size for LIST operations */
39
40 static char *progname;
41
42 void
43 usage(void)
44 {
45         fprintf(stderr, _(
46 "Usage: %s [-LRSq] -s attrname [-V attrvalue] pathname  # set value\n"
47 "       %s [-LRSq] -g attrname pathname                 # get value\n"
48 "       %s [-LRSq] -r attrname pathname                 # remove attr\n"
49 "       %s [-LRq]  -l pathname                          # list attrs \n"
50 "      -s reads a value from stdin and -g writes a value to stdout\n"),
51                 progname, progname, progname, progname);
52         exit(1);
53 }
54
55 int
56 main(int argc, char **argv)
57 {
58         char *attrname, *attrvalue, *filename, *buffer;
59         int attrlength, attrflags;
60         int opflag, i, ch, error, follow, verbose, rootflag, secureflag;
61         attrlist_t *alist;
62         attrlist_ent_t *aep;
63         attrlist_cursor_t cursor;
64
65         progname = basename(argv[0]);
66
67         setlocale(LC_CTYPE, "");
68         setlocale(LC_MESSAGES, "");
69         bindtextdomain(PACKAGE, LOCALEDIR);
70         textdomain(PACKAGE);
71
72         /*
73          * Pick up and validate the arguments.
74          */
75         verbose = 1;
76         follow = opflag = rootflag = secureflag = 0;
77         attrname = attrvalue = NULL;
78         while ((ch = getopt(argc, argv, "s:V:g:r:lqLRS")) != EOF) {
79                 switch (ch) {
80                 case 's':
81                         if ((opflag != 0) && (opflag != SETOP)) {
82                                 fprintf(stderr,
83                                   _("Only one of -s, -g, -r, or -l allowed\n"));
84                                 usage();
85                         }
86                         opflag = SETOP;
87                         attrname = optarg;
88                         break;
89                 case 'V':
90                         if ((opflag != 0) && (opflag != SETOP)) {
91                                 fprintf(stderr, _("-V only allowed with -s\n"));
92                                 usage();
93                         }
94                         opflag = SETOP;
95                         attrvalue = optarg;
96                         break;
97                 case 'g':
98                         if (opflag) {
99                                 fprintf(stderr,
100                                   _("Only one of -s, -g, -r, or -l allowed\n"));
101                                 usage();
102                         }
103                         opflag = GETOP;
104                         attrname = optarg;
105                         break;
106                 case 'r':
107                         if (opflag) {
108                                 fprintf(stderr,
109                                   _("Only one of -s, -g, -r, or -l allowed\n"));
110                                 usage();
111                         }
112                         opflag = REMOVEOP;
113                         attrname = optarg;
114                         break;
115                 case 'l':
116                         if (opflag) {
117                                 fprintf(stderr,
118                                   _("Only one of -s, -g, -r, or -l allowed\n"));
119                                 usage();
120                         }
121                         opflag = LISTOP;
122                         break;
123                 case 'L':
124                         follow++;
125                         break;
126                 case 'R':
127                         rootflag++;
128                         break;
129                 case 'S':
130                         secureflag++;
131                         break;
132                 case 'q':
133                         verbose = 0;
134                         break;
135                 default:
136                         fprintf(stderr, _("Unrecognized option: %c\n"),
137                                 (char)ch);
138                         usage();
139                         break;
140                 }
141         }
142         if (optind != argc-1) {
143                 fprintf(stderr, _("A filename to operate on is required\n"));
144                 usage();
145         }
146         filename = argv[optind];
147
148         attrflags = ((!follow ? ATTR_DONTFOLLOW : 0) |
149                      (secureflag ? ATTR_SECURE : 0) |
150                      (rootflag ? ATTR_ROOT : 0));
151         /*
152          * Break out into option-specific processing.
153          */
154         switch (opflag) {
155         case SETOP:
156                 if (attrvalue == NULL) {
157                         attrvalue = malloc(ATTR_MAX_VALUELEN);
158                         if (attrvalue == NULL) {
159                                 perror("malloc");
160                                 exit(1);
161                         }
162                         attrlength =
163                                 fread(attrvalue, 1, ATTR_MAX_VALUELEN, stdin);
164                 } else {
165                         attrlength = strlen(attrvalue);
166                 }
167                 error = attr_set(filename, attrname, attrvalue,
168                                            attrlength, attrflags);
169                 if (error) {
170                         perror("attr_set");
171                         fprintf(stderr, _("Could not set \"%s\" for %s\n"),
172                                         attrname, filename);
173                         exit(1);
174                 }
175                 if (verbose) {
176                         printf(_("Attribute \"%s\" set to a %d byte value "
177                                "for %s:\n"), attrname, attrlength, filename);
178                         fwrite(attrvalue, 1, attrlength, stdout);
179                         printf("\n");
180                 }
181                 break;
182
183         case GETOP:
184                 attrvalue = malloc(ATTR_MAX_VALUELEN);
185                 if (attrvalue == NULL) {
186                         perror("malloc");
187                         exit(1);
188                 }
189                 attrlength = ATTR_MAX_VALUELEN;
190                 error = attr_get(filename, attrname, attrvalue,
191                                            &attrlength, attrflags);
192                 if (error) {
193                         perror("attr_get");
194                         fprintf(stderr, _("Could not get \"%s\" for %s\n"),
195                                         attrname, filename);
196                         exit(1);
197                 }
198                 if (verbose) {
199                         printf(_("Attribute \"%s\" had a %d byte value "
200                                 "for %s:\n"), attrname, attrlength, filename);
201                 }
202                 fwrite(attrvalue, 1, attrlength, stdout);
203                 if (verbose) {
204                         printf("\n");
205                 }
206                 break;
207
208         case REMOVEOP:
209                 error = attr_remove(filename, attrname, attrflags);
210                 if (error) {
211                         perror("attr_remove");
212                         fprintf(stderr, _("Could not remove \"%s\" for %s\n"),
213                                         attrname, filename);
214                         exit(1);
215                 }
216                 break;
217
218         case LISTOP:
219                 if ((buffer = malloc(BUFSIZE)) == NULL) {
220                         perror("malloc");
221                         exit(1);
222                 }
223                 bzero((char *)&cursor, sizeof(cursor));
224                 do {
225                         error = attr_list(filename, buffer, BUFSIZE,
226                                           attrflags, &cursor);
227                         if (error) {
228                                 perror("attr_list");
229                                 fprintf(stderr,
230                                         _("Could not list \"%s\" for %s\n"),
231                                         attrname, filename);
232                                 exit(1);
233                         }
234
235                         alist = (attrlist_t *)buffer;
236                         for (i = 0; i < alist->al_count; i++) {
237                                 aep = (attrlist_ent_t *)&buffer[ alist->al_offset[i] ];
238                                 if (verbose) {
239                                         printf(
240                         _("Attribute \"%s\" has a %d byte value for %s\n"),
241                                                 aep->a_name, aep->a_valuelen,
242                                                 filename);
243                                 } else {
244                                         printf("%s\n", aep->a_name);
245                                 }
246                         }
247                 } while (alist->al_more);
248                 break;
249
250         default:
251                 fprintf(stderr,
252                         _("At least one of -s, -g, -r, or -l is required\n"));
253                 usage();
254                 break;
255         }
256
257         return(0);
258 }