extattrctl.c revision 74394
159247Srwatson/*-
274275Srwatson * Copyright (c) 1999, 2000, 2001 Robert N. M. Watson
359247Srwatson * All rights reserved.
459247Srwatson *
559247Srwatson * Redistribution and use in source and binary forms, with or without
659247Srwatson * modification, are permitted provided that the following conditions
759247Srwatson * are met:
859247Srwatson * 1. Redistributions of source code must retain the above copyright
959247Srwatson *    notice, this list of conditions and the following disclaimer.
1059247Srwatson * 2. Redistributions in binary form must reproduce the above copyright
1159247Srwatson *    notice, this list of conditions and the following disclaimer in the
1259247Srwatson *    documentation and/or other materials provided with the distribution.
1359247Srwatson *
1459247Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1559247Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1659247Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1759247Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1859247Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1959247Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2059247Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2159247Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2259247Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2359247Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2459247Srwatson * SUCH DAMAGE.
2559247Srwatson *
2674275Srwatson * $FreeBSD: head/usr.sbin/extattrctl/extattrctl.c 74394 2001-03-17 15:59:59Z tmm $
2759247Srwatson */
2859247Srwatson/*
2959247Srwatson * TrustedBSD Project - extended attribute support for UFS-like file systems
3059247Srwatson */
3159247Srwatson
3259247Srwatson#include <sys/types.h>
3359247Srwatson#include <sys/uio.h>
3459247Srwatson#include <sys/extattr.h>
3559445Srwatson#include <sys/param.h>
3659445Srwatson#include <sys/mount.h>
3759445Srwatson
3859247Srwatson#include <ufs/ufs/extattr.h>
3959445Srwatson
4074275Srwatson#include <errno.h>
4159247Srwatson#include <fcntl.h>
4274275Srwatson#include <libutil.h>
4359247Srwatson#include <stdio.h>
4459247Srwatson#include <stdlib.h>
4559247Srwatson#include <string.h>
4659247Srwatson#include <unistd.h>
4759247Srwatson
4859401Srwatsonextern char	*optarg;
4959401Srwatsonextern int	optind;
5059401Srwatson
5159247Srwatsonvoid
5259247Srwatsonusage(void)
5359247Srwatson{
5459247Srwatson
5559247Srwatson	fprintf(stderr,
5659247Srwatson	    "usage:\n"
5759247Srwatson	    "  extattrctl start [path]\n"
5859247Srwatson	    "  extattrctl stop [path]\n"
5965777Srwatson	    "  extattrctl initattr [-f] [-p path] [attrsize] [attrfile]\n"
6074275Srwatson	    "  extattrctl enable [path] [namespace] [attrname] [attrfile]\n"
6174275Srwatson	    "  extattrctl disable [path] [namespace] [attrname]\n");
6259401Srwatson	exit(-1);
6359247Srwatson}
6459247Srwatson
6559445Srwatsonlong
6659445Srwatsonnum_inodes_by_path(char *path)
6759445Srwatson{
6859445Srwatson	struct statfs	buf;
6959445Srwatson	int	error;
7059445Srwatson
7159445Srwatson	error = statfs(path, &buf);
7259445Srwatson	if (error) {
7359445Srwatson		perror("statfs");
7459445Srwatson		return (-1);
7559445Srwatson	}
7659445Srwatson
7759445Srwatson	return (buf.f_files);
7859445Srwatson}
7959445Srwatson
8059401Srwatsonint
8159401Srwatsoninitattr(int argc, char *argv[])
8259401Srwatson{
8359247Srwatson	struct ufs_extattr_fileheader	uef;
8459445Srwatson	char	*fs_path = NULL;
8559445Srwatson	char	*zero_buf = NULL;
8659445Srwatson	long	loop, num_inodes;
8765767Srwatson	int	ch, i, error, chunksize, overwrite = 0, flags;
8859247Srwatson
8959445Srwatson	optind = 0;
9065777Srwatson	while ((ch = getopt(argc, argv, "fp:r:w:")) != -1)
9159401Srwatson		switch (ch) {
9265777Srwatson		case 'f':
9365767Srwatson			overwrite = 1;
9465767Srwatson			break;
9559401Srwatson		case 'p':
9670003Srwatson			if ((fs_path = strdup(optarg)) == NULL) {
9770003Srwatson				perror("strdup");
9870003Srwatson				return(-1);
9970003Srwatson			}
10059401Srwatson			break;
10159401Srwatson		case '?':
10259401Srwatson		default:
10359401Srwatson			usage();
10459401Srwatson		}
10559401Srwatson
10659401Srwatson	argc -= optind;
10759401Srwatson	argv += optind;
10859401Srwatson
10959401Srwatson	if (argc != 2)
11059247Srwatson		usage();
11159401Srwatson
11265767Srwatson	if (overwrite)
11365767Srwatson		flags = O_CREAT | O_WRONLY;
11465767Srwatson	else
11565767Srwatson		flags = O_CREAT | O_EXCL | O_WRONLY;
11665767Srwatson
11759401Srwatson	error = 0;
11865767Srwatson	if ((i = open(argv[1], flags, 0600)) != -1) {
11959401Srwatson		uef.uef_magic = UFS_EXTATTR_MAGIC;
12059401Srwatson		uef.uef_version = UFS_EXTATTR_VERSION;
12159401Srwatson		uef.uef_size = atoi(argv[0]);
12259401Srwatson		if (write(i, &uef, sizeof(uef)) == -1)
12359401Srwatson			error = -1;
12459445Srwatson		else if (fs_path) {
12559445Srwatson			zero_buf = (char *) (malloc(uef.uef_size));
12659445Srwatson			if (zero_buf == NULL) {
12759445Srwatson				perror("malloc");
12859445Srwatson				unlink(argv[1]);
12959445Srwatson				return (-1);
13059445Srwatson			}
13159445Srwatson			memset(zero_buf, 0, uef.uef_size);
13259445Srwatson			num_inodes = num_inodes_by_path(fs_path);
13365589Srwatson			chunksize = sizeof(struct ufs_extattr_header) +
13465589Srwatson			    uef.uef_size;
13559445Srwatson			for (loop = 0; loop < num_inodes; loop++) {
13665589Srwatson				error = write(i, zero_buf, chunksize);
13765589Srwatson				if (error != chunksize) {
13859445Srwatson					perror("write");
13959445Srwatson					unlink(argv[1]);
14059445Srwatson					return (-1);
14159445Srwatson				}
14259445Srwatson			}
14359401Srwatson		}
14459247Srwatson	}
14565377Srwatson	if (i == -1) {
14665377Srwatson		/* unable to open file */
14759445Srwatson		perror(argv[1]);
14865377Srwatson		return (-1);
14965377Srwatson	}
15065377Srwatson	if (error == -1) {
15165377Srwatson		perror(argv[1]);
15259445Srwatson		unlink(argv[1]);
15359401Srwatson		return (-1);
15459401Srwatson	}
15559247Srwatson
15659401Srwatson	return (0);
15759401Srwatson}
15859401Srwatson
15959401Srwatsonint
16059401Srwatsonmain(int argc, char *argv[])
16159401Srwatson{
16274275Srwatson	int	error = 0, namespace;
16359401Srwatson
16459401Srwatson	if (argc < 2)
16559401Srwatson		usage();
16659401Srwatson
16759247Srwatson	if (!strcmp(argv[1], "start")) {
16859401Srwatson		if (argc != 3)
16959247Srwatson			usage();
17074275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0,
17174275Srwatson		    NULL);
17274275Srwatson		if (error) {
17365377Srwatson			perror("extattrctl start");
17474275Srwatson			return (-1);
17574275Srwatson		}
17674275Srwatson		return (0);
17759247Srwatson	} else if (!strcmp(argv[1], "stop")) {
17859401Srwatson		if (argc != 3)
17959247Srwatson			usage();
18074275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0,
18174275Srwatson		   NULL);
18274275Srwatson		if (error) {
18365377Srwatson			perror("extattrctl stop");
18474275Srwatson			return (-1);
18574275Srwatson		}
18674275Srwatson		return (0);
18759247Srwatson	} else if (!strcmp(argv[1], "enable")) {
18874275Srwatson		if (argc != 6)
18959247Srwatson			usage();
19074275Srwatson		error = extattr_string_to_namespace(argv[3], &namespace);
19174275Srwatson		if (error) {
19265377Srwatson			perror("extattrctl enable");
19374275Srwatson			return (-1);
19474275Srwatson		}
19574394Stmm		error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5],
19674394Stmm		    namespace, argv[4]);
19774275Srwatson		if (error) {
19874275Srwatson			perror("extattrctl enable");
19974275Srwatson			return (-1);
20074275Srwatson		}
20174275Srwatson		return (0);
20259247Srwatson	} else if (!strcmp(argv[1], "disable")) {
20374275Srwatson		if (argc != 5)
20459247Srwatson			usage();
20574275Srwatson		error = extattr_string_to_namespace(argv[3], &namespace);
20674275Srwatson		if (error) {
20765377Srwatson			perror("extattrctl disable");
20874275Srwatson			return (-1);
20974275Srwatson		}
21074275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL,
21174394Stmm		    namespace, argv[4]);
21274275Srwatson		if (error) {
21374275Srwatson			perror("extattrctl disable");
21474275Srwatson			return (-1);
21574275Srwatson		}
21674275Srwatson		return (0);
21759247Srwatson	} else if (!strcmp(argv[1], "initattr")) {
21859401Srwatson		argc -= 2;
21959401Srwatson		argv += 2;
22059401Srwatson		error = initattr(argc, argv);
22174275Srwatson		if (error)
22274275Srwatson			return (-1);
22374275Srwatson		return (0);
22459401Srwatson	} else
22559247Srwatson		usage();
22659247Srwatson}
227