Deleted Added
full compact
crontab.c (24428) crontab.c (29452)
1/* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice. May be sold if buildable source is provided to buyer. No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date. I can be reached as follows:
15 * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul
16 * From Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp
17 */
18
19#if !defined(lint) && !defined(LINT)
1/* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice. May be sold if buildable source is provided to buyer. No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date. I can be reached as follows:
15 * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul
16 * From Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp
17 */
18
19#if !defined(lint) && !defined(LINT)
20static char rcsid[] = "$Id: crontab.c,v 1.9 1997/02/22 16:04:53 peter Exp $";
20static const char rcsid[] =
21 "$Id: crontab.c,v 1.10 1997/03/31 05:09:58 imp Exp $";
21#endif
22
23/* crontab - install and manage per-user crontab files
24 * vix 02may87 [RCS has the rest of the log]
25 * vix 26jan87 [original]
26 */
27
28#define MAIN_PROGRAM

--- 39 unchanged lines hidden (view full) ---

68 parse_args __P((int c, char *v[]));
69static int replace_cmd __P((void));
70
71
72static void
73usage(msg)
74 char *msg;
75{
22#endif
23
24/* crontab - install and manage per-user crontab files
25 * vix 02may87 [RCS has the rest of the log]
26 * vix 26jan87 [original]
27 */
28
29#define MAIN_PROGRAM

--- 39 unchanged lines hidden (view full) ---

69 parse_args __P((int c, char *v[]));
70static int replace_cmd __P((void));
71
72
73static void
74usage(msg)
75 char *msg;
76{
76 fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg);
77 fprintf(stderr, "usage:\t%s [-u user] file\n", ProgramName);
78 fprintf(stderr, "\t%s [-u user] { -e | -l | -r }\n", ProgramName);
79 fprintf(stderr, "\t\t(default operation is replace, per 1003.2)\n");
80 fprintf(stderr, "\t-e\t(edit user's crontab)\n");
81 fprintf(stderr, "\t-l\t(list user's crontab)\n");
82 fprintf(stderr, "\t-r\t(delete user's crontab)\n");
77 fprintf(stderr, "crontab: usage error: %s\n", msg);
78 fprintf(stderr, "%s\n%s\n",
79 "usage: crontab [-u user] file",
80 " crontab [-u user] { -e | -l | -r }");
83 exit(ERROR_EXIT);
84}
85
86
87int
88main(argc, argv)
89 int argc;
90 char *argv[];

--- 9 unchanged lines hidden (view full) ---

100
101#if defined(BSD)
102 setlinebuf(stderr);
103#endif
104 parse_args(argc, argv); /* sets many globals, opens a file */
105 set_cron_uid();
106 set_cron_cwd();
107 if (!allowed(User)) {
81 exit(ERROR_EXIT);
82}
83
84
85int
86main(argc, argv)
87 int argc;
88 char *argv[];

--- 9 unchanged lines hidden (view full) ---

