extattrctl.c revision 86994
159247Srwatson/*-
286429Srwatson * Copyright (c) 1999-2001 Robert N. M. Watson
359247Srwatson * All rights reserved.
459247Srwatson *
586429Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
686429Srwatson *
759247Srwatson * Redistribution and use in source and binary forms, with or without
859247Srwatson * modification, are permitted provided that the following conditions
959247Srwatson * are met:
1059247Srwatson * 1. Redistributions of source code must retain the above copyright
1159247Srwatson *    notice, this list of conditions and the following disclaimer.
1259247Srwatson * 2. Redistributions in binary form must reproduce the above copyright
1359247Srwatson *    notice, this list of conditions and the following disclaimer in the
1459247Srwatson *    documentation and/or other materials provided with the distribution.
1559247Srwatson *
1659247Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1759247Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1859247Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1959247Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2059247Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2159247Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2259247Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2359247Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2459247Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2559247Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2659247Srwatson * SUCH DAMAGE.
2759247Srwatson *
2874275Srwatson * $FreeBSD: head/usr.sbin/extattrctl/extattrctl.c 86994 2001-11-27 18:58:56Z jedgar $
2959247Srwatson */
3059247Srwatson/*
3186429Srwatson * Developed by the TrustedBSD Project.
3286429Srwatson * Support for file system extended attribute.
3359247Srwatson */
3459247Srwatson
3559247Srwatson#include <sys/types.h>
3659247Srwatson#include <sys/uio.h>
3759247Srwatson#include <sys/extattr.h>
3859445Srwatson#include <sys/param.h>
3959445Srwatson#include <sys/mount.h>
4059445Srwatson
4159247Srwatson#include <ufs/ufs/extattr.h>
4259445Srwatson
4374275Srwatson#include <errno.h>
4459247Srwatson#include <fcntl.h>
4574275Srwatson#include <libutil.h>
4659247Srwatson#include <stdio.h>
4759247Srwatson#include <stdlib.h>
4859247Srwatson#include <string.h>
4959247Srwatson#include <unistd.h>
5059247Srwatson
5186994Sjedgarint initattr(int argc, char *argv[]);
5286994Sjedgarlong num_inodes_by_path(char *path);
5386994Sjedgarvoid usage(void);
5459401Srwatson
5559247Srwatsonvoid
5686994Sjedgarusage()
5759247Srwatson{
5859247Srwatson
5959247Srwatson	fprintf(stderr,
6059247Srwatson	    "usage:\n"
6159247Srwatson	    "  extattrctl start [path]\n"
6259247Srwatson	    "  extattrctl stop [path]\n"
6365777Srwatson	    "  extattrctl initattr [-f] [-p path] [attrsize] [attrfile]\n"
6474441Srwatson	    "  extattrctl enable [path] [attrnamespace] [attrname] [attrfile]\n"
6574441Srwatson	    "  extattrctl disable [path] [attrnamespace] [attrname]\n");
6659401Srwatson	exit(-1);
6759247Srwatson}
6859247Srwatson
6959445Srwatsonlong
7059445Srwatsonnum_inodes_by_path(char *path)
7159445Srwatson{
7259445Srwatson	struct statfs	buf;
7359445Srwatson	int	error;
7459445Srwatson
7559445Srwatson	error = statfs(path, &buf);
7659445Srwatson	if (error) {
7759445Srwatson		perror("statfs");
7859445Srwatson		return (-1);
7959445Srwatson	}
8059445Srwatson
8159445Srwatson	return (buf.f_files);
8259445Srwatson}
8359445Srwatson
8459401Srwatsonint
8559401Srwatsoninitattr(int argc, char *argv[])
8659401Srwatson{
8759247Srwatson	struct ufs_extattr_fileheader	uef;
8859445Srwatson	char	*fs_path = NULL;
8959445Srwatson	char	*zero_buf = NULL;
9059445Srwatson	long	loop, num_inodes;
9165767Srwatson	int	ch, i, error, chunksize, overwrite = 0, flags;
9259247Srwatson
9359445Srwatson	optind = 0;
9465777Srwatson	while ((ch = getopt(argc, argv, "fp:r:w:")) != -1)
9559401Srwatson		switch (ch) {
9665777Srwatson		case 'f':
9765767Srwatson			overwrite = 1;
9865767Srwatson			break;
9959401Srwatson		case 'p':
10070003Srwatson			if ((fs_path = strdup(optarg)) == NULL) {
10170003Srwatson				perror("strdup");
10270003Srwatson				return(-1);
10370003Srwatson			}
10459401Srwatson			break;
10559401Srwatson		case '?':
10659401Srwatson		default:
10759401Srwatson			usage();
10859401Srwatson		}
10959401Srwatson
11059401Srwatson	argc -= optind;
11159401Srwatson	argv += optind;
11259401Srwatson
11359401Srwatson	if (argc != 2)
11459247Srwatson		usage();
11559401Srwatson
11665767Srwatson	if (overwrite)
11765767Srwatson		flags = O_CREAT | O_WRONLY;
11865767Srwatson	else
11965767Srwatson		flags = O_CREAT | O_EXCL | O_WRONLY;
12065767Srwatson
12159401Srwatson	error = 0;
12265767Srwatson	if ((i = open(argv[1], flags, 0600)) != -1) {
12359401Srwatson		uef.uef_magic = UFS_EXTATTR_MAGIC;
12459401Srwatson		uef.uef_version = UFS_EXTATTR_VERSION;
12559401Srwatson		uef.uef_size = atoi(argv[0]);
12659401Srwatson		if (write(i, &uef, sizeof(uef)) == -1)
12759401Srwatson			error = -1;
12859445Srwatson		else if (fs_path) {
12986428Srwatson			chunksize = sizeof(struct ufs_extattr_header) +
13086428Srwatson			    uef.uef_size;
13186428Srwatson			zero_buf = (char *) (malloc(chunksize));
13259445Srwatson			if (zero_buf == NULL) {
13359445Srwatson				perror("malloc");
13459445Srwatson				unlink(argv[1]);
13559445Srwatson				return (-1);
13659445Srwatson			}
13786428Srwatson			memset(zero_buf, 0, chunksize);
13859445Srwatson			num_inodes = num_inodes_by_path(fs_path);
13959445Srwatson			for (loop = 0; loop < num_inodes; loop++) {
14065589Srwatson				error = write(i, zero_buf, chunksize);
14165589Srwatson				if (error != chunksize) {
14259445Srwatson					perror("write");
14359445Srwatson					unlink(argv[1]);
14459445Srwatson					return (-1);
14559445Srwatson				}
14659445Srwatson			}
14759401Srwatson		}
14859247Srwatson	}
14965377Srwatson	if (i == -1) {
15065377Srwatson		/* unable to open file */
15159445Srwatson		perror(argv[1]);
15265377Srwatson		return (-1);
15365377Srwatson	}
15465377Srwatson	if (error == -1) {
15565377Srwatson		perror(argv[1]);
15659445Srwatson		unlink(argv[1]);
15759401Srwatson		return (-1);
15859401Srwatson	}
15959247Srwatson
16059401Srwatson	return (0);
16159401Srwatson}
16259401Srwatson
16359401Srwatsonint
16459401Srwatsonmain(int argc, char *argv[])
16559401Srwatson{
16674441Srwatson	int	error = 0, attrnamespace;
16759401Srwatson
16859401Srwatson	if (argc < 2)
16959401Srwatson		usage();
17059401Srwatson
17159247Srwatson	if (!strcmp(argv[1], "start")) {
17259401Srwatson		if (argc != 3)
17359247Srwatson			usage();
17474275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0,
17574275Srwatson		    NULL);
17674275Srwatson		if (error) {
17765377Srwatson			perror("extattrctl start");
17874275Srwatson			return (-1);
17974275Srwatson		}
18059247Srwatson	} else if (!strcmp(argv[1], "stop")) {
18159401Srwatson		if (argc != 3)
18259247Srwatson			usage();
18374275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0,
18474275Srwatson		   NULL);
18574275Srwatson		if (error) {
18665377Srwatson			perror("extattrctl stop");
18774275Srwatson			return (-1);
18874275Srwatson		}
18959247Srwatson	} else if (!strcmp(argv[1], "enable")) {
19074275Srwatson		if (argc != 6)
19159247Srwatson			usage();
19274441Srwatson		error = extattr_string_to_namespace(argv[3], &attrnamespace);
19374275Srwatson		if (error) {
19465377Srwatson			perror("extattrctl enable");
19574275Srwatson			return (-1);
19674275Srwatson		}
19774394Stmm		error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5],
19874441Srwatson		    attrnamespace, argv[4]);
19974275Srwatson		if (error) {
20074275Srwatson			perror("extattrctl enable");
20174275Srwatson			return (-1);
20274275Srwatson		}
20359247Srwatson	} else if (!strcmp(argv[1], "disable")) {
20474275Srwatson		if (argc != 5)
20559247Srwatson			usage();
20674441Srwatson		error = extattr_string_to_namespace(argv[3], &attrnamespace);
20774275Srwatson		if (error) {
20865377Srwatson			perror("extattrctl disable");
20974275Srwatson			return (-1);
21074275Srwatson		}
21174275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL,
21274441Srwatson		    attrnamespace, argv[4]);
21374275Srwatson		if (error) {
21474275Srwatson			perror("extattrctl disable");
21574275Srwatson			return (-1);
21674275Srwatson		}
21759247Srwatson	} else if (!strcmp(argv[1], "initattr")) {
21859401Srwatson		argc -= 2;
21959401Srwatson		argv += 2;
22059401Srwatson		error = initattr(argc, argv);
22174275Srwatson		if (error)
22274275Srwatson			return (-1);
22359401Srwatson	} else
22459247Srwatson		usage();
22586994Sjedgar
22686994Sjedgar	return (0);
22759247Srwatson}
228