coverity appeasement - redundant check
[minix.git] / commands / chown / chown.c
blobe1b425bc7f70f1b14a21d48a12eced8fab680b95
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, hflag = 0;
35 char *pgmname, path[PATH_MAX + 1];
36 uid_t nuid;
37 gid_t ngid;
39 int main(int argc, char **argv);
40 void do_chown(char *file);
41 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".
48 int main(argc, argv)
49 int argc;
50 char *argv[];
52 char *id, *id2;
53 struct group *grp;
54 struct passwd *pwp;
55 int ch;
57 if (pgmname = strrchr(*argv, '/'))
58 pgmname++;
59 else
60 pgmname = *argv;
61 gflag = strcmp(pgmname, "chgrp");
63 while((ch = getopt(argc, argv, "Rh")) != -1) {
64 switch(ch) {
65 case 'R':
66 rflag = 1;
67 break;
68 case 'h':
69 hflag = 1;
70 break;
71 default:
72 usage();
76 argc -= optind;
77 argv += optind;
79 if (argc < 2) usage();
81 id = *argv++;
82 argc--;
83 if (id2 = strchr(id, ':')) *id2++ = '\0';
84 if (!id2 && !gflag) {
85 id2 = id;
86 id = 0;
88 if (id) {
89 if (isdigit(*id))
90 nuid = atoi(id);
91 else {
92 if (!(pwp = getpwnam(id))) {
93 std_err(id);
94 std_err(": unknown user name\n");
95 exit(1);
97 nuid = pwp->pw_uid;
99 oflag = 1;
100 } else
101 oflag = 0;
103 if (id2) {
104 if (isdigit(*id2))
105 ngid = atoi(id2);
106 else {
107 if (!(grp = getgrnam(id2))) {
108 std_err(id2);
109 std_err(": unknown group name\n");
110 exit(1);
112 ngid = grp->gr_gid;
114 gflag = 1;
115 } else
116 gflag = 0;
118 error = 0;
119 while (argc--) do_chown(*argv++);
120 return(error);
123 /* Apply the user/group modification here.
125 void do_chown(file)
126 char *file;
128 DIR *dirp;
129 struct dirent *entp;
130 char *namp;
131 struct stat st;
133 if (lstat(file, &st)) {
134 perror(file);
135 error = 1;
136 return;
139 if (S_ISLNK(st.st_mode) && rflag) return; /* Note: violates POSIX. */
141 if (S_ISLNK(st.st_mode) && hflag) {
142 fprintf(stderr, "chown: cannot lchown %s\n", file);
143 error = 1;
146 if (chown(file, oflag ? nuid : st.st_uid, gflag ? ngid : st.st_gid)) {
147 perror(file);
148 error = 1;
151 if (S_ISDIR(st.st_mode) && rflag) {
152 if (!(dirp = opendir(file))) {
153 perror(file);
154 error = 1;
155 return;
157 if (path != file) strcpy(path, file);
158 namp = path + strlen(path);
159 *namp++ = '/';
160 while (entp = readdir(dirp))
161 if (entp->d_name[0] != '.' ||
162 (entp->d_name[1] &&
163 (entp->d_name[1] != '.' || entp->d_name[2]))) {
164 strcpy(namp, entp->d_name);
165 do_chown(path);
167 closedir(dirp);
168 *--namp = '\0';
172 /* Posix prototype of the chown/chgrp function */
173 void usage()
175 std_err("Usage: ");
176 std_err(pgmname);
177 std_err(gflag ? " owner[:group]" : " [owner:]group");
178 std_err(" file...\n");
179 exit(1);