ricks@iscuva.ISCS.COM (Rick Schaeffer) (11/07/87)
The following posting contains the source and documentation for a cron task that runs on an Amiga. It can be compiled only with Aztec C 3.4 although mods to make it work with other compilers shouldn't be too tough. I hope no one minds my posting it here rather than comp.sources.amiga (it's pretty small). # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Amicron.doc # Makefile # Amicron.c # This archive created: Sat Nov 7 12:38:57 1987 cat << \SHAR_EOF > Amicron.doc AmiCron - Cron task for the Amiga This is a rather crude but effective version of the Unix (tm) program known as "cron" modified to run on an Amiga. For those who aren't Unix knowledgeable, cron is a background task which uses a disk-resident table to automatically run certain tasks on a regular basis. The cron table's format is very simple...it contains entries in the form of lines where each line has 6 fields and each field is separated by "white space" (either tabs or spaces) from it's neighbor. The fields are as follows: 1. Minute (0-59) 2. Hour (0-23) 3. Day (1-31) 4. Month (1-12) 5. Day of week (0-6 where 0=Sunday and 6=Saturday) 6. Command This is the command to be run at the appointed time. It will be run just as if typed into the CLI. Each of the first 5 fields are numbers. However, it is permissable to use an asterisk (*) in a field to mean ALL possible numbers for that field, and you can specify a series of numbers separated by commas (,) and ranges separated by dashes (-). For instance, in the Day field you could specify "1,5,10" to mean the first, fifth, and tenth days of the month; or you could specify "1-15" to mean the first through the fifteenth of the month. Here are some examples of Amicron table entries: 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 Incrementally backup the files every other day at 7:30 pm: 30 19 * * 1,3,5 sdbackup -l -s LAST dh0: incbkup_1: Backup the files on the 1st and 15th of each month at 1:00 am: 00 01 1,15 * * sdbackup -l dh0: SemiBkup_1: The Amicron table file is located using the following path: sys:usr/spool/cron/crontab and errors, if any are logged into the following path: sys:usr/spool/cron/cronerr Crontab entries *MUST* be left justified starting in column 1 and each entry must contain 6 fields, each separated by spaces or tabs. To run Amicron, you must first set up the directory "sys:usr/spool/cron" and then use your favorite editor to create the "crontab" file. Amicron needs a CLI window for displaying the output of the commands it runs...but it can be made as small or large as you wish. Assuming that you have placed Amicron in your command directory (c:), you can start it by typing the following line into a "newcli" window: Amicron Then you can size and move the window anywhere you want, just be sure not to type anything else into the window because that would prevent cron tasks from running. I have an entry in my startup-sequence file that looks like this: run newcli con:0/140/160/50/CronTask s:startcron The "s:startcron" file contains one line: Amicron This automatically sets up a tiny CronTask window and runs Amicron in it. This program was originally written by Steve R. Sampson (UUCP: sys1!killer!sampson), who very kindly responded to my request for a PD cron that I could port to Minix. I haven't done that yet (My new Amiga 2000 came in right after I received the cron program <grin>) but will do so ASAP. The modifications to make it run on the Amiga were very minor! Rick Schaeffer UUCP: seismo!uunet!iscuva!ricks E. 13611 26th Ave. Phone: (509)928-3533 Spokane, WA 99216 SHAR_EOF cat << \SHAR_EOF > Makefile Amicron: Amicron.o ln -o Amicron Amicron.o -lc32 Amicron.o: Amicron.c cc +l Amicron.c SHAR_EOF cat << \SHAR_EOF > Amicron.c /* * 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 <stdio.h> #include <time.h> #include <errno.h> #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); } } SHAR_EOF # End of shell archive exit 0 -- Rick Schaeffer UUCP: uunet!iscuva!ricks ISC Systems Corp. ricks@iscuva.ISCS.COM Box TAF-C8 Phone: (509)927-5114 Spokane, WA 99220