* Copyright (c) 1988, 1993, 1994
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1988, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)chown.c 8.2 (Berkeley) %G%";
void a_gid
__P((char *));
void a_uid
__P((char *));
void chownerr
__P((char *));
u_long id
__P((char *, char *));
int Rflag
, ischown
, fflag
;
int Hflag
, Lflag
, Pflag
, ch
, fts_options
, hflag
, rval
;
myname
= (cp
= rindex(*argv
, '/')) ? cp
+ 1 : *argv
;
ischown
= myname
[2] == 'o';
Hflag
= Lflag
= Pflag
= hflag
= 0;
while ((ch
= getopt(argc
, argv
, "HLPRfh")) != EOF
)
* In System V (and probably POSIX.2) the -h option
* causes chown/chgrp to change the owner/group of
* the symbolic link. 4.4BSD's symbolic links don't
* have owners/groups, so it's an undocumented noop.
* Do syntax checking, though.
fts_options
= FTS_NOSTAT
| FTS_PHYSICAL
;
"the -R and -h options may not be specified together.");
fts_options
|= FTS_COMFOLLOW
;
fts_options
&= ~FTS_PHYSICAL
;
fts_options
|= FTS_LOGICAL
;
if ((cp
= strchr(*argv
, '.')) != NULL
) {
if ((cp
= strchr(*argv
, ':')) != NULL
) {
if ((ftsp
= fts_open(++argv
, fts_options
, 0)) == NULL
)
for (rval
= 0; (p
= fts_read(ftsp
)) != NULL
;) {
if (Rflag
) /* Change it at FTS_DP. */
fts_set(ftsp
, p
, FTS_SKIP
);
warnx("tree cycle: %s", p
->fts_path
);
* The only symlinks that end up here are ones that
* don't point to anything and ones that we found
if (chown(p
->fts_accpath
, uid
, gid
) && !fflag
) {
if (*s
== '\0') /* Argument was "uid[:.]". */
gid
= ((gr
= getgrnam(s
)) == NULL
) ? id(s
, "group") : gr
->gr_gid
;
if (*s
== '\0') /* Argument was "[:.]gid". */
uid
= ((pw
= getpwnam(s
)) == NULL
) ? id(s
, "user") : pw
->pw_uid
;
* We know that uid_t's and gid_t's are unsigned longs.
val
= strtoul(name
, &ep
, 10);
errx(1, "%s: illegal %s name", name
, type
);
static int euid
= -1, ngroups
= -1;
/* Check for chown without being root. */
uid
!= -1 && euid
== -1 && (euid
= geteuid()) != 0) {
/* Check group membership; kernel just returns EPERM. */
if (gid
!= -1 && ngroups
== -1) {
ngroups
= getgroups(NGROUPS
, groups
);
while (--ngroups
>= 0 && gid
!= groups
[ngroups
]);
errx(1, "you are not a member of group %s", gname
);
"usage: %s [-R [-H | -L | -P]] [-f] %s file ...\n",
myname
, ischown
? "[owner][:group]" : "group");