home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE2.TAR / db.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  15.1 KB  |  658 lines

  1. /*
  2.  * db.c : Database routines for xarchie
  3.  *
  4.  * The functions in this file provide two distinct but related services.
  5.  * First, they implement a hierarchical host/location/file database that
  6.  * is used to store the results of the Prospero query. This database is
  7.  * implemented as a hierarchical set of doubly-linked lists, with each
  8.  * record containing information about the host/location/file and a
  9.  * pointer to its list of sub-records. See "db.h" for details. Secondly,
  10.  * these routines implement the mapping from the database to the browser
  11.  * lists. That is, there are functions that, given a host/location/file
  12.  * record, display its contents and the appropriate sub-records' contents
  13.  * in the browser panes.
  14.  *
  15.  * George Ferguson, ferguson@cs.rochester.edu, 4 Sep 1991.
  16.  *
  17.  */
  18. #include <X11/Intrinsic.h>
  19. #include <X11/StringDefs.h>
  20. #include <X11/Xaw/Cardinals.h>
  21. #include <X11/Xaw/List.h>
  22. #include "xarchie.h"
  23. #include "db.h"
  24. #include "alert.h"
  25.  
  26. /*
  27.  * Functions defined here:
  28.  */
  29. Database *newDb();
  30. void clearDb();
  31. HostEntry *addHost(), *lastHostEntry(), *findHostEntryFromString();
  32. HostEntry *findHostEntryFromIndex();
  33. LocEntry *addLoc(), *lastLocEntry(), *findLocEntryFromString();
  34. LocEntry *findLocEntryFromIndex();
  35. FileEntry *addFile(), *lastFileEntry(), *findFileEntryFromString();
  36. FileEntry *findFileEntryFromIndex();
  37. int findHostIndexFromEntry();
  38. int findLocIndexFromEntry();
  39. int findFileIndexFromEntry();
  40. void displayHosts(), displayLocs(), displayFiles();
  41. void setHostString(), setLocString(), setFileString();
  42. void setHostListFromStrings();
  43. void setLocListFromStrings();
  44. void setFileListFromStrings();
  45. void clearList();
  46.  
  47. /*
  48.  * Data defined here:
  49.  */
  50. /*
  51.  * These correspond to the highlighted items in the List widgets
  52.  */
  53. HostEntry *selectedHostEntry;
  54. LocEntry *selectedLocEntry;
  55. FileEntry *selectedFileEntry;
  56. /*
  57.  * These string arrays are needed since the only way to set a List
  58.  * widget in X is to pass it an array of strings. That is, there's
  59.  * no way to add items incrementally. Blech. Still, the arrays are
  60.  * grown as needed, so these values can be way off, as they are.
  61.  */
  62. #define INIT_NUM_HOST_STRINGS 1
  63. #define INIT_NUM_LOC_STRINGS  1
  64. #define INIT_NUM_FILE_STRINGS 1
  65. /* The arrays double in size as they grow */
  66. #define REALLOC_INCR(num) (2*(num))
  67.  
  68. static char **hostStrings,**locStrings,**fileStrings;
  69. static int numHostStrings,numLocStrings,numFileStrings;
  70.  
  71. /*    -    -    -    -    -    -    -    -    */
  72.  
  73. Database *
  74. newDb()
  75. {
  76.     Database *db;
  77.  
  78.     db = XtNew(Database);
  79.     db->hostEntries = NULL;
  80.     return(db);
  81. }
  82.  
  83. void
  84. clearDb(dbp)
  85. Database *dbp;
  86. {
  87.     HostEntry *hostp,*nexthostp;
  88.     LocEntry *locp,*nextlocp;
  89.     FileEntry *filep,*nextfilep;
  90.  
  91.     if (dbp == DB_NULL) {
  92.     alert0("DB error: attempt to clear NULL database\n");
  93.     return;
  94.     }
  95.     for (hostp=dbp->hostEntries; hostp != HOST_NULL; hostp=nexthostp) {
  96.     nexthostp = hostp->next;
  97.         for (locp=hostp->locEntries; locp != LOC_NULL; locp=nextlocp) {
  98.         nextlocp = locp->next;
  99.         for (filep=locp->fileEntries; filep != FILE_NULL;
  100.                             filep=nextfilep) {
  101.         nextfilep = filep->next;
  102.         XtFree(filep->name);
  103.         XtFree(filep);
  104.         }
  105.         XtFree(locp->linkpath);
  106.         XtFree(locp);
  107.     }
  108.     XtFree(hostp->hostname);
  109.     XtFree(hostp);
  110.     }
  111.     dbp->hostEntries = HOST_NULL;
  112. }
  113.     
  114. /*    -    -    -    -    -    -    -    -    */
  115.  
  116. HostEntry *
  117. addHostEntry(hostname,dbp,before)
  118. char *hostname;
  119. Database *dbp;
  120. HostEntry *before;
  121. {
  122.     HostEntry *hp,*last;
  123.  
  124.     hp = XtNew(HostEntry);
  125.     hp->hostname = (char *)NULL;
  126.     hp->locEntries = LOC_NULL;
  127.     hp->next = hp->prev = HOST_NULL;
  128.     if (dbp == DB_NULL) {
  129.     alert1("DB error: attempt to add host \"%.180s\" to NULL database",
  130.            hostname);
  131.     return(HOST_NULL);
  132.     } else if (dbp->hostEntries == HOST_NULL) {
  133.     dbp->hostEntries = hp;
  134.     hp->prev = hp->next = HOST_NULL;
  135.     } else if (before == HOST_NULL) {
  136.     last = lastHostEntry(dbp);
  137.     last->next = hp;
  138.     hp->prev = last;
  139.     hp->next = HOST_NULL;
  140.     } else {
  141.     if (before->prev == HOST_NULL)
  142.         dbp->hostEntries = hp;
  143.     else
  144.         before->prev->next = hp;
  145.     hp->prev = before->prev;
  146.     hp->next = before;
  147.     before->prev = hp;
  148.     }
  149.     hp->hostname = XtNewString(hostname);
  150.     return(hp);
  151. }
  152.  
  153. HostEntry *
  154. lastHostEntry(dbp)
  155. Database *dbp;
  156. {
  157.     HostEntry *hp;
  158.  
  159.     if (dbp == DB_NULL) {
  160.     alert0("DB error: attempt to find last host of NULL database\n");
  161.     return(HOST_NULL);
  162.     } else if (dbp->hostEntries == HOST_NULL)
  163.     return(HOST_NULL);
  164.     for (hp=dbp->hostEntries; hp->next != HOST_NULL; hp=hp->next)
  165.     /* EMPTY */ ;
  166.     return(hp);
  167. }
  168.  
  169. HostEntry *
  170. findHostEntryFromString(hostname,dbp)
  171. char *hostname;
  172. Database *dbp;
  173. {
  174.     HostEntry *hp;
  175.  
  176.     if (dbp == DB_NULL) {
  177.     alert1("DB error: attempt to find host \"%.180s\" in NULL database",
  178.            hostname);
  179.     return(HOST_NULL);
  180.     }
  181.     for (hp=dbp->hostEntries; hp != HOST_NULL &&
  182.                    strcmp(hp->hostname,hostname) != 0; hp=hp->next)
  183.     /* EMPTY */ ;
  184.     return(hp);
  185. }
  186.  
  187. HostEntry *
  188. findHostEntryFromIndex(index,dbp)
  189. int index;
  190. Database *dbp;
  191. {
  192.     HostEntry *hp;
  193.  
  194.     if (dbp == DB_NULL) {
  195.     alert1("DB error: attempt to find host index %d in NULL database",
  196.            index);
  197.     return(HOST_NULL);
  198.     }
  199.     for (hp=dbp->hostEntries; hp != HOST_NULL && index--; hp=hp->next)
  200.     /* EMPTY */ ;
  201.     return(hp);
  202. }
  203.  
  204. int
  205. findHostIndexFromEntry(hp)
  206. HostEntry *hp;
  207. {
  208.     int i;
  209.  
  210.     for (i=0; i < numHostStrings && *(hostStrings+i) != (char*)NULL; i++)
  211.         if (strcmp(hp->hostname,*(hostStrings+i)) == 0)
  212.             return(i);
  213.     return(-1);
  214. }
  215.  
  216.  
  217. /*    -    -    -    -    -    -    -    -    */
  218.  
  219. LocEntry *
  220. addLocEntry(linkpath,hostp,before)
  221. char *linkpath;
  222. HostEntry *hostp;
  223. LocEntry *before;
  224. {
  225.     LocEntry *lp,*last;
  226.  
  227.     lp = XtNew(LocEntry);
  228.     lp->linkpath = (char *)NULL;
  229.     lp->fileEntries = FILE_NULL;
  230.     lp->next = lp->prev = LOC_NULL;
  231.     if (hostp == HOST_NULL) {
  232.     alert1("DB error: attempt to add location \"%.180s\" to NULL host",
  233.            linkpath);
  234.     return(LOC_NULL);
  235.     } else if (hostp->locEntries == LOC_NULL) {
  236.     hostp->locEntries = lp;
  237.     lp->prev = lp->next = LOC_NULL;
  238.     } else if (before == LOC_NULL) {
  239.     last = lastLocEntry(hostp);
  240.     last->next = lp;
  241.     lp->prev = last;
  242.     lp->next = LOC_NULL;
  243.     } else {
  244.     if (before->prev == LOC_NULL)
  245.         hostp->locEntries = lp;
  246.     else
  247.         before->prev->next = lp;
  248.     lp->prev = before->prev;
  249.     lp->next = before;
  250.     before->prev = lp;
  251.     }
  252.     lp->linkpath = XtNewString(linkpath);
  253.     return(lp);
  254. }
  255.  
  256. LocEntry *
  257. lastLocEntry(locp)
  258. HostEntry *locp;
  259. {
  260.     LocEntry *lp;
  261.  
  262.     if (locp == HOST_NULL) {
  263.     alert0("DB error: attempt to find last location of NULL host\n");
  264.     return LOC_NULL;
  265.     } else if (locp->locEntries == LOC_NULL)
  266.     return(LOC_NULL);
  267.     for (lp=locp->locEntries; lp->next != LOC_NULL; lp=lp->next)
  268.     /* EMPTY */ ;
  269.     return(lp);
  270. }
  271.  
  272. LocEntry *
  273. findLocEntryFromString(linkpath,hostp)
  274. char *linkpath;
  275. HostEntry *hostp;
  276. {
  277.     LocEntry *lp;
  278.  
  279.     if (hostp == HOST_NULL) {
  280.     alert1("DB error: attempt to find loc \"%.180s\" in NULL host",
  281.            linkpath);
  282.     return(LOC_NULL);
  283.     }
  284.     for (lp=hostp->locEntries; lp != LOC_NULL &&
  285.                    strcmp(lp->linkpath,linkpath) != 0; lp=lp->next)
  286.     /* EMPTY */ ;
  287.     return(lp);
  288. }
  289.  
  290. LocEntry *
  291. findLocEntryFromIndex(index,hostp)
  292. int index;
  293. HostEntry *hostp;
  294. {
  295.     LocEntry *lp;
  296.  
  297.     if (hostp == HOST_NULL) {
  298.     alert1("DB error: attempt to find loc index %d in NULL host",
  299.            index);
  300.     return(LOC_NULL);
  301.     }
  302.     for (lp=hostp->locEntries; lp != LOC_NULL && index--; lp=lp->next)
  303.     /* EMPTY */ ;
  304.     return(lp);
  305. }
  306.  
  307. int
  308. findLocIndexFromEntry(lp)
  309. LocEntry *lp;
  310. {
  311.     int i;
  312.  
  313.     for (i=0; i < numLocStrings && *(locStrings+i) != (char *)NULL; i++)
  314.         if (strcmp(lp->linkpath,*(locStrings+i)) == 0)
  315.             return(i);
  316.     return(-1);
  317. }
  318.  
  319. /*    -    -    -    -    -    -    -    -    */
  320.  
  321. FileEntry *
  322. addFileEntry(name,size,modes,date,locp,before)
  323. char *name;
  324. int size;
  325. char *modes,*date;
  326. LocEntry *locp;
  327. FileEntry *before;
  328. {
  329.     FileEntry *fp,*last;
  330.  
  331.     fp = XtNew(FileEntry);
  332.     fp->name = (char *)NULL;
  333.     fp->next = fp->prev = FILE_NULL;
  334.     if (locp == LOC_NULL) {
  335.     alert1("DB error: attempt to add file \"%.180s\" to NULL location",
  336.            name);
  337.     return(FILE_NULL);
  338.     } else if (locp->fileEntries == FILE_NULL) {
  339.     locp->fileEntries = fp;
  340.     fp->prev = fp->next = FILE_NULL;
  341.     } else if (before == FILE_NULL) {
  342.     last = lastFileEntry(locp);
  343.     last->next = fp;
  344.     fp->prev = last;
  345.     fp->next = FILE_NULL;
  346.     } else {
  347.     if (before->prev == FILE_NULL)
  348.         locp->fileEntries = fp;
  349.     else
  350.         before->prev->next = fp;
  351.     fp->prev = before->prev;
  352.     fp->next = before;
  353.     before->prev = fp;
  354.     }
  355.     fp->name = XtNewString(name);
  356.     fp->size = size;
  357.     strncpy(fp->modes,modes,15);
  358.     strncpy(fp->date,date,15);
  359.     return(fp);
  360. }
  361.  
  362. FileEntry *
  363. lastFileEntry(locp)
  364. LocEntry *locp;
  365. {
  366.     FileEntry *fp;
  367.  
  368.     if (locp == LOC_NULL) {
  369.     alert0("DB error: attempt to find last file of NULL location\n");
  370.     return FILE_NULL;
  371.     } else if (locp->fileEntries == FILE_NULL)
  372.     return(FILE_NULL);
  373.     for (fp=locp->fileEntries; fp->next != FILE_NULL; fp=fp->next)
  374.     /* EMPTY */ ;
  375.     return(fp);
  376. }
  377.  
  378. FileEntry *
  379. findFileEntryFromString(name,locp)
  380. char *name;
  381. LocEntry *locp;
  382. {
  383.     FileEntry *fp;
  384.  
  385.     if (locp == LOC_NULL) {
  386.     alert1("DB error: attempt to find file \"%.180s\" in NULL location",
  387.            name);
  388.     return(FILE_NULL);
  389.     }
  390.     for (fp=locp->fileEntries; fp != FILE_NULL &&
  391.                    strcmp(fp->name,name) != 0; fp=fp->next)
  392.     /* EMPTY */ ;
  393.     return(fp);
  394. }
  395.  
  396. FileEntry *
  397. findFileEntryFromIndex(index,locp)
  398. int index;
  399. LocEntry *locp;
  400. {
  401.     FileEntry *fp;
  402.  
  403.     if (locp == LOC_NULL) {
  404.     alert1("DB error: attempt to find file index %d in NULL location",
  405.            index);
  406.     return(FILE_NULL);
  407.     }
  408.     for (fp=locp->fileEntries; fp != FILE_NULL && index--; fp=fp->next)
  409.     /* EMPTY */ ;
  410.     return(fp);
  411. }
  412.  
  413. int
  414. findFileIndexFromEntry(fp)
  415. FileEntry *fp;
  416. {
  417.     int i;
  418.  
  419.     for (i=0; i < numFileStrings && *(fileStrings+i) != (char *)NULL; i++)
  420.         if (strcmp(fp->name,*(fileStrings+i)) == 0)
  421.             return(i);
  422.     return(-1);
  423. }
  424.  
  425. /*    -    -    -    -    -    -    -    -    */
  426.  
  427. void
  428. displayHosts(dbp)
  429. Database *dbp;
  430. {
  431.     HostEntry *hp;
  432.     int i;
  433.  
  434.     if (dbp == DB_NULL) {
  435.     alert0("DB error: attempt to display hosts from NULL database\n");
  436.     return;
  437.     }
  438.     clearList(hostList);
  439.     clearList(locationList);
  440.     clearList(fileList);
  441.     i = 0;
  442.     for (hp=dbp->hostEntries; hp != NULL; hp=hp->next)
  443.     setHostString(i++,hp->hostname);
  444.     setHostString(i,(char *)NULL);
  445.     if (i > 0)
  446.     setHostListFromStrings();
  447.     if (i == 1) {
  448.     XawListHighlight(hostList,0);
  449.     selectedHostEntry = dbp->hostEntries;
  450.     displayHostInfo(selectedHostEntry);
  451.     displayLocs(selectedHostEntry);
  452.     } else {
  453.     selectedHostEntry = HOST_NULL;
  454.     clearHostInfo();
  455.     selectedLocEntry = LOC_NULL;
  456.     clearLocationInfo();
  457.     selectedFileEntry = FILE_NULL;
  458.     clearFileInfo();
  459.     }
  460. }
  461.  
  462. void
  463. displayLocs(hostp)
  464. HostEntry *hostp;
  465. {
  466.     LocEntry *lp;
  467.     int i;
  468.  
  469.     if (hostp == HOST_NULL) {
  470.     alert0("DB error: attempt to display locations from NULL host\n");
  471.     return;
  472.     }
  473.     clearList(locationList);
  474.     clearList(fileList);
  475.     i = 0;
  476.     for (lp=hostp->locEntries; lp != LOC_NULL; lp=lp->next)
  477.     setLocString(i++,lp->linkpath);
  478.     setLocString(i,(char *)NULL);
  479.     if (i > 0)
  480.     setLocListFromStrings();
  481.     if (i == 1) {
  482.     XawListHighlight(locationList,0);
  483.     selectedLocEntry = hostp->locEntries;
  484.     displayLocationInfo(selectedLocEntry);
  485.     displayFiles(selectedLocEntry);
  486.     } else {
  487.     selectedLocEntry = LOC_NULL;
  488.     clearLocationInfo();
  489.     selectedFileEntry = FILE_NULL;
  490.     clearFileInfo();
  491.     }
  492. }
  493.  
  494. void
  495. displayFiles(locp)
  496. LocEntry *locp;
  497. {
  498.     FileEntry *fp;
  499.     int i;
  500.  
  501.     if (locp == LOC_NULL) {
  502.     alert0("DB error: attempt to display files from NULL location\n");
  503.     return;
  504.     }
  505.     clearList(fileList);
  506.     i = 0;
  507.     for (fp=locp->fileEntries; fp != FILE_NULL; fp=fp->next)
  508.     setFileString(i++,fp->name);
  509.     setFileString(i,(char *)NULL);
  510.     if (i > 0)
  511.     setFileListFromStrings();
  512.     if (i == 1) {
  513.     XawListHighlight(fileList,0);
  514.     selectedFileEntry = locp->fileEntries;
  515.     displayFileInfo(selectedFileEntry);
  516.     } else {
  517.     selectedFileEntry = FILE_NULL;
  518.     clearFileInfo();
  519.     }
  520. }
  521.  
  522. /*    -    -    -    -    -    -    -    -    */
  523. /* These routines provide access to the dynamically-grown lists
  524.  * of strings. I bzero() the allocated space even though I shouldn't
  525.  * to.
  526.  */
  527.  
  528. void
  529. setHostString(i,s)
  530. int i;
  531. char *s;
  532. {
  533.     char **oldStr;
  534.     int oldNum;
  535.  
  536.     /* Free old string if there was one */
  537.     if (i < numHostStrings)
  538.     XtFree(*(hostStrings+i));
  539.     /* If this is the first call, get the initial string array */
  540.     if (numHostStrings == 0) {
  541.     numHostStrings = INIT_NUM_HOST_STRINGS;
  542.     hostStrings = (char **)XtCalloc(numHostStrings,sizeof(char *));
  543.     bzero(hostStrings,numHostStrings*sizeof(char *));
  544.     }
  545.     /* Grow the array until it's big enough for this string */
  546.     while (i >= numHostStrings) {
  547.     oldStr = hostStrings;
  548.     oldNum = numHostStrings;
  549.     numHostStrings = REALLOC_INCR(numHostStrings);
  550.     hostStrings = (char **)XtCalloc(numHostStrings,sizeof(char *));
  551.     bzero(hostStrings,numHostStrings*sizeof(char *));
  552.     bcopy(oldStr,hostStrings,oldNum*sizeof(char *));
  553.     XtFree(oldStr);
  554.     }
  555.     /* Finally, set this value */
  556.     if (s == (char *)NULL)
  557.     *(hostStrings+i) = (char *)NULL;
  558.     else
  559.     *(hostStrings+i) = XtNewString(s);
  560. }
  561.  
  562. void
  563. setLocString(i,s)
  564. int i;
  565. char *s;
  566.     char **oldStr;
  567.     int oldNum;
  568.  
  569.     /* Free old string if there was one */
  570.     if (i < numLocStrings)
  571.     XtFree(*(locStrings+i));
  572.     /* If this is the first call, get the initial string array */
  573.     if (numLocStrings == 0) {
  574.     numLocStrings = INIT_NUM_LOC_STRINGS;
  575.     locStrings = (char **)XtCalloc(numLocStrings,sizeof(char *));
  576.     bzero(locStrings,numLocStrings*sizeof(char *));
  577.     }
  578.     /* Grow the array until it's big enough for this string */
  579.     while (i >= numLocStrings) {
  580.     oldStr = locStrings;
  581.     oldNum = numLocStrings;
  582.     numLocStrings = REALLOC_INCR(numLocStrings);
  583.     locStrings = (char **)XtCalloc(numLocStrings,sizeof(char *));
  584.     bzero(locStrings,numLocStrings*sizeof(char *));
  585.     bcopy(oldStr,locStrings,oldNum*sizeof(char *));
  586.     XtFree(oldStr);
  587.     }
  588.     /* Finally, set this value */
  589.     if (s == (char *)NULL)
  590.     *(locStrings+i) = (char *)NULL;
  591.     else
  592.     *(locStrings+i) = XtNewString(s);
  593. }
  594.  
  595. void
  596. setFileString(i,s)
  597. int i;
  598. char *s;
  599. {
  600.     char **oldStr;
  601.     int oldNum;
  602.  
  603.     /* Free old string if there was one */
  604.     if (i < numFileStrings)
  605.     XtFree(*(fileStrings+i));
  606.     /* If this is the first call, get the initial string array */
  607.     if (numFileStrings == 0) {
  608.     numFileStrings = INIT_NUM_FILE_STRINGS;
  609.     fileStrings = (char **)XtCalloc(numFileStrings,sizeof(char *));
  610.     bzero(fileStrings,numFileStrings*sizeof(char *));
  611.     }
  612.     /* Grow the array until it's big enough for this string */
  613.     while (i >= numFileStrings) {
  614.     oldStr = fileStrings;
  615.     oldNum = numFileStrings;
  616.     numFileStrings = REALLOC_INCR(numFileStrings);
  617.     fileStrings = (char **)XtCalloc(numFileStrings,sizeof(char *));
  618.     bzero(fileStrings,numFileStrings*sizeof(char *));
  619.     bcopy(oldStr,fileStrings,oldNum*sizeof(char *));
  620.     XtFree(oldStr);
  621.     }
  622.     /* Finally, set this value */
  623.     if (s == (char *)NULL)
  624.     *(fileStrings+i) = (char *)NULL;
  625.     else
  626.     *(fileStrings+i) = XtNewString(s);
  627. }
  628.  
  629. /*    -    -    -    -    -    -    -    -    */
  630. /* These routines connect the arrays of strings to the list widgets. */
  631.  
  632. void
  633. setHostListFromStrings()
  634. {
  635.     XawListChange(hostList,hostStrings,0,0,True);
  636. }
  637.  
  638. void
  639. setLocListFromStrings()
  640. {
  641.     XawListChange(locationList,locStrings,0,0,True);
  642. }
  643.  
  644. void
  645. setFileListFromStrings()
  646. {
  647.     XawListChange(fileList,fileStrings,0,0,True);
  648. }
  649.  
  650. static char *emptyNames[] = { NULL };
  651.  
  652. void clearList(w)
  653. Widget w;
  654. {
  655.     XawListChange(w,emptyNames,0,0,False);
  656. }
  657.