BSD 4_3 release
[unix-history] / usr / src / etc / chown.c
CommitLineData
da158ee3
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
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
c76e0466 11#endif
da158ee3
DF
12
13#ifndef lint
95f51977 14static char sccsid[] = "@(#)chown.c 5.6 (Berkeley) 5/29/86";
c76e0466 15#endif
702e3fe5 16
69e53de7 17/*
c20a3dbc 18 * chown [-fR] uid[.gid] file ...
69e53de7
BJ
19 */
20
21#include <stdio.h>
22#include <ctype.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <pwd.h>
702e3fe5
KM
26#include <sys/dir.h>
27#include <grp.h>
c76e0466 28#include <strings.h>
69e53de7 29
c76e0466
SL
30struct passwd *pwd;
31struct passwd *getpwnam();
32struct stat stbuf;
69e53de7
BJ
33int uid;
34int status;
c76e0466
SL
35int fflag;
36int rflag;
69e53de7
BJ
37
38main(argc, argv)
c76e0466 39 char *argv[];
69e53de7 40{
702e3fe5 41 register int c, gid;
c76e0466 42 register char *cp, *group;
702e3fe5 43 struct group *grp;
69e53de7 44
c76e0466
SL
45 argc--, argv++;
46 while (argc > 0 && argv[0][0] == '-') {
47 for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
48
49 case 'f':
50 fflag++;
51 break;
52
53 case 'R':
54 rflag++;
55 break;
56
57 default:
58 fatal(255, "unknown option: %c", *cp);
59 }
60 argv++, argc--;
61 }
62 if (argc < 2) {
c20a3dbc 63 fprintf(stderr, "usage: chown [-fR] owner[.group] file ...\n");
702e3fe5 64 exit(-1);
69e53de7 65 }
0d1910d5 66 gid = -1;
c76e0466
SL
67 group = index(argv[0], '.');
68 if (group != NULL) {
69 *group++ = '\0';
70 if (!isnumber(group)) {
71 if ((grp = getgrnam(group)) == NULL)
72 fatal(255, "unknown group: %s",group);
73 gid = grp -> gr_gid;
0d1910d5
JB
74 (void) endgrent();
75 } else if (*group != '\0')
c76e0466 76 gid = atoi(group);
9a5d5654 77 }
c76e0466
SL
78 if (!isnumber(argv[0])) {
79 if ((pwd = getpwnam(argv[0])) == NULL)
80 fatal(255, "unknown user id: %s",argv[0]);
702e3fe5 81 uid = pwd->pw_uid;
c76e0466
SL
82 } else
83 uid = atoi(argv[0]);
84 for (c = 1; c < argc; c++) {
85 /* do stat for directory arguments */
80eff57a
KM
86 if (lstat(argv[c], &stbuf) < 0) {
87 status += Perror(argv[c]);
c76e0466 88 continue;
702e3fe5 89 }
d1c92693 90 if (rflag && ((stbuf.st_mode&S_IFMT) == S_IFDIR)) {
0d1910d5 91 status += chownr(argv[c], uid, gid);
c76e0466
SL
92 continue;
93 }
94 if (chown(argv[c], uid, gid)) {
80eff57a 95 status += Perror(argv[c]);
c76e0466 96 continue;
69e53de7
BJ
97 }
98 }
99 exit(status);
100}
101
102isnumber(s)
c76e0466 103 char *s;
69e53de7
BJ
104{
105 register c;
106
107 while(c = *s++)
c76e0466
SL
108 if (!isdigit(c))
109 return (0);
110 return (1);
69e53de7 111}
702e3fe5 112
0d1910d5 113chownr(dir, uid, gid)
c76e0466 114 char *dir;
702e3fe5 115{
c76e0466
SL
116 register DIR *dirp;
117 register struct direct *dp;
0d1910d5 118 struct stat st;
c76e0466 119 char savedir[1024];
0d1910d5
JB
120 int ecode;
121 extern char *getwd();
702e3fe5 122
0d1910d5 123 if (getwd(savedir) == (char *)0)
c76e0466
SL
124 fatal(255, "%s", savedir);
125 /*
126 * Change what we are given before doing it's contents.
127 */
80eff57a 128 if (chown(dir, uid, gid) < 0 && Perror(dir))
c76e0466 129 return (1);
80eff57a
KM
130 if (chdir(dir) < 0) {
131 Perror(dir);
132 return (1);
133 }
134 if ((dirp = opendir(".")) == NULL) {
135 Perror(dir);
136 return (1);
137 }
702e3fe5
KM
138 dp = readdir(dirp);
139 dp = readdir(dirp); /* read "." and ".." */
c76e0466 140 ecode = 0;
702e3fe5 141 for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
80eff57a
KM
142 if (lstat(dp->d_name, &st) < 0) {
143 ecode = Perror(dp->d_name);
c76e0466
SL
144 if (ecode)
145 break;
146 continue;
702e3fe5 147 }
d1c92693 148 if ((st.st_mode&S_IFMT) == S_IFDIR) {
0d1910d5 149 ecode = chownr(dp->d_name, uid, gid);
c76e0466
SL
150 if (ecode)
151 break;
152 continue;
153 }
154 if (chown(dp->d_name, uid, gid) < 0 &&
80eff57a 155 (ecode = Perror(dp->d_name)))
c76e0466 156 break;
702e3fe5
KM
157 }
158 closedir(dirp);
c76e0466
SL
159 if (chdir(savedir) < 0)
160 fatal(255, "can't change back to %s", savedir);
161 return (ecode);
162}
163
164error(fmt, a)
165 char *fmt, *a;
166{
167
168 if (!fflag) {
169 fprintf(stderr, "chown: ");
170 fprintf(stderr, fmt, a);
171 putc('\n', stderr);
172 }
173 return (!fflag);
174}
175
176fatal(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
186Perror(s)
187 char *s;
188{
189
80eff57a
KM
190 if (!fflag) {
191 fprintf(stderr, "chown: ");
192 perror(s);
193 }
194 return (!fflag);
702e3fe5 195}