SMOLNET PORTAL home about changes
/* TCP/IP routines stolen from the VMS GOPHERD */

#include stdio
#include socket
#include in
#include netdb

#if defined(UCX)
#include <errno.h>
#endif
 

#if defined(VMS) && (defined(WOLLONGONG) || defined(MULTINET) || defined(UCX))
/* Multinet and Wollongong (non UCX-emulation) use channel numbers */
/* for sockets, which are small multiples of 16.  The first 5 */
/* channels can be assumed to be already used, so we assume that */
/* sockets start at 64, and that only 64 VAXC fds are simultaneously */
/* open in the program.  Actually, the first socket is likely to be */
/* more like 176! */
#define IS_SOCKET(s) ((s)>=64)
 
/* Close a socket.  
 * Note that in old Wollongong and Multinet implementations close()
 * works only on fds, not sockets.
 * For UCX and Unix, closenet() is #defined to be close()
 */
int closenet(s)
int s;
{
    if (IS_SOCKET(s)) {
#ifdef MULTINET
	return (socket_close(s));
#endif
#ifdef WOLLONGONG
	return (netclose(s));
#endif
#ifdef UCX
	return (close(s));
#endif
    }
    else
	close(s); /* non-channel UCX socket */
}
#endif /* WOLLONGONG or MULTINET or UCX */


/* Read "n" bytes from a descriptor.
 * Use in place of read() when fd is a stream socket
 *
 * Returns the number of total bytes read.
 */

int readn(fd, ptr, nbytes)
  int fd;
  char *ptr;
  int nbytes;
{
     int nleft, nread;
     
     nleft = nbytes;
     while (nleft > 0) {
#if defined(VMS) && defined(WOLLONGONG)
	  nread = IS_SOCKET(fd) ? netread(fd, ptr, nleft) : read(fd, ptr, nleft);
#else
#if defined(VMS) && defined(MULTINET)
	  nread = IS_SOCKET(fd) ? socket_read(fd, ptr, nleft) : read(fd, ptr, nleft);
#else
	  nread = read(fd, ptr, nleft);
#endif
#endif
#if defined(VMS) && defined(UCX)
          if (nread < 0 && errno == EPIPE)
	       break;
#endif
	  if (nread < 0)
	       return(nread);	/* error, return <0 */
	  else if (nread == 0)	/* EOF */
	       break;
	  
	  nleft 	-= nread;
	  ptr 	+= nread;
     }
     return(nbytes - nleft);	/* return >= 0) */
}



/*
 * Write "n" bytes to a descriptor.
 * Use in place of write() when fd is a stream socket
 *
 * We return the number of bytes written
 */

int 
writen(fd, ptr, nbytes)
  int	fd;
  char	*ptr;
  int	nbytes;
{
     int nleft, nwritten;
     
     nleft = nbytes;
     while(nleft > 0) {
#if defined(VMS) && defined(WOLLONGONG)
	  nwritten = IS_SOCKET(fd) ? netwrite(fd, ptr, nleft) : write(fd, ptr, nleft);
#else
#if defined(VMS) && defined(MULTINET)
	  nwritten = IS_SOCKET(fd) ? socket_write(fd, ptr, nleft) : write(fd, ptr, nleft);
#else
	  nwritten = write(fd, ptr, nleft);
#endif
#endif
	  if (nwritten <= 0)
	       return(nwritten);	/* error */
	  
	  nleft	-= nwritten;
	  ptr	+= nwritten;
     }
     return(nbytes - nleft);
}


/*
 * Writestring uses the writen and strlen calls to write a
 * string to the file descriptor fd.  If the write fails
 * a -1 is returned. Otherwise zero is returned.
 */

int writestring(fd, stringptr)
  int	fd;
  char	*stringptr;
{
     int length;

     if (stringptr == NULL)
	  return(0);

     length = strlen(stringptr);
     if (writen(fd, stringptr, length) != length) {
	  return(-1);
     }
     else
	  return(0);
}

