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 |
038208f4 | 8 | static char sccsid[] = "@(#)chgrp.c 5.3 (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: | |
52 | fatal(255, "unknown option: %s", *cp); | |
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 SL |
86 | /* do stat for directory arguments */ |
87 | if (stat(argv[c], &stbuf)) { | |
88 | status += error("can't access %s", 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 | } | |
c76e0466 | 95 | if (rflag && stbuf.st_mode & S_IFDIR) { |
68e6b419 | 96 | status += chownr(argv[c], stbuf.st_uid, gid); |
c76e0466 SL |
97 | continue; |
98 | } | |
99 | if (chown(argv[c], stbuf.st_uid, gid)) { | |
100 | status += error("can't change %s", argv[c]); | |
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 KM |
117 | |
118 | chownr(dir, uid, gid) | |
c76e0466 | 119 | char *dir; |
68e6b419 | 120 | { |
c76e0466 SL |
121 | register DIR *dirp; |
122 | register struct direct *dp; | |
123 | register struct stat st; | |
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 SL |
131 | */ |
132 | if (chown(dir, uid, gid) < 0 && error("can't change %s", dir)) | |
133 | return (1); | |
134 | if (chdir(dir) < 0) | |
135 | return (Perror(dir)); | |
136 | if ((dirp = opendir(".")) == NULL) | |
137 | return (Perror(dir)); | |
68e6b419 KM |
138 | dp = readdir(dirp); |
139 | dp = readdir(dirp); /* read "." and ".." */ | |
c76e0466 | 140 | ecode = 0; |
68e6b419 | 141 | for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { |
c76e0466 SL |
142 | if (stat(dp->d_name, &st) < 0) { |
143 | ecode = error("can't access %s", dp->d_name); | |
144 | if (ecode) | |
145 | break; | |
146 | continue; | |
147 | } | |
038208f4 MK |
148 | if (uid && uid != st.st_uid) { |
149 | ecode = error("You are not the owner of %s", | |
150 | dp->d_name); | |
151 | continue; | |
152 | } | |
c76e0466 SL |
153 | if (st.st_mode&S_IFDIR) { |
154 | ecode = chownr(dp->d_name, st.st_uid, gid); | |
155 | if (ecode) | |
156 | break; | |
157 | continue; | |
68e6b419 | 158 | } |
c76e0466 SL |
159 | if (chown(dp->d_name, st.st_uid, gid) < 0 && |
160 | (ecode = error("can't change %s", dp->d_name))) | |
161 | break; | |
68e6b419 KM |
162 | } |
163 | closedir(dirp); | |
c76e0466 SL |
164 | if (chdir(savedir) < 0) |
165 | fatal(255, "can't change back to %s", savedir); | |
166 | return (ecode); | |
167 | } | |
168 | ||
169 | error(fmt, a) | |
170 | char *fmt, *a; | |
171 | { | |
172 | ||
173 | if (!fflag) { | |
174 | fprintf(stderr, "chgrp: "); | |
175 | fprintf(stderr, fmt, a); | |
176 | putc('\n', stderr); | |
177 | } | |
178 | return (!fflag); | |
179 | } | |
180 | ||
181 | fatal(status, fmt, a) | |
182 | int status; | |
183 | char *fmt, *a; | |
184 | { | |
185 | ||
186 | fflag = 0; | |
187 | (void) error(fmt, a); | |
188 | exit(status); | |
189 | } | |
190 | ||
191 | Perror(s) | |
192 | char *s; | |
193 | { | |
194 | ||
195 | fprintf(stderr, "chgrp: "); | |
196 | perror(s); | |
197 | return (1); | |
68e6b419 | 198 | } |