]> granicus.if.org Git - fcron/commitdiff
bug fixes + ask user for corrections
authorthib <thib>
Thu, 15 Jun 2000 20:17:06 +0000 (20:17 +0000)
committerthib <thib>
Thu, 15 Jun 2000 20:17:06 +0000 (20:17 +0000)
fcrontab.c
fileconf.c

index 877f853c8e1d766a51c6b0a590fe9519796b55ce..6ee65beae00e699bc5ee11de58d33d51fbea2694 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcrontab.c,v 1.5 2000-06-11 20:30:37 thib Exp $ */
+ /* $Id: fcrontab.c,v 1.6 2000-06-15 20:17:06 thib Exp $ */
 
 /* 
  * The goal of this program is simple : giving a user interface to fcron
@@ -42,7 +42,7 @@
 
 #include "fcrontab.h"
 
-char rcs_info[] = "$Id: fcrontab.c,v 1.5 2000-06-11 20:30:37 thib Exp $";
+char rcs_info[] = "$Id: fcrontab.c,v 1.6 2000-06-15 20:17:06 thib Exp $";
 
 void info(void);
 void usage(void);
@@ -284,15 +284,11 @@ remove_fcrontab(char rm_orig)
 
 }
 
+
 void
-make_file(char *file, char *user)
+write_file(char *file)
 {
 
-    explain("installing file '%s' for user %s", file, user);
-
-    /* read file and create a list in memory */
-    if ( read_file(file, user) != ERR ) {
-       
        if ( file_base->cf_line_base == NULL ) {
            /* no entries */
            explain("%s's fcrontab contains no entries", user);
@@ -315,14 +311,33 @@ make_file(char *file, char *user)
 
        } 
 
+}
+
+int
+make_file(char *file)
+{
+
+    explain("installing file '%s' for user %s", file, user);
+
+    /* read file and create a list in memory */
+    switch ( read_file(file, user) ) {
+    case 2:
+    case OK:
+
+       write_file(file);
+
        /* free memory used to store the list */
        delete_file(user);
 
        /* tell daemon to update the conf */
        need_sig = 1;
+       break;
 
-    } else
-       xexit(EXIT_ERR);
+    case ERR:
+       return ERR;
+    }
+
+    return OK;
     
 }
 
@@ -368,6 +383,7 @@ edit_file(char *buf)
     FILE *f, *fi;
     int file = 0;
     char c;
+    char correction = 0;
 
     explain("fcrontabs : editing %s's fcrontab", user);        
 
@@ -403,51 +419,89 @@ edit_file(char *buf)
     fclose(fi);
     close(file);
 
