Blame tools/attr.c

Packit 1437d9
/*
Packit 1437d9
 * Copyright (c) 2000-2002,2004 Silicon Graphics, Inc.
Packit 1437d9
 * All Rights Reserved.
Packit 1437d9
 *
Packit 1437d9
 * This program is free software: you can redistribute it and/or modify it
Packit 1437d9
 * under the terms of the GNU General Public License as published by
Packit 1437d9
 * the Free Software Foundation, either version 2 of the License, or
Packit 1437d9
 * (at your option) any later version.
Packit 1437d9
 *
Packit 1437d9
 * This program is distributed in the hope that it will be useful,
Packit 1437d9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1437d9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 1437d9
 * GNU General Public License for more details.
Packit 1437d9
 *
Packit 1437d9
 * You should have received a copy of the GNU General Public License
Packit 1437d9
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 1437d9
 */
Packit 1437d9
Packit 1437d9
#include "config.h"
Packit 1437d9
Packit 1437d9
#include <sys/types.h>
Packit 1437d9
#include <sys/param.h>
Packit 1437d9
#include <sys/stat.h>
Packit 1437d9
#include <stdio.h>
Packit 1437d9
#include <fcntl.h>
Packit 1437d9
#include <stdlib.h>
Packit 1437d9
#include <unistd.h>
Packit 1437d9
#include <errno.h>
Packit 1437d9
#include <string.h>
Packit 1437d9
#include <locale.h>
Packit 1437d9
Packit 1437d9
#include <attr/attributes.h>
Packit 1437d9
Packit 1437d9
#include "misc.h"
Packit 1437d9
Packit 1437d9
#define	SETOP		1		/* do a SET operation */
Packit 1437d9
#define	GETOP		2		/* do a GET operation */
Packit 1437d9
#define	REMOVEOP	3		/* do a REMOVE operation */
Packit 1437d9
#define	LISTOP		4		/* do a LIST operation */
Packit 1437d9
Packit 1437d9
#define	BUFSIZE		(60*1024)	/* buffer size for LIST operations */
Packit 1437d9
Packit 1437d9
static char *progname;
Packit 1437d9
Packit 1437d9
void
Packit 1437d9
usage(void)
Packit 1437d9
{
Packit 1437d9
	fprintf(stderr, _(
Packit 1437d9
"Usage: %s [-LRSq] -s attrname [-V attrvalue] pathname  # set value\n"
Packit 1437d9
"       %s [-LRSq] -g attrname pathname                 # get value\n"
Packit 1437d9
"       %s [-LRSq] -r attrname pathname                 # remove attr\n"
Packit 1437d9
"       %s [-LRq]  -l pathname                          # list attrs \n"
Packit 1437d9
"      -s reads a value from stdin and -g writes a value to stdout\n"),
Packit 1437d9
		progname, progname, progname, progname);
Packit 1437d9
	exit(1);
Packit 1437d9
}
Packit 1437d9
Packit 1437d9
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Packit 1437d9
int
Packit 1437d9
main(int argc, char **argv)
Packit 1437d9
{
Packit 1437d9
	char *attrname, *attrvalue, *filename, *buffer;
Packit 1437d9
	int attrlength, attrflags;
Packit 1437d9
	int opflag, i, ch, error, follow, verbose, rootflag, secureflag;
Packit 1437d9
	attrlist_t *alist;
Packit 1437d9
	attrlist_ent_t *aep;
Packit 1437d9
	attrlist_cursor_t cursor;
Packit 1437d9
Packit 1437d9
	progname = basename(argv[0]);
Packit 1437d9
Packit 1437d9
	setlocale(LC_CTYPE, "");
Packit 1437d9
	setlocale(LC_MESSAGES, "");
Packit 1437d9
	bindtextdomain(PACKAGE, LOCALEDIR);
Packit 1437d9
	textdomain(PACKAGE);
Packit 1437d9
Packit 1437d9
	/*
Packit 1437d9
	 * Pick up and validate the arguments.
Packit 1437d9
	 */
Packit 1437d9
	verbose = 1;
Packit 1437d9
	follow = opflag = rootflag = secureflag = 0;
Packit 1437d9
	attrname = attrvalue = NULL;
Packit 1437d9
	while ((ch = getopt(argc, argv, "s:V:g:r:lqLRS")) != EOF) {
Packit 1437d9
		switch (ch) {
Packit 1437d9
		case 's':
Packit 1437d9
			if ((opflag != 0) && (opflag != SETOP)) {
Packit 1437d9
				fprintf(stderr,
Packit 1437d9
				  _("Only one of -s, -g, -r, or -l allowed\n"));
Packit 1437d9
				usage();
Packit 1437d9
			}
Packit 1437d9
			opflag = SETOP;
Packit 1437d9
			attrname = optarg;
Packit 1437d9
			break;
Packit 1437d9
		case 'V':
Packit 1437d9
			if ((opflag != 0) && (opflag != SETOP)) {
Packit 1437d9
				fprintf(stderr, _("-V only allowed with -s\n"));
Packit 1437d9
				usage();
Packit 1437d9
			}
Packit 1437d9
			opflag = SETOP;
Packit 1437d9
			attrvalue = optarg;
Packit 1437d9
			break;
Packit 1437d9
		case 'g':
Packit 1437d9
			if (opflag) {
Packit 1437d9
				fprintf(stderr,
Packit 1437d9
				  _("Only one of -s, -g, -r, or -l allowed\n"));
Packit 1437d9
				usage();
Packit 1437d9
			}
Packit 1437d9
			opflag = GETOP;
Packit 1437d9
			attrname = optarg;
Packit 1437d9
			break;
Packit 1437d9
		case 'r':
Packit 1437d9
			if (opflag) {
Packit 1437d9
				fprintf(stderr,
Packit 1437d9
				  _("Only one of -s, -g, -r, or -l allowed\n"));
Packit 1437d9
				usage();
Packit 1437d9
			}
Packit 1437d9
			opflag = REMOVEOP;
Packit 1437d9
			attrname = optarg;
Packit 1437d9
			break;
Packit 1437d9
		case 'l':
Packit 1437d9
			if (opflag) {
Packit 1437d9
				fprintf(stderr,
Packit 1437d9
				  _("Only one of -s, -g, -r, or -l allowed\n"));
Packit 1437d9
				usage();
Packit 1437d9
			}
Packit 1437d9
			opflag = LISTOP;
Packit 1437d9
			break;
Packit 1437d9
		case 'L':
Packit 1437d9
			follow++;
Packit 1437d9
			break;
Packit 1437d9
		case 'R':
Packit 1437d9
			rootflag++;
Packit 1437d9
			break;
Packit 1437d9
		case 'S':
Packit 1437d9
			secureflag++;
Packit 1437d9
			break;
Packit 1437d9
		case 'q':
Packit 1437d9
			verbose = 0;
Packit 1437d9
			break;
Packit 1437d9
		default:
Packit 1437d9
			fprintf(stderr, _("Unrecognized option: %c\n"),
Packit 1437d9
				(char)ch);
Packit 1437d9
			usage();
Packit 1437d9
			break;
Packit 1437d9
		}
Packit 1437d9
	}
Packit 1437d9
	if (optind != argc-1) {
Packit 1437d9
		fprintf(stderr, _("A filename to operate on is required\n"));
Packit 1437d9
		usage();
Packit 1437d9
	}
Packit 1437d9
	filename = argv[optind];
Packit 1437d9
Packit 1437d9
	attrflags = ((!follow ? ATTR_DONTFOLLOW : 0) |
Packit 1437d9
		     (secureflag ? ATTR_SECURE : 0) |
Packit 1437d9
		     (rootflag ? ATTR_ROOT : 0));
Packit 1437d9
	/*
Packit 1437d9
	 * Break out into option-specific processing.
Packit 1437d9
	 */
Packit 1437d9
	switch (opflag) {
Packit 1437d9
	case SETOP:
Packit 1437d9
		if (!attrname) {
Packit 1437d9
		  fprintf(stderr, _("-V only allowed with -s\n"));
Packit 1437d9
		  usage();
Packit 1437d9
		}
Packit 1437d9
		if (attrvalue == NULL) {
Packit 1437d9
			attrvalue = malloc(ATTR_MAX_VALUELEN);
Packit 1437d9
			if (attrvalue == NULL) {
Packit 1437d9
				perror("malloc");
Packit 1437d9
				exit(1);
Packit 1437d9
			}
Packit 1437d9
			attrlength =
Packit 1437d9
				fread(attrvalue, 1, ATTR_MAX_VALUELEN, stdin);
Packit 1437d9
		} else {
Packit 1437d9
			attrlength = strlen(attrvalue);
Packit 1437d9
		}
Packit 1437d9
		error = attr_set(filename, attrname, attrvalue,
Packit 1437d9
					   attrlength, attrflags);
Packit 1437d9
		if (error) {
Packit 1437d9
			perror("attr_set");
Packit 1437d9
			fprintf(stderr, _("Could not set \"%s\" for %s\n"),
Packit 1437d9
					attrname, filename);
Packit 1437d9
			exit(1);
Packit 1437d9
		}
Packit 1437d9
		if (verbose) {
Packit 1437d9
			printf(_("Attribute \"%s\" set to a %d byte value "
Packit 1437d9
			       "for %s:\n"), attrname, attrlength, filename);
Packit 1437d9
			fwrite(attrvalue, 1, attrlength, stdout);
Packit 1437d9
			printf("\n");
Packit 1437d9
		}
Packit 1437d9
		break;
Packit 1437d9
Packit 1437d9
	case GETOP:
Packit 1437d9
		attrvalue = malloc(ATTR_MAX_VALUELEN);
Packit 1437d9
		if (attrvalue == NULL) {
Packit 1437d9
			perror("malloc");
Packit 1437d9
			exit(1);
Packit 1437d9
		}
Packit 1437d9
		attrlength = ATTR_MAX_VALUELEN;
Packit 1437d9
		error = attr_get(filename, attrname, attrvalue,
Packit 1437d9
					   &attrlength, attrflags);
Packit 1437d9
		if (error) {
Packit 1437d9
			perror("attr_get");
Packit 1437d9
			fprintf(stderr, _("Could not get \"%s\" for %s\n"),
Packit 1437d9
					attrname, filename);
Packit 1437d9
			exit(1);
Packit 1437d9
		}
Packit 1437d9
		if (verbose) {
Packit 1437d9
			printf(_("Attribute \"%s\" had a %d byte value "
Packit 1437d9
				"for %s:\n"), attrname, attrlength, filename);
Packit 1437d9
		}
Packit 1437d9
		fwrite(attrvalue, 1, attrlength, stdout);
Packit 1437d9
		if (verbose) {
Packit 1437d9
			printf("\n");
Packit 1437d9
		}
Packit 1437d9
		break;
Packit 1437d9
Packit 1437d9
	case REMOVEOP:
Packit 1437d9
		error = attr_remove(filename, attrname, attrflags);
Packit 1437d9
		if (error) {
Packit 1437d9
			perror("attr_remove");
Packit 1437d9
			fprintf(stderr, _("Could not remove \"%s\" for %s\n"),
Packit 1437d9
					attrname, filename);
Packit 1437d9
			exit(1);
Packit 1437d9
		}
Packit 1437d9
		break;
Packit 1437d9
Packit 1437d9
	case LISTOP:
Packit 1437d9
		if ((buffer = malloc(BUFSIZE)) == NULL) {
Packit 1437d9
			perror("malloc");
Packit 1437d9
			exit(1);
Packit 1437d9
		}
Packit 1437d9
		bzero((char *)&cursor, sizeof(cursor));
Packit 1437d9
		do {
Packit 1437d9
			error = attr_list(filename, buffer, BUFSIZE,
Packit 1437d9
					  attrflags, &cursor);
Packit 1437d9
			if (error) {
Packit 1437d9
				perror("attr_list");
Packit 1437d9
				fprintf(stderr,
Packit 1437d9
					_("Could not list %s\n"),
Packit 1437d9
					filename);
Packit 1437d9
				exit(1);
Packit 1437d9
			}
Packit 1437d9
Packit 1437d9
			alist = (attrlist_t *)buffer;
Packit 1437d9
			for (i = 0; i < alist->al_count; i++) {
Packit 1437d9
				aep = (attrlist_ent_t *)&buffer[ alist->al_offset[i] ];
Packit 1437d9
				if (verbose) {
Packit 1437d9
					printf(
Packit 1437d9
			_("Attribute \"%s\" has a %d byte value for %s\n"),
Packit 1437d9
						aep->a_name, aep->a_valuelen,
Packit 1437d9
						filename);
Packit 1437d9
				} else {
Packit 1437d9
					printf("%s\n", aep->a_name);
Packit 1437d9
				}
Packit 1437d9
			}
Packit 1437d9
		} while (alist->al_more);
Packit 1437d9
		break;
Packit 1437d9
Packit 1437d9
	default:
Packit 1437d9
		fprintf(stderr,
Packit 1437d9
			_("At least one of -s, -g, -r, or -l is required\n"));
Packit 1437d9
		usage();
Packit 1437d9
		break;
Packit 1437d9
	}
Packit 1437d9
Packit 1437d9
	return(0);
Packit 1437d9
}
Packit 1437d9
#pragma GCC diagnostic warning "-Wdeprecated-declarations"