/* Check if str is a value (recursive). */
int is_digit(char *str) {
int response = FALSE;
if (strlen(str) == 0) response = TRUE; else
if ((str[0] >= '0') && (str[0] <= '9')) {
str++;
response = is_digit(str);
}
return response;
}
/* Get parameters from string (recursive).
* Uses ' ' and TAB as separators.
* Ignores stuff after '<separator>#'. */
struct parameters *get_parameters(char *str) {
par = (struct parameters *) cmalloc(sizeof(struct parameters));
bzero(par, sizeof(struct parameters));
/* Assume as separator the nearest space or tab */
tab = strchr(str, 9);
space = strchr(str, 32);
if (tab > space) right = space; else right = tab;
if (right == NULL) {
if (tab == NULL) right = space; else right = tab;
}
if (right == NULL) {
/* Ignore all after '#' */
if (str[0] == '#') {
free(par);
par = NULL;
} else {
if (strlen(str) == 0) {
free(par);
par = NULL;
} else {
par->param = (char *) cmalloc(strlen(str) + 1);
strcpy(par->param, str);
}
}
} else {
/* Separate line in two parts and store the left part. */
left = str;
right[0] = 0;
do right++; while ((right[0] == 32) || (right[0] == 9));
/* If left side of separator is null, don't store it. */
if (strlen(left) == 0) {
free(par);
if (strlen(right) > 0) par = get_parameters(right); else
par = NULL;
} else {
/* Ignore all after '#' */
if (left[0] == '#') {
free(par);
par = NULL;
} else {
par->param = (char *) cmalloc(strlen(left) + 1);
strcpy(par->param, left);
/* Acquire parameters of the remaining string. */
if (strlen(right) > 0) par->next = get_parameters(right);
}
}
}
return par;
}
/* Read and acquire data in config file. */
void read_config(void) {
char *config_line;
struct parameters *p, *bp;
int line_number;
int flag_correct = FALSE;
int flag_missing = FALSE;
if (strlen(config_line) > 0) {
bp = get_parameters(config_line);
p = bp;
/* Check configuration file parameters */
if ((p != NULL) && (p->param != NULL)) {
if (strcmp(p->param, "daily") == 0)
/* Process 'daily' line */
e->options = OPTIONS_DAILY; else
if (strcmp(p->param, "monthly") == 0)
/* Process 'monthly' line */
e->options = OPTIONS_MONTHLY; else
if (strcmp(p->param, "yearly") == 0)
/* Process 'yearly' line */
e->options = OPTIONS_YEARLY; else
if (strcmp(p->param, "once") == 0)
/* Process 'once' line */
e->options = OPTIONS_ONCE; else {
fprintf(stderr, "Unknown parameter '%s' in '%s'.\n", p->param, config_fname);
}
/* Process following parameters */
if (e->options != OPTIONS_NONE) {
p = p->next;
if ((p != NULL) && (p->param != NULL)) {
char *left, *middle, *right;
int is_day(char *day) {
int response = FALSE;
if (is_digit(day)) {
int val = atoi(day);
if ((val >= 1) && (val <= 31))
response = TRUE;
}
return response;
}
int is_month(char *month) {
int response = FALSE;
if (is_digit(month)) {
int val = atoi(month);
if ((val >= 1) && (val <= 12))
response = TRUE;
}
return response;
}
int is_year(char *year) {
int response = FALSE;
if (is_digit(year)) {
int val = atoi(year);
if ((val >= 1970) && (val <= 65535))
response = TRUE;
}
return response;
}
int is_hour(char *hour) {
int response = FALSE;
if (is_digit(hour)) {
int val = atoi(hour);
if ((val >= 0) && (val <= 23))
response = TRUE;
}
return response;
}
int is_minsec(char *minsec) {
int response = FALSE;
if (is_digit(minsec)) {
int val = atoi(minsec);
if ((val >= 0) && (val <= 60))
response = TRUE;
}
return response;
}
flag_correct = FALSE;
switch(e->options) {
case OPTIONS_DAILY:
if (strcmp(p->param, "-") != 0) {
fprintf(stderr, "Bad parameter '%s' in line %d: must be '-'.\n", p->param, line_number);
} else flag_correct = TRUE;
break;
case OPTIONS_MONTHLY:
if (is_day(p->param)) {
e->day = atoi(p->param);
flag_correct = TRUE;
}
if (! flag_correct)
fprintf(stderr, "Bad parameter '%s' in line %d: must be a value in the range of 1-31.\n", p->param, line_number);
break;
case OPTIONS_YEARLY:
if ((right = strchr(p->param, '/')) != NULL) {
left = p->param;
right[0] = 0;
right++;
if ((is_day(left)) && (is_month(right))) {
e->day = atoi(left);
e->month = atoi(right);
flag_correct = TRUE;
} else {
right--;
right[0] = '/';
}
}
if (! flag_correct)
fprintf(stderr, "Bad parameter '%s' in line %d: must be a date in the format 'dd/mm'.\n", p->param, line_number);
break;
case OPTIONS_ONCE:
if ((middle = strchr(p->param, '/')) != NULL) {
left = p->param;
middle[0] = 0;
middle++;
if ((right = strchr(middle, '/')) != NULL) {
right[0] = 0;
right++;
if ((is_day(left)) && (is_month(middle)) && (is_year(right))) {
e->day = atoi(left);
e->month = atoi(middle);
e->year = atoi(right);
flag_correct = TRUE;
} else {
right--;
right[0] = '/';
middle--;
middle[0] = '/';
}
} else {
middle--;
middle[0] = '/';
}
}
if (! flag_correct)
fprintf(stderr, "Bad parameter '%s' in line %d: must be a date in the format 'dd/mm/yyyy'.\n", p->param, line_number);
break;
}
/* Date acquired. */
} else {
fprintf(stderr, "Bad parameter '%s' in line %d: must be a time in the format 'hh:mm:ss'.\n", p->param, line_number);
bzero(e, sizeof(struct execution));
}
} else flag_missing = TRUE;
} else
bzero(e, sizeof(struct execution));
} else flag_missing = TRUE;
if (flag_missing) {
bzero(e, sizeof(struct execution));
fprintf(stderr, "Missing parameter in line %d.\n", line_number);
}
}
}
}
}
}
/* Close configuration file and check for errors. */
fclose_check();
}
/* Main function. */
int main(int argc, char **args, char **envs) {
struct tm *now_tm;
time_t now_time_t;
int daemon = FALSE;
int nodashed = 0;
int i;
/* Evaluate parameters. */
for (i = 1; i < argc; i++) {
switch (args[i][0]) {
case '-': /* Dashed parameters. */
if ((strcmp(args[i], "-c") == 0) || (strcmp(args[i], "--config") == 0)) {
if ((i + 1 < argc) && (args[i + 1][0] != '-')) {
i++;
config_fname = args[i];
} else {
fprintf(stderr, "Invalid use of '%s'. Try '%s --help' to know more.\n", args[i], PROGRAM_NAME);
exit(EXIT_NOPARAM);
}
} else
if ((strcmp(args[i], "-d") == 0) || (strcmp(args[i], "--daemon") == 0)) {
daemon = TRUE;
} else
if ((strcmp(args[i], "-h") == 0) || (strcmp(args[i], "--help") == 0)) {
printf("%s\n", PROGRAM_TITLE);
printf("Usage: %s [OPTIONS]\n\n", PROGRAM_NAME);
printf("OPTIONS\n");
printf(" -c, --config file read 'file' for configuration\n");
printf(" instead of '/etc/scheduler.conf'.\n");
printf(" -d, --daemon fork in background.\n");
printf(" -h, --help display this text.\n");
printf(" -v, --verbose run in verbose mode.\n\n");
printf("Report bugs to <nngodinh@tiscalinet.it>.\n");
} else
if ((strcmp(args[i], "-v") == 0) || (strcmp(args[i], "--verbose") == 0)) {
verbose = TRUE;
} else {
fprintf(stderr, "Illegal parameter '%s'. Try '%s --help' to know more.\n", args[i], PROGRAM_NAME);
exit(EXIT_NOPARAM);
}
break;