remove traces of benchmarks from test/.
[minix.git] / commands / simple / chown.c
bloba6a0f04ff28e340277e03c5caf212f3307eecb7e
1 /* chown/chgrp - Change file ownership Author: V. Archer */
3 /* Copyright 1991 by Vincent Archer
4 * You may freely redistribute this software, in source or binary
5 * form, provided that you do not alter this copyright mention in any
6 * way.
7 */
9 /* Changed 3 Feb 93 by Kees J. Bot: setuid execution nonsense removed.
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <ctype.h>
15 #include <dirent.h>
16 #include <pwd.h>
17 #include <grp.h>
18 #include <string.h>
19 #include <limits.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <minix/minlib.h>
24 #include <stdio.h>
26 #ifndef S_ISLNK
27 #define S_ISLNK(mode) 0
28 #define lstat stat
29 #endif
31 #define S_IUGID (S_ISUID|S_ISGID)
33 /* Global variables, such as flags and path names */
34 int gflag, oflag, rflag, error;
35 char *pgmname, path[PATH_MAX + 1];
36 uid_t nuid;
37 gid_t ngid;
39 _PROTOTYPE(int main, (int argc, char **argv));
40 _PROTOTYPE(void do_chown, (char *file));
41 _PROTOTYPE(void usage, (void));
43 /* Main module. If chown(1) is invoked as chgrp(1), the behaviour is nearly
44 * identical, except that the default when a single name is given as an
45 * argument is to take a group id rather than an user id. This allow the
46 * non-Posix "chgrp user:group file".
47 * The single option switch used by chown/chgrp (-R) does not warrant a
48 * call to the getopt stuff. The two others flags (-g, -u) are set from
49 * the program name and arguments.
51 int main(argc, argv)
52 int argc;
53 char *argv[];
55 char *id, *id2;
56 struct group *grp;
57 struct passwd *pwp;
59 if (pgmname = strrchr(*argv, '/'))
60 pgmname++;
61 else
62 pgmname = *argv;
63 argc--;
64 argv++;
65 gflag = strcmp(pgmname, "chgrp");
67 if (argc && **argv == '-' && argv[0][1] == 'R') {
68 argc--;
69 argv++;
70 rflag = 1;
72 if (argc < 2) usage();
74 id = *argv++;
75 argc--;
76 if (id2 = strchr(id, ':')) *id2++ = '\0';
77 if (!id2 && !gflag) {
78 id2 = id;
79 id = 0;
81 if (id) {
82 if (isdigit(*id))
83 nuid = atoi(id);
84 else {
85 if (!(pwp = getpwnam(id))) {
86 std_err(id);
87 std_err(": unknown user name\n");
88 exit(1);
90 nuid = pwp->pw_uid;
92 oflag = 1;
93 } else
94 oflag = 0;
96 if (id2) {
97 if (isdigit(*id2))
98 ngid = atoi(id2);
99 else {
100 if (!(grp = getgrnam(id2))) {
101 std_err(id2);
102 std_err(": unknown group name\n");
103 exit(1);
105 ngid = grp->gr_gid;
107 gflag = 1;
108 } else
109 gflag = 0;
111 error = 0;
112 while (argc--) do_chown(*argv++);
113 return(error);
116 /* Apply the user/group modification here.
118 void do_chown(file)
119 char *file;
121 DIR *dirp;
122 struct dirent *entp;
123 char *namp;
124 struct stat st;
126 if (lstat(file, &st)) {
127 perror(file);
128 error = 1;
129 return;
132 if (S_ISLNK(st.st_mode) && rflag) return; /* Note: violates POSIX. */
134 if (chown(file, oflag ? nuid : st.st_uid, gflag ? ngid : st.st_gid)) {
135 perror(file);
136 error = 1;
139 if (S_ISDIR(st.st_mode) && rflag) {
140 if (!(dirp = opendir(file))) {
141 perror(file);
142 error = 1;
143 return;
145 if (path != file) strcpy(path, file);
146 namp = path + strlen(path);
147 *namp++ = '/';
148 while (entp = readdir(dirp))
149 if (entp->d_name[0] != '.' ||
150 (entp->d_name[1] &&
151 (entp->d_name[1] != '.' || entp->d_name[2]))) {
152 strcpy(namp, entp->d_name);
153 do_chown(path);
155 closedir(dirp);
156 *--namp = '\0';
160 /* Posix prototype of the chown/chgrp function */
161 void usage()
163 std_err("Usage: ");
164 std_err(pgmname);
165 std_err(gflag ? " owner[:group]" : " [owner:]group");
166 std_err(" file...\n");
167 exit(1);