]> granicus.if.org Git - mutt/commitdiff
patch.me.connect_timeout.1
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 4 Oct 2000 08:50:53 +0000 (08:50 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 4 Oct 2000 08:50:53 +0000 (08:50 +0000)
globals.h
init.h
mutt_socket.c
protos.h
signal.c

index 871e59ff4356378903e417b4b9b25b1833514a54..543e685f1a88e80ff1da034f0c1eb78cd8702a43 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -125,6 +125,7 @@ extern unsigned char QuadOptions[];
 
 WHERE unsigned short Counter INITVAL (0);
 
+WHERE short ConnectTimeout;
 WHERE short HistSize;
 WHERE short PagerContext;
 WHERE short PagerIndexLines;
diff --git a/init.h b/init.h
index 20ba1101e8c9bb7d1a04d2806d0ff0ffdd98d7d9..e7ee8cf85ccb5fee35d3698b2baab1eaf5653d90 100644 (file)
--- a/init.h
+++ b/init.h
@@ -319,6 +319,13 @@ struct option_t MuttVars[] = {
   ** When set, Mutt will prompt for confirmation when saving messages to a
   ** mailbox which does not yet exist before creating it.
   */
+  { "connect_timeout", DT_NUM, R_NONE, UL &ConnectTimeout, 30 },
+  /*
+  ** .pp
+  ** Causes Mutt to timeout a network connection (for IMAP or POP) after this
+  ** many seconds if the connection is not able to be established.  A negative
+  ** value causes Mutt to wait indefinitely for the connection to succeed.
+  */
   { "copy",            DT_QUAD, R_NONE, OPT_COPY, M_YES },
   /*
   ** .pp
index c56d07000e19293b0931fe2b0ab84d742413e25f..d513081e08b490ef941683db2b7d3b14b476716b 100644 (file)
@@ -219,6 +219,8 @@ static int socket_connect (int fd, struct sockaddr* sa)
 {
   int sa_size;
   int rc;
+  int save_errno;
+
   /* old first_try_without_preconnect removed for now. unset $preconnect
      first. */
 
@@ -229,10 +231,11 @@ static int socket_connect (int fd, struct sockaddr* sa)
     dprint (1, (debugfile, "Preconnect result: %d\n", rc));
     if (rc)
     {
-      mutt_perror (_("Preconnect command failed."));
-      sleep (1);
+       save_errno = errno;
+       mutt_perror (_("Preconnect command failed."));
+       sleep (1);
 
-      return -1;
+      return save_errno;
     }
   }
 
@@ -246,14 +249,25 @@ static int socket_connect (int fd, struct sockaddr* sa)
     return -1;
   }
   
+  if (ConnectTimeout > 0)
+      alarm (ConnectTimeout);
+
+  mutt_allow_interrupt (1);
+
+  save_errno = 0;
+
   if (connect (fd, sa, sa_size) < 0)
   {
-    dprint (2, (debugfile, "Connection failed. errno: %d...\n", errno));
-
-    return errno;
+      save_errno = errno;
+      dprint (2, (debugfile, "Connection failed. errno: %d...\n", errno));
+      SigInt = 0;      /* reset in case we caugh SIGINTR while in connect() */
   }
-  
-  return 0;
+
+  if (ConnectTimeout > 0)
+      alarm (0);
+  mutt_allow_interrupt (0);
+
+  return save_errno;
 }
 
 /* socket_new_conn: allocate and initialise a new connection. */
@@ -322,10 +336,9 @@ int raw_socket_open (CONNECTION* conn)
     fd = socket (cur->ai_family, cur->ai_socktype, cur->ai_protocol);
     if (fd >= 0)
     {
-      if (socket_connect (fd, res->ai_addr) == 0)
+      if ((rc = socket_connect (fd, res->ai_addr)) == 0)
       {
        conn->fd = fd;
-       rc = 0;
        break;
       }
       else
@@ -365,10 +378,9 @@ int raw_socket_open (CONNECTION* conn)
 
     if (fd > 0)
     {
-      if (socket_connect (fd, (struct sockaddr*) &sin) == 0)
+      if ((rc = socket_connect (fd, (struct sockaddr*) &sin) == 0))
       {
        conn->fd = fd;
-       rc = 0;
        break;
       }
       else
@@ -380,10 +392,7 @@ int raw_socket_open (CONNECTION* conn)
   if (rc)
   {
     mutt_error (_("Could not connect to %s (%s)."), conn->account.host,
-               rc == ETIMEDOUT ? "timed out" :
-               rc == ECONNREFUSED ? "connection refused" :
-               rc == ENETUNREACH ? "host unreachable" :
-               "unknown error");
+           (rc > 0) ? strerror (rc) : _("unknown error"));
     sleep (2);
   }
   
index e582aa4c6f4241036050ac2a5b9c1ac49635774c..a517de354ac94dcd426beed664cf65afa769aded 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -137,6 +137,7 @@ const char *mutt_fqdn(short);
 
 void mutt_adv_mktemp (char *, size_t);
 void mutt_alias_menu (char *, size_t, ALIAS *);
+void mutt_allow_interrupt (int);
 void mutt_block_signals (void);
 void mutt_block_signals_system (void);
 void mutt_body_handler (BODY *, STATE *);
index 68f1f3ca0ed161c84ad52a55a8969833f39c05af..85b5ada9fd21633d893500eec7375d2cbd7a85c9 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -111,12 +111,19 @@ void mutt_signal_init (void)
   /* we want to avoid race conditions */
   sigaddset (&act.sa_mask, SIGTSTP);
 
+  act.sa_handler = sighandler;
+
+  /* we want SIGALRM to abort the current syscall, so we do this before
+   * setting the SA_RESTART flag below.  currently this is only used to
+   * timeout on a connect() call in a reasonable amout of time.
+   */
+  sigaction (SIGALRM, &act, NULL);
+
   /* we also don't want to mess with interrupted system calls */
 #ifdef SA_RESTART
   act.sa_flags = SA_RESTART;
 #endif
 
-  act.sa_handler = sighandler;
   sigaction (SIGCONT, &act, NULL);
   sigaction (SIGTSTP, &act, NULL);
   sigaction (SIGINT, &act, NULL);
@@ -218,3 +225,16 @@ void mutt_unblock_signals_system (int catch)
     unset_option (OPTSYSSIGNALSBLOCKED);
   }
 }
+
+void mutt_allow_interrupt (int disposition)
+{
+  struct sigaction sa;
+  
+  memset (&sa, 0, sizeof sa);
+  sa.sa_handler = sighandler;
+#ifdef SA_RESTART
+  if (disposition == 0)
+    sa.sa_flags |= SA_RESTART;
+#endif
+  sigaction (SIGINT, &sa, NULL);
+}