home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * $Author: lindner $
- * $Revision: 1.1.1.3 $
- * $Date: 1993/01/11 19:54:06 $
- * $Source: /home/mudhoney/GopherSrc/release1.11/object/RCS/GSgopherobj.c,v $
- * $Status: $
- *
- * Paul Lindner, University of Minnesota CIS.
- *
- * Copyright 1991, 1992 by the Regents of the University of Minnesota
- * see the file "Copyright" in the distribution for conditions of use.
- *********************************************************************
- * MODULE: GSgopherobj.c
- * Implement gopher directory functions.
- *********************************************************************
- * Revision History:
- * $Log: GSgopherobj.c,v $
- * Revision 1.1.1.3 1993/01/11 19:54:06 lindner
- * Fixed syntax in UCX #defines. (DuH!)
- *
- * Revision 1.1.1.2 1993/01/08 19:00:00 lindner
- * Mods for UCX
- *
- * Revision 1.1.1.1 1992/12/31 05:01:31 lindner
- * Chnages for VMS.
- *
- * Revision 1.1 1992/12/17 21:03:54 jqj
- * Initial revision
- *
- * Revision 1.1 1992/12/10 23:27:52 lindner
- * gopher 1.1 release
- *
- *
- *********************************************************************/
-
- #include "GSgopherobj.h"
-
- #if defined(mips) && defined(ultrix) /*** Gross hack, yuck! ***/
- #define _SIZE_T
- #endif
-
- #include "String.h"
- #include <stdio.h>
- #include "compatible.h"
- extern int DEBUG;
-
- /*
- * These are needed for GSconnect(). Ick.
- */
- #ifdef VMS
- #include <socket.h>
- #include <in.h>
- #include <file.h>
- #include <inet.h>
- #include <netdb.h>
-
- #else
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <sys/file.h>
- #ifndef hpux
- #include <arpa/inet.h>
- #endif
- #include <netdb.h>
- #endif /* not VMS */
-
- #include "Malloc.h"
-
- /*
- * Make a new gopherobj, set the fields accordingly...
- */
-
- GopherObj *
- GSnewSet(objtype, Title, Selstr, Host, Port)
- char objtype;
- char *Title;
- char *Selstr;
- char *Host;
- int Port;
- {
- GopherObj *temp;
-
- temp = (GopherObj *) malloc(sizeof(GopherObj));
- temp->Selstr = STRnewSet(Selstr);
- temp->Title = STRnewSet(Title);
- temp->Host = STRnewSet(Host);
- temp->iPort = Port;
- GSsetNum(temp, -1);
- GSsetWeight(temp, 0);
-
- return(temp);
- }
-
-
- /*
- * Make a new gopherobj... Should reuse destroyed GopherObjs...
- */
-
- GopherObj *
- GSnew()
- {
- GopherObj *temp;
-
- temp = (GopherObj *) malloc(sizeof(GopherObj));
- temp->Selstr = STRnew();
- temp->Title = STRnew();
- temp->Host = STRnew();
-
- GSinit(temp);
-
- return(temp);
- }
-
- void
- GSdestroy(gs)
- GopherObj *gs;
- {
- STRdestroy(gs->Selstr);
- STRdestroy(gs->Title);
- STRdestroy(gs->Host);
-
- free(gs);
- }
-
-
-
- /*
- * Clear out all the crud
- */
-
- void
- GSinit(gs)
- GopherObj *gs;
- {
- GSsetType(gs, '\0');
-
- STRinit(gs->Title);
- STRinit(gs->Selstr);
- STRinit(gs->Host);
-
- gs->iPort = 0;
- GSsetNum(gs, -1);
- GSsetWeight(gs, 0);
- }
-
-
- void
- GStoNet(gs, sockfd)
- GopherObj *gs;
- int sockfd;
- {
- static char buf[1024];
-
- buf[0] = GSgetType(gs);
-
- sprintf(buf + 1, "%s\t%s\t%s\t%d\r\n",
- GSgetTitle(gs),
- GSgetPath(gs),
- GSgetHost(gs),
- GSgetPort(gs));
-
- writestring(sockfd, buf);
-
- if (DEBUG)
- fprintf(stderr, buf);
-
- }
-
-
- void
- GStoNetHTML(gs, sockfd)
- GopherObj *gs;
- int sockfd;
- {
- static char buf[1024];
- static char pathbuf[1024];
-
- buf[0] = '\0';
- pathbuf[0] = '\0';
-
- /** Convert Path so that spaces are %20 **/
- Tohexstr(GSgetPath(gs), pathbuf);
-
- sprintf(buf, "<A HREF=http://%s:%d/%s>%s</A>",
- GSgetHost(gs),
- GSgetPort(gs),
- pathbuf,
- GSgetTitle(gs));
-
- writestring(sockfd, buf);
-
- if (DEBUG)
- fprintf(stderr, "HTML: %s", buf);
-
- if (GSgetWeight(gs) != 0) {
- sprintf(buf, "Score: %d\r\n", GSgetWeight(gs));
- writestring(sockfd, buf);
- }
- else
- writestring(sockfd, "\r\n");
-
- }
-
-
- /*
- * Fill in a GopherObj, given an HREF= link from a WWW anchor..
- * So far only works with http
- */
-
- void
- GSfromHREF(gs, href)
- GopherObj *gs;
- char *href;
- {
- char *cp;
- char *host;
- char path[1024];
-
- if (strncasecmp(href, "http://", 7)==0) {
- host = href +7;
- cp = strchr(href+7, '/');
- if (cp == NULL)
- return;
-
- *cp = '\0';
- strcpy(path, "GET ");
- strcat(path, cp+1);
- GSsetPath(gs, path);
-
- GSsetType(gs, 'h');
-
- GSsetPath(gs, path);
-
- cp = strchr(host, ':');
- if (cp==NULL)
- GSsetPort(gs, 80); /** default WWW port **/
- else {
- GSsetPort(gs, atoi(cp+1));
- *cp = '\0';
- }
-
- GSsetHost(gs, host);
- }
- }
-
-
-
-
- extern int readfield();
- extern int readline();
-
- int
- GSfromNet(gs, sockfd)
- GopherObj *gs;
- int sockfd;
- {
- char foo[1024];
-
- if (readfield(sockfd, foo, 1024)<= 0) {
- /* EOF or error */
- return(-1);
- }
-
- GSsetType(gs, foo[0]);
-
- /** Get the kind of file from the first character **/
- /** Filter out files that we can't deal with **/
-
- switch (GSgetType(gs)) {
- case A_FILE:
- case A_DIRECTORY:
- case A_MACHEX:
- case A_PCBIN:
- case A_CSO:
- case A_INDEX:
- case A_TELNET:
- case A_SOUND:
- case A_UNIXBIN:
- case A_GIF:
- case A_HTML:
- case A_TN3270:
- case A_MIME:
- case A_IMAGE:
- break;
- case A_EOI:
- if (foo[1] == '\r' && foo[2] == '\n')
- return(1);
- default:
- return(-2);
- }
-
- /** Suck off the User Displayable name **/
- GSsetTitle(gs, foo+1);
-
- /** Suck off the Pathname **/
- if (readfield(sockfd, foo, 1024) == 0)
- return(-1);
- GSsetPath(gs, foo);
-
- /** Suck off the hostname **/
- if (readfield(sockfd, foo, 1024) == 0)
- return(-1);
- GSsetHost(gs, foo);
-
- if (readline(sockfd, foo, 1024)==0)
- return(-1);
-
- GSsetPort(gs, 0);
-
- /** Get the port number **/
- GSsetPort(gs, atoi(foo));
-
- return(0);
- }
-
- /** Copy a GopherObj ***/
-
- void
- GScpy(dest, orig)
- GopherObj *dest, *orig;
- {
- dest->sFileType = orig->sFileType;
- dest->iPort = orig->iPort;
- dest->Itemnum = orig->Itemnum;
-
- GSsetTitle(dest, GSgetTitle(orig));
- GSsetPath(dest, GSgetPath(orig));
- GSsetHost(dest, GSgetHost(orig));
- }
-
- /** Compare two GopherObjs ***/
-
- int
- GScmp(gs1, gs2)
- GopherObj *gs1, *gs2;
- {
- if (GSgetTitle(gs1) == NULL)
- return(1);
- if (GSgetTitle(gs2) == NULL)
- return(-1);
-
- return(strcmp(GSgetTitle(gs1), GSgetTitle(gs2)));
- }
-
-
-
-
- /* GSconnect performs a connection to socket 'service' on host
- * 'host'. Host can be a hostname or ip-address. If 'host' is null, the
- * local host is assumed. The parameter full_hostname will, on return,
- * contain the expanded hostname (if possible). Note that full_hostname is a
- * pointer to a char *, and is allocated by connect_to_gopher()
- *
- * Errors:
- *
- * -1 get service failed
- *
- * -2 get host failed
- *
- * -3 socket call failed
- *
- * -4 connect call failed
- */
-
- int
- GSconnect(gs)
- GopherObj *gs;
- {
- struct sockaddr_in Server;
- struct hostent *HostPtr;
- int iSock = 0;
- int ERRinet = -1;
-
- #ifdef _CRAY
- ERRinet = 0xFFFFFFFF; /* -1 doesn't sign extend on 64 bit machines */
- #endif
-
- /*** Find the hostname address ***/
-
- if ((Server.sin_addr.s_addr = inet_addr(GSgetHost(gs))) == ERRinet) {
- if (HostPtr = gethostbyname(GSgetHost(gs))) {
- bzero((char *) &Server, sizeof(Server));
- bcopy(HostPtr->h_addr, (char *) &Server.sin_addr, HostPtr->h_length);
- Server.sin_family = HostPtr->h_addrtype;
- } else
- return (-2);
- } else
- Server.sin_family = AF_INET;
-
- Server.sin_port = (unsigned short) htons(GSgetPort(gs));
-
- /*** Open the socket ***/
-
- if ((iSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return (-3);
-
- #ifndef UCX
- setsockopt(iSock, SOL_SOCKET, ~SO_LINGER, 0, 0);
- #endif
-
- setsockopt(iSock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
- setsockopt(iSock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
-
- /*** Connect ***/
-
- if (connect(iSock, (struct sockaddr *) &Server, sizeof(Server)) < 0) {
- closenet(iSock);
- return (-4);
- }
- return(iSock);
- }
-
- /*
- * GSfromLink takes an open file descriptor and starts reading from it.
- * It keeps going until it findsL
- * enough fields for a gopherobj
- * no data left
- *
- * returns 0 with success, -1 on an error.
- */
-
- #define G_PATH (1<<0)
- #define G_TYPE (1<<1)
- #define G_NAME (1<<2)
- #define G_PORT (1<<3)
- #define G_HOST (1<<4)
- #define G_ALL (G_PATH | G_TYPE | G_NAME | G_PORT | G_HOST)
-
- int
- GSfromLink(gs, fd, host, port)
- GopherObj *gs;
- int fd;
- char *host;
- int port;
- {
- int doneflags = 0;
- char buf[1024];
-
- while ((doneflags != G_ALL) && readline(fd, buf, 1024)) {
- if (buf[0] == '#')
- continue; /* comment */
-
- ZapCRLF(buf);
-
- if (strncmp(buf, "Type=", 5)==0) {
- GSsetType(gs, buf[5]);
- doneflags |= G_TYPE;
- }
-
- if (strncmp(buf, "Name=", 5)==0) {
- GSsetTitle(gs, buf+5);
- doneflags |= G_NAME;
- }
-
- if (strncmp(buf, "Path=", 5)==0) {
- GSsetPath(gs, buf+5);
- doneflags |= G_PATH;
- }
-
- if (strncmp(buf, "Host=", 5)==0) {
- if (buf[5] == '+' && buf[6] == '\0')
- GSsetHost(gs, host);
- else
- GSsetHost(gs, buf+5);
-
- doneflags |= G_HOST;
- }
- if (strncmp(buf, "Port=", 5)==0) {
- if (buf[5] == '+' && buf[6] == '\0')
- GSsetPort(gs, port);
- else
- GSsetPort(gs, atoi(buf+5));
-
- doneflags |= G_PORT;
- }
- if (strncmp(buf, "Numb=", 5)==0)
- GSsetNum(gs, atoi(buf+5));
-
- }
- return ((doneflags == G_ALL) ? 0 : -1); /* 0 == success */
- }
-
-
- void
- GStoLink(gs, fd)
- GopherObj *gs;
- int fd;
- {
- char gtype[2];
- char portnum[16];
-
- gtype[0] = GSgetType(gs);
- gtype[1] = '\0';
-
- writestring(fd, "#");
- writestring(fd, "\nType=");
- writestring(fd, gtype);
- writestring(fd, "\nName=");
- writestring(fd, GSgetTitle(gs));
- writestring(fd, "\nPath=");
- writestring(fd, GSgetPath(gs));
- writestring(fd, "\nHost=");
- writestring(fd, GSgetHost(gs));
- writestring(fd, "\nPort=");
- sprintf(portnum, "%d", GSgetPort(gs));
- writestring(fd, portnum);
- writestring(fd, "\n");
- }
-
-