POSIX.2, Draft 11
[unix-history] / usr / src / usr.sbin / chown / chown.c
CommitLineData
da158ee3 1/*
7445173f
KB
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
32ce521f 5 * %sccs.include.redist.c%
da158ee3
DF
6 */
7
8#ifndef lint
9char copyright[] =
7445173f 10"@(#) Copyright (c) 1988 Regents of the University of California.\n\
da158ee3 11 All rights reserved.\n";
7445173f 12#endif /* not lint */
da158ee3
DF
13
14#ifndef lint
5ce44ab4 15static char sccsid[] = "@(#)chown.c 5.17 (Berkeley) %G%";
7445173f 16#endif /* not lint */
702e3fe5 17
7445173f 18#include <sys/param.h>
69e53de7 19#include <sys/stat.h>
f78af81d
KB
20#include <sys/errno.h>
21#include <dirent.h>
a7bd3fcd 22#include <fts.h>
7445173f 23#include <pwd.h>
702e3fe5 24#include <grp.h>
7445173f
KB
25#include <stdio.h>
26#include <ctype.h>
a7bd3fcd 27#include <string.h>
69e53de7 28
fe46eefc
MT
29int ischown, uid, gid, fflag, rflag, retval;
30char *gname, *myname;
69e53de7
BJ
31
32main(argc, argv)
7445173f
KB
33 int argc;
34 char **argv;
69e53de7 35{
7445173f 36 extern int optind;
a7bd3fcd
KB
37 register FTS *fts;
38 register FTSENT *p;
7445173f
KB
39 register char *cp;
40 int ch;
69e53de7 41
7445173f
KB
42 myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
43 ischown = myname[2] == 'o';
c76e0466 44
7445173f
KB
45 while ((ch = getopt(argc, argv, "Rf")) != EOF)
46 switch((char)ch) {
47 case 'R':
a7bd3fcd 48 rflag = 1;
7445173f 49 break;
c76e0466 50 case 'f':
a7bd3fcd 51 fflag = 1;
c76e0466 52 break;
7445173f
KB
53 case '?':
54 default:
55 usage();
56 }
57 argv += optind;
58 argc -= optind;
c76e0466 59
7445173f
KB
60 if (argc < 2)
61 usage();
c76e0466 62
a7bd3fcd 63 uid = gid = -1;
7445173f 64 if (ischown) {
a7bd3fcd 65#ifdef SUPPORT_DOT
7445173f
KB
66 if (cp = index(*argv, '.')) {
67 *cp++ = '\0';
68 setgid(cp);
a7bd3fcd
KB
69 } else
70#endif
71 if (cp = index(*argv, ':')) {
72 *cp++ = '\0';
73 setgid(cp);
74 }
7445173f 75 setuid(*argv);
c76e0466 76 }
a7bd3fcd 77 else
7445173f 78 setgid(*argv);
69e53de7 79
a7bd3fcd 80 if (rflag) {
5ce44ab4 81 if (!(fts = fts_open(++argv, FTS_NOSTAT|FTS_PHYSICAL, 0))) {
a7bd3fcd
KB
82 (void)fprintf(stderr,
83 "%s: %s.\n", myname, strerror(errno));
84 exit(1);
c439a634 85 }
5ce44ab4 86 while (p = fts_read(fts)) {
a7bd3fcd
KB
87 if (p->fts_info == FTS_D)
88 continue;
89 if (p->fts_info == FTS_ERR) {
90 error(p->fts_path);
91 continue;
92 }
93 if (chown(p->fts_accpath, uid, gid) && !fflag)
94 chownerr(p->fts_path);
95 }
96 exit(retval);
c439a634 97 }
a7bd3fcd
KB
98 while (*++argv)
99 if (chown(*argv, uid, gid) && !fflag)
100 chownerr(*argv);
7445173f 101 exit(retval);
69e53de7 102}
702e3fe5 103
7445173f
KB
104setgid(s)
105 register char *s;
702e3fe5 106{
7445173f 107 struct group *gr, *getgrnam();
7445173f
KB
108
109 if (!*s) {
110 gid = -1; /* argument was "uid." */
111 return;
80eff57a 112 }
f9915d58 113 for (gname = s; *s && isdigit(*s); ++s);
7445173f 114 if (!*s)
f9915d58 115 gid = atoi(gname);
7445173f 116 else {
f9915d58 117 if (!(gr = getgrnam(gname))) {
f78af81d 118 (void)fprintf(stderr, "%s: unknown group id: %s\n",
f9915d58 119 myname, gname);
a7bd3fcd 120 exit(1);
c76e0466 121 }
7445173f
KB
122 gid = gr->gr_gid;
123 }
c76e0466
SL
124}
125
7445173f
KB
126setuid(s)
127 register char *s;
c76e0466 128{
7445173f
KB
129 struct passwd *pwd, *getpwnam();
130 char *beg;
c76e0466 131
7445173f
KB
132 if (!*s) {
133 uid = -1; /* argument was ".gid" */
134 return;
135 }
136 for (beg = s; *s && isdigit(*s); ++s);
137 if (!*s)
138 uid = atoi(beg);
139 else {
140 if (!(pwd = getpwnam(beg))) {
f78af81d
KB
141 (void)fprintf(stderr,
142 "chown: unknown user id: %s\n", beg);
a7bd3fcd 143 exit(1);
7445173f
KB
144 }
145 uid = pwd->pw_uid;
c76e0466 146 }
c76e0466
SL
147}
148
2a151187
KB
149chownerr(file)
150 char *file;
151{
152 static int euid = -1, ngroups = -1;
153
154 /* check for chown without being root */
f78af81d 155 if (errno != EPERM || uid != -1 && euid == -1 && (euid = geteuid())) {
2a151187
KB
156 if (fflag)
157 exit(0);
a7bd3fcd
KB
158 error(file);
159 exit(1);
2a151187
KB
160 }
161 /* check group membership; kernel just returns EPERM */
162 if (gid != -1 && ngroups == -1) {
163 int groups[NGROUPS];
164
165 ngroups = getgroups(NGROUPS, groups);
166 while (--ngroups >= 0 && gid != groups[ngroups]);
167 if (ngroups < 0) {
168 if (fflag)
169 exit(0);
f78af81d 170 (void)fprintf(stderr,
2a151187
KB
171 "%s: you are not a member of group %s.\n",
172 myname, gname);
a7bd3fcd 173 exit(1);
2a151187
KB
174 }
175 }
a7bd3fcd
KB
176 if (!fflag)
177 error(file);
2a151187
KB
178}
179
a7bd3fcd
KB
180error(name)
181 char *name;
c76e0466 182{
a7bd3fcd
KB
183 (void)fprintf(stderr, "%s: %s: %s\n", myname, name, strerror(errno));
184 retval = 1;
7445173f 185}
c76e0466 186
7445173f
KB
187usage()
188{
f78af81d 189 (void)fprintf(stderr, "usage: %s [-Rf] %s file ...\n", myname,
a7bd3fcd
KB
190 ischown ? "[owner][:group]" : "group");
191 exit(1);
702e3fe5 192}