/* minddb database module of reminder service Included are: addev Add an event to the event list findev Find event by name loaddb Load database. remev Unlink an event by address of EVT block savedb Save the database. 1985 Mark E. Mallett */ #include "minder.h" #include "comnd.h" #include "setjmp.h" #include "cpm.h" /* Local definitions */ /* External routines */ /* External data */ extern int Chgflg; /* Flags changes made */ extern int Evtcnt; /* Event count */ extern EVT *Evthdr; /* Address of the list header */ /* Local routines */ /* Local data */ /* *//* loaddb () Loads the database Accepts : Returns : */ loaddb() { IND int nent; /* Number of entries */ IND int code; /* entry code */ IND EVT *EVTptr; /* Points to EVT block */ IND FILE *evffp; /* File var for event file */ IND int orgusr; /* Original user number */ orgusr = CPM (_MRGUC, 0xFF); /* Get user number currently set */ CPM (_MRGUC, 0); /* Set to zero */ if ((evffp = fopen(_EVFNAM, "r")) == NULL) { CPM (_MRGUC, orgusr); /* Reset user code */ return; } Evthdr = NULL; /* Event list is empty */ Evtcnt = 0; /* Number of events is zero */ fread (&nent, sizeof(int), 1, evffp); /* Get number of entries */ while (nent--) /* Read through the file */ { EVTptr = calloc (1, sizeof(EVT)); /* Allocate a new EVT block */ rdevi (&EVTptr -> EVT_DTD, evffp); /* Date */ rdevi (&EVTptr -> EVT_DTM, evffp); /* Time */ rdevi (&EVTptr -> EVT_FLG, evffp); /* Flags */ rdevi (&EVTptr -> EVT_DIS, evffp); /* Disposition */ rdevi (&EVTptr -> EVT_ADV, evffp); /* Advance notice */ rdevi (&code, evffp); /* Reschedule units */ EVTptr -> EVT_RSU = code; rdevi (&EVTptr -> EVT_RSV, evffp); /* Reschedule value */ rdevi (&code, evffp); /* Reschedule original day */ EVTptr -> EVT_RSO = code; EVTptr -> EVT_NAM = revstr(evffp); /* Read optional components */ while (TRUE) { if (fread(&code, sizeof(int), 1, evffp) != 1) { code = 0xffff; /* Signal abort */ break; } switch (code) /* Process the entry */ { case _ECMSG: /* Message */ EVTptr -> EVT_MSG = revstr(evffp); break; case _ECFRM: /* From */ EVTptr -> EVT_FRM = revstr(evffp); break; case _ECFOR: /* For */ EVTptr -> EVT_FOR = revstr(evffp); break; case _ECEOE: /* End of entry */ break; /* End it */ default: /* Something else ? */ code = 0xffff; /* Signal abort */ break; /* phew */ } if (code == _ECEOE) /* If done with entry */ break; /* go take it. */ if (code == 0xffff) /* If exit signal */ break; /* then exit */ } /* End of entry, or abort from reading entry */ if (code == 0xffff) /* If abort signal */ break; /* then abort */ addev (EVTptr); /* Add this event */ } fclose (evffp); /* Close the file */ CPM (_MRGUC, orgusr); /* Set back to correct user # */ Chgflg = FALSE; /* Not changed from file. */ } /* *//* savedb () Loads the database Accepts : Returns : */ savedb() { IND FILE *evffp; /* File var for event file */ IND EVT *EVTptr; /* Addr of EVT block */ IND int orgusr; /* Original user number */ orgusr = CPM (_MRGUC, 0xFF); /* Get user number currently set */ CPM (_MRGUC, 0); /* Set to zero */ if ((evffp = fopen(_EVFNAM, "w")) == NULL) { CPM (_MRGUC, orgusr); /* Reset user code */ printf ("Can not open uif; file not written.\n"); return; } wrtevi (Evtcnt, evffp); /* Write the number of events */ EVTptr = Evthdr; /* Start at beginning */ while (EVTptr) /* Do each one */ { wrtevi (EVTptr -> EVT_DTD, evffp); /* Write Date */ wrtevi (EVTptr -> EVT_DTM, evffp); /* Write Time */ wrtevi (EVTptr -> EVT_FLG, evffp); /* Write Flags */ wrtevi (EVTptr -> EVT_DIS, evffp); /* Write Disposition */ wrtevi (EVTptr -> EVT_ADV, evffp); /* Write Advance notice */ wrtevi (EVTptr -> EVT_RSU, evffp); /* Write Reschedule units */ wrtevi (EVTptr -> EVT_RSV, evffp); /* Write Reschedule value */ wrtevi (EVTptr -> EVT_RSO, evffp); /* Write Reschedule original day */ wevstr (EVTptr -> EVT_NAM, evffp); /* Write event name */ /* Write optional components */ if (EVTptr -> EVT_MSG) { wrtevi (_ECMSG, evffp); /* Event code for message */ wevstr (EVTptr -> EVT_MSG, evffp); /* Write string */ } if (EVTptr -> EVT_FRM) { wrtevi (_ECFRM, evffp); /* Event code for from */ wevstr (EVTptr -> EVT_FRM, evffp); /* Write string */ } if (EVTptr -> EVT_FOR) { wrtevi (_ECFOR, evffp); /* Event code for for */ wevstr (EVTptr -> EVT_FOR, evffp); /* Write string */ } wrtevi (_ECEOE, evffp); /* End of entry */ EVTptr = EVTptr -> EVT_FLK; /* Step to next one */ } fclose (evffp); CPM (_MRGUC, orgusr); /* Set back to correct user # */ } /* *//* addev (EVTptr) Add event to event list Accepts : EVTptr Address of event block Returns : */ addev (EVTptr) EVT *EVTptr; /* Addr of event block */ { IND EVT *EVTlptr; /* Pointer to previous */ IND EVT *EVTcptr; /* Pointer to current */ EVTlptr = NULL; /* Set prev-ptr to none */ EVTcptr = Evthdr; /* Start at the head of the list */ while (EVTcptr) /* Follow the list */ { if (EVTptr -> EVT_DTD < EVTcptr -> EVT_DTD) break; /* Found point if lesser date */ if (EVTptr -> EVT_DTD == EVTcptr -> EVT_DTD) if (EVTptr -> EVT_DTM < EVTcptr -> EVT_DTM) break; /* Base on time if dates are same */ EVTlptr = EVTcptr; /* Remember prev-ptr */ EVTcptr = EVTcptr -> EVT_FLK; /* Step to next */ } /* Found insertion point (after EVTlptr). Link new one in */ EVTptr -> EVT_FLK = EVTcptr; /* Link to next */ if (EVTlptr == NULL) /* If head of list */ Evthdr = EVTptr; /* start new one */ else /* Otherwise */ EVTlptr -> EVT_FLK = EVTptr; /* link prev to this one */ Evtcnt++; /* Count new event */ Chgflg = TRUE; /* Mark change made */ } /* *//* findev (evname) Find an event by name Accepts : evname Address of the event name Returns : Address of the EVT block, or NULL if no such event. */ EVT *findev (evname) char *evname; /* The event name */ { IND EVT *EVTptr; /* Event pointer */ EVTptr = Evthdr; /* Start at the list beginning */ while (EVTptr) { if (nccmp(evname, EVTptr -> EVT_NAM) == 0) return (EVTptr); /* If same name, return it. */ EVTptr = EVTptr -> EVT_FLK; /* Try next one. */ } return (NULL); } /* *//* remev (EVTptr) Remove (unlink) event from event list Accepts : EVTptr Address of event block Returns : */ remev (EVTptr) EVT *EVTptr; /* Addr of event block */ { IND EVT *EVTlptr; /* Pointer to previous */ IND EVT *EVTcptr; /* Pointer to current */ EVTlptr = NULL; /* Set prev-ptr to none */ EVTcptr = Evthdr; /* Start at the head of the list */ while (EVTcptr) /* Follow the list */ { if (EVTcptr == EVTptr) /* if this is it... */ { if (EVTlptr == NULL) /* If no previous */ Evthdr = EVTptr -> EVT_FLK; /* remove from head */ else /* Otherwise */ EVTlptr -> EVT_FLK = EVTptr -> EVT_FLK; /* remove from previous link */ Evtcnt--; /* Subtract this event */ Chgflg = TRUE; /* Mark change made */ return; /* all done */ } EVTlptr = EVTcptr; /* Remember prev-ptr */ EVTcptr = EVTcptr -> EVT_FLK; /* Step to next */ } } /* *//* rdevi (iptr, fp) Read int from event file Accepts : iptr Address of variable fp File variable Returns : */ rdevi (iptr, fp) int *iptr; /* Addr of variable */ FILE *fp; /* File var. */ { fread (iptr, sizeof(int),1,fp); } /* *//* revstr (fp) Read string from EVT file fp, return copy of it Accepts : fp File variable for file positioned at string Returns : Address of string made */ char *revstr (fp) FILE *fp; /* File var */ { IND char str[101]; /* Temp string */ IND int c; /* Char value */ IND int cc; /* Character counter */ IND int i; /* Index */ i = 0; /* Init index */ cc = 0; /* Init character counter */ while (TRUE) /* Read from file */ { if (fread (&c, 1, 1, fp) != 1) return (NULL); /* oops */ cc++; /* Count the char */ if (c == NUL) /* If end of string */ break; /* go use it */ if (i < 100) /* If we've got room in string */ str[i++] = c; /* store it. */ } /* Done... allocate new string and return it */ str[i++] = NUL; /* Zero-end it */ if ((cc & 1) != 0) /* Must word-align the file */ fread (&c, 1, 1, fp); return (newstr(str)); /* Return copy of the string */ } /* *//* wrtevi (val, fp) Write int to event file Accepts : val Value to write fp File variable for event file Returns : */ wrtevi (val, fp) int val; /* What to write */ FILE *fp; /* File var */ { fwrite (&val, 2, 1, fp); /* Write it */ } /* *//* wevstr (str, fp) Write a string to the event file Accepts : str Addr of string to write fp File var for file Returns : */ wevstr (str, fp) char *str; /* Addr of string */ FILE *fp; /* Var for file to write to */ { IND int c; /* Char */ IND int cc; /* Character counter */ cc = 0; /* Init char count */ while (TRUE) /* Until done */ { c = (*str++)&0xff; /* Get next char */ fwrite (&c, 1, 1, fp); /* Write the character value */ cc++; /* Count it */ if (c == NUL) /* If end of string */ break; /* be done. */ } if ((cc & 1) != 0) /* If odd number of bytes */ fwrite (&c, 1, 1, fp); /* write an extra one */ }