/[baselayout]/trunk/src/checkown.c
Gentoo

Contents of /trunk/src/checkown.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2900 - (show annotations) (download) (as text)
Wed Sep 19 17:18:43 2007 UTC (10 years, 9 months ago) by uberlord
File MIME type: text/x-csrc
File size: 4001 byte(s)
Warn if file/directory mismatch
1 /*
2 checkown.c
3 Checks for the existance of a file or directory and creates it
4 if necessary. It can also correct its ownership.
5
6 Copyright 2007 Gentoo Foundation
7 */
8
9 #define APPLET "checkown"
10
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <getopt.h>
16 #include <grp.h>
17 #include <pwd.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22
23 #include "builtins.h"
24 #include "einfo.h"
25
26 static char *applet = NULL;
27
28 static int do_check (char *path, uid_t uid, gid_t gid, mode_t mode, int file)
29 {
30 struct stat st;
31
32 memset (&st, 0, sizeof (struct stat));
33
34 if (stat (path, &st)) {
35 if (file) {
36 int fd;
37 einfo ("%s: creating file", path);
38 if ((fd = open (path, O_CREAT)) == -1) {
39 eerror ("%s: open: %s", applet, strerror (errno));
40 return (-1);
41 }
42 close (fd);
43 } else {
44 einfo ("%s: creating directory", path);
45 if (! mode)
46 mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
47 if (mkdir (path, mode)) {
48 eerror ("%s: mkdir: %s", applet, strerror (errno));
49 return (-1);
50 }
51 mode = 0;
52 }
53 } else {
54 if ((file && S_ISDIR (st.st_mode)) ||
55 (! file && ! S_ISDIR (st.st_mode)))
56 {
57 if (file)
58 eerror ("%s: is a directory", path);
59 else
60 eerror ("%s: is a file", path);
61 return (-1);
62 }
63 }
64
65 if (mode && (st.st_mode & 0777) != mode) {
66 einfo ("%s: correcting mode", applet);
67 if (chmod (path, mode)) {
68 eerror ("%s: chmod: %s", applet, strerror (errno));
69 return (-1);
70 }
71 }
72
73 if (st.st_uid != uid || st.st_gid != gid) {
74 if (st.st_dev || st.st_ino)
75 einfo ("%s: correcting owner", path);
76 if (chown (path, uid, gid)) {
77 eerror ("%s: chown: %s", applet, strerror (errno));
78 return (-1);
79 }
80 }
81
82 return (0);
83 }
84
85 /* Based on busybox */
86 static int parse_mode (mode_t *mode, char *text)
87 {
88 /* Check for a numeric mode */
89 if ((*mode - '0') < 8) {
90 char *p;
91 unsigned long l = strtoul (text, &p, 8);
92 if (*p || l > 07777U) {
93 errno = EINVAL;
94 return (-1);
95 }
96 *mode = l;
97 return (0);
98 }
99
100 /* We currently don't check g+w type stuff */
101 errno = EINVAL;
102 return (-1);
103 }
104
105 static struct passwd *get_user (char **name)
106 {
107 struct passwd *pw;
108 char *p = *name;
109 char *token;
110 int tid;
111
112 token = strsep (&p, ":");
113 if (sscanf (token, "%d", &tid) != 1)
114 pw = getpwnam (token);
115 else
116 pw = getpwuid (tid);
117
118 if (pw)
119 *name = p;
120
121 return (pw);
122 }
123
124 static struct group *get_group (const char *name)
125 {
126 int tid;
127
128 if (sscanf (name, "%d", &tid) != 1)
129 return (getgrnam (name));
130 else
131 return (getgrgid (tid));
132 }
133
134 #include "_usage.h"
135 #define getoptstring "fm:g:u:" getoptstring_COMMON
136 static struct option longopts[] = {
137 { "directory", 0, NULL, 'd'},
138 { "file", 0, NULL, 'f'},
139 { "mode", 1, NULL, 'm'},
140 { "user", 1, NULL, 'u'},
141 { "group", 1, NULL, 'g'},
142 longopts_COMMON
143 { NULL, 0, NULL, 0}
144 };
145 #include "_usage.c"
146
147 int checkown (int argc, char **argv)
148 {
149 int opt;
150 uid_t uid = geteuid();
151 gid_t gid = getgid();
152 mode_t mode = 0;
153 struct passwd *pw = NULL;
154 struct group *gr = NULL;
155 bool file = 0;
156
157 char *p;
158 int retval = EXIT_SUCCESS;
159
160 applet = argv[0];
161
162 while ((opt = getopt_long (argc, argv, getoptstring,
163 longopts, (int *) 0)) != -1)
164 {
165 switch (opt) {
166 case 'd':
167 file = 0;
168 break;
169 case 'f':
170 file = 1;
171 break;
172 case 'm':
173 if (parse_mode (&mode, optarg))
174 eerrorx ("%s: invalid mode `%s'", applet, optarg);
175 break;
176 case 'u':
177 p = optarg;
178 if (! (pw = get_user (&p)))
179 eerrorx ("%s: user `%s' not found", applet, optarg);
180 if (p && *p)
181 optarg = p;
182 else
183 break;
184 case 'g':
185 if (! (gr = get_group (optarg)))
186 eerrorx ("%s: group `%s' not found", applet, optarg);
187 break;
188
189 case_RC_COMMON_GETOPT
190 }
191 }
192
193 if (pw) {
194 uid = pw->pw_uid;
195 gid = pw->pw_gid;
196 }
197 if (gr)
198 gid = gr->gr_gid;
199
200 while (optind < argc) {
201 if (do_check (argv[optind], uid, gid, mode, file))
202 retval = EXIT_FAILURE;
203 optind++;
204 }
205
206 exit (retval);
207 }

  ViewVC Help
Powered by ViewVC 1.1.20