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