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 >
C/C++ Source or Header  |  1986-06-19  |  13KB  |  701 lines

  1. /* minder
  2.  
  3.     Reminder service
  4.  
  5.     1985 Mark E. Mallett
  6. */
  7.  
  8. #include "minder.h"
  9. #include "comnd.h"
  10. #include "setjmp.h"
  11. #include "cpm.h"
  12.  
  13.     char    ovlccp = {0};        /* Don't overlay CCP (CP/M) */
  14.  
  15.  
  16.  
  17. /* Local definitions */
  18.  
  19.  
  20.  
  21.  
  22. /* External routines */
  23.  
  24.  
  25. /* External data */
  26.  
  27. extern    int    Chgflg;            /* Changes-made flag */
  28. extern    int    Curdat;            /* Current date */
  29. extern    int    Curtim;            /* Current time */
  30. extern    EVT    *Evthdr;        /* Heads the EVT list */
  31. extern    CFB    Inicfb;            /* CFB for initialization */
  32. extern    int    Osdate;            /* O/S supports date/time */
  33. extern    CSB    Topcsb;            /* top-level command state block */
  34. extern    jmp_buf    Topenv;            /* setjmp environment buffer */
  35. extern    char    *Usrnam;        /* Name of invoking user */
  36.  
  37.  
  38. /* Local routines */
  39.  
  40. extern    int    addcmd();        /* the ADD command */
  41. extern    int    exicmd();        /* the EXIT command */
  42. extern    int    hlpcmd();        /* the HELP command */
  43. extern    int    hlpcms();        /* Routine for help:command */
  44. extern    int    hlpful();        /* Routine for help:full */
  45. extern    int    liscmd();        /* the LIST command */
  46. extern    int    modcmd();        /* the MODIFY command */
  47. extern    int    quicmd();        /* the QUIT command */
  48. extern    int    remcmd();        /* the REMOVE command */
  49. extern    int    rptcmd();        /* the REPORT command */
  50. extern    int    shwcmd();        /* the SHOW command */
  51.  
  52. /* Local data */
  53.  
  54. static    int    Datflg = {FALSE};    /* -d option given */
  55. static    int    Rptmod = {FALSE};    /* If invoked in report mode */
  56.  
  57.  
  58.     /* Command keyword and dispatch tables */
  59.  
  60.  
  61. BYTE        *Cmktbl[] =    {    /* Command keywords.. */
  62.             "ADD",        /* Add event */
  63.             "EXIT",        /* Exit this program */
  64.             "HELP",        /* Give help */
  65.             "LIST",        /* List events */
  66.             "MODIFY",    /* Modify an event */
  67.             "QUIT",        /* Quit without saving changes */
  68.             "REMOVE",    /* Remove an event */
  69.             "REPORT",    /* Report active events */
  70.             "SHOW",        /* Show an event's definition */
  71.             NULL        /* Ends with a null pointer */
  72.                 };
  73.  
  74. int        (*Cmddsp[])() = {
  75.             addcmd,        /* ADD */
  76.             exicmd,        /* EXIT */
  77.             hlpcmd,        /* HELP */
  78.             liscmd,        /* LIST */
  79.             modcmd,        /* MODIFY */
  80.             quicmd,        /* QUIT */
  81.             remcmd,        /* REMOVE */
  82.             rptcmd,        /* REPORT */
  83.             shwcmd,        /* SHOW */
  84.             0        /* Ends with a zero for convenience */
  85.                 };
  86.  
  87.  
  88.     /* HELP keyword and dispatch tables */
  89.  
  90. BYTE         *Hlptbl[] = {
  91.             "COMMAND",
  92.             "FULL",
  93.             NULL
  94.                  };
  95.  
  96. int        (*Hlpdsp[])() = {
  97.             hlpcms,
  98.             hlpful,
  99.             0
  100.                     };
  101.  
  102.  
  103.  
  104.  
  105.     /* COMND blocks */
  106.  
  107. CFB        Cmkcfb = {_CMKEY, _CFHPP, 0, &Cmktbl, "Command, ", 0};
  108. static    CFB    Hkwcfb = {_CMKEY, _CFDPP, &Cmkcfb, &Hlptbl, 0, "FULL"};
  109. /* *//* main
  110.  
  111.         The main routine
  112.  
  113. */
  114.  
  115. main (argc, argv)
  116.  
  117. int        argc;
  118. char        **argv;
  119.  
  120. {
  121. IND    int        mo, da, yr;    /* Month, day, year */
  122. IND    int        c;        /* Character var */
  123. IND    int        i;        /* Scratch */
  124. IND    int        n;        /* NEXT index after arg */
  125. IND    BYTE        *aptr;        /* ptr to arg, if any */
  126. IND    BYTE        **kptr;        /* Points to kwd table entry */
  127. IND    WORD        cpmver;        /* CPM version number */
  128.  
  129. /* Supposed to do this for protection, so... */
  130.  
  131. printf ("MINDER vsn *1*; (C) 1985 Mark E. Mallett.\n");
  132.  
  133. for (i = 1; i < argc; i++)        /* Look at command line arguments */
  134.     {
  135.     if (argv[i][0] != '-')        /* Be tough */
  136.     {
  137.     printf ("Illegal argument %s\n", argv[i]);
  138.     exit(0);
  139.     }
  140.  
  141.     c = argv[i][1];            /* Look at option char */
  142.     c = tolower(c);
  143.     aptr = NULL;            /* Init pot. arg pointer */
  144.     if (argv[i][2] != NUL)        /* If anything after option char */
  145.     {
  146.     aptr = &argv[i][2];        /*  then that is it */
  147.     n = i;                /* Value of next i */
  148.     }
  149.     else
  150.     if (i < argc)            /* Only if there is one */
  151.         {
  152.         n = i+1;            /* Arg is next one */
  153.         aptr = argv[n];        /* Point to it */
  154.         }
  155.  
  156.     switch (c)                /* Branch on char */
  157.     {
  158.     case 'd':            /* Date supplied */
  159.         if (Datflg)            /* Already got one? */
  160.         printf ("Duplicate -d option.\n");
  161.         else
  162.         {
  163.         yr = 1900 + d2(aptr);    /* Get yr */
  164.         mo = d2(&aptr[2]);    /* Month */
  165.         da = d2(&aptr[4]);    /* Day */
  166.         cvedid (&Curdat, &Curtim, mo, da, yr, 0, 0);
  167.         Datflg = TRUE;
  168.         }
  169.         i = n;
  170.         break;
  171.  
  172.  
  173.     case 'r':            /* Report mode */
  174.         Rptmod = TRUE;        /* Set the flag */
  175.         break;
  176.  
  177.     case 'u':            /* Username */
  178.         if (Usrnam != NULL)        /* If more than one.. */
  179.         {
  180.         printf ("Duplicate username given\n");
  181.         exit();
  182.         }
  183.         Usrnam = newstr(aptr);    /* Remember user name */
  184.         i = n;            /* Skip to next argument */
  185.         break;
  186.  
  187.     default:            /* Something else */
  188.         printf ("Ignoring illegal option %s\n", argv[i]);
  189.     }
  190.  
  191.     }
  192.  
  193. cpmver = CPM (_MRCPV, 0);        /* Get CP/M version */
  194. if ((cpmver & 0xff00) != 0)        /* Not CP/M ? */
  195.     printf ("Warning... This is not a CP/M system.\n");
  196. Osdate = (cpmver >= 0x30);        /* Date fn in CPM+ */
  197.  
  198. if (!Osdate)                /* If os date/time not supported */
  199.     if (!Datflg)            /* We have to have date option */
  200.     {
  201.     printf ("Since this is not a CPM+ system, the current date must be\n");
  202.     printf ("supplied on the command line, in the form:\n");
  203.     printf ("        A> minder -d yymmdd\n");
  204.     exit(0);
  205.     }
  206.  
  207. loaddb();                /* Load the database */
  208.  
  209. if (Rptmod)                /* Invoked in report mode? */
  210.     {
  211.     report();                /* Call report module */
  212.     if (Chgflg)                /* Any changes? */
  213.     savedb();            /* Save db */
  214.     exit();                /* Be done */
  215.     }
  216.  
  217. printf ("Type ? for help at any time.\n");
  218.  
  219. /* Enter command loop */
  220.  
  221. while (TRUE)                /* Forever */
  222.     {
  223.     if (COMND (&Topcsb, &Inicfb) != _CROK) /* eh? */
  224.     {
  225.     printf ("Fatal error initializing COMND\n");
  226.     exit();
  227.     }
  228.  
  229.     setjmp (Topenv);            /* Mark here for reparse */
  230.  
  231.     if (COMNDi (&Topcsb, &Cmkcfb) != _CROK)    /* Collect keyword */
  232.     continue;
  233.  
  234.     kptr = (char **) (Topcsb.CSB_RVL._ADR);
  235.     i = kptr - (&Cmktbl[0]);        /* Get keyword index */
  236.     (*Cmddsp[i])();            /* Process command */
  237.     }
  238. }
  239. /*
  240.  
  241. *//* d2 (ptr)
  242.  
  243.     Returns value of 2-digit ASCII decimal string @ ptr
  244.  
  245. This is used for command line parsing of the date.
  246.  
  247. */
  248.  
  249. int d2 (ptr)
  250.  
  251. char        *ptr;
  252.  
  253. {
  254. IND    int    v;            /* Value */
  255.  
  256. v = (*ptr++) - '0';            /* First digit */
  257. v = (v*10) + (*ptr - '0');        /* Value */
  258. return (v);
  259. }
  260. /*
  261.  
  262. *//* addcmd ()
  263.  
  264.     Processes the ADD command.
  265.  
  266.  
  267. Accepts :
  268.  
  269.  
  270. Returns :
  271.  
  272.  
  273. */
  274.  
  275. addcmd ()
  276.  
  277. {
  278. IND    EVT    *EVTptr;        /* Pointer to event block */
  279.     char    evname[50];        /* Event name */
  280.  
  281. if (!noise (&Topcsb, "event named"))        /* Give guide words */
  282.     return;
  283.  
  284. if (!getuqs (&Topcsb, "event name", evname))
  285.     return;
  286.  
  287. if (!confrm (&Topcsb))            /* Confirm the command */
  288.     return;
  289.  
  290. if (findev(evname) != NULL)        /* Make sure not duplicate */
  291.     {
  292.     printf ("Event %s already exists.  Please use another name.\n", evname);
  293.     }
  294. else
  295.     {
  296.     EVTptr = calloc (1, sizeof(EVT));    /* Allocate event block */
  297.     EVTptr -> EVT_NAM = newstr (evname); /* Get event name */
  298.     if (Usrnam != NULL)            /* If we're identified */
  299.     {
  300.     EVTptr -> EVT_FRM = newstr(Usrnam);
  301.     EVTptr -> EVT_FOR = newstr(Usrnam);
  302.     }
  303.     evdef (EVTptr);            /* Go define it */
  304.     addev (EVTptr);            /* Add this event */
  305.     printf ("Event %s added.\n", EVTptr -> EVT_NAM);
  306.     }
  307. }
  308. /*
  309.  
  310. *//* exicmd ()
  311.  
  312.     Processes the EXIT command.
  313.  
  314.  
  315. Accepts :
  316.  
  317.  
  318. Returns :
  319.  
  320.  
  321. */
  322.  
  323. exicmd ()
  324.  
  325. {
  326. if (!noise (&Topcsb, "and save changes"))  /* Give guide words */
  327.     return;
  328.  
  329. if (!confrm (&Topcsb))            /* Confirm the command */
  330.     return;
  331.  
  332. if (Chgflg)                /* If any changes made */
  333.     savedb();                /* Save the database */
  334.  
  335. exit(0);
  336.  
  337. }
  338. /*
  339.  
  340. *//* hlpcmd()
  341.  
  342.     the HELP command
  343.  
  344.     (taken from lbbhlp.c)
  345.  
  346.  
  347. */
  348.  
  349. hlpcmd()
  350.  
  351. {
  352. int        i;            /* Command index */
  353. char        **kptr;            /* Keyword ptr ptr */
  354.  
  355. if (!noise (&Topcsb, "on subject"))    /* Give guidance */
  356.     return;
  357. if (COMNDi (&Topcsb, &Hkwcfb) != _CROK)    /* Get keyword */
  358.     return;
  359.  
  360. kptr = (char **) Topcsb.CSB_RVL._ADR;    /* Get returned pointer */
  361. if (Topcsb.CSB_CFB == &Cmkcfb)        /* If matched command keyword */
  362.     {
  363.     i = kptr - &Cmktbl[0];        /* Get index */
  364.     return (hlpcms(i));            /* Process the thing */
  365.     }
  366. i = kptr - &Hlptbl[0];            /* Get index */
  367.  
  368. (*Hlpdsp[i])(-1);            /* Process it */
  369.  
  370. }
  371. /*
  372. *//* hlpcms
  373.  
  374.     HELP COMMAND
  375.  
  376. */
  377.  
  378. hlpcms(inx)
  379.  
  380. int        inx;
  381.  
  382. {
  383. IND    int    i;            /* Scratch */
  384. IND    char    **kptr;            /* Ptr to kwd ptr */
  385.  
  386. if ((i = inx) == -1)            /* If not command keyword */
  387.     {
  388.     if (!noise (&Topcsb, "named"))    /* Guide again */
  389.         return;
  390.  
  391.     if (COMNDi (&Topcsb, &Cmkcfb) != _CROK)    /* Collect keyword */
  392.     return;
  393.  
  394.     kptr = (char **) (Topcsb.CSB_RVL._ADR);
  395.     i = kptr - (&Cmktbl[0]);        /* Get keyword index */
  396.     }
  397.  
  398. if (!confrm(&Topcsb))            /* Get confirmation */
  399.     return;
  400.  
  401. givhlp (Cmktbl[i]);            /* Give help for this command */
  402. }
  403. /*
  404. *//* hlpful
  405.  
  406.     HELP FULL
  407.  
  408. */
  409.  
  410. hlpful()
  411.  
  412. {
  413. if (!confrm(&Topcsb))            /* Get confirmation */
  414.     return;
  415.  
  416. givhlp ("*FULL*");            /* Give the full help */
  417. }
  418. /*
  419.  
  420. *//* givhlp (key)
  421.  
  422.     Extract keyed help from help file
  423.  
  424.  
  425. Accepts :
  426.  
  427.     key        String to match in help key
  428.  
  429.  
  430. Returns :
  431.  
  432.  
  433.  
  434. Notes :
  435.  
  436.     The help file MINDER.HLP is simple in organization; it contains
  437. a number of sections of text each beginning with /key and ending with
  438. a line beginning with slash (/)
  439.  
  440.  
  441.  
  442. */
  443.  
  444. givhlp (key)
  445.  
  446. char        *key;
  447.  
  448. {
  449. IND    int        c;        /* Character */
  450.     char        line[101];    /* Line buffer */
  451. IND    int        i;        /* Scratch */
  452. IND    int        intext;        /* Flag in text or not */
  453. IND    FILE        *fp;        /*  for Help file  */
  454.  
  455.  
  456. if ((fp = fopen("MINDER.HLP", "r")) == NULL)
  457.     {
  458.     printf ("Help file is not available!\n");
  459.     return;
  460.     }
  461.  
  462. printf ("Please wait while I look this up . . .\n");
  463. intext = FALSE;                /* Not in keyed text yet */
  464. while (TRUE)
  465.     {
  466.     i = 0;                /* Init line index */
  467.     while ((c = getfc (fp)) != EOF)
  468.     if (c == '\n')
  469.         break;
  470.     else if (i < 100)
  471.         line[i++] = c;
  472.  
  473.     if ((i == 0) && (c == EOF))
  474.     break;
  475.  
  476.     line[i] = NUL;
  477.  
  478.     if (line[0] == '/')            /* Special marker ? */
  479.     {
  480.     if (intext)            /* If in text */
  481.         break;            /*  ends with next slash line */
  482.     else                /* Not intext, look at key */
  483.         if (strcmp (&line[1], key) == 0)
  484.         {
  485.         intext = TRUE;
  486.         printf ("\n");
  487.         }
  488.     }
  489.  
  490.     else if (intext)            /* In text ? */
  491.     {
  492.     printf ("%s\n", line);        /* Print the line */
  493.     }
  494.     }
  495.  
  496. if (!intext)                /* If didn't find anything */
  497.     {
  498.     printf ("Help for %s is not available.\n", key);
  499.  
  500.     }
  501.  
  502. fclose (fp);
  503. }
  504. /*
  505.  
  506. *//* liscmd ()
  507.  
  508.     Processes the LIST command.
  509.  
  510.  
  511. Accepts :
  512.  
  513.  
  514. Returns :
  515.  
  516.  
  517. */
  518.  
  519. liscmd ()
  520.  
  521. {
  522. IND    EVT    *EVTptr;        /* Event block pointer */
  523. IND    int    m,d,y,hh,mm;        /* Date/time components */
  524. IND    int    okflg;            /* OK to list flag */
  525.  
  526. if (!noise (&Topcsb, "events"))        /* Give guide words */
  527.     return;
  528.  
  529. if (!confrm (&Topcsb))            /* Confirm the command */
  530.     return;
  531.  
  532. EVTptr = Evthdr;            /* Start at beginning */
  533. while (EVTptr)
  534.     {
  535.     okflg = chkfor(EVTptr);        /* Check it's ok to see.. */
  536.     if (Usrnam)                /* that includes from us */
  537.     if (EVTptr -> EVT_FRM)
  538.         if (nccmp (EVTptr -> EVT_FRM, Usrnam) == 0)
  539.         okflg = TRUE;
  540.  
  541.     if (okflg)                /* Make sure for us.. */
  542.     {
  543.     cvided (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM,
  544.         &m, &d, &y, &hh, &mm);
  545.     printf ("%c %02d/%02d/%04d %02d:%02d %-15s   %s\n",
  546.         chkfor(EVTptr)?'>':'<', m, d, y, hh, mm,
  547.         EVTptr -> EVT_NAM,  EVTptr -> EVT_MSG);
  548.     }
  549.     EVTptr = EVTptr -> EVT_FLK;
  550.     }
  551.  
  552. }
  553. /*
  554.  
  555. *//* modcmd ()
  556.  
  557.     Processes the MODIFY command.
  558.  
  559.  
  560. Accepts :
  561.  
  562.  
  563. Returns :
  564.  
  565.  
  566. */
  567.  
  568. modcmd ()
  569.  
  570. {
  571. IND    EVT    *EVTptr;        /* Pointer to event block */
  572.  
  573. if (!noise (&Topcsb, "event named"))    /* Give guide words */
  574.     return;
  575.  
  576. if ((EVTptr = getenm (&Topcsb)) == NULL)  /* Get event name */
  577.     return;
  578.  
  579. if (!confrm (&Topcsb))            /* Confirm the command */
  580.     return;
  581.  
  582. remev (EVTptr);                /* Unlink this event */
  583. evdef (EVTptr);                /* Modify it */
  584. addev (EVTptr);                /* Put the event back in */
  585. }
  586. /*
  587.  
  588. *//* quicmd ()
  589.  
  590.     Processes the QUIT command.
  591.  
  592.  
  593. Accepts :
  594.  
  595.  
  596. Returns :
  597.  
  598.  
  599. */
  600.  
  601. quicmd ()
  602.  
  603. {
  604. if (!noise (&Topcsb, "without saving changes"))  /* Give guide words */
  605.     return;
  606.  
  607. if (!confrm (&Topcsb))            /* Confirm the command */
  608.     return;
  609.  
  610. exit(0);
  611.  
  612. }
  613. /*
  614.  
  615. *//* remcmd ()
  616.  
  617.     Processes the REMOVE command.
  618.  
  619.  
  620. Accepts :
  621.  
  622.  
  623. Returns :
  624.  
  625.  
  626. */
  627.  
  628. remcmd ()
  629.  
  630. {
  631. IND    EVT    *EVTptr;        /* Event pointer */
  632.  
  633. if (!noise (&Topcsb, "event named"))    /* Give guide words */
  634.     return;
  635.  
  636. if ((EVTptr = getenm (&Topcsb)) == NULL)  /* Get event name */
  637.     return;
  638.  
  639. if (!confrm (&Topcsb))            /* Confirm the command */
  640.     return;
  641.  
  642. remev (EVTptr);                /* Unlink this event */
  643. }
  644. /*
  645.  
  646. *//* rptcmd ()
  647.  
  648.     Processes the REPORT command.
  649.  
  650.  
  651. Accepts :
  652.  
  653.  
  654. Returns :
  655.  
  656.  
  657. */
  658.  
  659. rptcmd ()
  660.  
  661. {
  662. if (!noise (&Topcsb, "active events"))    /* Give guide words */
  663.     return;
  664.  
  665. if (!confrm (&Topcsb))            /* Confirm the command */
  666.     return;
  667.  
  668. report();                /* Call the reporter. */
  669. }
  670. /*
  671.  
  672. *//* shwcmd ()
  673.  
  674.     Processes the SHOW command.
  675.  
  676.  
  677. Accepts :
  678.  
  679.  
  680. Returns :
  681.  
  682.  
  683. */
  684.  
  685. shwcmd ()
  686.  
  687. {
  688. IND    EVT    *EVTptr;        /* Pointer to event block */
  689.  
  690. if (!noise (&Topcsb, "event named"))        /* Give guide words */
  691.     return;
  692.  
  693. if ((EVTptr = getenm (&Topcsb)) == NULL)  /* Get event name */
  694.     return;
  695.  
  696. if (!confrm (&Topcsb))            /* Confirm the command */
  697.     return;
  698.  
  699. evshw(EVTptr);                /* Show it */
  700. }
  701.