extattrctl.c revision 93928
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 93928 2002-04-06 05:02:54Z des $
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[]);
5288740Srwatsonint showattr(int argc, char *argv[]);
5386994Sjedgarlong num_inodes_by_path(char *path);
5486994Sjedgarvoid usage(void);
5559401Srwatson
5659247Srwatsonvoid
5786994Sjedgarusage()
5859247Srwatson{
5959247Srwatson
6059247Srwatson	fprintf(stderr,
6159247Srwatson	    "usage:\n"
6259247Srwatson	    "  extattrctl start [path]\n"
6359247Srwatson	    "  extattrctl stop [path]\n"
6465777Srwatson	    "  extattrctl initattr [-f] [-p path] [attrsize] [attrfile]\n"
6588740Srwatson	    "  extattrctl showattr [attrfile]\n"
6674441Srwatson	    "  extattrctl enable [path] [attrnamespace] [attrname] [attrfile]\n"
6774441Srwatson	    "  extattrctl disable [path] [attrnamespace] [attrname]\n");
6859401Srwatson	exit(-1);
6959247Srwatson}
7059247Srwatson
7159445Srwatsonlong
7259445Srwatsonnum_inodes_by_path(char *path)
7359445Srwatson{
7459445Srwatson	struct statfs	buf;
7559445Srwatson	int	error;
7659445Srwatson
7759445Srwatson	error = statfs(path, &buf);
7859445Srwatson	if (error) {
7959445Srwatson		perror("statfs");
8059445Srwatson		return (-1);
8159445Srwatson	}
8259445Srwatson
8359445Srwatson	return (buf.f_files);
8459445Srwatson}
8559445Srwatson
8693928Sdesstatic const char zero_buf[8192];
8793928Sdes
8859401Srwatsonint
8959401Srwatsoninitattr(int argc, char *argv[])
9059401Srwatson{
9159247Srwatson	struct ufs_extattr_fileheader	uef;
9259445Srwatson	char	*fs_path = NULL;
9393928Sdes	int	ch, i, error, flags;
9493928Sdes	ssize_t	wlen;
9593928Sdes	size_t	easize;
9659247Srwatson
9793928Sdes	flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
9859445Srwatson	optind = 0;
9965777Srwatson	while ((ch = getopt(argc, argv, "fp:r:w:")) != -1)
10059401Srwatson		switch (ch) {
10165777Srwatson		case 'f':
10293928Sdes			flags &= ~O_EXCL;
10365767Srwatson			break;
10459401Srwatson		case 'p':
10593928Sdes			fs_path = optarg;
10659401Srwatson			break;
10759401Srwatson		case '?':
10859401Srwatson		default:
10959401Srwatson			usage();
11059401Srwatson		}
11159401Srwatson
11259401Srwatson	argc -= optind;
11359401Srwatson	argv += optind;
11459401Srwatson
11559401Srwatson	if (argc != 2)
11659247Srwatson		usage();
11759401Srwatson
11859401Srwatson	error = 0;
11993928Sdes	if ((i = open(argv[1], flags, 0600)) == -1) {
12065377Srwatson		/* unable to open file */
12159445Srwatson		perror(argv[1]);
12265377Srwatson		return (-1);
12365377Srwatson	}
12493928Sdes	uef.uef_magic = UFS_EXTATTR_MAGIC;
12593928Sdes	uef.uef_version = UFS_EXTATTR_VERSION;
12693928Sdes	uef.uef_size = atoi(argv[0]);
12793928Sdes	if (write(i, &uef, sizeof(uef)) == -1)
12893928Sdes		error = -1;
12993928Sdes	else if (fs_path != NULL) {
13093928Sdes		easize = (sizeof uef + uef.uef_size) *
13193928Sdes		    num_inodes_by_path(fs_path);
13293928Sdes		while (easize > 0) {
13393928Sdes			if (easize > sizeof zero_buf)
13493928Sdes				wlen = write(i, zero_buf, sizeof zero_buf);
13593928Sdes			else
13693928Sdes				wlen = write(i, zero_buf, easize);
13793928Sdes			if (wlen == -1) {
13893928Sdes				error = -1;
13993928Sdes				break;
14093928Sdes			}
14193928Sdes			easize -= wlen;
14293928Sdes		}
14393928Sdes	}
14465377Srwatson	if (error == -1) {
14565377Srwatson		perror(argv[1]);
14659445Srwatson		unlink(argv[1]);
14759401Srwatson		return (-1);
14859401Srwatson	}
14959247Srwatson
15059401Srwatson	return (0);
15159401Srwatson}
15259401Srwatson
15359401Srwatsonint
15488740Srwatsonshowattr(int argc, char *argv[])
15588740Srwatson{
15688740Srwatson	struct ufs_extattr_fileheader	uef;
15788740Srwatson	int i, fd;
15888740Srwatson
15988740Srwatson	if (argc != 1)
16088740Srwatson		usage();
16188740Srwatson
16288740Srwatson	fd = open(argv[0], O_RDONLY);
16388740Srwatson	if (fd == -1) {
16488740Srwatson		perror(argv[0]);
16588740Srwatson		return (-1);
16688740Srwatson	}
16788740Srwatson
16888740Srwatson	i = read(fd, &uef, sizeof(uef));
16988740Srwatson	if (i == -1) {
17088740Srwatson		perror(argv[0]);
17188740Srwatson		return (-1);
17288740Srwatson	}
17388740Srwatson	if (i != sizeof(uef)) {
17488740Srwatson		fprintf(stderr, "%s: invalid file header\n", argv[0]);
17588740Srwatson		return (-1);
17688740Srwatson	}
17788740Srwatson
17888740Srwatson	if (uef.uef_magic != UFS_EXTATTR_MAGIC) {
17988740Srwatson		fprintf(stderr, "%s: bad magic\n", argv[0]);
18088740Srwatson		return (-1);
18188740Srwatson	}
18288740Srwatson
18388740Srwatson	printf("%s: version %d, size %d\n", argv[0], uef.uef_version,
18488740Srwatson	    uef.uef_size);
18588740Srwatson
18688740Srwatson	return (0);
18788740Srwatson}
18888740Srwatson
18988740Srwatsonint
19059401Srwatsonmain(int argc, char *argv[])
19159401Srwatson{
19274441Srwatson	int	error = 0, attrnamespace;
19359401Srwatson
19459401Srwatson	if (argc < 2)
19559401Srwatson		usage();
19659401Srwatson
19759247Srwatson	if (!strcmp(argv[1], "start")) {
19859401Srwatson		if (argc != 3)
19959247Srwatson			usage();
20074275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0,
20174275Srwatson		    NULL);
20274275Srwatson		if (error) {
20365377Srwatson			perror("extattrctl start");
20474275Srwatson			return (-1);
20574275Srwatson		}
20659247Srwatson	} else if (!strcmp(argv[1], "stop")) {
20759401Srwatson		if (argc != 3)
20859247Srwatson			usage();
20974275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0,
21074275Srwatson		   NULL);
21174275Srwatson		if (error) {
21265377Srwatson			perror("extattrctl stop");
21374275Srwatson			return (-1);
21474275Srwatson		}
21559247Srwatson	} else if (!strcmp(argv[1], "enable")) {
21674275Srwatson		if (argc != 6)
21759247Srwatson			usage();
21874441Srwatson		error = extattr_string_to_namespace(argv[3], &attrnamespace);
21974275Srwatson		if (error) {
22065377Srwatson			perror("extattrctl enable");
22174275Srwatson			return (-1);
22274275Srwatson		}
22374394Stmm		error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5],
22474441Srwatson		    attrnamespace, argv[4]);
22574275Srwatson		if (error) {
22674275Srwatson			perror("extattrctl enable");
22774275Srwatson			return (-1);
22874275Srwatson		}
22959247Srwatson	} else if (!strcmp(argv[1], "disable")) {
23074275Srwatson		if (argc != 5)
23159247Srwatson			usage();
23274441Srwatson		error = extattr_string_to_namespace(argv[3], &attrnamespace);
23374275Srwatson		if (error) {
23465377Srwatson			perror("extattrctl disable");
23574275Srwatson			return (-1);
23674275Srwatson		}
23774275Srwatson		error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL,
23874441Srwatson		    attrnamespace, argv[4]);
23974275Srwatson		if (error) {
24074275Srwatson			perror("extattrctl disable");
24174275Srwatson			return (-1);
24274275Srwatson		}
24359247Srwatson	} else if (!strcmp(argv[1], "initattr")) {
24459401Srwatson		argc -= 2;
24559401Srwatson		argv += 2;
24659401Srwatson		error = initattr(argc, argv);
24774275Srwatson		if (error)
24874275Srwatson			return (-1);
24988740Srwatson	} else if (!strcmp(argv[1], "showattr")) {
25088740Srwatson		argc -= 2;
25188740Srwatson		argv += 2;
25288740Srwatson		error = showattr(argc, argv);
25388740Srwatson		if (error)
25488740Srwatson			return (-1);
25559401Srwatson	} else
25659247Srwatson		usage();
25786994Sjedgar
25886994Sjedgar	return (0);
25959247Srwatson}
260