extattrctl.c revision 65589
1/*-
2 * Copyright (c) 1999, 2000 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$FreeBSD: head/usr.sbin/extattrctl/extattrctl.c 65589 2000-09-07 20:32:31Z rwatson $
27 */
28/*
29 * TrustedBSD Project - extended attribute support for UFS-like file systems
30 */
31
32#include <sys/types.h>
33#include <sys/uio.h>
34#include <sys/extattr.h>
35#include <sys/param.h>
36#include <sys/mount.h>
37
38#include <ufs/ufs/extattr.h>
39
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <unistd.h>
45
46extern char	*optarg;
47extern int	optind;
48
49void
50usage(void)
51{
52
53	fprintf(stderr,
54	    "usage:\n"
55	    "  extattrctl start [path]\n"
56	    "  extattrctl stop [path]\n"
57	    "  extattrctl initattr [-p path] [attrsize] [attrfile]\n"
58	    "  extattrctl enable [path] [attrname] [attrfile]\n"
59	    "  extattrctl disable [path] [attrname]\n");
60	exit(-1);
61}
62
63long
64num_inodes_by_path(char *path)
65{
66	struct statfs	buf;
67	int	error;
68
69	error = statfs(path, &buf);
70	if (error) {
71		perror("statfs");
72		return (-1);
73	}
74
75	return (buf.f_files);
76}
77
78int
79initattr(int argc, char *argv[])
80{
81	struct ufs_extattr_fileheader	uef;
82	char	*fs_path = NULL;
83	char	*zero_buf = NULL;
84	long	loop, num_inodes;
85	int	ch, i, error, chunksize;
86
87	optind = 0;
88	while ((ch = getopt(argc, argv, "p:r:w:")) != -1)
89		switch (ch) {
90		case 'p':
91			fs_path = strdup(optarg);
92			break;
93		case '?':
94		default:
95			usage();
96		}
97
98	argc -= optind;
99	argv += optind;
100
101	if (argc != 2)
102		usage();
103
104	error = 0;
105	if ((i = open(argv[1], O_CREAT | O_EXCL | O_WRONLY, 0600)) != -1) {
106		uef.uef_magic = UFS_EXTATTR_MAGIC;
107		uef.uef_version = UFS_EXTATTR_VERSION;
108		uef.uef_size = atoi(argv[0]);
109		if (write(i, &uef, sizeof(uef)) == -1)
110			error = -1;
111		else if (fs_path) {
112			zero_buf = (char *) (malloc(uef.uef_size));
113			if (zero_buf == NULL) {
114				perror("malloc");
115				unlink(argv[1]);
116				return (-1);
117			}
118			memset(zero_buf, 0, uef.uef_size);
119			num_inodes = num_inodes_by_path(fs_path);
120			chunksize = sizeof(struct ufs_extattr_header) +
121			    uef.uef_size;
122			for (loop = 0; loop < num_inodes; loop++) {
123				error = write(i, zero_buf, chunksize);
124				if (error != chunksize) {
125					perror("write");
126					unlink(argv[1]);
127					return (-1);
128				}
129			}
130		}
131	}
132	if (i == -1) {
133		/* unable to open file */
134		perror(argv[1]);
135		return (-1);
136	}
137	if (error == -1) {
138		perror(argv[1]);
139		unlink(argv[1]);
140		return (-1);
141	}
142
143	return (0);
144}
145
146int
147main(int argc, char *argv[])
148{
149	int	error = 0;
150
151	if (argc < 2)
152		usage();
153
154	if (!strcmp(argv[1], "start")) {
155		if (argc != 3)
156			usage();
157		error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, 0, 0);
158		if (error)
159			perror("extattrctl start");
160	} else if (!strcmp(argv[1], "stop")) {
161		if (argc != 3)
162			usage();
163		error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, 0, 0);
164		if (error)
165			perror("extattrctl stop");
166	} else if (!strcmp(argv[1], "enable")) {
167		if (argc != 5)
168			usage();
169		error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[3],
170		    argv[4]);
171		if (error)
172			perror("extattrctl enable");
173	} else if (!strcmp(argv[1], "disable")) {
174		if (argc != 4)
175			usage();
176		error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, argv[3],
177		    NULL);
178		if (error)
179			perror("extattrctl disable");
180	} else if (!strcmp(argv[1], "initattr")) {
181		argc -= 2;
182		argv += 2;
183		error = initattr(argc, argv);
184	} else
185		usage();
186	return(error);
187}
188