Commit | Line | Data |
---|---|---|
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 |
8 | static 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 |
23 | struct group *gr, *getgrnam(), *getgrgid(); |
24 | struct passwd *getpwuid(), *pwd; | |
25 | struct stat stbuf; | |
85f1f03c | 26 | int gid, uid; |
de68ad37 | 27 | int status; |
68e6b419 | 28 | int fflag, rflag; |
5f0e98a5 BJ |
29 | /* VARARGS */ |
30 | int fprintf(); | |
de68ad37 BJ |
31 | |
32 | main(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 |
87 | ok: |
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 | ||
109 | isnumber(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 | |
120 | chownr(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 | } |