Someone forgot that ioctl.h didn't require types.h
[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
038208f4 8static 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
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:
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
84ok:
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
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
KM
117
118chownr(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
169error(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
181fatal(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
191Perror(s)
192 char *s;
193{
194
195 fprintf(stderr, "chgrp: ");
196 perror(s);
197 return (1);
68e6b419 198}