📄 htinet.c
字号:
/* HTInet.c** GENERIC INTERNET UTILITIES**** (c) COPYRIGHT MIT 1995.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTInet.c,v 2.28 2000/01/06 10:48:50 kahan Exp $**** This code is in common between client and server sides.**** 16 Mar 96 HFN Spawned off from HTTCP.c*//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "HTParse.h"#include "HTAlert.h"#include "HTError.h"#include "HTNetMan.h"#include "HTDNS.h"#include "HTInet.h" /* Implemented here */#ifndef DEFAULT_NEWS_HOST#define DEFAULT_NEWS_HOST "news"#endif#ifndef SERVER_FILE#define SERVER_FILE "/usr/local/lib/rn/server"#endif/* ------------------------------------------------------------------------- *//*** Returns the string equivalent to the errno passed in the argument.** We can't use errno directly as we have both errno and socerrno. The** result is a dynamic string that must be freed by the caller.*/PUBLIC char * HTErrnoString (int errornumber){ char * msg = NULL;#ifdef _WINSOCKAPI_ if ((msg = (char *) HT_MALLOC(64)) == NULL) HT_OUTOFMEM("HTErrnoString"); *msg = '\0'; sprintf(msg, "WinSock reported error=%ld", WSAGetLastError());#else#ifdef HAVE_STRERROR StrAllocCopy(msg, strerror(errornumber));#else#ifdef HAVE_SYS_ERRLIST#ifdef HAVE_SYS_NERR if (errno < sys_nerr) StrAllocCopy(msg, sys_errlist[errno]); else StrAllocCopy(msg, "Unknown error");#else StrAllocCopy(msg, sys_errlist[errno]);#endif /* HAVE_SYS_NERR */#else#ifdef VMS if ((msg = (char *) HT_MALLOC(64)) == NULL) HT_OUTOFMEM("HTErrnoString"); *msg = '\0'; sprintf(msg, "Unix errno=%ld dec, VMS error=%lx hex", errornumber, vaxc$errno);#else StrAllocCopy(msg, "Error number not translated!");#endif /* _WINSOCKAPI_ */#endif /* VMS */#endif /* HAVE_SYS_ERRLIST */#endif /* HAVE_STRERROR */ return msg;}/* Debug error message*/PUBLIC int HTInetStatus (int errnum, char * where){#ifdef VMS HTTRACE(CORE_TRACE, "System Error Unix = %ld dec\n" _ errno); HTTRACE(CORE_TRACE, "System Error VMS = %lx hex\n" _ vaxc$errno); return (-vaxc$errno);#else#ifdef _WINSOCKAPI_ HTTRACE(CORE_TRACE, "System Error Unix = %ld dec\n" _ errno); HTTRACE(CORE_TRACE, "System Error WinSock error=%lx hex\n" _ WSAGetLastError()); return (-errnum);#else#ifdef HTDEBUG if (CORE_TRACE) { char * errmsg = HTErrnoString(errnum); HTTRACE(CORE_TRACE, "System Error %d after call to %s() failed\n............ %s\n" _ errno _ where _ errmsg); HT_FREE(errmsg); }#endif /* HTDEBUG */ return (-errnum);#endif /* _WINSOCKAPI_ */#endif /* VMS */}/* 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 (int * pstatus, char ** pp, unsigned int max_value){ unsigned int n=0; if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */ *pstatus = -3; /* No number where one expeceted */ return 0; } while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0'; if (n>max_value) { *pstatus = -4; /* Cardinal outside range */ return 0; } return n;}/* ------------------------------------------------------------------------- *//* SIGNAL HANDLING *//* ------------------------------------------------------------------------- */#ifdef WWWLIB_SIG/* HTSetSignal** This function sets up signal handlers. This might not be necessary to** call if the application has its own handlers.*/#include <signal.h>PUBLIC void HTSetSignal (void){ /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal ** when attemting to connect to a remote host where you normally should ** get `connection refused' back */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { HTTRACE(CORE_TRACE, "HTSignal.... Can't catch SIGPIPE\n"); } else { HTTRACE(CORE_TRACE, "HTSignal.... Ignoring SIGPIPE\n"); }}#else /* WWWLIB_SIG */PUBLIC void HTSetSignal (void) { }#endif /* WWWLIB_SIG *//* ------------------------------------------------------------------------- *//* HOST NAME FUNCTIONS *//* ------------------------------------------------------------------------- *//* 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 (SockA * sin){#ifndef DECNET /* Function only used below for a trace message */#if 0 /* This dumps core on some Sun systems :-(. The problem is now, that the current implememtation only works for IP-addresses and not in other address spaces. */ return inet_ntoa(sin->sin_addr);#endif static char string[16]; sprintf(string, "%d.%d.%d.%d", (int)*((unsigned char *)(&sin->sin_addr)+0), (int)*((unsigned char *)(&sin->sin_addr)+1), (int)*((unsigned char *)(&sin->sin_addr)+2), (int)*((unsigned char *)(&sin->sin_addr)+3)); return string;#else return "";#endif /* Decnet */}/* Parse a network node address and port** -------------------------------------** It is assumed that any portnumber and numeric host address** is given in decimal notation. Separation character is '.'** Any port number gets chopped off** Returns:** >0 Number of homes** 0 Wait for persistent socket** -1 Error*/PUBLIC int HTParseInet (HTHost * host, char * hostname, HTRequest * request){ int status = 1; SockA *sin = &host->sock_addr;#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. */ sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(hostname)); /* <=6 in phase 4 */ strncpy (sin->sdn_nam.n_name, hostname, sin->sdn_nam.n_len + 1); HTTRACE(CORE_TRACE, "DECnet: Parsed address as object number %d on host %.6s...\n" _ sin->sdn_objnum _ hostname);#else /* Internet */ { char *strptr = hostname; while (*strptr) { if (*strptr == ':') { *strptr = '\0'; /* Don't want port number in numeric host */ break; } if (!isdigit((int) *strptr) && *strptr != '.') break; strptr++; } if (!*strptr) {#ifdef GUSI sin->sin_addr = inet_addr(hostname); /* See netinet/in.h */#else sin->sin_addr.s_addr = inet_addr(hostname); /* See arpa/inet.h */#endif } else { char * port = strchr(hostname, ':'); /* Chop port */ if (port) *port = '\0'; status = HTGetHostByName(host, hostname, request); }#ifdef HTDEBUG if (status > 0) HTTRACE(CORE_TRACE, "ParseInet... as port %d on %s with %d homes\n" _ (int) ntohs(sin->sin_port) _ HTInetString(sin) _ status);#endif /* HTDEBUG */ }#endif /* Internet vs. Decnet */ return status;}#if 0/* HTGetDomainName** Returns the current domain name without the local host name.** The response is pointing to a static area that might be changed** using HTSetHostName().**** Returns NULL on error, "" if domain name is not found*/PRIVATE char * HTGetDomainName (void){ char * host = HTGetHostName(); char * domain; if (host && *host) { if ((domain = strchr(host, '.')) != NULL) return ++domain; else return ""; } else return NULL;}#endif/* HTGetHostName** Returns the name of this host. It uses the following algoritm:**** 1) gethostname()** 2) if the hostname doesn't contain any '.' try to read** /etc/resolv.conf. If there is no domain line in this file then** 3) Try getdomainname and do as the man pages say for resolv.conf (sun)** If there is no domain line in this file, then it is derived** from the domain name set by the domainname(1) command, usually** by removing the first component. For example, if the domain-** name is set to ``foo.podunk.edu'' then the default domain name** used will be ``pudunk.edu''.**** This is the same procedure as used by res_init() and sendmail.**** Return: hostname on success else NULL*/PUBLIC char * HTGetHostName (void){ char * hostname = NULL; int fqdn = 0; /* 0=no, 1=host, 2=fqdn */ char name[MAXHOSTNAMELEN+1]; *(name+MAXHOSTNAMELEN) = '\0';#if defined(HAVE_SYSINFO) && defined(SI_HOSTNAME) if (!fqdn && sysinfo(SI_HOSTNAME, name, MAXHOSTNAMELEN) > 0) { char * dot = strchr(name, '.'); HTTRACE(CORE_TRACE, "HostName.... sysinfo says `%s\'\n" _ name); StrAllocCopy(hostname, name); fqdn = dot ? 2 : 1; }#endif /* HAVE_SYSINFO */#ifdef HAVE_GETHOSTNAME if (!fqdn && gethostname(name, MAXHOSTNAMELEN) == 0) { char * dot = strchr(name, '.'); HTTRACE(CORE_TRACE, "HostName.... gethostname says `%s\'\n" _ name); StrAllocCopy(hostname, name); fqdn = dot ? 2 : 1; }#endif /* HAVE_GETHOSTNAME */#ifdef RESOLV_CONF /* Now try the resolver config file */ { FILE *fp; if (fqdn==1 && (fp = fopen(RESOLV_CONF, "r")) != NULL) { char buffer[80]; *(buffer+79) = '\0'; while (fgets(buffer, 79, fp)) { if (!strncasecomp(buffer, "domain", 6) || !strncasecomp(buffer, "search", 6)) { char *domainstr = buffer+6; char *end; while (*domainstr == ' ' || *domainstr == '\t') domainstr++; end = domainstr; while (*end && !isspace((int) *end)) end++; *end = '\0'; if (*domainstr) { StrAllocCat(hostname, "."); StrAllocCat(hostname, domainstr); fqdn = 2; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -