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 / GSgopherobj.c < prev    next >
Text File  |  1992-06-11  |  9KB  |  438 lines

  1. /*
  2.  * This is a crude attempt at doing some object-based programming in C
  3.  */
  4. #include "GSgopherobj.h"
  5.  
  6. #if defined(mips)   /*** Gross hack, yuck! ***/
  7. #define _SIZE_T
  8. #endif
  9.  
  10. #include <string.h>
  11. #include <stdio.h>
  12. extern int DEBUG;
  13.  
  14. /*
  15.  * These are needed for GSconnect().  Ick.
  16.  */
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <netinet/in.h>
  20. #include <sys/file.h>
  21. #ifndef hpux
  22. #include <arpa/inet.h>
  23. #endif
  24. #include <netdb.h>
  25.  
  26. #include "Malloc.h"
  27.  
  28. /*
  29.  * Make a new gopherstruct...  Should reuse destroyed GopherObjs...
  30.  */
  31.  
  32. GopherObj *
  33. GSnew()
  34. {
  35.      GopherObj *temp;
  36.  
  37.      temp = (GopherObj *) malloc(sizeof(GopherObj));
  38.      temp->Selstr = STRnew();
  39.      temp->Title  = STRnew();
  40.      temp->Host   = STRnew();
  41.  
  42.      GSinit(temp);
  43.      
  44.      return(temp);
  45. }
  46.  
  47. void
  48. GSdestroy(gs)
  49.   GopherObj *gs;
  50. {
  51.      STRdestroy(gs->Selstr);
  52.      STRdestroy(gs->Title);
  53.      STRdestroy(gs->Host);
  54.  
  55.      free(gs);
  56. }
  57.      
  58.  
  59.  
  60. /*
  61.  * Clear out all the crud 
  62.  */
  63.  
  64. void
  65. GSinit(gs)
  66.   GopherObj *gs;
  67. {
  68.      GSsetType(gs, '\0');
  69.      
  70.      STRinit(gs->Title);
  71.      STRinit(gs->Selstr);
  72.      STRinit(gs->Host);
  73.  
  74.      gs->iPort = 0;
  75.      gs->iItemnum = 0;
  76.      GSsetWeight(gs, 0);
  77. }
  78.  
  79.  
  80. void
  81. GStoNet(gs, sockfd)
  82.   GopherObj *gs;
  83.   int sockfd;
  84. {
  85.      static char buf[1024];
  86.  
  87.      buf[0] = GSgetType(gs);
  88.  
  89.      if (GSgetWeight(gs) == 0)
  90.       sprintf(buf + 1, "%s\t%s\t%s\t%d\r\n",
  91.           GSgetTitle(gs),
  92.           GSgetPath(gs),
  93.           GSgetHost(gs),
  94.           GSgetPort(gs));
  95.      else
  96.       sprintf(buf + 1, "%s\t%s\t%s\t%d\t%d\r\n",
  97.           GSgetTitle(gs),
  98.           GSgetPath(gs),
  99.           GSgetHost(gs),
  100.           GSgetPort(gs),
  101.           GSgetWeight(gs));
  102.       
  103.      writestring(sockfd, buf);
  104.      
  105.      if (DEBUG)
  106.       fprintf(stderr, buf);
  107.  
  108. }
  109.  
  110.  
  111. void
  112. GStoNetHTML(gs, sockfd)
  113.   GopherObj *gs;
  114.   int sockfd;
  115. {
  116.      static char buf[1024];
  117.      static char pathbuf[1024];
  118.      char *cp, *cpout;
  119.  
  120.      buf[0] = '\0';
  121.      pathbuf[0] = '\0';
  122.  
  123.      /** Convert Path so that spaces are %20 **/
  124.      Tohexstr(GSgetPath(gs), pathbuf);
  125.  
  126.      sprintf(buf, "<A HREF=http://%s:%d/%s>%s</A>",
  127.          GSgetHost(gs),
  128.          GSgetPort(gs),
  129.          pathbuf,
  130.          GSgetTitle(gs));
  131.  
  132.      writestring(sockfd, buf);
  133.  
  134.      if (DEBUG)
  135.       fprintf(stderr, "HTML: %s", buf);
  136.      
  137.      if (GSgetWeight(gs) != 0) {
  138.       sprintf(buf, "Score: %d\r\n", GSgetWeight(gs));
  139.       writestring(sockfd, buf);
  140.      }
  141.      else
  142.       writestring(sockfd, "\r\n");
  143.  
  144. }
  145.  
  146.  
  147. /*
  148.  * Fill in a GopherObj, given an HREF= link from a WWW anchor..
  149.  * So far only works with http
  150.  */
  151.  
  152. void
  153. GSfromHREF(gs, href)
  154.   GopherObj *gs;
  155.   char *href;
  156. {
  157.      char *cp;
  158.      char *host;
  159.      char *port;
  160.      char path[1024];
  161.      
  162.      if (strncasecmp(href, "http://", 7)==0) {
  163.       host = href +7;
  164.       cp  = strchr(href+7, '/');
  165.       if (cp == NULL)
  166.            return;
  167.       
  168.       *cp = '\0';
  169.       strcpy(path, "GET ");
  170.       strcat(path, cp+1);
  171.       GSsetPath(gs, path);
  172.  
  173.       GSsetType(gs, 'h');
  174.  
  175.       GSsetPath(gs, path);
  176.       
  177.       cp = strchr(host, ':');
  178.       if (cp==NULL) 
  179.            GSsetPort(gs, 80);  /** default WWW port **/
  180.       else
  181.            GSsetPort(gs, atoi(cp+1));
  182.  
  183.       *cp = '\0';
  184.       GSsetHost(gs, host);
  185.      }
  186. }
  187.       
  188.  
  189.  
  190.  
  191. extern int readfield();
  192. extern int readline();
  193.  
  194. int
  195. GSfromNet(gs, sockfd)
  196.   GopherObj *gs;
  197.   int sockfd;
  198. {
  199.      char *cPtr = NULL;
  200.      char foo[1024];
  201.      
  202.      if (readfield(sockfd, foo, 1024)<= 0) {
  203.       /* EOF or error */
  204.       return(-1);
  205.      }
  206.  
  207.      GSsetType(gs, foo[0]);
  208.  
  209.      /** Get the kind of file from the first character **/
  210.      /** Filter out files that we can't deal with **/
  211.  
  212.      switch (GSgetType(gs)) {
  213.        case A_FILE:
  214.        case A_DIRECTORY:
  215.        case A_MACHEX:
  216.        case A_PCHEX:
  217.        case A_CSO:
  218.        case A_INDEX:
  219.        case A_TELNET:
  220.        case A_SOUND:
  221.        case A_UNIXBIN:
  222.        case A_HTML:
  223.        case A_TN3270:
  224.        case A_MIME:
  225. /*     case A_EVENT:
  226.        case A_CALENDAR:   not ready for prime time yet */
  227.       break;
  228.        case A_EOI:
  229.       return(1);
  230.      default:
  231.     return(-1);  
  232.      }
  233.  
  234.      /** Suck off the User Displayable name **/
  235.      GSsetTitle(gs, foo+1);
  236.      
  237.      /** Suck off the Pathname **/
  238.      if (readfield(sockfd, foo, 1024) == 0)
  239.       return(-1);
  240.      GSsetPath(gs, foo);
  241.  
  242.      /** Suck off the hostname **/
  243.      if (readfield(sockfd, foo, 1024) == 0)
  244.       return(-1);
  245.      GSsetHost(gs, foo);
  246.  
  247.      if (readline(sockfd, foo, 1024)==0)
  248.       return(-1); 
  249.  
  250.      GSsetPort(gs, 0);
  251.  
  252.      /** Get the port number **/
  253.      GSsetPort(gs, atoi(foo));
  254.  
  255.      return(0);
  256. }
  257.  
  258. /** Copy a GopherObj ***/
  259.  
  260. void
  261. GScpy(dest, orig)
  262.   GopherObj *dest, *orig;
  263. {
  264.      dest->sFileType = orig->sFileType;
  265.      dest->iPort     = orig->iPort;
  266.      dest->iItemnum  = orig->iItemnum;
  267.  
  268.      GSsetTitle(dest, GSgetTitle(orig));
  269.      GSsetPath(dest, GSgetPath(orig));
  270.      GSsetHost(dest, GSgetHost(orig));
  271. }
  272.  
  273. /** Compare two GopherObjs ***/
  274.  
  275. int
  276. GScmp(gs1, gs2)
  277.   GopherObj *gs1, *gs2;
  278. {
  279.      if (GSgetTitle(gs1) == NULL)
  280.       return(1);
  281.      if (GSgetTitle(gs2) == NULL)
  282.       return(-1);
  283.  
  284.      return(strcmp(GSgetTitle(gs1), GSgetTitle(gs2)));
  285. }
  286.  
  287.  
  288.  
  289.  
  290. /* GSconnect performs a connection to socket 'service' on host
  291.  * 'host'.  Host can be a hostname or ip-address.  If 'host' is null, the
  292.  * local host is assumed.   The parameter full_hostname will, on return,
  293.  * contain the expanded hostname (if possible).  Note that full_hostname is a
  294.  * pointer to a char *, and is allocated by connect_to_gopher()
  295.  *
  296.  * Errors:
  297.  *
  298.  * -1 get service failed
  299.  *
  300.  * -2 get host failed
  301.  *
  302.  * -3 socket call failed
  303.  *
  304.  * -4 connect call failed
  305.  */
  306.  
  307. int
  308. GSconnect(gs)
  309.   GopherObj *gs;
  310. {
  311.      struct sockaddr_in Server;
  312.      char sBuf[16];
  313.      struct hostent *HostPtr;
  314.      int iSock = 0;
  315.      
  316.      if ((Server.sin_addr.s_addr = inet_addr(GSgetHost(gs))) == -1) {
  317.       if (HostPtr = gethostbyname(GSgetHost(gs))) {
  318.            bzero((char *) &Server, sizeof(Server));
  319.            bcopy(HostPtr->h_addr, (char *) &Server.sin_addr, HostPtr->h_length);
  320.            Server.sin_family = HostPtr->h_addrtype;
  321.       } else
  322.            return (-2);
  323.      } else
  324.       Server.sin_family = AF_INET;
  325.  
  326.      Server.sin_port = (unsigned short) htons(GSgetPort(gs));
  327.  
  328.      if ((iSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  329.       return (-3);
  330.  
  331.      setsockopt(iSock, SOL_SOCKET, ~SO_LINGER, 0, 0);
  332.      setsockopt(iSock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
  333.      setsockopt(iSock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
  334.  
  335.      if (connect(iSock, (struct sockaddr *) &Server, sizeof(Server)) < 0) {
  336.       close(iSock);
  337.       return (-4);
  338.      }
  339.      return(iSock);
  340. }
  341.  
  342. /*
  343.  * GSfromLink takes an open file descriptor and starts reading from it.
  344.  * It keeps going until it findsL
  345.  *    enough fields for a gopherobj
  346.  *    no data left
  347.  * 
  348.  * returns 0 with success, -1 on an error.
  349.  */
  350.  
  351. #define    G_PATH    (1<<0)
  352. #define    G_TYPE  (1<<1)
  353. #define    G_NAME    (1<<2)
  354. #define    G_PORT    (1<<3)
  355. #define    G_HOST    (1<<4)
  356. #define    G_ALL (G_PATH | G_TYPE | G_NAME | G_PORT | G_HOST)
  357.  
  358. int
  359. GSfromLink(gs, fd, host, port)
  360.   GopherObj *gs;
  361.   int       fd;
  362.   char      *host;
  363.   int       port;
  364. {
  365.      int doneflags = 0;
  366.      char buf[1024];
  367.  
  368.      while ((doneflags != G_ALL) && readline(fd, buf, 1024)) {
  369.       if (buf[0] == '#')
  370.            continue;   /* comment */
  371.  
  372.       ZapCRLF(buf);
  373.  
  374.       if (strncmp(buf, "Type=", 5)==0) {
  375.            GSsetType(gs, buf[5]);
  376.            doneflags |= G_TYPE;
  377.       }
  378.       
  379.       if (strncmp(buf, "Name=", 5)==0) {
  380.            GSsetTitle(gs, buf+5);
  381.            doneflags |= G_NAME;
  382.       }
  383.        
  384.       if (strncmp(buf, "Path=", 5)==0) {
  385.            GSsetPath(gs, buf+5);
  386.            doneflags |= G_PATH;
  387.       }
  388.        
  389.       if (strncmp(buf, "Host=", 5)==0) {
  390.            if (buf[5] == '+' && buf[6] == '\0')
  391.             GSsetHost(gs, host);
  392.            else
  393.             GSsetHost(gs, buf+5);
  394.  
  395.            doneflags |= G_HOST;
  396.       }
  397.       if (strncmp(buf, "Port=", 5)==0) {
  398.            if (buf[5] == '+' && buf[6] == '\0')
  399.             GSsetPort(gs, port);
  400.            else
  401.             GSsetPort(gs, atoi(buf+5));
  402.  
  403.            doneflags |= G_PORT;
  404.       }
  405.       if (strncmp(buf, "Numb=", 5)==0)
  406.            GSsetNum(gs, atoi(buf+5));
  407.       
  408.      }
  409.      return ((doneflags == G_ALL) ? 0 : -1); /* 0 == success */
  410. }
  411.  
  412.  
  413. void
  414. GStoLink(gs, fd)
  415.   GopherObj *gs;
  416.   int fd;
  417. {
  418.      char gtype[2];
  419.      char portnum[16];
  420.      
  421.      gtype[0] = GSgetType(gs);
  422.      gtype[1] = '\0';
  423.  
  424.      writestring(fd, "#");
  425.      writestring(fd, "\nType=");
  426.      writestring(fd, gtype);
  427.      writestring(fd, "\nName=");
  428.      writestring(fd, GSgetTitle(gs));
  429.      writestring(fd, "\nPath=");
  430.      writestring(fd, GSgetPath(gs));
  431.      writestring(fd, "\nHost=");
  432.      writestring(fd, GSgetHost(gs));
  433.      writestring(fd, "\nPort=");
  434.      sprintf(portnum, "%d", GSgetPort(gs));
  435.      writestring(fd, portnum);
  436.      writestring(fd, "\n");
  437. }
  438.