]> Pileus Git - ~andy/fetchmail/blobdiff - socket.c
Fix typo repsonsible -> responsible.
[~andy/fetchmail] / socket.c
index d0098ee86c3f52f9b2f9faa02d3fc15bc3ed55df..e8ed58402f80d3113ba8754c9b0007eb56d46bd3 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -26,7 +26,7 @@
 #include "socket.h"
 #include "fetchmail.h"
 #include "getaddrinfo.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "sdump.h"
 
 /* Defines to allow Cygwin to play nice... */
@@ -48,7 +48,6 @@ extern int h_errno;
 # endif
 #endif /* ndef h_errno */
 
-#ifdef HAVE_SOCKETPAIR
 static char *const *parse_plugin(const char *plugin, const char *host, const char *service)
 {
        char **argvec;
@@ -102,6 +101,7 @@ static char *const *parse_plugin(const char *plugin, const char *host, const cha
        if (!argvec)
        {
                report(stderr, GT_("fetchmail: malloc failed\n"));
+               free(plugin_copy);
                return NULL;
        }
        memset(argvec, 0, s);
@@ -147,7 +147,7 @@ static int handle_plugin(const char *host,
                (void) close(fds[1]);
                if ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) ) {
                        report(stderr, GT_("dup2 failed\n"));
-                       exit(1);
+                       _exit(EXIT_FAILURE);
                }
                /* fds[0] is now connected to 0 and 1; close it */
                (void) close(fds[0]);
@@ -156,7 +156,7 @@ static int handle_plugin(const char *host,
                argvec = parse_plugin(plugin,host,service);
                execvp(*argvec, argvec);
                report(stderr, GT_("execvp(%s) failed\n"), *argvec);
-               exit(0);
+               _exit(EXIT_FAILURE);
                break;
        default:        /* parent */
                /* NOP */
@@ -166,31 +166,12 @@ static int handle_plugin(const char *host,
     (void) close(fds[0]);
     return fds[1];
 }
-#endif /* HAVE_SOCKETPAIR */
 
-#ifdef __UNUSED__
-
-int SockCheckOpen(int fd)
-/* poll given socket; is it selectable? */
-{
-    fd_set r, w, e;
-    int rt;
-    struct timeval tv;
-  
-    for (;;) 
-    {
-       FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
-       FD_SET(fd, &e);
-    
-       tv.tv_sec = 0; tv.tv_usec = 0;
-       rt = select(fd+1, &r, &w, &e, &tv);
-       if (rt == -1 && (errno != EAGAIN && errno != EINTR))
-           return 0;
-       if (rt != -1)
-           return 1;
-    }
+/** Set socket to SO_KEEPALIVE. \return 0 for success. */
+int SockKeepalive(int sock) {
+    int keepalive = 1;
+    return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof keepalive);
 }
-#endif /* __UNUSED__ */
 
 int UnixOpen(const char *path)
 {
@@ -207,12 +188,12 @@ int UnixOpen(const char *path)
        return -1;
     }
 
-       /* Socket opened saved. Usefull if connect timeout 
-        * because it can be closed.
-        */
-       mailserver_socket_temp = sock;
-    
-       if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
+    /* Socket opened saved. Useful if connect timeout
+     * because it can be closed.
+     */
+    mailserver_socket_temp = sock;
+
+    if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
     {
        int olderr = errno;
        fm_close(sock); /* don't use SockClose, no traffic yet */
@@ -220,9 +201,9 @@ int UnixOpen(const char *path)
        errno = olderr;
        sock = -1;
     }
-       
-       /* No connect timeout, then no need to set mailserver_socket_temp */
-       mailserver_socket_temp = -1;
+
+    /* No connect timeout, then no need to set mailserver_socket_temp */
+    mailserver_socket_temp = -1;
 
     return sock;
 }
@@ -235,10 +216,8 @@ int SockOpen(const char *host, const char *service,
     int ord;
     char errbuf[8192] = "";
 
-#ifdef HAVE_SOCKETPAIR
     if (plugin)
        return handle_plugin(host,service,plugin);
-#endif /* HAVE_SOCKETPAIR */
 
     memset(&req, 0, sizeof(struct addrinfo));
     req.ai_socktype = SOCK_STREAM;
@@ -286,6 +265,8 @@ int SockOpen(const char *host, const char *service,
            continue;
        }
 
+       SockKeepalive(i);
+
        /* Save socket descriptor.
         * Used to close the socket after connect timeout. */
        mailserver_socket_temp = i;
@@ -327,7 +308,6 @@ int SockOpen(const char *host, const char *service,
     return i;
 }
 
-
 int SockPrintf(int sock, const char* format, ...)
 {
     va_list ap;
@@ -340,6 +320,7 @@ int SockPrintf(int sock, const char* format, ...)
 }
 
 #ifdef SSL_ENABLE
+#define OPENSSL_NO_SSL_INTERN 1
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
@@ -399,7 +380,7 @@ int SockRead(int sock, char *buf, int len)
                /* OK...  SSL_peek works a little different from MSG_PEEK
                        Problem is that SSL_peek can return 0 if there
                        is no data currently available.  If, on the other
-                       hand, we loose the socket, we also get a zero, but
+                       hand, we lose the socket, we also get a zero, but
                        the SSL_read then SEGFAULTS!  To deal with this,
                        we'll check the error code any time we get a return
                        of zero from SSL_peek.  If we have an error, we bail.
@@ -556,7 +537,7 @@ static int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )
 
        if (outlevel >= O_VERBOSE) {
                if (depth == 0 && SSLverbose)
-                       report(stderr, GT_("Server certificate:\n"));
+                       report(stdout, GT_("Server certificate:\n"));
                else {
                        if (_firstrun) {
                                _firstrun = 0;
@@ -827,16 +808,14 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck
        /* Make sure a connection referring to an older context is not left */
        _ssl_context[sock] = NULL;
        if(myproto) {
-               if(!strcasecmp("ssl2",myproto)) {
-                       _ctx[sock] = SSL_CTX_new(SSLv2_client_method());
-               } else if(!strcasecmp("ssl3",myproto)) {
+               if(!strcasecmp("ssl3",myproto)) {
                        _ctx[sock] = SSL_CTX_new(SSLv3_client_method());
                } else if(!strcasecmp("tls1",myproto)) {
                        _ctx[sock] = SSL_CTX_new(TLSv1_client_method());
                } else if (!strcasecmp("ssl23",myproto)) {
                        myproto = NULL;
                } else {
-                       fprintf(stderr,GT_("Invalid SSL protocol '%s' specified, using default (SSLv23).\n"), myproto);
+                       fprintf(stderr,GT_("Invalid SSL protocol '%s' specified, using default (SSL23).\n"), myproto);
                        myproto = NULL;
                }
        }
@@ -848,7 +827,7 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck
                return(-1);
        }
 
-       SSL_CTX_set_options(_ctx[sock], SSL_OP_ALL);
+       SSL_CTX_set_options(_ctx[sock], (SSL_OP_ALL | SSL_OP_NO_SSLv2) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
 
        if (certck) {
                SSL_CTX_set_verify(_ctx[sock], SSL_VERIFY_PEER, SSL_ck_verify_callback);
@@ -967,30 +946,6 @@ int SockClose(int sock)
     }
 #endif
 
-#ifdef __UNUSED__
-    /* 
-     * This hangs in RedHat 6.2 after fetchmail runs for a while a
-     * FIN_WAIT2 comes up in netstat and fetchmail never returns from
-     * the recv system call. (Reported from jtnews
-     * <jtnews@bellatlantic.net>, Wed, 24 May 2000 21:26:02.)
-     *
-     * Half-close the connection first so the other end gets notified.
-     *
-     * This stops sends but allows receives (effectively, it sends a
-     * TCP <FIN>).  */
-    if (shutdown(sock, 1) == 0) {
-       char ch;
-       /* If there is any data still waiting in the queue, discard it.
-        * Call recv() until either it returns 0 (meaning we received a FIN)
-        * or any error occurs.  This makes sure all data sent by the other
-        * side is acknowledged at the TCP level.
-        */
-       if (fm_peek(sock, &ch, 1) > 0)
-           while (fm_read(sock, &ch, 1) > 0)
-               continue;
-    }
-#endif /* __UNUSED__ */
-
     /* if there's an error closing at this point, not much we can do */
     return(fm_close(sock));    /* this is guarded */
 }
@@ -1003,7 +958,7 @@ int SockClose(int sock)
  */
 static ssize_t cygwin_read(int sock, void *buf, size_t count)
 {
-    char *bp = buf;
+    char *bp = (char *)buf;
     size_t n = 0;
 
     if ((n = read(sock, bp, count)) == (size_t)-1)
@@ -1023,21 +978,3 @@ static ssize_t cygwin_read(int sock, void *buf, size_t count)
     return count;
 }
 #endif /* __CYGWIN__ */
-
-#ifdef MAIN
-/*
- * Use the chargen service to test input buffering directly.
- * You may have to uncomment the `chargen' service description in your
- * inetd.conf (and then SIGHUP inetd) for this to work.  */
-main()
-{
-    int                sock = SockOpen("localhost", "chargen", NULL);
-    char       buf[80];
-
-    while (SockRead(sock, buf, sizeof(buf)-1))
-       SockWrite(1, buf, strlen(buf));
-    SockClose(sock);
-}
-#endif /* MAIN */
-
-/* socket.c ends here */