try to make sure that path-addrs always have <angle brackets>
[unix-history] / usr / src / usr.sbin / chown / chgrp.c
CommitLineData
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 8static 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
23struct group *gr, *getgrnam(), *getgrgid();
24struct passwd *getpwuid(), *pwd;
25struct stat stbuf;
85f1f03c 26int gid, uid;
de68ad37 27int status;
68e6b419 28int fflag, rflag;
5f0e98a5
BJ
29/* VARARGS */
30int fprintf();
de68ad37
BJ
31
32main(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
84ok:
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
107isnumber(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 118chownr(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
173error(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
185fatal(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
195Perror(s)
196 char *s;
197{
198
b3290c4c
KM
199 if (!fflag) {
200 fprintf(stderr, "chgrp: ");
201 perror(s);
202 }
203 return (!fflag);
68e6b419 204}