📄 httcp.c
字号:
(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, WEXITSTATUS(waitstat))); } } if (!got_rehostent) { goto failed; } }#else /* Not NSL_FORK: */#ifdef _WINDOWS_NSL { HANDLE hThread, dwThreadID;#ifndef __CYGWIN__ if (!system_is_NT) { /* for Windows9x */ unsigned long t; t = (unsigned long)inet_addr(host); if ((int)t != -1) phost = gethostbyaddr((char *)&t, sizeof (t), AF_INET); else phost = gethostbyname(host); } else { /* for Windows NT */#endif /* !__CYGWIN__ */ phost = (struct hostent *) NULL; donelookup = FALSE; hThread = CreateThread((void *)NULL, 4096UL, (LPTHREAD_START_ROUTINE)_fork_func, (void *)NULL, 0UL, (unsigned long *)&dwThreadID); if (!hThread) MessageBox((void *)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 (phost) { lynx_nsl_status = HT_OK; result_phost = phost; } else { lynx_nsl_status = HT_ERROR; goto failed; } }#else /* !NSL_FORK, !_WINDOWS_NSL: */ { struct 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 INET6PRIVATE int HTParseInet ARGS2( SockA *, soc_in, CONST char *, str){ char *port; int dotcount_ip = 0; /* for dotted decimal IP addr */ char *strptr;#ifndef _WINDOWS_NSL char *host = NULL;#endif /* _WINDOWS_NSL */ 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; }#ifdef _WINDOWS_NSL strncpy(host, str, sizeof(host));#else StrAllocCopy(host, str); /* Make a copy we can mutilate */#endif /* _WINDOWS_NSL */ /* ** 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') {#ifndef _WINDOWS_NSL FREE(host);#endif /* _WINDOWS_NSL */ 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));#ifndef _WINDOWS_NSL FREE(host);#endif /* _WINDOWS_NSL */ 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 */#ifndef _WINDOWS_NSL FREE(host);#endif /* _WINDOWS_NSL */ } 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 phost = LYGetHostByName(host); /* See above */ if (!phost) goto failed; memcpy((void *)&soc_in->sin_addr, phost->h_addr, phost->h_length);#else /* !_WINDOWS_NSL */ { struct hostent *phost; phost = LYGetHostByName(host); /* See above */ if (!phost) goto failed;#if defined(VMS) && defined(CMU_TCP) /* ** In LIBCMU, phost->h_length contains not the length of one address ** (four bytes) but the number of bytes in *h_addr, i.e., some multiple ** of four. Thus we need to hard code the value here, and remember to ** change it if/when IP addresses change in size. :-( LIBCMU is no ** longer supported, and CMU users are encouraged to obtain and use ** SOCKETSHR/NETLIB instead. - S. Bjorndahl */ memcpy((void *)&soc_in->sin_addr, phost->h_addr, 4);#else 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, phost->h_length);#endif /* VMS && CMU_TCP */ }#endif /* _WINDOWS_NSL */#ifndef _WINDOWS_NSL FREE(host);#endif /* _WINDOWS_NSL */ } /* 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));#ifndef _WINDOWS_NSL FREE(host);#endif /* _WINDOWS_NSL */ switch (lynx_nsl_status) { case HT_NOT_ACCEPTABLE: case HT_INTERRUPTED: return lynx_nsl_status; default: return -1; }}#endif /* !INET6 */#ifdef INET6PRIVATE struct addrinfo *HTGetAddrInfo ARGS2( CONST char *, str, CONST int, defport){ struct addrinfo hints, *res; int error; char *p; char *s; char *host, *port; char pbuf[10]; s = strdup(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 { snprintf(pbuf, sizeof(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; } return res;}#endif /* INET6 */#ifdef LY_FIND_LEAKS/* Free our name for the host on which we are - FM** -------------------------------------------***/PRIVATE void free_HTTCP_hostname NOARGS{ FREE(hostname);}#endif /* LY_FIND_LEAKS *//* Derive the name of the host on which we are** -------------------------------------------***/#ifndef MAXHOSTNAMELEN#define MAXHOSTNAMELEN 64 /* Arbitrary limit */#endif /* MAXHOSTNAMELEN */PRIVATE void get_host_details NOARGS{ 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 struct addrinfo hints, *res; int error;#else struct hostent * phost; /* Pointer to host -- See netdb.h */#endif /* INET6 */#endif /* NEED_HOST_ADDRESS */ int 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 = getenv("UCX$BIND_DOMAIN"); if (domain_name == NULL) domain_name = getenv("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, 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 */}PUBLIC CONST char * HTHostName NOARGS{ get_host_details(); return hostname;}#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*/PUBLIC int HTDoConnect ARGS4( CONST char *, url, 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 struct addrinfo *res, *res0;#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! */ _HTProgress(host); 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. */#ifdef INET6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -