* `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"
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);
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[] = {
}
+
+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)
#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; \
}
i = 0;
bzero(opt_name, sizeof(opt_name));
- while ( isalnum(*ptr) )
+ while ( isalnum(*ptr) && i < sizeof(opt_name))
opt_name[i++] = *ptr++;
i = 1;
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;
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;
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;
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;
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));
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);
/* 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++;
* `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 $ */
/*
#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
/* 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 {
* `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 */
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__
(_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__ */