entry.c (e93f27e3aeb7c0778012b7732bc6376e20f80427) | entry.c (fe590ffe40f49fe09d8275fbf29f0d46c5b99dc7) |
---|---|
1/* Copyright 1988,1990,1993,1994 by Paul Vixie | 1/* 2 * Copyright 1988,1990,1993,1994 by Paul Vixie |
2 * All rights reserved | 3 * All rights reserved |
4 */ 5 6/* 7 * Copyright (c) 1997 by Internet Software Consortium |
|
3 * | 8 * |
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. | 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. |
12 * | 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 | 13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. |
16 */ 17 18#if !defined(lint) && !defined(LINT) 19static const char rcsid[] = | 21 */ 22 23#if !defined(lint) && !defined(LINT) 24static const char rcsid[] = |
20 "$FreeBSD$"; | 25 "$Id: entry.c,v 1.3 1998/08/14 00:32:39 vixie Exp $"; |
21#endif 22 23/* vix 26jan87 [RCS'd; rest of log is in RCS file] 24 * vix 01jan87 [added line-level error recovery] 25 * vix 31dec86 [added /step to the from-to range, per bob@acornrc] 26 * vix 30dec86 [written] 27 */ 28 --- 8 unchanged lines hidden (view full) --- 37 e_none, e_minute, e_hour, e_dom, e_month, e_dow, 38 e_cmd, e_timespec, e_username, e_group, e_option, 39 e_mem 40#ifdef LOGIN_CAP 41 , e_class 42#endif 43} ecode_e; 44 | 26#endif 27 28/* vix 26jan87 [RCS'd; rest of log is in RCS file] 29 * vix 01jan87 [added line-level error recovery] 30 * vix 31dec86 [added /step to the from-to range, per bob@acornrc] 31 * vix 30dec86 [written] 32 */ 33 --- 8 unchanged lines hidden (view full) --- 42 e_none, e_minute, e_hour, e_dom, e_month, e_dow, 43 e_cmd, e_timespec, e_username, e_group, e_option, 44 e_mem 45#ifdef LOGIN_CAP 46 , e_class 47#endif 48} ecode_e; 49 |
45static char get_list(bitstr_t *, int, int, char *[], int, FILE *), 46 get_range(bitstr_t *, int, int, char *[], int, FILE *), 47 get_number(int *, int, char *[], int, FILE *); 48static int set_element(bitstr_t *, int, int, int); 49 50static char *ecodes[] = | 50static const char *ecodes[] = |
51 { 52 "no error", 53 "bad minute", 54 "bad hour", 55 "bad day-of-month", 56 "bad month", 57 "bad day-of-week", 58 "bad command", 59 "bad time specifier", 60 "bad username", 61 "bad group name", 62 "bad option", 63 "out of memory", 64#ifdef LOGIN_CAP 65 "bad class name", 66#endif 67 }; 68 | 51 { 52 "no error", 53 "bad minute", 54 "bad hour", 55 "bad day-of-month", 56 "bad month", 57 "bad day-of-week", 58 "bad command", 59 "bad time specifier", 60 "bad username", 61 "bad group name", 62 "bad option", 63 "out of memory", 64#ifdef LOGIN_CAP 65 "bad class name", 66#endif 67 }; 68 |
69static char get_list(bitstr_t *, int, int, const char *[], int, FILE *), 70 get_range(bitstr_t *, int, int, const char *[], int, FILE *), 71 get_number(int *, int, const char *[], int, FILE *); 72static int set_element(bitstr_t *, int, int, int); |
|
69 70void 71free_entry(entry *e) 72{ 73#ifdef LOGIN_CAP 74 if (e->class != NULL) 75 free(e->class); 76#endif --- 4 unchanged lines hidden (view full) --- 81 free(e); 82} 83 84 85/* return NULL if eof or syntax error occurs; 86 * otherwise return a pointer to a new entry. 87 */ 88entry * | 73 74void 75free_entry(entry *e) 76{ 77#ifdef LOGIN_CAP 78 if (e->class != NULL) 79 free(e->class); 80#endif --- 4 unchanged lines hidden (view full) --- 85 free(e); 86} 87 88 89/* return NULL if eof or syntax error occurs; 90 * otherwise return a pointer to a new entry. 91 */ 92entry * |
89load_entry(FILE *file, void (*error_func)(char *), struct passwd *pw, | 93load_entry(FILE *file, void (*error_func)(const char *), struct passwd *pw, |
90 char **envp) 91{ 92 /* this function reads one crontab entry -- the next -- from a file. 93 * it skips any leading blank lines, ignores comments, and returns 94 * EOF if for any reason the entry can't be read and parsed. 95 * 96 * the entry is also parsed here. 97 * 98 * syntax: 99 * user crontab: 100 * minutes hours doms months dows cmd\n 101 * system crontab (/etc/crontab): 102 * minutes hours doms months dows USERNAME cmd\n 103 */ 104 105 ecode_e ecode = e_none; 106 entry *e; 107 int ch; | 94 char **envp) 95{ 96 /* this function reads one crontab entry -- the next -- from a file. 97 * it skips any leading blank lines, ignores comments, and returns 98 * EOF if for any reason the entry can't be read and parsed. 99 * 100 * the entry is also parsed here. 101 * 102 * syntax: 103 * user crontab: 104 * minutes hours doms months dows cmd\n 105 * system crontab (/etc/crontab): 106 * minutes hours doms months dows USERNAME cmd\n 107 */ 108 109 ecode_e ecode = e_none; 110 entry *e; 111 int ch; |
112 int len; |
|
108 char cmd[MAX_COMMAND]; 109 char envstr[MAX_ENVSTR]; 110 char **prev_env; 111 112 Debug(DPARS, ("load_entry()...about to eat comments\n")) 113 114 skip_comments(file); 115 --- 258 unchanged lines hidden (view full) --- 374 e->envp = env_copy(envp); 375 if (e->envp == NULL) { 376 warn("env_copy"); 377 ecode = e_mem; 378 goto eof; 379 } 380 if (!env_get("SHELL", e->envp)) { 381 prev_env = e->envp; | 113 char cmd[MAX_COMMAND]; 114 char envstr[MAX_ENVSTR]; 115 char **prev_env; 116 117 Debug(DPARS, ("load_entry()...about to eat comments\n")) 118 119 skip_comments(file); 120 --- 258 unchanged lines hidden (view full) --- 379 e->envp = env_copy(envp); 380 if (e->envp == NULL) { 381 warn("env_copy"); 382 ecode = e_mem; 383 goto eof; 384 } 385 if (!env_get("SHELL", e->envp)) { 386 prev_env = e->envp; |
382 sprintf(envstr, "SHELL=%s", _PATH_BSHELL); 383 e->envp = env_set(e->envp, envstr); | 387 e->envp = env_set(e->envp, "SHELL=" _PATH_BSHELL); |
384 if (e->envp == NULL) { | 388 if (e->envp == NULL) { |
385 warn("env_set(%s)", envstr); | 389 warn("env_set(%s)", "SHELL=" _PATH_BSHELL); |
386 env_free(prev_env); 387 ecode = e_mem; 388 goto eof; 389 } 390 } 391 /* If LOGIN_CAP, this is deferred to do_command where the login class 392 * is processed. If !LOGIN_CAP, do it here. 393 */ 394#ifndef LOGIN_CAP 395 if (!env_get("HOME", e->envp)) { 396 prev_env = e->envp; | 390 env_free(prev_env); 391 ecode = e_mem; 392 goto eof; 393 } 394 } 395 /* If LOGIN_CAP, this is deferred to do_command where the login class 396 * is processed. If !LOGIN_CAP, do it here. 397 */ 398#ifndef LOGIN_CAP 399 if (!env_get("HOME", e->envp)) { 400 prev_env = e->envp; |
397 sprintf(envstr, "HOME=%s", pw->pw_dir); 398 e->envp = env_set(e->envp, envstr); 399 if (e->envp == NULL) { | 401 len = snprintf(envstr, sizeof(envstr), "HOME=%s", pw->pw_dir); 402 if (len < sizeof(envstr)) 403 e->envp = env_set(e->envp, envstr); 404 if (len >= sizeof(envstr) || e->envp == NULL) { |
400 warn("env_set(%s)", envstr); 401 env_free(prev_env); 402 ecode = e_mem; 403 goto eof; 404 } 405 } 406#endif 407 prev_env = e->envp; | 405 warn("env_set(%s)", envstr); 406 env_free(prev_env); 407 ecode = e_mem; 408 goto eof; 409 } 410 } 411#endif 412 prev_env = e->envp; |
408 sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name); 409 e->envp = env_set(e->envp, envstr); 410 if (e->envp == NULL) { | 413 len = snprintf(envstr, sizeof(envstr), "LOGNAME=%s", pw->pw_name); 414 if (len < (int)sizeof(envstr)) 415 e->envp = env_set(e->envp, envstr); 416 if (len >= (int)sizeof(envstr) || e->envp == NULL) { |
411 warn("env_set(%s)", envstr); 412 env_free(prev_env); 413 ecode = e_mem; 414 goto eof; 415 } 416#if defined(BSD) 417 prev_env = e->envp; | 417 warn("env_set(%s)", envstr); 418 env_free(prev_env); 419 ecode = e_mem; 420 goto eof; 421 } 422#if defined(BSD) 423 prev_env = e->envp; |
418 sprintf(envstr, "%s=%s", "USER", pw->pw_name); 419 e->envp = env_set(e->envp, envstr); 420 if (e->envp == NULL) { | 424 len = snprintf(envstr, sizeof(envstr), "USER=%s", pw->pw_name); 425 if (len < (int)sizeof(envstr)) 426 e->envp = env_set(e->envp, envstr); 427 if (len >= (int)sizeof(envstr) || e->envp == NULL) { |
421 warn("env_set(%s)", envstr); 422 env_free(prev_env); 423 ecode = e_mem; 424 goto eof; 425 } 426#endif 427 428 Debug(DPARS, ("load_entry()...checking for command options\n")) --- 43 unchanged lines hidden (view full) --- 472 473 unget_char(ch, file); 474 475 Debug(DPARS, ("load_entry()...about to parse command\n")) 476 477 /* Everything up to the next \n or EOF is part of the command... 478 * too bad we don't know in advance how long it will be, since we 479 * need to malloc a string for it... so, we limit it to MAX_COMMAND. | 428 warn("env_set(%s)", envstr); 429 env_free(prev_env); 430 ecode = e_mem; 431 goto eof; 432 } 433#endif 434 435 Debug(DPARS, ("load_entry()...checking for command options\n")) --- 43 unchanged lines hidden (view full) --- 479 480 unget_char(ch, file); 481 482 Debug(DPARS, ("load_entry()...about to parse command\n")) 483 484 /* Everything up to the next \n or EOF is part of the command... 485 * too bad we don't know in advance how long it will be, since we 486 * need to malloc a string for it... so, we limit it to MAX_COMMAND. |
480 * XXX - should use realloc(). | |
481 */ 482 ch = get_string(cmd, MAX_COMMAND, file, "\n"); 483 484 /* a file without a \n before the EOF is rude, so we'll complain... 485 */ 486 if (ch == EOF) { 487 ecode = e_cmd; 488 goto eof; --- 18 unchanged lines hidden (view full) --- 507 if (ecode != e_none && error_func) 508 (*error_func)(ecodes[(int)ecode]); 509 while (ch != EOF && ch != '\n') 510 ch = get_char(file); 511 return NULL; 512} 513 514 | 487 */ 488 ch = get_string(cmd, MAX_COMMAND, file, "\n"); 489 490 /* a file without a \n before the EOF is rude, so we'll complain... 491 */ 492 if (ch == EOF) { 493 ecode = e_cmd; 494 goto eof; --- 18 unchanged lines hidden (view full) --- 513 if (ecode != e_none && error_func) 514 (*error_func)(ecodes[(int)ecode]); 515 while (ch != EOF && ch != '\n') 516 ch = get_char(file); 517 return NULL; 518} 519 520 |
521/* 522 * bits one bit per flag, default=FALSE 523 * low, high bounds, impl. offset for bitstr 524 * names NULL or names for these elements 525 * ch current character being processed 526 * file file being read 527 */ |
|
515static char | 528static char |
516get_list(bitstr_t *bits, int low, int high, char *names[], int ch, FILE *file) | 529get_list(bitstr_t *bits, int low, int high, const char *names[], int ch, 530 FILE *file) |
517{ | 531{ |
518 register int done; | 532 int done; |
519 520 /* we know that we point to a non-blank character here; 521 * must do a Skip_Blanks before we exit, so that the 522 * next call (or the code that picks up the cmd) can 523 * assume the same thing. 524 */ 525 526 Debug(DPARS|DEXT, ("get_list()...entered\n")) --- 22 unchanged lines hidden (view full) --- 549 Skip_Blanks(ch, file) 550 551 Debug(DPARS|DEXT, ("get_list()...exiting w/ %02x\n", ch)) 552 553 return ch; 554} 555 556 | 533 534 /* we know that we point to a non-blank character here; 535 * must do a Skip_Blanks before we exit, so that the 536 * next call (or the code that picks up the cmd) can 537 * assume the same thing. 538 */ 539 540 Debug(DPARS|DEXT, ("get_list()...entered\n")) --- 22 unchanged lines hidden (view full) --- 563 Skip_Blanks(ch, file) 564 565 Debug(DPARS|DEXT, ("get_list()...exiting w/ %02x\n", ch)) 566 567 return ch; 568} 569 570 |
571/* 572 * bits one bit per flag, default=FALSE 573 * low, high bounds, impl. offset for bitstr 574 * names NULL or names for these elements 575 * ch current character being processed 576 * file file being read 577 */ |
|
557static char | 578static char |
558get_range(bitstr_t *bits, int low, int high, char *names[], int ch, FILE *file) | 579get_range(bitstr_t *bits, int low, int high, const char *names[], int ch, 580 FILE *file) |
559{ 560 /* range = number | number "-" number [ "/" number ] 561 */ 562 | 581{ 582 /* range = number | number "-" number [ "/" number ] 583 */ 584 |
563 register int i; 564 auto int num1, num2, num3; | 585 int i, num1, num2, num3; |
565 566 Debug(DPARS|DEXT, ("get_range()...entering, exit won't show\n")) 567 568 if (ch == '*') { 569 /* '*' means "first-last" but can still be modified by /step 570 */ 571 num1 = low; 572 num2 = high; --- 58 unchanged lines hidden (view full) --- 631 for (i = num1; i <= num2; i += num3) 632 if (EOF == set_element(bits, low, high, i)) 633 return EOF; 634 635 return ch; 636} 637 638 | 586 587 Debug(DPARS|DEXT, ("get_range()...entering, exit won't show\n")) 588 589 if (ch == '*') { 590 /* '*' means "first-last" but can still be modified by /step 591 */ 592 num1 = low; 593 num2 = high; --- 58 unchanged lines hidden (view full) --- 652 for (i = num1; i <= num2; i += num3) 653 if (EOF == set_element(bits, low, high, i)) 654 return EOF; 655 656 return ch; 657} 658 659 |
660/* 661 * numptr where does the result go? 662 * low offset applied to enum result 663 * names symbolic names, if any, for enums 664 * ch current character 665 * file source 666 */ |
|
639static char | 667static char |
640get_number(int *numptr, int low, char *names[], int ch, FILE *file) | 668get_number(int *numptr, int low, const char *names[], int ch, FILE *file) |
641{ 642 char temp[MAX_TEMPSTR], *pc; 643 int len, i, all_digits; 644 645 /* collect alphanumerics into our fixed-size temp array 646 */ 647 pc = temp; 648 len = 0; --- 53 unchanged lines hidden --- | 669{ 670 char temp[MAX_TEMPSTR], *pc; 671 int len, i, all_digits; 672 673 /* collect alphanumerics into our fixed-size temp array 674 */ 675 pc = temp; 676 len = 0; --- 53 unchanged lines hidden --- |