98
99#if defined(BSD)
100 setlinebuf(stderr);
101#endif
102 parse_args(argc, argv); /* sets many globals, opens a file */
103 set_cron_uid();
104 set_cron_cwd();
105 if (!allowed(User)) {
108 fprintf(stderr,
109 "You (%s) are not allowed to use this program (%s)\n",
110 User, ProgramName);
111 fprintf(stderr, "See crontab(1) for more information\n");
106 warnx("you (%s) are not allowed to use this program", User);
112 log_it(RealUser, Pid, "AUTH", "crontab command not allowed");
113 exit(ERROR_EXIT);
114 }
115 exitstatus = OK_EXIT;
116 switch (Option) {
117 case opt_list: list_cmd();
118 break;
119 case opt_delete: delete_cmd();
120 break;
121 case opt_edit: edit_cmd();
122 break;
123 case opt_replace: if (replace_cmd() < 0)
124 exitstatus = ERROR_EXIT;
125 break;
107 log_it(RealUser, Pid, "AUTH", "crontab command not allowed");
108 exit(ERROR_EXIT);
109 }
110 exitstatus = OK_EXIT;
111 switch (Option) {
112 case opt_list: list_cmd();
113 break;
114 case opt_delete: delete_cmd();
115 break;
116 case opt_edit: edit_cmd();
117 break;
118 case opt_replace: if (replace_cmd() < 0)
119 exitstatus = ERROR_EXIT;
120 break;
121 case opt_unknown:
122 break;
126 }
127 exit(0);
128 /*NOTREACHED*/
129}
130
131
132static void
133parse_args(argc, argv)
134 int argc;
135 char *argv[];
136{
137 int argch;
138
123 }
124 exit(0);
125 /*NOTREACHED*/
126}
127
128
129static void
130parse_args(argc, argv)
131 int argc;
132 char *argv[];
133{
134 int argch;
135
139 if (!(pw = getpwuid(getuid()))) {
140 fprintf(stderr, "%s: your UID isn't in the passwd file.\n",
141 ProgramName);
142 fprintf(stderr, "bailing out.\n");
143 exit(ERROR_EXIT);
144 }
136 if (!(pw = getpwuid(getuid())))
137 errx(ERROR_EXIT, "your UID isn't in the passwd file, bailing out");
145 (void) strncpy(User, pw->pw_name, (sizeof User)-1);
146 User[(sizeof User)-1] = '\0';
147 strcpy(RealUser, User);
148 Filename[0] = '\0';
149 Option = opt_unknown;
150 while ((argch = getopt(argc, argv, "u:lerx:")) != -1) {
151 switch (argch) {
152 case 'x':
153 if (!set_debug_flags(optarg))
154 usage("bad debug option");
155 break;
156 case 'u':
157 if (getuid() != ROOT_UID)
138 (void) strncpy(User, pw->pw_name, (sizeof User)-1);
139 User[(sizeof User)-1] = '\0';
140 strcpy(RealUser, User);
141 Filename[0] = '\0';
142 Option = opt_unknown;
143 while ((argch = getopt(argc, argv, "u:lerx:")) != -1) {
144 switch (argch) {
145 case 'x':
146 if (!set_debug_flags(optarg))
147 usage("bad debug option");
148 break;
149 case 'u':
150 if (getuid() != ROOT_UID)
158 {
159 fprintf(stderr,
160 "must be privileged to use -u\n");
161 exit(ERROR_EXIT);
162 }
151 errx(ERROR_EXIT, "must be privileged to use -u");
163 if (!(pw = getpwnam(optarg)))
152 if (!(pw = getpwnam(optarg)))
164 {
165 fprintf(stderr, "%s: user `%s' unknown\n",
166 ProgramName, optarg);
167 exit(ERROR_EXIT);
168 }
153 errx(ERROR_EXIT, "user `%s' unknown", optarg);
169 (void) strncpy(User, pw->pw_name, (sizeof User)-1);
170 User[(sizeof User)-1] = '\0';
171 break;
172 case 'l':
173 if (Option != opt_unknown)
174 usage("only one operation permitted");
175 Option = opt_list;
176 break;

--- 40 unchanged lines hidden (view full) ---

217 /* relinquish the setuid status of the binary during
218 * the open, lest nonroot users read files they should
219 * not be able to read. we can't use access() here
220 * since there's a race condition. thanks go out to
221 * Arnt Gulbrandsen <agulbra@pvv.unit.no> for spotting
222 * the race.
223 */
224
154 (void) strncpy(User, pw->pw_name, (sizeof User)-1);
155 User[(sizeof User)-1] = '\0';
156 break;
157 case 'l':
158 if (Option != opt_unknown)
159 usage("only one operation permitted");
160 Option = opt_list;
161 break;

--- 40 unchanged lines hidden (view full) ---

202 /* relinquish the setuid status of the binary during
203 * the open, lest nonroot users read files they should
204 * not be able to read. we can't use access() here
205 * since there's a race condition. thanks go out to
206 * Arnt Gulbrandsen <agulbra@pvv.unit.no> for spotting
207 * the race.
208 */
209
225 if (swap_uids() < OK) {
226 perror("swapping uids");
227 exit(ERROR_EXIT);
228 }
229 if (!(NewCrontab = fopen(Filename, "r"))) {
230 perror(Filename);
231 exit(ERROR_EXIT);
232 }
233 if (swap_uids() < OK) {
234 perror("swapping uids back");
235 exit(ERROR_EXIT);
236 }
210 if (swap_uids() < OK)
211 err(ERROR_EXIT, "swapping uids");
212 if (!(NewCrontab = fopen(Filename, "r")))
213 err(ERROR_EXIT, "%s", Filename);
214 if (swap_uids() < OK)
215 err(ERROR_EXIT, "swapping uids back");
237 }
238 }
239
240 Debug(DMISC, ("user=%s, file=%s, option=%s\n",
241 User, Filename, Options[(int)Option]))
242}
243
244
245static void
246list_cmd() {
247 char n[MAX_FNAME];
248 FILE *f;
249 int ch;
250
251 log_it(RealUser, Pid, "LIST", User);
252 (void) sprintf(n, CRON_TAB(User));
253 if (!(f = fopen(n, "r"))) {
254 if (errno == ENOENT)
216 }
217 }
218
219 Debug(DMISC, ("user=%s, file=%s, option=%s\n",
220 User, Filename, Options[(int)Option]))
221}
222
223
224static void
225list_cmd() {
226 char n[MAX_FNAME];
227 FILE *f;
228 int ch;
229
230 log_it(RealUser, Pid, "LIST", User);
231 (void) sprintf(n, CRON_TAB(User));
232 if (!(f = fopen(n, "r"))) {
233 if (errno == ENOENT)
255 fprintf(stderr, "no crontab for %s\n", User);
234 errx(ERROR_EXIT, "no crontab for %s", User);
256 else
235 else
257 perror(n);
258 exit(ERROR_EXIT);
236 err(ERROR_EXIT, "%s", n);
259 }
260
261 /* file is open. copy to stdout, close.
262 */
263 Set_LineNum(1)
264 while (EOF != (ch = get_char(f)))
265 putchar(ch);
266 fclose(f);
267}
268
269
270static void
271delete_cmd() {
272 char n[MAX_FNAME];
273
274 log_it(RealUser, Pid, "DELETE", User);
275 (void) sprintf(n, CRON_TAB(User));
276 if (unlink(n)) {
277 if (errno == ENOENT)
237 }
238
239 /* file is open. copy to stdout, close.
240 */
241 Set_LineNum(1)
242 while (EOF != (ch = get_char(f)))
243 putchar(ch);
244 fclose(f);
245}
246
247
248static void
249delete_cmd() {
250 char n[MAX_FNAME];
251
252 log_it(RealUser, Pid, "DELETE", User);
253 (void) sprintf(n, CRON_TAB(User));
254 if (unlink(n)) {
255 if (errno == ENOENT)
278 fprintf(stderr, "no crontab for %s\n", User);
256 errx(ERROR_EXIT, "no crontab for %s", User);
279 else
257 else
280 perror(n);
281 exit(ERROR_EXIT);
258 err(ERROR_EXIT, "%s", n);
282 }
283 poke_daemon();
284}
285
286
287static void
288check_error(msg)
289 char *msg;

--- 12 unchanged lines hidden (view full) ---

302 time_t mtime;
303 WAIT_T waiter;
304 PID_T pid, xpid;
305 mode_t um;
306
307 log_it(RealUser, Pid, "BEGIN EDIT", User);
308 (void) sprintf(n, CRON_TAB(User));
309 if (!(f = fopen(n, "r"))) {
259 }
260 poke_daemon();
261}
262
263
264static void
265check_error(msg)
266 char *msg;

