Rev 45 | Rev 51 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 45 | Rev 49 | ||
---|---|---|---|
1 | 1 | ||
2 | /// inotify cron table manipulator main file
|
2 | /// inotify cron table manipulator main file
|
3 | /**
|
3 | /**
|
4 | * \file ict-main.cpp
|
4 | * \file ict-main.cpp
|
5 | *
|
5 | *
|
6 | * inotify cron system
|
6 | * inotify cron system
|
7 | *
|
7 | *
|
8 | * Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
|
8 | * Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
|
9 | *
|
9 | *
|
10 | * This program is free software; you can use it, redistribute
|
10 | * This program is free software; you can use it, redistribute
|
11 | * it and/or modify it under the terms of the GNU General Public
|
11 | * it and/or modify it under the terms of the GNU General Public
|
12 | * License, version 2 (see LICENSE-GPL).
|
12 | * License, version 2 (see LICENSE-GPL).
|
13 | *
|
13 | *
|
14 | */
|
14 | */
|
15 | 15 | ||
16 | 16 | ||
17 | #include <argp.h>
|
17 | #include <argp.h>
|
18 | #include <pwd.h>
|
18 | #include <pwd.h>
|
19 | #include <string>
|
19 | #include <string>
|
20 | #include <stdio.h>
|
20 | #include <stdio.h>
|
21 | #include <unistd.h>
|
21 | #include <unistd.h>
|
22 | #include <sys/stat.h>
|
22 | #include <sys/stat.h>
|
23 | #include <sys/wait.h>
|
23 | #include <sys/wait.h>
|
24 | 24 | ||
25 | #include "incrontab.h"
|
25 | #include "incrontab.h"
|
26 | 26 | ||
27 | 27 | ||
28 | // #define INCRON_DEFAULT_EDITOR "nano" // for vim haters like me ;-)
|
28 | // #define INCRON_DEFAULT_EDITOR "nano" // for vim haters like me ;-)
|
29 | #define INCRON_DEFAULT_EDITOR "vim"
|
29 | #define INCRON_DEFAULT_EDITOR "vim"
|
30 | 30 | ||
31 | 31 | ||
32 | const char* argp_program_version = "incrontab 0.1.0"; |
32 | const char* argp_program_version = "incrontab 0.3.0"; |
33 | const char* argp_program_bug_address = "<bugs@aiken.cz>"; |
33 | const char* argp_program_bug_address = "<bugs@aiken.cz>"; |
34 | 34 | ||
35 | static char doc[] = "Table manipulator for incrond (inotify Cron daemon)"; |
35 | static char doc[] = "Table manipulator for incrond (inotify cron daemon)"; |
36 | 36 | ||
37 | static char args_doc[] = "FILE"; |
37 | static char args_doc[] = "FILE"; |
38 | 38 | ||
39 | static struct argp_option options[] = { |
39 | static struct argp_option options[] = { |
40 | {"list", 'l', 0, 0, "List current table" }, |
40 | {"list", 'l', 0, 0, "List current table" }, |
41 | {"remove", 'r', 0, 0, "Remove table completely" }, |
41 | {"remove", 'r', 0, 0, "Remove table completely" }, |
42 | {"edit", 'e', 0, 0, "Edit table" }, |
42 | {"edit", 'e', 0, 0, "Edit table" }, |
43 | {"user", 'u', "USER", 0, "Override current user" }, |
43 | {"user", 'u', "USER", 0, "Override current user" }, |
44 | { 0 } |
44 | { 0 } |
45 | }; |
45 | }; |
46 | 46 | ||
- | 47 | /// incrontab operations
|
|
47 | enum
|
48 | typedef enum |
48 | {
|
49 | {
|
49 | OPER_NONE, |
50 | OPER_NONE, /// nothing
|
50 | OPER_LIST, |
51 | OPER_LIST, /// list table
|
51 | OPER_REMOVE, |
52 | OPER_REMOVE, /// remove table
|
52 | OPER_EDIT |
53 | OPER_EDIT /// edit table
|
53 | }; |
54 | } InCronTab_Operation_t; |
54 | 55 | ||
- | 56 | /// incrontab arguments
|
|
55 | struct arguments
|
57 | struct arguments
|
56 | {
|
58 | {
|
57 | char *user; |
59 | char *user; /// user name |
58 | int oper; |
60 | int oper; /// operation code |
59 | char *file; |
61 | char *file; /// file to import |
60 | }; |
62 | }; |
61 | 63 | ||
- | 64 | /// Parses the program options (arguments).
|
|
- | 65 | /**
|
|
- | 66 | * \param[in] key argument key (name)
|
|
- | 67 | * \param[in] arg argument value
|
|
- | 68 | * \param[out] state options setting
|
|
- | 69 | * \return 0 on success, ARGP_ERR_UNKNOWN on unknown argument(s)
|
|
- | 70 | */
|
|
62 | static error_t parse_opt (int key, char *arg, struct argp_state *state) |
71 | static error_t parse_opt(int key, char *arg, struct argp_state *state) |
63 | {
|
72 | {
|
64 | struct arguments* arguments = (struct arguments*) state->input; |
73 | struct arguments* arguments = (struct arguments*) state->input; |
65 | 74 | ||
66 | switch (key) { |
75 | switch (key) { |
67 | case 'l': |
76 | case 'l': |
68 | arguments->oper = OPER_LIST; |
77 | arguments->oper = OPER_LIST; |
69 | break; |
78 | break; |
70 | case 'r': |
79 | case 'r': |
71 | arguments->oper = OPER_REMOVE; |
80 | arguments->oper = OPER_REMOVE; |
72 | break; |
81 | break; |
73 | case 'e': |
82 | case 'e': |
74 | arguments->oper = OPER_EDIT; |
83 | arguments->oper = OPER_EDIT; |
75 | break; |
84 | break; |
76 | case 'u': |
85 | case 'u': |
77 | arguments->user = arg; |
86 | arguments->user = arg; |
78 | break; |
87 | break; |
79 | case ARGP_KEY_ARG: |
88 | case ARGP_KEY_ARG: |
80 | if (state->arg_num >= 1) |
89 | if (state->arg_num >= 1) |
81 | argp_usage(state); |
90 | argp_usage(state); |
82 | arguments->file = arg; |
91 | arguments->file = arg; |
83 | break; |
92 | break; |
84 | case ARGP_KEY_END: |
93 | case ARGP_KEY_END: |
85 | break; |
94 | break; |
86 | default: |
95 | default: |
87 | return ARGP_ERR_UNKNOWN; |
96 | return ARGP_ERR_UNKNOWN; |
88 | }
|
97 | }
|
89 | 98 | ||
90 | return 0; |
99 | return 0; |
91 | }
|
100 | }
|
92 | 101 | ||
93 | - | ||
- | 102 | /// Program arguments
|
|
94 | static struct argp argp = { options, parse_opt, args_doc, doc }; |
103 | static struct argp argp = { options, parse_opt, args_doc, doc }; |
95 | 104 | ||
- | 105 | /// Unlink a file with temporarily changed UID.
|
|
- | 106 | /**
|
|
- | 107 | * \param[in] file file to unlink
|
|
- | 108 | * \param[in] uid UID for unlink processing
|
|
- | 109 | *
|
|
- | 110 | * \attention No error checking is done!
|
|
- | 111 | */
|
|
96 | void unlink_suid(const char* file, uid_t uid) |
112 | void unlink_suid(const char* file, uid_t uid) |
97 | {
|
113 | {
|
98 | uid_t iu = geteuid(); |
114 | uid_t iu = geteuid(); |
99 | seteuid(uid); |
115 | seteuid(uid); |
100 | unlink(file); |
116 | unlink(file); |
101 | seteuid(iu); |
117 | seteuid(iu); |
102 | }
|
118 | }
|
103 | 119 | ||
- | 120 | /// Copies a file to an user table.
|
|
- | 121 | /**
|
|
- | 122 | * \param[in] path path to file
|
|
- | 123 | * \param[in] user user name
|
|
- | 124 | * \return true = success, false = failure
|
|
- | 125 | */
|
|
104 | bool copy_from_file(const char* path, const char* user) |
126 | bool copy_from_file(const char* path, const char* user) |
105 | {
|
127 | {
|
106 | InCronTab tab;
|
128 | InCronTab tab;
|
107 | std::string s(path); |
129 | std::string s(path); |
108 | if (s == "-") |
130 | if (s == "-") |
109 | s = "/dev/stdin"; |
131 | s = "/dev/stdin"; |
110 | if (!tab.Load(s)) { |
132 | if (!tab.Load(s)) { |
111 | fprintf(stderr, "cannot load table from file: %s\n", path); |
133 | fprintf(stderr, "cannot load table from file: %s\n", path); |
112 | return false; |
134 | return false; |
113 | }
|
135 | }
|
114 | 136 | ||
115 | std::string out(InCronTab::GetUserTablePath(user)); |
137 | std::string out(InCronTab::GetUserTablePath(user)); |
116 | if (!tab.Save(out)) { |
138 | if (!tab.Save(out)) { |
117 | fprintf(stderr, "cannot create table for user: %s\n", user); |
139 | fprintf(stderr, "cannot create table for user: %s\n", user); |
118 | return false; |
140 | return false; |
119 | }
|
141 | }
|
120 | 142 | ||
121 | return true; |
143 | return true; |
122 | }
|
144 | }
|
123 | 145 | ||
- | 146 | /// Removes an user table.
|
|
- | 147 | /**
|
|
- | 148 | * \param[in] user user name
|
|
- | 149 | * \return true = success, false = failure
|
|
- | 150 | */
|
|
124 | bool remove_table(const char* user) |
151 | bool remove_table(const char* user) |
125 | {
|
152 | {
|
126 | std::string tp(InCronTab::GetUserTablePath(user)); |
153 | std::string tp(InCronTab::GetUserTablePath(user)); |
127 | 154 | ||
128 | if (unlink(tp.c_str()) != 0 && errno != ENOENT) { |
155 | if (unlink(tp.c_str()) != 0 && errno != ENOENT) { |
129 | fprintf(stderr, "cannot remove table for user: %s\n", user); |
156 | fprintf(stderr, "cannot remove table for user: %s\n", user); |
130 | return false; |
157 | return false; |
131 | }
|
158 | }
|
132 | 159 | ||
133 | return true; |
160 | return true; |
134 | }
|
161 | }
|
135 | 162 | ||
- | 163 | /// Lists an user table.
|
|
- | 164 | /**
|
|
- | 165 | * \param[in] user user name
|
|
- | 166 | * \return true = success, false = failure
|
|
- | 167 | *
|
|
- | 168 | * \attention Listing is currently done through 'cat'.
|
|
- | 169 | */
|
|
136 | bool list_table(const char* user) |
170 | bool list_table(const char* user) |
137 | {
|
171 | {
|
138 | std::string tp(InCronTab::GetUserTablePath(user)); |
172 | std::string tp(InCronTab::GetUserTablePath(user)); |
139 | 173 | ||
140 | if (access(tp.c_str(), R_OK) != 0) { |
174 | if (access(tp.c_str(), R_OK) != 0) { |
141 | if (errno == ENOENT) { |
175 | if (errno == ENOENT) { |
142 | fprintf(stderr, "no table for %s\n", user); |
176 | fprintf(stderr, "no table for %s\n", user); |
143 | return true; |
177 | return true; |
144 | }
|
178 | }
|
145 | else { |
179 | else { |
146 | fprintf(stderr, "cannot read table for %s: %s\n", user, strerror(errno)); |
180 | fprintf(stderr, "cannot read table for %s: %s\n", user, strerror(errno)); |
147 | return false; |
181 | return false; |
148 | }
|
182 | }
|
149 | }
|
183 | }
|
150 | 184 | ||
151 | std::string cmd("cat "); |
185 | std::string cmd("cat "); |
152 | cmd.append(tp); |
186 | cmd.append(tp); |
153 | return system(cmd.c_str()) == 0; |
187 | return system(cmd.c_str()) == 0; |
154 | }
|
188 | }
|
155 | 189 | ||
- | 190 | /// Allows to edit an user table.
|
|
- | 191 | /**
|
|
- | 192 | * \param[in] user user name
|
|
- | 193 | * \return true = success, false = failure
|
|
- | 194 | *
|
|
- | 195 | * \attention This function is very complex and may contain
|
|
- | 196 | * various bugs including security ones. Please keep
|
|
- | 197 | * it in mind..
|
|
- | 198 | */
|
|
156 | bool edit_table(const char* user) |
199 | bool edit_table(const char* user) |
157 | {
|
200 | {
|
158 | std::string tp(InCronTab::GetUserTablePath(user)); |
201 | std::string tp(InCronTab::GetUserTablePath(user)); |
159 | 202 | ||
160 | struct passwd* ppwd = getpwnam(user); |
203 | struct passwd* ppwd = getpwnam(user); |
161 | if (ppwd == NULL) { |
204 | if (ppwd == NULL) { |
162 | fprintf(stderr, "cannot find user %s: %s\n", user, strerror(errno)); |
205 | fprintf(stderr, "cannot find user %s: %s\n", user, strerror(errno)); |
163 | return false; |
206 | return false; |
164 | }
|
207 | }
|
165 | uid_t uid = ppwd->pw_uid; |
208 | uid_t uid = ppwd->pw_uid; |
166 | 209 | ||
167 | char s[NAME_MAX]; |
210 | char s[NAME_MAX]; |
168 | strcpy(s, "/tmp/incron.table-XXXXXX"); |
211 | strcpy(s, "/tmp/incron.table-XXXXXX"); |
169 | 212 | ||
170 | uid_t iu = geteuid(); |
213 | uid_t iu = geteuid(); |
171 | 214 | ||
172 | if (seteuid(uid) != 0) { |
215 | if (seteuid(uid) != 0) { |
173 | fprintf(stderr, "cannot change effective UID: %s\n", strerror(errno)); |
216 | fprintf(stderr, "cannot change effective UID: %s\n", strerror(errno)); |
174 | return false; |
217 | return false; |
175 | }
|
218 | }
|
176 | 219 | ||
177 | int fd = mkstemp(s); |
220 | int fd = mkstemp(s); |
178 | if (fd == -1) { |
221 | if (fd == -1) { |
179 | fprintf(stderr, "cannot create temporary file: %s\n", strerror(errno)); |
222 | fprintf(stderr, "cannot create temporary file: %s\n", strerror(errno)); |
180 | return false; |
223 | return false; |
181 | }
|
224 | }
|
182 | 225 | ||
183 | if (fchmod(fd, 0644) != 0) { |
226 | if (fchmod(fd, 0644) != 0) { |
184 | fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno)); |
227 | fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno)); |
185 | close(fd); |
228 | close(fd); |
186 | unlink_suid(s, uid); |
229 | unlink_suid(s, uid); |
187 | return false; |
230 | return false; |
188 | }
|
231 | }
|
189 | 232 | ||
190 | if (seteuid(iu) != 0) { |
233 | if (seteuid(iu) != 0) { |
191 | fprintf(stderr, "cannot change effective UID: %s\n", strerror(errno)); |
234 | fprintf(stderr, "cannot change effective UID: %s\n", strerror(errno)); |
192 | close(fd); |
235 | close(fd); |
193 | unlink_suid(s, uid); |
236 | unlink_suid(s, uid); |
194 | return false; |
237 | return false; |
195 | }
|
238 | }
|
196 | 239 | ||
197 | FILE* out = fdopen(fd, "w"); |
240 | FILE* out = fdopen(fd, "w"); |
198 | if (out == NULL) { |
241 | if (out == NULL) { |
199 | fprintf(stderr, "cannot write to temporary file: %s\n", strerror(errno)); |
242 | fprintf(stderr, "cannot write to temporary file: %s\n", strerror(errno)); |
200 | close(fd); |
243 | close(fd); |
201 | unlink_suid(s, uid); |
244 | unlink_suid(s, uid); |
202 | return false; |
245 | return false; |
203 | }
|
246 | }
|
204 | 247 | ||
205 | FILE* in = fopen(tp.c_str(), "r"); |
248 | FILE* in = fopen(tp.c_str(), "r"); |
206 | if (in == NULL) { |
249 | if (in == NULL) { |
207 | if (errno == ENOENT) { |
250 | if (errno == ENOENT) { |
208 | in = fopen("/dev/null", "r"); |
251 | in = fopen("/dev/null", "r"); |
209 | if (in == NULL) { |
252 | if (in == NULL) { |
210 | fprintf(stderr, "cannot get empty table for %s: %s\n", user, strerror(errno)); |
253 | fprintf(stderr, "cannot get empty table for %s: %s\n", user, strerror(errno)); |
211 | fclose(out); |
254 | fclose(out); |
212 | unlink_suid(s, uid); |
255 | unlink_suid(s, uid); |
213 | return false; |
256 | return false; |
214 | }
|
257 | }
|
215 | }
|
258 | }
|
216 | else { |
259 | else { |
217 | fprintf(stderr, "cannot read old table for %s: %s\n", user, strerror(errno)); |
260 | fprintf(stderr, "cannot read old table for %s: %s\n", user, strerror(errno)); |
218 | fclose(out); |
261 | fclose(out); |
219 | unlink_suid(s, uid); |
262 | unlink_suid(s, uid); |
220 | return false; |
263 | return false; |
221 | }
|
264 | }
|
222 | }
|
265 | }
|
223 | 266 | ||
224 | char buf[1024]; |
267 | char buf[1024]; |
225 | while (fgets(buf, 1024, in) != NULL) { |
268 | while (fgets(buf, 1024, in) != NULL) { |
226 | fputs(buf, out); |
269 | fputs(buf, out); |
227 | }
|
270 | }
|
228 | fclose(in); |
271 | fclose(in); |
229 | fclose(out); |
272 | fclose(out); |
230 | 273 | ||
231 | struct stat st; |
274 | struct stat st; |
232 | if (stat(s, &st) != 0) { |
275 | if (stat(s, &st) != 0) { |
233 | fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno)); |
276 | fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno)); |
234 | unlink_suid(s, uid); |
277 | unlink_suid(s, uid); |
235 | return false; |
278 | return false; |
236 | }
|
279 | }
|
237 | 280 | ||
238 | time_t mt = st.st_mtime; |
281 | time_t mt = st.st_mtime; |
239 | 282 | ||
240 | const char* e = getenv("EDITOR"); |
283 | const char* e = getenv("EDITOR"); |
241 | if (e == NULL) |
284 | if (e == NULL) |
242 | e = INCRON_DEFAULT_EDITOR; |
285 | e = INCRON_DEFAULT_EDITOR; |
243 | 286 | ||
244 | pid_t pid = fork(); |
287 | pid_t pid = fork(); |
245 | if (pid == 0) { |
288 | if (pid == 0) { |
246 | if (setuid(uid) != 0) { |
289 | if (setuid(uid) != 0) { |
247 | fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno)); |
290 | fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno)); |
248 | return false; |
291 | return false; |
249 | }
|
292 | }
|
250 | 293 | ||
251 | execlp(e, e, s, NULL); |
294 | execlp(e, e, s, NULL); |
252 | _exit(1); |
295 | _exit(1); |
253 | }
|
296 | }
|
254 | else if (pid > 0) { |
297 | else if (pid > 0) { |
255 | int status; |
298 | int status; |
256 | if (wait(&status) != pid) { |
299 | if (wait(&status) != pid) { |
257 | perror("error while waiting for editor"); |
300 | perror("error while waiting for editor"); |
258 | unlink_suid(s, uid); |
301 | unlink_suid(s, uid); |
259 | return false; |
302 | return false; |
260 | }
|
303 | }
|
261 | if (!(WIFEXITED(status)) || WEXITSTATUS(status) != 0) { |
304 | if (!(WIFEXITED(status)) || WEXITSTATUS(status) != 0) { |
262 | perror("editor finished with error"); |
305 | perror("editor finished with error"); |
263 | unlink_suid(s, uid); |
306 | unlink_suid(s, uid); |
264 | return false; |
307 | return false; |
265 | }
|
308 | }
|
266 | }
|
309 | }
|
267 | else { |
310 | else { |
268 | perror("cannot start editor"); |
311 | perror("cannot start editor"); |
269 | unlink_suid(s, uid); |
312 | unlink_suid(s, uid); |
270 | return false; |
313 | return false; |
271 | }
|
314 | }
|
272 | 315 | ||
273 | if (stat(s, &st) != 0) { |
316 | if (stat(s, &st) != 0) { |
274 | fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno)); |
317 | fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno)); |
275 | unlink_suid(s, uid); |
318 | unlink_suid(s, uid); |
276 | return false; |
319 | return false; |
277 | }
|
320 | }
|
278 | 321 | ||
279 | if (st.st_mtime == mt) { |
322 | if (st.st_mtime == mt) { |
280 | fprintf(stderr, "table unchanged\n"); |
323 | fprintf(stderr, "table unchanged\n"); |
281 | unlink_suid(s, uid); |
324 | unlink_suid(s, uid); |
282 | return true; |
325 | return true; |
283 | }
|
326 | }
|
284 | 327 | ||
285 | InCronTab ict;
|
328 | InCronTab ict;
|
286 | if (!ict.Load(s) || !ict.Save(tp)) { |
329 | if (!ict.Load(s) || !ict.Save(tp)) { |
287 | fprintf(stderr, "cannot move temporary table: %s\n", strerror(errno)); |
330 | fprintf(stderr, "cannot move temporary table: %s\n", strerror(errno)); |
288 | unlink(s); |
331 | unlink(s); |
289 | return false; |
332 | return false; |
290 | }
|
333 | }
|
291 | 334 | ||
292 | fprintf(stderr, "table updated\n"); |
335 | fprintf(stderr, "table updated\n"); |
293 | 336 | ||
294 | unlink_suid(s, uid); |
337 | unlink_suid(s, uid); |
295 | return true; |
338 | return true; |
296 | }
|
339 | }
|
297 | 340 | ||
298 | 341 | ||
299 | int main(int argc, char** argv) |
342 | int main(int argc, char** argv) |
300 | {
|
343 | {
|
301 | struct arguments arguments; |
344 | struct arguments arguments; |
302 | 345 | ||
303 | arguments.user = NULL; |
346 | arguments.user = NULL; |
304 | arguments.oper = OPER_NONE; |
347 | arguments.oper = OPER_NONE; |
305 | arguments.file = NULL; |
348 | arguments.file = NULL; |
306 | 349 | ||
307 | argp_parse (&argp, argc, argv, 0, 0, &arguments); |
350 | argp_parse (&argp, argc, argv, 0, 0, &arguments); |
308 | 351 | ||
309 | if (arguments.file != NULL && arguments.oper != OPER_NONE) { |
352 | if (arguments.file != NULL && arguments.oper != OPER_NONE) { |
310 | fprintf(stderr, "invalid arguments - specify source file or operation\n"); |
353 | fprintf(stderr, "invalid arguments - specify source file or operation\n"); |
311 | return 1; |
354 | return 1; |
312 | }
|
355 | }
|
313 | if (arguments.file == NULL && arguments.oper == OPER_NONE) { |
356 | if (arguments.file == NULL && arguments.oper == OPER_NONE) { |
314 | fprintf(stderr, "invalid arguments - specify source file or operation\n"); |
357 | fprintf(stderr, "invalid arguments - specify source file or operation\n"); |
315 | return 1; |
358 | return 1; |
316 | }
|
359 | }
|
317 | 360 | ||
318 | uid_t uid = getuid(); |
361 | uid_t uid = getuid(); |
319 | 362 | ||
320 | if (uid != 0 && arguments.user != NULL) { |
363 | if (uid != 0 && arguments.user != NULL) { |
321 | fprintf(stderr, "cannot access table for user %s: permission denied\n", arguments.user); |
364 | fprintf(stderr, "cannot access table for user %s: permission denied\n", arguments.user); |
322 | return 1; |
365 | return 1; |
323 | }
|
366 | }
|
324 | 367 | ||
325 | struct passwd pwd; |
368 | struct passwd pwd; |
326 | 369 | ||
327 | if (arguments.user == NULL) { |
370 | if (arguments.user == NULL) { |
328 | struct passwd* ppwd = getpwuid(uid); |
371 | struct passwd* ppwd = getpwuid(uid); |
329 | if (ppwd == NULL) { |
372 | if (ppwd == NULL) { |
330 | fprintf(stderr, "cannot determine current user\n"); |
373 | fprintf(stderr, "cannot determine current user\n"); |
331 | return 1; |
374 | return 1; |
332 | }
|
375 | }
|
333 | memcpy(&pwd, ppwd, sizeof(pwd)); |
376 | memcpy(&pwd, ppwd, sizeof(pwd)); |
334 | arguments.user = pwd.pw_name; |
377 | arguments.user = pwd.pw_name; |
335 | }
|
378 | }
|
336 | else if (getpwnam(arguments.user) == NULL) { |
379 | else if (getpwnam(arguments.user) == NULL) { |
337 | fprintf(stderr, "user %s not found\n", arguments.user); |
380 | fprintf(stderr, "user %s not found\n", arguments.user); |
338 | return 1; |
381 | return 1; |
339 | }
|
382 | }
|
340 | 383 | ||
341 | if (!InCronTab::CheckUser(arguments.user)) { |
384 | if (!InCronTab::CheckUser(arguments.user)) { |
342 | fprintf(stderr, "user %s is not allowed to use incron\n", arguments.user); |
385 | fprintf(stderr, "user %s is not allowed to use incron\n", arguments.user); |
343 | return 1; |
386 | return 1; |
344 | }
|
387 | }
|
345 | 388 | ||
346 | switch (arguments.oper) { |
389 | switch (arguments.oper) { |
347 | case OPER_NONE: |
390 | case OPER_NONE: |
348 | fprintf(stderr, "copying table from file: %s\n", arguments.file); |
391 | fprintf(stderr, "copying table from file: %s\n", arguments.file); |
349 | if (!copy_from_file(arguments.file, arguments.user)) |
392 | if (!copy_from_file(arguments.file, arguments.user)) |
350 | return 1; |
393 | return 1; |
351 | break; |
394 | break; |
352 | case OPER_LIST: |
395 | case OPER_LIST: |
353 | if (!list_table(arguments.user)) |
396 | if (!list_table(arguments.user)) |
354 | return 1; |
397 | return 1; |
355 | break; |
398 | break; |
356 | case OPER_REMOVE: |
399 | case OPER_REMOVE: |
357 | fprintf(stderr, "removing table for user %s\n", arguments.user); |
400 | fprintf(stderr, "removing table for user %s\n", arguments.user); |
358 | if (!remove_table(arguments.user)) |
401 | if (!remove_table(arguments.user)) |
359 | return 1; |
402 | return 1; |
360 | break; |
403 | break; |
361 | case OPER_EDIT: |
404 | case OPER_EDIT: |
362 | if (!edit_table(arguments.user)) |
405 | if (!edit_table(arguments.user)) |
363 | return 1; |
406 | return 1; |
364 | break; |
407 | break; |
365 | default: |
408 | default: |
366 | fprintf(stderr, "invalid usage\n"); |
409 | fprintf(stderr, "invalid usage\n"); |
367 | return 1; |
410 | return 1; |
368 | }
|
411 | }
|
369 | 412 | ||
370 | return 0; |
413 | return 0; |
371 | }
|
414 | }
|
372 | 415 |