[comp.sources.amiga] v91i061: AmiCron 4.2 - cron task for the amiga, Part01/01

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (03/14/91)

Submitted-by: ps106363@lehtori.tut.fi (Pasi Sainio)
Posting-number: Volume 91, Issue 061
Archive-name: utilities/amicron-4.2/part01

[ includes uuencoded executables  ...tad ]

There is now two version.  One that detaches
itself from the running shell and the other one that doesn't.  So if
you need the shell-window use AmiCronS and if you don't, use AmiCron.
The other difference is the crontable IS NO LONGER DISK-RESIDENT!!.
The program will read it to the ram and use that.  If you want to use
an other crontable, just run the program with other filename.  It will
send a messages to the one that is resident and it will read the new 
table to the memory.

This is a (no longer) 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.


#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  AmiCron.c AmiCron.doc AmiCron.uu AmiCronS.uu crontab inc.c
#   makefile run.a self.a start.a
# Wrapped by tadguy@ab20 on Wed Mar 13 20:36:57 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'AmiCron.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AmiCron.c'\"
else
echo shar: Extracting \"'AmiCron.c'\" \(13838 characters\)
sed "s/^X//" >'AmiCron.c' <<'END_OF_FILE'
X/****************************************************************************
X *                                                                          *
X *                              A M I C R O N                               *
X *                                                                          *
X *                         Version 4.2 - 03-Jan-91                          *
X *                                                                          *
X *                              by P. Sainio                                *
X *                                                                          *
X ****************************************************************************
X
X	This is my version of AmiCron, I hope you like it... It's still
Xin public domain so if you have any ideas let us know about them.
X
X *
X *	amicron.c	(Version 2.5(a&L) by <CB>)
X *
X *	Public Domain (p) No Rights Reserved
X *
X *	This program operates as a daemon, waking up every minute
X *	to execute the CRONTAB table.  
X *
X *	Put in startup-sequence like:
X *		run newcli con:0/140/160/50/CronTask s:startcron
X *	The startcron file needs to contains just one line:
X *		amicron
X *
X *	Some notes are included below concerning the cron table
X *	file format.  In this version the cron table file is left
X *	on disk and not moved to core, and  the command character
X *	to signify a newline '%' is not used.
X *
X *	Some cron table entry examples:
X *
X *	Print the date in the crontask window every minute:
X *		* * * * * date
X *
X *	Print the date in the crontask window on the hour, every hour:
X *		0 * * * * date
X *
X *	Run uupc at 4:30 am every day except Sat and Sun:
X *		30 4 * * 1-5 uupc -siscuva
X *
X *	Backup the files every other day at 7:30 pm:
X *		30 19 * * 1,3,5 sdbackup -s LAST dh0: incbkup_1:
X *
X */
X
X/* 
X * Public Domain (p) by S. R. Sampson
X * Version 2.3, October 1987
X * Amiga port by Rick Schaeffer October 1987
X *
X * Rick Schaeffer          UUCP:  seismo!uunet!iscuva!ricks!ricks
X * E. 13611 26th Ave.      Phone: (509)928-3533
X * Spokane, WA  99216
X *
X * Modified path for CronTab & CronErr to suit Amiga enviroment better
X * Version 2.31  <CB> 15.12.87 
X *
X * Fixed bug with CronTab entries specifying an event by date (month)
X * i.e. "* * 24 12 * say Merry christmas", now works!
X * Version 2.32 <CB> 25.12.87
X *
X * Removed "CronErr", an obvious Unix "feature"
X * Version 2.33 <CB> 31.12.87 
X *
X * Additional support for Lattice 4.0, changed to complete sleep (no more  
X * 5 I/O ints. per second), added command line parameter for CronTab path.
X * Added feature to align Cron to start on 01 seconds, including "loss"
X * due to lengthy command calls or extensive I/O.
X * Version 2.4 <CB> 10.01.88 
X *
X * GRRRRRRR. Just when I thought it was safe to release that thing, C=A brings
X * out AmyDos 1.3. So to have the output of programs called by Cron visible, I
X * changed the "Run >nil:" parameter for execute() back to "Run ". This means,                         
X * that you will have to look at the annoying CLI[#] messages, each time some 
X * program is called. I was pleased with the way the old RUN >nil: worked, and
X * will try to convince Andy Finkel to bring it back.
X * In the meantime, this is:
X * Version 2.5 <CB> 27.03.88
X *
X * Changed it to use ARP.  There is two versions, one that detaches itself from
X * self and the other that doesn't
X * Version 4.2 <PS> 03.01.91
X
X                        
X______  /          
X______\O                    - The Software Brewery - 
X      \\              		    
X       o            Sparkling, fresh software from W.-Germany
X                 
X     @@@@@	      Straight from the bar to your Amiga
X     |~~~|\        
X     | | |/        
X     |___|        With our regards to the Software Distillery
X
XMembers are (listed alphabetically):
XChristian Balzer alias <CB>, Lattice C, user interfaces, beer addict. 
XChristof Bonnkirch, Aztec C, telecommunications, money adict.
XHeiko Rath alias <HR>, Assembler, ROM-Kernal stuff, Marabou addict. 
XPeter Stark alias PS, Lattice C, IO & utilities, WordStar addict.
XRalf Woitinas alias RAF, Assembler, anything, Ray-Tracing addict.
XTorsten Wronski alias MM, Assembler, anything, girls addict.
X
XBeverages: Altenmuenster Brauer Bier, Urfraenkisches Landbier, Grohe Bock.
X
XSend exotic drinks, comments, critizism, flames to:
X
XThe Software Brewery
XChristian Balzer
XIm Wingertsberg 45
XD-6108 Weiterstadt
XWest-Germany
X
XOur BBS "AmigaNode" isn't online yet. As soon as it becomes available, 
Xyou'll be the first to know :-).
X
X *
X * Compilation notes:
X * Program is compiled with Lattice C 5.05 and the makefile is included.
X * I have removed some of the comments, sorry about that.  If you're
X * intrested see the original source.
X *
X * NOTE!!!  There is no errorchecking for crontab-file...
X */
X
X#define MAXLINE	132
X#define SIZE	64
X#define ABSEXECBASE ((struct ExecBase **)4L)
X#define NOCRON "Can't get crontab-file"
X#define CRONPORT "AmiCronV4.2"
X#define NO_MESS_MEM "No memory for message!"
X#define NO_REPLY "Could not create replyport!"
X#define ERR_IN_FILE "Error reading crontab-file!"
X#define NO_DEVICE "Could not open timer.device!"
X#define NO_TIMER_PORT "Could not open timerport!"
X#define NO_CRON_PORT "Could not create CronPort!"
X#define EXITING "Quiting the AmiCron!"
X
Xstruct cronmsg {
X	struct Message cm_Msg;
X	char *newfile;
X};
X
Xstruct iobuf {
X	unsigned char *base;
X	unsigned char *ptr;
X	int rcnt;
X	int size;
X};
X
Xtypedef char boolean;
X
Xextern struct ArpBase *ArpBase;
Xextern struct DOSBase *DOSBase;
Xextern struct IntuitionBase *IntuitionBase;
X
Xstruct MsgPort *timerport,*cronport,*mycron=NULL,*replyport;
Xstruct iobuf fd;
Xstruct cronmsg *newcron;
X
Xstruct NewShell nsh;
Xstruct timerequest tr;
X
Xchar min[SIZE],hour[SIZE],day[SIZE],month[SIZE],wday[SIZE],command[SIZE],eof,
X		*tokv[]={min,hour,day,month,wday},
X		*com="CronFile",*args,*help="Usage: AmiCron [CronFile]",
X		cronfile[256]="S:CronTab";
X
Xstruct TextAttr myfont = {
X	"topaz.font",
X	TOPAZ_EIGHTY,0,0 };
X
Xstruct IntuiText body1={
X	0,1,JAM1,10,5,&myfont,NULL,NULL },body2={
X	0,1,JAM1,10,14,&myfont,NULL,NULL },no1={
X	0,1,JAM1,6,3,&myfont,"Cancel",NULL },no2={
X	0,1,JAM1,6,3,&myfont,"Quit",NULL };
X
Xstatic void cleanup(void),alarm(int),wakeup(void),MyExit(void);
Xstatic ULONG systime(void);
Xstatic boolean getline(void),getfile(void),
X					match(register char *,register int);
Xstatic char *scanner(register char *,register char *),
X				*fgets(char *,int);
X
Xvoid __asm __saveds AmiCron(register __a0 char *cmd,register __d0 long len) {
X
X	ULONG current,signals,getsigs,timesig,messig;
X	long count;
X	register struct tm *tm;
X
X	count=GADS(cmd,len,help,&args,com);
X	if (count<0) {
X		body1.IText=args;
X		AutoRequest(NULL,&body1,NULL,&no1,0,0,188,50);
X		cleanup();
X	}
X
X	if (count)
X		strcpy(cronfile,args);
X
X	Forbid();
X
X	if (mycron=FindPort(CRONPORT)) {
X		Permit();
X		if (replyport=CreatePort(0,0)) {
X			if (newcron=AllocMem(sizeof(struct cronmsg),
X										MEMF_PUBLIC|MEMF_CLEAR)) {
X				newcron->cm_Msg.mn_Node.ln_Type=NT_MESSAGE;
X				newcron->cm_Msg.mn_ReplyPort=replyport;
X				newcron->newfile=cronfile;
X				PutMsg(mycron,newcron);
X				WaitPort(replyport);
X				FreeMem(newcron,sizeof(struct cronmsg));
X			}
X			else {
X				body1.IText=NO_MESS_MEM;
X				AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_MESS_MEM)*8+44,50);
X			}
X			DeletePort(replyport);
X		}
X		else {
X			body1.IText=NO_REPLY;
X			AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_REPLY)*8+44,50);
X		}
X		cleanup();
X	}
X
X	else {
X		if (!(cronport=CreatePort(CRONPORT,0))) {
X			body1.IText=NO_CRON_PORT;
X			AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_CRON_PORT)*8+44,50);
X			cleanup();
X		}
X	}
X	Permit();
X
X	if (timerport=CreatePort(0,0)) {
X		tr.tr_node.io_Message.mn_Node.ln_Type=NT_MESSAGE;
X		tr.tr_node.io_Message.mn_Length=sizeof(struct timerequest);
X		tr.tr_node.io_Message.mn_ReplyPort=timerport;
X
X		if (!OpenDevice(TIMERNAME,UNIT_VBLANK,&tr,0)) {
X			if (getfile()) {
X				signals=SIGBREAKF_CTRL_C|(timesig = 1<<timerport->mp_SigBit)|
X							(messig = 1<<cronport->mp_SigBit);
X				for (;;) {
X					wakeup();
X					current=systime();
X					tm=localtime(&current);
X					alarm(60-tm->tm_sec);
X					do {
X						getsigs=Wait(signals);
X						if (getsigs & SIGBREAKF_CTRL_C)
X							cleanup();
X						if (getsigs & messig) {
X							if (newcron=(struct cronmsg *)GetMsg(cronport)) {
X								strcpy(cronfile,newcron->newfile);
X								ReplyMsg(newcron);
X								DosFreeMem(fd.base);
X								fd.base=NULL;
X								if (!getfile())
X									cleanup();
X							}
X						}
X					}
X					while (!(getsigs & timesig));
X				}
X			}
X		}
X	}
X	cleanup();
X}
X
Xstatic void wakeup() {
X
X	register struct tm *tm;
X	long cur_time;
X 	
X	cur_time=systime();		/* get the current time */
X	tm = localtime(&cur_time);	/* break it down */
X 
X	/* Now let's see if there is a CronTab file out there <CB> */ 	
X
X	eof = FALSE;
X 
X	while (!eof)  {
X		if (getline() && match(min,tm->tm_min) &&
X		   match(hour,tm->tm_hour) && match(day,tm->tm_mday) &&
X		   match(month,tm->tm_mon+1) && match(wday,tm->tm_wday))  {
X		/* Weird localtime months ^ range from 0-11 !!! <CB>*/
X			nsh.nsh_Pri=(*ABSEXECBASE)->ThisTask->tc_Node.ln_Pri;
X			nsh.nsh_Control=BACKGROUND_SHELL;
X			nsh.nsh_Input=Input();
X			nsh.nsh_Output=Output();
X			ASyncRun(command,NULL,(struct ProcessControlBlock *)&nsh);
X		}
X	}
X}
X 
X 
X/*
X *	A line consists of six fields.  The first five are:
X *
X *		minute:         0-59
X *		hour:           0-23
X *		day:            1-31
X *		month:          1-12
X *		weekday:        0-6 (Sunday = 0)
X *
X *	The fields are seperated by spaces or tabs, with the
X *	first field left justified (no leading spaces or tabs).
X *	See below for optional field syntax.
X *
X *	The last field is the command field.  This command will
X *	be executed by the CLI just as if typed from a console.
X */
X
Xstatic boolean getline() {
X	register char *p;
X	register int   i;
X	char buffer[MAXLINE];
X 
X	if (fgets(buffer,sizeof buffer) == NULL)  {
X		eof = TRUE;
X		return(FALSE);
X	}
X 
X	for (p = buffer, i = 0; i < 5; i++)  {
X		if ((p = scanner(tokv[i], p)) == (char *)NULL)
X			return(FALSE);
X	}
X 
X	strcpy(command, p);     /* scoop the command */
X	return(TRUE);
X}
X 
X 
Xstatic char *scanner(register char *token,register char *offset) {
X	/*	*token	target buffer to receive scanned token */
X	/*	*offset	place holder into source buffer */
X	while ((*offset != ' ') && (*offset != '\t') && *offset)
X		*token++ = *offset++;
X 
X	/*
X	 *      Check for possible error condition
X	 */
X         
X	if (!*offset)
X		return ((char *)NULL);
X 
X	*token = '\0';
X        
X	while ((*offset == ' ') || (*offset == '\t'))
X		offset++;
X 
X	return (offset);
X}
X 
X 
X/*
X *	This routine will match the left string with the right number.
X *
X *	The string can contain the following syntax:
X *
X *	*		This will return TRUE for any number
X *	x,y [,z, ...]	This will return TRUE for any number given.
X *	x-y		This will return TRUE for any number within
X *			the range of x thru y.
X */
X 
Xstatic boolean match(register char *left,register int right) {
X
X	register int	n;
X	register char	c;
X 
X	n = 0;
X
X	if (!strcmp(left, "*"))
X		return(TRUE);
X 
X	while ((c = *left++) && (c >= '0') && (c <= '9'))
X		n  =  (n * 10) + c - '0';
X 
X	switch (c)  {
X		case '\0':
X			return ((boolean)(right == n));
X 
X		case ',':
X			if ((boolean)(right == n))
X				return(TRUE);
X			do {
X				n = 0;
X				while ((c = *left++) && (c >= '0') && (c <= '9'))
X					n = (n * 10) + c - '0';
X 				if (right == n)
X					return(TRUE);
X			} while (c == ',');
X			return(FALSE);
X 
X		case '-':
X			if (right < n)
X				return(FALSE);
X 
X			n = 0;
X			while ((c = *left++) && (c >= '0') && (c <= '9'))
X				n = (n * 10) + c - '0';
X 
X			return((boolean)(right <= n));
X	}
X}
X
Xstatic boolean getfile(void) {
X
X	BPTR lock,file;
X	struct FileInfoBlock *fib;
X	boolean succ=FALSE;
X
X	if (lock=Lock(cronfile,ACCESS_READ)) {
X		if (fib=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC)) {
X			if (Examine(lock,fib)) {
X				if (fd.base=DosAllocMem(fib->fib_Size)) {
X					if (file=Open(cronfile,MODE_OLDFILE)) {
X						fd.size=Read(file,fd.base,fib->fib_Size);
X						if (fd.size=fib->fib_Size)
X							fd.ptr=fd.base;
X							succ=TRUE;
X						Close(file);
X					}
X				}
X			}
X			FreeMem(fib,sizeof(struct FileInfoBlock));
X		}
X		UnLock(lock);
X	}
X	if (!succ) {
X
X		long length;
X
X		body1.IText=NOCRON;
X		body1.NextText=&body2;
X		body2.IText=cronfile;
X		length=strlen(cronfile);
X
X		AutoRequest(NULL,&body1,NULL,&no1,0,0,((length>sizeof(NOCRON))?
X						length : sizeof(NOCRON))*8+44,59);
X	}
X	return succ;
X}
X
Xstatic char *fgets(char *buffer,int len) {
X
X	unsigned char ch;
X	int count=0;
X
X	while (len>count) {
X		if (fd.rcnt<fd.size) {
X			if ((ch=*fd.ptr++)=='\n') {
X				buffer[count++]='\0';
X				fd.rcnt++;
X				return buffer;
X			}
X			buffer[count++]=ch;
X			fd.rcnt++;
X		}
X		else {
X			fd.rcnt=0;
X			fd.ptr=fd.base;
X			if (count==0)
X				return NULL;
X			else {
X				buffer[count]='\0';
X				return buffer;
X			}
X		}
X	}
X}
X
Xstatic ULONG systime() {
X	tr.tr_node.io_Command=TR_GETSYSTIME;
X	DoIO(&tr);
X	return (tr.tr_time.tv_secs+(((8*365+2)*24+6)*60*60));
X	/* To Greenwich Mean Time  ^^^^^^^^^^^^^^^^^^^^^ */
X}
X
Xstatic void alarm(int secs) {
X	tr.tr_node.io_Command=TR_ADDREQUEST;
X	tr.tr_time.tv_secs=secs;
X	tr.tr_time.tv_micro=0;
X	SendIO(&tr);
X}
X
Xstatic void cleanup() {
X	if (cronport) {
X		Forbid();
X		while (newcron=(struct cronmsg *)GetMsg(cronport))
X			ReplyMsg(newcron);
X		DeletePort(cronport);
X		Permit();
X		if (fd.base)
X			DosFreeMem(fd.base);
X		if (timerport) {
X			if (tr.tr_node.io_Device) {
X				if (tr.tr_node.io_Command)
X					AbortIO(&tr);
X				CloseDevice(&tr);
X			}
X			else {
X				body1.IText=NO_DEVICE;
X				AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_DEVICE)*8+44,50);
X			}
X			DeletePort(timerport);
X		}
X		else {
X			body1.IText=NO_TIMER_PORT;
X			AutoRequest(NULL,&body1,NULL,&no1,0,0,sizeof(NO_TIMER_PORT)*8+44,50);
X		}
X		body1.IText=EXITING;
X		body1.NextText=NULL;
X		AutoRequest(NULL,&body1,NULL,&no2,0,0,sizeof(EXITING)*8+44,50);
X	}
X	MyExit();
X}
END_OF_FILE
if test 13838 -ne `wc -c <'AmiCron.c'`; then
    echo shar: \"'AmiCron.c'\" unpacked with wrong size!
