xref: /original-bsd/usr.sbin/chown/chgrp.c (revision 6219b5e8)
1 #ifndef lint
2 static	char *sccsid = "@(#)chgrp.c	4.8 85/03/20";
3 #endif
4 
5 /*
6  * chgrp -fR gid file ...
7  */
8 
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <grp.h>
14 #include <pwd.h>
15 #include <sys/dir.h>
16 
17 struct	group *gr, *getgrnam(), *getgrgid();
18 struct	passwd *getpwuid(), *pwd;
19 struct	stat stbuf;
20 int	gid, uid;
21 int	status;
22 int	fflag, rflag;
23 /* VARARGS */
24 int	fprintf();
25 
26 main(argc, argv)
27 	int argc;
28 	char *argv[];
29 {
30 	register c, i;
31 	register char *flags;
32 
33 	argc--, argv++;
34 	if (*argv[0] == '-') {
35 		for (flags = argv[0]; *flags; ++flags)
36 			switch (*flags) {
37 			  case '-':			break;
38 			  case 'f': 	fflag++;	break;
39 			  case 'R':	rflag++;	break;
40 			  default:
41 				printf("chgrp: unknown option: %s\n", *flags);
42 				exit(255);
43 			}
44 		argv++, argc--;
45 	}
46 	if (argc < 2) {
47 		fprintf(stderr, "usage: chgrp [-fR] gid file ...\n");
48 		exit(255);
49 	}
50 	uid = getuid();
51 	if (isnumber(argv[0])) {
52 		gid = atoi(argv[0]);
53 		gr = getgrgid(gid);
54 		if (uid && gr == NULL) {
55 			fprintf(stderr, "%s: unknown group\n", argv[0]);
56 			exit(255);
57 		}
58 	} else {
59 		gr = getgrnam(argv[0]);
60 		if (gr == NULL) {
61 			fprintf(stderr, "%s: unknown group\n", argv[0]);
62 			exit(255);
63 		}
64 		gid = gr->gr_gid;
65 	}
66 	pwd = getpwuid(uid);
67 	if (pwd == NULL) {
68 		fprintf(stderr, "Who are you?\n");
69 		exit(255);
70 	}
71 	if (uid && pwd->pw_gid != gid) {
72 		for (i=0; gr->gr_mem[i]; i++)
73 			if (!(strcmp(pwd->pw_name, gr->gr_mem[i])))
74 				goto ok;
75 		if (fflag)
76 			exit(0);
77 		fprintf(stderr, "You are not a member of the %s group.\n",
78 		    		argv[0]);
79 		exit(255);
80 	}
81 ok:
82 	for (c = 1; c < argc; c++) {
83 		if (lstat(argv[c], &stbuf)) {
84 			perror(argv[c]);
85 			continue;
86 		}
87 		if (uid && uid != stbuf.st_uid) {
88 			if (fflag)
89 				continue;
90 			fprintf(stderr, "You are not the owner of %s\n"
91 				      , argv[c]);
92 			++status;
93 			continue;
94 		}
95 		if (rflag && stbuf.st_mode & S_IFDIR)
96 			status += chownr(argv[c], stbuf.st_uid, gid);
97 		else if (chown(argv[c], stbuf.st_uid, gid) && !fflag)
98 			perror(argv[c]);
99 	}
100 	exit(status);
101 }
102 
103 isnumber(s)
104 	char *s;
105 {
106 	register int c;
107 
108 	while (c = *s++)
109 		if (!isdigit(c))
110 			return (0);
111 	return (1);
112 }
113 
114 chownr(dir, uid, gid)
115 	char	*dir;
116 {
117 	register DIR		*dirp;
118 	register struct direct	*dp;
119 	register struct stat	st;
120 	char			savedir[1024];
121 
122 	if (getwd(savedir) == 0) {
123 		fprintf(stderr, "chgrp: %s\n", savedir);
124 		exit(255);
125 	}
126 	if (chown(dir, uid, gid) < 0 && !fflag) {
127 		perror(dir);
128 		return(1);
129 	}
130 
131 	chdir(dir);
132 	if ((dirp = opendir(".")) == NULL) {
133 		perror(dir);
134 		exit(status);
135 	}
136 	dp = readdir(dirp);
137 	dp = readdir(dirp); /* read "." and ".." */
138 
139 	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
140 		if (lstat(dp->d_name, &st) < 0) {
141 			fprintf(stderr, "chgrp: can't access %s\n", dp->d_name);
142 			return(1);
143 		}
144 		if (st.st_mode & S_IFDIR)
145 			chownr(dp->d_name, st.st_uid, gid);
146 		else
147 			if (chown(dp->d_name, st.st_uid, gid) < 0 && !fflag) {
148 				perror(dp->d_name);
149 				return(1);
150 			}
151 	}
152 	closedir(dirp);
153 	chdir(savedir);
154 	return(0);
155 }
156