home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
AZTEC-C
/
MINDER.ARK
/
MINDER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1986-06-19
|
13KB
|
701 lines
/* minder
Reminder service
1985 Mark E. Mallett
*/
#include "minder.h"
#include "comnd.h"
#include "setjmp.h"
#include "cpm.h"
char ovlccp = {0}; /* Don't overlay CCP (CP/M) */
/* Local definitions */
/* External routines */
/* External data */
extern int Chgflg; /* Changes-made flag */
extern int Curdat; /* Current date */
extern int Curtim; /* Current time */
extern EVT *Evthdr; /* Heads the EVT list */
extern CFB Inicfb; /* CFB for initialization */
extern int Osdate; /* O/S supports date/time */
extern CSB Topcsb; /* top-level command state block */
extern jmp_buf Topenv; /* setjmp environment buffer */
extern char *Usrnam; /* Name of invoking user */
/* Local routines */
extern int addcmd(); /* the ADD command */
extern int exicmd(); /* the EXIT command */
extern int hlpcmd(); /* the HELP command */
extern int hlpcms(); /* Routine for help:command */
extern int hlpful(); /* Routine for help:full */
extern int liscmd(); /* the LIST command */
extern int modcmd(); /* the MODIFY command */
extern int quicmd(); /* the QUIT command */
extern int remcmd(); /* the REMOVE command */
extern int rptcmd(); /* the REPORT command */
extern int shwcmd(); /* the SHOW command */
/* Local data */
static int Datflg = {FALSE}; /* -d option given */
static int Rptmod = {FALSE}; /* If invoked in report mode */
/* Command keyword and dispatch tables */
BYTE *Cmktbl[] = { /* Command keywords.. */
"ADD", /* Add event */
"EXIT", /* Exit this program */
"HELP", /* Give help */
"LIST", /* List events */
"MODIFY", /* Modify an event */
"QUIT", /* Quit without saving changes */
"REMOVE", /* Remove an event */
"REPORT", /* Report active events */
"SHOW", /* Show an event's definition */
NULL /* Ends with a null pointer */
};
int (*Cmddsp[])() = {
addcmd, /* ADD */
exicmd, /* EXIT */
hlpcmd, /* HELP */
liscmd, /* LIST */
modcmd, /* MODIFY */
quicmd, /* QUIT */
remcmd, /* REMOVE */
rptcmd, /* REPORT */
shwcmd, /* SHOW */
0 /* Ends with a zero for convenience */
};
/* HELP keyword and dispatch tables */
BYTE *Hlptbl[] = {
"COMMAND",
"FULL",
NULL
};
int (*Hlpdsp[])() = {
hlpcms,
hlpful,
0
};
/* COMND blocks */
CFB Cmkcfb = {_CMKEY, _CFHPP, 0, &Cmktbl, "Command, ", 0};
static CFB Hkwcfb = {_CMKEY, _CFDPP, &Cmkcfb, &Hlptbl, 0, "FULL"};
/**//* main
The main routine
*/
main (argc, argv)
int argc;
char **argv;
{
IND int mo, da, yr; /* Month, day, year */
IND int c; /* Character var */
IND int i; /* Scratch */
IND int n; /* NEXT index after arg */
IND BYTE *aptr; /* ptr to arg, if any */
IND BYTE **kptr; /* Points to kwd table entry */
IND WORD cpmver; /* CPM version number */
/* Supposed to do this for protection, so... */
printf ("MINDER vsn *1*; (C) 1985 Mark E. Mallett.\n");
for (i = 1; i < argc; i++) /* Look at command line arguments */
{
if (argv[i][0] != '-') /* Be tough */
{
printf ("Illegal argument %s\n", argv[i]);
exit(0);
}
c = argv[i][1]; /* Look at option char */
c = tolower(c);
aptr = NULL; /* Init pot. arg pointer */
if (argv[i][2] != NUL) /* If anything after option char */
{
aptr = &argv[i][2]; /* then that is it */
n = i; /* Value of next i */
}
else
if (i < argc) /* Only if there is one */
{
n = i+1; /* Arg is next one */
aptr = argv[n]; /* Point to it */
}
switch (c) /* Branch on char */
{
case 'd': /* Date supplied */
if (Datflg) /* Already got one? */
printf ("Duplicate -d option.\n");
else
{
yr = 1900 + d2(aptr); /* Get yr */
mo = d2(&aptr[2]); /* Month */
da = d2(&aptr[4]); /* Day */
cvedid (&Curdat, &Curtim, mo, da, yr, 0, 0);
Datflg = TRUE;
}
i = n;
break;
case 'r': /* Report mode */
Rptmod = TRUE; /* Set the flag */
break;
case 'u': /* Username */
if (Usrnam != NULL) /* If more than one.. */
{
printf ("Duplicate username given\n");
exit();
}
Usrnam = newstr(aptr); /* Remember user name */
i = n; /* Skip to next argument */
break;
default: /* Something else */
printf ("Ignoring illegal option %s\n", argv[i]);
}
}
cpmver = CPM (_MRCPV, 0); /* Get CP/M version */
if ((cpmver & 0xff00) != 0) /* Not CP/M ? */
printf ("Warning... This is not a CP/M system.\n");
Osdate = (cpmver >= 0x30); /* Date fn in CPM+ */
if (!Osdate) /* If os date/time not supported */
if (!Datflg) /* We have to have date option */
{
printf ("Since this is not a CPM+ system, the current date must be\n");
printf ("supplied on the command line, in the form:\n");
printf (" A> minder -d yymmdd\n");
exit(0);
}
loaddb(); /* Load the database */
if (Rptmod) /* Invoked in report mode? */
{
report(); /* Call report module */
if (Chgflg) /* Any changes? */
savedb(); /* Save db */
exit(); /* Be done */
}
printf ("Type ? for help at any time.\n");
/* Enter command loop */
while (TRUE) /* Forever */
{
if (COMND (&Topcsb, &Inicfb) != _CROK) /* eh? */
{
printf ("Fatal error initializing COMND\n");
exit();
}
setjmp (Topenv); /* Mark here for reparse */
if (COMNDi (&Topcsb, &Cmkcfb) != _CROK) /* Collect keyword */
continue;
kptr = (char **) (Topcsb.CSB_RVL._ADR);
i = kptr - (&Cmktbl[0]); /* Get keyword index */
(*Cmddsp[i])(); /* Process command */
}
}
/*
*//* d2 (ptr)
Returns value of 2-digit ASCII decimal string @ ptr
This is used for command line parsing of the date.
*/
int d2 (ptr)
char *ptr;
{
IND int v; /* Value */
v = (*ptr++) - '0'; /* First digit */
v = (v*10) + (*ptr - '0'); /* Value */
return (v);
}
/*
*//* addcmd ()
Processes the ADD command.
Accepts :
Returns :
*/
addcmd ()
{
IND EVT *EVTptr; /* Pointer to event block */
char evname[50]; /* Event name */
if (!noise (&Topcsb, "event named")) /* Give guide words */
return;
if (!getuqs (&Topcsb, "event name", evname))
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
if (findev(evname) != NULL) /* Make sure not duplicate */
{
printf ("Event %s already exists. Please use another name.\n", evname);
}
else
{
EVTptr = calloc (1, sizeof(EVT)); /* Allocate event block */
EVTptr -> EVT_NAM = newstr (evname); /* Get event name */
if (Usrnam != NULL) /* If we're identified */
{
EVTptr -> EVT_FRM = newstr(Usrnam);
EVTptr -> EVT_FOR = newstr(Usrnam);
}
evdef (EVTptr); /* Go define it */
addev (EVTptr); /* Add this event */
printf ("Event %s added.\n", EVTptr -> EVT_NAM);
}
}
/*
*//* exicmd ()
Processes the EXIT command.
Accepts :
Returns :
*/
exicmd ()
{
if (!noise (&Topcsb, "and save changes")) /* Give guide words */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
if (Chgflg) /* If any changes made */
savedb(); /* Save the database */
exit(0);
}
/*
*//* hlpcmd()
the HELP command
(taken from lbbhlp.c)
*/
hlpcmd()
{
int i; /* Command index */
char **kptr; /* Keyword ptr ptr */
if (!noise (&Topcsb, "on subject")) /* Give guidance */
return;
if (COMNDi (&Topcsb, &Hkwcfb) != _CROK) /* Get keyword */
return;
kptr = (char **) Topcsb.CSB_RVL._ADR; /* Get returned pointer */
if (Topcsb.CSB_CFB == &Cmkcfb) /* If matched command keyword */
{
i = kptr - &Cmktbl[0]; /* Get index */
return (hlpcms(i)); /* Process the thing */
}
i = kptr - &Hlptbl[0]; /* Get index */
(*Hlpdsp[i])(-1); /* Process it */
}
/*
*//* hlpcms
HELP COMMAND
*/
hlpcms(inx)
int inx;
{
IND int i; /* Scratch */
IND char **kptr; /* Ptr to kwd ptr */
if ((i = inx) == -1) /* If not command keyword */
{
if (!noise (&Topcsb, "named")) /* Guide again */
return;
if (COMNDi (&Topcsb, &Cmkcfb) != _CROK) /* Collect keyword */
return;
kptr = (char **) (Topcsb.CSB_RVL._ADR);
i = kptr - (&Cmktbl[0]); /* Get keyword index */
}
if (!confrm(&Topcsb)) /* Get confirmation */
return;
givhlp (Cmktbl[i]); /* Give help for this command */
}
/*
*//* hlpful
HELP FULL
*/
hlpful()
{
if (!confrm(&Topcsb)) /* Get confirmation */
return;
givhlp ("*FULL*"); /* Give the full help */
}
/*
*//* givhlp (key)
Extract keyed help from help file
Accepts :
key String to match in help key
Returns :
Notes :
The help file MINDER.HLP is simple in organization; it contains
a number of sections of text each beginning with /key and ending with
a line beginning with slash (/)
*/
givhlp (key)
char *key;
{
IND int c; /* Character */
char line[101]; /* Line buffer */
IND int i; /* Scratch */
IND int intext; /* Flag in text or not */
IND FILE *fp; /* for Help file */
if ((fp = fopen("MINDER.HLP", "r")) == NULL)
{
printf ("Help file is not available!\n");
return;
}
printf ("Please wait while I look this up . . .\n");
intext = FALSE; /* Not in keyed text yet */
while (TRUE)
{
i = 0; /* Init line index */
while ((c = getfc (fp)) != EOF)
if (c == '\n')
break;
else if (i < 100)
line[i++] = c;
if ((i == 0) && (c == EOF))
break;
line[i] = NUL;
if (line[0] == '/') /* Special marker ? */
{
if (intext) /* If in text */
break; /* ends with next slash line */
else /* Not intext, look at key */
if (strcmp (&line[1], key) == 0)
{
intext = TRUE;
printf ("\n");
}
}
else if (intext) /* In text ? */
{
printf ("%s\n", line); /* Print the line */
}
}
if (!intext) /* If didn't find anything */
{
printf ("Help for %s is not available.\n", key);
}
fclose (fp);
}
/*
*//* liscmd ()
Processes the LIST command.
Accepts :
Returns :
*/
liscmd ()
{
IND EVT *EVTptr; /* Event block pointer */
IND int m,d,y,hh,mm; /* Date/time components */
IND int okflg; /* OK to list flag */
if (!noise (&Topcsb, "events")) /* Give guide words */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
EVTptr = Evthdr; /* Start at beginning */
while (EVTptr)
{
okflg = chkfor(EVTptr); /* Check it's ok to see.. */
if (Usrnam) /* that includes from us */
if (EVTptr -> EVT_FRM)
if (nccmp (EVTptr -> EVT_FRM, Usrnam) == 0)
okflg = TRUE;
if (okflg) /* Make sure for us.. */
{
cvided (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM,
&m, &d, &y, &hh, &mm);
printf ("%c %02d/%02d/%04d %02d:%02d %-15s %s\n",
chkfor(EVTptr)?'>':'<', m, d, y, hh, mm,
EVTptr -> EVT_NAM, EVTptr -> EVT_MSG);
}
EVTptr = EVTptr -> EVT_FLK;
}
}
/*
*//* modcmd ()
Processes the MODIFY command.
Accepts :
Returns :
*/
modcmd ()
{
IND EVT *EVTptr; /* Pointer to event block */
if (!noise (&Topcsb, "event named")) /* Give guide words */
return;
if ((EVTptr = getenm (&Topcsb)) == NULL) /* Get event name */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
remev (EVTptr); /* Unlink this event */
evdef (EVTptr); /* Modify it */
addev (EVTptr); /* Put the event back in */
}
/*
*//* quicmd ()
Processes the QUIT command.
Accepts :
Returns :
*/
quicmd ()
{
if (!noise (&Topcsb, "without saving changes")) /* Give guide words */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
exit(0);
}
/*
*//* remcmd ()
Processes the REMOVE command.
Accepts :
Returns :
*/
remcmd ()
{
IND EVT *EVTptr; /* Event pointer */
if (!noise (&Topcsb, "event named")) /* Give guide words */
return;
if ((EVTptr = getenm (&Topcsb)) == NULL) /* Get event name */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
remev (EVTptr); /* Unlink this event */
}
/*
*//* rptcmd ()
Processes the REPORT command.
Accepts :
Returns :
*/
rptcmd ()
{
if (!noise (&Topcsb, "active events")) /* Give guide words */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
report(); /* Call the reporter. */
}
/*
*//* shwcmd ()
Processes the SHOW command.
Accepts :
Returns :
*/
shwcmd ()
{
IND EVT *EVTptr; /* Pointer to event block */
if (!noise (&Topcsb, "event named")) /* Give guide words */
return;
if ((EVTptr = getenm (&Topcsb)) == NULL) /* Get event name */
return;
if (!confrm (&Topcsb)) /* Confirm the command */
return;
evshw(EVTptr); /* Show it */
}