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