Index: chatru.c =================================================================== RCS file: /cvsroot/alcc/alcc/chatru.c,v retrieving revision 1.8 diff -u -r1.8 chatru.c --- chatru.c 31 Oct 2006 03:59:45 -0000 1.8 +++ chatru.c 3 Nov 2006 13:30:19 -0000 @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -84,6 +85,11 @@ */ regex_t RegEx[RE_LAST]; +/* + * Proxy routine variables + */ +static bool p_state = 1; +//static bool direct = 0; /* * init @@ -95,11 +101,6 @@ void init (struct InitializerReturnData *ret) { - struct hostent *serverInfo; - char *p; - struct url *purl; - int x; - Login[0] = '\0'; // Set login and ticket to "" Ticket[0] = '\0'; @@ -112,6 +113,60 @@ "Broken regular expressions"); return; } + prepConn (ret); + return; +} + +static void +prepConn (struct InitializerReturnData *ret) +{ + bool pConnState = false, dConnState = false; + + if (((pConnState = prepProxy ()) == 0) + && ((dConnState = prepDirect ()) == 0)) + { + if (!pConnState) { + switch (pConnState) + { + case EINVAL: + snprintf (ret->response, ret->responseSize, iCCCP_SEModInit, + "HTTP_PROXY contains an invalid proxy address"); + break; + case EDOOFUS: + strncpy (ret->response, iCCCP_SEMemory, ret->responseSize); + break; + } + } + if (!dConnState) { + switch (errno) + { + case EAFNOSUPPORT: + snprintf (ret->response, ret->responseSize, iCCCP_SENetwork, + "Unexpected IPv6 server name resolution"); + break; + default: + snprintf (ret->response, ret->responseSize, iCCCP_SENetwork, + hstrerror (h_errno)); + } + } + } + else { + if (dConnState) { + strncpy (ret->response, iCCCP_HostFound, ret->responseSize); + ret->response[ret->responseSize - 1] = '\0'; + } + ret->next = &initConnect; + ret->clientParser = &clientParser; + } + return; +} + +static bool +prepProxy (void) +{ + char *p; + struct url *purl; + int x; bzero (&ServerAddress, sizeof (ServerAddress)); ServerAddress.sin_family = AF_INET; @@ -122,13 +177,13 @@ purl = parseProxyURL (p); if (purl == NULL) { - strncpy (ret->response, iCCCP_SEMemory, ret->responseSize); - return; + errno = EINVAL; + return false; } #ifdef DEBUG_MODULE fprintf (stderr, "[chatru] init(): Proxy host:%s port:%d\n", - purl->host, purl->port); + purl->host, purl->port); #endif ServerAddress.sin_port = htons (purl->port ? purl->port : @@ -138,36 +193,42 @@ if (x == 0) { - snprintf (ret->response, ret->responseSize, iCCCP_SEModInit, - "HTTP_PROXY contains an invalid proxy address"); - return; + errno = EDOOFUS; + return false; } - ret->next = &initConnect; - ret->clientParser = &clientParser; + p_state = true; + return true; } - else if ((serverInfo = gethostbyname (SERVER_HOSTNAME)) == NULL) + errno = 0; // No proxy defined + return false; +} + +static bool +prepDirect (void) +{ + struct hostent *serverInfo; + + bzero (&ServerAddress, sizeof (ServerAddress)); + ServerAddress.sin_family = AF_INET; + + if ((serverInfo = gethostbyname (SERVER_HOSTNAME)) == NULL) { - snprintf (ret->response, ret->responseSize, iCCCP_SENetwork, - hstrerror (h_errno)); } else if (serverInfo->h_addrtype == AF_INET) { - strncpy (ret->response, iCCCP_HostFound, ret->responseSize); - ret->response[ret->responseSize - 1] = '\0'; ServerAddress.sin_port = htons ((short)SERVER_PORT); memcpy (&(ServerAddress.sin_addr.s_addr), serverInfo->h_addr_list[0], serverInfo->h_length); - - ret->next = &initConnect; - ret->clientParser = &clientParser; + p_state = false; + return true; } else { - snprintf (ret->response, ret->responseSize, iCCCP_SENetwork, - "Unexpected IPv6 server name resolution"); + errno = EAFNOSUPPORT; } + return false; } /* @@ -201,7 +262,7 @@ initConnect (struct InitializerReturnData *ret) { int sock; - + int saved_errno; ret->next = NULL; // We are the last sock = socket (PF_INET, SOCK_STREAM, 0); @@ -215,10 +276,17 @@ } if (connect (sock, (struct sockaddr *)&ServerAddress, - sizeof (struct sockaddr_in)) == -1) + sizeof (struct sockaddr_in)) == -1) { + saved_errno = errno; + if (p_state && prepDirect()) // ignore any errs + { + initConnect (ret); + return; + } + errno = saved_errno; snprintf (ret->response, ret->responseSize, iCCCP_SENetwork, - strerror (errno)); + strerror (errno)); ret->clientParser = NULL; return;