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