/*
 * Read from the socket into a buffer.  Mucho more efficent in terms of
 * system calls..
 * 
 * returns bytes read, or <0 for an error
 */

#define RECVSIZE 4096

int readrecvbuf(sockfd, buf, len)
  int sockfd;
  char *buf;
  int len;
{
     static char recvbuf[RECVSIZE];
     static int  recvbufptr  = 0;
     static int  recvbufsize = 0;
     static int Oldsockfd = 0;
     int bytesread = 0;

     if (recvbufptr == 0 || Oldsockfd != sockfd) {
#if defined(VMS) && defined(WOLLONGONG)
	  recvbufsize = IS_SOCKET(sockfd) ?
		netread(sockfd, recvbuf, RECVSIZE) : read(sockfd, recvbuf, RECVSIZE);
#else
#if defined(VMS) && defined(MULTINET)
	  recvbufsize = IS_SOCKET(sockfd) ?
		socket_read(sockfd, recvbuf, RECVSIZE) : read(sockfd, recvbuf, RECVSIZE);
#else
	  recvbufsize = read(sockfd, recvbuf, RECVSIZE);
#endif
#endif
	  Oldsockfd = sockfd;
	  recvbufptr = 0;
	  if (recvbufsize == 0)
	       return(0);
#if defined(VMS) && defined(UCX)
	  if (recvbufsize < 0 && errno == EPIPE)
	       return(0);
#endif

     }
     
     while (len--) {
	  *buf++ = recvbuf[recvbufptr++];
	  bytesread++;

	  if (recvbufptr == recvbufsize && len != 0) {
	       recvbufsize = readn(sockfd, recvbuf, RECVSIZE);
	       recvbufptr = 0;
	       if (recvbufsize == 0)
		    return(bytesread);
	       if (recvbufsize < 0)
		    return(recvbufsize);

	  } else if (recvbufptr >= recvbufsize)
	       recvbufptr = 0;
     }
     return(bytesread);
}     


/*
 * Read a line from a descriptor.  Read the line one byte at a time,
 * looking for the newline.  We store the newline in the buffer,
 * then follow it with a null (the same as fgets(3)).
 * We return the number of characters up to, but not including,
 * the null (the same as strlen(3))
 */

int readline(fd, ptr, maxlen)
  int	fd;
  char	*ptr;
  int 	maxlen;
{
     int n;
     int rc;
     char c;

     
     for (n=1; n < maxlen; n++) {
	  if ( (rc = readrecvbuf(fd, &c, 1)) == 1) {
	       *ptr++ = c;
	       if (c == '\n')
		    break;
	  }
	  else if (rc == 0) {
	       if (n == 1)
		    return(0);	/* EOF, no data read */
	       else
		    break;		/* EOF, some data was read */
	  }
	  else
	       return(-1);		/* error */
     }
     
     *ptr = 0; 				/* Tack a NULL on the end */

     return(n);
}


/*
 * ZapCRLF removes all carriage returns and linefeeds from a C-string.
 */

void
ZapCRLF(inputline)
  char *inputline;
{
     char *cp;

     cp = strchr(inputline, '\r');    /* Zap CR-LF */
     if (cp != NULL)
	  *cp = '\0';
     else {
	  cp = strchr(inputline, '\n');
	  if (cp != NULL)
	       *cp = '\0';
     }
}


void inet_netnames(int sock, char *host_name)
{
    struct sockaddr_in sa;
    int                length;
    u_long             net_addr;
    struct hostent     *hp;

    length = sizeof(sa);
    getpeername(sock, &sa, &length);
    strcpy(host_name, inet_ntoa(sa.sin_addr));

    hp = gethostbyaddr((char *) &sa.sin_addr,
                       sizeof (sa.sin_addr.s_addr), AF_INET);
     
    if (hp != NULL)
        strcpy(host_name, hp->h_name);
}
.
Response: text/plain
Original URLgopher://bitreich.org/0/gopher2007/2007-gopher-mirror/gop...
Content-Typetext/plain; charset=utf-8