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 / MINDDB.C < prev    next >
C/C++ Source or Header  |  1986-06-19  |  10KB  |  498 lines

  1. /* minddb
  2.  
  3.     database module of reminder service
  4.     Included are:
  5.  
  6.         addev        Add an event to the event list
  7.         findev        Find event by name
  8.         loaddb        Load database.
  9.         remev        Unlink an event by address of EVT block
  10.         savedb        Save the database.
  11.  
  12.     1985 Mark E. Mallett
  13. */
  14.  
  15. #include "minder.h"
  16. #include "comnd.h"
  17. #include "setjmp.h"
  18. #include "cpm.h"
  19.  
  20.  
  21.  
  22. /* Local definitions */
  23.  
  24.  
  25.  
  26.  
  27. /* External routines */
  28.  
  29.  
  30. /* External data */
  31.  
  32. extern    int    Chgflg;            /* Flags changes made */
  33. extern    int    Evtcnt;            /* Event count */
  34. extern    EVT    *Evthdr;        /* Address of the list header */
  35.  
  36.  
  37. /* Local routines */
  38.  
  39.  
  40.  
  41. /* Local data */
  42.  
  43. /*
  44.  
  45. *//* loaddb ()
  46.  
  47.     Loads the database
  48.  
  49.  
  50. Accepts :
  51.  
  52.  
  53. Returns :
  54.  
  55.  
  56. */
  57.  
  58. loaddb()
  59.  
  60. {
  61. IND    int    nent;            /* Number of entries */
  62. IND    int    code;            /* entry code */
  63. IND    EVT    *EVTptr;        /* Points to EVT block */
  64. IND    FILE    *evffp;            /* File var for event file */
  65. IND    int    orgusr;            /* Original user number */
  66.  
  67. orgusr = CPM (_MRGUC, 0xFF);        /* Get user number currently set */
  68. CPM (_MRGUC, 0);            /* Set to zero */
  69. if ((evffp = fopen(_EVFNAM, "r")) == NULL)
  70.     {
  71.     CPM (_MRGUC, orgusr);        /* Reset user code */
  72.     return;
  73.     }
  74.  
  75. Evthdr = NULL;                /* Event list is empty */
  76. Evtcnt = 0;                /* Number of events is zero */
  77.  
  78. fread (&nent, sizeof(int), 1, evffp);    /* Get number of entries */
  79.  
  80. while (nent--)                /* Read through the file */
  81.     {
  82.     EVTptr = calloc (1, sizeof(EVT));    /* Allocate a new EVT block */
  83.  
  84.     rdevi (&EVTptr -> EVT_DTD, evffp);    /* Date */
  85.     rdevi (&EVTptr -> EVT_DTM, evffp);    /* Time */
  86.     rdevi (&EVTptr -> EVT_FLG, evffp);    /* Flags */
  87.     rdevi (&EVTptr -> EVT_DIS, evffp);    /* Disposition */
  88.     rdevi (&EVTptr -> EVT_ADV, evffp);    /* Advance notice */
  89.     rdevi (&code, evffp);        /* Reschedule units */
  90.     EVTptr -> EVT_RSU = code;
  91.     rdevi (&EVTptr -> EVT_RSV, evffp);    /* Reschedule value */
  92.     rdevi (&code, evffp);        /* Reschedule original day */
  93.     EVTptr -> EVT_RSO = code;
  94.  
  95.     EVTptr -> EVT_NAM = revstr(evffp);
  96.  
  97.  
  98. /* Read optional components */
  99.  
  100.     while (TRUE)
  101.     {
  102.     if (fread(&code, sizeof(int), 1, evffp) != 1)
  103.         {
  104.         code = 0xffff;        /* Signal abort */
  105.         break;
  106.         }
  107.  
  108.     switch (code)            /* Process the entry */
  109.         {
  110.         case _ECMSG:        /* Message */
  111.         EVTptr -> EVT_MSG = revstr(evffp);
  112.         break;
  113.  
  114.         case _ECFRM:        /* From */
  115.         EVTptr -> EVT_FRM = revstr(evffp);
  116.         break;
  117.  
  118.         case _ECFOR:        /* For */
  119.         EVTptr -> EVT_FOR = revstr(evffp);
  120.         break;
  121.  
  122.         case _ECEOE:        /* End of entry */
  123.         break;            /* End it */
  124.  
  125.         default:            /* Something else ? */
  126.         code = 0xffff;        /* Signal abort */
  127.         break;            /* phew */
  128.         }
  129.  
  130.     if (code == _ECEOE)        /* If done with entry */
  131.         break;            /*  go take it. */
  132.  
  133.     if (code == 0xffff)        /* If exit signal */
  134.         break;            /*  then exit */
  135.     }
  136.  
  137. /* End of entry, or abort from reading entry */
  138.  
  139.     if (code == 0xffff)            /* If abort signal */
  140.     break;                /*  then abort */
  141.  
  142.     addev (EVTptr);            /* Add this event */
  143.     }
  144.  
  145. fclose (evffp);                /* Close the file */
  146. CPM (_MRGUC, orgusr);            /* Set back to correct user # */
  147.  
  148. Chgflg = FALSE;                /* Not changed from file. */
  149.  
  150. }
  151. /*
  152.  
  153. *//* savedb ()
  154.  
  155.     Loads the database
  156.  
  157.  
  158. Accepts :
  159.  
  160.  
  161. Returns :
  162.  
  163.  
  164. */
  165.  
  166. savedb()
  167.  
  168. {
  169. IND    FILE    *evffp;            /* File var for event file */
  170. IND    EVT    *EVTptr;        /* Addr of EVT block */
  171. IND    int    orgusr;            /* Original user number */
  172.  
  173. orgusr = CPM (_MRGUC, 0xFF);        /* Get user number currently set */
  174. CPM (_MRGUC, 0);            /* Set to zero */
  175. if ((evffp = fopen(_EVFNAM, "w")) == NULL)
  176.     {
  177.     CPM (_MRGUC, orgusr);        /* Reset user code */
  178.     printf ("Can not open uif; file not written.\n");
  179.     return;
  180.     }
  181.  
  182. wrtevi (Evtcnt, evffp);            /* Write the number of events */
  183. EVTptr = Evthdr;            /* Start at beginning */
  184. while (EVTptr)                /* Do each one */
  185.     {
  186.     wrtevi (EVTptr -> EVT_DTD, evffp);    /* Write Date */
  187.     wrtevi (EVTptr -> EVT_DTM, evffp);    /* Write Time */
  188.     wrtevi (EVTptr -> EVT_FLG, evffp);    /* Write Flags */
  189.     wrtevi (EVTptr -> EVT_DIS, evffp);    /* Write Disposition */
  190.     wrtevi (EVTptr -> EVT_ADV, evffp);    /* Write Advance notice */
  191.     wrtevi (EVTptr -> EVT_RSU, evffp);    /* Write Reschedule units */
  192.     wrtevi (EVTptr -> EVT_RSV, evffp);    /* Write Reschedule value */
  193.     wrtevi (EVTptr -> EVT_RSO, evffp);    /* Write Reschedule original day */
  194.  
  195.     wevstr (EVTptr -> EVT_NAM, evffp);    /* Write event name */
  196.  
  197.  
  198. /* Write optional components */
  199.     if (EVTptr -> EVT_MSG)
  200.     {
  201.     wrtevi (_ECMSG, evffp);        /* Event code for message */
  202.     wevstr (EVTptr -> EVT_MSG, evffp);    /* Write string */
  203.     }
  204.  
  205.     if (EVTptr -> EVT_FRM)
  206.     {
  207.     wrtevi (_ECFRM, evffp);        /* Event code for from */
  208.     wevstr (EVTptr -> EVT_FRM, evffp);    /* Write string */
  209.     }
  210.  
  211.     if (EVTptr -> EVT_FOR)
  212.     {
  213.     wrtevi (_ECFOR, evffp);        /* Event code for for */
  214.     wevstr (EVTptr -> EVT_FOR, evffp);    /* Write string */
  215.     }
  216.  
  217.     wrtevi (_ECEOE, evffp);        /* End of entry */
  218.  
  219.     EVTptr = EVTptr -> EVT_FLK;        /* Step to next one */
  220.     }
  221.  
  222. fclose (evffp);
  223. CPM (_MRGUC, orgusr);            /* Set back to correct user # */
  224.  
  225. }
  226. /*
  227.  
  228. *//* addev (EVTptr)
  229.  
  230.     Add event to event list
  231.  
  232.  
  233. Accepts :
  234.  
  235.     EVTptr        Address of event block
  236.  
  237.  
  238. Returns :
  239.  
  240.  
  241. */
  242.  
  243. addev (EVTptr)
  244.  
  245. EVT        *EVTptr;        /* Addr of event block */
  246.  
  247. {
  248. IND    EVT    *EVTlptr;        /* Pointer to previous */
  249. IND    EVT    *EVTcptr;        /* Pointer to current */
  250.  
  251. EVTlptr = NULL;                /* Set prev-ptr to none */
  252. EVTcptr = Evthdr;            /* Start at the head of the list */
  253. while (EVTcptr)                /* Follow the list */
  254.     {
  255.     if (EVTptr -> EVT_DTD < EVTcptr -> EVT_DTD)
  256.     break;                /* Found point if lesser date */
  257.     if (EVTptr -> EVT_DTD == EVTcptr -> EVT_DTD)
  258.     if (EVTptr -> EVT_DTM < EVTcptr -> EVT_DTM)
  259.         break;            /* Base on time if dates are same */
  260.  
  261.     EVTlptr = EVTcptr;            /* Remember prev-ptr */
  262.     EVTcptr = EVTcptr -> EVT_FLK;    /* Step to next */
  263.     }
  264.  
  265. /* Found insertion point (after EVTlptr).  Link new one in */
  266.  
  267. EVTptr -> EVT_FLK = EVTcptr;        /* Link to next */
  268. if (EVTlptr == NULL)            /* If head of list */
  269.     Evthdr = EVTptr;            /*  start new one */
  270. else                    /* Otherwise */
  271.     EVTlptr -> EVT_FLK = EVTptr;    /*  link prev to this one */
  272.  
  273. Evtcnt++;                /* Count new event */
  274. Chgflg = TRUE;                /* Mark change made */
  275. }
  276. /*
  277.  
  278. *//* findev (evname)
  279.  
  280.     Find an event by name
  281.  
  282.  
  283. Accepts :
  284.  
  285.     evname        Address of the event name
  286.  
  287.  
  288. Returns :
  289.  
  290.     <value>        Address of the EVT block, or
  291.             NULL if no such event.
  292.  
  293. */
  294.  
  295. EVT *findev (evname)
  296.  
  297. char        *evname;        /* The event name */
  298.  
  299. {
  300. IND    EVT    *EVTptr;        /* Event pointer */
  301.  
  302. EVTptr = Evthdr;            /* Start at the list beginning */
  303. while (EVTptr)
  304.     {
  305.     if (nccmp(evname, EVTptr -> EVT_NAM) == 0)
  306.     return (EVTptr);        /* If same name, return it. */
  307.     EVTptr = EVTptr -> EVT_FLK;        /* Try next one. */
  308.     }
  309.  
  310. return (NULL);
  311. }
  312. /*
  313.  
  314. *//* remev (EVTptr)
  315.  
  316.     Remove (unlink) event from event list
  317.  
  318.  
  319. Accepts :
  320.  
  321.     EVTptr        Address of event block
  322.  
  323.  
  324. Returns :
  325.  
  326.  
  327. */
  328.  
  329. remev (EVTptr)
  330.  
  331. EVT        *EVTptr;        /* Addr of event block */
  332.  
  333. {
  334. IND    EVT    *EVTlptr;        /* Pointer to previous */
  335. IND    EVT    *EVTcptr;        /* Pointer to current */
  336.  
  337. EVTlptr = NULL;                /* Set prev-ptr to none */
  338. EVTcptr = Evthdr;            /* Start at the head of the list */
  339. while (EVTcptr)                /* Follow the list */
  340.     {
  341.     if (EVTcptr == EVTptr)        /* if this is it... */
  342.     {
  343.     if (EVTlptr == NULL)        /* If no previous */
  344.         Evthdr = EVTptr -> EVT_FLK;    /*  remove from head */
  345.     else                /* Otherwise */
  346.         EVTlptr -> EVT_FLK = EVTptr -> EVT_FLK;
  347.                     /*  remove from previous link */
  348.     Evtcnt--;            /* Subtract this event */
  349.     Chgflg = TRUE;            /* Mark change made */
  350.     return;                /* all done */
  351.     }
  352.  
  353.     EVTlptr = EVTcptr;            /* Remember prev-ptr */
  354.     EVTcptr = EVTcptr -> EVT_FLK;    /* Step to next */
  355.     }
  356. }
  357. /*
  358.  
  359. *//* rdevi (iptr, fp)
  360.  
  361.     Read int from event file
  362.  
  363.  
  364. Accepts :
  365.  
  366.     iptr        Address of variable
  367.     fp        File variable
  368.  
  369.  
  370. Returns :
  371.  
  372.  
  373. */
  374.  
  375. rdevi (iptr, fp)
  376.  
  377. int        *iptr;            /* Addr of variable */
  378. FILE        *fp;            /* File var. */
  379.  
  380. {
  381. fread (iptr, sizeof(int),1,fp);
  382. }
  383. /*
  384.  
  385. *//* revstr (fp)
  386.  
  387.     Read string from EVT file fp, return copy of it
  388.  
  389.  
  390. Accepts :
  391.  
  392.     fp        File variable for file positioned at string
  393.  
  394.  
  395. Returns :
  396.  
  397.     <value>        Address of string made
  398.  
  399.  
  400. */
  401.  
  402. char *revstr (fp)
  403.  
  404. FILE        *fp;            /* File var */
  405.  
  406. {
  407. IND    char    str[101];        /* Temp string */
  408. IND    int    c;            /* Char value */
  409. IND    int    cc;            /* Character counter */
  410. IND    int    i;            /* Index */
  411.  
  412. i = 0;                    /* Init index */
  413. cc = 0;                    /* Init character counter */
  414. while (TRUE)                /* Read from file */
  415.     {
  416.     if (fread (&c, 1, 1, fp) != 1)
  417.     return (NULL);            /* oops */
  418.     cc++;                /* Count the char */
  419.     if (c == NUL)            /* If end of string */
  420.     break;                /*  go use it */
  421.     if (i < 100)            /* If we've got room in string */
  422.     str[i++] = c;            /*  store it. */
  423.     }
  424.  
  425. /* Done... allocate new string and return it */
  426.  
  427. str[i++] = NUL;                /* Zero-end it */
  428. if ((cc & 1) != 0)            /* Must word-align the file */
  429.     fread (&c, 1, 1, fp);
  430. return (newstr(str));            /* Return copy of the string */
  431. }
  432. /*
  433.  
  434. *//* wrtevi (val, fp)
  435.  
  436.     Write int to event file
  437.  
  438.  
  439. Accepts :
  440.  
  441.     val        Value to write
  442.     fp        File variable for event file
  443.  
  444.  
  445. Returns :
  446.  
  447.  
  448. */
  449.  
  450. wrtevi (val, fp)
  451.  
  452. int        val;            /* What to write */
  453. FILE        *fp;            /* File var */
  454.  
  455. {
  456. fwrite (&val, 2, 1, fp);        /* Write it */
  457. }
  458. /*
  459.  
  460. *//* wevstr (str, fp)
  461.  
  462.     Write a string to the event file
  463.  
  464.  
  465. Accepts :
  466.  
  467.     str        Addr of string to write
  468.     fp        File var for file
  469.  
  470.  
  471. Returns :
  472.  
  473. */
  474.  
  475. wevstr (str, fp)
  476.  
  477. char        *str;            /* Addr of string */
  478. FILE        *fp;            /* Var for file to write to */
  479.  
  480. {
  481. IND    int    c;            /* Char */
  482. IND    int    cc;            /* Character counter */
  483.  
  484. cc = 0;                    /* Init char count */
  485. while (TRUE)                /* Until done */
  486.     {
  487.     c = (*str++)&0xff;            /* Get next char */
  488.     fwrite (&c, 1, 1, fp);        /* Write the character value */
  489.     cc++;                /* Count it */
  490.     if (c == NUL)            /* If end of string */
  491.     break;                /*  be done. */
  492.     }
  493.  
  494. if ((cc & 1) != 0)            /* If odd number of bytes */
  495.     fwrite (&c, 1, 1, fp);        /*  write an extra one */
  496.  
  497. }
  498.