home *** CD-ROM | disk | FTP | other *** search
- /*
- * db.c : Database routines for xkal.
- * Handles searching and updating the appointment array.
- *
- * George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
- *
- * $Id: db.c,v 1.5 90/11/07 11:22:44 ferguson Exp $
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #include <X11/Intrinsic.h>
- #include "util.h"
- #include "date-strings.h"
- extern char *getenv();
-
- extern char *program;
-
- /*
- * Functions defined here:
- */
- void initDb(), addAppoint(), deleteAppoint();
- void addScheduleDow(), addSchedule(), deleteScheduleDow(), deleteSchedule();
- char *lookup(),*lookupAppoint(),*lookupScheduleDow(),*lookupSchedule();
- void readAppoints(), writeAppoints();
- static void parseApp(), parseSched();
- static char *expandFilename();
-
- /* - - - - - - - - */
-
- typedef struct _msgrec {
- int pos;
- char *text;
- struct _msgrec *next;
- } Msgrec;
- typedef struct _dayrec {
- int day;
- Msgrec *msgs;
- struct _dayrec *next;
- } Dayrec;
- typedef struct _monrec {
- int mon;
- Dayrec *days;
- struct _monrec *next;
- } Monrec;
- typedef struct _yearrec {
- int year;
- Monrec *mons;
- struct _yearrec *next;
- } Yearrec;
-
- static Yearrec *Db = NULL;
- static char *schedule[7][22];
-
- /* - - - - - - - - */
- /* Initialization (pretty lame) */
-
- void
- initDb()
- {
- int i,j;
-
- Db = NULL; /* should really free everything... */
- for (i=0; i < 7; i++)
- for (j=0; j < 22; j++)
- schedule[i][j] = NULL;
- }
-
- /* - - - - - - - - */
- /* Appointment routines */
-
- void
- addAppoint(pos,day,mon,year,text)
- int pos,day,mon,year;
- char *text;
- {
- Yearrec *yp;
- Monrec *mp;
- Dayrec *dp;
- Msgrec *xp;
-
- if (Db == NULL) {
- Db = XtNew(Yearrec);
- Db->year = year;
- Db->mons = NULL;
- Db->next = NULL;
- }
- for (yp = Db; yp->year != year && yp->next != NULL; yp = yp->next) ;
- if (yp->year != year) {
- yp->next = XtNew(Yearrec);
- yp->next->year = year;
- yp->next->mons = NULL;
- yp->next->next = NULL;
- yp = yp->next;
- }
- if (yp->mons == NULL) {
- yp->mons = XtNew(Monrec);
- yp->mons->mon = mon;
- yp->mons->days = NULL;
- yp->mons->next = NULL;
- }
- for (mp = yp->mons; mp->mon != mon && mp->next != NULL; mp = mp->next) ;
- if (mp->mon != mon) {
- mp->next = XtNew(Monrec);
- mp->next->mon = mon;
- mp->next->days = NULL;
- mp->next->next=NULL;
- mp = mp->next;
- }
-
- if (mp->days == NULL) {
- mp->days = XtNew(Dayrec);
- mp->days->day = day;
- mp->days->msgs = NULL;
- mp->days->next = NULL;
- }
- for (dp = mp->days; dp->day != day && dp->next != NULL; dp = dp->next) ;
- if (dp->day != day) {
- dp->next = XtNew(Dayrec);
- dp->next->day = day;
- dp->next->msgs = NULL;
- dp->next->next=NULL;
- dp = dp->next;
- }
-
- if (dp->msgs == NULL) {
- dp->msgs = XtNew(Msgrec);
- dp->msgs->pos = pos;
- dp->msgs->text = NULL;
- dp->msgs->next = NULL;
- }
- for (xp = dp->msgs; xp->pos != pos && xp->next != NULL; xp = xp->next) ;
- if (xp->pos != pos) {
- xp->next = XtNew(Msgrec);
- xp->next->pos = pos;
- xp->next->text = NULL;
- xp->next->next = NULL;
- xp = xp->next;
- }
- XtFree(xp->text);
- xp->text = XtNewString(text);
- }
-
- void
- deleteAppoint(pos,day,mon,year)
- int pos,day,mon,year;
- {
- Yearrec *yp,*yp2;
- Monrec *mp,*mp2;
- Dayrec *dp,*dp2;
- Msgrec *xp,*xp2;
-
- for (yp = Db; yp != NULL && yp->year != year; yp = yp->next) ;
- if (yp == NULL)
- return; /* error? */
-
- for (mp = yp->mons; mp != NULL && mp->mon != mon; mp = mp->next) ;
- if (mp == NULL)
- return; /* error? */
-
- for (dp = mp->days; dp != NULL && dp->day != day; dp = dp->next) ;
- if (dp == NULL)
- return; /* error? */
-
- for (xp = dp->msgs; xp != NULL && xp->pos != pos; xp = xp->next) ;
- if (xp == NULL)
- return; /* error? */
-
- /* Now free 'em up */
-
- XtFree(xp->text); /* free the text */
-
- if (dp->msgs == xp) /* and the msgrec */
- dp->msgs = xp->next;
- else {
- for (xp2 = dp->msgs; xp2->next != xp; xp2 = xp2->next) ;
- xp2->next = xp->next;
- }
- XtFree(xp);
-
- if (dp->msgs == NULL) { /* if no more entries, free the day */
- if (mp->days == dp)
- mp->days = dp->next;
- else {
- for (dp2 = mp->days; dp2->next != dp; dp2 = dp2->next) ;
- dp2->next = dp->next;
- }
- XtFree(dp);
- }
-
- if (mp->days == NULL) { /* if no more days, free the month */
- if (yp->mons == mp)
- yp->mons = mp->next;
- else {
- for (mp2 = yp->mons; mp2->next != mp; mp2 = mp2->next) ;
- mp2->next = mp->next;
- }
- XtFree(mp);
- }
-
- if (yp->mons == NULL) { /* if no more months, free the year */
- if (Db == yp)
- Db = NULL;
- else {
- for (yp2 = Db; yp2->next != yp; yp2 = yp2->next) ;
- yp2->next = yp->next;
- }
- XtFree(yp);
- }
- }
-
- /* - - - - - - - - */
- /* Schedule routines */
-
- void
- addScheduleDow(pos,dow,msg)
- int pos,dow;
- char *msg;
- {
- XtFree(schedule[dow][pos]);
- schedule[dow][pos] = XtNewString(msg);
- }
-
- void
- addSchedule(pos,day,mon,year,msg)
- int pos,day,mon,year;
- char *msg;
- {
- lookupScheduleDow(pos,computeDOW(day,mon,year),msg);
- }
-
- void
- deleteScheduleDow(pos,dow)
- int pos,dow;
- {
- XtFree(schedule[dow][pos]);
- schedule[dow][pos] = NULL;
- }
-
- void
- deleteSchedule(pos,day,mon,year)
- int pos,day,mon,year;
- {
- lookupScheduleDow(pos,computeDOW(day,mon,year));
- }
-
- /* - - - - - - - - */
- /* Lookup routines */
-
- char *
- lookup(pos,day,mon,year)
- {
- char *s;
-
- if ((s=lookupAppoint(pos,day,mon,year)) != NULL)
- return(s);
- else
- return(lookupSchedule(pos,day,mon,year));
- }
-
- char *
- lookupAppoint(pos,day,mon,year)
- int pos,day,mon,year;
- {
- Yearrec *yp;
- Monrec *mp;
- Dayrec *dp;
- Msgrec *xp;
-
- for (yp = Db; yp != NULL && yp->year != year; yp = yp->next) ;
- if (yp != NULL) {
- for (mp = yp->mons; mp != NULL && mp->mon != mon; mp = mp->next) ;
- if (mp != NULL) {
- for (dp = mp->days; dp != NULL && dp->day != day; dp = dp->next) ;
- if (dp != NULL) {
- for (xp = dp->msgs; xp != NULL && xp->pos != pos; xp = xp->next) ;
- if (xp != NULL)
- return(xp->text);
- }
- }
- }
- return(NULL);
- }
-
- char *
- lookupScheduleDow(pos,dow)
- int pos,dow;
- {
- return(schedule[dow][pos]);
- }
-
- char *
- lookupSchedule(pos,day,mon,year)
- int pos,day,mon,year;
- {
- return(lookupScheduleDow(pos,computeDOW(day,mon,year)));
- }
-
-
- /* - - - - - - - - */
- /* I/O routines */
-
- void
- readAppoints(name)
- char *name;
- {
- FILE *fp;
- char *fname,buf[256];
- int line,i,n,c;
-
- fname = expandFilename(name);
- if ((fp=fopen(fname,"r")) == NULL) {
- if (errno != ENOENT) /* appointment file may not exist */
- perror(fname);
- return;
- }
- line = 0;
- while (1) {
- n = 0;
- line += 1;
- while (n < 255 && (c=getc(fp)) != EOF && c != '\n')
- buf[n++] = c;
- buf[n] = '\0';
- if (n == 0)
- break;
- else if (c != EOF && c != '\n') {
- fprintf(stderr,"%s: line %d too long, file %s\n",program,
- line,fname);
- while ((c=getc(fp)) != EOF && c != '\n') ;
- }
- for (i=0; isspace(buf[i]) && i < n; i++) ;
- if (buf[i] == '#')
- continue;
- else if (isdigit(buf[i]))
- parseApp(buf,line,fname);
- else
- parseSched(buf,line,fname);
- }
- fclose(fp);
- }
-
- static void
- parseApp(buf,line,fname)
- char *buf;
- int line;
- char *fname;
- {
- int d,m,y,h,h2,pos;
- char mstr[4],msg[256];
-
- if (sscanf(buf,"%d %3s %d %d:%d %256[^\n]",&d,mstr,&y,&h,&h2,msg) != 6) {
- fprintf(stderr,"%s: file \"%s\", line %d: invalid appointment: %s\n",
- program,fname,line,buf);
- return;
- }
- if (islower(mstr[0]))
- mstr[0] = toupper(mstr[0]);
- for (m=0; m < 12; m++)
- if (strncmp(shortMonStr[m],mstr,3) == 0)
- break;
- if (m == 12) {
- fprintf(stderr,"%s: file \"%s\", line %d: invalid month: %s\n",
- program,fname,line,mstr);
- return;
- }
- if (h2 < 30)
- pos = (h-8)*2;
- else
- pos = (h-8)*2+1;
- addAppoint(pos,d,m,y-1900,msg);
- }
-
- static void
- parseSched(buf,line,fname)
- char *buf;
- int line;
- char *fname;
- {
- int d,h,h2,pos;
- char dowstr[4],msg[256];
-
- if (sscanf(buf,"%3s %d:%d %256[^\n]",dowstr,&h,&h2,msg) != 4) {
- fprintf(stderr,"%s: file \"%s\", line %d: invalid schedule entry: %s\n",
- program,fname,line,buf);
- return;
- }
- if (islower(dowstr[0]))
- dowstr[0] = toupper(dowstr[0]);
- for (d=0; d<7; d++)
- if (strcmp(dowstr,shortDayStr[d]) == 0)
- break;
- if (d == 7) {
- fprintf(stderr,"%s: file \"%s\", line %d: invalid day-of-week: %s\n",
- program,fname,line,dowstr);
- return;
- }
- if (h2 < 30)
- pos = (h-8)*2;
- else
- pos = (h-8)*2+1;
- addScheduleDow(pos,d,msg);
- }
-
- void
- writeAppoints(name)
- char *name;
- {
- FILE *fp;
- char *fname;
- Yearrec *yp;
- Monrec *mp;
- Dayrec *dp;
- Msgrec *xp;
- int h,h2,i,d;
-
- fname = expandFilename(name);
- if ((fp=fopen(fname,"w")) == NULL) {
- perror(fname);
- return;
- }
- for (d=0; d < 7; d++)
- for (i=0; i < 22; i++)
- if (schedule[d][i] != NULL)
- fprintf(fp,"%3s %2d:%02d %s\n",shortDayStr[d],i/2+8,i%2*30,
- schedule[d][i]);
- for (yp = Db; yp != NULL; yp = yp->next)
- for (mp = yp->mons; mp != NULL; mp = mp->next)
- for (dp = mp->days; dp != NULL; dp = dp->next)
- for (xp = dp->msgs; xp != NULL; xp = xp->next) {
- h = 8+(xp->pos / 2);
- h2 = (xp->pos % 2)*30;
- fprintf(fp,"%2d %3.3s %4d %2d:%02d %s\n",
- dp->day,shortMonStr[mp->mon],
- 1900+yp->year,
- h,h2,xp->text);
- }
- fclose(fp);
- }
-
- static char filename[1024];
-
- static char *
- expandFilename(name)
- char *name;
- {
- char *s;
-
- if (*name == '~') {
- if ((s=getenv("HOME")) == NULL) {
- printf("%s: can't expand ~ to $HOME\n",program);
- return;
- } else {
- strcpy(filename,s);
- strcat(filename,name+1);
- }
- } else {
- strcpy(filename,name);
- }
- return(filename);
- }
-