* starttls.c (redirect): New function.
[elisp/starttls.git] / starttls.c
index 85c2145..93748fd 100644 (file)
@@ -57,6 +57,7 @@ extern int tls_read(int, char *, int);
 extern int tls_pending();
 
 static char *opt_cert_file = NULL, *opt_key_file = NULL;
+static bool opt_assuan = false;
 static int tls_fd = -1;
 
 static void
@@ -119,6 +120,47 @@ tcp_connect (hostname, service)
 }
 
 int
+redirect (fd, buffer, nbuffer, write_function)
+     int fd;
+     char *buffer;
+     int nbuffer;
+     int (*write_function) (int, const char *, int);
+{
+  sigset_t mask, orig_mask;
+  struct pollfd writefds[1];
+  int wrote;
+  char *retry;
+
+  sigemptyset (&mask);
+  sigaddset (&mask, SIGALRM);
+
+  writefds[0].fd = fd;
+  writefds[0].events = POLLOUT;
+
+  for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
+    {
+      int ready;
+
+      sigprocmask (SIG_SETMASK, &mask, &orig_mask);
+      ready = poll (writefds, 1, -1);
+      sigprocmask (SIG_SETMASK, &orig_mask, NULL);
+      if (ready == -1 && errno != EINTR)
+       {
+         if (opt_assuan)
+           printf ("ERR 1 poll: %s\r\n", strerror (errno));
+         return 1;
+       }
+      wrote = (*write_function)(fd, retry, nbuffer);
+      if (wrote == -1)
+       {
+         if (opt_assuan)
+           printf ("ERR 1 write: %s\r\n", strerror (errno));
+         return 1;
+       }
+    }
+}
+
+int
 main (argc, argv) 
      int argc;
      char **argv;
@@ -126,7 +168,7 @@ main (argc, argv)
   int in = fileno (stdin), out = fileno (stdout),
     nbuffer, wrote;
   struct pollfd readfds[2], writefds[1];
-  char buffer[BUFSIZ], *retry;
+  char buffer[1001], *retry;
   struct sigaction act;
   sigset_t orig_mask;
 
@@ -137,12 +179,13 @@ main (argc, argv)
       {"cert-file", 1, 0, 'c'},
       {"key-file", 1, 0, 'k'},
       {"help", 0, 0, 'h'},
+      {"assuan", 0, 0, 'A'},
       {0, 0, 0, 0}
     };
 
   while (1)
     {
-      c = getopt_long (argc, argv, "c:k:h", long_options, &option_index);
+      c = getopt_long (argc, argv, "c:k:hA", long_options, &option_index);
       if (c == -1)
        break;
     
@@ -157,6 +200,9 @@ main (argc, argv)
        case 'h':
          usage (argv[0]);
          return 0;
+       case 'A':
+         opt_assuan = true;
+         break;
        default:
          usage (argv[0]);
          return 1;
@@ -198,7 +244,8 @@ main (argc, argv)
       sigprocmask (SIG_SETMASK, &orig_mask, NULL);
       if (ready == -1 && errno != EINTR)
        {
-         perror ("poll");
+         if (opt_assuan)
+           printf ("ERR 1 poll: %s\r\n", strerror (errno));
          return 1;
        }
       if (readfds[0].revents & POLLIN)
@@ -207,20 +254,7 @@ main (argc, argv)
 
          if (nbuffer == 0)
            goto finish;
-         for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
-           {
-             writefds[0].fd = tls_fd;
-             sigprocmask (SIG_SETMASK, &act.sa_mask, &orig_mask);
-             ready = poll (writefds, 1, -1);
-             sigprocmask (SIG_SETMASK, &orig_mask, NULL);
-             if (ready == -1 && errno != EINTR)
-               {
-                 perror ("poll");
-                 return 1;
-               }
-             wrote = tls_write(tls_fd, retry, nbuffer);
-             if (wrote < 0) goto finish;
-           }
+         redirect (tls_fd, buffer, nbuffer, tls_write);
        }
       if (readfds[1].revents & POLLIN)
        {
@@ -228,20 +262,7 @@ readtop:
          nbuffer = tls_read(tls_fd, buffer, sizeof buffer -1);
          if (nbuffer == 0)
            goto finish;
-         for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
-           {
-             writefds[0].fd = out;
-             sigprocmask (SIG_SETMASK, &act.sa_mask, &orig_mask);
-             ready = poll (writefds, 1, -1);
-             sigprocmask (SIG_SETMASK, &orig_mask, NULL);
-             if (ready == -1 && errno != EINTR)
-               {
-                 perror ("poll");
-                 return 1;
-               }
-             wrote = write (out, retry, nbuffer);
-             if (wrote < 0) goto finish;
-           }
+         redirect (out, buffer, nbuffer, write);
          if (tls_pending())
            goto readtop;
        }