home *** CD-ROM | disk | FTP | other *** search
- /*
- * db.c : Database routines for xarchie
- *
- * The functions in this file provide two distinct but related services.
- * First, they implement a hierarchical host/location/file database that
- * is used to store the results of the Prospero query. This database is
- * implemented as a hierarchical set of doubly-linked lists, with each
- * record containing information about the host/location/file and a
- * pointer to its list of sub-records. See "db.h" for details. Secondly,
- * these routines implement the mapping from the database to the browser
- * lists. That is, there are functions that, given a host/location/file
- * record, display its contents and the appropriate sub-records' contents
- * in the browser panes.
- *
- * George Ferguson, ferguson@cs.rochester.edu, 4 Sep 1991.
- *
- */
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/Cardinals.h>
- #include <X11/Xaw/List.h>
- #include "xarchie.h"
- #include "db.h"
- #include "alert.h"
-
- /*
- * Functions defined here:
- */
- Database *newDb();
- void clearDb();
- HostEntry *addHost(), *lastHostEntry(), *findHostEntryFromString();
- HostEntry *findHostEntryFromIndex();
- LocEntry *addLoc(), *lastLocEntry(), *findLocEntryFromString();
- LocEntry *findLocEntryFromIndex();
- FileEntry *addFile(), *lastFileEntry(), *findFileEntryFromString();
- FileEntry *findFileEntryFromIndex();
- int findHostIndexFromEntry();
- int findLocIndexFromEntry();
- int findFileIndexFromEntry();
- void displayHosts(), displayLocs(), displayFiles();
- void setHostString(), setLocString(), setFileString();
- void setHostListFromStrings();
- void setLocListFromStrings();
- void setFileListFromStrings();
- void clearList();
-
- /*
- * Data defined here:
- */
- /*
- * These correspond to the highlighted items in the List widgets
- */
- HostEntry *selectedHostEntry;
- LocEntry *selectedLocEntry;
- FileEntry *selectedFileEntry;
- /*
- * These string arrays are needed since the only way to set a List
- * widget in X is to pass it an array of strings. That is, there's
- * no way to add items incrementally. Blech. Still, the arrays are
- * grown as needed, so these values can be way off, as they are.
- */
- #define INIT_NUM_HOST_STRINGS 1
- #define INIT_NUM_LOC_STRINGS 1
- #define INIT_NUM_FILE_STRINGS 1
- /* The arrays double in size as they grow */
- #define REALLOC_INCR(num) (2*(num))
-
- static char **hostStrings,**locStrings,**fileStrings;
- static int numHostStrings,numLocStrings,numFileStrings;
-
- /* - - - - - - - - */
-
- Database *
- newDb()
- {
- Database *db;
-
- db = XtNew(Database);
- db->hostEntries = NULL;
- return(db);
- }
-
- void
- clearDb(dbp)
- Database *dbp;
- {
- HostEntry *hostp,*nexthostp;
- LocEntry *locp,*nextlocp;
- FileEntry *filep,*nextfilep;
-
- if (dbp == DB_NULL) {
- alert0("DB error: attempt to clear NULL database\n");
- return;
- }
- for (hostp=dbp->hostEntries; hostp != HOST_NULL; hostp=nexthostp) {
- nexthostp = hostp->next;
- for (locp=hostp->locEntries; locp != LOC_NULL; locp=nextlocp) {
- nextlocp = locp->next;
- for (filep=locp->fileEntries; filep != FILE_NULL;
- filep=nextfilep) {
- nextfilep = filep->next;
- XtFree(filep->name);
- XtFree(filep);
- }
- XtFree(locp->linkpath);
- XtFree(locp);
- }
- XtFree(hostp->hostname);
- XtFree(hostp);
- }
- dbp->hostEntries = HOST_NULL;
- }
-
- /* - - - - - - - - */
-
- HostEntry *
- addHostEntry(hostname,dbp,before)
- char *hostname;
- Database *dbp;
- HostEntry *before;
- {
- HostEntry *hp,*last;
-
- hp = XtNew(HostEntry);
- hp->hostname = (char *)NULL;
- hp->locEntries = LOC_NULL;
- hp->next = hp->prev = HOST_NULL;
- if (dbp == DB_NULL) {
- alert1("DB error: attempt to add host \"%.180s\" to NULL database",
- hostname);
- return(HOST_NULL);
- } else if (dbp->hostEntries == HOST_NULL) {
- dbp->hostEntries = hp;
- hp->prev = hp->next = HOST_NULL;
- } else if (before == HOST_NULL) {
- last = lastHostEntry(dbp);
- last->next = hp;
- hp->prev = last;
- hp->next = HOST_NULL;
- } else {
- if (before->prev == HOST_NULL)
- dbp->hostEntries = hp;
- else
- before->prev->next = hp;
- hp->prev = before->prev;
- hp->next = before;
- before->prev = hp;
- }
- hp->hostname = XtNewString(hostname);
- return(hp);
- }
-
- HostEntry *
- lastHostEntry(dbp)
- Database *dbp;
- {
- HostEntry *hp;
-
- if (dbp == DB_NULL) {
- alert0("DB error: attempt to find last host of NULL database\n");
- return(HOST_NULL);
- } else if (dbp->hostEntries == HOST_NULL)
- return(HOST_NULL);
- for (hp=dbp->hostEntries; hp->next != HOST_NULL; hp=hp->next)
- /* EMPTY */ ;
- return(hp);
- }
-
- HostEntry *
- findHostEntryFromString(hostname,dbp)
- char *hostname;
- Database *dbp;
- {
- HostEntry *hp;
-
- if (dbp == DB_NULL) {
- alert1("DB error: attempt to find host \"%.180s\" in NULL database",
- hostname);
- return(HOST_NULL);
- }
- for (hp=dbp->hostEntries; hp != HOST_NULL &&
- strcmp(hp->hostname,hostname) != 0; hp=hp->next)
- /* EMPTY */ ;
- return(hp);
- }
-
- HostEntry *
- findHostEntryFromIndex(index,dbp)
- int index;
- Database *dbp;
- {
- HostEntry *hp;
-
- if (dbp == DB_NULL) {
- alert1("DB error: attempt to find host index %d in NULL database",
- index);
- return(HOST_NULL);
- }
- for (hp=dbp->hostEntries; hp != HOST_NULL && index--; hp=hp->next)
- /* EMPTY */ ;
- return(hp);
- }
-
- int
- findHostIndexFromEntry(hp)
- HostEntry *hp;
- {
- int i;
-
- for (i=0; i < numHostStrings && *(hostStrings+i) != (char*)NULL; i++)
- if (strcmp(hp->hostname,*(hostStrings+i)) == 0)
- return(i);
- return(-1);
- }
-
-
- /* - - - - - - - - */
-
- LocEntry *
- addLocEntry(linkpath,hostp,before)
- char *linkpath;
- HostEntry *hostp;
- LocEntry *before;
- {
- LocEntry *lp,*last;
-
- lp = XtNew(LocEntry);
- lp->linkpath = (char *)NULL;
- lp->fileEntries = FILE_NULL;
- lp->next = lp->prev = LOC_NULL;
- if (hostp == HOST_NULL) {
- alert1("DB error: attempt to add location \"%.180s\" to NULL host",
- linkpath);
- return(LOC_NULL);
- } else if (hostp->locEntries == LOC_NULL) {
- hostp->locEntries = lp;
- lp->prev = lp->next = LOC_NULL;
- } else if (before == LOC_NULL) {
- last = lastLocEntry(hostp);
- last->next = lp;
- lp->prev = last;
- lp->next = LOC_NULL;
- } else {
- if (before->prev == LOC_NULL)
- hostp->locEntries = lp;
- else
- before->prev->next = lp;
- lp->prev = before->prev;
- lp->next = before;
- before->prev = lp;
- }
- lp->linkpath = XtNewString(linkpath);
- return(lp);
- }
-
- LocEntry *
- lastLocEntry(locp)
- HostEntry *locp;
- {
- LocEntry *lp;
-
- if (locp == HOST_NULL) {
- alert0("DB error: attempt to find last location of NULL host\n");
- return LOC_NULL;
- } else if (locp->locEntries == LOC_NULL)
- return(LOC_NULL);
- for (lp=locp->locEntries; lp->next != LOC_NULL; lp=lp->next)
- /* EMPTY */ ;
- return(lp);
- }
-
- LocEntry *
- findLocEntryFromString(linkpath,hostp)
- char *linkpath;
- HostEntry *hostp;
- {
- LocEntry *lp;
-
- if (hostp == HOST_NULL) {
- alert1("DB error: attempt to find loc \"%.180s\" in NULL host",
- linkpath);
- return(LOC_NULL);
- }
- for (lp=hostp->locEntries; lp != LOC_NULL &&
- strcmp(lp->linkpath,linkpath) != 0; lp=lp->next)
- /* EMPTY */ ;
- return(lp);
- }
-
- LocEntry *
- findLocEntryFromIndex(index,hostp)
- int index;
- HostEntry *hostp;
- {
- LocEntry *lp;
-
- if (hostp == HOST_NULL) {
- alert1("DB error: attempt to find loc index %d in NULL host",
- index);
- return(LOC_NULL);
- }
- for (lp=hostp->locEntries; lp != LOC_NULL && index--; lp=lp->next)
- /* EMPTY */ ;
- return(lp);
- }
-
- int
- findLocIndexFromEntry(lp)
- LocEntry *lp;
- {
- int i;
-
- for (i=0; i < numLocStrings && *(locStrings+i) != (char *)NULL; i++)
- if (strcmp(lp->linkpath,*(locStrings+i)) == 0)
- return(i);
- return(-1);
- }
-
- /* - - - - - - - - */
-
- FileEntry *
- addFileEntry(name,size,modes,date,locp,before)
- char *name;
- int size;
- char *modes,*date;
- LocEntry *locp;
- FileEntry *before;
- {
- FileEntry *fp,*last;
-
- fp = XtNew(FileEntry);
- fp->name = (char *)NULL;
- fp->next = fp->prev = FILE_NULL;
- if (locp == LOC_NULL) {
- alert1("DB error: attempt to add file \"%.180s\" to NULL location",
- name);
- return(FILE_NULL);
- } else if (locp->fileEntries == FILE_NULL) {
- locp->fileEntries = fp;
- fp->prev = fp->next = FILE_NULL;
- } else if (before == FILE_NULL) {
- last = lastFileEntry(locp);
- last->next = fp;
- fp->prev = last;
- fp->next = FILE_NULL;
- } else {
- if (before->prev == FILE_NULL)
- locp->fileEntries = fp;
- else
- before->prev->next = fp;
- fp->prev = before->prev;
- fp->next = before;
- before->prev = fp;
- }
- fp->name = XtNewString(name);
- fp->size = size;
- strncpy(fp->modes,modes,15);
- strncpy(fp->date,date,15);
- return(fp);
- }
-
- FileEntry *
- lastFileEntry(locp)
- LocEntry *locp;
- {
- FileEntry *fp;
-
- if (locp == LOC_NULL) {
- alert0("DB error: attempt to find last file of NULL location\n");
- return FILE_NULL;
- } else if (locp->fileEntries == FILE_NULL)
- return(FILE_NULL);
- for (fp=locp->fileEntries; fp->next != FILE_NULL; fp=fp->next)
- /* EMPTY */ ;
- return(fp);
- }
-
- FileEntry *
- findFileEntryFromString(name,locp)
- char *name;
- LocEntry *locp;
- {
- FileEntry *fp;
-
- if (locp == LOC_NULL) {
- alert1("DB error: attempt to find file \"%.180s\" in NULL location",
- name);
- return(FILE_NULL);
- }
- for (fp=locp->fileEntries; fp != FILE_NULL &&
- strcmp(fp->name,name) != 0; fp=fp->next)
- /* EMPTY */ ;
- return(fp);
- }
-
- FileEntry *
- findFileEntryFromIndex(index,locp)
- int index;
- LocEntry *locp;
- {
- FileEntry *fp;
-
- if (locp == LOC_NULL) {
- alert1("DB error: attempt to find file index %d in NULL location",
- index);
- return(FILE_NULL);
- }
- for (fp=locp->fileEntries; fp != FILE_NULL && index--; fp=fp->next)
- /* EMPTY */ ;
- return(fp);
- }
-
- int
- findFileIndexFromEntry(fp)
- FileEntry *fp;
- {
- int i;
-
- for (i=0; i < numFileStrings && *(fileStrings+i) != (char *)NULL; i++)
- if (strcmp(fp->name,*(fileStrings+i)) == 0)
- return(i);
- return(-1);
- }
-
- /* - - - - - - - - */
-
- void
- displayHosts(dbp)
- Database *dbp;
- {
- HostEntry *hp;
- int i;
-
- if (dbp == DB_NULL) {
- alert0("DB error: attempt to display hosts from NULL database\n");
- return;
- }
- clearList(hostList);
- clearList(locationList);
- clearList(fileList);
- i = 0;
- for (hp=dbp->hostEntries; hp != NULL; hp=hp->next)
- setHostString(i++,hp->hostname);
- setHostString(i,(char *)NULL);
- if (i > 0)
- setHostListFromStrings();
- if (i == 1) {
- XawListHighlight(hostList,0);
- selectedHostEntry = dbp->hostEntries;
- displayHostInfo(selectedHostEntry);
- displayLocs(selectedHostEntry);
- } else {
- selectedHostEntry = HOST_NULL;
- clearHostInfo();
- selectedLocEntry = LOC_NULL;
- clearLocationInfo();
- selectedFileEntry = FILE_NULL;
- clearFileInfo();
- }
- }
-
- void
- displayLocs(hostp)
- HostEntry *hostp;
- {
- LocEntry *lp;
- int i;
-
- if (hostp == HOST_NULL) {
- alert0("DB error: attempt to display locations from NULL host\n");
- return;
- }
- clearList(locationList);
- clearList(fileList);
- i = 0;
- for (lp=hostp->locEntries; lp != LOC_NULL; lp=lp->next)
- setLocString(i++,lp->linkpath);
- setLocString(i,(char *)NULL);
- if (i > 0)
- setLocListFromStrings();
- if (i == 1) {
- XawListHighlight(locationList,0);
- selectedLocEntry = hostp->locEntries;
- displayLocationInfo(selectedLocEntry);
- displayFiles(selectedLocEntry);
- } else {
- selectedLocEntry = LOC_NULL;
- clearLocationInfo();
- selectedFileEntry = FILE_NULL;
- clearFileInfo();
- }
- }
-
- void
- displayFiles(locp)
- LocEntry *locp;
- {
- FileEntry *fp;
- int i;
-
- if (locp == LOC_NULL) {
- alert0("DB error: attempt to display files from NULL location\n");
- return;
- }
- clearList(fileList);
- i = 0;
- for (fp=locp->fileEntries; fp != FILE_NULL; fp=fp->next)
- setFileString(i++,fp->name);
- setFileString(i,(char *)NULL);
- if (i > 0)
- setFileListFromStrings();
- if (i == 1) {
- XawListHighlight(fileList,0);
- selectedFileEntry = locp->fileEntries;
- displayFileInfo(selectedFileEntry);
- } else {
- selectedFileEntry = FILE_NULL;
- clearFileInfo();
- }
- }
-
- /* - - - - - - - - */
- /* These routines provide access to the dynamically-grown lists
- * of strings. I bzero() the allocated space even though I shouldn't
- * to.
- */
-
- void
- setHostString(i,s)
- int i;
- char *s;
- {
- char **oldStr;
- int oldNum;
-
- /* Free old string if there was one */
- if (i < numHostStrings)
- XtFree(*(hostStrings+i));
- /* If this is the first call, get the initial string array */
- if (numHostStrings == 0) {
- numHostStrings = INIT_NUM_HOST_STRINGS;
- hostStrings = (char **)XtCalloc(numHostStrings,sizeof(char *));
- bzero(hostStrings,numHostStrings*sizeof(char *));
- }
- /* Grow the array until it's big enough for this string */
- while (i >= numHostStrings) {
- oldStr = hostStrings;
- oldNum = numHostStrings;
- numHostStrings = REALLOC_INCR(numHostStrings);
- hostStrings = (char **)XtCalloc(numHostStrings,sizeof(char *));
- bzero(hostStrings,numHostStrings*sizeof(char *));
- bcopy(oldStr,hostStrings,oldNum*sizeof(char *));
- XtFree(oldStr);
- }
- /* Finally, set this value */
- if (s == (char *)NULL)
- *(hostStrings+i) = (char *)NULL;
- else
- *(hostStrings+i) = XtNewString(s);
- }
-
- void
- setLocString(i,s)
- int i;
- char *s;
- {
- char **oldStr;
- int oldNum;
-
- /* Free old string if there was one */
- if (i < numLocStrings)
- XtFree(*(locStrings+i));
- /* If this is the first call, get the initial string array */
- if (numLocStrings == 0) {
- numLocStrings = INIT_NUM_LOC_STRINGS;
- locStrings = (char **)XtCalloc(numLocStrings,sizeof(char *));
- bzero(locStrings,numLocStrings*sizeof(char *));
- }
- /* Grow the array until it's big enough for this string */
- while (i >= numLocStrings) {
- oldStr = locStrings;
- oldNum = numLocStrings;
- numLocStrings = REALLOC_INCR(numLocStrings);
- locStrings = (char **)XtCalloc(numLocStrings,sizeof(char *));
- bzero(locStrings,numLocStrings*sizeof(char *));
- bcopy(oldStr,locStrings,oldNum*sizeof(char *));
- XtFree(oldStr);
- }
- /* Finally, set this value */
- if (s == (char *)NULL)
- *(locStrings+i) = (char *)NULL;
- else
- *(locStrings+i) = XtNewString(s);
- }
-
- void
- setFileString(i,s)
- int i;
- char *s;
- {
- char **oldStr;
- int oldNum;
-
- /* Free old string if there was one */
- if (i < numFileStrings)
- XtFree(*(fileStrings+i));
- /* If this is the first call, get the initial string array */
- if (numFileStrings == 0) {
- numFileStrings = INIT_NUM_FILE_STRINGS;
- fileStrings = (char **)XtCalloc(numFileStrings,sizeof(char *));
- bzero(fileStrings,numFileStrings*sizeof(char *));
- }
- /* Grow the array until it's big enough for this string */
- while (i >= numFileStrings) {
- oldStr = fileStrings;
- oldNum = numFileStrings;
- numFileStrings = REALLOC_INCR(numFileStrings);
- fileStrings = (char **)XtCalloc(numFileStrings,sizeof(char *));
- bzero(fileStrings,numFileStrings*sizeof(char *));
- bcopy(oldStr,fileStrings,oldNum*sizeof(char *));
- XtFree(oldStr);
- }
- /* Finally, set this value */
- if (s == (char *)NULL)
- *(fileStrings+i) = (char *)NULL;
- else
- *(fileStrings+i) = XtNewString(s);
- }
-
- /* - - - - - - - - */
- /* These routines connect the arrays of strings to the list widgets. */
-
- void
- setHostListFromStrings()
- {
- XawListChange(hostList,hostStrings,0,0,True);
- }
-
- void
- setLocListFromStrings()
- {
- XawListChange(locationList,locStrings,0,0,True);
- }
-
- void
- setFileListFromStrings()
- {
- XawListChange(fileList,fileStrings,0,0,True);
- }
-
- static char *emptyNames[] = { NULL };
-
- void clearList(w)
- Widget w;
- {
- XawListChange(w,emptyNames,0,0,False);
- }
-