version 2.26, 1994/11/09 12:02:32
|
version 2.27, 1994/11/09 14:44:22
|
Line 24
|
Line 24
|
#include "HTParse.h" |
#include "HTParse.h" |
#include "HTAccess.h" |
#include "HTAccess.h" |
#include "HTError.h" |
#include "HTError.h" |
|
#include "HTThread.h" |
#include "HTTCP.h" /* Implemented here */ |
#include "HTTCP.h" /* Implemented here */ |
|
|
#ifdef VMS |
#ifdef VMS |
Line 87 PRIVATE HTList *hostcache = NULL; /* Li
|
Line 88 PRIVATE HTList *hostcache = NULL; /* Li
|
PRIVATE unsigned int HTCacheSize = 0; /* Current size of cache */ |
PRIVATE unsigned int HTCacheSize = 0; /* Current size of cache */ |
|
|
/* ------------------------------------------------------------------------- */ |
/* ------------------------------------------------------------------------- */ |
|
/* TEMPORARY STUFF */ |
|
#define IOCTL ioctl |
|
/* ------------------------------------------------------------------------- */ |
|
|
/* Encode INET status (as in sys/errno.h) inet_status() |
/* Encode INET status (as in sys/errno.h) inet_status() |
** ------------------ |
** ------------------ |
Line 165 PUBLIC int HTInetStatus ARGS1(char *, wh
|
Line 169 PUBLIC int HTInetStatus ARGS1(char *, wh
|
{ |
{ |
#ifndef VMS |
#ifndef VMS |
|
|
CTRACE(tfp, |
if (PROT_TRACE) |
"TCP errno... %d after call to %s() failed.\n............ %s\n", |
fprintf(stderr, "TCP errno... %d after call to %s() failed.\n............ %s\n", errno, where, HTErrnoString()); |
errno, where, HTErrnoString()); |
|
|
|
#else /* VMS */ |
#else /* VMS */ |
|
|
CTRACE(tfp, " Unix error number = %ld dec\n", errno); |
if (PROT_TRACE) fprintf(stderr, " Unix error number = %ld dec\n", errno); |
CTRACE(tfp, " VMS error = %lx hex\n", vaxc$errno); |
if (PROT_TRACE) fprintf(stderr, " VMS error = %lx hex\n", vaxc$errno); |
|
|
#ifdef MULTINET |
#ifdef MULTINET |
CTRACE(tfp, " Multinet error = %lx hex\n", socket_errno); |
if (PROT_TRACE) fprintf(stderr, " Multinet error = %lx hex\n", socket_errno); |
CTRACE(tfp, " Error String = %s\n", vms_errno_string()); |
if (PROT_TRACE) fprintf(stderr, " Error String = %s\n", vms_errno_string()); |
#endif /* MULTINET */ |
#endif /* MULTINET */ |
|
|
#endif /* VMS */ |
#endif /* VMS */ |
Line 227 PUBLIC unsigned int HTCardinal ARGS3
|
Line 230 PUBLIC unsigned int HTCardinal ARGS3
|
} |
} |
|
|
/* ------------------------------------------------------------------------- */ |
/* ------------------------------------------------------------------------- */ |
|
/* 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 NOARGS |
|
{ |
|
/* 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) { |
|
if (PROT_TRACE) fprintf(stderr, "HTSignal.... Can't catch SIGPIPE\n"); |
|
} else { |
|
if (PROT_TRACE) fprintf(stderr, "HTSignal.... Ignoring SIGPIPE\n"); |
|
} |
|
} |
|
#endif /* WWWLIB_SIG */ |
|
|
|
/* ------------------------------------------------------------------------- */ |
/* HOST CACHE MANAGEMENT */ |
/* HOST CACHE MANAGEMENT */ |
/* ------------------------------------------------------------------------- */ |
/* ------------------------------------------------------------------------- */ |
|
|
/* HTTCPCacheRemoveElement |
/* HTTCPCacheRemoveElement |
** |
** |
** Remove the element specified from the cache |
** Remove the element specified from the cache |
*/ |
*/ |
PRIVATE void HTTCPCacheRemoveElement ARGS1(host_info *, element) |
PRIVATE void HTTCPCacheRemoveElement ARGS1(host_info *, element) |
{ |
{ |
if (!hostcache) { |
if (!hostcache) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostCache... Remove not done, no cache\n"); |
fprintf(stderr, "HostCache... Remove not done, no cache\n"); |
return; |
return; |
} |
} |
if (TRACE) fprintf(stderr, "HostCache... Remove `%s' from cache\n", |
if (PROT_TRACE) fprintf(stderr, "HostCache... Remove `%s' from cache\n", |
HTAtom_name(element->hostname)); |
HTAtom_name(element->hostname)); |
HTList_removeObject(hostcache, element); |
HTList_removeObject(hostcache, (void *) element); |
if (*element->addrlist) |
if (*element->addrlist) |
free(*element->addrlist); |
free(*element->addrlist); |
if (element->addrlist) |
if (element->addrlist) |
Line 287 PRIVATE void HTTCPCacheGarbage NOARGS
|
Line 314 PRIVATE void HTTCPCacheGarbage NOARGS
|
host_info *pres, *worst_match = NULL; |
host_info *pres, *worst_match = NULL; |
unsigned int worst_hits = 30000; /* Should use UINT_MAX :-( */ |
unsigned int worst_hits = 30000; /* Should use UINT_MAX :-( */ |
if (!hostcache) { |
if (!hostcache) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostCache... Garbage collection not done, no cache\n"); |
fprintf(stderr, "HostCache... Garbage collection not done, no cache\n"); |
return; |
return; |
} |
} |
Line 321 PRIVATE host_info *HTTCPCacheAddElement
|
Line 348 PRIVATE host_info *HTTCPCacheAddElement
|
char **index = element->h_addr_list; |
char **index = element->h_addr_list; |
int cnt = 1; |
int cnt = 1; |
if (!host || !element) { |
if (!host || !element) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostCache... Bad argument to add to cache\n"); |
fprintf(stderr, "HostCache... Bad argument to add to cache\n"); |
return NULL; |
return NULL; |
} |
} |
Line 348 PRIVATE host_info *HTTCPCacheAddElement
|
Line 375 PRIVATE host_info *HTTCPCacheAddElement
|
if (!hostcache) |
if (!hostcache) |
hostcache = HTList_new(); |
hostcache = HTList_new(); |
|
|
if (TRACE) { |
if (PROT_TRACE) { |
if (newhost->homes == 1) |
if (newhost->homes == 1) |
fprintf(stderr, "HostCache... Adding single-homed host `%s'\n", |
fprintf(stderr, "HostCache... Adding single-homed host `%s'\n", |
HTAtom_name(host)); |
HTAtom_name(host)); |
Line 421 PUBLIC void HTTCPAddrWeights ARGS2(char
|
Line 448 PUBLIC void HTTCPAddrWeights ARGS2(char
|
fprintf(stderr, "AddrWeights. Home %d has weight %4.2f\n", cnt, |
fprintf(stderr, "AddrWeights. Home %d has weight %4.2f\n", cnt, |
*(pres->weight+cnt)); |
*(pres->weight+cnt)); |
} |
} |
} else if (TRACE) { |
} else if (PROT_TRACE) { |
fprintf(stderr, "HostCache... Weights not calculated, host not found in cache: `%s\'\n", host); |
fprintf(stderr, "HostCache... Weights not calculated, host not found in cache: `%s\'\n", host); |
} |
} |
} |
} |
Line 478 PUBLIC int HTGetHostByName ARGS3(char *,
|
Line 505 PUBLIC int HTGetHostByName ARGS3(char *,
|
HTList *cur = hostcache; /* Search cache */ |
HTList *cur = hostcache; /* Search cache */ |
while ((pres = (host_info *) HTList_nextObject(cur)) != NULL) { |
while ((pres = (host_info *) HTList_nextObject(cur)) != NULL) { |
if (pres->hostname == hostatom) { |
if (pres->hostname == hostatom) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostByName.. Host `%s\' found in cache.\n", host); |
fprintf(stderr, "HostByName.. Host `%s\' found in cache.\n", host); |
break; |
break; |
} |
} |
Line 503 PUBLIC int HTGetHostByName ARGS3(char *,
|
Line 530 PUBLIC int HTGetHostByName ARGS3(char *,
|
} else { /* Go and ask for it */ |
} else { /* Go and ask for it */ |
struct hostent *hostelement; /* see netdb.h */ |
struct hostent *hostelement; /* see netdb.h */ |
#ifdef MVS /* Outstanding problem with crash in MVS gethostbyname */ |
#ifdef MVS /* Outstanding problem with crash in MVS gethostbyname */ |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HTTCP on MVS gethostbyname(%s)\n", host); |
fprintf(stderr, "HTTCP on MVS gethostbyname(%s)\n", host); |
#endif |
#endif |
if ((hostelement = gethostbyname(host)) == NULL) { |
if ((hostelement = gethostbyname(host)) == NULL) { |
if (TRACE) fprintf(stderr, "HostByName.. Can't find internet node name `%s'.\n", host); |
if (PROT_TRACE) |
|
fprintf(stderr, "HostByName.. Can't find internet node name `%s'.\n", host); |
return -1; |
return -1; |
} |
} |
|
|
Line 549 PUBLIC char * HTGetHostBySock ARGS1(int,
|
Line 577 PUBLIC char * HTGetHostBySock ARGS1(int,
|
sizeof(struct in_addr), |
sizeof(struct in_addr), |
AF_INET); |
AF_INET); |
if (!phost) { |
if (!phost) { |
if (TRACE) fprintf(stderr, |
if (PROT_TRACE) |
"TCP......... Can't find internet node name for peer!!\n"); |
fprintf(stderr, "TCP......... Can't find internet node name for peer!!\n"); |
return NULL; |
return NULL; |
} |
} |
StrAllocCopy(name, phost->h_name); |
StrAllocCopy(name, phost->h_name); |
if (TRACE) fprintf(stderr, "TCP......... Peer name is `%s'\n", name); |
if (PROT_TRACE) fprintf(stderr, "TCP......... Peer name is `%s'\n", name); |
|
|
return name; |
return name; |
|
|
Line 591 PUBLIC int HTParseInet ARGS3(SockA *, si
|
Line 619 PUBLIC int HTParseInet ARGS3(SockA *, si
|
if ((port=strchr(host, ':'))) { |
if ((port=strchr(host, ':'))) { |
*port++ = 0; /* Chop off port */ |
*port++ = 0; /* Chop off port */ |
if (isdigit(*port)) { |
if (isdigit(*port)) { |
|
if (TRACE) fprintf(stderr, "TESTTESTTEST `%s\'\n", host); |
|
|
#ifdef DECNET |
#ifdef DECNET |
sin->sdn_objnum = (unsigned char)(strtol(port, (char**)0, 10)); |
sin->sdn_objnum = (unsigned char)(strtol(port, (char**)0, 10)); |
#else /* Internet */ |
#else /* Internet */ |
Line 613 PUBLIC int HTParseInet ARGS3(SockA *, si
|
Line 643 PUBLIC int HTParseInet ARGS3(SockA *, si
|
sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(host)); /* <=6 in phase 4 */ |
sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(host)); /* <=6 in phase 4 */ |
strncpy (sin->sdn_nam.n_name, host, sin->sdn_nam.n_len + 1); |
strncpy (sin->sdn_nam.n_name, host, sin->sdn_nam.n_len + 1); |
|
|
if (TRACE) fprintf(stderr, |
if (PROT_TRACE) fprintf(stderr, |
"DECnet: Parsed address as object number %d on host %.6s...\n", |
"DECnet: Parsed address as object number %d on host %.6s...\n", |
sin->sdn_objnum, host); |
sin->sdn_objnum, host); |
|
|
Line 638 PUBLIC int HTParseInet ARGS3(SockA *, si
|
Line 668 PUBLIC int HTParseInet ARGS3(SockA *, si
|
return -1; |
return -1; |
} |
} |
} |
} |
if (TRACE) { |
if (PROT_TRACE) { |
fprintf(stderr, "ParseInet... Parsed address as port %d on %s\n", |
fprintf(stderr, "ParseInet... Parsed address as port %d on %s\n", |
(int) ntohs(sin->sin_port), |
(int) ntohs(sin->sin_port), |
HTInetString(sin)); |
HTInetString(sin)); |
Line 668 PRIVATE void get_host_details NOARGS
|
Line 698 PRIVATE void get_host_details NOARGS
|
|
|
if (hostname) return; /* Already done */ |
if (hostname) return; /* Already done */ |
gethostname(name, namelength); /* Without domain */ |
gethostname(name, namelength); /* Without domain */ |
if (TRACE) fprintf(stderr, "TCP......... Local host name is %s\n", name); |
if (PROT_TRACE) fprintf(stderr, "TCP......... Local host name is %s\n", name); |
StrAllocCopy(hostname, name); |
StrAllocCopy(hostname, name); |
|
|
#ifndef DECNET /* Decnet ain't got no damn name server 8#OO */ |
#ifndef DECNET /* Decnet ain't got no damn name server 8#OO */ |
phost=gethostbyname(name); /* See netdb.h */ |
phost=gethostbyname(name); /* See netdb.h */ |
if (!phost) { |
if (!phost) { |
if (TRACE) fprintf(stderr, |
if (PROT_TRACE) fprintf(stderr, |
"TCP......... Can't find my own internet node address for `%s'!!\n", |
"TCP......... Can't find my own internet node address for `%s'!!\n", |
name); |
name); |
return; /* Fail! */ |
return; /* Fail! */ |
} |
} |
StrAllocCopy(hostname, phost->h_name); |
StrAllocCopy(hostname, phost->h_name); |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "TCP......... Full local host name is %s\n", hostname); |
fprintf(stderr, "TCP......... Full local host name is %s\n", hostname); |
|
|
#ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ |
#ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ |
memcpy(&HTHostAddress, &phost->h_addr, phost->h_length); |
memcpy(&HTHostAddress, &phost->h_addr, phost->h_length); |
if (TRACE) fprintf(stderr, " Name server says that I am `%s' = %s\n", |
if (PROT_TRACE) fprintf(stderr, " Name server says that I am `%s' = %s\n", |
hostname, HTInetString(&HTHostAddress)); |
hostname, HTInetString(&HTHostAddress)); |
#endif /* NEED_HOST_ADDRESS */ |
#endif /* NEED_HOST_ADDRESS */ |
|
|
Line 732 PUBLIC void HTSetHostName ARGS1(char *,
|
Line 762 PUBLIC void HTSetHostName ARGS1(char *,
|
if (*(hostname+strlen(hostname)-1) == '.') /* Remove trailing dot */ |
if (*(hostname+strlen(hostname)-1) == '.') /* Remove trailing dot */ |
*(hostname+strlen(hostname)-1) = '\0'; |
*(hostname+strlen(hostname)-1) = '\0'; |
} else { |
} else { |
if (TRACE) fprintf(stderr, "SetHostName. Bad argument ignored\n"); |
if (PROT_TRACE) fprintf(stderr, "SetHostName. Bad argument ignored\n"); |
} |
} |
} |
} |
|
|
Line 767 PUBLIC CONST char * HTGetHostName NOARGS
|
Line 797 PUBLIC CONST char * HTGetHostName NOARGS
|
} |
} |
*(name+MAXHOSTNAMELEN) = '\0'; |
*(name+MAXHOSTNAMELEN) = '\0'; |
if (gethostname(name, MAXHOSTNAMELEN)) { /* Maybe without domain */ |
if (gethostname(name, MAXHOSTNAMELEN)) { /* Maybe without domain */ |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostName.... Can't get host name\n"); |
fprintf(stderr, "HostName.... Can't get host name\n"); |
return NULL; |
return NULL; |
} |
} |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostName.... Local host name is `%s\'\n", name); |
fprintf(stderr, "HostName.... Local host name is `%s\'\n", name); |
StrAllocCopy(hostname, name); |
StrAllocCopy(hostname, name); |
{ |
{ |
Line 810 PUBLIC CONST char * HTGetHostName NOARGS
|
Line 840 PUBLIC CONST char * HTGetHostName NOARGS
|
#ifndef sco |
#ifndef sco |
if (!got_it) { |
if (!got_it) { |
if (getdomainname(name, MAXHOSTNAMELEN)) { |
if (getdomainname(name, MAXHOSTNAMELEN)) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostName.... Can't get domain name\n"); |
fprintf(stderr, "HostName.... Can't get domain name\n"); |
StrAllocCopy(hostname, ""); |
StrAllocCopy(hostname, ""); |
return NULL; |
return NULL; |
Line 838 PUBLIC CONST char * HTGetHostName NOARGS
|
Line 868 PUBLIC CONST char * HTGetHostName NOARGS
|
if (*(hostname+strlen(hostname)-1) == '.') /* Remove trailing dot */ |
if (*(hostname+strlen(hostname)-1) == '.') /* Remove trailing dot */ |
*(hostname+strlen(hostname)-1) = '\0'; |
*(hostname+strlen(hostname)-1) = '\0'; |
} |
} |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostName.... Full host name is `%s\'\n", hostname); |
fprintf(stderr, "HostName.... Full host name is `%s\'\n", hostname); |
return hostname; |
return hostname; |
|
|
Line 848 PUBLIC CONST char * HTGetHostName NOARGS
|
Line 878 PUBLIC CONST char * HTGetHostName NOARGS
|
{ |
{ |
struct hostent *hostelement; |
struct hostent *hostelement; |
if ((hostelement = gethostbyname(hostname)) == NULL) { |
if ((hostelement = gethostbyname(hostname)) == NULL) { |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HostName.... Can't find host name on DNS\n"); |
fprintf(stderr, "HostName.... Can't find host name on DNS\n"); |
FREE(hostname); |
FREE(hostname); |
return NULL; |
return NULL; |
Line 863 PUBLIC CONST char * HTGetHostName NOARGS
|
Line 893 PUBLIC CONST char * HTGetHostName NOARGS
|
/* HTSetMailAddress |
/* HTSetMailAddress |
** Sets the current mail address plus host name and domain name. |
** Sets the current mail address plus host name and domain name. |
** If this is not set then the default approach is used using |
** If this is not set then the default approach is used using |
** HTGetMailAddress(). |
** HTGetMailAddress(). If the argument is NULL or "" then HTGetMailAddress |
|
** returns NULL on a succeding request. |
*/ |
*/ |
PUBLIC void HTSetMailAddress ARGS1(char *, address) |
PUBLIC void HTSetMailAddress ARGS1(char *, address) |
{ |
{ |
if (address && *address) |
if (!address || !*address) |
|
StrAllocCopy(mailaddress, ""); |
|
else |
StrAllocCopy(mailaddress, address); |
StrAllocCopy(mailaddress, address); |
else { |
if (TRACE) |
if (TRACE) fprintf(stderr, "SetMailAddress. Bad argument ignored\n"); |
fprintf(stderr, "SetMailAdr.. Set mail address to `%s\'\n", |
} |
mailaddress); |
} |
} |
|
|
|
|
Line 906 PUBLIC CONST char * HTGetMailAddress NOA
|
Line 939 PUBLIC CONST char * HTGetMailAddress NOA
|
|
|
#ifdef VMS |
#ifdef VMS |
if ((login = (char *) cuserid(NULL)) == NULL) { |
if ((login = (char *) cuserid(NULL)) == NULL) { |
if (TRACE) fprintf(stderr, "MailAddress. cuserid returns NULL\n"); |
if (PROT_TRACE) fprintf(stderr, "MailAddress. cuserid returns NULL\n"); |
} |
} |
|
|
#else /* not VMS */ |
#else /* not VMS */ |
if ((login = (char *) getlogin()) == NULL) { |
if ((login = (char *) getlogin()) == NULL) { |
if (TRACE) fprintf(stderr, "MailAddress. getlogin returns NULL\n"); |
if (PROT_TRACE) |
|
fprintf(stderr, "MailAddress. getlogin returns NULL\n"); |
if ((pw_info = getpwuid(getuid())) == NULL) { |
if ((pw_info = getpwuid(getuid())) == NULL) { |
if (TRACE) fprintf(stderr, "MailAddress. getpwid returns NULL\n"); |
if (PROT_TRACE) |
|
fprintf(stderr, "MailAddress. getpwid returns NULL\n"); |
if ((login = getenv("LOGNAME")) == NULL) { |
if ((login = getenv("LOGNAME")) == NULL) { |
if (TRACE) fprintf(stderr, "MailAddress. LOGNAME not found\n"); |
if (PROT_TRACE) |
|
fprintf(stderr, "MailAddress. LOGNAME not found\n"); |
if ((login = getenv("USER")) == NULL) { |
if ((login = getenv("USER")) == NULL) { |
if (TRACE) fprintf(stderr,"MailAddress. USER not found\n"); |
if (PROT_TRACE) |
|
fprintf(stderr,"MailAddress. USER not found\n"); |
return NULL; /* I GIVE UP */ |
return NULL; /* I GIVE UP */ |
} |
} |
} |
} |
Line 955 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
Line 992 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
u_short, default_port, u_long *, addr, |
u_short, default_port, u_long *, addr, |
BOOL, use_cur) |
BOOL, use_cur) |
{ |
{ |
time_t deltatime; |
|
int hosts; |
|
int status; |
int status; |
SockA sock_addr; /* SockA is defined in tcp.h */ |
|
char *p1 = HTParse(url, "", PARSE_HOST); |
char *p1 = HTParse(url, "", PARSE_HOST); |
char *at_sign; |
char *at_sign; |
char *host; |
char *host; |
|
|
/* if theres an @ then use the stuff after it as a hostname */ |
/* if theres an @ then use the stuff after it as a hostname */ |
if((at_sign = strchr(p1,'@')) != NULL) |
if((at_sign = strchr(p1, '@')) != NULL) |
host = at_sign+1; |
host = at_sign+1; |
else |
else |
host = p1; |
host = p1; |
Line 973 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
Line 1007 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
NULL, 0, "HTDoConnect"); |
NULL, 0, "HTDoConnect"); |
free(p1); |
free(p1); |
return -1; |
return -1; |
} else |
} else { |
if (TRACE) fprintf(stderr, "HTDoConnect. Looking up `%s\'\n", host); |
if (PROT_TRACE) |
|
fprintf(stderr, "HTDoConnect. Looking up `%s\'\n", host); |
|
} |
|
|
/* Set up defaults */ |
/* Set up defaults */ |
memset((void *) &sock_addr, '\0', sizeof(sock_addr)); |
if (net->sockfd < 0) { |
|
memset((void *) &net->sock_addr, '\0', sizeof(net->sock_addr)); |
#ifdef DECNET |
#ifdef DECNET |
sock_addr.sdn_family = AF_DECnet; /* Family = DECnet, host order */ |
net->sock_addr.sdn_family = AF_DECnet;/* Family = DECnet, host order */ |
sock_addr.sdn_objnum = DNP_OBJ; /* Default: http object number */ |
net->sock_addr.sdn_objnum = DNP_OBJ; /* Default: http object number */ |
#else /* Internet */ |
#else /* Internet */ |
sock_addr.sin_family = AF_INET; |
net->sock_addr.sin_family = AF_INET; |
sock_addr.sin_port = htons(default_port); |
net->sock_addr.sin_port = htons(default_port); |
#endif |
#endif |
|
} |
|
|
/* If we are trying to connect to a multi-homed host then loop here until |
/* If we are trying to connect to a multi-homed host then loop here until |
success or we have tried all IP-addresses */ |
success or we have tried all IP-addresses */ |
do { |
do { |
if ((hosts = HTParseInet(&sock_addr, host, use_cur)) < 0) { |
if (net->sockfd < 0) { |
if (TRACE) fprintf(stderr, "HTDoConnect. Can't locate remote host `%s\'\n", host); |
int hosts; |
HTErrorAdd(net->request, ERR_FATAL, NO, HTERR_NO_REMOTE_HOST, |
if ((hosts = HTParseInet(&net->sock_addr, host, use_cur)) < 0) { |
(void *) host, strlen(host), "HTDoConnect"); |
if (PROT_TRACE) |
goto errorend; |
fprintf(stderr, "HTDoConnect. Can't locate remote host `%s\'\n", host); |
} |
HTErrorAdd(net->request, ERR_FATAL, NO, HTERR_NO_REMOTE_HOST, |
|
(void *) host, strlen(host), "HTDoConnect"); |
|
break; |
|
}; |
|
if (!net->addressCount && hosts > 1) |
|
net->addressCount = hosts; |
#ifdef DECNET |
#ifdef DECNET |
if ((net->sockfd = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) |
if ((net->sockfd = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) |
#else |
#else |
if ((net->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) |
if ((net->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) |
#endif |
#endif |
|
{ |
|
HTErrorSysAdd(net->request, ERR_FATAL, NO, "socket"); |
|
break; |
|
} |
|
if (addr) |
|
*addr = ntohl(net->sock_addr.sin_addr.s_addr); |
|
if (PROT_TRACE) |
|
fprintf(stderr, "HTDoConnect. Created socket number %d\n", |
|
net->sockfd); |
|
|
|
/* If non-blocking protocol then change socket status */ |
|
/* I use FCNTL so that I can ask the status before I set it */ |
|
if (!HTProtocolBlocking(net->request)) { |
|
if((status = FCNTL(net->sockfd, F_GETFL, 0)) != -1) { |
|
status |= FNDELAY; |
|
status = FCNTL(net->sockfd, F_SETFL, status); |
|
} |
|
if (status == -1) { |
|
if (PROT_TRACE) |
|
fprintf(stderr, "HTDoConnect. Can NOT make socket non-blocking\n"); |
|
} |
|
} |
|
|
|
/* If multi-homed host then start timer on connection */ |
|
if (net->addressCount >= 1) |
|
net->connecttime = time(NULL); |
|
} |
|
|
|
/* Check for interrupt */ |
|
if (HTThreadIntr(net->sockfd)) { |
|
if (NETCLOSE(net->sockfd) < 0) |
|
HTErrorSysAdd(net->request, ERR_FATAL, NO, "NETCLOSE"); |
|
HTThreadState(net->sockfd, THD_CLOSE); |
|
net->sockfd = -1; |
|
free(p1); |
|
return HT_INTERRUPTED; |
|
} |
|
|
|
/* Do a connect */ |
|
status = connect(net->sockfd, (struct sockaddr *) &net->sock_addr, |
|
sizeof(net->sock_addr)); |
|
/* |
|
* 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. |
|
*/ |
|
#ifdef EAGAIN |
|
if ((status < 0) && ((errno == EINPROGRESS) || (errno == EAGAIN))) |
|
#else |
|
if ((status < 0) && (errno == EINPROGRESS)) |
|
#endif /* EAGAIN */ |
{ |
{ |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "socket"); |
if (PROT_TRACE) |
goto errorend; |
fprintf(stderr, "HTDoConnect. WOULD BLOCK `%s'\n", host); |
|
HTThreadState(net->sockfd, THD_SET_WRITE); |
|
free(p1); |
|
return HT_WOULD_BLOCK; |
} |
} |
if (addr) |
if (net->addressCount >= 1) { |
*addr = ntohl(sock_addr.sin_addr.s_addr); |
net->connecttime = time(NULL) - net->connecttime; |
if (PROT_TRACE) |
|
fprintf(stderr, "HTDoConnect. Created socket number %d\n", |
|
net->sockfd); |
|
|
|
/* If multi-homed host then start timer on connection */ |
|
if (hosts > 1) |
|
deltatime = time(NULL); |
|
|
|
status = connect(net->sockfd, (struct sockaddr *) &sock_addr, |
|
sizeof(sock_addr)); |
|
if (hosts > 1) { |
|
deltatime = time(NULL) - deltatime; |
|
if (status < 0) { |
if (status < 0) { |
|
if (errno == EISCONN) { /* connect multi after would block */ |
|
HTThreadState(net->sockfd, THD_CLR_WRITE); |
|
HTTCPAddrWeights(host, net->connecttime); |
|
free(p1); |
|
net->addressCount = 0; |
|
return 0; |
|
} |
HTErrorSysAdd(net->request, ERR_NON_FATAL, NO, "connect"); |
HTErrorSysAdd(net->request, ERR_NON_FATAL, NO, "connect"); |
|
|
|
/* I have added EINVAL `invalid argument' as this is what I |
|
get back from a non-blocking connect where I should |
|
get `connection refused' */ |
if (errno==ECONNREFUSED || errno==ETIMEDOUT || |
if (errno==ECONNREFUSED || errno==ETIMEDOUT || |
errno==ENETUNREACH || errno==EHOSTUNREACH || |
errno==ENETUNREACH || errno==EHOSTUNREACH || |
errno==EHOSTDOWN) |
errno==EHOSTDOWN || errno==EINVAL) |
deltatime += TCP_DELAY; |
net->connecttime += TCP_DELAY; |
else |
else |
deltatime += TCP_PENALTY; |
net->connecttime += TCP_PENALTY; |
if (NETCLOSE(net->sockfd) < 0) |
if (NETCLOSE(net->sockfd) < 0) |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "close"); |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "NETCLOSE"); |
HTTCPAddrWeights(host, deltatime); |
HTThreadState(net->sockfd, THD_CLOSE); |
|
net->sockfd = -1; |
|
HTTCPAddrWeights(host, net->connecttime); |
|
} else { /* Connect on multi-homed */ |
|
HTTCPAddrWeights(host, net->connecttime); |
|
free(p1); |
|
net->addressCount = 0; |
|
return 0; |
|
} |
|
} else if (status < 0) { |
|
if (errno == EISCONN) { /* Connect single after would block */ |
|
HTThreadState(net->sockfd, THD_CLR_WRITE); |
|
net->addressCount = 0; |
|
free(p1); |
|
return 0; |
} else { |
} else { |
HTTCPAddrWeights(host, deltatime); |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "connect"); |
|
HTTCPCacheRemoveHost(host); |
|
if (NETCLOSE(net->sockfd) < 0) |
|
HTErrorSysAdd(net->request, ERR_FATAL, NO, "NETCLOSE"); |
|
HTThreadState(net->sockfd, THD_CLOSE); |
break; |
break; |
} |
} |
} else if (status < 0) { |
} else { /* Connect on single homed */ |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "connect"); |
free(p1); |
HTTCPCacheRemoveHost(host); |
net->addressCount = 0; |
if (NETCLOSE(net->sockfd) < 0) |
return 0; |
HTErrorSysAdd(net->request, ERR_FATAL, NO, "close"); |
|
goto errorend; |
|
} |
} |
} while (net->addressCount++ < hosts-1); |
} while (--net->addressCount); |
|
|
if (hosts > 1 && net->addressCount >= hosts) { |
|
if (PROT_TRACE) fprintf(stderr, "HTDoConnect. None of the %d addresses on multi-homed host is accessible\n", hosts); |
|
goto errorend; |
|
} |
|
|
|
free(p1); |
if (PROT_TRACE) |
net->addressCount = 0; |
fprintf(stderr, "HTDoConnect. Connect failed\n"); |
return status; |
|
|
|
errorend: |
|
free (p1); |
free (p1); |
net->addressCount = 0; |
net->addressCount = 0; |
net->sockfd = -1; |
net->sockfd = -1; |
Line 1067 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
Line 1183 PUBLIC int HTDoConnect ARGS5(HTNetInfo *
|
** |
** |
** BUGS Interrupted is not yet implemented!!! |
** BUGS Interrupted is not yet implemented!!! |
** |
** |
** Returns 0 if OK, -1 on error |
** Returns HT_WOULD_BLOCK if waiting |
|
** 0 if OK, |
|
** -1 on error |
*/ |
*/ |
PUBLIC int HTDoAccept ARGS1(HTNetInfo *, net) |
PUBLIC int HTDoAccept ARGS1(HTNetInfo *, net) |
{ |
{ |
Line 1076 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
Line 1194 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
int cnt; |
int cnt; |
int soc_addrlen = sizeof(soc_address); |
int soc_addrlen = sizeof(soc_address); |
if (net->sockfd < 0) { |
if (net->sockfd < 0) { |
if (TRACE) fprintf(stderr, "HTDoAccept.. Bad socket number\n"); |
if (PROT_TRACE) fprintf(stderr, "HTDoAccept.. Bad socket number\n"); |
return -1; |
return -1; |
} |
} |
|
|
/* First make the socket non-blocking */ |
/* First make the socket non-blocking */ |
#ifdef VMS |
#ifdef VMS |
#ifdef MULTINET |
#ifdef MULTINET |
Line 1103 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
Line 1221 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
for(cnt=0; cnt<MAX_ACCEPT_POLL; cnt++) { |
for(cnt=0; cnt<MAX_ACCEPT_POLL; cnt++) { |
if ((status = accept(net->sockfd, (struct sockaddr*) &soc_address, |
if ((status = accept(net->sockfd, (struct sockaddr*) &soc_address, |
&soc_addrlen)) >= 0) { |
&soc_addrlen)) >= 0) { |
if (TRACE) fprintf(stderr, |
if (PROT_TRACE) fprintf(stderr, |
"HTDoAccept.. Accepted new socket %d\n", |
"HTDoAccept.. Accepted new socket %d\n", |
status); |
status); |
return status; |
return status; |
Line 1113 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
Line 1231 PUBLIC int HTDoAccept ARGS1(HTNetInfo *,
|
} |
} |
|
|
/* If nothing has happened */ |
/* If nothing has happened */ |
if (TRACE) |
if (PROT_TRACE) |
fprintf(stderr, "HTDoAccept.. Timed out, no connection!\n"); |
fprintf(stderr, "HTDoAccept.. Timed out, no connection!\n"); |
HTErrorAdd(net->request, ERR_FATAL, NO, HTERR_TIME_OUT, NULL, 0, |
HTErrorAdd(net->request, ERR_FATAL, NO, HTERR_TIME_OUT, NULL, 0, |
"HTDoAccept"); |
"HTDoAccept"); |
return -1; |
return -1; |
} |
} |
|
|
|
|