10b024677ec64ebbf298de810929292a693436ad6Elliott Hughes/*	$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $	*/
20b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
30b024677ec64ebbf298de810929292a693436ad6Elliott Hughes/*
40b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * Copyright (c) 1988, 1993, 1994, 2003
50b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *	The Regents of the University of California.  All rights reserved.
60b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *
70b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * Redistribution and use in source and binary forms, with or without
80b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * modification, are permitted provided that the following conditions
90b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * are met:
100b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * 1. Redistributions of source code must retain the above copyright
110b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *    notice, this list of conditions and the following disclaimer.
120b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright
130b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *    notice, this list of conditions and the following disclaimer in the
140b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *    documentation and/or other materials provided with the distribution.
150b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * 3. Neither the name of the University nor the names of its contributors
160b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *    may be used to endorse or promote products derived from this software
170b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *    without specific prior written permission.
180b024677ec64ebbf298de810929292a693436ad6Elliott Hughes *
190b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
200b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
210b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
220b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
230b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
240b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
250b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
260b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
270b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
280b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
290b024677ec64ebbf298de810929292a693436ad6Elliott Hughes * SUCH DAMAGE.
300b024677ec64ebbf298de810929292a693436ad6Elliott Hughes */
310b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
320b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <sys/cdefs.h>
330b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#ifndef lint
340b024677ec64ebbf298de810929292a693436ad6Elliott Hughes__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\
350b024677ec64ebbf298de810929292a693436ad6Elliott Hughes The Regents of the University of California.  All rights reserved.");
360b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#endif /* not lint */
370b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
380b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#ifndef lint
390b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#if 0
400b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic char sccsid[] = "@(#)chown.c	8.8 (Berkeley) 4/4/94";
410b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#else
420b024677ec64ebbf298de810929292a693436ad6Elliott Hughes__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $");
430b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#endif
440b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#endif /* not lint */
450b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
470b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <sys/stat.h>
480b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
490b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <ctype.h>
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h>
510b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <err.h>
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
530b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <locale.h>
540b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <fts.h>
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <grp.h>
560b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <pwd.h>
570b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <stdio.h>
580b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <stdlib.h>
590b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <string.h>
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
610b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#include <getopt.h>
620b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
630b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic void	a_gid(const char *);
640b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic void	a_uid(const char *);
650b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic id_t	id(const char *, const char *);
660b024677ec64ebbf298de810929292a693436ad6Elliott Hughes__dead static void	usage(void);
670b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
680b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic uid_t uid;
690b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic gid_t gid;
700b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic int ischown;
710b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic const char *myname;
720b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
730b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstruct option chown_longopts[] = {
740b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	{ "reference",		required_argument,	0,
750b024677ec64ebbf298de810929292a693436ad6Elliott Hughes						1 },
760b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	{ NULL,			0,			0,
770b024677ec64ebbf298de810929292a693436ad6Elliott Hughes						0 },
780b024677ec64ebbf298de810929292a693436ad6Elliott Hughes};
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
800b024677ec64ebbf298de810929292a693436ad6Elliott Hughesint
817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesmain(int argc, char **argv)
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
830b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	FTS *ftsp;
840b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	FTSENT *p;
850b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag;
860b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	char *cp, *reference;
870b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	int (*change_owner)(const char *, uid_t, gid_t);
880b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
890b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	setprogname(*argv);
900b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
910b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	(void)setlocale(LC_ALL, "");
920b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
930b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	myname = getprogname();
940b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	ischown = (myname[2] == 'o');
950b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	reference = NULL;
960b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
970b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
980b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	while ((ch = getopt_long(argc, argv, "HLPRfhv",
990b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	    chown_longopts, NULL)) != -1)
1000b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		switch (ch) {
1010b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 1:
1020b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			reference = optarg;
1030b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1040b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'H':
1050b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Hflag = 1;
1060b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Lflag = 0;
1070b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1080b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'L':
1090b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Lflag = 1;
1100b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Hflag = 0;
1110b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1120b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'P':
1130b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Hflag = Lflag = 0;
1140b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1150b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'R':
1160b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			Rflag = 1;
1170b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1180b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'f':
1190b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			fflag = 1;
1200b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1210b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'h':
1220b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			/*
1230b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * In System V the -h option causes chown/chgrp to
1240b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * change the owner/group of the symbolic link.
1250b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * 4.4BSD's symbolic links didn't have owners/groups,
1260b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * so it was an undocumented noop.
1270b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * In NetBSD 1.3, lchown(2) is introduced.
1280b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 */
1290b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			hflag = 1;
1300b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1310b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case 'v':
1320b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			vflag = 1;
1330b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
1340b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case '?':
1350b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		default:
1360b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			usage();
1370b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		}
1380b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	argv += optind;
1390b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	argc -= optind;
1400b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1410b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (argc == 0 || (argc == 1 && reference == NULL))
1420b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		usage();
1430b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1440b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	fts_options = FTS_PHYSICAL;
1450b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (Rflag) {
1460b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if (Hflag)
1470b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			fts_options |= FTS_COMFOLLOW;
1480b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if (Lflag) {
1490b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			if (hflag)
1500b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				errx(EXIT_FAILURE,
1510b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				    "the -L and -h options "
1520b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				    "may not be specified together.");
1530b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			fts_options &= ~FTS_PHYSICAL;
1540b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			fts_options |= FTS_LOGICAL;
1550b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		}
1560b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	} else if (!hflag)
1570b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		fts_options |= FTS_COMFOLLOW;
1580b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1590b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	uid = (uid_t)-1;
1600b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	gid = (gid_t)-1;
1610b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (reference == NULL) {
1620b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if (ischown) {
1630b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			if ((cp = strchr(*argv, ':')) != NULL) {
1640b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				*cp++ = '\0';
1650b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				a_gid(cp);
1660b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			}
1670b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#ifdef SUPPORT_DOT
1680b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			else if ((cp = strrchr(*argv, '.')) != NULL) {
1690b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				if (uid_from_user(*argv, &uid) == -1) {
1700b024677ec64ebbf298de810929292a693436ad6Elliott Hughes					*cp++ = '\0';
1710b024677ec64ebbf298de810929292a693436ad6Elliott Hughes					a_gid(cp);
1720b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				}
1730b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			}
1740b024677ec64ebbf298de810929292a693436ad6Elliott Hughes#endif
1750b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			a_uid(*argv);
1760b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		} else
1770b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			a_gid(*argv);
1780b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		argv++;
1790b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	} else {
1800b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		struct stat st;
1810b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1820b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if (stat(reference, &st) == -1)
1830b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			err(EXIT_FAILURE, "Cannot stat `%s'", reference);
1840b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if (ischown)
1850b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			uid = st.st_uid;
1860b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		gid = st.st_gid;
1870b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	}
1880b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1890b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
1900b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		err(EXIT_FAILURE, "fts_open");
1910b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
1920b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) {
1930b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		change_owner = chown;
1940b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		switch (p->fts_info) {
1950b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_D:
1960b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			if (!Rflag)		/* Change it at FTS_DP. */
1970b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				fts_set(ftsp, p, FTS_SKIP);
1980b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			continue;
1990b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_DNR:			/* Warn, chown, continue. */
2000b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
2010b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			rval = EXIT_FAILURE;
2020b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
2030b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_ERR:			/* Warn, continue. */
2040b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_NS:
2050b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
2060b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			rval = EXIT_FAILURE;
2070b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			continue;
2080b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_SL:			/* Ignore unless -h. */
2090b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			/*
2100b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * All symlinks we found while doing a physical
2110b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * walk end up here.
2120b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 */
2130b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			if (!hflag)
2140b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				continue;
2150b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			/*
2160b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * Note that if we follow a symlink, fts_info is
2170b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * not FTS_SL but FTS_F or whatever.  And we should
2180b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * use lchown only for FTS_SL and should use chown
2190b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * for others.
2200b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 */
2210b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			change_owner = lchown;
2220b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
2230b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		case FTS_SLNONE:		/* Ignore. */
2240b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			/*
2250b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * The only symlinks that end up here are ones that
2260b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * don't point to anything.  Note that if we are
2270b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * doing a phisycal walk, we never reach here unless
2280b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 * we asked to follow explicitly.
2290b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			 */
2300b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			continue;
2310b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		default:
2320b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			break;
2330b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		}
2340b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2350b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) {
2360b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			warn("%s", p->fts_path);
2370b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			rval = EXIT_FAILURE;
2380b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		} else {
2390b024677ec64ebbf298de810929292a693436ad6Elliott Hughes			if (vflag)
2400b024677ec64ebbf298de810929292a693436ad6Elliott Hughes				printf("%s\n", p->fts_path);
2410b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		}
2420b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	}
2430b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (errno)
2440b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		err(EXIT_FAILURE, "fts_read");
2450b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	exit(rval);
2460b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	/* NOTREACHED */
2470b024677ec64ebbf298de810929292a693436ad6Elliott Hughes}
2480b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2490b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic void
2500b024677ec64ebbf298de810929292a693436ad6Elliott Hughesa_gid(const char *s)
2510b024677ec64ebbf298de810929292a693436ad6Elliott Hughes{
2520b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	struct group *gr;
2530b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2540b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (*s == '\0')			/* Argument was "uid[:.]". */
2550b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		return;
2560b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	gr = *s == '#' ? NULL : getgrnam(s);
2570b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (gr == NULL)
2580b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		gid = id(s, "group");
2590b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	else
2600b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		gid = gr->gr_gid;
2610b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	return;
2620b024677ec64ebbf298de810929292a693436ad6Elliott Hughes}
2630b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2640b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic void
2650b024677ec64ebbf298de810929292a693436ad6Elliott Hughesa_uid(const char *s)
2660b024677ec64ebbf298de810929292a693436ad6Elliott Hughes{
2670b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (*s == '\0')			/* Argument was "[:.]gid". */
2680b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		return;
2690b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (*s == '#' || uid_from_user(s, &uid) == -1) {
2700b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		uid = id(s, "user");
2710b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	}
2720b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	return;
2730b024677ec64ebbf298de810929292a693436ad6Elliott Hughes}
2740b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2750b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic id_t
2760b024677ec64ebbf298de810929292a693436ad6Elliott Hughesid(const char *name, const char *type)
2770b024677ec64ebbf298de810929292a693436ad6Elliott Hughes{
2780b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	id_t val;
2790b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	char *ep;
2800b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2810b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	errno = 0;
2820b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (*name == '#')
2830b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		name++;
2840b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	val = (id_t)strtoul(name, &ep, 10);
2850b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (errno)
2860b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		err(EXIT_FAILURE, "%s", name);
2870b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	if (*ep != '\0')
2880b024677ec64ebbf298de810929292a693436ad6Elliott Hughes		errx(EXIT_FAILURE, "%s: invalid %s name", name, type);
2890b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	return (val);
2900b024677ec64ebbf298de810929292a693436ad6Elliott Hughes}
2910b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2920b024677ec64ebbf298de810929292a693436ad6Elliott Hughesstatic void
2930b024677ec64ebbf298de810929292a693436ad6Elliott Hughesusage(void)
2940b024677ec64ebbf298de810929292a693436ad6Elliott Hughes{
2950b024677ec64ebbf298de810929292a693436ad6Elliott Hughes
2960b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	(void)fprintf(stderr,
2970b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	    "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n"
2980b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	    "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n",
2990b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	    myname, ischown ? "owner:group|owner|:group" : "group",
3000b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	    myname);
3010b024677ec64ebbf298de810929292a693436ad6Elliott Hughes	exit(EXIT_FAILURE);
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
303