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.2 (Berkeley) 08/31/85"; 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 it's 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 (st.st_mode&S_IFDIR) { 149 ecode = chownr(dp->d_name, st.st_uid, gid); 150 if (ecode) 151 break; 152 continue; 153 } 154 if (chown(dp->d_name, st.st_uid, gid) < 0 && 155 (ecode = error("can't change %s", dp->d_name))) 156 break; 157 } 158 closedir(dirp); 159 if (chdir(savedir) < 0) 160 fatal(255, "can't change back to %s", savedir); 161 return (ecode); 162 } 163 164 error(fmt, a) 165 char *fmt, *a; 166 { 167 168 if (!fflag) { 169 fprintf(stderr, "chgrp: "); 170 fprintf(stderr, fmt, a); 171 putc('\n', stderr); 172 } 173 return (!fflag); 174 } 175 176 fatal(status, fmt, a) 177 int status; 178 char *fmt, *a; 179 { 180 181 fflag = 0; 182 (void) error(fmt, a); 183 exit(status); 184 } 185 186 Perror(s) 187 char *s; 188 { 189 190 fprintf(stderr, "chgrp: "); 191 perror(s); 192 return (1); 193 } 194