fi
# end of 'AmiCron.c'
fi
if test -f 'AmiCron.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AmiCron.doc'\"
else
echo shar: Extracting \"'AmiCron.doc'\" \(9059 characters\)
sed "s/^X//" >'AmiCron.doc' <<'END_OF_FILE'
X                    AmiCron - Cron task for the Amiga
X
XFollowing below is the original AmiCron documentation by Rick
XSchaeffer (Version 2.3) and Christian Balzer (Version 2.5).
XI haven't changed it so I list here the changes.
X<PS>
X
XThe difference is that there is now two version.  One that detaches
Xitself from the running shell and the other one that doesn't.  So if
Xyou need the shell-window use AmiCronS and if you don't, use AmiCron.
XThe other difference is the crontable IS NO LONGER DISK-RESIDENT!!.
XThe program will read it to the ram and use that.  If you want to use
Xan other crontable, just run the program with other filename.  It will
Xsend a messages to the one that is resident and it will read the new 
Xtable to the memory.
X<PS>
X
X---snip------snap------snip------snap------snip------snap------snip---
X
XFollowing below is the original AmiCron documentation by Rick
XSchaeffer (Version 2.3). I changed it were necessary and listed
Xadditional features below.
X<CB>
X
XThis is a (no longer) crude but effective version of the Unix (tm) 
Xprogram known as "cron" modified to run on an Amiga.  For those 
Xwho aren't Unix knowledgeable, cron is a background task which 
Xuses a disk-resident table to automatically run certain tasks on a 
Xregular basis.  The cron table's format is very simple...it 
Xcontains entries in the form of lines where each line has 6 fields 
Xand each field is separated by "white space" (either tabs or 
Xspaces) from it's neighbor. The fields are as follows:
X
X   1.  Minute       (0-59)
X   2.  Hour         (0-23)
X   3.  Day          (1-31)	(now works, <CB>)
X   4.  Month        (1-12) 
X   5.  Day of week  (0-6 where 0=Sunday and 6=Saturday)
X   6.  Command      This is the command to be run at the appointed 
X                    time.  It will be run just as if typed into 
X                    the CLI.
X
XEach of the first 5 fields are numbers.  However, it is 
Xpermissable to use an asterisk (*) in a field to mean ALL possible 
Xnumbers for that field,  and you can specify a series of numbers 
Xseparated by commas (,) and ranges separated by dashes (-).  For 
Xinstance, in the Day field you could specify "1,5,10" to mean the 
Xfirst, fifth, and tenth days of the month; or you could specify 
X"1-15" to mean the first through the fifteenth of the month.  Here 
Xare some examples of Amicron table entries:
X
X  	Print the date in the crontask window every minute:
X  		* * * * * date
X  
X  	Print the date in the crontask window on the hour, every hour:
X  		0 * * * * date
X  
X  	Run uupc at 4:30 am every day except Sat and Sun:
X  		30 4 * * 1-5 uupc -siscuva
X  
X  	Incrementally backup the files every other day at 7:30 pm:
X  		30 19 * * 1,3,5 sdbackup -l -s LAST dh0: incbkup_1:
X
X    	Backup the files on the 1st and 15th of each month at 1:00 am:
X        	00 01 1,15 * * sdbackup -l dh0: SemiBkup_1:
X
XThe Amicron table file is by default located using the following path:
X
X    S:	(or S:CronTab to be exact and include the filename)
X
Xbut you now may specify a complete path (including filename!) for
Xthe CronTab file (which needn't but should have this name) as a
Xcommand line parameter like this:
X
X    Amicron RAM:MyCronTab
X
Xwhich would cause Amicron to use the CronTab file "MyCronTab"
Xlocated in the RAM: disk and not to access a disk drive every minute
Xto read in the CronTab file.
X
XCrontab entries *MUST* be left justified starting in column 1 and 
Xeach entry must contain 6 fields, each separated by spaces or 
Xtabs.
X
XTo run Amicron, you must use your favorite editor to create the
X"CronTab" file.  Amicron needs a CLI window for displaying the 
Xoutput of the commands it runs...but it can be made as small or 
Xlarge as you wish.  Assuming that you have placed Amicron in your 
Xcommand directory (c:), you can start it by typing the following 
Xline into a "newcli" window:
X    Amicron
XThen you can size and move the window anywhere you want, just be 
Xsure not to type anything else into the window because that would 
Xprevent cron tasks from running (read: printing something in that 
Xwindow).
X
XI have an entry in my startup-sequence file that looks like this:
X   run newcli con:0/140/160/50/CronTask s:startcron
XThe "s:startcron" file contains one line:
X   Amicron
XThis automatically sets up a tiny CronTask window and runs Amicron 
Xin it.
X
XThis program was originally written by Steve R.  Sampson (UUCP:
Xsys1!killer!sampson), who very kindly responded to my request for
Xa PD cron that I could port to Minix.  I haven't done that yet
X(My new Amiga 2000 came in right after I received the cron
Xprogram <grin>) but will do so ASAP.  The modifications to make
Xit run on the Amiga were very minor!
X
XRick Schaeffer          UUCP:  seismo!uunet!iscuva!ricks
XE. 13611 26th Ave.      Phone: (509)928-3533
XSpokane, WA  99216
X
X---- Changes up to Version 2.4
XV2.31& V2.32
XBesides changing the paths for CronTab (s:) & CronErr (t:) to more
Xdecent Amiga places, I encountered a bug when I wanted to start
Xcron a special program on xmas. After some investigation I found
Xout that the localtime() function returns months only in the range
Xfrom  0 to 11. So it was not surprising  that my "12" in the month
Xfield of CronTab was completely ignored. 
XTo not have the user adapt to the computer by having him to supply
Xmonths in the range from 0 to 11, I now increase the localtime()
Xmonth by one, so the documentation above is correct again. 
X
XV2.33
XThen I started wondering what that CronErr file was doing in the
Xfirst place, since all errors where displayed in the CLI window.
XThat instantly lead to the removal of this Unix artefact.
XI'm aware of the need for a stderr output, nevertheless Cron should
Xalways be attached to a CLI, so we can get rid of CronErr. 
X
XV2.4 (a = Aztec C V3.6 , L = Lattice C V4.0)
XI experienced a loss of aprox. one second per minute in the AmiCron
Xwakeups, since it was send to sleep for a fixed amount of time (59
Xseconds). The time Cron did spent in "bed" increased with the
Xlength of the command call and the workload of the machine
X(especially I/O ints. like disk access). 
XSo I now align to the to the next minute and keep this alignment by
Xtranquilizing the task only for the remaining time 'till the next
Xminute. Although the goal of starting it on the minute may only work
Xif there is no heavy workload on your machine, this delay is at least
Xnot cumulative, like the one in the original version.
XAnother odd thing is that the Delay() function (nasty AmigaDog) 
Xobviously creates 5 I/O ints. per second (measured with SysMon
Xby Perry S. Kivolovitz). 
XAlthough I couldn't detect any performance decreases caused by these
Xinterrupts, I decided to use the TimeDelay function from the Timer.c
XRKM example by Rob Peck in version 2.4 of AmiCron. Besides creating
Xno I/O ints., I found that the TimeDelay() function is not effected
Xby other I/O ints., so it turned out to be MUCH more accurate than
Xthe Delay() function and therefore worth compiling & linking that
Xtimer.c part.  
XI also included the path command line parameter, a check for the 
Xexistance of the CronTab file and tighten up the code here and there.
X
XV2.5
XJust in time for KS & WB 1.3 I changed my "run >nil:" call in AmiCron
Xback to a plain "run", since the 1.3 RUN kills ALL output, not just
Xthe naughty "[CLIn]" message from RUN. Hope you have a good time
Xwatching thoose CLI messages in your Cron window :-}.
X
XSome hints for the serious AmiCron addict: 
XIf don't wanna AmiCron to stumble  through your default path and
Xblast you with requesters (i.e you sometimes remove a disk with
Xutilities on which you have a path assigned to), why not define
Xyour own path in the StartCron batch file? Quite simple, but very
Xeffective.
XAmiCron can be easyly terminated (during it's next wakeup) by typing
XCtrl-C in its window or by sending it a break using the BREAK
Xcommand.  
X
XThis project/enhancement/fix is a combined effort by:
X                          
X______  /          
X______\O                    - The Software Brewery - 
X      \\              		    
X       o            Sparkling, fresh software from W.-Germany
X                 
X     @@@@@	      Straight from the bar to your Amiga
X     |~~~|\        
X     | | |/        
X     |___|        With our regards to the Software Distillery
X---------------------------------------------------------------------
X
Xa West-German group of (hopefully professional) Amiga programmers
Xinspired by the Software Destillery 
X(but we germans are more into brewing & drinking beer <grin>).
X
XProgramming & documentation by <CB>
X
X<CB> is : Christian Balzer 
X          Im Wingertsberg 45
X          D-6108 Weiterstadt
X          W. Germany
X
XAztec C support by Christof Bonnkirch (another CB :-) )
XFurther support/ideas by Peter Stark, Heiko Rath and Ralf Woitinas.
X
XI would like to thank Steve R. Sampson for his initial PD cron, Rick
XSchaeffer for his port to the Amiga, Rob Peck for all the work he
Xdid and will (hopefully) do in the future and especially Fred Fish
Xfor his continuous effort to spread all that fantastic PD software 
Xall over the world, without all of them I wouldn't have done this.   
X<CB>
END_OF_FILE
if test 9059 -ne `wc -c <'AmiCron.doc'`; then
    echo shar: \"'AmiCron.doc'\" unpacked with wrong size!