--- 12 unchanged lines hidden (view full) ---

279 time_t mtime;
280 WAIT_T waiter;
281 PID_T pid, xpid;
282 mode_t um;
283
284 log_it(RealUser, Pid, "BEGIN EDIT", User);
285 (void) sprintf(n, CRON_TAB(User));
286 if (!(f = fopen(n, "r"))) {
310 if (errno != ENOENT) {
311 perror(n);
312 exit(ERROR_EXIT);
313 }
314 fprintf(stderr, "no crontab for %s - using an empty one\n",
315 User);
316 if (!(f = fopen("/dev/null", "r"))) {
317 perror("/dev/null");
318 exit(ERROR_EXIT);
319 }
287 if (errno != ENOENT)
288 err(ERROR_EXIT, "%s", n);
289 warnx("no crontab for %s - using an empty one", User);
290 if (!(f = fopen("/dev/null", "r")))
291 err(ERROR_EXIT, "/dev/null");
320 }
321
322 um = umask(077);
323 (void) sprintf(Filename, "/tmp/crontab.XXXXXXXXXX");
324 if ((t = mkstemp(Filename)) == -1) {
292 }
293
294 um = umask(077);
295 (void) sprintf(Filename, "/tmp/crontab.XXXXXXXXXX");
296 if ((t = mkstemp(Filename)) == -1) {
325 perror(Filename);
297 warn("%s", Filename);
326 (void) umask(um);
327 goto fatal;
328 }
329 (void) umask(um);
330#ifdef HAS_FCHOWN
331 if (fchown(t, getuid(), getgid()) < 0) {
332#else
333 if (chown(Filename, getuid(), getgid()) < 0) {
334#endif
298 (void) umask(um);
299 goto fatal;
300 }
301 (void) umask(um);
302#ifdef HAS_FCHOWN
303 if (fchown(t, getuid(), getgid()) < 0) {
304#else
305 if (chown(Filename, getuid(), getgid()) < 0) {
306#endif
335 perror("fchown");
307 warn("fchown");
336 goto fatal;
337 }
338 if (!(NewCrontab = fdopen(t, "w"))) {
308 goto fatal;
309 }
310 if (!(NewCrontab = fdopen(t, "w"))) {
339 perror("fdopen");
311 warn("fdopen");
340 goto fatal;
341 }
342
343 Set_LineNum(1)
344
345 /* ignore the top few comments since we probably put them there.
346 */
347 for (x = 0; x < NHEADER_LINES; x++) {

--- 12 unchanged lines hidden (view full) ---

360 }
361
362 /* copy the rest of the crontab (if any) to the temp file.
363 */
364 if (EOF != ch)
365 while (EOF != (ch = get_char(f)))
366 putc(ch, NewCrontab);
367 fclose(f);
312 goto fatal;
313 }
314
315 Set_LineNum(1)
316
317 /* ignore the top few comments since we probably put them there.
318 */
319 for (x = 0; x < NHEADER_LINES; x++) {

--- 12 unchanged lines hidden (view full) ---

332 }
333
334 /* copy the rest of the crontab (if any) to the temp file.
335 */
336 if (EOF != ch)
337 while (EOF != (ch = get_char(f)))
338 putc(ch, NewCrontab);
339 fclose(f);
368 if (fclose(NewCrontab)) {
369 perror(Filename);
370 exit(ERROR_EXIT);
371 }
340 if (fclose(NewCrontab))
341 err(ERROR_EXIT, "%s", Filename);
372 again:
373 if (stat(Filename, &statbuf) < 0) {
342 again:
343 if (stat(Filename, &statbuf) < 0) {
374 perror("stat");
344 warn("stat");
375 fatal: unlink(Filename);
376 exit(ERROR_EXIT);
377 }
378 mtime = statbuf.st_mtime;
379
380 if ((!(editor = getenv("VISUAL")))
381 && (!(editor = getenv("EDITOR")))
382 ) {

--- 5 unchanged lines hidden (view full) ---

388 * new one; even backup files are supposed to be made by copying
389 * rather than by renaming. if some editor does not support this,
390 * then don't use it. the security problems are more severe if we
391 * close and reopen the file around the edit.
392 */
393
394 switch (pid = fork()) {
395 case -1:
345 fatal: unlink(Filename);
346 exit(ERROR_EXIT);
347 }
348 mtime = statbuf.st_mtime;
349
350 if ((!(editor = getenv("VISUAL")))
351 && (!(editor = getenv("EDITOR")))
352 ) {

--- 5 unchanged lines hidden (view full) ---

358 * new one; even backup files are supposed to be made by copying
359 * rather than by renaming. if some editor does not support this,
360 * then don't use it. the security problems are more severe if we
361 * close and reopen the file around the edit.
362 */
363
364 switch (pid = fork()) {
365 case -1:
396 perror("fork");
366 warn("fork");
397 goto fatal;
398 case 0:
399 /* child */
367 goto fatal;
368 case 0:
369 /* child */
400 if (setuid(getuid()) < 0) {
401 perror("setuid(getuid())");
402 exit(ERROR_EXIT);
403 }
404 if (chdir("/tmp") < 0) {
405 perror("chdir(/tmp)");
406 exit(ERROR_EXIT);
407 }
408 if (strlen(editor) + strlen(Filename) + 2 >= MAX_TEMPSTR) {
409 fprintf(stderr, "%s: editor or filename too long\n",
410 ProgramName);
411 exit(ERROR_EXIT);
412 }
370 if (setuid(getuid()) < 0)
371 err(ERROR_EXIT, "setuid(getuid())");
372 if (chdir("/tmp") < 0)
373 err(ERROR_EXIT, "chdir(/tmp)");
374 if (strlen(editor) + strlen(Filename) + 2 >= MAX_TEMPSTR)
375 errx(ERROR_EXIT, "editor or filename too long");
413 execlp(editor, editor, Filename, NULL);
376 execlp(editor, editor, Filename, NULL);
414 perror(editor);
415 exit(ERROR_EXIT);
377 err(ERROR_EXIT, "%s", editor);
416 /*NOTREACHED*/
417 default:
418 /* parent */
419 break;
420 }
421
422 /* parent */
423 {
424 void (*f[4])();
425 f[0] = signal(SIGHUP, SIG_IGN);
426 f[1] = signal(SIGINT, SIG_IGN);
427 f[2] = signal(SIGTERM, SIG_IGN);
428 xpid = wait(&waiter);
429 signal(SIGHUP, f[0]);
430 signal(SIGINT, f[1]);
431 signal(SIGTERM, f[2]);
432 }
433 if (xpid != pid) {
378 /*NOTREACHED*/
379 default:
380 /* parent */
381 break;
382 }
383
384 /* parent */
385 {
386 void (*f[4])();
387 f[0] = signal(SIGHUP, SIG_IGN);
388 f[1] = signal(SIGINT, SIG_IGN);
389 f[2] = signal(SIGTERM, SIG_IGN);
390 xpid = wait(&waiter);
391 signal(SIGHUP, f[0]);
392 signal(SIGINT, f[1]);
393 signal(SIGTERM, f[2]);
394 }
395 if (xpid != pid) {
434 fprintf(stderr, "%s: wrong PID (%d != %d) from \"%s\"\n",
435 ProgramName, xpid, pid, editor);
396 warnx("wrong PID (%d != %d) from \"%s\"", xpid, pid, editor);
436 goto fatal;
437 }
438 if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) {
397 goto fatal;
398 }
399 if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) {
439 fprintf(stderr, "%s: \"%s\" exited with status %d\n",
440 ProgramName, editor, WEXITSTATUS(waiter));
400 warnx("\"%s\" exited with status %d", editor, WEXITSTATUS(waiter));
441 goto fatal;
442 }
443 if (WIFSIGNALED(waiter)) {
401 goto fatal;
402 }
403 if (WIFSIGNALED(waiter)) {
444 fprintf(stderr,
445 "%s: \"%s\" killed; signal %d (%score dumped)\n",
446 ProgramName, editor, WTERMSIG(waiter),
447 WCOREDUMP(waiter) ?"" :"no ");
404 warnx("\"%s\" killed; signal %d (%score dumped)",
405 editor, WTERMSIG(waiter), WCOREDUMP(waiter) ?"" :"no ");
448 goto fatal;
449 }
450 if (stat(Filename, &statbuf) < 0) {
406 goto fatal;
407 }
408 if (stat(Filename, &statbuf) < 0) {
451 perror("stat");
409 warn("stat");
452 goto fatal;
453 }
454 if (mtime == statbuf.st_mtime) {
410 goto fatal;
411 }
412 if (mtime == statbuf.st_mtime) {
455 fprintf(stderr, "%s: no changes made to crontab\n",
456 ProgramName);
413 warnx("no changes made to crontab");
457 goto remove;
458 }
414 goto remove;
415 }
459 fprintf(stderr, "%s: installing new crontab\n", ProgramName);
416 warnx("installing new crontab");
460 if (!(NewCrontab = fopen(Filename, "r"))) {
417 if (!(NewCrontab = fopen(Filename, "r"))) {
461 perror(Filename);
418 warn("%s", Filename);
462 goto fatal;
463 }
464 switch (replace_cmd()) {
465 case 0:
466 break;
467 case -1:
468 for (;;) {
469 printf("Do you want to retry the same edit? ");

--- 7 unchanged lines hidden (view full) ---

477 goto abandon;
478 default:
479 fprintf(stderr, "Enter Y or N\n");
480 }
481 }
482 /*NOTREACHED*/
483 case -2:
484 abandon:
419 goto fatal;
420 }
421 switch (replace_cmd()) {
422 case 0:
423 break;
424 case -1:
425 for (;;) {
426 printf("Do you want to retry the same edit? ");

--- 7 unchanged lines hidden (view full) ---

434 goto abandon;
435 default:
436 fprintf(stderr, "Enter Y or N\n");
437 }
438 }
439 /*NOTREACHED*/
440 case -2:
441 abandon:
485 fprintf(stderr, "%s: edits left in %s\n",
486 ProgramName, Filename);
442 warnx("edits left in %s", Filename);
487 goto done;
488 default:
443 goto done;
444 default:
489 fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n",
490 ProgramName);
445 warnx("panic: bad switch() in replace_cmd()");
491 goto fatal;
492 }
493 remove:
494 unlink(Filename);
495 done:
496 log_it(RealUser, Pid, "END EDIT", User);
497}
498

--- 7 unchanged lines hidden (view full) ---

506 char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME];
507 FILE *tmp;
508 int ch, eof;
509 entry *e;
510 time_t now = time(NULL);
511 char **envp = env_init();
512
513 if (envp == NULL) {
446 goto fatal;
447 }
448 remove:
449 unlink(Filename);
450 done:
451 log_it(RealUser, Pid, "END EDIT", User);
452}
453

--- 7 unchanged lines hidden (view full) ---

461 char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME];
462 FILE *tmp;
463 int ch, eof;
464 entry *e;
465 time_t now = time(NULL);
466 char **envp = env_init();
467
468 if (envp == NULL) {
514 fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
469 warnx("cannot allocate memory");
515 return (-2);
516 }
517
518 (void) sprintf(n, "tmp.%d", Pid);
519 (void) sprintf(tn, CRON_TAB(n));
520 if (!(tmp = fopen(tn, "w+"))) {
470 return (-2);
471 }
472
473 (void) sprintf(n, "tmp.%d", Pid);
474 (void) sprintf(tn, CRON_TAB(n));
475 if (!(tmp = fopen(tn, "w+"))) {
521 perror(tn);
476 warn("%s", tn);
522 return (-2);
523 }
524
525 /* write a signature at the top of the file.
526 *
527 * VERY IMPORTANT: make sure NHEADER_LINES agrees with this code.
528 */
529 fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");

