xref: /csrg-svn/usr.sbin/chown/chgrp.c (revision 18451)
16392Sroot #ifndef lint
2*18451Smckusick static	char *sccsid = "@(#)chgrp.c	4.8 85/03/20";
36392Sroot #endif
46392Sroot 
5974Sbill /*
6*18451Smckusick  * chgrp -fR gid file ...
7974Sbill  */
8974Sbill 
9974Sbill #include <stdio.h>
10974Sbill #include <ctype.h>
11974Sbill #include <sys/types.h>
12974Sbill #include <sys/stat.h>
13974Sbill #include <grp.h>
146037Swnj #include <pwd.h>
15*18451Smckusick #include <sys/dir.h>
16974Sbill 
176392Sroot struct	group *gr, *getgrnam(), *getgrgid();
186392Sroot struct	passwd *getpwuid(), *pwd;
196392Sroot struct	stat stbuf;
206037Swnj int	gid, uid;
21974Sbill int	status;
22*18451Smckusick int	fflag, rflag;
236392Sroot /* VARARGS */
246392Sroot int	fprintf();
25974Sbill 
26974Sbill main(argc, argv)
276392Sroot 	int argc;
286392Sroot 	char *argv[];
29974Sbill {
306037Swnj 	register c, i;
31*18451Smckusick 	register char *flags;
32974Sbill 
336392Sroot 	argc--, argv++;
34*18451Smckusick 	if (*argv[0] == '-') {
35*18451Smckusick 		for (flags = argv[0]; *flags; ++flags)
36*18451Smckusick 			switch (*flags) {
37*18451Smckusick 			  case '-':			break;
38*18451Smckusick 			  case 'f': 	fflag++;	break;
39*18451Smckusick 			  case 'R':	rflag++;	break;
40*18451Smckusick 			  default:
41*18451Smckusick 				printf("chgrp: unknown option: %s\n", *flags);
42*18451Smckusick 				exit(255);
43*18451Smckusick 			}
4412075Sralph 		argv++, argc--;
4512075Sralph 	}
466392Sroot 	if (argc < 2) {
47*18451Smckusick 		fprintf(stderr, "usage: chgrp [-fR] gid file ...\n");
48*18451Smckusick 		exit(255);
49974Sbill 	}
506037Swnj 	uid = getuid();
516392Sroot 	if (isnumber(argv[0])) {
5210426Ssam 		gid = atoi(argv[0]);
536392Sroot 		gr = getgrgid(gid);
546392Sroot 		if (uid && gr == NULL) {
55*18451Smckusick 			fprintf(stderr, "%s: unknown group\n", argv[0]);
56*18451Smckusick 			exit(255);
576037Swnj 		}
58974Sbill 	} else {
596392Sroot 		gr = getgrnam(argv[0]);
606392Sroot 		if (gr == NULL) {
61*18451Smckusick 			fprintf(stderr, "%s: unknown group\n", argv[0]);
62*18451Smckusick 			exit(255);
63974Sbill 		}
64974Sbill 		gid = gr->gr_gid;
65974Sbill 	}
666392Sroot 	pwd = getpwuid(uid);
676392Sroot 	if (pwd == NULL) {
686392Sroot 		fprintf(stderr, "Who are you?\n");
69*18451Smckusick 		exit(255);
706037Swnj 	}
716392Sroot 	if (uid && pwd->pw_gid != gid) {
726392Sroot 		for (i=0; gr->gr_mem[i]; i++)
736392Sroot 			if (!(strcmp(pwd->pw_name, gr->gr_mem[i])))
746392Sroot 				goto ok;
7512075Sralph 		if (fflag)
7612075Sralph 			exit(0);
776392Sroot 		fprintf(stderr, "You are not a member of the %s group.\n",
78*18451Smckusick 		    		argv[0]);
79*18451Smckusick 		exit(255);
806037Swnj 	}
816392Sroot ok:
826392Sroot 	for (c = 1; c < argc; c++) {
8315583Smckusick 		if (lstat(argv[c], &stbuf)) {
846392Sroot 			perror(argv[c]);
856392Sroot 			continue;
866392Sroot 		}
876037Swnj 		if (uid && uid != stbuf.st_uid) {
8812075Sralph 			if (fflag)
8912075Sralph 				continue;
90*18451Smckusick 			fprintf(stderr, "You are not the owner of %s\n"
91*18451Smckusick 				      , argv[c]);
92*18451Smckusick 			++status;
936392Sroot 			continue;
946392Sroot 		}
95*18451Smckusick 		if (rflag && stbuf.st_mode & S_IFDIR)
96*18451Smckusick 			status += chownr(argv[c], stbuf.st_uid, gid);
97*18451Smckusick 		else if (chown(argv[c], stbuf.st_uid, gid) && !fflag)
986392Sroot 			perror(argv[c]);
99974Sbill 	}
100974Sbill 	exit(status);
101974Sbill }
102974Sbill 
103974Sbill isnumber(s)
1046392Sroot 	char *s;
105974Sbill {
1066392Sroot 	register int c;
107974Sbill 
1086392Sroot 	while (c = *s++)
1096392Sroot 		if (!isdigit(c))
1106392Sroot 			return (0);
1116392Sroot 	return (1);
112974Sbill }
113*18451Smckusick 
114*18451Smckusick chownr(dir, uid, gid)
115*18451Smckusick 	char	*dir;
116*18451Smckusick {
117*18451Smckusick 	register DIR		*dirp;
118*18451Smckusick 	register struct direct	*dp;
119*18451Smckusick 	register struct stat	st;
120*18451Smckusick 	char			savedir[1024];
121*18451Smckusick 
122*18451Smckusick 	if (getwd(savedir) == 0) {
123*18451Smckusick 		fprintf(stderr, "chgrp: %s\n", savedir);
124*18451Smckusick 		exit(255);
125*18451Smckusick 	}
126*18451Smckusick 	if (chown(dir, uid, gid) < 0 && !fflag) {
127*18451Smckusick 		perror(dir);
128*18451Smckusick 		return(1);
129*18451Smckusick 	}
130*18451Smckusick 
131*18451Smckusick 	chdir(dir);
132*18451Smckusick 	if ((dirp = opendir(".")) == NULL) {
133*18451Smckusick 		perror(dir);
134*18451Smckusick 		exit(status);
135*18451Smckusick 	}
136*18451Smckusick 	dp = readdir(dirp);
137*18451Smckusick 	dp = readdir(dirp); /* read "." and ".." */
138*18451Smckusick 
139*18451Smckusick 	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
140*18451Smckusick 		if (lstat(dp->d_name, &st) < 0) {
141*18451Smckusick 			fprintf(stderr, "chgrp: can't access %s\n", dp->d_name);
142*18451Smckusick 			return(1);
143*18451Smckusick 		}
144*18451Smckusick 		if (st.st_mode & S_IFDIR)
145*18451Smckusick 			chownr(dp->d_name, st.st_uid, gid);
146*18451Smckusick 		else
147*18451Smckusick 			if (chown(dp->d_name, st.st_uid, gid) < 0 && !fflag) {
148*18451Smckusick 				perror(dp->d_name);
149*18451Smckusick 				return(1);
150*18451Smckusick 			}
151*18451Smckusick 	}
152*18451Smckusick 	closedir(dirp);
153*18451Smckusick 	chdir(savedir);
154*18451Smckusick 	return(0);
155*18451Smckusick }
156