119840Sdist /* 219840Sdist * Copyright (c) 1980 Regents of the University of California. 319840Sdist * All rights reserved. The Berkeley software License Agreement 419840Sdist * specifies the terms and conditions for redistribution. 519840Sdist */ 619840Sdist 76392Sroot #ifndef lint 8*26262Skarels static char sccsid[] = "@(#)chgrp.c 5.4 (Berkeley) 02/20/86"; 919840Sdist #endif not lint 106392Sroot 11974Sbill /* 1218451Smckusick * chgrp -fR gid file ... 13974Sbill */ 14974Sbill 15974Sbill #include <stdio.h> 16974Sbill #include <ctype.h> 17974Sbill #include <sys/types.h> 18974Sbill #include <sys/stat.h> 19974Sbill #include <grp.h> 206037Swnj #include <pwd.h> 2118451Smckusick #include <sys/dir.h> 22974Sbill 236392Sroot struct group *gr, *getgrnam(), *getgrgid(); 246392Sroot struct passwd *getpwuid(), *pwd; 256392Sroot struct stat stbuf; 266037Swnj int gid, uid; 27974Sbill int status; 2818451Smckusick int fflag, rflag; 296392Sroot /* VARARGS */ 306392Sroot int fprintf(); 31974Sbill 32974Sbill main(argc, argv) 336392Sroot int argc; 346392Sroot char *argv[]; 35974Sbill { 366037Swnj register c, i; 3724504Ssam register char *cp; 38974Sbill 396392Sroot argc--, argv++; 4024504Ssam while (argc > 0 && argv[0][0] == '-') { 4124504Ssam for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { 4224504Ssam 4324504Ssam case 'f': 4424504Ssam fflag++; 4524504Ssam break; 4624504Ssam 4724504Ssam case 'R': 4824504Ssam rflag++; 4924504Ssam break; 5024504Ssam 5124504Ssam default: 52*26262Skarels fatal(255, "unknown option: %c", *cp); 5324504Ssam /*NOTREACHED*/ 5424504Ssam } 5512075Sralph argv++, argc--; 5612075Sralph } 576392Sroot if (argc < 2) { 5818451Smckusick fprintf(stderr, "usage: chgrp [-fR] gid file ...\n"); 5918451Smckusick exit(255); 60974Sbill } 616037Swnj uid = getuid(); 626392Sroot if (isnumber(argv[0])) { 6310426Ssam gid = atoi(argv[0]); 646392Sroot gr = getgrgid(gid); 6524504Ssam if (uid && gr == NULL) 6624504Ssam fatal(255, "%s: unknown group", argv[0]); 67974Sbill } else { 686392Sroot gr = getgrnam(argv[0]); 6924504Ssam if (gr == NULL) 7024504Ssam fatal(255, "%s: unknown group", argv[0]); 71974Sbill gid = gr->gr_gid; 72974Sbill } 736392Sroot pwd = getpwuid(uid); 7424504Ssam if (pwd == NULL) 7524504Ssam fatal(255, "Who are you?"); 766392Sroot if (uid && pwd->pw_gid != gid) { 776392Sroot for (i=0; gr->gr_mem[i]; i++) 786392Sroot if (!(strcmp(pwd->pw_name, gr->gr_mem[i]))) 796392Sroot goto ok; 8012075Sralph if (fflag) 8112075Sralph exit(0); 8224504Ssam fatal(255, "You are not a member of the %s group", argv[0]); 836037Swnj } 846392Sroot ok: 856392Sroot for (c = 1; c < argc; c++) { 8624504Ssam /* do stat for directory arguments */ 8724504Ssam if (stat(argv[c], &stbuf)) { 8824504Ssam status += error("can't access %s", argv[c]); 896392Sroot continue; 906392Sroot } 916037Swnj if (uid && uid != stbuf.st_uid) { 9224504Ssam status += error("You are not the owner of %s", argv[c]); 936392Sroot continue; 946392Sroot } 9524504Ssam if (rflag && stbuf.st_mode & S_IFDIR) { 9618451Smckusick status += chownr(argv[c], stbuf.st_uid, gid); 9724504Ssam continue; 9824504Ssam } 9924504Ssam if (chown(argv[c], stbuf.st_uid, gid)) { 10024504Ssam status += error("can't change %s", argv[c]); 10124504Ssam continue; 10224504Ssam } 103974Sbill } 104974Sbill exit(status); 105974Sbill } 106974Sbill 107974Sbill isnumber(s) 1086392Sroot char *s; 109974Sbill { 1106392Sroot register int c; 111974Sbill 1126392Sroot while (c = *s++) 1136392Sroot if (!isdigit(c)) 1146392Sroot return (0); 1156392Sroot return (1); 116974Sbill } 11718451Smckusick 11818451Smckusick chownr(dir, uid, gid) 11924504Ssam char *dir; 12018451Smckusick { 12124504Ssam register DIR *dirp; 12224504Ssam register struct direct *dp; 12324504Ssam register struct stat st; 12424504Ssam char savedir[1024]; 12524504Ssam int ecode; 12618451Smckusick 12724504Ssam if (getwd(savedir) == 0) 12824504Ssam fatal(255, "%s", savedir); 12924504Ssam /* 13025936Skarels * Change what we are given before doing its contents. 13124504Ssam */ 13224504Ssam if (chown(dir, uid, gid) < 0 && error("can't change %s", dir)) 13324504Ssam return (1); 13424504Ssam if (chdir(dir) < 0) 13524504Ssam return (Perror(dir)); 13624504Ssam if ((dirp = opendir(".")) == NULL) 13724504Ssam return (Perror(dir)); 13818451Smckusick dp = readdir(dirp); 13918451Smckusick dp = readdir(dirp); /* read "." and ".." */ 14024504Ssam ecode = 0; 14118451Smckusick for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 14224504Ssam if (stat(dp->d_name, &st) < 0) { 14324504Ssam ecode = error("can't access %s", dp->d_name); 14424504Ssam if (ecode) 14524504Ssam break; 14624504Ssam continue; 14718451Smckusick } 14825936Skarels if (uid && uid != st.st_uid) { 14925936Skarels ecode = error("You are not the owner of %s", 15025936Skarels dp->d_name); 15125936Skarels continue; 15225936Skarels } 15324504Ssam if (st.st_mode&S_IFDIR) { 15424504Ssam ecode = chownr(dp->d_name, st.st_uid, gid); 15524504Ssam if (ecode) 15624504Ssam break; 15724504Ssam continue; 15824504Ssam } 15924504Ssam if (chown(dp->d_name, st.st_uid, gid) < 0 && 16024504Ssam (ecode = error("can't change %s", dp->d_name))) 16124504Ssam break; 16218451Smckusick } 16318451Smckusick closedir(dirp); 16424504Ssam if (chdir(savedir) < 0) 16524504Ssam fatal(255, "can't change back to %s", savedir); 16624504Ssam return (ecode); 16718451Smckusick } 16824504Ssam 16924504Ssam error(fmt, a) 17024504Ssam char *fmt, *a; 17124504Ssam { 17224504Ssam 17324504Ssam if (!fflag) { 17424504Ssam fprintf(stderr, "chgrp: "); 17524504Ssam fprintf(stderr, fmt, a); 17624504Ssam putc('\n', stderr); 17724504Ssam } 17824504Ssam return (!fflag); 17924504Ssam } 18024504Ssam 18124504Ssam fatal(status, fmt, a) 18224504Ssam int status; 18324504Ssam char *fmt, *a; 18424504Ssam { 18524504Ssam 18624504Ssam fflag = 0; 18724504Ssam (void) error(fmt, a); 18824504Ssam exit(status); 18924504Ssam } 19024504Ssam 19124504Ssam Perror(s) 19224504Ssam char *s; 19324504Ssam { 19424504Ssam 19524504Ssam fprintf(stderr, "chgrp: "); 19624504Ssam perror(s); 19724504Ssam return (1); 19824504Ssam } 199