-    if ( stat(tmp, &st) == 0 )
-       mtime = st.st_mtime;
-    else
-       die_e("could not stat '%s'", buf);
+    do {
+
+       if ( stat(tmp, &st) == 0 )
+           mtime = st.st_mtime;
+       else
+           die_e("could not stat '%s'", buf);
     
 
-    switch ( pid = fork() ) {
-    case 0:
-       /* child */
-       if (setuid(getuid()) < 0) {
-           perror("setuid(getuid())");
+       switch ( pid = fork() ) {
+       case 0:
+           /* child */
+           if (setuid(getuid()) < 0) {
+               perror("setuid(getuid())");
+               xexit(EXIT_ERR);
+           }
+           execlp(editor, editor, tmp, NULL);
+           perror(editor);
            xexit(EXIT_ERR);
-       }
-       execlp(editor, editor, tmp, NULL);
-       perror(editor);
-       xexit(EXIT_ERR);
 
-    case -1:
-       perror("fork");
-       xexit(EXIT_ERR);
+       case -1:
+           perror("fork");
+           xexit(EXIT_ERR);
 
-    default:
-       /* parent */
-       break ;
-    }
+       default:
+           /* parent */
+           break ;
+       }
            
-    /* only reached by parent */
-    wait4(pid, &status, 0, NULL);
-    if ( ! WIFEXITED(status) ) {
-       fprintf(stderr, "Editor exited abnormally:"
-               " fcrontab is unchanged.\n");
-       xexit(EXIT_ERR);
-    }
+       /* only reached by parent */
+       wait4(pid, &status, 0, NULL);
+       if ( ! WIFEXITED(status) ) {
+           fprintf(stderr, "Editor exited abnormally:"
+                   " fcrontab is unchanged.\n");
+           xexit(EXIT_ERR);
+       }
 
-    /* check if file has been modified */
-    if ( stat(tmp, &st) != 0 )
-       die_e("could not stat %s", tmp);
+       /* check if file has been modified */
+       if ( stat(tmp, &st) != 0 )
+           die_e("could not stat %s", tmp);
     
-    else if ( st.st_mtime > mtime )
-       make_file(tmp, user);
+       else if ( st.st_mtime > mtime || correction == 1) {
+
+           correction = 0;
+
+           switch ( read_file(tmp, user) ) {
+           case ERR:
+               if ( remove(tmp) != 0 )
+                   error("could not remove %s", tmp);
+               xexit (EXIT_ERR);
+           case 2:
+               fprintf(stderr, "\nFile contains some errors. "
+                       "Ignore [i] or Correct [c] ? ");
+               /* the 2nd getchar() is for the newline char (\n) */
+               while ( (c = getchar()) && getchar() && c != 'i' && c != 'c' )
+                   fprintf(stderr, "Please press c to correct, "
+                           "or i to ignore: ");
+               if ( c == 'c' ) {
+                   /* free memory used to store the list */
+                   delete_file(user);
+                   correction = 1;
+               }
+               break;
+           default:
+               break;
+           }
+
+       }
+       else {
+           fprintf(stderr, "Fcrontab is unchanged :"
+                   " no need to install it.\n"); 
+           xexit(EXIT_OK);
+       }
 
-    else
-       fprintf(stderr, "Fcrontab is unchanged :"
-               " no need to install it.\n"); 
+    } while ( correction == 1);
 
+    write_file(tmp);
+    
+    /* free memory used to store the list */
+    delete_file(user);
+    
+    /* tell daemon to update the conf */
+    need_sig = 1;
+    
     if ( remove(tmp) != 0 )
        error("could not remove %s", tmp);
            
@@ -603,11 +657,14 @@ main(int argc, char **argv)
            if ( chown(tmp, getuid(), getgid()) != 0 )
                die_e("could not chown %s", tmp);
 
-           make_file(tmp, user);
-       
-           remove(tmp);
-
-           xexit ( EXIT_OK );
+           if ( make_file(tmp) == ERR ) {
+               remove(tmp);
+               xexit ( EXIT_ERR );
+           }
+           else {
+               remove(tmp);
+               xexit ( EXIT_OK );
+           }
 
        }
 
@@ -619,9 +676,10 @@ main(int argc, char **argv)
            else
                strncpy(file, argv[file_opt], sizeof(file));
 
-           make_file(file, user);
-       
-           xexit ( EXIT_OK );
+           if (make_file(file) == OK)
+               xexit ( EXIT_OK );
+           else
+               xexit ( EXIT_ERR );
 
        }
 
@@ -639,7 +697,6 @@ main(int argc, char **argv)
     }
 
 
-
     /* list user's entries */
     if ( list_opt == 1 ) {
 
@@ -650,7 +707,6 @@ main(int argc, char **argv)
     }
 
 
