From: Thibault Godouet Date: Thu, 22 Jun 2000 12:33:55 +0000 (+0000) Subject: added options : forcemail dayand dayor runas nice X-Git-Tag: ver2_9_4~653 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a365eb9da357afe56f011cea64e33f001b23a21;p=thirdparty%2Ffcron.git added options : forcemail dayand dayor runas nice --- diff --git a/fileconf.c b/fileconf.c index 29a8843..5c6e95d 100644 --- a/fileconf.c +++ b/fileconf.c @@ -22,7 +22,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: fileconf.c,v 1.8 2000-06-21 15:00:07 thib Exp $ */ + /* $Id: fileconf.c,v 1.9 2000-06-22 12:33:55 thib Exp $ */ #include "fcrontab.h" @@ -30,6 +30,8 @@ char *get_string(char *ptr); int get_line(char *str, size_t size, FILE *file); char *get_time(char *ptr, time_t *time); char *get_num(char *ptr, int *num, int max, const char **names); +char *get_runas(char *ptr, uid_t *uid); +char *get_nice(char *ptr, int *nice); char *get_bool(char *ptr, int *i); char *read_field(char *ptr, bitstr_t *ary, int max, const char **names); void read_freq(char *ptr, CF *cf); @@ -42,6 +44,7 @@ char need_correction; CL default_line; /* default options for a line */ char *file_name; int line; +extern char *user; /* warning : all names must have the same length */ const char *dows_ary[] = { @@ -337,6 +340,62 @@ read_env(char *ptr, CF *cf) } + +char * +get_runas(char *ptr, uid_t *uid) + /* read a user name and put his uid in variable uid */ +{ + char name[USER_NAME_LEN]; + struct passwd *pas; + int i = 0; + + bzero(name, sizeof(name)); + + while ( isalnum(*ptr) && i < sizeof(name)) + name[i++] = *ptr++; + + if ((pas = getpwnam(user)) == NULL) { + fprintf(stderr, "%s is not in passwd file", name); + return NULL; + } + + *uid = pas->pw_uid; + + return ptr; + +} + + +char * +get_nice(char *ptr, int *nice) + /* read a nice value and put it in variable nice */ +{ + char negative = 0; + + if ( *ptr == '-' ) { + negative = 1; + ptr++; + } + + if ( (ptr = get_num(ptr, nice, 20, NULL)) == NULL ) + return NULL; + + if ( negative == 1 ) { + if (getuid() != 0) { + fprintf(stderr, "must be privileged to use a negative argument " + "with nice: set to 0\n"); + need_correction = 1; + *nice = 0; + } + + *nice *= (-1); + } + + return ptr; + +} + + char * get_bool(char *ptr, int *i) /* get a bool value : either true (1) or false (0) @@ -381,7 +440,7 @@ read_opt(char *ptr, CL *cl) #define Handle_err \ { \ fprintf(stderr, "%s:%d: Argument for option '%s' is not valid: " \ - "skipping line.\n", file_name, line, opt_name); \ + "skipping end of line.\n", file_name, line, opt_name); \ need_correction = 1; \ return NULL; \ } @@ -393,7 +452,7 @@ read_opt(char *ptr, CL *cl) i = 0; bzero(opt_name, sizeof(opt_name)); - while ( isalnum(*ptr) ) + while ( isalnum(*ptr) && i < sizeof(opt_name)) opt_name[i++] = *ptr++; i = 1; @@ -414,6 +473,7 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); } + else if(strcmp(opt_name, "b")==0 || strcmp(opt_name, "bootrun")==0){ if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) Handle_err; @@ -424,6 +484,7 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); } + else if( strcmp(opt_name, "reset")==0 ) { if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) Handle_err; @@ -438,6 +499,7 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' %ld\n",opt_name,cl->cl_nextexe); } + else if(strcmp(opt_name, "r")==0 || strcmp(opt_name, "runfreq")==0) { if( ! in_brackets || (ptr=get_num(ptr, &i, 65534, NULL)) == NULL ) Handle_err; @@ -445,6 +507,7 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); } + else if(strcmp(opt_name, "m")==0 || strcmp(opt_name, "mail")==0){ if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) Handle_err; @@ -455,6 +518,18 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); } + + else if( strcmp(opt_name, "forcemail") == 0 ) { + if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) + Handle_err; + if ( i == 0 ) + clear_mailzerolength(cl->cl_option); + else + set_mailzerolength(cl->cl_option); + if (debug_opt) + fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); + } + else if( strcmp(opt_name, "mailto") == 0) { char buf[50]; bzero(buf, sizeof(buf)); @@ -471,6 +546,53 @@ read_opt(char *ptr, CL *cl) if (debug_opt) fprintf(stderr, " Opt : '%s' '%s'\n", opt_name, buf); } + + else if( strcmp(opt_name, "dayand") == 0 ) { + if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) + Handle_err; + if ( i == 0 ) + set_dayor(cl->cl_option); + else + set_dayand(cl->cl_option); + if (debug_opt) + fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); + } + + else if( strcmp(opt_name, "dayor") == 0 ) { + if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL ) + Handle_err; + if ( i == 0 ) + set_dayand(cl->cl_option); + else + set_dayor(cl->cl_option); + if (debug_opt) + fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); + } + + else if(strcmp(opt_name, "n") == 0 || strcmp(opt_name, "nice") == 0) { + if( ! in_brackets || (ptr = get_nice(ptr, &i)) == NULL ) + Handle_err; + cl->cl_nice = (char)i; + if (debug_opt) + fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); + } + + else if(strcmp(opt_name, "runas") == 0) { + uid_t uid; + if (getuid() != 0) { + fprintf(stderr, "must be privileged to use option runas: " + "skipping option\n"); + need_correction = 1; + while( *ptr != ')' && *ptr != ' ' && *ptr != '\0' ) + ptr++; + } + if( ! in_brackets || (ptr = get_runas(ptr, &uid)) == NULL ) + Handle_err; + cl->cl_nice = i; + if (debug_opt) + fprintf(stderr, " Opt : '%s' %d\n", opt_name, i); + } + else { fprintf(stderr, "%s:%d: Option '%s' unknown: " "skipping option.\n", file_name, line, opt_name); @@ -552,11 +674,16 @@ read_freq(char *ptr, CF *cf) /* read a freq entry, and append a line to cf */ { CL *cl = NULL; + struct passwd *pas; Alloc(cl, CL); memcpy(cl, &default_line, sizeof(CL)); set_freq(cl->cl_option); cl->cl_runfreq = 0; + if ((pas = getpwnam(user)) == NULL) + die("failed to get uid for %s", user); + cl->cl_runas = pas->pw_uid; + /* skip the @ */ ptr++; diff --git a/global.h b/global.h index 1544de0..62b6f50 100644 --- a/global.h +++ b/global.h @@ -21,7 +21,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: global.h,v 1.11 2000-06-21 13:46:37 thib Exp $ */ + /* $Id: global.h,v 1.12 2000-06-22 12:34:37 thib Exp $ */ /* @@ -57,7 +57,7 @@ #include "option.h" -#define FILEVERSION "005" /* syntax's version of fcrontabs : +#define FILEVERSION "006" /* syntax's version of fcrontabs : * must have a length of 3 characters */ #define ERR -1 @@ -89,21 +89,23 @@ typedef struct CF { /* warning : do not change the order of the members of this structure * because some tests made are dependent to that order */ typedef struct CL { - struct CL *cl_next; - struct CF *cl_file; /* the file in which the line is */ - char cl_option; /* options for that line (see option.h) */ - char *cl_shell; /* shell command */ - pid_t cl_pid; /* running pid, 0, or armed (-1) */ - time_t cl_nextexe; /* time and date of the next execution */ - short int cl_remain; /* remaining until next execution */ - time_t cl_timefreq; /* Run every n seconds */ - short int cl_runfreq; /* Run once every n matches */ + struct CL *cl_next; + struct CF *cl_file; /* the file in which the line is */ + unsigned short cl_option; /* options for that line (see option.h) */ + char *cl_shell; /* shell command */ + char cl_nice; /* nice value to control priority */ + uid_t cl_runas; /* determine permissions of the job */ + pid_t cl_pid; /* running pid, 0, or armed (-1) */ + time_t cl_nextexe; /* time and date of the next execution */ + short int cl_remain; /* remaining until next execution */ + time_t cl_timefreq; /* Run every n seconds */ + short int cl_runfreq; /* Run once every n matches */ /* see bitstring(3) man page for more details */ - bitstr_t bit_decl(cl_mins, 60); /* 0-59 */ - bitstr_t bit_decl(cl_hrs, 24); /* 0-23 */ - bitstr_t bit_decl(cl_days, 32); /* 1-31 */ - bitstr_t bit_decl(cl_mons, 12); /* 0-11 */ - bitstr_t bit_decl(cl_dow, 8); /* 0-7, 0 and 7 are both Sunday */ + bitstr_t bit_decl(cl_mins, 60); /* 0-59 */ + bitstr_t bit_decl(cl_hrs, 24); /* 0-23 */ + bitstr_t bit_decl(cl_days, 32); /* 1-31 */ + bitstr_t bit_decl(cl_mons, 12); /* 0-11 */ + bitstr_t bit_decl(cl_dow, 8); /* 0-7, 0 and 7 are both Sunday */ } CL; typedef struct job { diff --git a/option.h b/option.h index 8aeaf88..110e74f 100644 --- a/option.h +++ b/option.h @@ -21,7 +21,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: option.h,v 1.4 2000-06-21 13:46:55 thib Exp $ */ + /* $Id: option.h,v 1.5 2000-06-22 12:35:03 thib Exp $ */ /* read and set options of a line */ @@ -33,14 +33,18 @@ 0 is this job based on time and date or system up time ? 1 is this job based on system load average ? 2 perform a logic OR or a logic AND between load averages ? - 3 should we run this job if it should have been executed - during system down? - 4 should this job be run serially ? - 5 does the output have to be mailed to user ? - 6 does the output (even if zero-length) must be mailed to user ? + 3 perform a logic OR or a logic AND between week day and month day ? + 4 should we run this job at fcron startup if it should have been + executed during system down? + 5 should this job be run serially ? + 6 is this job run serially only once (for bootrun) ? + 7 does the output have to be mailed to user ? + 8 does the output (even if zero-length) must be mailed to user ? */ +/* default value corresponds to a bit value of 0 */ + #ifndef __OPTIONH__ #define __OPTIONH__ @@ -98,64 +102,78 @@ (_bit_clear(opt, 2)) /* - bit 3 : set to 1 : run this line if it should have been executed - during system down - set to 0 : do not run it + bit 3 : set to 1 : perform a logic OR between week day and month day + set to 0 : perform a logic AND between week day and month day */ -#define is_bootrun(opt) \ +#define is_dayor(opt) \ (_bit_test(opt, 3)) -#define set_bootrun(opt) \ +#define is_dayand(opt) \ + ( ! _bit_test(opt, 3)) +#define set_dayor(opt) \ (_bit_set(opt, 3)) -#define clear_bootrun(opt) \ +#define set_dayand(opt) \ (_bit_clear(opt, 3)) /* - bit 4 : set to 1 : run this line serially - set to 0 : do not run it serially + bit 4 : set to 1 : run this line at fcron's startup if it should have been + executed during system down + set to 0 : do not run it at fcron's startup */ -#define is_serial(opt) \ +#define is_bootrun(opt) \ (_bit_test(opt, 4)) -#define set_serial(opt) \ +#define set_bootrun(opt) \ (_bit_set(opt, 4)) -#define clear_serial(opt) \ +#define clear_bootrun(opt) \ (_bit_clear(opt, 4)) /* - bit 5 : set to 1 : do not mail output - set to 0 : mail output to user + bit 5 : set to 1 : run this line serially + set to 0 : do not run it serially */ -#define is_mail(opt) \ - ( ! _bit_test(opt, 5)) -#define set_mail(opt) \ - (_bit_clear(opt, 5)) -#define clear_mail(opt) \ +#define is_serial(opt) \ + (_bit_test(opt, 5)) +#define set_serial(opt) \ (_bit_set(opt, 5)) +#define clear_serial(opt) \ + (_bit_clear(opt, 5)) /* - bit 6 : set to 1 : mail output even if it is zero-length to user - set to 0 : mail output only if it is non-zero length + bit 6 : set to 1 : job is being serialized once + set to 0 : job is not being serialized once */ -#define is_zerolength(opt) \ +#define is_serial_once(opt) \ (_bit_test(opt, 6)) -#define set_zerolength(opt) \ +#define set_serial_once(opt) \ (_bit_set(opt, 6)) -#define clear_zerolength(opt) \ +#define clear_serial_once(opt) \ (_bit_clear(opt, 6)) /* - bit 7 : set to 1 : job is being serialized once - set to 0 : job is not being serialized once + bit 7 : set to 1 : do not mail output + set to 0 : mail output to user */ -#define is_serial_once(opt) \ - (_bit_test(opt, 7)) -#define set_serial_once(opt) \ - (_bit_set(opt, 7)) -#define clear_serial_once(opt) \ +#define is_mail(opt) \ + ( ! _bit_test(opt, 7)) +#define set_mail(opt) \ (_bit_clear(opt, 7)) +#define clear_mail(opt) \ + (_bit_set(opt, 7)) + + +/* + bit 8 : set to 1 : mail output even if it is zero-length to user + set to 0 : mail output only if it is non-zero length +*/ +#define is_mailzerolength(opt) \ + (_bit_test(opt, 8)) +#define set_mailzerolength(opt) \ + (_bit_set(opt, 8)) +#define clear_mailzerolength(opt) \ + (_bit_clear(opt, 8)) #endif /* __OPTIONH__ */