⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httcp.c

📁 用于linux和其他unix下面的
💻 C
📖 第 1 页 / 共 4 页
字号:
/*			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 OK_HOST(p) ((p) != 0 && ((p)->h_length) != 0)#ifdef SVR4_BSDSELECTPUBLIC int BSDselect PARAMS((	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>#ifndef FD_SETSIZE#if defined(UCX) || defined(SOCKETSHR_TCP) || defined(CMU_TCP)#define FD_SETSIZE 32#else#define FD_SETSIZE 256#endif /* Limit # sockets to 32 for UCX, BSN - also SOCKETSHR and CMU, AH */#endif /* FD_SETSIZE *//***  Module-Wide variables*/PRIVATE char *hostname = NULL;		/* The name of this host *//***  PUBLIC VARIABLES*/#ifdef SOCKSextern BOOLEAN socks_flag;PUBLIC unsigned long socks_bind_remoteAddr; /* for long Rbind */#endif /* SOCKS *//* PUBLIC SockA HTHostAddress; */	/* The internet address of the host */					/* Valid after call to HTHostName() *//*	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_ERRLISTextern char *sys_errlist[];		/* see man perror on cernvax */extern int sys_nerr;#endif /* DECL_SYS_ERRLIST */#ifdef _WINDOWS_NSLchar host[512];struct hostent  *phost;	/* Pointer to host - See netdb.h */int donelookup;static unsigned long _fork_func (void *arglist){#ifdef SH_EX    unsigned long addr;    addr = (unsigned long)inet_addr(host);    if ((int)addr != -1)	phost = gethostbyaddr((char *)&addr, sizeof (addr), AF_INET);    else	phost = gethostbyname(host);#else    phost = gethostbyname(host);#endif    donelookup = TRUE;    return (unsigned long)(phost);}#endif /* _WINDOWS_NSL */#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>PUBLIC int HTioctl ARGS3(	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**	---------------------*/PUBLIC int HTInetStatus ARGS1(	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*/PUBLIC unsigned int HTCardinal ARGS3(	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 + *((*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.*/PUBLIC CONST char * HTInetString ARGS1(	SockA*,		soc_in){#ifdef INET6    static char hostbuf[MAXHOSTNAMELEN];    getnameinfo((struct sockaddr *)soc_in,	    SOCKADDR_LEN(soc_in),	    hostbuf, 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.*/PUBLIC BOOL valid_hostname ARGS1(	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*/PRIVATE void quench ARGS1(	int,	sig GCC_UNUSED){    _exit(2);}#endif /* NSL_FORK */PUBLIC 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 struct hostent.****  dump_hostent - dumps the contents of a struct hostent to the**  trace log or stderr, including all pointer values, strings, and**  addresses, in a format inspired by gdb's print format. - kw*/PRIVATE void dump_hostent ARGS2(    CONST char *,		msgprefix,    CONST struct hostent *,	phost){    if (TRACE) {	int i;	char **pcnt;	CTRACE((tfp,"%s: %p ", msgprefix, 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", 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", 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 struct 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 struct hostent. - kw**  See also description of LYGetHostByName.*/#ifdef NSL_FORK#define REHOSTENT_SIZE 128		/* not bigger than pipe buffer! */typedef struct {	struct hostent	h;	char		rest[REHOSTENT_SIZE];    } AlignedHOSTENT;PRIVATE size_t fill_rehostent ARGS3(    char *,			rehostent,    size_t,			rehostentsize,    CONST struct hostent *,	phost){    AlignedHOSTENT *data = (AlignedHOSTENT *)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(struct 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 = 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;	    }	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -