All pastes #236266 Raw Edit

Stuff

public text v1 · immutable
·published 2006-11-03 18:49 UTC
rendered paste body
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 <sys/socket.h>
 #include <arpa/inet.h>
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
@@ -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;