xref: /csrg-svn/usr.sbin/chown/chgrp.c (revision 25936)
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.3 (Berkeley) 01/21/86";
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 
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: %s", *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 (stat(argv[c], &stbuf)) {
88 			status += error("can't access %s", 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_IFDIR) {
96 			status += chownr(argv[c], stbuf.st_uid, gid);
97 			continue;
98 		}
99 		if (chown(argv[c], stbuf.st_uid, gid)) {
100 			status += error("can't change %s", argv[c]);
101 			continue;
102 		}
103 	}
104 	exit(status);
105 }
106 
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 
118 chownr(dir, uid, gid)
119 	char *dir;
120 {
121 	register DIR *dirp;
122 	register struct direct *dp;
123 	register 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, 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));
138 	dp = readdir(dirp);
139 	dp = readdir(dirp); /* read "." and ".." */
140 	ecode = 0;
141 	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
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 		}
148 		if (uid && uid != st.st_uid) {
149 			ecode = error("You are not the owner of %s",
150 				dp->d_name);
151 			continue;
152 		}
153 		if (st.st_mode&S_IFDIR) {
154 			ecode = chownr(dp->d_name, st.st_uid, gid);
155 			if (ecode)
156 				break;
157 			continue;
158 		}
159 		if (chown(dp->d_name, st.st_uid, gid) < 0 &&
160 		    (ecode = error("can't change %s", dp->d_name)))
161 			break;
162 	}
163 	closedir(dirp);
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);
198 }
199