1 /*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7 #ifndef lint
8 static char sccsid[] = "@(#)chgrp.c 5.9 (Berkeley) 12/21/87";
9 #endif not lint
10
11 /*
12 * chgrp -fR gid file ...
13 */
14
15 #include <stdio.h>
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <grp.h>
20 #include <pwd.h>
21 #include <sys/dir.h>
22
23 struct group *gr, *getgrnam(), *getgrgid();
24 struct passwd *getpwuid(), *pwd;
25 struct stat stbuf;
26 int gid, uid;
27 int status;
28 int fflag, rflag;
29 /* VARARGS */
30 int fprintf();
31
main(argc,argv)32 main(argc, argv)
33 int argc;
34 char *argv[];
35 {
36 register c, i;
37 register char *cp;
38
39 argc--, argv++;
40 while (argc > 0 && argv[0][0] == '-') {
41 for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
42
43 case 'f':
44 fflag++;
45 break;
46
47 case 'R':
48 rflag++;
49 break;
50
51 default:
52 fatal(255, "unknown option: %c", *cp);
53 /*NOTREACHED*/
54 }
55 argv++, argc--;
56 }
57 if (argc < 2) {
58 fprintf(stderr, "usage: chgrp [-fR] gid file ...\n");
59 exit(255);
60 }
61 uid = getuid();
62 if (isnumber(argv[0])) {
63 gid = atoi(argv[0]);
64 gr = getgrgid(gid);
65 if (uid && gr == NULL)
66 fatal(255, "%s: unknown group", argv[0]);
67 } else {
68 gr = getgrnam(argv[0]);
69 if (gr == NULL)
70 fatal(255, "%s: unknown group", argv[0]);
71 gid = gr->gr_gid;
72 }
73 pwd = getpwuid(uid);
74 if (pwd == NULL)
75 fatal(255, "Who are you?");
76 if (uid && pwd->pw_gid != gid) {
77 for (i=0; gr->gr_mem[i]; i++)
78 if (!(strcmp(pwd->pw_name, gr->gr_mem[i])))
79 goto ok;
80 if (fflag)
81 exit(0);
82 fatal(255, "You are not a member of the %s group", argv[0]);
83 }
84 ok:
85 for (c = 1; c < argc; c++) {
86 /* do stat for directory arguments */
87 if (lstat(argv[c], &stbuf)) {
88 status += Perror(argv[c]);
89 continue;
90 }
91 if (uid && uid != stbuf.st_uid) {
92 status += error("You are not the owner of %s", argv[c]);
93 continue;
94 }
95 if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFDIR)) {
96 status += chownr(argv[c]);
97 continue;
98 }
99 if (chown(argv[c], -1, gid)) {
100 status += Perror(argv[c]);
101 continue;
102 }
103 }
104 exit(status);
105 }
106
isnumber(s)107 isnumber(s)
108 char *s;
109 {
110 register int c;
111
112 while (c = *s++)
113 if (!isdigit(c))
114 return (0);
115 return (1);
116 }
117
chownr(dir)118 chownr(dir)
119 char *dir;
120 {
121 register DIR *dirp;
122 register struct direct *dp;
123 struct stat st;
124 char savedir[1024];
125 int ecode;
126
127 if (getwd(savedir) == 0)
128 fatal(255, "%s", savedir);
129 /*
130 * Change what we are given before doing its contents.
131 */
132 if (chown(dir, -1, gid) < 0 && Perror(dir))
133 return (1);
134 if (chdir(dir) < 0) {
135 Perror(dir);
136 return (1);
137 }
138 if ((dirp = opendir(".")) == NULL) {
139 Perror(dir);
140 return (1);
141 }
142 dp = readdir(dirp);
143 dp = readdir(dirp); /* read "." and ".." */
144 ecode = 0;
145 for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
146 if (lstat(dp->d_name, &st) < 0) {
147 ecode = Perror(dp->d_name);
148 if (ecode)
149 break;
150 continue;
151 }
152 if (uid && uid != st.st_uid) {
153 ecode = error("You are not the owner of %s",
154 dp->d_name);
155 continue;
156 }
157 if ((st.st_mode & S_IFMT) == S_IFDIR) {
158 ecode = chownr(dp->d_name);
159 if (ecode)
160 break;
161 continue;
162 }
163 if (chown(dp->d_name, -1, gid) < 0 &&
164 (ecode = Perror(dp->d_name)))
165 break;
166 }
167 closedir(dirp);
168 if (chdir(savedir) < 0)
169 fatal(255, "can't change back to %s", savedir);
170 return (ecode);
171 }
172
error(fmt,a)173 error(fmt, a)
174 char *fmt, *a;
175 {
176
177 if (!fflag) {
178 fprintf(stderr, "chgrp: ");
179 fprintf(stderr, fmt, a);
180 putc('\n', stderr);
181 }
182 return (!fflag);
183 }
184
fatal(status,fmt,a)185 fatal(status, fmt, a)
186 int status;
187 char *fmt, *a;
188 {
189
190 fflag = 0;
191 (void) error(fmt, a);
192 exit(status);
193 }
194
Perror(s)195 Perror(s)
196 char *s;
197 {
198
199 if (!fflag) {
200 fprintf(stderr, "chgrp: ");
201 perror(s);
202 }
203 return (!fflag);
204 }
205