Diff for /libwww/Library/src/HTTCP.c between versions 2.26 and 2.27

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;
 }  }
   
   

Removed from v.2.26  
changed lines
  Added in v.2.27


Webmaster