/* * amicron.c * * Public Domain (p) No Rights Reserved * * This program operates as a daemon, waking up every minute * to execute the CRONTAB table. Logging errors to CRONERR. * * Put in startup-sequence as: * run newcli con:0/140/160/50/CronTask s:startcron * The startcron file contains one line: * amicron * * Some notes are included below concerning the cron table * file format. In this version the cron table file is left * on disk and not moved to core, and the command character * to signify a newline '%' is not used. * * Some cron table entry examples: * * Print the date in the crontask window every minute: * * * * * * date * * Print the date in the crontask window on the hour, every hour: * 0 * * * * date * * Run uupc at 4:30 am every day except Sat and Sun: * 30 4 * * 1-5 uupc -siscuva * * Backup the files every other day at 7:30 pm: * 30 19 * * 1,3,5 sdbackup -s LAST dh0: incbkup_1: * */ /* * Public Domain (p) by S. R. Sampson * Version 2.3, October 1987 * Amiga port by Rick Schaeffer October 1987 * * Rick Schaeffer UUCP: seismo!uunet!iscuva!ricks!ricks * E. 13611 26th Ave. Phone: (509)928-3533 * Spokane, WA 99216 */ #include #include #include #define TRUE 1 #define FALSE 0 #define CRONTAB "Sys:usr/spool/cron/crontab" #define CRONERR "Sys:usr/spool/cron/cronerr" #define MAXLINE 132 #define SIZE 64 extern int errno; int eof; char min[SIZE], hour[SIZE], day[SIZE], month[SIZE], wday[SIZE], command[SIZE]; char *tokv[] = { min, hour, day, month, wday }; FILE *fd, *err; /* * This is the basics, ready for bells and whistles * */ void main() { void wakeup(); /* * fopen() will create the file if it does not exist. * Any other errors will be output to stderr at startup. */ if ((err = fopen(CRONERR, "a")) == (FILE *)NULL) { perror("cron"); exit(1); } for (;;) { wakeup(); Delay(50*59); /* sleep for one minute */ } } void wakeup() { register struct tm *tm; struct tm *localtime(); char *ctime(); long cur_time; time(&cur_time); /* get the current time */ tm = localtime(&cur_time); /* break it down */ fd = fopen(CRONTAB, "r"); eof = FALSE; while (!eof) { if (getline() && match(min,tm->tm_min) && match(hour,tm->tm_hour) && match(day,tm->tm_mday) && match(month,tm->tm_mon) && match(wday,tm->tm_wday)) { fexecl("Run","Run",command,NULL); } } fclose(fd); } /* * A line consists of six fields. The first five are: * * minute: 0-59 * hour: 0-23 * day: 1-31 * month: 1-12 * weekday: 0-6 (Sunday = 0) * * The fields are seperated by spaces or tabs, with the * first field left justified (no leading spaces or tabs). * See below for optional field syntax. * * The last field is the command field. This command will * be executed by the CLI just as if typed from a console. */ int getline() { register char *p; register int i; char buffer[MAXLINE], *scanner(), *fgets(); if (fgets(buffer, sizeof buffer, fd) == NULL) { eof = TRUE; return(FALSE); } for (p = buffer, i = 0; i < 5; i++) { if ((p = scanner(tokv[i], p)) == (char *)NULL) return(FALSE); } strcpy(command, p); /* scoop the command */ return(TRUE); } char *scanner(token, offset) register char *token; /* target buffer to receive scanned token */ register char *offset; /* place holder into source buffer */ { while ((*offset != ' ') && (*offset != '\t') && *offset) *token++ = *offset++; /* * Check for possible error condition */ if (!*offset) return ((char *)NULL); *token = '\0'; while ((*offset == ' ') || (*offset == '\t')) offset++; return (offset); } /* * This routine will match the left string with the right number. * * The string can contain the following syntax: * * * This will return TRUE for any number * x,y [,z, ...] This will return TRUE for any number given. * x-y This will return TRUE for any number within * the range of x thru y. */ int match(left, right) register char *left; register int right; { register int n; register char c; n = 0; if (!strcmp(left, "*")) return(TRUE); while ((c = *left++) && (c >= '0') && (c <= '9')) n = (n * 10) + c - '0'; switch (c) { case '\0': return (right == n); case ',': if (right == n) return(TRUE); do { n = 0; while ((c = *left++) && (c >= '0') && (c <= '9')) n = (n * 10) + c - '0'; if (right == n) return(TRUE); } while (c == ','); return(FALSE); case '-': if (right < n) return(FALSE); n = 0; while ((c = *left++) && (c >= '0') && (c <= '9')) n = (n * 10) + c - '0'; return(right <= n); } }