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