diff options
Diffstat (limited to 'toolbox/upstream-netbsd/sbin/chown/chown.c')
-rw-r--r-- | toolbox/upstream-netbsd/sbin/chown/chown.c | 302 |
1 files changed, 0 insertions, 302 deletions
diff --git a/toolbox/upstream-netbsd/sbin/chown/chown.c b/toolbox/upstream-netbsd/sbin/chown/chown.c deleted file mode 100644 index ee46eee..0000000 --- a/toolbox/upstream-netbsd/sbin/chown/chown.c +++ /dev/null @@ -1,302 +0,0 @@ -/* $NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $ */ - -/* - * Copyright (c) 1988, 1993, 1994, 2003 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94"; -#else -__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <dirent.h> -#include <err.h> -#include <errno.h> -#include <locale.h> -#include <fts.h> -#include <grp.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <getopt.h> - -static void a_gid(const char *); -static void a_uid(const char *); -static id_t id(const char *, const char *); -__dead static void usage(void); - -static uid_t uid; -static gid_t gid; -static int ischown; -static const char *myname; - -struct option chown_longopts[] = { - { "reference", required_argument, 0, - 1 }, - { NULL, 0, 0, - 0 }, -}; - -int -main(int argc, char **argv) -{ - FTS *ftsp; - FTSENT *p; - int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag; - char *cp, *reference; - int (*change_owner)(const char *, uid_t, gid_t); - - setprogname(*argv); - - (void)setlocale(LC_ALL, ""); - - myname = getprogname(); - ischown = (myname[2] == 'o'); - reference = NULL; - - Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; - while ((ch = getopt_long(argc, argv, "HLPRfhv", - chown_longopts, NULL)) != -1) - switch (ch) { - case 1: - reference = optarg; - break; - case 'H': - Hflag = 1; - Lflag = 0; - break; - case 'L': - Lflag = 1; - Hflag = 0; - break; - case 'P': - Hflag = Lflag = 0; - break; - case 'R': - Rflag = 1; - break; - case 'f': - fflag = 1; - break; - case 'h': - /* - * In System V the -h option causes chown/chgrp to - * change the owner/group of the symbolic link. - * 4.4BSD's symbolic links didn't have owners/groups, - * so it was an undocumented noop. - * In NetBSD 1.3, lchown(2) is introduced. - */ - hflag = 1; - break; - case 'v': - vflag = 1; - break; - case '?': - default: - usage(); - } - argv += optind; - argc -= optind; - - if (argc == 0 || (argc == 1 && reference == NULL)) - usage(); - - fts_options = FTS_PHYSICAL; - if (Rflag) { - if (Hflag) - fts_options |= FTS_COMFOLLOW; - if (Lflag) { - if (hflag) - errx(EXIT_FAILURE, - "the -L and -h options " - "may not be specified together."); - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; - } - } else if (!hflag) - fts_options |= FTS_COMFOLLOW; - - uid = (uid_t)-1; - gid = (gid_t)-1; - if (reference == NULL) { - if (ischown) { - if ((cp = strchr(*argv, ':')) != NULL) { - *cp++ = '\0'; - a_gid(cp); - } -#ifdef SUPPORT_DOT - else if ((cp = strrchr(*argv, '.')) != NULL) { - if (uid_from_user(*argv, &uid) == -1) { - *cp++ = '\0'; - a_gid(cp); - } - } -#endif - a_uid(*argv); - } else - a_gid(*argv); - argv++; - } else { - struct stat st; - - if (stat(reference, &st) == -1) - err(EXIT_FAILURE, "Cannot stat `%s'", reference); - if (ischown) - uid = st.st_uid; - gid = st.st_gid; - } - - if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) - err(EXIT_FAILURE, "fts_open"); - - for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) { - change_owner = chown; - switch (p->fts_info) { - case FTS_D: - if (!Rflag) /* Change it at FTS_DP. */ - fts_set(ftsp, p, FTS_SKIP); - continue; - case FTS_DNR: /* Warn, chown, continue. */ - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); - rval = EXIT_FAILURE; - break; - case FTS_ERR: /* Warn, continue. */ - case FTS_NS: - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); - rval = EXIT_FAILURE; - continue; - case FTS_SL: /* Ignore unless -h. */ - /* - * All symlinks we found while doing a physical - * walk end up here. - */ - if (!hflag) - continue; - /* - * Note that if we follow a symlink, fts_info is - * not FTS_SL but FTS_F or whatever. And we should - * use lchown only for FTS_SL and should use chown - * for others. - */ - change_owner = lchown; - break; - case FTS_SLNONE: /* Ignore. */ - /* - * The only symlinks that end up here are ones that - * don't point to anything. Note that if we are - * doing a phisycal walk, we never reach here unless - * we asked to follow explicitly. - */ - continue; - default: - break; - } - - if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) { - warn("%s", p->fts_path); - rval = EXIT_FAILURE; - } else { - if (vflag) - printf("%s\n", p->fts_path); - } - } - if (errno) - err(EXIT_FAILURE, "fts_read"); - exit(rval); - /* NOTREACHED */ -} - -static void -a_gid(const char *s) -{ - struct group *gr; - - if (*s == '\0') /* Argument was "uid[:.]". */ - return; - gr = *s == '#' ? NULL : getgrnam(s); - if (gr == NULL) - gid = id(s, "group"); - else - gid = gr->gr_gid; - return; -} - -static void -a_uid(const char *s) -{ - if (*s == '\0') /* Argument was "[:.]gid". */ - return; - if (*s == '#' || uid_from_user(s, &uid) == -1) { - uid = id(s, "user"); - } - return; -} - -static id_t -id(const char *name, const char *type) -{ - id_t val; - char *ep; - - errno = 0; - if (*name == '#') - name++; - val = (id_t)strtoul(name, &ep, 10); - if (errno) - err(EXIT_FAILURE, "%s", name); - if (*ep != '\0') - errx(EXIT_FAILURE, "%s: invalid %s name", name, type); - return (val); -} - -static void -usage(void) -{ - - (void)fprintf(stderr, - "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n" - "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n", - myname, ischown ? "owner:group|owner|:group" : "group", - myname); - exit(EXIT_FAILURE); -} |