]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/extattrctl/extattrctl.c
This commit was generated by cvs2svn to compensate for changes in r90238,
[FreeBSD/FreeBSD.git] / usr.sbin / extattrctl / extattrctl.c
1 /*-
2  * Copyright (c) 1999-2001 Robert N. M. Watson
3  * All rights reserved.
4  *
5  * This software was developed by Robert Watson for the TrustedBSD Project.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 /*
31  * Developed by the TrustedBSD Project.
32  * Support for file system extended attribute.
33  */
34
35 #include <sys/types.h>
36 #include <sys/uio.h>
37 #include <sys/extattr.h>
38 #include <sys/param.h>
39 #include <sys/mount.h>
40
41 #include <ufs/ufs/extattr.h>
42
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <libutil.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50
51 int initattr(int argc, char *argv[]);
52 int showattr(int argc, char *argv[]);
53 long num_inodes_by_path(char *path);
54 void usage(void);
55
56 void
57 usage()
58 {
59
60         fprintf(stderr,
61             "usage:\n"
62             "  extattrctl start [path]\n"
63             "  extattrctl stop [path]\n"
64             "  extattrctl initattr [-f] [-p path] [attrsize] [attrfile]\n"
65             "  extattrctl showattr [attrfile]\n"
66             "  extattrctl enable [path] [attrnamespace] [attrname] [attrfile]\n"
67             "  extattrctl disable [path] [attrnamespace] [attrname]\n");
68         exit(-1);
69 }
70
71 long
72 num_inodes_by_path(char *path)
73 {
74         struct statfs   buf;
75         int     error;
76
77         error = statfs(path, &buf);
78         if (error) {
79                 perror("statfs");
80                 return (-1);
81         }
82
83         return (buf.f_files);
84 }
85
86 int
87 initattr(int argc, char *argv[])
88 {
89         struct ufs_extattr_fileheader   uef;
90         char    *fs_path = NULL;
91         char    *zero_buf = NULL;
92         long    loop, num_inodes;
93         int     ch, i, error, chunksize, overwrite = 0, flags;
94
95         optind = 0;
96         while ((ch = getopt(argc, argv, "fp:r:w:")) != -1)
97                 switch (ch) {
98                 case 'f':
99                         overwrite = 1;
100                         break;
101                 case 'p':
102                         if ((fs_path = strdup(optarg)) == NULL) {
103                                 perror("strdup");
104                                 return(-1);
105                         }
106                         break;
107                 case '?':
108                 default:
109                         usage();
110                 }
111
112         argc -= optind;
113         argv += optind;
114
115         if (argc != 2)
116                 usage();
117
118         if (overwrite)
119                 flags = O_CREAT | O_WRONLY;
120         else
121                 flags = O_CREAT | O_EXCL | O_WRONLY;
122
123         error = 0;
124         if ((i = open(argv[1], flags, 0600)) != -1) {
125                 uef.uef_magic = UFS_EXTATTR_MAGIC;
126                 uef.uef_version = UFS_EXTATTR_VERSION;
127                 uef.uef_size = atoi(argv[0]);
128                 if (write(i, &uef, sizeof(uef)) == -1)
129                         error = -1;
130                 else if (fs_path) {
131                         chunksize = sizeof(struct ufs_extattr_header) +
132                             uef.uef_size;
133                         zero_buf = (char *) (malloc(chunksize));
134                         if (zero_buf == NULL) {
135                                 perror("malloc");
136                                 unlink(argv[1]);
137                                 return (-1);
138                         }
139                         memset(zero_buf, 0, chunksize);
140                         num_inodes = num_inodes_by_path(fs_path);
141                         for (loop = 0; loop < num_inodes; loop++) {
142                                 error = write(i, zero_buf, chunksize);
143                                 if (error != chunksize) {
144                                         perror("write");
145                                         unlink(argv[1]);
146                                         return (-1);
147                                 }
148                         }
149                 }
150         }
151         if (i == -1) {
152                 /* unable to open file */
153                 perror(argv[1]);
154                 return (-1);
155         }
156         if (error == -1) {
157                 perror(argv[1]);
158                 unlink(argv[1]);
159                 return (-1);
160         }
161
162         return (0);
163 }
164
165 int
166 showattr(int argc, char *argv[])
167 {
168         struct ufs_extattr_fileheader   uef;
169         int i, fd;
170
171         if (argc != 1)
172                 usage();
173
174         fd = open(argv[0], O_RDONLY);
175         if (fd == -1) {
176                 perror(argv[0]);
177                 return (-1);
178         }
179
180         i = read(fd, &uef, sizeof(uef));
181         if (i == -1) {
182                 perror(argv[0]);
183                 return (-1);
184         }
185         if (i != sizeof(uef)) {
186                 fprintf(stderr, "%s: invalid file header\n", argv[0]);
187                 return (-1);
188         }
189
190         if (uef.uef_magic != UFS_EXTATTR_MAGIC) {
191                 fprintf(stderr, "%s: bad magic\n", argv[0]);
192                 return (-1);
193         }
194
195         printf("%s: version %d, size %d\n", argv[0], uef.uef_version,
196             uef.uef_size);
197
198         return (0);
199 }
200
201 int
202 main(int argc, char *argv[])
203 {
204         int     error = 0, attrnamespace;
205
206         if (argc < 2)
207                 usage();
208
209         if (!strcmp(argv[1], "start")) {
210                 if (argc != 3)
211                         usage();
212                 error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0,
213                     NULL);
214                 if (error) {
215                         perror("extattrctl start");
216                         return (-1);
217                 }
218         } else if (!strcmp(argv[1], "stop")) {
219                 if (argc != 3)
220                         usage();
221                 error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0,
222                    NULL);
223                 if (error) {
224                         perror("extattrctl stop");
225                         return (-1);
226                 }
227         } else if (!strcmp(argv[1], "enable")) {
228                 if (argc != 6)
229                         usage();
230                 error = extattr_string_to_namespace(argv[3], &attrnamespace);
231                 if (error) {
232                         perror("extattrctl enable");
233                         return (-1);
234                 }
235                 error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5],
236                     attrnamespace, argv[4]);
237                 if (error) {
238                         perror("extattrctl enable");
239                         return (-1);
240                 }
241         } else if (!strcmp(argv[1], "disable")) {
242                 if (argc != 5)
243                         usage();
244                 error = extattr_string_to_namespace(argv[3], &attrnamespace);
245                 if (error) {
246                         perror("extattrctl disable");
247                         return (-1);
248                 }
249                 error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL,
250                     attrnamespace, argv[4]);
251                 if (error) {
252                         perror("extattrctl disable");
253                         return (-1);
254                 }
255         } else if (!strcmp(argv[1], "initattr")) {
256                 argc -= 2;
257                 argv += 2;
258                 error = initattr(argc, argv);
259                 if (error)
260                         return (-1);
261         } else if (!strcmp(argv[1], "showattr")) {
262                 argc -= 2;
263                 argv += 2;
264                 error = showattr(argc, argv);
265                 if (error)
266                         return (-1);
267         } else
268                 usage();
269
270         return (0);
271 }