Commit | Line | Data |
---|---|---|
bcf1365c DF |
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 | ||
5f0e98a5 | 7 | #ifndef lint |
eb1c99ef | 8 | static char sccsid[] = "@(#)chgrp.c 5.9 (Berkeley) %G%"; |
bcf1365c | 9 | #endif not lint |
5f0e98a5 | 10 | |
de68ad37 | 11 | /* |
68e6b419 | 12 | * chgrp -fR gid file ... |
de68ad37 BJ |
13 | */ |
14 | ||
15 | #include <stdio.h> | |
16 | #include <ctype.h> | |
17 | #include <sys/types.h> | |
18 | #include <sys/stat.h> | |
19 | #include <grp.h> | |
85f1f03c | 20 | #include <pwd.h> |
68e6b419 | 21 | #include <sys/dir.h> |
de68ad37 | 22 | |
5f0e98a5 BJ |
23 | struct group *gr, *getgrnam(), *getgrgid(); |
24 | struct passwd *getpwuid(), *pwd; | |
25 | struct stat stbuf; | |
85f1f03c | 26 | int gid, uid; |
de68ad37 | 27 | int status; |
68e6b419 | 28 | int fflag, rflag; |
5f0e98a5 BJ |
29 | /* VARARGS */ |
30 | int fprintf(); | |
de68ad37 BJ |
31 | |
32 | main(argc, argv) | |
5f0e98a5 BJ |
33 | int argc; |
34 | char *argv[]; | |
de68ad37 | 35 | { |
85f1f03c | 36 | register c, i; |
c76e0466 | 37 | register char *cp; |
de68ad37 | 38 | |
5f0e98a5 | 39 | argc--, argv++; |
c76e0466 SL |
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: | |
43a11e0e | 52 | fatal(255, "unknown option: %c", *cp); |
c76e0466 SL |
53 | /*NOTREACHED*/ |
54 | } | |
8788247f RC |
55 | argv++, argc--; |
56 | } | |
5f0e98a5 | 57 | if (argc < 2) { |
68e6b419 KM |
58 | fprintf(stderr, "usage: chgrp [-fR] gid file ...\n"); |
59 | exit(255); | |
de68ad37 | 60 | } |
85f1f03c | 61 | uid = getuid(); |
5f0e98a5 | 62 | if (isnumber(argv[0])) { |
77d4d541 | 63 | gid = atoi(argv[0]); |
5f0e98a5 | 64 | gr = getgrgid(gid); |
c76e0466 SL |
65 | if (uid && gr == NULL) |
66 | fatal(255, "%s: unknown group", argv[0]); | |
de68ad37 | 67 | } else { |
5f0e98a5 | 68 | gr = getgrnam(argv[0]); |
c76e0466 SL |
69 | if (gr == NULL) |
70 | fatal(255, "%s: unknown group", argv[0]); | |
de68ad37 BJ |
71 | gid = gr->gr_gid; |
72 | } | |
5f0e98a5 | 73 | pwd = getpwuid(uid); |
c76e0466 SL |
74 | if (pwd == NULL) |
75 | fatal(255, "Who are you?"); | |
5f0e98a5 BJ |
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; | |
8788247f RC |
80 | if (fflag) |
81 | exit(0); | |
c76e0466 | 82 | fatal(255, "You are not a member of the %s group", argv[0]); |
85f1f03c | 83 | } |
5f0e98a5 BJ |
84 | ok: |
85 | for (c = 1; c < argc; c++) { | |
c76e0466 | 86 | /* do stat for directory arguments */ |
b3290c4c KM |
87 | if (lstat(argv[c], &stbuf)) { |
88 | status += Perror(argv[c]); | |
5f0e98a5 BJ |
89 | continue; |
90 | } | |
85f1f03c | 91 | if (uid && uid != stbuf.st_uid) { |
c76e0466 | 92 | status += error("You are not the owner of %s", argv[c]); |
5f0e98a5 BJ |
93 | continue; |
94 | } | |
9c3d388c | 95 | if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFDIR)) { |
735727c9 | 96 | status += chownr(argv[c]); |
c76e0466 SL |
97 | continue; |
98 | } | |
b3290c4c KM |
99 | if (chown(argv[c], -1, gid)) { |
100 | status += Perror(argv[c]); | |
c76e0466 SL |
101 | continue; |
102 | } | |
de68ad37 BJ |
103 | } |
104 | exit(status); | |
105 | } | |
106 | ||
107 | isnumber(s) | |
5f0e98a5 | 108 | char *s; |
de68ad37 | 109 | { |
5f0e98a5 | 110 | register int c; |
de68ad37 | 111 | |
5f0e98a5 BJ |
112 | while (c = *s++) |
113 | if (!isdigit(c)) | |
114 | return (0); | |
115 | return (1); | |
de68ad37 | 116 | } |
68e6b419 | 117 | |
735727c9 | 118 | chownr(dir) |
c76e0466 | 119 | char *dir; |
68e6b419 | 120 | { |
c76e0466 SL |
121 | register DIR *dirp; |
122 | register struct direct *dp; | |
eb1c99ef | 123 | struct stat st; |
c76e0466 SL |
124 | char savedir[1024]; |
125 | int ecode; | |
68e6b419 | 126 | |
c76e0466 SL |
127 | if (getwd(savedir) == 0) |
128 | fatal(255, "%s", savedir); | |
129 | /* | |
038208f4 | 130 | * Change what we are given before doing its contents. |
c76e0466 | 131 | */ |
b3290c4c | 132 | if (chown(dir, -1, gid) < 0 && Perror(dir)) |
c76e0466 | 133 | return (1); |
b3290c4c KM |
134 | if (chdir(dir) < 0) { |
135 | Perror(dir); | |
136 | return (1); | |
137 | } | |
138 | if ((dirp = opendir(".")) == NULL) { | |
139 | Perror(dir); | |
140 | return (1); | |
141 | } | |
68e6b419 KM |
142 | dp = readdir(dirp); |
143 | dp = readdir(dirp); /* read "." and ".." */ | |
c76e0466 | 144 | ecode = 0; |
68e6b419 | 145 | for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { |
b3290c4c KM |
146 | if (lstat(dp->d_name, &st) < 0) { |
147 | ecode = Perror(dp->d_name); | |
c76e0466 SL |
148 | if (ecode) |
149 | break; | |
150 | continue; | |
151 | } | |
038208f4 MK |
152 | if (uid && uid != st.st_uid) { |
153 | ecode = error("You are not the owner of %s", | |
154 | dp->d_name); | |
155 | continue; | |
156 | } | |
9c3d388c | 157 | if ((st.st_mode & S_IFMT) == S_IFDIR) { |
735727c9 | 158 | ecode = chownr(dp->d_name); |
c76e0466 SL |
159 | if (ecode) |
160 | break; | |
161 | continue; | |
68e6b419 | 162 | } |
b3290c4c KM |
163 | if (chown(dp->d_name, -1, gid) < 0 && |
164 | (ecode = Perror(dp->d_name))) | |
c76e0466 | 165 | break; |
68e6b419 KM |
166 | } |
167 | closedir(dirp); | |
c76e0466 SL |
168 | if (chdir(savedir) < 0) |
169 | fatal(255, "can't change back to %s", savedir); | |
170 | return (ecode); | |
171 | } | |
172 | ||
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 | ||
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 | ||
195 | Perror(s) | |
196 | char *s; | |
197 | { | |
198 | ||
b3290c4c KM |
199 | if (!fflag) { |
200 | fprintf(stderr, "chgrp: "); | |
201 | perror(s); | |
202 | } | |
203 | return (!fflag); | |
68e6b419 | 204 | } |