3
/* NetBSD: chown.c,v 1.32 2008/07/21 13:36:57 lukem Exp */
6
* Copyright (c) 1988, 1993, 1994, 2003
7
* The Regents of the University of California. All rights reserved.
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
* 3. Neither the name of the University nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
21
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
#include <sys/cdefs.h>
36
__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\
37
The Regents of the University of California. All rights reserved.");
42
static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94";
44
__RCSID("$NetBSD: chown.c,v 1.32 2008/07/21 13:36:57 lukem Exp $");
48
#include <sys/types.h>
67
#include <rump/ukfs.h>
69
#include <fts2fsufts.h>
70
#include <fsu_mount.h>
75
chown(const char *path, uid_t owner, gid_t group)
78
return ukfs_chown(ukfs, path, owner, group);
82
lchown(const char *path, uid_t owner, gid_t group)
85
return ukfs_lchown(ukfs, path, owner, group);
90
static void a_gid(const char *);
91
static void a_uid(const char *);
92
static id_t id(const char *, const char *);
93
static void usage(void);
101
main(int argc, char **argv)
105
int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag;
107
int (*change_owner)(const char *, uid_t, gid_t);
109
(void)setlocale(LC_ALL, "");
111
myname = (cp = strrchr(*argv, '/')) ? cp + 1 : *argv;
113
ischown = (myname[6] == 'o' || myname[2] == 'o');
115
ischown = (myname[2] == 'o');
119
FSU_MOUNT(argc, argv, ukfs);
122
Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
123
while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
144
* In System V the -h option causes chown/chgrp to
145
* change the owner/group of the symbolic link.
146
* 4.4BSD's symbolic links didn't have owners/groups,
147
* so it was an undocumented noop.
148
* In NetBSD 1.3, lchown(2) is introduced.
165
fts_options = FTS_PHYSICAL;
168
fts_options |= FTS_COMFOLLOW;
172
"the -L and -h options "
173
"may not be specified together.");
174
fts_options &= ~FTS_PHYSICAL;
175
fts_options |= FTS_LOGICAL;
178
fts_options |= FTS_COMFOLLOW;
183
if ((cp = strchr(*argv, ':')) != NULL) {
188
else if ((cp = strrchr(*argv, '.')) != NULL) {
189
if (uid_from_user(*argv, &uid) == -1) {
199
if ((ftsp = fts_open(++argv, fts_options, NULL)) == NULL)
200
err(EXIT_FAILURE, "fts_open");
202
for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) {
203
change_owner = chown;
204
switch (p->fts_info) {
206
if (!Rflag) /* Change it at FTS_DP. */
207
fts_set(ftsp, p, FTS_SKIP);
209
case FTS_DNR: /* Warn, chown, continue. */
210
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
213
case FTS_ERR: /* Warn, continue. */
215
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
218
case FTS_SL: /* Ignore unless -h. */
220
* All symlinks we found while doing a physical
226
* Note that if we follow a symlink, fts_info is
227
* not FTS_SL but FTS_F or whatever. And we should
228
* use lchown only for FTS_SL and should use chown
231
change_owner = lchown;
233
case FTS_SLNONE: /* Ignore. */
235
* The only symlinks that end up here are ones that
236
* don't point to anything. Note that if we are
237
* doing a phisycal walk, we never reach here unless
238
* we asked to follow explicitly.
245
if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) {
246
warn("%s", p->fts_path);
250
printf("%s\n", p->fts_path);
254
err(EXIT_FAILURE, "fts_read");
264
if (*s == '\0') /* Argument was "uid[:.]". */
266
gr = *s == '#' ? NULL : getgrnam(s);
268
gid = id(s, "group");
277
if (*s == '\0') /* Argument was "[:.]gid". */
279
if (*s == '#' || uid_from_user(s, &uid) == -1) {
286
id(const char *name, const char *type)
294
val = (id_t)strtoul(name, &ep, 10);
296
err(EXIT_FAILURE, "%s", name);
298
errx(EXIT_FAILURE, "%s: invalid %s name", name, type);
306
(void)fprintf(stderr,
307
"usage: %s %s [-R [-H | -L | -P]] [-fhv] %s file ...\n",
308
myname, fsu_mount_usage(),
309
ischown ? "[owner][:group]" : "group");
312
(void)fprintf(stderr,
313
"usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n",
314
myname, ischown ? "[owner][:group]" : "group");