about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation/HTTCP.c
diff options
context:
space:
mode:
Diffstat (limited to 'WWW/Library/Implementation/HTTCP.c')
-rw-r--r--WWW/Library/Implementation/HTTCP.c2182
1 files changed, 0 insertions, 2182 deletions
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
deleted file mode 100644
index 2723422c..00000000
--- a/WWW/Library/Implementation/HTTCP.c
+++ /dev/null
@@ -1,2182 +0,0 @@
-/*
- * $LynxId: HTTCP.c,v 1.107 2012/02/09 12:36:45 tom Exp $
- *
- *			Generic Communication Code		HTTCP.c
- *			==========================
- *
- *	This code is in common between client and server sides.
- *
- *	16 Jan 92  TBL	Fix strtol() undefined on CMU Mach.
- *	25 Jun 92  JFG	Added DECNET option through TCP socket emulation.
- *	13 Sep 93  MD	Added correct return of vmserrorno for HTInetStatus.
- *			Added decoding of vms error message for MULTINET.
- *	7-DEC-1993 Bjorn S. Nilsson, ALEPH, CERN, VMS UCX ioctl() changes
- *			(done of Mosaic)
- *	19 Feb 94  Danny Mayer	Added Bjorn Fixes to Lynx version
- *	 7 Mar 94  Danny Mayer	Added Fix UCX version for full domain name
- *	20 May 94  Andy Harper	Added support for CMU TCP/IP transport
- *	17 Nov 94  Andy Harper	Added support for SOCKETSHR transport
- *	16 Jul 95  S. Bjorndahl added kluge to deal with LIBCMU bug
- */
-
-#include <HTUtils.h>
-#include <HTParse.h>
-#include <HTAlert.h>
-#include <HTTCP.h>
-#include <LYGlobalDefs.h>	/* added for no_suspend */
-#include <LYUtils.h>
-
-#ifdef NSL_FORK
-#include <signal.h>
-#include <www_wait.h>
-#endif /* NSL_FORK */
-
-#ifdef HAVE_RESOLV_H
-#include <resolv.h>
-#endif
-
-#ifdef __DJGPP__
-#include <netdb.h>
-#endif /* __DJGPP__ */
-
-#define LYNX_ADDRINFO	struct addrinfo
-#define LYNX_HOSTENT	struct hostent
-
-#define OK_HOST(p) ((p) != 0 && ((p)->h_length) != 0)
-
-#ifdef SVR4_BSDSELECT
-int BSDselect(int nfds,
-	      fd_set * readfds,
-	      fd_set * writefds,
-	      fd_set * exceptfds,
-	      struct timeval *select_timeout);
-
-#ifdef select
-#undef select
-#endif /* select */
-#define select BSDselect
-#ifdef SOCKS
-#ifdef Rselect
-#undef Rselect
-#endif /* Rselect */
-#define Rselect BSDselect
-#endif /* SOCKS */
-#endif /* SVR4_BSDSELECT */
-
-#include <LYLeaks.h>
-
-/*
- *  Module-Wide variables
- */
-static char *hostname = NULL;	/* The name of this host */
-
-/*
- *  PUBLIC VARIABLES
- */
-#ifdef SOCKS
-unsigned long socks_bind_remoteAddr;	/* for long Rbind */
-#endif /* SOCKS */
-
-/*	Encode INET status (as in sys/errno.h)			  inet_status()
- *	------------------
- *
- *  On entry,
- *	where		gives a description of what caused the error
- *	global errno	gives the error number in the Unix way.
- *
- *  On return,
- *	returns		a negative status in the Unix way.
- */
-
-#ifdef DECL_SYS_ERRLIST
-extern char *sys_errlist[];	/* see man perror on cernvax */
-extern int sys_nerr;
-#endif /* DECL_SYS_ERRLIST */
-
-#ifdef __DJGPP__
-static int ResolveYield(void)
-{
-    return HTCheckForInterrupt()? 0 : 1;
-}
-#endif
-
-#if defined(VMS) && defined(UCX)
-/*
- *  A routine to mimic the ioctl function for UCX.
- *  Bjorn S. Nilsson, 25-Nov-1993. Based on an example in the UCX manual.
- */
-#include <HTioctl.h>
-
-int HTioctl(int d,
-	    int request,
-	    int *argp)
-{
-    int sdc, status;
-    unsigned short fun, iosb[4];
-    char *p5, *p6;
-    struct comm {
-	int command;
-	char *addr;
-    } ioctl_comm;
-    struct it2 {
-	unsigned short len;
-	unsigned short opt;
-	struct comm *addr;
-    } ioctl_desc;
-
-    if ((sdc = vaxc$get_sdc(d)) == 0) {
-	set_errno(EBADF);
-	return -1;
-    }
-    ioctl_desc.opt = UCX$C_IOCTL;
-    ioctl_desc.len = sizeof(struct comm);
-
-    ioctl_desc.addr = &ioctl_comm;
-    if (request & IOC_OUT) {
-	fun = IO$_SENSEMODE;
-	p5 = 0;
-	p6 = (char *) &ioctl_desc;
-    } else {
-	fun = IO$_SETMODE;
-	p5 = (char *) &ioctl_desc;
-	p6 = 0;
-    }
-    ioctl_comm.command = request;
-    ioctl_comm.addr = (char *) argp;
-    status = sys$qiow(0, sdc, fun, iosb, 0, 0, 0, 0, 0, 0, p5, p6);
-    if (!(status & 01)) {
-	set_errno(status);
-	return -1;
-    }
-    if (!(iosb[0] & 01)) {
-	set_errno(iosb[0]);
-	return -1;
-    }
-    return 0;
-}
-#endif /* VMS && UCX */
-
-#define MY_FORMAT "TCP: Error %d in `SOCKET_ERRNO' after call to %s() failed.\n\t%s\n"
-	   /* third arg is transport/platform specific */
-
-/*	Report Internet Error
- *	---------------------
- */
-int HTInetStatus(const char *where)
-{
-    int status;
-    int saved_errno = errno;
-
-#ifdef VMS
-#ifdef MULTINET
-    SOCKET_ERRNO = vmserrno;
-#endif /* MULTINET */
-#endif /* VMS */
-
-#ifdef VM
-    CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where,
-	    "(Error number not translated)"));	/* What Is the VM equiv? */
-#define ER_NO_TRANS_DONE
-#endif /* VM */
-
-#ifdef VMS
-#ifdef MULTINET
-    CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where,
-	    vms_errno_string()));
-#else
-    CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where,
-	    ((SOCKET_ERRNO > 0 && SOCKET_ERRNO <= 65) ?
-	     strerror(SOCKET_ERRNO) : "(Error number not translated)")));
-#endif /* MULTINET */
-#define ER_NO_TRANS_DONE
-#endif /* VMS */
-
-#ifdef HAVE_STRERROR
-    CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where,
-	    strerror(SOCKET_ERRNO)));
-#define ER_NO_TRANS_DONE
-#endif /* HAVE_STRERROR */
-
-#ifndef ER_NO_TRANS_DONE
-    CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where,
-	    (SOCKET_ERRNO < sys_nerr ?
-	     sys_errlist[SOCKET_ERRNO] : "Unknown error")));
-#endif /* !ER_NO_TRANS_DONE */
-
-#ifdef VMS
-#ifndef MULTINET
-    CTRACE((tfp,
-	    "         Unix error number (SOCKET_ERRNO) = %ld dec\n",
-	    SOCKET_ERRNO));
-    CTRACE((tfp,
-	    "         VMS error (vaxc$errno)    = %lx hex\n",
-	    vaxc$errno));
-#endif /* MULTINET */
-#endif /* VMS */
-
-    set_errno(saved_errno);
-
-#ifdef VMS
-    /*
-     * uerrno and errno happen to be zero if vmserrno <> 0
-     */
-#ifdef MULTINET
-    status = -vmserrno;
-#else
-    status = -vaxc$errno;
-#endif /* MULTINET */
-#else
-    status = -SOCKET_ERRNO;
-#endif /* VMS */
-    return status;
-}
-
-/*	Parse a cardinal value				       parse_cardinal()
- *	----------------------
- *
- * On entry,
- *	*pp	    points to first character to be interpreted, terminated by
- *		    non 0:9 character.
- *	*pstatus    points to status already valid
- *	maxvalue    gives the largest allowable value.
- *
- * On exit,
- *	*pp	    points to first unread character
- *	*pstatus    points to status updated iff bad
- */
-unsigned int HTCardinal(int *pstatus,
-			char **pp,
-			unsigned int max_value)
-{
-    unsigned int n;
-
-    if ((**pp < '0') || (**pp > '9')) {		/* Null string is error */
-	*pstatus = -3;		/* No number where one expected */
-	return 0;
-    }
-
-    n = 0;
-    while ((**pp >= '0') && (**pp <= '9'))
-	n = n * 10 + (unsigned) (*((*pp)++) - '0');
-
-    if (n > max_value) {
-	*pstatus = -4;		/* Cardinal outside range */
-	return 0;
-    }
-
-    return n;
-}
-
-#ifndef DECNET			/* Function only used below for a trace message */
-/*	Produce a string for an Internet address
- *	----------------------------------------
- *
- *  On exit,
- *	returns a pointer to a static string which must be copied if
- *		it is to be kept.
- */
-const char *HTInetString(SockA * soc_in)
-{
-#ifdef INET6
-    static char hostbuf[MAXHOSTNAMELEN];
-
-    getnameinfo((struct sockaddr *) soc_in,
-		SOCKADDR_LEN(soc_in),
-		hostbuf, (socklen_t) sizeof(hostbuf),
-		NULL, 0,
-		NI_NUMERICHOST);
-    return hostbuf;
-#else
-    static char string[20];
-
-    sprintf(string, "%d.%d.%d.%d",
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 0),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 1),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 2),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 3));
-    return string;
-#endif /* INET6 */
-}
-#endif /* !DECNET */
-
-/*	Check whether string is a valid Internet hostname - kw
- *	-------------------------------------------------
- *
- *  Checks whether
- *  - contains only valid chars for domain names (actually, the
- *    restrictions are somewhat relaxed),
- *  - no leading dots or empty segments,
- *  - no segment starts with '-' or '+' [this protects telnet command],
- *  - max. length of dot-separated segment <= 63 (RFC 1034,1035),
- *  - total length <= 254 (if it ends with dot) or 253 (otherwise)
- *     [an interpretation of RFC 1034,1035, although RFC 1123
- *      suggests 255 as limit - kw].
- *
- *  Note: user (before '@') and port (after ':') components from
- *      host part of URL should be already stripped (if appropriate)
- *      from the input string.
- *
- *  On exit,
- *	returns 1 if valid, otherwise 0.
- */
-BOOL valid_hostname(char *name)
-{
-    int i = 1, iseg = 0;
-    char *cp = name;
-
-    if (!(name && *name))
-	return NO;
-    for (; (*cp && i <= 253); cp++, i++) {
-	if (*cp == '.') {
-	    if (iseg == 0) {
-		return NO;
-	    } else {
-		iseg = 0;
-		continue;
-	    }
-	} else if (iseg == 0 && (*cp == '-' || *cp == '+')) {
-	    return NO;
-	} else if (++iseg > 63) {
-	    return NO;
-	}
-	if (!isalnum(UCH(*cp)) &&
-	    *cp != '-' && *cp != '_' &&
-	    *cp != '$' && *cp != '+') {
-	    return NO;
-	}
-    }
-    return (BOOL) (*cp == '\0' || (*cp == '.' && iseg != 0 && cp[1] == '\0'));
-}
-
-#ifdef NSL_FORK
-/*
- *  Function to allow us to be killed with a normal signal (not
- *  SIGKILL), but don't go through normal libc exit() processing, which
- *  would screw up parent's stdio.  -BL
- */
-static void quench(int sig GCC_UNUSED)
-{
-    _exit(2);
-}
-#endif /* NSL_FORK */
-
-int lynx_nsl_status = HT_OK;
-
-#define DEBUG_HOSTENT		/* disable in case of problems */
-#define DEBUG_HOSTENT_CHILD	/* for NSL_FORK, may screw up trace file */
-
-/*
- *  Two auxiliary functions for name lookup and LYNX_HOSTENT.
- *
- *  dump_hostent - dumps the contents of a LYNX_HOSTENT to the
- *  trace log or stderr, including all pointer values, strings, and
- *  addresses, in a format inspired by gdb's print format. - kw
- */
-static void dump_hostent(const char *msgprefix,
-			 const LYNX_HOSTENT *phost)
-{
-    if (TRACE) {
-	int i;
-	char **pcnt;
-
-	CTRACE((tfp, "%s: %p ", msgprefix, (const void *) phost));
-	if (phost) {
-	    CTRACE((tfp, "{ h_name = %p", phost->h_name));
-	    if (phost->h_name) {
-		CTRACE((tfp, " \"%s\",", phost->h_name));
-	    } else {
-		CTRACE((tfp, ","));
-	    }
-	    CTRACE((tfp, "\n\t h_aliases = %p", (void *) phost->h_aliases));
-	    if (phost->h_aliases) {
-		CTRACE((tfp, " {"));
-		for (pcnt = phost->h_aliases; *pcnt; pcnt++) {
-		    CTRACE((tfp, "%s %p \"%s\"",
-			    (pcnt == phost->h_aliases ? " " : ", "),
-			    *pcnt, *pcnt));
-		}
-		CTRACE((tfp, "%s0x0 },\n\t",
-			(*phost->h_aliases ? ", " : " ")));
-	    } else {
-		CTRACE((tfp, ",\n\t"));
-	    }
-	    CTRACE((tfp, " h_addrtype = %d,", phost->h_addrtype));
-	    CTRACE((tfp, " h_length = %d,\n\t", phost->h_length));
-	    CTRACE((tfp, " h_addr_list = %p", (void *) phost->h_addr_list));
-	    if (phost->h_addr_list) {
-		CTRACE((tfp, " {"));
-		for (pcnt = phost->h_addr_list; *pcnt; pcnt++) {
-		    CTRACE((tfp, "%s %p",
-			    (pcnt == phost->h_addr_list ? "" : ","),
-			    *pcnt));
-		    for (i = 0; i < phost->h_length; i++) {
-			CTRACE((tfp, "%s%d%s", (i == 0 ? " \"" : "."),
-				(int) *((unsigned char *) (*pcnt) + i),
-				(i + 1 == phost->h_length ? "\"" : "")));
-		    }
-		}
-		if (*phost->h_addr_list) {
-		    CTRACE((tfp, ", 0x0 } }"));
-		} else {
-		    CTRACE((tfp, " 0x0 } }"));
-		}
-	    } else {
-		CTRACE((tfp, "}"));
-	    }
-	}
-	CTRACE((tfp, "\n"));
-	fflush(tfp);
-    }
-}
-
-/*
- *  fill_rehostent - copies as much as possible relevant content from
- *  the LYNX_HOSTENT pointed to by phost to the char buffer given
- *  by rehostent, subject to maximum output length rehostentsize,
- *  following pointers and building self-contained output which can be
- *  cast to a LYNX_HOSTENT. - kw
- *  See also description of LYGetHostByName.
- */
-#if defined(NSL_FORK) || defined(_WINDOWS_NSL)
-
-#define REHOSTENT_SIZE 128	/* not bigger than pipe buffer! */
-
-typedef struct {
-    LYNX_HOSTENT h;
-    char rest[REHOSTENT_SIZE];
-} AlignedHOSTENT;
-
-static size_t fill_rehostent(char *rehostent,
-			     size_t rehostentsize,
-			     const LYNX_HOSTENT *phost)
-{
-    AlignedHOSTENT *data = (AlignedHOSTENT *) (void *) rehostent;
-    int num_addrs = 0;
-    int num_aliases = 0;
-    char **pcnt;
-    char *p_next_char;
-    char **p_next_charptr;
-    size_t name_len = 0;
-    size_t required_per_addr;
-    size_t curlen = sizeof(LYNX_HOSTENT);
-    size_t available = rehostentsize - curlen;
-    size_t chk_available, mem_this_alias, required_this_alias;
-    int i_addr, i_alias;
-
-    if (!phost)
-	return 0;
-    required_per_addr = (size_t) phost->h_length + sizeof(char *);
-
-    if (phost->h_addr_list)
-	available -= sizeof(phost->h_addr_list[0]);
-    if (phost->h_aliases)
-	available -= sizeof(phost->h_aliases[0]);
-    if (phost->h_name)
-	available--;
-    if (phost->h_addr_list) {
-	if (phost->h_addr_list[0]) {
-	    if (available >= required_per_addr) {
-		num_addrs++;
-		available -= required_per_addr;
-	    }
-	}
-    }
-    if (phost->h_name) {
-	name_len = strlen(phost->h_name);
-	if (available >= name_len) {
-	    available -= name_len;
-	} else {
-	    name_len = 0;
-	}
-    }
-    if (num_addrs) {
-	for (pcnt = phost->h_addr_list + 1; *pcnt; pcnt++) {
-	    if (available >= required_per_addr) {
-		num_addrs++;
-		available -= required_per_addr;
-	    } else {
-		break;
-	    }
-	}
-    }
-    chk_available = available;
-    if (phost->h_aliases) {
-	for (pcnt = phost->h_aliases; *pcnt; pcnt++) {
-	    required_this_alias = sizeof(phost->h_aliases[0]) +
-		strlen(*pcnt) + 1;
-	    if (chk_available >= required_this_alias) {
-		num_aliases++;
-		chk_available -= required_this_alias;
-	    }
-	}
-    }
-
-    data->h.h_addrtype = phost->h_addrtype;
-    data->h.h_length = phost->h_length;
-    p_next_charptr = (char **) (void *) (rehostent + curlen);
-    p_next_char = rehostent + curlen;
-    if (phost->h_addr_list)
-	p_next_char += (size_t) (num_addrs + 1) * sizeof(phost->h_addr_list[0]);
-    if (phost->h_aliases)
-	p_next_char += (size_t) (num_aliases + 1) * sizeof(phost->h_aliases[0]);
-
-    if (phost->h_addr_list) {
-	data->h.h_addr_list = p_next_charptr;
-	for (pcnt = phost->h_addr_list, i_addr = 0;
-	     i_addr < num_addrs;
-	     pcnt++, i_addr++) {
-	    MemCpy(p_next_char, *pcnt, sizeof(phost->h_addr_list[0]));
-	    *p_next_charptr++ = p_next_char;
-	    p_next_char += sizeof(phost->h_addr_list[0]);
-	}
-	*p_next_charptr = NULL;
-    } else {
-	data->h.h_addr_list = NULL;
-    }
-
-    if (phost->h_name) {
-	data->h.h_name = p_next_char;
-	if (name_len) {
-	    strcpy(p_next_char, phost->h_name);
-	    p_next_char += name_len + 1;
-	} else {
-	    *p_next_char++ = '\0';
-	}
-    } else {
-	data->h.h_name = NULL;
-    }
-
-    if (phost->h_aliases) {
-	data->h.h_aliases = p_next_charptr;
-	for (pcnt = phost->h_aliases, i_alias = 0;
-	     (*pcnt && i_alias < num_addrs);
-	     pcnt++, i_alias++) {
-	    mem_this_alias = strlen(*pcnt) + 1;
-	    required_this_alias = sizeof(phost->h_aliases[0]) +
-		mem_this_alias;
-	    if (available >= required_this_alias) {
-		i_alias++;
-		available -= required_this_alias;
-		strcpy(p_next_char, *pcnt);
-		*p_next_charptr++ = p_next_char;
-		p_next_char += mem_this_alias;
-	    }
-	    p_next_char += sizeof(phost->h_aliases[0]);
-	}
-	*p_next_charptr = NULL;
-    } else {
-	data->h.h_aliases = NULL;
-    }
-    curlen = (size_t) (p_next_char - (char *) rehostent);
-    return curlen;
-}
-
-/*
- * This chunk of code is used in both win32 and cygwin.
- */
-#if defined(_WINDOWS_NSL)
-static LYNX_HOSTENT *gbl_phost;	/* Pointer to host - See netdb.h */
-
-#if !(defined(__CYGWIN__) && defined(NSL_FORK))
-static int donelookup;
-
-static unsigned long __stdcall _fork_func(void *arg)
-{
-    const char *host = (const char *) arg;
-    static AlignedHOSTENT aligned_full_rehostent;
-    char *rehostent = (char *) &aligned_full_rehostent;
-    size_t rehostentlen = 0;
-
-#ifdef SH_EX
-    unsigned long addr;
-
-    addr = (unsigned long) inet_addr(host);
-    if (addr != INADDR_NONE)
-	gbl_phost = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
-    else
-	gbl_phost = gethostbyname(host);
-#else
-    gbl_phost = gethostbyname(host);
-#endif
-
-    if (gbl_phost) {
-	rehostentlen = fill_rehostent(rehostent,
-				      (size_t) REHOSTENT_SIZE,
-				      gbl_phost);
-	if (rehostentlen == 0) {
-	    gbl_phost = (LYNX_HOSTENT *) NULL;
-	} else {
-	    gbl_phost = (LYNX_HOSTENT *) rehostent;
-	}
-    }
-
-    donelookup = TRUE;
-    return (unsigned long) (gbl_phost);
-}
-#endif /* __CYGWIN__ */
-#endif /* _WINDOWS_NSL */
-#endif /* NSL_FORK */
-
-#ifndef HAVE_H_ERRNO
-#undef  h_errno
-#define h_errno my_errno
-static int my_errno;
-
-#else /* we do HAVE_H_ERRNO: */
-#ifndef h_errno			/* there may be a macro as well as the extern data */
-extern int h_errno;
-#endif
-#endif
-
-/*
- * Even though it is a small amount, we cannot count on reading the whole
- * struct via a pipe in one read -TD
- */
-#ifdef NSL_FORK
-static unsigned readit(int fd, char *buffer, size_t length)
-{
-    unsigned result = 0;
-
-    while (length != 0) {
-	unsigned got = (unsigned) read(fd, buffer, length);
-
-	if ((int) got > 0) {
-	    result += got;
-	    buffer += got;
-	    length -= got;
-	} else {
-	    break;
-	}
-    }
-    return result;
-}
-#endif /* NSL_FORK */
-
-/*	Resolve an internet hostname, like gethostbyname
- *	------------------------------------------------
- *
- *  On entry,
- *	str	points to the given host name, not numeric address,
- *		without colon or port number.
- *
- *  On exit,
- *	returns a pointer to a LYNX_HOSTENT in static storage,
- *	or NULL in case of error or user interruption.
- *
- *  The interface is intended to be exactly the same as for (Unix)
- *  gethostbyname(), except for the following:
- *
- *  If NSL_FORK is not used, the result of gethostbyname is returned
- *  directly.  Otherwise:
- *  All lists, addresses, and strings referred to by pointers in the
- *  returned struct are located, together with the returned struct
- *  itself, in a buffer of size REHOSTENT_SIZE.  If not everything fits,
- *  some info is omitted, but the function is careful to still return
- *  a valid structure, without truncating strings; it tries to return,
- *  in order of decreasing priority, the first address (h_addr_list[0]), the
- *  official name (h_name), the additional addresses, then alias names.
- *
- *  If NULL is returned, the reason is made available in the global
- *  variable lynx_nsl_status, with one of the following values:
- *	HT_INTERRUPTED		Interrupted by user
- *	HT_NOT_ACCEPTABLE	Hostname detected as invalid
- *				(also sets h_errno)
- *	HT_H_ERRNO_VALID	An error occurred, and h_errno holds
- *				an appropriate value
- *	HT_ERROR		Resolver error, reason not known
- *	HT_INTERNAL		Internal error
- */
-LYNX_HOSTENT *LYGetHostByName(char *str)
-{
-    char *host = str;
-
-#ifdef NSL_FORK
-    /* for transfer of result between from child to parent: */
-    static AlignedHOSTENT aligned_full_rehostent;
-
-    /*
-     * We could define rehosten directly as a static char
-     * rehostent[REHOSTENT_SIZE], but the indirect approach via the above
-     * struct should automatically take care of alignment requirements.
-     * Note that, in addition,
-     * - this must be static, as we shall return a pointer to it which must
-     *   remain valid, and
-     * - we have to use the same rehostent in the child process as in the
-     *   parent (its address in the parent's address space must be the same as
-     *   in the child's, otherwise the internal pointers built by the child's
-     *   call to fill_rehostent would be invalid when seen by the parent).  -kw
-     */
-    void *rehostent = (void *) &aligned_full_rehostent;
-
-    /* for transfer of status from child to parent: */
-    struct _statuses {
-	size_t rehostentlen;
-	int h_length;
-	int child_errno;	/* sometimes useful to pass this on */
-	int child_h_errno;
-	BOOL h_errno_valid;
-    } statuses;
-
-    size_t rehostentlen = 0;
-#endif /* NSL_FORK */
-
-    LYNX_HOSTENT *result_phost = NULL;
-
-#ifdef __DJGPP__
-    _resolve_hook = ResolveYield;
-#endif
-
-    if (!str) {
-	CTRACE((tfp, "LYGetHostByName: Can't parse `NULL'.\n"));
-	lynx_nsl_status = HT_INTERNAL;
-	return NULL;
-    }
-    CTRACE((tfp, "LYGetHostByName: parsing `%s'.\n", str));
-
-    /*  Could disable this if all our callers already check - kw */
-    if (HTCheckForInterrupt()) {
-	CTRACE((tfp, "LYGetHostByName: INTERRUPTED for '%s'.\n", str));
-	lynx_nsl_status = HT_INTERRUPTED;
-	return NULL;
-    }
-
-    if (!valid_hostname(host)) {
-	lynx_nsl_status = HT_NOT_ACCEPTABLE;
-#ifdef NO_RECOVERY
-#ifdef _WINDOWS
-	WSASetLastError(NO_RECOVERY);
-#else
-	h_errno = NO_RECOVERY;
-#endif
-#endif
-	return NULL;
-    }
-#ifdef MVS			/* Outstanding problem with crash in MVS gethostbyname */
-    CTRACE((tfp, "LYGetHostByName: Calling gethostbyname(%s)\n", host));
-#endif /* MVS */
-
-    CTRACE_FLUSH(tfp);		/* so child messages will not mess up parent log */
-
-    lynx_nsl_status = HT_INTERNAL;	/* should be set to something else below */
-
-#ifdef NSL_FORK
-    statuses.h_errno_valid = NO;
-    /*
-     * Start block for fork-based gethostbyname() with checks for interrupts.
-     * - Tom Zerucha (tz@execpc.com) & FM
-     */
-    {
-	int got_rehostent = 0;
-
-#if HAVE_SIGACTION
-	sigset_t old_sigset;
-	sigset_t new_sigset;
-#endif
-	/*
-	 * Pipe, child pid, status buffers, start time, select() control
-	 * variables.
-	 */
-	int fpid, waitret;
-	int pfd[2], selret;
-	unsigned readret;
-
-#ifdef HAVE_TYPE_UNIONWAIT
-	union wait waitstat;
-
-#else
-	int waitstat = 0;
-#endif
-	time_t start_time = time((time_t *) 0);
-	fd_set readfds;
-	struct timeval one_second;
-	long dns_patience = 30;	/* how many seconds will we wait for DNS? */
-	int child_exited = 0;
-
-	/*
-	 * Reap any children that have terminated since last time through.
-	 * This might include children that we killed, then waited with WNOHANG
-	 * before they were actually ready to be reaped.  (Should be max of 1
-	 * in this state, but the loop is safe if waitpid() is implemented
-	 * correctly:  returns 0 when children exist but none have exited; -1
-	 * with errno == ECHILD when no children.) -BL
-	 */
-	do {
-	    waitret = waitpid(-1, 0, WNOHANG);
-	} while (waitret > 0 || (waitret == -1 && errno == EINTR));
-	waitret = 0;
-
-	IGNORE_RC(pipe(pfd));
-
-#if HAVE_SIGACTION
-	/*
-	 * Attempt to prevent a rare situation where the child could execute
-	 * the Lynx signal handlers because it gets killed before it even has a
-	 * chance to reset its handlers, resulting in bogus 'Exiting via
-	 * interrupt' message and screen corruption or worse.
-	 * Should that continue to be reported, for systems without
-	 * sigprocmask(), we need to find a different solutions for those.  -
-	 * kw 19990430
-	 */
-	sigemptyset(&new_sigset);
-	sigaddset(&new_sigset, SIGTERM);
-	sigaddset(&new_sigset, SIGINT);
-#ifndef NOSIGHUP
-	sigaddset(&new_sigset, SIGHUP);
-#endif /* NOSIGHUP */
-#ifdef SIGTSTP
-	sigaddset(&new_sigset, SIGTSTP);
-#endif /* SIGTSTP */
-#ifdef SIGWINCH
-	sigaddset(&new_sigset, SIGWINCH);
-#endif /* SIGWINCH */
-	sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);
-#endif /* HAVE_SIGACTION */
-
-	if ((fpid = fork()) == 0) {
-	    LYNX_HOSTENT *phost;	/* Pointer to host - See netdb.h */
-
-	    /*
-	     * Child - for the long call.
-	     *
-	     * Make sure parent can kill us at will.  -BL
-	     */
-	    (void) signal(SIGTERM, quench);
-
-	    /*
-	     * Also make sure the child does not run one of the signal handlers
-	     * that may have been installed by Lynx if one of those signals
-	     * occurs.  For example we don't want the child to remove temp
-	     * files on ^C, let the parent deal with that.  - kw
-	     */
-	    (void) signal(SIGINT, quench);
-#ifndef NOSIGHUP
-	    (void) signal(SIGHUP, quench);
-#endif /* NOSIGHUP */
-#ifdef SIGTSTP
-	    if (no_suspend)
-		(void) signal(SIGTSTP, SIG_IGN);
-	    else
-		(void) signal(SIGTSTP, SIG_DFL);
-#endif /* SIGTSTP */
-#ifdef SIGWINCH
-	    (void) signal(SIGWINCH, SIG_IGN);
-#endif /* SIGWINCH */
-#ifndef __linux__
-#ifndef DOSPATH
-	    signal(SIGBUS, SIG_DFL);
-#endif /* DOSPATH */
-#endif /* !__linux__ */
-	    signal(SIGSEGV, SIG_DFL);
-	    signal(SIGILL, SIG_DFL);
-
-#if HAVE_SIGACTION
-	    /* Restore signal mask to whatever it was before the fork. -kw */
-	    sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-#endif /* HAVE_SIGACTION */
-
-	    /*
-	     * Child won't use read side.  -BL
-	     */
-	    close(pfd[0]);
-#ifdef HAVE_H_ERRNO
-	    /* to detect cases when it doesn't get set although it should */
-	    h_errno = -2;
-#endif
-	    set_errno(0);
-	    phost = gethostbyname(host);
-	    statuses.child_errno = errno;
-	    statuses.child_h_errno = h_errno;
-#ifdef HAVE_H_ERRNO
-	    statuses.h_errno_valid = YES;
-#endif
-#ifdef MVS
-	    CTRACE((tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost));
-#endif /* MVS */
-
-#ifdef DEBUG_HOSTENT_CHILD
-	    dump_hostent("CHILD gethostbyname", phost);
-#endif
-	    if (OK_HOST(phost)) {
-		rehostentlen = fill_rehostent(rehostent,
-					      (size_t) REHOSTENT_SIZE,
-					      phost);
-#ifdef DEBUG_HOSTENT_CHILD
-		dump_hostent("CHILD fill_rehostent", (LYNX_HOSTENT *) rehostent);
-#endif
-	    }
-	    if (rehostentlen <= sizeof(LYNX_HOSTENT) ||
-		!OK_HOST((LYNX_HOSTENT *) rehostent)) {
-		rehostentlen = 0;
-		statuses.h_length = 0;
-	    } else {
-		statuses.h_length = ((LYNX_HOSTENT *) rehostent)->h_length;
-#ifdef HAVE_H_ERRNO
-		if (h_errno == -2)	/* success, but h_errno unchanged? */
-		    statuses.h_errno_valid = NO;
-#endif
-	    }
-	    /*
-	     * Send variables indicating status of lookup to parent.  That
-	     * includes rehostentlen, which the parent will use as the size for
-	     * the second read (if > 0).
-	     */
-	    if (!statuses.child_errno)
-		statuses.child_errno = errno;
-	    statuses.rehostentlen = rehostentlen;
-	    IGNORE_RC(write(pfd[1], &statuses, sizeof(statuses)));
-
-	    if (rehostentlen) {
-		/*
-		 * Return our resulting rehostent through pipe...
-		 */
-		IGNORE_RC(write(pfd[1], rehostent, rehostentlen));
-		close(pfd[1]);
-		_exit(0);
-	    } else {
-		/*
-		 * ...  or return error as exit code.
-		 */
-		_exit(1);
-	    }
-	}
-#if HAVE_SIGACTION
-	/*
-	 * (parent) Restore signal mask to whatever it was before the fork.  -
-	 * kw
-	 */
-	sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-#endif /* HAVE_SIGACTION */
-
-	/*
-	 * (parent) Wait until lookup finishes, or interrupt, or cycled too
-	 * many times (just in case) -BL
-	 */
-
-	close(pfd[1]);		/* parent won't use write side -BL */
-
-	if (fpid < 0) {		/* fork failed */
-	    close(pfd[0]);
-	    goto failed;
-	}
-
-	while (child_exited || (long) (time((time_t *) 0) - start_time) < dns_patience) {
-
-	    FD_ZERO(&readfds);
-	    /*
-	     * This allows us to abort immediately, not after 1-second timeout,
-	     * when user hits abort key.  Can't do this when using SLANG (or at
-	     * least I don't know how), so SLANG users must live with up-to-1s
-	     * timeout.  -BL
-	     *
-	     * Whoops -- we need to make sure stdin is actually selectable!
-	     * /dev/null isn't, on some systems, which makes some useful Lynx
-	     * invocations fail.  -BL
-	     */
-	    {
-		int kbd_fd = LYConsoleInputFD(TRUE);
-
-		if (kbd_fd != INVSOC) {
-		    FD_SET(kbd_fd, &readfds);
-		}
-	    }
-
-	    one_second.tv_sec = 1;
-	    one_second.tv_usec = 0;
-	    FD_SET(pfd[0], &readfds);
-
-	    /*
-	     * Return when data received, interrupted, or failed.  If nothing
-	     * is waiting, we sleep for 1 second in select(), to be nice to the
-	     * system.  -BL
-	     */
-#ifdef SOCKS
-	    if (socks_flag)
-		selret = Rselect(pfd[0] + 1, &readfds, NULL, NULL, &one_second);
-	    else
-#endif /* SOCKS */
-		selret = select(pfd[0] + 1, &readfds, NULL, NULL, &one_second);
-
-	    if ((selret > 0) && FD_ISSET(pfd[0], &readfds)) {
-		/*
-		 * First get status, including length of address.  -BL, kw
-		 */
-		readret = readit(pfd[0], (char *) &statuses, sizeof(statuses));
-		if (readret == sizeof(statuses)) {
-		    h_errno = statuses.child_h_errno;
-		    set_errno(statuses.child_errno);
-#ifdef HAVE_H_ERRNO
-		    if (statuses.h_errno_valid) {
-			lynx_nsl_status = HT_H_ERRNO_VALID;
-			/*
-			 * If something went wrong in the child process other
-			 * than normal lookup errors, and it appears that we
-			 * have enough info to know what went wrong, generate
-			 * diagnostic output.  ENOMEM observed on linux in
-			 * processes constrained with ulimit.  It would be too
-			 * unkind to abort the session, access to local files
-			 * or through a proxy may still work.  - kw
-			 */
-			if (
-#ifdef NETDB_INTERNAL		/* linux glibc: defined in netdb.h */
-			       (errno && h_errno == NETDB_INTERNAL) ||
-#endif
-			       (errno == ENOMEM &&
-				statuses.rehostentlen == 0 &&
-			/* should probably be NETDB_INTERNAL if child
-			   memory exhausted, but we may find that
-			   h_errno remains unchanged. - kw */
-				h_errno == -2)) {
-#ifndef MULTINET
-			    HTInetStatus("CHILD gethostbyname");
-#endif
-			    HTAlert(LYStrerror(statuses.child_errno));
-			    if (errno == ENOMEM) {
-				/*
-				 * Not much point in continuing, right?  Fake a
-				 * 'z', should shorten pointless guessing
-				 * cycle.  - kw
-				 */
-				LYFakeZap(YES);
-			    }
-			}
-		    }
-#endif /* HAVE_H_ERRNO */
-		    if (statuses.rehostentlen > sizeof(LYNX_HOSTENT)) {
-			/*
-			 * Then get the full reorganized hostent.  -BL, kw
-			 */
-			readret = readit(pfd[0], rehostent, statuses.rehostentlen);
-#ifdef DEBUG_HOSTENT
-			dump_hostent("Read from pipe", (LYNX_HOSTENT *) rehostent);
-#endif
-			if (readret == statuses.rehostentlen) {
-			    got_rehostent = 1;
-			    result_phost = (LYNX_HOSTENT *) rehostent;
-			    lynx_nsl_status = HT_OK;
-			} else if (!statuses.h_errno_valid) {
-			    lynx_nsl_status = HT_INTERNAL;
-			}
-		    }
-		} else {
-		    lynx_nsl_status = HT_ERROR;
-		}
-		/*
-		 * Make sure child is cleaned up.  -BL
-		 */
-		if (!child_exited)
-		    waitret = waitpid(fpid, &waitstat, WNOHANG);
-		if (!WIFEXITED(waitstat) && !WIFSIGNALED(waitstat)) {
-		    kill(fpid, SIGTERM);
-		    waitret = waitpid(fpid, &waitstat, WNOHANG);
-		}
-		break;
-	    }
-
-	    /*
-	     * Clean up if child exited before & no data received.  -BL
-	     */
-	    if (child_exited) {
-		waitret = waitpid(fpid, &waitstat, WNOHANG);
-		break;
-	    }
-	    /*
-	     * If child exited, loop once more looking for data.  -BL
-	     */
-	    if ((waitret = waitpid(fpid, &waitstat, WNOHANG)) > 0) {
-		/*
-		 * Data will be arriving right now, so make sure we don't
-		 * short-circuit out for too many loops, and skip the interrupt
-		 * check.  -BL
-		 */
-		child_exited = 1;
-		continue;
-	    }
-
-	    /*
-	     * Abort if interrupt key pressed.
-	     */
-	    if (HTCheckForInterrupt()) {
-		CTRACE((tfp, "LYGetHostByName: INTERRUPTED gethostbyname.\n"));
-		kill(fpid, SIGTERM);
-		waitpid(fpid, NULL, WNOHANG);
-		close(pfd[0]);
-		lynx_nsl_status = HT_INTERRUPTED;
-		return NULL;
-	    }
-	}
-	close(pfd[0]);
-	if (waitret <= 0) {
-	    kill(fpid, SIGTERM);
-	    waitret = waitpid(fpid, &waitstat, WNOHANG);
-	}
-	if (waitret > 0) {
-	    if (WIFEXITED(waitstat)) {
-		CTRACE((tfp,
-			"LYGetHostByName: NSL_FORK child %d exited, status 0x%x.\n",
-			(int) waitret, WEXITSTATUS(waitstat)));
-	    } else if (WIFSIGNALED(waitstat)) {
-		CTRACE((tfp,
-			"LYGetHostByName: NSL_FORK child %d got signal, status 0x%x!\n",
-			(int) waitret, WTERMSIG(waitstat)));
-#ifdef WCOREDUMP
-		if (WCOREDUMP(waitstat)) {
-		    CTRACE((tfp,
-			    "LYGetHostByName: NSL_FORK child %d dumped core!\n",
-			    (int) waitret));
-		}
-#endif /* WCOREDUMP */
-	    } else if (WIFSTOPPED(waitstat)) {
-		CTRACE((tfp,
-			"LYGetHostByName: NSL_FORK child %d is stopped, status 0x%x!\n",
-			(int) waitret, WSTOPSIG(waitstat)));
-	    }
-	}
-	if (!got_rehostent) {
-	    goto failed;
-	}
-    }
-#else /* Not NSL_FORK: */
-
-#ifdef _WINDOWS_NSL
-    {
-	HANDLE hThread;
-	DWORD dwThreadID;
-
-#ifndef __CYGWIN__
-	if (!system_is_NT) {	/* for Windows9x */
-	    unsigned long t;
-
-	    t = (unsigned long) inet_addr(host);
-	    if (t != INADDR_NONE)
-		gbl_phost = gethostbyaddr((char *) &t, sizeof(t), AF_INET);
-	    else
-		gbl_phost = gethostbyname(host);
-	} else {		/* for Windows NT */
-#endif /* !__CYGWIN__ */
-	    gbl_phost = (LYNX_HOSTENT *) NULL;
-	    donelookup = FALSE;
-
-#if defined(__CYGWIN__) || defined(USE_WINSOCK2_H)
-	    SetLastError(WSAHOST_NOT_FOUND);
-#else
-	    WSASetLastError(WSAHOST_NOT_FOUND);
-#endif
-
-	    hThread = CreateThread(NULL, 4096UL, _fork_func, host, 0UL,
-				   &dwThreadID);
-	    if (!hThread)
-		MessageBox(NULL, "CreateThread",
-			   "CreateThread Failed", 0L);
-
-	    while (!donelookup) {
-		if (HTCheckForInterrupt()) {
-		    /* Note that host is a character array and is not freed */
-		    /* to avoid possible subthread problems: */
-		    if (!CloseHandle(hThread)) {
-			MessageBox((void *) NULL,
-				   "CloseHandle", "CloseHandle Failed", 0L);
-		    }
-		    lynx_nsl_status = HT_INTERRUPTED;
-		    return NULL;
-		}
-	    }
-#ifndef __CYGWIN__
-	}
-#endif /* !__CYGWIN__ */
-	if (gbl_phost) {
-	    lynx_nsl_status = HT_OK;
-	    result_phost = gbl_phost;
-	} else {
-	    lynx_nsl_status = HT_ERROR;
-	    goto failed;
-	}
-    }
-
-#else /* !NSL_FORK, !_WINDOWS_NSL: */
-    {
-	LYNX_HOSTENT *phost;
-
-	phost = gethostbyname(host);	/* See netdb.h */
-#ifdef MVS
-	CTRACE((tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost));
-#endif /* MVS */
-	if (phost) {
-	    lynx_nsl_status = HT_OK;
-	    result_phost = phost;
-	} else {
-	    lynx_nsl_status = HT_H_ERRNO_VALID;
-	    goto failed;
-	}
-    }
-#endif /* !NSL_FORK, !_WINDOWS_NSL */
-#endif /* !NSL_FORK */
-
-#ifdef DEBUG_HOSTENT
-    dump_hostent("End of LYGetHostByName", result_phost);
-    CTRACE((tfp, "LYGetHostByName: Resolved name to a hostent.\n"));
-#endif
-
-    return result_phost;	/* OK */
-
-  failed:
-    CTRACE((tfp, "LYGetHostByName: Can't find internet node name `%s'.\n",
-	    host));
-    return NULL;
-}
-
-/*	Parse a network node address and port
- *	-------------------------------------
- *
- *  On entry,
- *	str	points to a string with a node name or number,
- *		with optional trailing colon and port number.
- *	soc_in	points to the binary internet or decnet address field.
- *
- *  On exit,
- *	*soc_in is filled in.  If no port is specified in str, that
- *		field is left unchanged in *soc_in.
- */
-#ifndef INET6
-static int HTParseInet(SockA * soc_in, const char *str)
-{
-    char *port;
-    int dotcount_ip = 0;	/* for dotted decimal IP addr */
-    char *strptr;
-    char *host = NULL;
-
-    if (!str) {
-	CTRACE((tfp, "HTParseInet: Can't parse `NULL'.\n"));
-	return -1;
-    }
-    CTRACE((tfp, "HTParseInet: parsing `%s'.\n", str));
-    if (HTCheckForInterrupt()) {
-	CTRACE((tfp, "HTParseInet: INTERRUPTED for '%s'.\n", str));
-	return -1;
-    }
-    StrAllocCopy(host, str);	/* Make a copy we can mutilate */
-    /*
-     * Parse port number if present.
-     */
-    if ((port = strchr(host, ':')) != NULL) {
-	*port++ = 0;		/* Chop off port */
-	strptr = port;
-	if (port[0] >= '0' && port[0] <= '9') {
-#ifdef UNIX
-	    soc_in->sin_port = (PortNumber) htons(strtol(port, &strptr, 10));
-#else /* VMS: */
-#ifdef DECNET
-	    soc_in->sdn_objnum = (unsigned char) (strtol(port, &strptr, 10));
-#else
-	    soc_in->sin_port = htons((PortNumber) strtol(port, &strptr, 10));
-#endif /* Decnet */
-#endif /* Unix vs. VMS */
-#ifdef SUPPRESS			/* 1. crashes!?!.  2. URL syntax has number not name */
-	} else {
-	    struct servent *serv = getservbyname(port, (char *) 0);
-
-	    if (serv) {
-		soc_in->sin_port = serv->s_port;
-	    } else {
-		CTRACE((tfp, "TCP: Unknown service %s\n", port));
-	    }
-#endif /* SUPPRESS */
-	}
-	if (strptr && *strptr != '\0') {
-	    FREE(host);
-	    HTAlwaysAlert(NULL, gettext("Address has invalid port"));
-	    return -1;
-	}
-    }
-#ifdef DECNET
-    /*
-     * Read Decnet node name.  @@ Should know about DECnet addresses, but it's
-     * probably worth waiting until the Phase transition from IV to V.
-     */
-    soc_in->sdn_nam.n_len = min(DN_MAXNAML, strlen(host));	/* <=6 in phase 4 */
-    StrNCpy(soc_in->sdn_nam.n_name, host, soc_in->sdn_nam.n_len + 1);
-    CTRACE((tfp,
-	    "DECnet: Parsed address as object number %d on host %.6s...\n",
-	    soc_in->sdn_objnum, host));
-#else /* parse Internet host: */
-
-    if (*host >= '0' && *host <= '9') {		/* Test for numeric node address: */
-	strptr = host;
-	while (*strptr) {
-	    if (*strptr == '.') {
-		dotcount_ip++;
-	    } else if (!isdigit(UCH(*strptr))) {
-		break;
-	    }
-	    strptr++;
-	}
-	if (*strptr) {		/* found non-numeric, assume domain name */
-	    dotcount_ip = 0;
-	}
-    }
-
-    /*
-     * Parse host number if present.
-     */
-    if (dotcount_ip == 3)	/* Numeric node address: */
-    {
-#ifdef DGUX_OLD
-	soc_in->sin_addr.s_addr = inet_addr(host).s_addr;	/* See arpa/inet.h */
-#else
-#ifdef GUSI
-	soc_in->sin_addr = inet_addr(host);	/* See netinet/in.h */
-#else
-#ifdef HAVE_INET_ATON
-	if (!inet_aton(host, &(soc_in->sin_addr))) {
-	    CTRACE((tfp, "inet_aton(%s) returns error\n", host));
-	    FREE(host);
-	    return -1;
-	}
-#else
-	soc_in->sin_addr.s_addr = inet_addr(host);	/* See arpa/inet.h */
-#endif /* HAVE_INET_ATON */
-#endif /* GUSI */
-#endif /* DGUX_OLD */
-	FREE(host);
-    } else {			/* Alphanumeric node name: */
-
-#ifdef MVS			/* Outstanding problem with crash in MVS gethostbyname */
-	CTRACE((tfp, "HTParseInet: Calling LYGetHostByName(%s)\n", host));
-#endif /* MVS */
-
-#ifdef _WINDOWS_NSL
-	gbl_phost = LYGetHostByName(host);	/* See above */
-	if (!gbl_phost)
-	    goto failed;
-	MemCpy((void *) &soc_in->sin_addr, gbl_phost->h_addr_list[0], gbl_phost->h_length);
-#else /* !_WINDOWS_NSL */
-	{
-	    LYNX_HOSTENT *phost;
-
-	    phost = LYGetHostByName(host);	/* See above */
-
-	    if (!phost)
-		goto failed;
-	    if (!phost)
-		goto failed;
-	    if (phost->h_length != sizeof soc_in->sin_addr) {
-		HTAlwaysAlert(host, gettext("Address length looks invalid"));
-	    }
-	    MemCpy((void *) &soc_in->sin_addr, phost->h_addr_list[0], phost->h_length);
-	}
-#endif /* _WINDOWS_NSL */
-
-	FREE(host);
-    }				/* Alphanumeric node name */
-
-    CTRACE((tfp,
-	    "HTParseInet: Parsed address as port %d, IP address %d.%d.%d.%d\n",
-	    (int) ntohs(soc_in->sin_port),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 0),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 1),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 2),
-	    (int) *((unsigned char *) (&soc_in->sin_addr) + 3)));
-#endif /* Internet vs. Decnet */
-
-    return 0;			/* OK */
-
-  failed:
-    CTRACE((tfp, "HTParseInet: Can't find internet node name `%s'.\n",
-	    host));
-    FREE(host);
-    switch (lynx_nsl_status) {
-    case HT_NOT_ACCEPTABLE:
-    case HT_INTERRUPTED:
-	return lynx_nsl_status;
-    default:
-	return -1;
-    }
-}
-#endif /* !INET6 */
-
-#ifdef INET6
-static LYNX_ADDRINFO *HTGetAddrInfo(const char *str,
-				    const int defport)
-{
-    LYNX_ADDRINFO hints, *res;
-    int error;
-    char *p;
-    char *s = NULL;
-    char *host, *port;
-    char pbuf[80];
-
-    StrAllocCopy(s, str);
-
-    if (s[0] == '[' && (p = strchr(s, ']')) != NULL) {
-	*p++ = '\0';
-	host = s + 1;
-    } else {
-	p = s;
-	host = &s[0];
-    }
-    port = strrchr(p, ':');
-    if (port) {
-	*port++ = '\0';
-    } else {
-	sprintf(pbuf, "%d", defport);
-	port = pbuf;
-    }
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = PF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-    error = getaddrinfo(host, port, &hints, &res);
-    if (error || !res) {
-	CTRACE((tfp, "HTGetAddrInfo: getaddrinfo(%s, %s): %s\n", host, port,
-		gai_strerror(error)));
-	res = NULL;
-    }
-
-    free(s);
-    return res;
-}
-#endif /* INET6 */
-
-#ifdef LY_FIND_LEAKS
-/*	Free our name for the host on which we are - FM
- *	-------------------------------------------
- *
- */
-static void free_HTTCP_hostname(void)
-{
-    FREE(hostname);
-}
-#endif /* LY_FIND_LEAKS */
-
-/*	Derive the name of the host on which we are
- *	-------------------------------------------
- *
- */
-static void get_host_details(void)
-{
-    char name[MAXHOSTNAMELEN + 1];	/* The name of this host */
-
-#ifdef UCX
-    char *domain_name;		/* The name of this host domain */
-#endif /* UCX */
-#ifdef NEED_HOST_ADDRESS	/* no -- needs name server! */
-#ifdef INET6
-    LYNX_ADDRINFO hints, *res;
-    int error;
-
-#else
-    LYNX_HOSTENT *phost;	/* Pointer to host -- See netdb.h */
-#endif /* INET6 */
-#endif /* NEED_HOST_ADDRESS */
-    size_t namelength = sizeof(name);
-
-    if (hostname)
-	return;			/* Already done */
-    gethostname(name, namelength);	/* Without domain */
-    StrAllocCopy(hostname, name);
-#ifdef LY_FIND_LEAKS
-    atexit(free_HTTCP_hostname);
-#endif
-#ifdef UCX
-    /*
-     * UCX doesn't give the complete domain name.  Get rest from UCX$BIND_DOM
-     * logical.
-     */
-    if (strchr(hostname, '.') == NULL) {	/* Not full address */
-	domain_name = LYGetEnv("UCX$BIND_DOMAIN");
-	if (domain_name == NULL)
-	    domain_name = LYGetEnv("TCPIP$BIND_DOMAIN");
-	if (domain_name != NULL) {
-	    StrAllocCat(hostname, ".");
-	    StrAllocCat(hostname, domain_name);
-	}
-    }
-#endif /* UCX */
-    CTRACE((tfp, "TCP: Local host name is %s\n", hostname));
-
-#ifndef DECNET			/* Decnet ain't got no damn name server 8#OO */
-#ifdef NEED_HOST_ADDRESS	/* no -- needs name server! */
-#ifdef INET6
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = PF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = AI_CANONNAME;
-    error = getaddrinfo(name, NULL, &hints, &res);
-    if (error || !res || !res->ai_canonname) {
-	CTRACE((tfp, "TCP: %s: `%s'\n", gai_strerror(error), name));
-	if (res)
-	    freeaddrinfo(res);
-	return;			/* Fail! */
-    }
-    StrAllocCopy(hostname, res->ai_canonname);
-    MemCpy(&HTHostAddress, res->ai_addr, res->ai_addrlen);
-    freeaddrinfo(res);
-#else
-    phost = gethostbyname(name);	/* See netdb.h */
-    if (!OK_HOST(phost)) {
-	CTRACE((tfp,
-		"TCP: Can't find my own internet node address for `%s'!!\n",
-		name));
-	return;			/* Fail! */
-    }
-    StrAllocCopy(hostname, phost->h_name);
-    MemCpy(&HTHostAddress, &phost->h_addr_list[0], phost->h_length);
-#endif /* INET6 */
-    CTRACE((tfp, "     Name server says that I am `%s' = %s\n",
-	    hostname, HTInetString(&HTHostAddress)));
-#endif /* NEED_HOST_ADDRESS */
-
-#endif /* !DECNET */
-}
-
-const char *HTHostName(void)
-{
-    get_host_details();
-    return hostname;
-}
-
-#ifdef _WINDOWS
-#define SET_EINTR WSASetLastError(EINTR)
-#else
-#define SET_EINTR SOCKET_ERRNO = EINTR
-#endif
-
-static BOOL HTWasInterrupted(int *status)
-{
-    BOOL result = FALSE;
-
-    if (HTCheckForInterrupt()) {
-	result = TRUE;
-	*status = HT_INTERRUPTED;
-	SET_EINTR;
-    }
-    return result;
-}
-
-#define TRIES_PER_SECOND 10
-
-/*
- * Set the select-timeout to 0.1 seconds.
- */
-static void set_timeout(struct timeval *timeoutp)
-{
-    timeoutp->tv_sec = 0;
-    timeoutp->tv_usec = 100000;
-}
-
-#ifndef MULTINET		/* SOCKET_ERRNO != errno ? */
-#if !defined(UCX) || !defined(VAXC)	/* errno not modifiable ? */
-#define SOCKET_DEBUG_TRACE	/* show errno status after some system calls */
-#endif /* UCX && VAXC */
-#endif /* MULTINET */
-/*
- *  Interruptible connect as implemented for Mosaic by Marc Andreesen
- *  and hacked in for Lynx years ago by Lou Montulli, and further
- *  modified over the years by numerous Lynx lovers. - FM
- */
-int HTDoConnect(const char *url,
-		const char *protocol,
-		int default_port,
-		int *s)
-{
-    int status = 0;
-    char *line = NULL;
-    char *p1 = NULL;
-    char *at_sign = NULL;
-    char *host = NULL;
-
-#ifdef INET6
-    LYNX_ADDRINFO *res = 0, *res0 = 0;
-
-#else
-    struct sockaddr_in soc_address;
-    struct sockaddr_in *soc_in = &soc_address;
-
-    /*
-     * Set up defaults.
-     */
-    memset(soc_in, 0, sizeof(*soc_in));
-    soc_in->sin_family = AF_INET;
-    soc_in->sin_port = htons((PortNumber) default_port);
-#endif /* INET6 */
-
-    /*
-     * Get node name and optional port number.
-     */
-    p1 = HTParse(url, "", PARSE_HOST);
-    if ((at_sign = strchr(p1, '@')) != NULL) {
-	/*
-	 * If there's an @ then use the stuff after it as a hostname.
-	 */
-	StrAllocCopy(host, (at_sign + 1));
-    } else {
-	StrAllocCopy(host, p1);
-    }
-    FREE(p1);
-
-    HTSprintf0(&line, "%s%s", WWW_FIND_MESSAGE, host);
-    _HTProgress(line);
-#ifdef INET6
-    /* HTParseInet() is useless! */
-    res0 = HTGetAddrInfo(host, default_port);
-    if (res0 == NULL) {
-	HTSprintf0(&line, gettext("Unable to locate remote host %s."), host);
-	_HTProgress(line);
-	FREE(host);
-	FREE(line);
-	return HT_NO_DATA;
-    }
-#else
-    status = HTParseInet(soc_in, host);
-    if (status) {
-	if (status != HT_INTERRUPTED) {
-	    if (status == HT_NOT_ACCEPTABLE) {
-		/* Not HTProgress, so warning won't be overwritten immediately;
-		 * but not HTAlert, because typically there will be other
-		 * alerts from the callers.  - kw
-		 */
-		HTUserMsg2(gettext("Invalid hostname %s"), host);
-	    } else {
-		HTSprintf0(&line,
-			   gettext("Unable to locate remote host %s."), host);
-		_HTProgress(line);
-	    }
-	    status = HT_NO_DATA;
-	}
-	FREE(host);
-	FREE(line);
-	return status;
-    }
-#endif /* INET6 */
-
-    HTSprintf0(&line, gettext("Making %s connection to %s"), protocol, host);
-    _HTProgress(line);
-    FREE(host);
-    FREE(line);
-
-    /*
-     * Now, let's get a socket set up from the server for the data.
-     */
-#ifndef INET6
-    *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (*s == -1) {
-	HTAlert(gettext("socket failed."));
-	return HT_NO_DATA;
-    }
-#else
-    for (res = res0; res; res = res->ai_next) {
-	*s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-	if (*s == -1) {
-	    char hostbuf[1024], portbuf[1024];
-
-	    getnameinfo(res->ai_addr, res->ai_addrlen,
-			hostbuf, (socklen_t) sizeof(hostbuf),
-			portbuf, (socklen_t) sizeof(portbuf),
-			NI_NUMERICHOST | NI_NUMERICSERV);
-	    HTSprintf0(&line,
-		       gettext("socket failed: family %d addr %s port %s."),
-		       res->ai_family, hostbuf, portbuf);
-	    _HTProgress(line);
-	    FREE(line);
-	    continue;
-	}
-#endif /* INET6 */
-
-#if !defined(DOSPATH) || defined(__DJGPP__)
-#if !defined(NO_IOCTL) || defined(USE_FCNTL)
-	/*
-	 * Make the socket non-blocking, so the connect can be canceled.  This
-	 * means that when we issue the connect we should NOT have to wait for
-	 * the accept on the other end.
-	 */
-	{
-#ifdef USE_FCNTL
-	    int ret = fcntl(*s, F_SETFL, O_NONBLOCK);
-
-#else
-	    int val = 1;
-	    int ret = IOCTL(*s, FIONBIO, &val);
-#endif /* USE_FCNTL */
-	    if (ret == -1)
-		_HTProgress(gettext("Could not make connection non-blocking."));
-	}
-#endif /* !NO_IOCTL || USE_FCNTL */
-#endif /* !DOSPATH || __DJGPP__ */
-
-	/*
-	 * Issue the connect.  Since the server can't do an instantaneous
-	 * accept and we are non-blocking, this will almost certainly return a
-	 * negative status.
-	 */
-#ifdef SOCKS
-	if (socks_flag) {
-#ifdef INET6
-	    status = Rconnect(*s, res->ai_addr, res->ai_addrlen);
-#else
-	    status = Rconnect(*s, (struct sockaddr *) &soc_address,
-			      sizeof(soc_address));
-#ifndef SHORTENED_RBIND
-	    socks_bind_remoteAddr = soc_address.sin_addr.s_addr;
-#endif
-#endif /* INET6 */
-	} else
-#endif /* SOCKS */
-#ifdef INET6
-	    status = connect(*s, res->ai_addr, res->ai_addrlen);
-#else
-	    status = connect(*s, (struct sockaddr *) &soc_address, sizeof(soc_address));
-#endif /* INET6 */
-
-	/*
-	 * According to the Sun man page for connect:
-	 *  EINPROGRESS         The socket is non-blocking and the  con-
-	 *                      nection cannot be completed immediately.
-	 *                      It is possible to select(2) for  comple-
-	 *                      tion  by  selecting the socket for writ-
-	 *                      ing.
-	 * According to the Motorola SVR4 man page for connect:
-	 *  EAGAIN              The socket is non-blocking and the  con-
-	 *                      nection cannot be completed immediately.
-	 *                      It is possible to select for  completion
-	 *                      by  selecting  the  socket  for writing.
-	 *                      However, this is only  possible  if  the
-	 *                      socket  STREAMS  module  is  the topmost
-	 *                      module on  the  protocol  stack  with  a
-	 *                      write  service  procedure.  This will be
-	 *                      the normal case.
-	 */
-	if ((status < 0) &&
-	    (SOCKET_ERRNO == EINPROGRESS
-#ifdef EAGAIN
-	     || SOCKET_ERRNO == EAGAIN
-#endif
-	    )) {
-	    struct timeval select_timeout;
-	    int ret;
-	    int tries = 0;
-
-#ifdef SOCKET_DEBUG_TRACE
-	    HTInetStatus("this socket's first connect");
-#endif /* SOCKET_DEBUG_TRACE */
-	    ret = 0;
-	    while (ret <= 0) {
-		fd_set writefds;
-
-		/*
-		 * Protect against an infinite loop.
-		 */
-		if ((tries++ / TRIES_PER_SECOND) >= connect_timeout) {
-		    HTAlert(gettext("Connection failed (too many retries)."));
-#ifdef INET6
-		    FREE(line);
-		    if (res0)
-			freeaddrinfo(res0);
-#endif /* INET6 */
-		    return HT_NO_DATA;
-		}
-		set_timeout(&select_timeout);
-		FD_ZERO(&writefds);
-		FD_SET((unsigned) *s, &writefds);
-#ifdef SOCKS
-		if (socks_flag)
-		    ret = Rselect(*s + 1, NULL,
-				  &writefds, NULL, &select_timeout);
-		else
-#endif /* SOCKS */
-		    ret = select(*s + 1,
-				 NULL,
-				 &writefds,
-				 NULL,
-				 &select_timeout);
-
-#ifdef SOCKET_DEBUG_TRACE
-		if (tries == 1) {
-		    HTInetStatus("this socket's first select");
-		}
-#endif /* SOCKET_DEBUG_TRACE */
-		/*
-		 * If we suspend, then it is possible that select will be
-		 * interrupted.  Allow for this possibility.  - JED
-		 */
-		if ((ret == -1) && (errno == EINTR))
-		    continue;
-
-#ifdef SOCKET_DEBUG_TRACE
-		if (ret < 0) {
-		    HTInetStatus("failed select");
-		}
-#endif /* SOCKET_DEBUG_TRACE */
-		/*
-		 * Again according to the Sun and Motorola man pages for
-		 * connect:
-		 *  EALREADY    The socket is non-blocking and a  previ-
-		 *              ous  connection attempt has not yet been
-		 *              completed.
-		 * Thus if the SOCKET_ERRNO is NOT EALREADY we have a real
-		 * error, and should break out here and return that error.
-		 * Otherwise if it is EALREADY keep on trying to complete the
-		 * connection.
-		 */
-		if ((ret < 0) && (SOCKET_ERRNO != EALREADY)) {
-		    status = ret;
-		    break;
-		} else if (ret > 0) {
-		    /*
-		     * Extra check here for connection success, if we try to
-		     * connect again, and get EISCONN, it means we have a
-		     * successful connection.  But don't check with SOCKS.
-		     */
-#ifdef SOCKS
-		    if (socks_flag) {
-			status = 0;
-		    } else {
-#endif /* SOCKS */
-#ifdef INET6
-			status = connect(*s, res->ai_addr, res->ai_addrlen);
-#else
-			status = connect(*s, (struct sockaddr *) &soc_address,
-					 sizeof(soc_address));
-#endif /* INET6 */
-#ifdef UCX
-			/*
-			 * A UCX feature:  Instead of returning EISCONN UCX
-			 * returns EADDRINUSE.  Test for this status also.
-			 */
-			if ((status < 0) && ((SOCKET_ERRNO == EISCONN) ||
-					     (SOCKET_ERRNO == EADDRINUSE)))
-#else
-			if ((status < 0) && (SOCKET_ERRNO == EISCONN))
-#endif /* UCX */
-			{
-			    status = 0;
-			}
-
-			if (status && (SOCKET_ERRNO == EALREADY))	/* new stuff LJM */
-			    ret = 0;	/* keep going */
-			else {
-#ifdef SOCKET_DEBUG_TRACE
-			    if (status < 0) {
-				HTInetStatus("confirm-ready connect");
-			    }
-#endif /* SOCKET_DEBUG_TRACE */
-			    break;
-			}
-#ifdef SOCKS
-		    }
-#endif /* SOCKS */
-		}
-#ifdef SOCKS
-		else if (!socks_flag)
-#else
-		else
-#endif /* SOCKS */
-		{
-		    /*
-		     * The select says we aren't ready yet.  Try to connect
-		     * again to make sure.  If we don't get EALREADY or
-		     * EISCONN, something has gone wrong.  Break out and report
-		     * it.
-		     *
-		     * For some reason, SVR4 returns EAGAIN here instead of
-		     * EALREADY, even though the man page says it should be
-		     * EALREADY.
-		     *
-		     * For some reason, UCX pre 3 apparently returns errno =
-		     * 18242 instead of EALREADY or EISCONN.
-		     */
-#ifdef INET6
-		    status = connect(*s, res->ai_addr, res->ai_addrlen);
-#else
-		    status = connect(*s, (struct sockaddr *) &soc_address,
-				     sizeof(soc_address));
-#endif /* INET6 */
-		    if ((status < 0) &&
-			(SOCKET_ERRNO != EALREADY
-#ifdef EAGAIN
-			 && SOCKET_ERRNO != EAGAIN
-#endif
-			) &&
-#ifdef UCX
-			(SOCKET_ERRNO != 18242) &&
-#endif /* UCX */
-			(SOCKET_ERRNO != EISCONN)) {
-#ifdef SOCKET_DEBUG_TRACE
-			HTInetStatus("confirm-not-ready connect");
-#endif /* SOCKET_DEBUG_TRACE */
-			break;
-		    }
-		}
-		if (HTWasInterrupted(&status)) {
-		    CTRACE((tfp, "*** INTERRUPTED in middle of connect.\n"));
-		    break;
-		}
-	    }
-	}
-#ifdef SOCKET_DEBUG_TRACE
-	else if (status < 0) {
-	    HTInetStatus("this socket's first and only connect");
-	}
-#endif /* SOCKET_DEBUG_TRACE */
-#ifdef INET6
-	if (status < 0) {
-	    NETCLOSE(*s);
-	    *s = -1;
-	    continue;
-	}
-	break;
-    }
-#endif /* INET6 */
-
-#ifdef INET6
-    if (*s < 0)
-#else
-    if (status < 0)
-#endif /* INET6 */
-    {
-	/*
-	 * The connect attempt failed or was interrupted, so close up the
-	 * socket.
-	 */
-	NETCLOSE(*s);
-    }
-#if !defined(DOSPATH) || defined(__DJGPP__)
-#if !defined(NO_IOCTL) || defined(USE_FCNTL)
-    else {
-	/*
-	 * Make the socket blocking again on good connect.
-	 */
-#ifdef USE_FCNTL
-	int ret = fcntl(*s, F_SETFL, 0);
-
-#else
-	int val = 0;
-	int ret = IOCTL(*s, FIONBIO, &val);
-#endif /* USE_FCNTL */
-	if (ret == -1)
-	    _HTProgress(gettext("Could not restore socket to blocking."));
-    }
-#endif /* !NO_IOCTL || USE_FCNTL */
-#endif /* !DOSPATH || __DJGPP__ */
-
-#ifdef INET6
-    FREE(line);
-    if (res0)
-	freeaddrinfo(res0);
-#endif /* INET6 */
-    return status;
-}
-
-/*
- *  This is so interruptible reads can be implemented cleanly.
- */
-int HTDoRead(int fildes,
-	     void *buf,
-	     unsigned nbyte)
-{
-    int result;
-    BOOL ready;
-
-#if !defined(NO_IOCTL)
-    int ret;
-    fd_set readfds;
-    struct timeval select_timeout;
-    int tries = 0;
-
-#ifdef USE_READPROGRESS
-    int otries = 0;
-    time_t otime = time((time_t *) 0);
-    time_t start = otime;
-#endif
-#endif /* !NO_IOCTL */
-
-#if defined(UNIX) && !defined(__BEOS__)
-    if (fildes == 0) {
-	/*
-	 * 0 can be a valid socket fd, but if it's a tty something must have
-	 * gone wrong.  - kw
-	 */
-	if (isatty(fildes)) {
-	    CTRACE((tfp, "HTDoRead - refusing to read fd 0 which is a tty!\n"));
-	    return -1;
-	}
-    } else
-#endif
-    if (fildes <= 0) {
-	CTRACE((tfp, "HTDoRead - no file descriptor!\n"));
-	return -1;
-    }
-
-    if (HTWasInterrupted(&result)) {
-	CTRACE((tfp, "HTDoRead - interrupted before starting!\n"));
-	return (result);
-    }
-#if defined(NO_IOCTL)
-    ready = TRUE;
-#else
-    ready = FALSE;
-    while (!ready) {
-	/*
-	 * Protect against an infinite loop.
-	 */
-	if ((tries++ / TRIES_PER_SECOND) >= reading_timeout) {
-	    HTAlert(gettext("Socket read failed (too many tries)."));
-	    SET_EINTR;
-	    result = HT_INTERRUPTED;
-	    break;
-	}
-#ifdef USE_READPROGRESS
-	if (tries - otries > TRIES_PER_SECOND) {
-	    time_t t = time((time_t *) 0);
-
-	    otries = tries;
-	    if (t - otime >= 5) {
-		otime = t;
-		HTReadProgress((off_t) (-1), (off_t) 0);	/* Put "stalled" message */
-	    }
-	}
-#endif
-
-	/*
-	 * If we suspend, then it is possible that select will be interrupted.
-	 * Allow for this possibility.  - JED
-	 */
-	do {
-	    set_timeout(&select_timeout);
-	    FD_ZERO(&readfds);
-	    FD_SET((unsigned) fildes, &readfds);
-#ifdef SOCKS
-	    if (socks_flag)
-		ret = Rselect(fildes + 1,
-			      &readfds, NULL, NULL, &select_timeout);
-	    else
-#endif /* SOCKS */
-		ret = select(fildes + 1,
-			     &readfds, NULL, NULL, &select_timeout);
-	} while ((ret == -1) && (errno == EINTR));
-
-	if (ret < 0) {
-	    result = -1;
-	    break;
-	} else if (ret > 0) {
-	    ready = TRUE;
-	} else if (HTWasInterrupted(&result)) {
-	    break;
-	}
-    }
-#endif /* !NO_IOCTL */
-
-    if (ready) {
-#if defined(UCX) && defined(VAXC)
-	/*
-	 * VAXC and UCX problem only.
-	 */
-	errno = vaxc$errno = 0;
-	result = SOCKET_READ(fildes, buf, nbyte);
-	CTRACE((tfp,
-		"Read - result,errno,vaxc$errno: %d %d %d\n", result, errno, vaxc$errno));
-	if ((result <= 0) && TRACE)
-	    perror("HTTCP.C:HTDoRead:read");	/* RJF */
-	/*
-	 * An errno value of EPIPE and result < 0 indicates end-of-file on VAXC.
-	 */
-	if ((result <= 0) && (errno == EPIPE)) {
-	    result = 0;
-	    set_errno(0);
-	}
-#else
-#ifdef UNIX
-	while ((result = (int) SOCKET_READ(fildes, buf, nbyte)) == -1) {
-	    if (errno == EINTR)
-		continue;
-#ifdef ERESTARTSYS
-	    if (errno == ERESTARTSYS)
-		continue;
-#endif /* ERESTARTSYS */
-	    HTInetStatus("read");
-	    break;
-	}
-#else /* UNIX */
-	result = SOCKET_READ(fildes, buf, nbyte);
-#endif /* !UNIX */
-#endif /* UCX && VAXC */
-    }
-#ifdef USE_READPROGRESS
-    CTRACE2(TRACE_TIMING, (tfp, "...HTDoRead returns %d (%" PRI_time_t
-			   " seconds)\n",
-			   result, CAST_time_t (time((time_t *)0) - start)));
-#endif
-    return result;
-}
-
-#ifdef SVR4_BSDSELECT
-/*
- *  This is a fix for the difference between BSD's select() and
- *  SVR4's select().  SVR4's select() can never return a value larger
- *  than the total number of file descriptors being checked.  So, if
- *  you select for read and write on one file descriptor, and both
- *  are true, SVR4 select() will only return 1.  BSD select in the
- *  same situation will return 2.
- *
- *	Additionally, BSD select() on timing out, will zero the masks,
- *	while SVR4 does not.  This is fixed here as well.
- *
- *	Set your tabstops to 4 characters to have this code nicely formatted.
- *
- *	Jerry Whelan, guru@bradley.edu, June 12th, 1993
- */
-#ifdef select
-#undef select
-#endif /* select */
-
-#ifdef SOCKS
-#ifdef Rselect
-#undef Rselect
-#endif /* Rselect */
-#endif /* SOCKS */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/select.h>
-
-int BSDselect(int nfds,
-	      fd_set * readfds,
-	      fd_set * writefds,
-	      fd_set * exceptfds,
-	      struct timeval *select_timeout)
-{
-    int rval, i;
-
-#ifdef SOCKS
-    if (socks_flag)
-	rval = Rselect(nfds, readfds, writefds, exceptfds, select_timeout);
-    else
-#endif /* SOCKS */
-	rval = select(nfds, readfds, writefds, exceptfds, select_timeout);
-
-    switch (rval) {
-    case -1:
-	return (rval);
-
-    case 0:
-	if (readfds != NULL)
-	    FD_ZERO(readfds);
-	if (writefds != NULL)
-	    FD_ZERO(writefds);
-	if (exceptfds != NULL)
-	    FD_ZERO(exceptfds);
-	return (rval);
-
-    default:
-	for (i = 0, rval = 0; i < nfds; i++) {
-	    if ((readfds != NULL) && FD_ISSET(i, readfds))
-		rval++;
-	    if ((writefds != NULL) && FD_ISSET(i, writefds))
-		rval++;
-	    if ((exceptfds != NULL) && FD_ISSET(i, exceptfds))
-		rval++;
-
-	}
-	return (rval);
-    }
-/* Should never get here */
-}
-#endif /* SVR4_BSDSELECT */