]> git.ipfire.org Git - thirdparty/fcron.git/commitdiff
added options : forcemail dayand dayor runas nice
authorThibault Godouet <yo8192@users.noreply.github.com>
Thu, 22 Jun 2000 12:33:55 +0000 (12:33 +0000)
committerThibault Godouet <yo8192@users.noreply.github.com>
Thu, 22 Jun 2000 12:33:55 +0000 (12:33 +0000)
fileconf.c
global.h
option.h

index 29a8843cbc119f414196069774fd60ac2362bc00..5c6e95de028774aebd0c9dfc16cf5b9136be2e43 100644 (file)
@@ -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++;
index 1544de07ae0a66464491c6db9b88f7e5ab020de9..62b6f50e0eba0a23a45e6c5655c2075223abd12a 100644 (file)
--- 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 {
index 8aeaf88cbf5bec482206795da25f103f57ebf35e..110e74fdb2782585d6e8356f97b6bdbd6554bb53 100644 (file)
--- 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 */
 
   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__ */