fi
# end of 'AmiCron.doc'
fi
if test -f 'AmiCron.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AmiCron.uu'\"
else
echo shar: Extracting \"'AmiCron.uu'\" \(6921 characters\)
sed "s/^X//" >'AmiCron.uu' <<'END_OF_FILE'
Xbegin 666 AmiCron
XM```#\P`````````%``````````0```!H````4P```EL```#P````_````^D`O
XM``!H8`I*_```!]``````2?D`````2H!G%B/`````0$/Y````1&`"$MA1R/_\[
XM8!(S^0``$`````!$<`$CP````$!'^0```;QR`"`\````C6`")L%1R/_\+'@`?
XM!$/Y```!4W`G3J[]V"E```AG``"R($`I:``X`!`@*``P*4``#"9N`10B*P"8Z
XM+$!.KO^@*4``!$7Y```!)"5\```'T```%6L`"0`$%7P``@`%(CP```%.)#P`!
XM``/M+&P`#$ZN_^(E0``.)4``"D?Z_S8E4P`6*5,``"QX``12+@$GD\E!^@!JD
XM+&P`"$ZN_=Y#^@`V2H!K$$*3,T``!$'Z`(=.KO\<8!I!^@!?3J[_'"(L``1.?
XMKO^F(DXL>``$3J[^8BQX``1.=0```48`````````````````````````````Y
XM``````````````````!!;6E#<F]N`$Y)3#H`87)P+FQI8G)A<GD`0V]U;&0@#
XM;F]T(&-R96%T92`E<RUP<F]C97-S(0H`)7,@<W1A<G1E9"!A="!B86-K9W)O1
XM=6YD('-H96QL("5D"@````/L````!`````````$>````J@```)````!:````8
XM!`````$````R````'@```#H````8`````@````0```!`````#@````````/RP
XM```#Z0```%-)^0````!!^0```$0@.0```$!.N@$P+&P`""(L``1.KO^F+'@`(
XM!%(N`2<B+```+&P`#$ZN_V0L;``(3J[^ADYU````````````````````````@
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM``````````````````````!.^0````!P80```^P````"`````0````X````(@
XM`````0````(```%&`````0````0````"`````````_(```/I```"6TY5_^1(=
XMYR\Z2?D`````)D@N`$CG`#`@2R`'(FP`,$7L`ZPF;``L+&P`"$ZN_P1,WPP`1
XM*T#_Z&PN*6P#K`%(2'@`,DAX`+QP`"\`+P!(;`%D<@`O`4AL`3PO`4ZZ"/AAZ
XM``?63^\`($JM_^AG#"!L`ZQ#[``T$MAF_"QX``1.KO]\0_H"A$ZN_GHI0``4)
XM9P``V$ZN_W:1R'``+&P`"$ZN_LXI0`'$9P``CG`8(CP``0`!+'@`!$ZN_SHIR
XM0`'82H!G.B!`$7P`!0`((&P!V"%L`<0`#D'L`#0B;`'8(T@`%"!L`!1.KOZ2V
XM(&P!Q$ZN_H`B;`'8<!A.KO\N8"Q!^@(6*4@!2$AX`#)(>`#D<``O`"\`2&P!5
XM9'(`+P%(;`$\+P%.N@@T3^\`(")L`<0L;``(3J[^R&`L0?H!]"E(`4A(>``RF
XM2'@!#'``+P`O`$AL`61R`"\!2&P!/"\!3KH'^D_O`"!A``;48$9!^@&><``LU
XM;``(3J[^SBE``<!*@&8P0?H!R"E(`4A(>``R2'@!!'(`+P$O`4AL`61T`"\"+
XM2&P!/"\"3KH'LF$`!I!/[P`@+'@`!$ZN_W:1R'``+&P`"$ZN_LXI0`&\9P``/
XM]AE\``4""CE\`"@"%"E``A!!^@&(<`%#[`("<@`L>``$3J[^1$J`9@``S&$`G
XM!'!*`&<``,)P`"!L`;P0*``/<@$D`>&B*`(@!`!`$`!T`"!L`<`4*``/Y:&`R
XM@2P`*T'_[&$``:YA``6^*T#__$AM__Q.N@<L)$!P/)"2+H!A``7(6$\@!BQX(
XM``1.KO["*@`(!0`,9P1A``78(`7`K?_L9TH@;`'`+'@`!$ZN_HPI0`'82H!G(
XM-B)`(&D`%$WL`#0<V&;\(FP!V"QX``1.KOZ&(FP!R"QL``A.KOZD0JP!R&$`T
XM`[Q*`&8$80`%AB`%P(1GDF``_VYA``5X3-]<]$Y=3G5#<F]N1FEL90``57-A0
XM9V4Z($%M:4-R;VX@6T-R;VY&:6QE70!T;W!A>BYF;VYT``!#86YC96P``%%U8
XM:70``$%M:4-R;VY6-"XR`$YO(&UE;6]R>2!F;W(@;65S<V%G92$``$-O=6QDJ
XM(&YO="!C<F5A=&4@<F5P;'EP;W)T(0!#;W5L9"!N;W0@8W)E871E($-R;VY0U
XM;W)T(0``=&EM97(N9&5V:6-E```J`$-A;B=T(&=E="!C<F]N=&%B+69I;&4`"
XM`$-O=6QD(&YO="!O<&5N('1I;65R+F1E=FEC92$``$-O=6QD(&YO="!O<&5NT
XM('1I;65R<&]R="$`475I=&EN9R!T:&4@06UI0W)O;B$``$Y5__A(YP`R80`$S
XM"BM`__A(;?_X3KH%>%A/)D!"+`.J2BP#JF8``*AA``"L2@!G\"\K``1(;`(JB
XM80`!2E!/2@!GWB\K``A(;`)J80`!.%!/2@!GS"\K``Q(;`*J80`!)E!/2@!GP
XMNB`K`!!2@"\`2&P"ZF$``1!03TH`9Z0O*P`82&P#*F$``/Y03TH`9Y(P?``$@
XM(E`@:0$4&6@`"0'@&7P`@@'A+&P`#$ZN_\HI0`'F3J[_Q"E``>I![`-JD\E%[
XM[`'<+&P`"$ZN_=Y@`/]43-],`$Y=3G5.5?]T2.<!$$AX`(1(;?]T80`"O%!/8
XM2H!F"AE\``$#JG``8#I'[?]T?@!P!;Z`;"(@!^6`+PM![``8+S`(`&$``"90V
XM3R9`(`MF!'``8!!2AV#8($M#[`-J$MAF_'`!3-\(@$Y=3G5(YP`P)F\`#"1OS
XM`!`0$G(@L`%G$'()L`%G"DH`9P86P%**8.A*$F8$<`!@%D(3$!)R(+`!9P9R_
XM";`!9@12BF#N(`I,WPP`3G5(YP<0)F\`%"XO`!A\`"!+0_K^`A`8L!EF#$H`G
XM9O9F!G`!8```WAH;(`5*`&<B<#"Z`&4<<#FZ`&(6(`9R"DZZ`\1R`!(%T($L1
XM`'(PG(%@UG``$`5*0&<.!$``+&<64T!G8F```)Z^AE?`1`!(@$C`8```D+Z&C
XM5\!$`$B`2,!*`&<$<`%@?'P`&AL@!4H`9R)P,+H`91QP.;H`8A8@!G(*3KH#Y
XM8G(`$@70@2P`<C"<@6#6OH9F!'`!8$AP++H`9\9P`&`^OH9L!'``8#9\`!H;@
XM(`5*`&<B<#"Z`&4<<#FZ`&(6(`9R"DZZ`QQR`!(%T($L`'(PG(%@UKZ&7\!$9
XM`$B`2,!,WPC@3G5(YS\2>@!![``T(@AT_BQL``Q.KO^L+@!*AV<``)@@/```"
XM`01R`2QX``1.KO\Z)D`@"V=V(@<D"RQL``Q.KO^:2H!G5B`K`'PL;``(3J[^\
XMJBE``<AG1$'L`#0B""0\```#[2QL``Q.KO_B+`!*AF<J(@8D+`'()BL`?$ZNZ
XM_]8I0`'4(BL`?"E!`=1G!BEL`<@!S'H!(@9.KO_<(DL@/````00L>``$3J[_>
XM+B('+&P`#$ZN_Z9*!6980?K\5"E(`4A![`%0*4@!3$'L`#0I2`%<(DA*&6;\(
XM4XF3R"@)<!>X@&,$(@1@`B(`YX%P+-*`2'@`.R\!<``O`"\`2&P!9'0`+P)(-
XM;`$\+P).N@'F3^\`("`%3-](_$YU2.<'$"9O`!0N+P`8>@"^A6]8("P!T+"L?
XM`=1L-"!L`<P<&"E(`<QR"KP!9A0@15*%<@`@"!>!"`!2K`'0(`M@*B!%4H4@)
XM"!>&"`!2K`'08+YP`"E``=`I;`'(`<Q*A68$<`!@!D(S6``@"TS?".!.=2\.)
XM.7P`"@(>0^P"`BQX``1.KOXX(#P/#)-@T*P"(BQ?3G5(YP$"+B\`##E\``D"?
XM'BE'`B)"K`(F0^P"`BQX``1.KOXR3-]`@$YU+PY*K`'`9P`!#BQX``1.KO]\&
XM(&P!P"QX``1.KOZ,*4`!V$J`9P@B0$ZN_H9@Y")L`<`L;``(3J[^R"QX``1.#
XMKO]V2JP!R&<,(FP!R"QL``A.KOZD2JP!O&=@2JP"%F<@2FP"'F<,0^P"`BQX9
XM``1.KOX@0^P"`BQX``1.KOX^8"Q!^OK2*4@!2$AX`#)(>`$4<``O`"\`2&P!(
XM9'(`+P%(;`$\+P%.N@!X3^\`(")L`;PL;``(3J[^R&`L0?KZMBE(`4A(>``R5
XM2'@`_'``+P`O`$AL`61R`"\!2&P!/"\!3KH`/D_O`"!!^OJD*4@!2)'(*4@!H
XM3$AX`#)(>`#4<``O`"\`2&P!>"\(2&P!/"\(3KH`#D_O`"!.N@`,+%].=4[Y)
XM```"($[Y````%D[Y```!/$[Y```!!````^P````!`````0``"5P````#````H
XM`P``"6(```EH```)5@````$````$````"@````````/R```#Z0```/!.5?_XX
XM+PLF;`.P(`MF!$?Z`'P94P/$&6L``0/%&6L``@/&0BP#QT'L`\0I2`.\0>L`H
XM`TAM__@O"$ZZ`'Y03U:`U\`@+?_X(CP```X03KH`[BE``[A*$V<>&5,#R!EKO
XM``$#R1EK``(#RG``&4`#RW(!*4$#M&`(0BP#R$*L`[1![`/(*4@#P"9?3EU.[
XM=4-35#8`````````````````````````````````````````````````````5
XM(&\`!")(<@!P`"\"#!``*V<&#!``+68"4D@0&`0``#!M$@P```EN#"0!Y8'26
XM@M*!TH!@Y@P1`"UF`D2!)!\@"%.`(&\`"""!D(E.=4Y5__PO"R9O`!!.NO[PI
XM(!.0K`.X*T#__$JL`[1G"`:M```.$/_\2&W__$ZZ`2PF;?_X3EU.=0``2.<PT
XM`"0`)@%(0DA#Q,'&P,#!U$-(0D)"T(),WP`,3G5*@&H``!Y$@$J!:@``#$2!Y
XM80``($2!3G5A```81(!$@4YU2H%J```,1(%A```&1(!.=2\"2$$T`68``")(!
XM0$A!2$(T`&<```:$P3`"2$`T`(3!,`)(0C(")!].=2\#=A`,00"`9```!N&9+
XM44,,00@`9```!NF964,,02``9```!N6954-*06L```;CF5-#-`#FJ$A"0D+FB
XMJDA#@,$V`#`"-`-(0<3!D()D```(4T/0@63^<@`R`TA#Y[A(0,%!)A\D'TYU0
XM2.<P,BQL`!`@;P`8(F\`'"1O`"`F;P`D("\`*"(O`"PD+P`P)B\`-$ZN_J1,C
XMWTP,3G4``````````'!A3E7_Z$CG#Q`F;P`T(!,B/``!48!.NO[J*T#_\"P`%
XM(!,B/``!48!.NO[8+@$@!R(\```.$$ZZ_LHH`"`'(CP```X03KK^O"X!(`=RX
XM/$ZZ_K(K0/_H(`=R/$ZZ_J8N`2E'`\PI;?_H`]`I1`/42&W_\&$``$PJ`"`%I
XM!(````=L*4`#X"EM__`#Z"Z%2&W_\&$``(8I0`/<("W_\%*`*4`#V"`&6(!R[
XM!TZZ_E@I00/D0>P#S"`(3.T(\/_43EU.=4CG`Q`F;P`0+CP```>R+!,,A@``G
XM`6UO'B`'<@1.NOXD2H%F"`2&```!;F`&!(8```%M4H=@V@R&```!;680(`=RT
XM!$ZZ_?Y*@6<$4H=\`":&(`=,WPC`3G5(YP<0)F\`%"XO`!@@!W($3KK]V$J!$
XM9@9P'2E``9!Z`"P3<`RZ@&P<(`7E@$'L`8PB,`@`LH9N#$'L`8R<L`@`4H5@_
XMWB:&(`5,WPC@3G4```/R```#Z@```&\`````````````````````````````6
XM``````(J```":@```JH```+J```#*@```L@```+24SI#<F]N5&%B````````Q
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````NP`"`````$````*``4```$T````````````[
XM`0````H`#@```30````````````!````!@`#```!-````O@```````$````&.
XM``,```$T```#```````````?````'````!\````>````'P```!X````?````/
XM'P```!X````?````'@```!\```/L````!0````(```&$```!<````30````PJ
XM````+`````D````$````*````"0````@````'````!@```&````!;````5@`@
X+``%$`````````_($^
X``
Xend
Xsize 4916
END_OF_FILE
if test 6921 -ne `wc -c <'AmiCron.uu'`; then
    echo shar: \"'AmiCron.uu'\" unpacked with wrong size!
fi
# end of 'AmiCron.uu'
fi
if test -f 'AmiCronS.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AmiCronS.uu'\"
else
echo shar: Extracting \"'AmiCronS.uu'\" \(6568 characters\)
sed "s/^X//" >'AmiCronS.uu' <<'END_OF_FILE'
Xbegin 666 AmiCronS
XM```#\P`````````#``````````(````5```#1P```/H```/I````%4CG@(!)-
XM^0`````L>``$0_D````^<"=.KOW8*4```"!`*6@`,``$*6@`.``(3-\!`4ZZ7
XM`!HL;```3J[^ADYU87)P+FQI8G)A<GD```!.^0````!P80```^P````!````C
XM`````!`````!`````0```$X````!`````@````8````````#\@```^D```-'4
XM3E7_Y$CG+SI)^0`````F2"X`2.<`,"!+(`<B;``H1>P#I"9L`"0L;```3J[_$
XM!$S?#``K0/_H;"XI;`.D`4!(>``R2'@`O'``+P`O`$AL`5QR`"\!2&P!-"\!L
XM3KH+(&$`!]9/[P`@2JW_Z&<,(&P#I$/L`"P2V&;\+'@`!$ZN_WQ#^@*$3J[^6
XM>BE```QG``#83J[_=I'(<``L;```3J[^SBE``;QG``".<!@B/``!``$L>``$S
XM3J[_.BE``=!*@&<Z($`1?``%``@@;`'0(6P!O``.0>P`+")L`=`C2``4(&P`,
XM#$ZN_I(@;`&\3J[^@")L`=!P&$ZN_RY@+$'Z`A8I2`%`2'@`,DAX`.1P`"\`Q
XM+P!(;`%<<@`O`4AL`30O`4ZZ"EQ/[P`@(FP!O"QL``!.KO[(8"Q!^@'T*4@!:
XM0$AX`#)(>`$,<``O`"\`2&P!7'(`+P%(;`$T+P%.N@HB3^\`(&$`!M1@1D'Z'
XM`9YP`"QL``!.KO[.*4`!N$J`9C!!^@'(*4@!0$AX`#)(>`$$<@`O`2\!2&P!E
XM7'0`+P)(;`$T+P).N@G:80`&D$_O`"`L>``$3J[_=I'(<``L;```3J[^SBE`&
XM`;1G``#V&7P`!0(".7P`*`(,*4`""$'Z`8AP`4/L`?IR`"QX``1.KOY$2H!FU
XM``#,80`$<$H`9P``PG``(&P!M!`H``]R`20!X:(H`B`$`$`0`'0`(&P!N!0HZ
XM``_EH8"!+``K0?_L80`!KF$`!;XK0/_\2&W__$ZZ""8D0'`\D)(N@&$`!<A8_
XM3R`&+'@`!$ZN_L(J``@%``QG!&$`!=@@!<"M_^QG2B!L`;@L>``$3J[^C"E`/
XM`=!*@&<V(D`@:0`43>P`+!S89OPB;`'0+'@`!$ZN_H8B;`'`+&P``$ZN_J1"`
XMK`'`80`#O$H`9@1A``6&(`7`A&>28`#_;F$`!7A,WUST3EU.=4-R;VY&:6QEU
XM``!5<V%G93H@06UI0W)O;B!;0W)O;D9I;&5=`'1O<&%Z+F9O;G0``$-A;F-E/
XM;```475I=```06UI0W)O;E8T+C(`3F\@;65M;W)Y(&9O<B!M97-S86=E(0``E
XM0V]U;&0@;F]T(&-R96%T92!R97!L>7!O<G0A`$-O=6QD(&YO="!C<F5A=&4@*
XM0W)O;E!O<G0A``!T:6UE<BYD979I8V4``"H`0V%N)W0@9V5T(&-R;VYT86(M$
XM9FEL90``0V]U;&0@;F]T(&]P96X@=&EM97(N9&5V:6-E(0``0V]U;&0@;F]T"
XM(&]P96X@=&EM97)P;W)T(0!1=6ET:6YG('1H92!!;6E#<F]N(0``3E7_^$CGN
XM`#)A``0**T#_^$AM__A.N@9R6$\F0$(L`Z)*+`.B9@``J&$``*Q*`&?P+RL``
XM!$AL`B)A``%*4$]*`&?>+RL`"$AL`F)A``$X4$]*`&?,+RL`#$AL`J)A``$FL
XM4$]*`&>Z("L`$%*`+P!(;`+B80`!$%!/2@!GI"\K`!A(;`,B80``_E!/2@!G>
XMDC!\``0B4"!I`109:``)`=@9?`""`=DL;``$3J[_RBE``=Y.KO_$*4`!XD'L'
XM`V*3R47L`=0L;```3J[]WF``_U1,WTP`3EU.=4Y5_W1(YP$02'@`A$AM_W1AQ
XM``*\4$]*@&8*&7P``0.B<`!@.D?M_W1^`'`%OH!L(B`'Y8`O"T'L`!`O,`@`L
XM80``)E!/)D`@"V8$<`!@$%*'8-@@2T/L`V(2V&;\<`%,WPB`3EU.=4CG`#`FT
XM;P`,)&\`$!`2<B"P`6<0<@FP`6<*2@!G!A;`4HI@Z$H29@1P`&`60A,0$G(@]
XML`%G!G()L`%F!%**8.X@"DS?#`!.=4CG!Q`F;P`4+B\`&'P`($M#^OX"$!BPB
XM&68,2@!F]F8&<`%@``#>&AL@!4H`9R)P,+H`91QP.;H`8A8@!G(*3KH$_'(`+
XM$@70@2P`<C"<@6#6<``0!4I`9PX$0``L9Q930&=B8```GKZ&5\!$`$B`2,!@C
XM``"0OH97P$0`2(!(P$H`9P1P`6!\?``:&R`%2@!G(G`PN@!E''`YN@!B%B`&&
XM<@I.N@2:<@`2!="!+`!R,)R!8-:^AF8$<`%@2'`LN@!GQG``8#Z^AFP$<`!@Y
XM-GP`&AL@!4H`9R)P,+H`91QP.;H`8A8@!G(*3KH$5'(`$@70@2P`<C"<@6#62
XMOH9?P$0`2(!(P$S?".!.=4CG/Q)Z`$'L`"PB"'3^+&P`!$ZN_ZPN`$J'9P``E
XMF"`\```!!'(!+'@`!$ZN_SHF0"`+9W8B!R0++&P`!$ZN_YI*@&=6("L`?"QLF
XM``!.KOZJ*4`!P&=$0>P`+"(()#P```/M+&P`!$ZN_^(L`$J&9RHB!B0L`<`FQ
XM*P!\3J[_UBE``<PB*P!\*4$!S&<&*6P!P`'$>@$B!DZN_]PB2R`\```!!"QXB
XM``1.KO\N(@<L;``$3J[_IDH%9EA!^OQ4*4@!0$'L`4@I2`%$0>P`+"E(`50B*
XM2$H99OQ3B9/(*`EP%[B`8P0B!&`"(@#G@7`LTH!(>``[+P%P`"\`+P!(;`%<E
XM=``O`DAL`30O`DZZ!`Y/[P`@(`5,WTC\3G5(YP<0)F\`%"XO`!AZ`+Z%;U@@6
XM+`'(L*P!S&PT(&P!Q!P8*4@!Q'(*O`%F%"!%4H5R`"`(%X$(`%*L`<@@"V`J>
XM($52A2`(%X8(`%*L`<A@OG``*4`!R"EL`<`!Q$J%9@1P`&`&0C-8`"`+3-\(E
XMX$YU+PXY?``*`A9#[`'Z+'@`!$ZN_C@@/`\,DV#0K`(:+%].=4CG`0(N+P`,F
XM.7P`"0(6*4<"&D*L`AY#[`'Z+'@`!$ZN_C),WT"`3G4O#DJL`;AG``$.+'@`B
XM!$ZN_WP@;`&X+'@`!$ZN_HPI0`'02H!G"")`3J[^AF#D(FP!N"QL``!.KO[(H
XM+'@`!$ZN_W9*K`'`9PPB;`'`+&P``$ZN_J1*K`&T9V!*K`(.9R!*;`(69PQ#+
XM[`'Z+'@`!$ZN_B!#[`'Z+'@`!$ZN_CY@+$'Z^M(I2`%`2'@`,DAX`11P`"\`>
XM+P!(;`%<<@`O`4AL`30O`4ZZ`J!/[P`@(FP!M"QL``!.KO[(8"Q!^OJV*4@!)
XM0$AX`#)(>`#\<``O`"\`2&P!7'(`+P%(;`$T+P%.N@)F3^\`($'Z^J0I2`%`A
XMD<@I2`%$2'@`,DAX`-1P`"\`+P!(;`%P+PA(;`$T+PA.N@(V3^\`($ZZ``8LW
XM7TYU3OD````T<&%.5?_X+PLF;`.H(`MF!$?Z`'P94P.\&6L``0.]&6L``@.^(
XM0BP#OT'L`[PI2`.T0>L``TAM__@O"$ZZ`'Y03U:`U\`@+?_X(CP```X03KH`P
XM[BE``[!*$V<>&5,#P!EK``$#P1EK``(#PG``&4`#PW(!*4$#K&`(0BP#P$*L1
XM`ZQ![`/`*4@#N"9?3EU.=4-35#8`````````````````````````````````>
XM````````````````````(&\`!")(<@!P`"\"#!``*V<&#!``+68"4D@0&`0`[
XM`#!M$@P```EN#"0!Y8'2@M*!TH!@Y@P1`"UF`D2!)!\@"%.`(&\`"""!D(E.<
XM=4Y5__PO"R9O`!!.NO[P(!.0K`.P*T#__$JL`ZQG"`:M```.$/_\2&W__$ZZ(
XM`2PF;?_X3EU.=0``2.<P`"0`)@%(0DA#Q,'&P,#!U$-(0D)"T(),WP`,3G5*K
XM@&H``!Y$@$J!:@``#$2!80``($2!3G5A```81(!$@4YU2H%J```,1(%A```&-
XM1(!.=2\"2$$T`68``")(0$A!2$(T`&<```:$P3`"2$`T`(3!,`)(0C(")!].S
XM=2\#=A`,00"`9```!N&944,,00@`9```!NF964,,02``9```!N6954-*06L`R
XM``;CF5-#-`#FJ$A"0D+FJDA#@,$V`#`"-`-(0<3!D()D```(4T/0@63^<@`R<
XM`TA#Y[A(0,%!)A\D'TYU2.<P,BQL``@@;P`8(F\`'"1O`"`F;P`D("\`*"(O[
XM`"PD+P`P)B\`-$ZN_J1,WTP,3G4``````````'!A3E7_Z$CG#Q`F;P`T(!,BC
XM/``!48!.NO[J*T#_\"P`(!,B/``!48!.NO[8+@$@!R(\```.$$ZZ_LHH`"`'V
XM(CP```X03KK^O"X!(`=R/$ZZ_K(K0/_H(`=R/$ZZ_J8N`2E'`\0I;?_H`\@ID
XM1`/,2&W_\&$``$PJ`"`%!(````=L*4`#V"EM__`#X"Z%2&W_\&$``(8I0`/44
XM("W_\%*`*4`#T"`&6(!R!TZZ_E@I00/<0>P#Q"`(3.T(\/_43EU.=4CG`Q`F>
XM;P`0+CP```>R+!,,A@```6UO'B`'<@1.NOXD2H%F"`2&```!;F`&!(8```%M%
XM4H=@V@R&```!;680(`=R!$ZZ_?Y*@6<$4H=\`":&(`=,WPC`3G5(YP<0)F\`8
XM%"XO`!@@!W($3KK]V$J!9@9P'2E``8AZ`"P3<`RZ@&P<(`7E@$'L`80B,`@`&
XMLH9N#$'L`82<L`@`4H5@WB:&(`5,WPC@3G4```/L`````0````````E6````#
XM`0````(````*`````````_(```/J````^@````````````````````````(B-
XM```"8@```J(```+B```#(@```L@```+24SI#<F]N5&%B````````````````E
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````NP`"`````$````*``4```$L`````````````0````H`^
XM#@```2P````````````!````!@`#```!+````O@```````$````&``,```$LC
XM```#```````````?````'````!\````>````'P```!X````?````'P```!X`4
XM```?````'@```!\`````````````````````````````````````````````<
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM``````````````````````````````````````````````````/L````!0``T
XM``$```%\```!:````2P````H````)`````D````"````(````!P````8````_
X=%````!````%X```!9````5````$\`````````_("'
X``
Xend
Xsize 4664
END_OF_FILE
if test 6568 -ne `wc -c <'AmiCronS.uu'`; then
    echo shar: \"'AmiCronS.uu'\" unpacked with wrong size!
fi
# end of 'AmiCronS.uu'
fi
if test -f 'crontab' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crontab'\"
else
echo shar: Extracting \"'crontab'\" \(15 characters\)
sed "s/^X//" >'crontab' <<'END_OF_FILE'
X* * * * * beep
END_OF_FILE
if test 15 -ne `wc -c <'crontab'`; then
    echo shar: \"'crontab'\" unpacked with wrong size!
fi
# end of 'crontab'
fi
if test -f 'inc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inc.c'\"
else
echo shar: Extracting \"'inc.c'\" \(277 characters\)
sed "s/^X//" >'inc.c' <<'END_OF_FILE'
X#include <proto/exec.h>
X#include <proto/arp.h>
X#include <proto/dos.h>
X#include <proto/intuition.h>
X
X#include <exec/execbase.h>
X#include <exec/memory.h>
X#include <devices/timer.h>
X#include <libraries/arpbase.h>
X#include <graphics/text.h>
X
X#include <time.h>
X#include <string.h>
X
END_OF_FILE
if test 277 -ne `wc -c <'inc.c'`; then
    echo shar: \"'inc.c'\" unpacked with wrong size!
fi
# end of 'inc.c'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(479 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
XAmiCron.lzh : AmiCronS AmiCron
X	lharc f AmiCron.lzh *
X
XAmiCronS : AmiCron.o self.o
X	blink self.o+AmiCron.o to AmiCronS lib lib:lc.lib sd sc
X
XAmiCron : AmiCron.o start.o run.o
X	blink start.o+run.o+AmiCron.o to AmiCron lib lib:lc.lib sd
X
XAmiCron.o : AmiCron.c inc.p
X	lc -Hinc.p -v -cusfq AmiCron
X
Xinc.p : inc.c
X	lc -ph -v -cusfq -oinc.p inc.c
X
Xstart.o : start.a
X	lc:asm -u -iinclude: start.a
X
Xrun.o : run.a
X	lc:asm -u -iinclude: run.a
X
Xself.o : self.a
X	lc:asm -u -iinclude: self.a
END_OF_FILE
if test 479 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'run.a' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'run.a'\"
else
echo shar: Extracting \"'run.a'\" \(559 characters\)
sed "s/^X//" >'run.a' <<'END_OF_FILE'
X	INCLUDE	"macros.i"
X	INCLUDE	"exec/types.i"
X	INCLUDE	"libraries/arpbase.i"
X	INCLUDE	"exec/ables.i"
X
XExecBase	EQU	4
X
X	csect	_NOMERGE,0,0,0,4
X;	section	_NOMERGE,code
X
X	XDEF	MyExit,cmdlen,cmdline,run
X	XREF	LinkerDB,AmiCron,curdir,ArpBase,DOSBase,seglist
X
Xrun	lea	LinkerDB,a4
X	lea	cmdline,a0
X	move.l	cmdlen,d0
X	jsr	AmiCron(pc)
XMyExit	move.l	ArpBase(a4),a6
X	move.l	curdir(a4),d1
X	Call	UnLock
X
X	move.l	ExecBase.w,a6
X	FORBID
X	move.l	seglist(a4),d1
X	move.l	DOSBase(a4),a6
X	Call	UnLoadSeg
X	move.l	ArpBase(a4),a6
X	Call	ArpExit
X	rts
X
Xcmdlen	dc.l	0
Xcmdline	ds.b	256
X	END
END_OF_FILE
if test 559 -ne `wc -c <'run.a'`; then
    echo shar: \"'run.a'\" unpacked with wrong size!
fi
# end of 'run.a'
fi
if test -f 'self.a' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'self.a'\"
else
echo shar: Extracting \"'self.a'\" \(784 characters\)
sed "s/^X//" >'self.a' <<'END_OF_FILE'
X	INCLUDE	"macros.i"
X	INCLUDE	"exec/types.i"
X	INCLUDE	"exec/ables.i"
X	INCLUDE	"exec/execbase.i"
X	INCLUDE	"libraries/dosextens.i"
X	INCLUDE	"libraries/arpbase.i"
X
X	BITDEF	PR,DEFSTACK,7
XExecBase	EQU	4
X
X	xref	LinkerDB
X	xref	AmiCron
X
X	csect	_NOMERGE,0,0,0,4
X;	section	_NOMERGE,code
X
X	XDEF	MyExit
X
Xrun	movem.l	d0/a0,-(a7)
X	lea	LinkerDB,a4
Xcont	move.l	ExecBase.w,a6
X	lea	Arp,a1
X	moveq.l	#ArpVersion,d0
X	Call	OpenLibrary
X	move.l	d0,ArpBase(a4)
X	move.l	d0,a0
X	move.l	ab_DosBase(a0),DOSBase(a4)
X	move.l	ab_IntuiBase(a0),IntuitionBase(a4)
X
X	movem.l	(a7)+,d0/a0
X	jsr	AmiCron(pc)
XMyExit	move.l	ArpBase(a4),a6
X	Call	ArpExit
X	rts
X
XArp	dc.b	"arp.library",0
X
X	csect	__MERGED,1,0,0,4
X;	section	__MERGED,data
X
X	xdef	ArpBase,DOSBase,IntuitionBase
X
XArpBase	dc.l	0
XDOSBase	dc.l	0
XIntuitionBase
X	dc.l	0
X	END
END_OF_FILE
if test 784 -ne `wc -c <'self.a'`; then
    echo shar: \"'self.a'\" unpacked with wrong size!
fi
# end of 'self.a'
fi
if test -f 'start.a' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'start.a'\"
else
echo shar: Extracting \"'start.a'\" \(2032 characters\)
sed "s/^X//" >'start.a' <<'END_OF_FILE'
X	INCLUDE	"macros.i"
X	INCLUDE	"exec/types.i"
X	INCLUDE	"exec/ables.i"
X	INCLUDE	"exec/execbase.i"
X	INCLUDE	"libraries/dosextens.i"
X	INCLUDE	"libraries/arpbase.i"
X
XExecBase	EQU	4
X
X	xref	LinkerDB,_BSSBAS,_BSSLEN
X	xref	run,cmdline,cmdlen
X
X	csect	_STARTUP,0,0,0,4
X
Xstart	RESIDENT	2000
X	lea	LinkerDB,a4
X	tst.l	d0
X	beq.s	nocmd
X	move.l	d0,cmdlen
X	lea	cmdline,a1
X	bra.s	cpy1
Xcpy_cmd	move.b	(a0)+,(a1)+
Xcpy1	dbf	d0,cpy_cmd
X	bra.s	cont
X
Xnocmd	move.w	$1000,cmdline
X	moveq.l	#1,d0
X	move.l	d0,cmdlen
X
Xcont	lea	_BSSBAS,a3
X	moveq.l	#0,d1
X	move.l	#_BSSLEN,d0
X	bra.s	clr_lp
Xclr_bss	move.l	d1,(a3)+
Xclr_lp	dbf	d0,clr_bss
X
X	move.l	ExecBase.w,a6
X	lea	Arp,a1
X	moveq.l	#ArpVersion,d0
X	Call	OpenLibrary
X	move.l	d0,ArpBase(a4)
X	beq	noarp
X	move.l	d0,a0
X	move.l	ab_IntuiBase(a0),IntuitionBase(a4)
X	move.l	ab_DosBase(a0),d0
X	move.l	d0,DOSBase(a4)
X
X	move.l	ThisTask(a6),a3
X	move.l	pr_CurrentDir(a3),d1
X	move.l	d0,a6
X	Call	DupLock
X	move.l	d0,curdir(a4)
X
X	lea	pcb,a2
X	move.l	#2000,pcb_StackSize(a2)
X	move.b	LN_PRI(a3),pcb_Pri(a2)
X	move.b	#PRF_CLOSESPLAT,pcb_Control(a2)
X
X	move.l	#CON,d1
X	move.l	#MODE_OLDFILE,d2
X	move.l	DOSBase(a4),a6
X	Call	Open
X	move.l	d0,pcb_Output(a2)
X	move.l	d0,pcb_Input(a2)
X
X	lea	start-4(pc),a3
X	move.l	(a3),pcb_LoadedCode(a2)
X	move.l	(a3),seglist(a4)
X	move.l	ExecBase.w,a6
X	FORBID
X	suba.l	a1,a1
X	lea	name(pc),a0
X	move.l	ArpBase(a4),a6
X	Call	ASyncRun
X
X	lea	args(pc),a1
X
X	tst.l	d0
X	bmi.s	starterr
X
X	clr.l	(a3)
X	move.w	d0,4(a1)
X	lea	startmess(pc),a0
X	Call	Printf
X	bra.s	noclose
X
Xstarterr	lea	error(pc),a0
X	Call	Printf
X	move.l	curdir(a4),d1
X	Call	UnLock
X	movea.l	a6,a1
X	move.l	ExecBase.w,a6
X	Call	CloseLibrary
Xnoclose	move.l	ExecBase.w,a6
X;	Call	Permit
X
Xnoarp	rts
X
Xargs	dc.l	name
Xnum	dc.w	0
X
Xpcb	ds.b	pcb_SIZEOF
Xname	dc.b	"AmiCron",0
XCON	dc.b	"NIL:",0
X
XArp	dc.b	"arp.library",0
Xerror	dc.b	"Could not create %s-process!",10,0
Xstartmess	dc.b	"%s started at background shell %d",10,0
X
X	csect	__MERGED,1,0,0,4
X
X	xdef	IntuitionBase,ArpBase,DOSBase,curdir,seglist
X
Xseglist	dc.l	0
Xcurdir	dc.l	0
XArpBase	dc.l	0
XDOSBase	dc.l	0
XIntuitionBase
X	dc.l	0
X	END
END_OF_FILE
if test 2032 -ne `wc -c <'start.a'`; then
    echo shar: \"'start.a'\" unpacked with wrong size!
fi
# end of 'start.a'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.