source: trunk/minix/commands/simple/chown.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.3 KB
Line 
1/* chown/chgrp - Change file ownership Author: V. Archer */
2
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 */
8
9/* Changed 3 Feb 93 by Kees J. Bot: setuid execution nonsense removed.
10 */
11
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>
25
26#ifndef S_ISLNK
27#define S_ISLNK(mode) 0
28#define lstat stat
29#endif
30
31#define S_IUGID (S_ISUID|S_ISGID)
32
33/* Global variables, such as flags and path names */
34int gflag, oflag, rflag, error;
35char *pgmname, path[PATH_MAX + 1];
36uid_t nuid;
37gid_t ngid;
38
39_PROTOTYPE(int main, (int argc, char **argv));
40_PROTOTYPE(void do_chown, (char *file));
41_PROTOTYPE(void usage, (void));
42
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.
50 */
51int main(argc, argv)
52int argc;
53char *argv[];
54{
55 char *id, *id2;
56 struct group *grp;
57 struct passwd *pwp;
58
59 if (pgmname = strrchr(*argv, '/'))
60 pgmname++;
61 else
62 pgmname = *argv;
63 argc--;
64 argv++;
65 gflag = strcmp(pgmname, "chgrp");
66
67 if (argc && **argv == '-' && argv[0][1] == 'R') {
68 argc--;
69 argv++;
70 rflag = 1;
71 }
72 if (argc < 2) usage();
73
74 id = *argv++;
75 argc--;
76 if (id2 = strchr(id, ':')) *id2++ = '\0';
77 if (!id2 && !gflag) {
78 id2 = id;
79 id = 0;
80 }
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);
89 }
90 nuid = pwp->pw_uid;
91 }
92 oflag = 1;
93 } else
94 oflag = 0;
95
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);
104 }
105 ngid = grp->gr_gid;
106 }
107 gflag = 1;
108 } else
109 gflag = 0;
110
111 error = 0;
112 while (argc--) do_chown(*argv++);
113 return(error);
114}
115
116/* Apply the user/group modification here.
117 */
118void do_chown(file)
119char *file;
120{
121 DIR *dirp;
122 struct dirent *entp;
123 char *namp;
124 struct stat st;
125
126 if (lstat(file, &st)) {
127 perror(file);
128 error = 1;
129 return;
130 }
131
132 if (S_ISLNK(st.st_mode) && rflag) return; /* Note: violates POSIX. */
133
134 if (chown(file, oflag ? nuid : st.st_uid, gflag ? ngid : st.st_gid)) {
135 perror(file);
136 error = 1;
137 }
138
139 if (S_ISDIR(st.st_mode) && rflag) {
140 if (!(dirp = opendir(file))) {
141 perror(file);
142 error = 1;
143 return;
144 }
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);
154 }
155 closedir(dirp);
156 *--namp = '\0';
157 }
158}
159
160/* Posix prototype of the chown/chgrp function */
161void usage()
162{
163 std_err("Usage: ");
164 std_err(pgmname);
165 std_err(gflag ? " owner[:group]" : " [owner:]group");
166 std_err(" file...\n");
167 exit(1);
168}
Note: See TracBrowser for help on using the repository browser.