/* * TCP/IP String IOT routines - TOPS-20 version * * Mark Crispin, SUMEX Computer Project, 4 August 1988 * * Copyright (c) 1988 Stanford University * */ #include #include #include #include #include #include "tcpsio.h" #include "misc.h" /* src:memstr.c */ extern void bcopy(char *,char *,int); #define BUFLEN 8192 typedef struct tcp_stream { char *host; /* host name */ char *localhost; /* local host name */ int jfn; /* jfn for connection */ char ibuf[BUFLEN]; /* input buffer */ } TCPSTREAM; extern void usrlog(); /* TCP/IP open * Accepts: host name * contact port number * Returns: TCP stream if success else NIL */ TCPSTREAM *tcp_open (host,port) char *host; int port; { char tmp[1024]; TCPSTREAM *stream = NIL; int argblk[5]; int jfn; char hostname[128]; char file[128]; argblk[1] = monsym (".GTDPN");/* get IP address and primary name */ argblk[2] = (int) (host-1); /* pointer to host */ argblk[4] = (int) (hostname-1); if (!jsys (GTDOM,argblk)) { /* do it the domain way */ argblk[1] = _GTHSN; /* failed, convert string to number */ if (!jsys (GTHST,argblk)) { /* and do it by host table */ sprintf (tmp,"No such host as %s",host); usrlog (tmp); return (NIL); } argblk[1] = _GTHNS; /* convert number to string */ argblk[2] = (int) (hostname-1); /* get the official name */ if (!jsys (GTHST,argblk)) strcpy (hostname,host); } sprintf (file,"TCP:.%o-%d;PERSIST:30;CONNECTION:ACTIVE",argblk[3],port); argblk[1] = GJ_SHT; /* short form GTJFN% */ argblk[2] = (int) (file-1); /* pointer to file name */ if (!jsys (GTJFN,argblk)) { /* get JFN for TCP: file */ usrlog ("Unable to create TCP JFN"); return (NIL); } jfn = argblk[1]; /* note JFN for later */ /* want 8-bit bidirectional I/O */ argblk[2] = OF_RD|OF_WR|(FLD (8,monsym("OF%BSZ"))); if (!jsys (OPENF,argblk)) { sprintf (tmp,"Can't connect to %s,%d server",hostname,port); usrlog (tmp); return (NIL); } /* create TCP/IP stream */ stream = (TCPSTREAM *) malloc (sizeof (TCPSTREAM)); /* copy official host name */ stream->host = malloc (1+strlen (hostname)); strcpy (stream->host,hostname); argblk[1] = _GTHNS; /* convert number to string */ argblk[2] = (int) (hostname-1); argblk[3] = -1; /* want local host */ if (!jsys (GTDOM,argblk)) /* copy local host name */ if (!jsys (GTHST,argblk)) strcpy (hostname,"LOCAL"); stream->localhost = malloc (1+strlen (hostname)); strcpy (stream->localhost,hostname); stream->jfn = jfn; /* init JFN */ return (stream); } /* TCP/IP receive line * Accepts: TCP/IP stream * Returns: text line string or NIL if failure */ char *tcp_getline (stream) TCPSTREAM *stream; { int argblk[5]; int size; char *line; argblk[1] = stream->jfn; /* read from TCP */ /* pointer to buffer */ argblk[2] = (int) (stream->ibuf-1); argblk[3] = BUFLEN; /* max number of bytes to read */ argblk[4] = '\015'; /* terminate on CR */ if (!jsys (SIN,argblk)) return (NIL); size = BUFLEN-argblk[3]-1; /* number of bytes read (not including CR) */ line = malloc (size+1); /* copy string to free storage */ bcopy (stream->ibuf,line,size); line[size] = '\0'; /* tie off string with null */ jsys (BIN,argblk); /* eat the line feed */ return (line); } /* TCP/IP receive buffer * Accepts: TCP/IP stream * size in bytes * buffer to read into * Returns: T if success, NIL otherwise */ tcp_getbuffer (stream,size,buffer) TCPSTREAM *stream; int size; char *buffer; { int argblk[5]; argblk[1] = stream->jfn; /* read from TCP */ argblk[2] = (int) (buffer-1); /* pointer to buffer */ argblk[3] = -size; /* number of bytes to read */ if (!jsys (SIN,argblk)) return (NIL); buffer[size] = '\0'; /* tie off text */ return (T); } /* TCP/IP send string as record * Accepts: TCP/IP stream * Returns: T if success else NIL */ tcp_soutr (stream,string) TCPSTREAM *stream; char *string; { int argblk[5]; argblk[1] = stream->jfn; /* write to TCP */ argblk[2] = (int) (string-1); /* pointer to buffer */ argblk[3] = 0; /* write until NUL */ if (!jsys (SOUTR,argblk)) return (NIL); return (T); } /* TCP/IP close * Accepts: TCP/IP stream */ void tcp_close (stream) TCPSTREAM *stream; { int argblk[5]; argblk[1] = stream->jfn; /* close TCP */ jsys (CLOSF,argblk); free (stream->host); /* flush host names */ free (stream->localhost); free ((char *) stream); /* flush the stream */ } /* TCP/IP return host for this stream * Accepts: TCP/IP stream * Returns: host name for this stream */ char *tcp_host (stream) TCPSTREAM *stream; { return (stream->host); /* return host name */ } /* TCP/IP return local host for this stream * Accepts: TCP/IP stream * Returns: local host name for this stream */ char *tcp_localhost (stream) TCPSTREAM *stream; { return (stream->localhost); /* return local host name */ }