-
     /* edit user's entries */
     if ( edit_opt == 1 ) {
 
index d384e7b2f971bf0e59106fb2bec5aafb5c44d120..500c56c6f1f560899df9a16f12af5cf021b3949a 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fileconf.c,v 1.4 2000-06-10 22:16:44 thib Exp $ */
+ /* $Id: fileconf.c,v 1.5 2000-06-15 20:17:46 thib Exp $ */
 
 #include "fcrontab.h"
 
@@ -33,10 +33,12 @@ void read_freq(char *ptr, CF *cf, int line, char *file_name);
 void read_arys(char *ptr, CF *cf, int line, char *file_name);
 char *read_field(char *ptr, bitstr_t *ary, int max, const char **names,
               int line, char *file_name);
-void read_env(char *ptr, CF *cf, int line);
+void read_env(char *ptr, CF *cf, int line, char *file_name);
 char *get_string(char *ptr);
 
 
+char need_correction;
+
 /* warning : all names must have the same length */
 const char *dows_ary[] = {
     "sun", "mon", "tue", "wed", "thu", "fri", "sat",
@@ -70,9 +72,11 @@ get_string(char *ptr)
     if ( quote != 0 ) {
        if ( *(ptr + length - 1) == quote )
            *(ptr + length - 1) = '\0';
-       else
+       else {
            /* mismatched quotes */
+           need_correction = 1;
            return NULL;
+       }
     }
     
 
@@ -125,6 +129,7 @@ get_line(char *str, size_t size, FILE *file, int *line)
     while ((*str = getc(file)) != '\n' && *str != EOF )
        ;
     (*line)++;
+    need_correction = 1;
     return ERR;
 
 }
@@ -144,6 +149,7 @@ read_file(char *file_name, char *user)
     int ret;
     
     bzero(buf, sizeof(buf));
+    need_correction = 0;
 
     /* open file */
 
@@ -172,8 +178,8 @@ read_file(char *file_name, char *user)
        if ( (ret = get_line(buf, sizeof(buf), file, &line)) == OK)
            ;
        else if ( ret == ERR ) {
-           fprintf(stderr, "Line %d of %s is too long (more than %d):"
-                   " skipping line.\n",line, file_name, sizeof(buf));
+           fprintf(stderr, "%s:%d: Line is too long (more than %d):"
+                   " skipping line.\n", file_name, line, sizeof(buf));
            continue;
        } else
            /* EOF : no more lines */
@@ -207,7 +213,7 @@ read_file(char *file_name, char *user)
                read_arys(ptr, cf, line, file_name);
                entries++;
            } else
-               read_env(ptr, cf, line);
+               read_env(ptr, cf, line, file_name);
        }
 
        line++; 
@@ -220,12 +226,15 @@ read_file(char *file_name, char *user)
 
     fclose(file);
     
-    return OK;
+    if ( ! need_correction )
+       return OK;
+    else
+       return 2;
 
 }
 
 void
-read_env(char *ptr, CF *cf, int line)
+read_env(char *ptr, CF *cf, int line, char *file_name)
     /* append env variable list.
      * (remove blanks) */
 {
@@ -243,14 +252,21 @@ read_env(char *ptr, CF *cf, int line)
     }
     name[j] = '\0';
 
+    if ( name == '\0' )
+       goto error;
+
     /* skip '=' and spaces around */
-    while ( isspace(*ptr) || *ptr == '=' )
+    while ( isspace(*ptr) )
        ptr++;
 
+    /* if j == 0 name is a zero length string */
+    if ( *ptr++ != '=' || j == 0 )
+       goto error;
+
     /* get value */
     if ( ( val = get_string(ptr)) == NULL ) {
-       fprintf(stderr, "Error at line %d (mismatched"
-               " quotes): skipping line.\n", line);
+       fprintf(stderr, "%s:%d: Mismatched  quotes: skipping line.\n",
+               file_name, line);
        return;
     }
 
@@ -258,8 +274,11 @@ read_env(char *ptr, CF *cf, int line)
        fprintf(stderr, "  Env : '%s=%s'\n", name, val);
 
     /* we ignore USER's assignment */
-    if ( strcmp(name, "USER") == 0 )
+    if ( strcmp(name, "USER") == 0 ) {
+       fprintf(stderr, "%s:%d: USER assignement is not allowed: ignored.\n",
+               file_name, line);       
        return;
+    }
 
     /* the MAILTO assignment is, in fact, an fcron option :
      *  we don't store it in the same way. */
@@ -278,6 +297,11 @@ read_env(char *ptr, CF *cf, int line)
     
     return;
 
+  error:
+       fprintf(stderr, "%s:%d: Syntax error: skipping line.\n",
+               file_name, line);
+       return;
+
 }
 
 
@@ -306,10 +330,14 @@ get_time(char *ptr, time_t *time, int line, char *file_name )
        case 'd':               /* days */
            sum *= 24;
        case 'h':               /* hours */
-           sum *= 60;
+           sum *= 3600;
            ptr++;
+           break;
        default:                /* minutes */
-           sum *= 60;
+           if ( (*ptr != ' ') && (*ptr != '\t') ) {
+               need_correction = 1;
+               return NULL;
+           }
            
        }
 
