AUSAM/source/S/alarm.c
/*
*
* Can be run in two ways (depending on its name(argv[0]))
*
* alarm - send a message to the terminal at the specified time
*
* runat - execc the given command and arguments at the specified time
*
* Times are specified in the form: Fri Jun 1 9:53:14 1979
* Any of the arguments (except for the hours:minutes) may be ommited,
* the current date, month, year, being assumed.
* The arguments may be specified in any order.
* Alarm (Runat) also recognises "am", "pm", and "tomorrow" as valid
* arguments.
*
* Michael Rourke - June 1979
*/
#include <stdio.h>
#include <date.h>
#define MAXSLEEP 65535l
#define SECINDAY 86400l
#define SECINHOUR 3600l
#define SECINMIN 60l
int daysinmonth[]
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
char *dayandmonth[]
{
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec",
"sun", "mon", "tue", "wed", "thu", "fri", "sat",
"tom", "am", "pm"
};
int hour, minute, second, day, year, dayofweek, month, nargs, relative;
char sdayofweek, syear, smonth, sday, stime, runat, srelative, spm, pm;
long mtime(), time(), systime;
struct date *localtime(), *tim;
main(argc, argv)
register int argc;
register char *argv[];
{
long ttime;
runat = (argv[0][0] == 'r');
systime = time();
tim = localtime(systime);
day = tim->d_dyofmon;
year = tim->d_year + 1900;
month = tim->d_month;
if((argc == 1) || getargs(argc, argv) || (runat && ((argc - nargs - 1) == 0)) || ( ! runat && (nargs != argc)))
if(runat)
{
fprintf(stderr, "Usage:\nrunat [day] [month] [date] hours:minutes[:seconds] [year] : command\n");
fprintf(stderr, "runat +minutes : command\n");
}
else
{
fprintf(stderr, "Usage:\nalarm [day] [month] [date] hours:minutes[:seconds] [year]\n");
fprintf(stderr, "alarm +minutes\n");
}
else
{
if((ttime = mtime() - systime) <= 0)
{
fprintf(stderr, "This time has already passed\n");
exit(-1);
}
go(ttime, argc - nargs - 1, &argv[nargs+1]);
}
}
getargs(argc, argv)
int argc;
register char *argv[];
{
int thour, tmin, tsec, tint, k, ch, found;
register int j, arg;
char tstr[3];
for(arg = 1; (arg < argc) && (argv[arg][0] != ':'); arg++)
{
thour = tmin = tsec = tint = 0;
if(argv[arg][0] >= 'A') /* a string */
{
for(j = 0; argv[arg][j] && j < 3; j++) /* map upper to lower case */
if((argv[arg][j] >= 'A') && (argv[arg][j] <= 'Z'))
tstr[j] = argv[arg][j] + 'a' - 'A';
else
tstr[j] = argv[arg][j];
found = 0;
for(j = 0; (j < 12 + 7 + 3) && (! found); j++) /* look for string */
for(k = 0; k < 3; k++)
if(tstr[k] != dayandmonth[j][k])
break;
else if( ! dayandmonth[j][k + 1])
found++;
if(found)
if(--j < 12) /* a month */
{
smonth++;
month = j;
}
else if(j < 12 + 7) /* a day of week */
{
sdayofweek++;
dayofweek = j - 12;
}
else switch(j)
{
case 12 + 7:
/* tomorrow */
sdayofweek++;
dayofweek = (tim->d_dyofwk + 1) % 7;
break;
case 12 + 7 + 1:
/* am */
spm++;
break;
case 12 + 7 + 2:
/* pm */
spm++;
pm++;
break;
}
else
{
fprintf(stderr, "Unidentified argument: \"%s\"\n", argv[arg]);
return(1);
}
}
else if(sscanf(argv[arg], "%d:%d:%d", &thour, &tmin, &tsec) > 1) /* the time */
{
if((thour >= 0) && (thour < 24) && (tmin >= 0) && (tmin < 60) && (tsec >= 0) && (tsec < 60))
{
stime++;
hour = thour;
minute = tmin;
second = tsec;
}
else
{
fprintf(stderr, "Time out of range\n");
return(1);
}
}
else if(sscanf(argv[arg], "+%d%c", &tint, &ch) == 1) /* a relative time */
{
srelative++;
relative = tint * SECINMIN;
}
else if(sscanf(argv[arg], "%d%c", &tint, &ch) == 1) /* a date or year */
if(tint > 31) /* year */
{
syear++;
year = tint;
}
else if((tint > 0) && (tint <= 31)) /* day */
{
sday++;
day = tint;
}
else
{
fprintf(stderr, "Date out of range\n");
return(1);
}
else
{
fprintf(stderr, "Unidentified argument: \"%s\"\n", argv[arg]);
return(1);
}
if((sday > 1) || (syear > 1) || (smonth > 1) || (sdayofweek > 1) || (stime > 1) || (srelative > 1) || (spm > 1))
{
fprintf(stderr, "Repeated argument: \"%s\"\n", argv[arg]);
return(1);
}
}
nargs = arg;
if(srelative)
return((arg != 2) || (runat && (argv[arg][0] != ':')));
else
return(( ! stime) || (runat && (argv[arg][0] != ':')));
}
long mtime()
{
register int i, disp, days 0;
if(srelative)
return(systime + relative);
for(i = 1970; i < year; i++)
if(i % 4)
days =+ 365l;
else
days =+ 366l; /* a leap year */
if(year % 4 == 0)
daysinmonth[1] = 29;
for(i = 0; i < month; i++)
days =+ daysinmonth[i];
days =+ day - 1; /* days since 1 Jan 1970 */
if(sdayofweek && ! sday) {
disp = dayofweek - tim->d_dyofwk;
if(disp < 0)
disp =+ 7;
days =+ disp;
}
if(pm)
hour =+ 12;
return(days * SECINDAY + hour * SECINHOUR + minute * SECINMIN + second);
}
go(wait, argc, argv)
long wait;
int argc;
char *argv[];
{
register unsigned shortw, longw, i;
switch(fork()) {
case -1:
fprintf(stderr, "Cannot fork\n");
exit(-1);
case 0:
/* child */
break;
default:
/* parent */
fprintf(stderr, "It is now %s", ctime(systime));
if(runat)
fprintf(stderr, "Runat is set for %s",ctime(systime+wait));
else
fprintf(stderr, "Alarm is set for %s",ctime(systime+wait));
exit(0);
}
signal(2, 1);
signal(3, 1);
longw = wait / MAXSLEEP;
shortw = wait % MAXSLEEP;
for(i = 0; i < longw; i++)
sleep(MAXSLEEP);
sleep(shortw);
if(runat)
{
argv[argc] = 0;
execc(*argv, argv);
fprintf(stderr, "\nrunat: cannot execc \"%s\"\n", *argv);
}
else
fprintf(stderr, "\07\nWarning, the time is %s\07",ijtime());
exit(0);
}