home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * *
- * A M I C R O N *
- * *
- * Version 4.2 - 03-Jan-91 *
- * *
- * by P. Sainio *
- * *
- ****************************************************************************
-
- This is my version of AmiCron, I hope you like it... It's still
- in public domain so if you have any ideas let us know about them.
-
- *
- * amicron.c (Version 2.5(a&L) by <CB>)
- *
- * Public Domain (p) No Rights Reserved
- *
- * This program operates as a daemon, waking up every minute
- * to execute the CRONTAB table.
- *
- * Put in startup-sequence like:
- * run newcli con:0/140/160/50/CronTask s:startcron
- * The startcron file needs to contains just 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
- *
- * Modified path for CronTab & CronErr to suit Amiga enviroment better
- * Version 2.31 <CB> 15.12.87
- *
- * Fixed bug with CronTab entries specifying an event by date (month)
- * i.e. "* * 24 12 * say Merry christmas", now works!
- * Version 2.32 <CB> 25.12.87
- *
- * Removed "CronErr", an obvious Unix "feature"
- * Version 2.33 <CB> 31.12.87
- *
- * Additional support for Lattice 4.0, changed to complete sleep (no more
- * 5 I/O ints. per second), added command line parameter for CronTab path.
- * Added feature to align Cron to start on 01 seconds, including "loss"
- * due to lengthy command calls or extensive I/O.
- * Version 2.4 <CB> 10.01.88
- *
- * GRRRRRRR. Just when I thought it was safe to release that thing, C=A brings
- * out AmyDos 1.3. So to have the output of programs called by Cron visible, I
- * changed the "Run >nil:" parameter for execute() back to "Run ". This means,
- * that you will have to look at the annoying CLI[#] messages, each time some
- * program is called. I was pleased with the way the old RUN >nil: worked, and
- * will try to convince Andy Finkel to bring it back.
- * In the meantime, this is:
- * Version 2.5 <CB> 27.03.88
- *
- * Changed it to use ARP. There is two versions, one that detaches itself from
- * self and the other that doesn't
- * Version 4.2 <PS> 03.01.91
-
-
- ______ /
- ______\O - The Software Brewery -
- \\
- o Sparkling, fresh software from W.-Germany
-
- @@@@@ Straight from the bar to your Amiga
- |~~~|\
- | | |/
- |___| With our regards to the Software Distillery
-
- Members are (listed alphabetically):
- Christian Balzer alias <CB>, Lattice C, user interfaces, beer addict.
- Christof Bonnkirch, Aztec C, telecommunications, money adict.
- Heiko Rath alias <HR>, Assembler, ROM-Kernal stuff, Marabou addict.
- Peter Stark alias PS, Lattice C, IO & utilities, WordStar addict.
- Ralf Woitinas alias RAF, Assembler, anything, Ray-Tracing addict.
- Torsten Wronski alias MM, Assembler, anything, girls addict.
-
- Beverages: Altenmuenster Brauer Bier, Urfraenkisches Landbier, Grohe Bock.
-
- Send exotic drinks, comments, critizism, flames to:
-
- The Software Brewery
- Christian Balzer
- Im Wingertsberg 45
- D-6108 Weiterstadt
- West-Germany
-
- Our BBS "AmigaNode" isn't online yet. As soon as it becomes available,
- you'll be the first to know :-).
-
- *
- * Compilation notes:
- * Program is compiled with Lattice C 5.05 and the makefile is included.
- * I have removed some of the comments, sorry about that. If you're
- * intrested see the original source.
- *
- * NOTE!!! There is no errorchecking for crontab-file...
- */
-
- #define MAXLINE 132
- #define SIZE 64
- #define ABSEXECBASE ((struct ExecBase **)4L)
- #define NOCRON "Can't get crontab-file"
- #define CRONPORT "AmiCronV4.2"
- #define NO_MESS_MEM "No memory for message!"
- #define NO_REPLY "Could not create replyport!"
- #define ERR_IN_FILE "Error reading crontab-file!"
- #define NO_DEVICE "Could not open timer.device!"
- #define NO_TIMER_PORT "Could not open timerport!"
- #define NO_CRON_PORT "Could not create CronPort!"
- #define EXITING "Quiting the AmiCron!"
-
- struct cronmsg {
- struct Message cm_Msg;
- char *newfile;
- };
-
- struct iobuf {
- unsigned char *base;
- unsigned char *ptr;
- int rcnt;
- int size;
- };
-
- typedef char boolean;
-
- extern struct ArpBase *ArpBase;
- extern struct DOSBase *DOSBase;
- extern struct IntuitionBase *IntuitionBase;
-
- struct MsgPort *timerport,*cronport,*mycron=NULL,*replyport;
- struct iobuf fd;
- struct cronmsg *newcron;
-
- struct NewShell nsh;
- struct timerequest tr;
-
- char min[SIZE],hour[SIZE],day[SIZE],month[SIZE],wday[SIZE],command[SIZE],eof,
- *tokv[]={min,hour,day,month,wday},
- *com="CronFile",*args,*help="Usage: AmiCron [CronFile]",
- cronfile[256]="S:CronTab";
-
- struct TextAttr myfont = {
- "topaz.font",
- TOPAZ_EIGHTY,0,0 };
-
- struct IntuiText body1={
- 0,1,JAM1,10,5,&myfont,NULL,NULL },body2={
- 0,1,JAM1,10,14,&myfont,NULL,NULL },no1={
- 0,1,JAM1,6,3,&myfont,"Cancel",NULL },no2={
- 0,1,JAM1,6,3,&myfont,"Quit",NULL };
-
- static void cleanup(void),alarm(int),wakeup(void),MyExit(void);
- static ULONG systime(void);
- static boolean getline(void),getfile(void),
- match(register char *,register int);
- static char *scanner(register char *,register char *),
- *fgets(char *,int);
-
- void __asm __saveds AmiCron(register __a0 char *cmd,register __d0 long len) {
-
- ULONG current,signals,getsigs,timesig,messig;
- long count;
- register struct tm *tm;
-
- count=GADS(cmd,len,help,&args,com);
- if (count<0) {
- body1.IText=args;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,188,50);
- cleanup();
- }
-
- if (count)
- strcpy(cronfile,args);
-
- Forbid();
-
- if (mycron=FindPort(CRONPORT)) {
- Permit();
- if (replyport=CreatePort(0,0)) {
- if (newcron=AllocMem(sizeof(struct cronmsg),
- MEMF_PUBLIC|MEMF_CLEAR)) {
- newcron->cm_Msg.mn_Node.ln_Type=NT_MESSAGE;
- newcron->cm_Msg.mn_ReplyPort=replyport;
- newcron->newfile=cronfile;
- PutMsg(mycron,newcron);
- WaitPort(replyport);
- FreeMem(newcron,sizeof(struct cronmsg));
- }
- else {
- body1.IText=NO_MESS_MEM;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_MESS_MEM)*8+44,50);
- }
- DeletePort(replyport);
- }
- else {
- body1.IText=NO_REPLY;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_REPLY)*8+44,50);
- }
- cleanup();
- }
-
- else {
- if (!(cronport=CreatePort(CRONPORT,0))) {
- body1.IText=NO_CRON_PORT;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_CRON_PORT)*8+44,50);
- cleanup();
- }
- }
- Permit();
-
- if (timerport=CreatePort(0,0)) {
- tr.tr_node.io_Message.mn_Node.ln_Type=NT_MESSAGE;
- tr.tr_node.io_Message.mn_Length=sizeof(struct timerequest);
- tr.tr_node.io_Message.mn_ReplyPort=timerport;
-
- if (!OpenDevice(TIMERNAME,UNIT_VBLANK,&tr,0)) {
- if (getfile()) {
- signals=SIGBREAKF_CTRL_C|(timesig = 1<<timerport->mp_SigBit)|
- (messig = 1<<cronport->mp_SigBit);
- for (;;) {
- wakeup();
- current=systime();
- tm=localtime(¤t);
- alarm(60-tm->tm_sec);
- do {
- getsigs=Wait(signals);
- if (getsigs & SIGBREAKF_CTRL_C)
- cleanup();
- if (getsigs & messig) {
- if (newcron=(struct cronmsg *)GetMsg(cronport)) {
- strcpy(cronfile,newcron->newfile);
- ReplyMsg(newcron);
- DosFreeMem(fd.base);
- fd.base=NULL;
- if (!getfile())
- cleanup();
- }
- }
- }
- while (!(getsigs & timesig));
- }
- }
- }
- }
- cleanup();
- }
-
- static void wakeup() {
-
- register struct tm *tm;
- long cur_time;
-
- cur_time=systime(); /* get the current time */
- tm = localtime(&cur_time); /* break it down */
-
- /* Now let's see if there is a CronTab file out there <CB> */
-
- 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+1) && match(wday,tm->tm_wday)) {
- /* Weird localtime months ^ range from 0-11 !!! <CB>*/
- nsh.nsh_Pri=(*ABSEXECBASE)->ThisTask->tc_Node.ln_Pri;
- nsh.nsh_Control=BACKGROUND_SHELL;
- nsh.nsh_Input=Input();
- nsh.nsh_Output=Output();
- ASyncRun(command,NULL,(struct ProcessControlBlock *)&nsh);
- }
- }
- }
-
-
- /*
- * 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.
- */
-
- static boolean getline() {
- register char *p;
- register int i;
- char buffer[MAXLINE];
-
- if (fgets(buffer,sizeof buffer) == 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);
- }
-
-
- static char *scanner(register char *token,register char *offset) {
- /* *token target buffer to receive scanned token */
- /* *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.
- */
-
- static boolean match(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 ((boolean)(right == n));
-
- case ',':
- if ((boolean)(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((boolean)(right <= n));
- }
- }
-
- static boolean getfile(void) {
-
- BPTR lock,file;
- struct FileInfoBlock *fib;
- boolean succ=FALSE;
-
- if (lock=Lock(cronfile,ACCESS_READ)) {
- if (fib=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC)) {
- if (Examine(lock,fib)) {
- if (fd.base=DosAllocMem(fib->fib_Size)) {
- if (file=Open(cronfile,MODE_OLDFILE)) {
- fd.size=Read(file,fd.base,fib->fib_Size);
- if (fd.size=fib->fib_Size)
- fd.ptr=fd.base;
- succ=TRUE;
- Close(file);
- }
- }
- }
- FreeMem(fib,sizeof(struct FileInfoBlock));
- }
- UnLock(lock);
- }
- if (!succ) {
-
- long length;
-
- body1.IText=NOCRON;
- body1.NextText=&body2;
- body2.IText=cronfile;
- length=strlen(cronfile);
-
- AutoRequest(NULL,&body1,NULL,&no1,0,0,((length>sizeof(NOCRON))?
- length : sizeof(NOCRON))*8+44,59);
- }
- return succ;
- }
-
- static char *fgets(char *buffer,int len) {
-
- unsigned char ch;
- int count=0;
-
- while (len>count) {
- if (fd.rcnt<fd.size) {
- if ((ch=*fd.ptr++)=='\n') {
- buffer[count++]='\0';
- fd.rcnt++;
- return buffer;
- }
- buffer[count++]=ch;
- fd.rcnt++;
- }
- else {
- fd.rcnt=0;
- fd.ptr=fd.base;
- if (count==0)
- return NULL;
- else {
- buffer[count]='\0';
- return buffer;
- }
- }
- }
- }
-
- static ULONG systime() {
- tr.tr_node.io_Command=TR_GETSYSTIME;
- DoIO(&tr);
- return (tr.tr_time.tv_secs+(((8*365+2)*24+6)*60*60));
- /* To Greenwich Mean Time ^^^^^^^^^^^^^^^^^^^^^ */
- }
-
- static void alarm(int secs) {
- tr.tr_node.io_Command=TR_ADDREQUEST;
- tr.tr_time.tv_secs=secs;
- tr.tr_time.tv_micro=0;
- SendIO(&tr);
- }
-
- static void cleanup() {
- if (cronport) {
- Forbid();
- while (newcron=(struct cronmsg *)GetMsg(cronport))
- ReplyMsg(newcron);
- DeletePort(cronport);
- Permit();
- if (fd.base)
- DosFreeMem(fd.base);
- if (timerport) {
- if (tr.tr_node.io_Device) {
- if (tr.tr_node.io_Command)
- AbortIO(&tr);
- CloseDevice(&tr);
- }
- else {
- body1.IText=NO_DEVICE;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_DEVICE)*8+44,50);
- }
- DeletePort(timerport);
- }
- else {
- body1.IText=NO_TIMER_PORT;
- AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_TIMER_PORT)*8+44,50);
- }
- body1.IText=EXITING;
- body1.NextText=NULL;
- AutoRequest(NULL,&body1,NULL,&no2,0,0,sizeof(EXITING)*8+44,50);
- }
- MyExit();
- }
-