@@ -333,15 +361,25 @@ read_freq(char *ptr, CF *cf, int line, char *file_name)
 
     ptr++;
     /* get the time before first execution */
-    ptr = get_time(ptr, &(cl->cl_nextexe), line, file_name);
+    if ( (ptr = get_time(ptr, &(cl->cl_nextexe), line, file_name)) == NULL ) {
+       fprintf(stderr, "%s:%d: Error while reading first delay:"
+               " skipping line.\n", file_name, line);
+       return;
+    }
 
     Skip_blanks(ptr);
 
     /* then cl_timefreq */
-    ptr = get_time(ptr, &(cl->cl_timefreq), line, file_name);
+    if ( (ptr = get_time(ptr, &(cl->cl_timefreq), line, file_name)) == NULL) {
+       fprintf(stderr, "%s:%d: Error while reading frequency:"
+               " skipping line.\n", file_name, line);
+       return;
+    }
+       
     if ( cl->cl_timefreq == 0) {
-       fprintf(stderr, "Error at line %d of file %s (no freq"
-               " specified): skipping line.\n", line, file_name);
+       fprintf(stderr, "%s:%d: no freq specified: skipping line.\n",
+               file_name, line);
+       need_correction = 1;
        free(cl);
        return;
     }
@@ -354,8 +392,8 @@ read_freq(char *ptr, CF *cf, int line, char *file_name)
 
     /* get cl_shell field ( remove trailing blanks ) */
     if ( (cl->cl_shell = get_string(ptr)) == NULL ) {
-       fprintf(stderr, "Error at line %d of file %s (mismatched"
-               " quotes): skipping line.\n", line, file_name);
+       fprintf(stderr, "%s:%d: Mismatched quotes: skipping line.\n",
+               file_name, line);
        free(cl);
        return;
     }
@@ -375,8 +413,8 @@ read_freq(char *ptr, CF *cf, int line, char *file_name)
   if((ptr = read_field(ptr, ary, max, aryconst, line, file_name)) == NULL) { \
       if (debug_opt) \
           fprintf(stderr, "\n"); \
-      fprintf(stderr, "Error while reading " descrp " field line %d" \
-             " of file %s: ignoring line.\n", line, file_name); \
+      fprintf(stderr, "%s:%d: Error while reading " descrp " field: " \
+             "skipping line.\n", file_name, line); \
       free(cl); \
       return; \
   }
@@ -426,8 +464,8 @@ read_arys(char *ptr, CF *cf, int line, char *file_name)
 
     /* get the shell command (remove trailing blanks) */
     if ( (cl->cl_shell = get_string(ptr)) == NULL ) {
-       fprintf(stderr, "Error at line %d of file %s (mismatched"
-               " quotes): skipping line.\n", line, file_name);
+       fprintf(stderr, "%s:%d: Mismatched quotes: skipping line.\n",
+               file_name, line);
        free(cl);
        return;
     }
@@ -451,8 +489,10 @@ read_num(char *ptr, int *num, int max, const char **names)
     if ( isalpha(*ptr) ) {
        int i;
 
-       if ( names == NULL )
+       if ( names == NULL ) {
+           need_correction = 1;
            return NULL;
+       }
 
        /* set string to lower case */
        for ( i = 0; i < strlen(names[0]); i++ )
@@ -467,6 +507,7 @@ read_num(char *ptr, int *num, int max, const char **names)
            }
 
        /* string is not in name list */
+       need_correction = 1;
        return NULL;
 
     } else {
@@ -479,8 +520,10 @@ read_num(char *ptr, int *num, int max, const char **names)
            *num *= 10; 
            *num += *ptr - 48; 
 
-           if (*num >= max) 
+           if (*num >= max) {
+               need_correction = 1;
                return NULL;
+           }
 
            ptr++; 
 
@@ -540,10 +583,11 @@ read_field(char *ptr, bitstr_t *ary, int max, const char **names,
                ptr++;
                if ( (ptr = read_num(ptr, &stop, max, names)) == NULL )
                    return NULL;
-           } else
+           } else {
                /* syntax error */
+               need_correction = 1;
                return NULL;
-
+           }
        }
 
        /* check for step size */