* `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
#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);
}
+
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);
}
+}
+
+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;
}
FILE *f, *fi;
int file = 0;
char c;
+ char correction = 0;
explain("fcrontabs : editing %s's fcrontab", user);
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);
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 );
+ }
}
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 );
}
}
-
/* list user's entries */
if ( list_opt == 1 ) {
}
-
/* edit user's entries */
if ( edit_opt == 1 ) {
* `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"
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",
if ( quote != 0 ) {
if ( *(ptr + length - 1) == quote )
*(ptr + length - 1) = '\0';
- else
+ else {
/* mismatched quotes */
+ need_correction = 1;
return NULL;
+ }
}
while ((*str = getc(file)) != '\n' && *str != EOF )
;
(*line)++;
+ need_correction = 1;
return ERR;
}
int ret;
bzero(buf, sizeof(buf));
+ need_correction = 0;
/* open file */
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 */
read_arys(ptr, cf, line, file_name);
entries++;
} else
- read_env(ptr, cf, line);
+ read_env(ptr, cf, line, file_name);
}
line++;
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) */
{
}
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;
}
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. */
return;
+ error:
+ fprintf(stderr, "%s:%d: Syntax error: skipping line.\n",
+ file_name, line);
+ return;
+
}
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;
+ }
}
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;
}
/* 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;
}
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; \
}
/* 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;
}
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++ )
}
/* string is not in name list */
+ need_correction = 1;
return NULL;
} else {
*num *= 10;
*num += *ptr - 48;
- if (*num >= max)
+ if (*num >= max) {
+ need_correction = 1;
return NULL;
+ }
ptr++;
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 */