--- 5 unchanged lines hidden (view full) ---

535 Set_LineNum(1)
536 while (EOF != (ch = get_char(NewCrontab)))
537 putc(ch, tmp);
538 fclose(NewCrontab);
539 ftruncate(fileno(tmp), ftell(tmp));
540 fflush(tmp); rewind(tmp);
541
542 if (ferror(tmp)) {
477 return (-2);
478 }
479
480 /* write a signature at the top of the file.
481 *
482 * VERY IMPORTANT: make sure NHEADER_LINES agrees with this code.
483 */
484 fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");

--- 5 unchanged lines hidden (view full) ---

490 Set_LineNum(1)
491 while (EOF != (ch = get_char(NewCrontab)))
492 putc(ch, tmp);
493 fclose(NewCrontab);
494 ftruncate(fileno(tmp), ftell(tmp));
495 fflush(tmp); rewind(tmp);
496
497 if (ferror(tmp)) {
543 fprintf(stderr, "%s: error while writing new crontab to %s\n",
544 ProgramName, tn);
498 warnx("error while writing new crontab to %s", tn);
545 fclose(tmp); unlink(tn);
546 return (-2);
547 }
548
549 /* check the syntax of the file being installed.
550 */
551
552 /* BUG: was reporting errors after the EOF if there were any errors

--- 13 unchanged lines hidden (view full) ---

566 free(e);
567 break;
568 case TRUE:
569 break;
570 }
571 }
572
573 if (CheckErrorCount != 0) {
499 fclose(tmp); unlink(tn);
500 return (-2);
501 }
502
503 /* check the syntax of the file being installed.
504 */
505
506 /* BUG: was reporting errors after the EOF if there were any errors

--- 13 unchanged lines hidden (view full) ---

520 free(e);
521 break;
522 case TRUE:
523 break;
524 }
525 }
526
527 if (CheckErrorCount != 0) {
574 fprintf(stderr, "errors in crontab file, can't install.\n");
528 warnx("errors in crontab file, can't install");
575 fclose(tmp); unlink(tn);
576 return (-1);
577 }
578
579#ifdef HAS_FCHOWN
580 if (fchown(fileno(tmp), ROOT_UID, -1) < OK)
581#else
582 if (chown(tn, ROOT_UID, -1) < OK)
583#endif
584 {
529 fclose(tmp); unlink(tn);
530 return (-1);
531 }
532
533#ifdef HAS_FCHOWN
534 if (fchown(fileno(tmp), ROOT_UID, -1) < OK)
535#else
536 if (chown(tn, ROOT_UID, -1) < OK)
537#endif
538 {
585 perror("chown");
539 warn("chown");
586 fclose(tmp); unlink(tn);
587 return (-2);
588 }
589
590#ifdef HAS_FCHMOD
591 if (fchmod(fileno(tmp), 0600) < OK)
592#else
593 if (chmod(tn, 0600) < OK)
594#endif
595 {
540 fclose(tmp); unlink(tn);
541 return (-2);
542 }
543
544#ifdef HAS_FCHMOD
545 if (fchmod(fileno(tmp), 0600) < OK)
546#else
547 if (chmod(tn, 0600) < OK)
548#endif
549 {
596 perror("chown");
550 warn("chown");
597 fclose(tmp); unlink(tn);
598 return (-2);
599 }
600
601 if (fclose(tmp) == EOF) {
551 fclose(tmp); unlink(tn);
552 return (-2);
553 }
554
555 if (fclose(tmp) == EOF) {
602 perror("fclose");
556 warn("fclose");
603 unlink(tn);
604 return (-2);
605 }
606
607 (void) sprintf(n, CRON_TAB(User));
608 if (rename(tn, n)) {
557 unlink(tn);
558 return (-2);
559 }
560
561 (void) sprintf(n, CRON_TAB(User));
562 if (rename(tn, n)) {
609 fprintf(stderr, "%s: error renaming %s to %s\n",
610 ProgramName, tn, n);
611 perror("rename");
563 warn("error renaming %s to %s", tn, n);
612 unlink(tn);
613 return (-2);
614 }
615 log_it(RealUser, Pid, "REPLACE", User);
616
617 poke_daemon();
618
619 return (0);

--- 4 unchanged lines hidden (view full) ---

624poke_daemon() {
625#ifdef USE_UTIMES
626 struct timeval tvs[2];
627 struct timezone tz;
628
629 (void) gettimeofday(&tvs[0], &tz);
630 tvs[1] = tvs[0];
631 if (utimes(SPOOL_DIR, tvs) < OK) {
564 unlink(tn);
565 return (-2);
566 }
567 log_it(RealUser, Pid, "REPLACE", User);
568
569 poke_daemon();
570
571 return (0);

--- 4 unchanged lines hidden (view full) ---

576poke_daemon() {
577#ifdef USE_UTIMES
578 struct timeval tvs[2];
579 struct timezone tz;
580
581 (void) gettimeofday(&tvs[0], &tz);
582 tvs[1] = tvs[0];
583 if (utimes(SPOOL_DIR, tvs) < OK) {
632 fprintf(stderr, "crontab: can't update mtime on spooldir\n");
633 perror(SPOOL_DIR);
584 warn("can't update mtime on spooldir %s", SPOOL_DIR);
634 return;
635 }
636#else
637 if (utime(SPOOL_DIR, NULL) < OK) {
585 return;
586 }
587#else
588 if (utime(SPOOL_DIR, NULL) < OK) {
638 fprintf(stderr, "crontab: can't update mtime on spooldir\n");
639 perror(SPOOL_DIR);
589 warn("can't update mtime on spooldir %s", SPOOL_DIR);
640 return;
641 }
642#endif /*USE_UTIMES*/
643}
590 return;
591 }
592#endif /*USE_UTIMES*/
593}