Aggregation of remote POP3 accounts is now working.
[citadel.git] / citadel / clientsocket.c
index c2f992ed72013163a08f61b246738766bb85b3bf..eef8a3563a28213c8ca3ad970d5c8e98c176c55c 100644 (file)
 #include <stdarg.h>
 #include "citadel.h"
 #include "server.h"
-#include "serv_extensions.h"
 #ifndef HAVE_SNPRINTF
 #include "snprintf.h"
 #endif
 #include "sysdep_decls.h"
-#include <clientsocket.h>
+#include "config.h"
+#include "clientsocket.h"
+#include "tools.h"
 
 #ifndef INADDR_NONE
 #define INADDR_NONE 0xffffffff
@@ -42,14 +43,15 @@ int sock_connect(char *host, char *service, char *protocol)
        struct servent *pse;
        struct protoent *ppe;
        struct sockaddr_in sin;
+       struct sockaddr_in egress_sin;
        int s, type;
 
-       if (host == NULL) return(-1);
-       if (strlen(host) == 0) return(-1);
-       if (service == NULL) return(-1);
-       if (strlen(service) == 0) return(-1);
-       if (protocol == NULL) return(-1);
-       if (strlen(protocol) == 0) return(-1);
+       if ((host == NULL) || IsEmptyStr(host)) 
+               return(-1);
+       if ((service == NULL) || IsEmptyStr(service)) 
+               return(-1);
+       if ((protocol == NULL) || IsEmptyStr(protocol)) 
+               return(-1);
 
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
@@ -87,6 +89,22 @@ int sock_connect(char *host, char *service, char *protocol)
                return(-1);
        }
 
+       /* If citserver is bound to a specific IP address on the host, make
+        * sure we use that address for outbound connections.
+        */
+       memset(&egress_sin, 0, sizeof(egress_sin));
+       egress_sin.sin_family = AF_INET;
+       if (!IsEmptyStr(config.c_ip_addr)) {
+               egress_sin.sin_addr.s_addr = inet_addr(config.c_ip_addr);
+               if (egress_sin.sin_addr.s_addr == !INADDR_ANY) {
+                       egress_sin.sin_addr.s_addr = INADDR_ANY;
+               }
+
+               /* If this bind fails, no problem; we can still use INADDR_ANY */
+               bind(s, (struct sockaddr *)&egress_sin, sizeof(egress_sin));
+        }
+
+       /* Now try to connect to the remote host. */
        if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
                lprintf(CTDL_ERR, "Can't connect to %s:%s: %s\n",
                        host, service, strerror(errno));
@@ -171,7 +189,7 @@ int sock_write(int sock, char *buf, int nbytes)
  * Input string from socket - implemented in terms of sock_read()
  * 
  */
-int sock_gets(int sock, char *buf)
+int sock_getln(int sock, char *buf, int bufsize)
 {
        int i;
 
@@ -179,20 +197,20 @@ int sock_gets(int sock, char *buf)
         */
        for (i = 0;; i++) {
                if (sock_read(sock, &buf[i], 1) < 0) return(-1);
-               if (buf[i] == '\n' || i == (SIZ-1))
+               if (buf[i] == '\n' || i == (bufsize-1))
                        break;
        }
 
        /* If we got a long line, discard characters until the newline.
         */
-       if (i == (SIZ-1))
+       if (i == (bufsize-1))
                while (buf[i] != '\n')
                        if (sock_read(sock, &buf[i], 1) < 0) return(-1);
 
        /* Strip any trailing CR and LF characters.
         */
        buf[i] = 0;
-       while ( (strlen(buf)>0)
+       while ( (!IsEmptyStr(buf))
              && ((buf[strlen(buf)-1]==13)
              || (buf[strlen(buf)-1]==10)) ) {
                buf[strlen(buf)-1] = 0;
@@ -209,12 +227,12 @@ int ml_sock_gets(int sock, char *buf) {
        char bigbuf[1024];
        int g;
 
-       g = sock_gets(sock, buf);
+       g = sock_getln(sock, buf, SIZ);
        if (g < 4) return(g);
        if (buf[3] != '-') return(g);
 
        do {
-               g = sock_gets(sock, bigbuf);
+               g = sock_getln(sock, bigbuf, SIZ);
                if (g < 0) return(g);
        } while ( (g >= 4) && (bigbuf[3] == '-') );