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: #if !defined(lint) && defined(DOSCCS) 8: static char sccsid[] = "@(#)chgrp.c 5.7.1 (2.11BSD GTE) 11/4/94"; 9: #endif 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/file.h> 19: #include <sys/stat.h> 20: #include <grp.h> 21: #include <pwd.h> 22: #include <sys/dir.h> 23: 24: struct group *gr, *getgrnam(), *getgrgid(); 25: struct passwd *getpwuid(), *pwd; 26: struct stat stbuf; 27: gid_t gid; 28: uid_t uid; 29: int status; 30: int fflag, rflag; 31: static char *fchdirmsg = "Can't fchdir() back to starting directory"; 32: 33: main(argc, argv) 34: int argc; 35: char *argv[]; 36: { 37: register c, i; 38: register char *cp; 39: int fcurdir; 40: 41: argc--, argv++; 42: while (argc > 0 && argv[0][0] == '-') { 43: for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { 44: 45: case 'f': 46: fflag++; 47: break; 48: 49: case 'R': 50: rflag++; 51: break; 52: 53: default: 54: fatal(255, "unknown option: %c", *cp); 55: /*NOTREACHED*/ 56: } 57: argv++, argc--; 58: } 59: if (argc < 2) { 60: fprintf(stderr, "usage: chgrp [-fR] gid file ...\n"); 61: exit(255); 62: } 63: uid = getuid(); 64: if (isnumber(argv[0])) { 65: gid = atoi(argv[0]); 66: gr = getgrgid(gid); 67: if (uid && gr == NULL) 68: fatal(255, "%s: unknown group", argv[0]); 69: } else { 70: gr = getgrnam(argv[0]); 71: if (gr == NULL) 72: fatal(255, "%s: unknown group", argv[0]); 73: gid = gr->gr_gid; 74: } 75: pwd = getpwuid(uid); 76: if (pwd == NULL) 77: fatal(255, "Who are you?"); 78: if (uid && pwd->pw_gid != gid) { 79: for (i=0; gr->gr_mem[i]; i++) 80: if (!(strcmp(pwd->pw_name, gr->gr_mem[i]))) 81: goto ok; 82: if (fflag) 83: exit(0); 84: fatal(255, "You are not a member of the %s group", argv[0]); 85: } 86: ok: 87: fcurdir = open(".", O_RDONLY); 88: if (fcurdir < 0) 89: fatal(255, "Can't open ."); 90: 91: for (c = 1; c < argc; c++) { 92: /* do stat for directory arguments */ 93: if (lstat(argv[c], &stbuf)) { 94: status += Perror(argv[c]); 95: continue; 96: } 97: if (uid && uid != stbuf.st_uid) { 98: status += error("You are not the owner of %s", argv[c]); 99: continue; 100: } 101: if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFDIR)) { 102: status += chownr(argv[c], stbuf.st_uid, gid, fcurdir); 103: continue; 104: } 105: if (chown(argv[c], -1, gid)) { 106: status += Perror(argv[c]); 107: continue; 108: } 109: } 110: exit(status); 111: } 112: 113: isnumber(s) 114: char *s; 115: { 116: register int c; 117: 118: while (c = *s++) 119: if (!isdigit(c)) 120: return (0); 121: return (1); 122: } 123: 124: chownr(dir, uid, gid, savedir) 125: char *dir; 126: uid_t uid; 127: gid_t gid; 128: int savedir; 129: { 130: register DIR *dirp; 131: register struct direct *dp; 132: struct stat st; 133: int ecode; 134: 135: /* 136: * Change what we are given before doing its contents. 137: */ 138: if (chown(dir, -1, gid) < 0 && Perror(dir)) 139: return (1); 140: if (chdir(dir) < 0) { 141: Perror(dir); 142: return (1); 143: } 144: if ((dirp = opendir(".")) == NULL) { 145: Perror(dir); 146: return (1); 147: } 148: dp = readdir(dirp); 149: dp = readdir(dirp); /* read "." and ".." */ 150: ecode = 0; 151: for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 152: if (lstat(dp->d_name, &st) < 0) { 153: ecode = Perror(dp->d_name); 154: if (ecode) 155: break; 156: continue; 157: } 158: if (uid && uid != st.st_uid) { 159: ecode = error("You are not the owner of %s", 160: dp->d_name); 161: continue; 162: } 163: if ((st.st_mode & S_IFMT) == S_IFDIR) { 164: ecode = chownr(dp->d_name, st.st_uid, gid, dirfd(dirp)); 165: if (ecode) 166: break; 167: continue; 168: } 169: if (chown(dp->d_name, -1, gid) < 0 && 170: (ecode = Perror(dp->d_name))) 171: break; 172: } 173: if (fchdir(savedir) < 0) 174: fatal(255, fchdirmsg); 175: closedir(dirp); 176: return (ecode); 177: } 178: 179: error(fmt, a) 180: char *fmt, *a; 181: { 182: 183: if (!fflag) { 184: fprintf(stderr, "chgrp: "); 185: fprintf(stderr, fmt, a); 186: putc('\n', stderr); 187: } 188: return (!fflag); 189: } 190: 191: /* VARARGS */ 192: fatal(status, fmt, a) 193: int status; 194: char *fmt, *a; 195: { 196: 197: fflag = 0; 198: (void) error(fmt, a); 199: exit(status); 200: } 201: 202: Perror(s) 203: char *s; 204: { 205: 206: if (!fflag) { 207: fprintf(stderr, "chgrp: "); 208: perror(s); 209: } 210: return (!fflag); 211: }