home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / object / GDgopherdir.c < prev    next >
C/C++ Source or Header  |  1992-06-22  |  5KB  |  310 lines

  1. /*
  2.  * This is a crude attempt at doing some object-based programming in C
  3.  */
  4. #include "GDgopherdir.h"
  5. #include <Malloc.h>
  6.  
  7.  
  8. #include <string.h>
  9. #include <stdio.h>
  10. extern int DEBUG;
  11.  
  12.  
  13. /***********************************************************************
  14. ** Stuff for GopherDirObjs
  15. **
  16. ***********************************************************************/
  17.  
  18.  
  19. GopherDirObj*
  20. GDnew(size)
  21.   int size;
  22. {
  23.      int i;
  24.      GopherDirObj *temp;
  25.      
  26.      temp = (GopherDirObj*) malloc(sizeof(GopherDirObj));
  27.      temp->Gophers = (GopherObj **) malloc(size * sizeof(GopherObj*));
  28.      
  29.      for (i = 0; i < size; i++)
  30.       temp->Gophers[i] = GSnew();
  31.  
  32.      temp->maxsize = size;
  33.      temp->Title = STRnew();
  34.  
  35.      GDinit(temp);
  36.      return(temp);
  37. }
  38.  
  39.  
  40. void
  41. GDdestroy(gd)
  42.   GopherDirObj *gd;
  43. {
  44.      int i;
  45.      
  46.      for (i = 0; i < gd->maxsize; i++)
  47.       GSdestroy(gd->Gophers[i]);
  48.  
  49.      STRdestroy(gd->Title);
  50.  
  51.      free(gd->Gophers);
  52.      free(gd);
  53. }
  54.  
  55.  
  56. void
  57. GDinit(gd)
  58.   GopherDirObj *gd;
  59. {
  60.      int i;
  61.  
  62.      for (i=0; i<gd->maxsize; i++) {
  63.       GSinit(GDgetEntry(gd, i));
  64.      }
  65.  
  66.      GDsetTop(gd, 0);
  67.  
  68.      STRinit(gd->Title);
  69. }
  70.  
  71.  
  72. /*
  73.  * Increase the size of the GopherObj pointer array to "size"
  74.  */
  75.  
  76. void
  77. GDgrow(gd, size)
  78.   GopherDirObj *gd;
  79.   int size;
  80. {
  81.      GopherObj **temp;
  82.      int i;
  83.  
  84.      if (size < gd->maxsize)
  85.       return; /** Size is smaller than requested **/
  86.  
  87.      temp = (GopherObj **) realloc(gd->Gophers, size*sizeof(GopherObj*));
  88.  
  89.      if (temp == NULL)
  90.       fprintf(stderr, "Out of memory!!!\n"), exit(-1);
  91.  
  92.      if (temp != gd->Gophers) {
  93.       gd->Gophers = temp;
  94.      }
  95.  
  96.      /** Initialize the new GopherObjs.  **/
  97.  
  98.      for (i= gd->maxsize; i< size; i++)
  99.       gd->Gophers[i] = GSnew();
  100.      
  101.      gd->maxsize = size;
  102.      return;
  103. }
  104.  
  105.  
  106. extern int DEBUG;
  107.  
  108. /** This proc adds a GopherObj to a gopherdir. **/
  109. void
  110. GDaddGS(gd, gs)
  111.   GopherDirObj *gd;
  112.   GopherObj *gs;
  113. {
  114.     int n, i;
  115.  
  116.     if (GDgetTop(gd) == gd->maxsize)
  117.           GDgrow(gd, gd->maxsize*2);
  118.  
  119.     if (DEBUG)
  120.         fprintf(stderr, "Adding %s, Top=%d, Num=%d\n",
  121.             GSgetTitle(gs), GDgetTop(gd), GSgetNum(gs));
  122.  
  123.     if ((n = GSgetNum(gs)) == 0)    /* if we don't care where it goes */
  124.         n=1;            /* put it in the first available slot */
  125.  
  126.     if (GSgetType(GDgetEntry(gd, n-1)) != '\0') {    /* that slot is in use*/
  127.         for (i=1; ; i++)        /* find any empty slot */
  128.             if (GSgetType(GDgetEntry(gd, i-1)) == '\0')
  129.                 break;        /* got one */
  130.         if (i >= GDgetTop(gd))    /* item was past end of list */
  131.             GDsetTop(gd, i);    /* update end of list */
  132.         if (GSgetNum(gs) != 0) {    /* if we want that slot */
  133.             /* kick out the entry that's in our way */
  134.             GScpy(GDgetEntry(gd, i-1), GDgetEntry(gd, n-1));
  135.         } else {
  136.             n = i;    /* don't be a bully */
  137.         }
  138.     }
  139.  
  140.     GScpy(GDgetEntry(gd, n-1), gs);        /* put our entry in place */
  141.     if (n >= GDgetTop(gd))            /* item was past end of list */
  142.         GDsetTop(gd, n);        /* update end of list */
  143.  
  144. }
  145.  
  146.  
  147. /*
  148.  * Really weird!!!  We need this for qsort,  don't know why we can't use
  149.  * GScmp...
  150.  */
  151.  
  152. int
  153. GSmoocmp(gs1, gs2)
  154.   GopherObj **gs1, **gs2;
  155. {
  156.      if (GSgetTitle(*gs1) == NULL)
  157.       return(1);
  158.      if (GSgetTitle(*gs2) == NULL)
  159.       return(-1);
  160.  
  161.      return(strcmp(GSgetTitle(*gs1), GSgetTitle(*gs2)));
  162. }
  163.  
  164. /*
  165.  * Sorts a gopher directory
  166.  */
  167.  
  168. void
  169. GDsort(gd)
  170.   GopherDirObj *gd;
  171. {
  172.      int i;
  173.  
  174.      /*** Find first non-numbered entry ***/
  175.  
  176.      for (i=0; ; i++) {
  177.       if (GSgetNum(GDgetEntry(gd, i)) == 0)
  178.            break;
  179.      }
  180.  
  181.      /*** Everything up to i is already sorted by user-defined ordering ***/
  182.  
  183.      if (GDgetTop(gd) <= i)
  184.       /** No more sorting needed ***/
  185.       return;
  186.  
  187.      
  188.      qsort((char *) (&(gd->Gophers[i])), gd->Top-i, 
  189.        sizeof(GopherObj*),GSmoocmp);
  190.  
  191. }
  192.  
  193.  
  194. void
  195. GDtoNet(gd, sockfd)
  196.   GopherDirObj *gd;
  197.   int sockfd;
  198. {
  199.      int i;
  200.  
  201.      for (i=0; i< GDgetTop(gd); i++) {
  202.       GStoNet(GDgetEntry(gd, i), sockfd);
  203.      }      
  204.  
  205. }
  206.  
  207. void
  208. GDtoNetHTML(gd, sockfd)
  209.   GopherDirObj *gd;
  210.   int sockfd;
  211. {
  212.      int i;
  213.      
  214.      writestring(sockfd, "<MENU>\r\n");
  215.      
  216.      for (i=0; i< GDgetTop(gd); i++) {
  217.       writestring(sockfd, "<LI>");
  218.       GStoNetHTML(GDgetEntry(gd, i), sockfd);
  219.      }      
  220.      writestring(sockfd, "</MENU>");
  221. }
  222.  
  223.  
  224. /*
  225.  * Fill up a GopherDirObj with GopherObjs, given a gopher directory coming
  226.  * from sockfd.
  227.  *
  228.  * For each GopherObj retrieved, eachitem() is executed.
  229.  *
  230.  */
  231.  
  232. int
  233. GDfromNet(gd, sockfd, eachitem)
  234.   GopherDirObj *gd;
  235.   int sockfd;
  236.   int (*eachitem)();
  237. {
  238.      static GopherObj *TempGopher;
  239.      static char ZesTmp[1024];
  240.      int j, i;
  241.  
  242.      if (TempGopher == NULL)
  243.       TempGopher = GSnew();
  244.  
  245.      for (j=0; ; j++) {
  246.  
  247.       if (j == gd->maxsize)
  248.            GDgrow(gd, gd->maxsize*2);
  249.  
  250.       ZesTmp[0] = '\0';
  251.       
  252.       GSinit(TempGopher);
  253.       i = GSfromNet(TempGopher, sockfd);
  254.       
  255.       if (i==0) {
  256.            GDaddGS(gd, TempGopher);
  257.            if (eachitem != NULL) 
  258.             eachitem();
  259.       }
  260.  
  261.       else if (i==1)
  262.            return(j);
  263.  
  264.       if (i<0) {
  265.            j = j-1;
  266.            if (j<0) j=0;
  267.            readline(sockfd, ZesTmp, 1024); /** Get the rest of the line **/
  268.            return(j);
  269.       }
  270.      }
  271.  
  272.  
  273. /*
  274.  * Given an open file descriptor and an inited GopherDirobj,
  275.  *   read in gopher links, and add them to a gopherdir
  276.  */
  277.  
  278. void
  279. GDfromLink(gd, fd, host, port)
  280.   GopherDirObj *gd;
  281.   int          fd;
  282.   char         *host;
  283.   int          port;
  284. {
  285.      GopherObj *gs;
  286.  
  287.      gs = GSnew();
  288.  
  289.      while (GSfromLink(gs, fd, host, port) != -1)
  290.       GDaddGS(gd, gs);
  291.  
  292.      GSdestroy(gs);
  293. }
  294.  
  295.  
  296.  
  297. void
  298. GDtoLink(gd, fd)
  299.   GopherDirObj *gd;
  300.   int fd;
  301. {
  302.      int i;
  303.  
  304.      for (i=0; i< GDgetTop(gd); i++) {
  305.       GStoLink(GDgetEntry(gd, i), fd);
  306.      }      
  307.  
  308. }
  309.