/* mind1 module of reminder service 1985 Mark E. Mallett */ #include "minder.h" #include "comnd.h" #include "setjmp.h" /* Local definitions */ /* External routines */ /* External data */ extern CFB Inicfb; /* CFB for initialization */ extern char Tmpabf[]; /* Temp atom buffer */ extern CSB Tmpcsb; /* Temp command state block */ extern jmp_buf Tmpenv; /* setjmp environment buffer */ /* Local routines */ extern int sdsdel(); /* disposition: delete */ extern int sdskep(); /* disposition: keep */ extern int sdsrsc(); /* disposition: reschedule */ extern int setack(); /* Set ACK parameter */ extern int setadv(); /* Set ADVANCE-NOTICE value */ extern int setat(); /* Set AT parameter */ extern int setdis(); /* Set DISPOSITION */ extern int setdon(); /* Done with definitions */ extern int setfor(); /* Set FOR */ extern int sethlp(); /* Set HELP command */ extern int setmsg(); /* Set the event message */ extern int setnam(); /* Set the event name */ extern int setshw(); /* Show current settings */ extern int shlcms(); /* Routine for help:command */ extern int shlful(); /* Routine for help:full */ /* Local data */ /* Attribute command keyword and dispatch tables */ BYTE *Setktb[] = { /* Command keywords.. */ "ACKNOWLEDGE", /* Toggle ack required */ "ADVANCE-NOTICE", /* Specify advance notice */ "AT", /* Specify the event time */ "DISPOSITION", /* Set message disposition */ "DONE", /* Done. */ "FOR", /* For who? */ "HELP", /* Give help */ "MESSAGE", /* Set a message */ "NAME", /* Name the event */ "SHOW", /* Show current settings */ NULL /* Ends with a null pointer */ }; int (*Setdsp[])() = { setack, /* ACKNOWLEDGE */ setadv, /* ADVANCE-NOTICE */ setat, /* AT */ setdis, /* DISPOSITION */ setdon, /* DONE */ setfor, /* FOR */ sethlp, /* HELP */ setmsg, /* MESSAGE */ setnam, /* NAME */ setshw, /* SHOW */ 0 /* Ends with a zero for convenience */ }; /* HELP keyword and dispatch tables */ BYTE *Shltbl[] = { "COMMAND", "FULL", NULL }; int (*Shldsp[])() = { shlcms, shlful, 0 }; /* Keywords and dispatch for DISPOSITIONs */ BYTE *Sdsktb[] = { "DELETE", /* Delete the event */ "KEEP", /* Keep it. */ "RESCHEDULE", /* Reschedule it */ NULL /* Ends with NULL */ }; int (*Sdsdsp[])() = { sdsdel, /* DELETE */ sdskep, /* KEEP */ sdsrsc, /* RESCHEDULE */ 0 /* Ends with zero */ }; /* Keywords for reschedule classes */ BYTE *Schktb[] = { "Days", "Weeks", "Months", "Years", NULL }; /* Same thing, only for printing */ BYTE *Rsuktb[] = { "Day", "Week", "Month", "Year" }; /* COMND blocks */ static CFB Dancfb = {_CMNUM, _CFHPP|_CFSDH, 0, 10, "Number of days of advance notice", 0}; static CFB Deccfb = {_CMNUM, 0, 0, 10, 0, 0}; CFB Dtmcfb = {_CMDAT, _CFDTD|_CFDTT, 0, 0, 0, 0}; CFB Schcfb = {_CMKEY, _CFHPP, 0, &Schktb, "Unit, ", 0}; CFB Sdkcfb = {_CMKEY, _CFHPP|_CFDPP, 0, &Sdsktb, "Disposition, ", "DELETE"}; CFB Stkcfb = {_CMKEY, _CFHPP|_CFDPP, 0, &Setktb, "Command, ", "DONE"}; static CFB Shlcfb = {_CMKEY, _CFDPP, &Stkcfb, &Shltbl, 0, "FULL"}; /* Other things */ static int Sdnflg = {FALSE}; /* Set done flag */ /* *//* evshw (EVTptr) Show event elements Accepts : EVTptr Address of event block Returns : */ evshw (EVTptr) EVT *EVTptr; /* Addr of event block */ { IND int m,d,y,hh,mm; /* Date/time components */ cvided (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM, &m, &d, &y, &hh, &mm); printf ("Event \"%s\" active at %02d/%02d/%04d %02d:%02d\n\n", EVTptr -> EVT_NAM, m, d, y, hh, mm); printf (" >>%s<<\n\n", EVTptr -> EVT_MSG); if (EVTptr -> EVT_FRM != NULL) printf ("From: %s\n", EVTptr -> EVT_FRM); if (EVTptr -> EVT_FOR != NULL) printf ("For: %s\n", EVTptr -> EVT_FOR); if (EVTptr -> EVT_FLG & _EFACK) printf ("Acknowledgement required\n"); else printf ("Automatic "); printf ("Disposition: "); switch (EVTptr -> EVT_DIS) { case _EDDEL: printf ("delete\n"); break; case _EDKEEP: printf ("keep\n"); break; case _EDSCH: printf ("reschedule in %d %s", EVTptr -> EVT_RSV, Rsuktb[EVTptr -> EVT_RSU]); if (EVTptr -> EVT_RSV != 1) putchar('s'); printf ("\n"); break; default: printf ("unknown\n"); } if (EVTptr -> EVT_ADV) { printf ("%d day", EVTptr -> EVT_ADV); if (EVTptr -> EVT_ADV != 1) putchar ('s'); printf (" advance notice\n"); } printf ("\n"); } /* *//* evdef (EVTptr) Define parameters of an event. Accepts : EVTptr Address of the event block Returns : */ evdef (EVTptr) EVT *EVTptr; /* Address of event block */ { IND int i; /* Scratch */ IND BYTE **kptr; /* Points to kwd table entry */ printf ("Specify event parameters. Type DONE to end.\n\n"); Tmpcsb.CSB_PMT = "MIND-DEF> "; /* Set prompt */ /* Enter command loop */ while (TRUE) /* Forever */ { if (COMND (&Tmpcsb, &Inicfb) != _CROK) /* eh? */ { printf ("Fatal error initializing COMND\n"); exit(); } setjmp (Tmpenv); /* Mark here for reparse */ if (COMNDi (&Tmpcsb, &Stkcfb) != _CROK) /* Collect keyword */ continue; kptr = (char **) (Tmpcsb.CSB_RVL._ADR); i = kptr - (&Setktb[0]); /* Get keyword index */ Sdnflg = FALSE; /* Set not done. */ (*Setdsp[i])(EVTptr); /* Process command */ if (Sdnflg) /* If done flag was set */ break; /* exit command loop */ } } /* *//* setack (EVTptr) Processes the ACKNOWLEDGE set-command. Accepts : EVTptr Address of event block Returns : */ setack (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { if (!noise (&Tmpcsb, "flag toggled")) /* Give guide words */ return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; if (EVTptr -> EVT_FLG & _EFACK) /* ack required? */ { printf ("Acknowledgement not required\n"); EVTptr -> EVT_FLG &= ~_EFACK; } else { printf ("Acknowledgement now required\n"); EVTptr -> EVT_FLG |= _EFACK; } } /* *//* setadv (EVTptr) Processes the ADVANCE-NOTICE set-command. Accepts : EVTptr Address of event block Returns : */ setadv (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { if (!noise (&Tmpcsb, "in")) /* Give guide words */ return; if (COMNDi (&Tmpcsb, &Dancfb) != _CROK) /* Get # days */ return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTptr -> EVT_ADV = Tmpcsb.CSB_RVL._INT; /* Save # of days */ } /* *//* setat (EVTptr) Processes the AT set-command. Accepts : EVTptr Address of event block Returns : */ setat (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { IND int *rslptr; /* Result pointer */ IND int id, it; /* Internal date and time */ rslptr = &Tmpabf[0]; /* Where the result is stored */ if (!noise (&Tmpcsb, "date/time")) /* Give guide words */ return; if (COMNDi (&Tmpcsb, &Dtmcfb) != _CROK) /* Get date/time */ return; id = rslptr[0]; /* Pick up date and time */ it = rslptr[1]; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTptr -> EVT_DTD = id; /* Store date */ EVTptr -> EVT_DTM = 0; /* Store time */ } /* *//* setdis (EVTptr) Processes the DISPOSITION set-command. Accepts : EVTptr Address of event block Returns : */ setdis (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { IND char **kptr; /* Keyword ptr ptr */ IND int i; /* Index */ if (!noise (&Tmpcsb, "is")) /* Give guide words */ return; if (COMNDi (&Tmpcsb, &Sdkcfb) != _CROK) /* Get disposition keyword */ return; kptr = (char **) (Tmpcsb.CSB_RVL._ADR); i = kptr - (&Sdsktb[0]); /* Get keyword index */ (*Sdsdsp[i])(EVTptr); /* Process command */ } /* *//* setdon (EVTptr) Processes the DONE set-command. Accepts : EVTptr Address of event block Returns : */ setdon (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { IND int cplflg; /* TRUE if complete def */ if (!noise (&Tmpcsb, "with definitions")) /* Give guide words */ return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; /* Check out the event, make sure all fields are filled */ cplflg = TRUE; /* Presume complete def */ if (EVTptr -> EVT_MSG == NULL) notdon (&cplflg, "message"); if (EVTptr -> EVT_FOR == NULL) notdon (&cplflg, "recipient (FOR)"); if (EVTptr -> EVT_DTD == 0) notdon (&cplflg, "time (AT)"); if (cplflg) Sdnflg = TRUE; printf ("\n"); } /* notdon - subservient to "setdon" routine */ notdon (flg, msg) int *flg; char *msg; { if (*flg) printf ("\n ** Event is incomplete **\n\nMust supply: "); else printf (", "); printf ("%s", msg); *flg = FALSE; } /* *//* setfor (EVTptr) Processes the FOR set-command. Accepts : EVTptr Address of event block Returns : */ setfor (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { char whoto[50]; /* For name buffer */ if (!noise (&Tmpcsb, "recipient")) /* Give guide words */ return; if (!getuqs(&Tmpcsb, "user name", whoto)) return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; if (EVTptr -> EVT_FOR != NULL) /* If any old name */ free (EVTptr -> EVT_FOR); /* Free old name storage */ EVTptr -> EVT_FOR = newstr(whoto); /* Remember new name */ } /* *//* sethlp() the HELP command (taken from lbbhlp.c) */ sethlp() { int i; /* Command index */ char **kptr; /* Keyword ptr ptr */ if (!noise (&Tmpcsb, "on subject")) /* Give guidance */ return; if (COMNDi (&Tmpcsb, &Shlcfb) != _CROK) /* Get keyword */ return; kptr = (char **) Tmpcsb.CSB_RVL._ADR; /* Get returned pointer */ if (Tmpcsb.CSB_CFB == &Stkcfb) /* If matched command keyword */ { i = kptr - &Setktb[0]; /* Get index */ return (shlcms(i)); /* Process the thing */ } i = kptr - &Shltbl[0]; /* Get index */ (*Shldsp[i])(-1); /* Process it */ } /* *//* shlcms HELP COMMAND */ shlcms(inx) int inx; { IND int i; /* Scratch */ IND char **kptr; /* Ptr to kwd ptr */ char kbuf[50]; /* Keyword buffer */ if ((i = inx) == -1) /* If not command keyword */ { if (!noise (&Tmpcsb, "named")) /* Guide again */ return; if (COMNDi (&Tmpcsb, &Stkcfb) != _CROK) /* Collect keyword */ return; kptr = (char **) (Tmpcsb.CSB_RVL._ADR); i = kptr - (&Setktb[0]); /* Get keyword index */ } if (!confrm(&Tmpcsb)) /* Get confirmation */ return; strcpy (kbuf, "DEF-"); /* Prefix for definition helpname */ strcat (kbuf, Setktb[i]); /* Add command name */ givhlp (kbuf); /* Give help for it. */ } /* *//* shlful HELP FULL */ shlful() { if (!confrm(&Tmpcsb)) /* Get confirmation */ return; givhlp ("DEF-*FULL*"); /* Give the full help */ } /* *//* setmsg (EVTptr) Processes the MESSAGE set-command. Accepts : EVTptr Address of event block Returns : */ setmsg (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { char evmsg[100]; /* Event message buffer */ if (!noise (&Tmpcsb, "text is")) /* Give guide words */ return; if (!getrol (&Tmpcsb, "message text", evmsg)) return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; if (EVTptr -> EVT_MSG != NULL) /* If any old message */ free (EVTptr -> EVT_MSG); /* get rid of it */ EVTptr -> EVT_MSG = newstr(evmsg); /* Save new message */ } /* *//* setnam (EVTptr) Processes the NAME set-command. Accepts : EVTptr Address of event block Returns : */ setnam (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { IND EVT *EVTcptr; /* EVT check-pointer */ char evname[50]; /* Event name buffer */ if (!noise (&Tmpcsb, "new name")) /* Give guide words */ return; if (!getuqs(&Tmpcsb, "event name", evname)) return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTcptr = findev(evname); /* See if name exists */ if (EVTcptr != NULL) /* If so */ if (EVTcptr != EVTptr) /* If different one */ { printf ("Event %s already exists; name remains %s\n", evname, EVTptr -> EVT_NAM); return; } if (EVTptr -> EVT_NAM != NULL) /* If any old name */ free (EVTptr -> EVT_NAM); /* Free old name storage */ EVTptr -> EVT_NAM = newstr(evname); /* Remember new name */ } /* *//* setshw (EVTptr) Processes the SHOW command. Accepts : EVTptr Address of event block Returns : */ setshw (EVTptr) EVT *EVTptr; /* Address of event block */ { if (!noise (&Tmpcsb, "event definitions")) /* Give guide words */ return; if (!confrm (&Tmpcsb)) /* Confirm the command */ return; evshw (EVTptr); /* Show it */ } /* *//* sdsdel (EVTptr) Processes the DELETE disposition Accepts : EVTptr Address of event block Returns : */ sdsdel (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTptr -> EVT_DIS = _EDDEL; /* Set disposition type */ } /* *//* sdskep (EVTptr) Processes the KEEP disposition Accepts : EVTptr Address of event block Returns : */ sdskep (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTptr -> EVT_DIS = _EDKEEP; /* Set disposition type */ } /* *//* sdsrsc (EVTptr) Processes the RESCHEDULE disposition Accepts : EVTptr Address of event block Returns : */ sdsrsc (EVTptr) EVT *EVTptr; /* Addr of EVT block */ { IND int units, value; /* Units and value */ IND char **kptr; /* Ptr ptr */ if (!noise (&Tmpcsb, "in")) /* Give guide */ return; if (COMNDi (&Tmpcsb, &Deccfb) != _CROK) /* Get number */ return; value = Tmpcsb.CSB_RVL._INT; /* Get the value */ if (!noise (&Tmpcsb, "units")) /* Guide */ return; if (COMNDi (&Tmpcsb, &Schcfb) != _CROK) /* Get units */ return; kptr = (char **) (Tmpcsb.CSB_RVL._ADR); units = kptr - (&Schktb[0]); /* Get keyword index */ if (!confrm (&Tmpcsb)) /* Confirm the command */ return; EVTptr -> EVT_DIS = _EDSCH; /* Set disposition type */ EVTptr -> EVT_RSU = units; /* Remember units */ EVTptr -> EVT_RSV = value; /* Reschedule value */ /* Remember original day-of-month */ cvided (EVTptr -> EVT_DTM, 0, &units, &value, &units, &units, &units); EVTptr -> EVT_RSO = value; /* just for february... */ }