home *** CD-ROM | disk | FTP | other *** search
- /*
- * db.c : Database routines for xarchie
- *
- * George Ferguson, ferguson@cs.rochester.edu, 2 Nov 1991.
- * Version 2.0: 23 Apr 1993.
- */
-
- #include <stdio.h>
- #include "db.h"
- #include "weight.h"
- #include "stringdefs.h"
- #include "debug.h"
-
- #ifdef XARCHIE
- # include <X11/Intrinsic.h>
- #else /*!XARCHIE*/
- # include "xtypes.h"
- #endif
-
- /*
- * Functions defined here:
- */
- DbEntry *newEntry();
- void clearEntries();
- DbEntry *addEntry();
- DbEntry *lastEntry();
- DbEntry *findEntryFromString();
- DbEntry *findEntryFromIndex();
- int findIndexFromEntry();
- void setEntryData(), freeEntryData();
- void sortEntriesRecursively(), sortEntries();
- int cmpEntryNames(), cmpEntryDates(), cmpEntryWeights();
-
- static void clearEntriesInternal();
- static char *entryDate(),*hostDate(),*locationDate();
-
- /* - - - - - - - - */
-
- DbEntry *
- newEntry()
- {
- DbEntry *new;
-
- new = XtNew(DbEntry);
- new->name = NULL;
- new->type = DB_NOTYPE;
- new->size = -1;
- new->modes = "";
- new->date = "";
- new->gt_date = "";
- new->vlink = NULL;
- new->selected = -1;
- new->entries = NULL;
- new->next = new->prev = new->parent = NULL;
- return(new);
- }
-
- void
- clearEntries(dbp)
- DbEntry *dbp;
- {
- if (dbp == NULL) {
- fprintf(stderr,"DB Error: Attempt to clear NULL list\n");
- return;
- } else {
- clearEntriesInternal(dbp->entries);
- dbp->entries = NULL;
- }
- }
-
- static void
- clearEntriesInternal(dbp)
- DbEntry *dbp;
- {
- DbEntry *t;
-
- while (dbp != NULL) {
- clearEntriesInternal(dbp->entries);
- freeEntryData(dbp);
- t = dbp;
- dbp = dbp->next;
- XtFree((char *)t);
- }
- }
-
- /* - - - - - - - - */
-
- DbEntry *
- addEntry(parent,before)
- DbEntry *parent;
- DbEntry *before;
- {
- DbEntry *new,*last;
-
- DEBUG2("adding entry to 0x%x before 0x%x\n",parent,before);
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to add entry to NULL list\n");
- return(NULL);
- } else if (parent->entries == NULL) {
- /* No items already in list */
- DEBUG0(" inserting as new list\n");
- new = XtNew(DbEntry);
- DEBUG1(" new entry is 0x%x\n",new);
- parent->entries = new;
- new->prev = NULL;
- new->next = NULL;
- } else if (before == NULL) {
- /* Insert at end of list */
- DEBUG0(" inserting at end of list\n");
- last = lastEntry(parent);
- new = XtNew(DbEntry);
- DEBUG1(" new entry is 0x%x\n",new);
- last->next = new;
- new->prev = last;
- new->next = NULL;
- } else if (before->prev == NULL) {
- /* Insert at head of list */
- DEBUG0(" inserting at head of list\n");
- new = XtNew(DbEntry);
- DEBUG1(" new entry is 0x%x\n",new);
- parent->entries = new;
- new->prev = NULL;
- new->next = before;
- before->prev = new;
- } else {
- /* Insert somewhere in the middle of list */
- DEBUG0(" inserting in middle of list\n");
- new = XtNew(DbEntry);
- DEBUG1(" new entry is 0x%x\n",new);
- before->prev->next = new;
- new->prev = before->prev;
- new->next = before;
- before->prev = new;
- }
- new->parent = parent;
- new->entries = NULL;
- new->name = NULL;
- new->type = DB_NOTYPE;
- new->size = -1;
- new->modes = "";
- new->date = "";
- new->gt_date = "";
- new->vlink = NULL;
- DEBUG0(" done adding new entry\n");
- return(new);
- }
-
- DbEntry *
- lastEntry(parent)
- DbEntry *parent;
- {
- DbEntry *dbp;
-
- DEBUG1("finding last entry in entries for 0x%x\n",parent);
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to find last entry of NULL list\n");
- return(NULL);
- } else if (parent->entries == NULL) {
- DEBUG1("no entries for 0x%x, returning NULL\n",parent);
- return(NULL);
- } else {
- for (dbp=parent->entries; dbp->next != NULL; dbp=dbp->next)
- /* EMPTY */ ;
- DEBUG2("last entry for 0x%x is 0x%x\n",parent,dbp);
- return(dbp);
- }
- }
-
- DbEntry *
- findEntryFromString(parent,string)
- DbEntry *parent;
- char *string;
- {
- DbEntry *dbp;
-
- DEBUG2("finding entry \"%s\" in entries for 0x%x\n",string,parent);
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to find \"%s\" in NULL list",string);
- return(NULL);
- } else {
- for (dbp=parent->entries; dbp != NULL &&
- strcmp(dbp->name,string) != 0; dbp=dbp->next)
- /* EMPTY */ ;
- DEBUG1(" find returning 0x%x\n",dbp);
- return(dbp);
- }
- }
-
- DbEntry *
- findEntryFromIndex(parent,index)
- DbEntry *parent;
- int index;
- {
- DbEntry *dbp;
-
- DEBUG2("finding entry with index %d in entries for 0x%x\n",index,parent);
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to find index %d in NULL list",index);
- return(NULL);
- } else {
- for (dbp=parent->entries; dbp != NULL && index--; dbp=dbp->next)
- /* EMPTY */ ;
- DEBUG1(" find returning 0x%x\n",dbp);
- return(dbp);
- }
- }
-
- int
- findIndexFromEntry(parent,entry)
- DbEntry *parent,*entry;
- {
- DbEntry *dbp;
- int index;
-
- DEBUG2("finding index for entry 0x%x in entries for 0x%x\n",entry,parent);
- index = 0;
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to find entry 0x%x in NULL list",entry);
- return(0);
- } else {
- for (dbp=parent->entries; dbp != NULL; dbp=dbp->next) {
- if (strcmp(entry->name,dbp->name) == 0) {
- DEBUG1(" return index %d\n",index);
- return(index);
- }
- index += 1;
- }
- }
- return(-1);
- }
-
- /* - - - - - - - - */
- /*
- * Allocate and set the data for the given DbEntry.
- */
- void
- setEntryData(dbp,name,type,size,modes,date,gt_date,vlink)
- DbEntry *dbp;
- char *name;
- int type;
- int size;
- char *modes,*date,*gt_date;
- VLINK vlink;
- {
- XtFree(dbp->name);
- dbp->name = XtNewString(name);
- dbp->type = type;
- dbp->size = size;
- dbp->modes = XtNewString(modes);
- dbp->date = XtNewString(date);
- dbp->gt_date = XtNewString(gt_date);
- dbp->vlink = vlink;
- DEBUG2("set data for entry 0x%x, name=\"%s\"\n",dbp,dbp->name);
- }
-
- /*
- * Free up anything associated with the given DbEntry.
- */
- void
- freeEntryData(dbp)
- DbEntry *dbp;
- {
- XtFree((char *)(dbp->name));
- if (dbp->vlink)
- vlfree(dbp->vlink);
- }
-
- /* - - - - - - - - */
- /*
- * Sorts entries of parent and then calls itself on each of them.
- */
- void
- sortEntriesRecursively(parent,cmp_proc)
- DbEntry *parent;
- int (*cmp_proc)();
- {
- DbEntry *dbp;
-
- if (parent == NULL || cmp_proc == NULL)
- return;
- DEBUG1(" sorting entries recursively for 0x%x\n",parent);
- sortEntries(parent,cmp_proc);
- for (dbp=parent->entries; dbp != NULL; dbp = dbp->next)
- sortEntriesRecursively(dbp->entries,cmp_proc);
- DEBUG1(" done sorting entries recursively for 0x%x\n",parent);
- }
-
- /*
- * Sorts entries of parent using a selection sort and the given cmp_proc.
- */
- void
- sortEntries(parent,cmp_proc)
- DbEntry *parent;
- int (*cmp_proc)();
- {
- DbEntry *p,*nextp,*lowest,*q,*pnext,*pprev;
-
- DEBUG1(" sorting entries for 0x%x\n",parent);
- for (p = parent->entries; p != NULL; p = nextp) {
- nextp = p->next;
- lowest = p;
- for (q = p->next; q != NULL; q = q->next)
- if ((*cmp_proc)(q,lowest) < 0)
- lowest = q;
- if (p != lowest) {
- /* swap the two links */
- pnext = p->next;
- pprev = p->prev;
- if (lowest->next != NULL)
- lowest->next->prev = p;
- p->next = lowest->next;
- if (nextp == lowest) {
- p->prev = lowest;
- } else {
- lowest->prev->next = p;
- p->prev = lowest->prev;
- }
- if (nextp == lowest) {
- lowest->next = p;
- } else {
- pnext->prev = lowest;
- lowest->next = pnext;
- }
- if (pprev != NULL)
- pprev->next = lowest;
- lowest->prev = pprev;
- /* keep the head of the list in the right place */
- if (parent->entries == p)
- parent->entries = lowest;
- }
- }
- DEBUG1(" done sorting entries for 0x%x\n",parent);
- }
-
- /*
- * cmpEntryNames(p,q) : Compare entries by name. Returns < 0 if p belongs
- * before q, > 0 if q belongs before p, and == 0 if names are identical.
- */
- int
- cmpEntryNames(p,q)
- DbEntry *p,*q;
- {
- return(strcmp(p->name,q->name));
- }
-
- /*
- * cmpEntryDates(p,q) : Compare entries by date. If the dates are the same
- * or both entries don't have a date, then compare by name.
- *
- * To make this useful, I've made it sort hosts and locations by the
- * newest thing in them. To make it faster, it caches the computed date
- * in the otherwise unused date field.
- */
- int
- cmpEntryDates(p,q)
- DbEntry *p,*q;
- {
- int result;
-
- if (!*(p->gt_date))
- p->gt_date = entryDate(p);
- if (!*(q->gt_date))
- q->gt_date = entryDate(q);
- if ((result=strcmp(q->gt_date,p->gt_date)) != 0) /* note order! */
- return(result);
- else
- return(cmpEntryNames(p,q));
- }
-
- static char *
- entryDate(dbp)
- DbEntry *dbp;
- {
- if (dbp->type == DB_HOST)
- return(hostDate(dbp));
- else if (dbp->type == DB_LOCATION)
- return(locationDate(dbp));
- else
- return(dbp->gt_date);
- }
-
- /*
- * Returns the date of the newest (biggest date) location in the host.
- */
- static char *
- hostDate(dbp)
- DbEntry *dbp;
- {
- DbEntry *loc;
- char *date = "";
- char *locdate;
-
- for (loc=dbp->entries; loc != NULL; loc=loc->next) {
- locdate = locationDate(loc);
- if (!*date || strcmp(date,locdate) < 0)
- date = locdate;
- }
- return(date);
- }
-
- /*
- * Returns the date of the newest (biggest date) entry in the location.
- */
- static char *
- locationDate(dbp)
- DbEntry *dbp;
- {
- DbEntry *file;
- char *date = "";
-
- for (file=dbp->entries; file != NULL; file=file->next) {
- if (!*date || strcmp(date,file->gt_date) < 0)
- date = file->gt_date;
- }
- return(date);
- }
-
- /*
- * cmpEntryWeights(p,q) : Compare entries by user-defined "weights".
- */
- int
- cmpEntryWeights(p,q)
- DbEntry *p,*q;
- {
- int result;
-
- if ((result=hostWeight(p->name)-hostWeight(q->name)) != 0)
- return(result);
- else
- return(cmpEntryNames(p,q));
- }
-