OSSP CVS Repository

ossp - Difference in ossp-pkg/lmtp2nntp/lmtp2nntp.c versions 1.36 and 1.37
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.36 -> 1.37

--- lmtp2nntp.c  2001/08/30 09:01:59     1.36
+++ lmtp2nntp.c  2001/08/30 11:53:25     1.37
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <sys/utsname.h>
+#include <sys/time.h>
 
 /* third party */
 #include "str.h"
@@ -73,6 +74,7 @@
     char   *lhlo_domain;
 };
 
+static int connect_nonb(int, const struct sockaddr *, socklen_t, int);
 static void initsession(struct session *session);
 static void resetsession(struct session *session);
 int groupmatch(char *, size_t, char *);
@@ -94,6 +96,7 @@
     char           *option_deliverymodefakestatus;
     char           *option_deliverymodefakedsn;
     int             option_maxmessagesize;
+    int             option_waittime;
     int             nsc;
     struct ns       ns[MAXNEWSSERVICES];
     char           *azGroupargs;
@@ -125,13 +128,21 @@
 static void usage(char *command)
 {
     /*  use
-     *  perl <lmtp2nntp.c -e 'while (<>) { if(m/\/\*POD (.*) .*\*\//) { $_=$1; s/.<(.*?)>/$1/g ; print "$_ " };}'
+     *  perl <lmtp2nntp.c -e 'while (<>) { if(m/\/\*POD (.*) .*\*\//) { $_=$1; s/.<(.*?)>/$1/g ; print "\"$_\"\n" };}'
      *  to pull the USAGE string out of this source
      */
     fprintf(stderr, 
             "USAGE: %s "
-            "[-V] [-d deliverymode] [-g groupmode] [-h host[:port][,host[:port], ...]] "
-            "[-m maxmessagesize] [-n hostname] [-t tracefile] [-v] newsgroup [newsgroup ...]"
+            "[-V]"
+            "[-d deliverymode]"
+            "[-g groupmode]"
+            "[-h host[:port][,host[:port], ...]]"
+            "[-m maxmessagesize]"
+            "[-n hostname]"
+            "[-t tracefile]"
+            "[-v]"
+            "[-w waittime]"
+            "newsgroup [newsgroup ...]"
             "\n",
             command);
     return;
@@ -164,6 +175,7 @@
     ctx->option_deliverymodefakestatus = "553";   /* Requested action not taken: mailbox name not allowed */
     ctx->option_deliverymodefakedsn    = "5.7.1"; /* Delivery not authorized, message refused */
     ctx->option_maxmessagesize = 8 * 1024 * 1024;
+    ctx->option_waittime = -1;
     ctx->nsc = 0;
     for (i=0; i < MAXNEWSSERVICES; i++) {
         ctx->ns[i].h = NULL;
@@ -205,7 +217,7 @@
      */
 
     /* read in the arguments */
-    while ((i = getopt(argc, argv, "Vd:g:h:m:n:t:v")) != -1) {
+    while ((i = getopt(argc, argv, "Vd:g:h:m:n:t:vw:")) != -1) {
         switch (i) {
             case 'V': /*POD [B<-V>] (version)*/
                 fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu);
@@ -331,6 +343,14 @@
             case 'v': /*POD [B<-v>] (verbose)*/
                 ctx->option_verbose = TRUE;
                 break;
+            case 'w': /*POD [B<-w> I<waittime>] */
+                    ctx->option_waittime = atoi(optarg);
+                    if(ctx->option_waittime < 1) {
+                        fprintf(stderr, "%s:Error: waittime %d to option -w must be greater 1 second.\n", 
+                                progname, ctx->option_waittime);
+                        exit(ERR_EXECUTION);
+                    }
+                break;
             case '?':
             default:
                 usage(progname);
@@ -389,6 +409,61 @@
     return rc;
 }
 
+/* taken from "UNIX Network Programming", Volume 1, second edition W. Richard
+ * Stevens, connect_nonb.c from section 15.4 "Nonblocking connect", page 411,
+ * http://www.kohala.com/start/
+ */
+int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen, int nsec)
+{
+        int                             flags, n, error;
+        socklen_t               len;
+        fd_set                  rset, wset;
+        struct timeval  tval;
+
+        flags = fcntl(sockfd, F_GETFL, 0);
+        fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+        error = 0;
+        if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
+                if (errno != EINPROGRESS)
+                        return(-1);
+
+        /* Do whatever we want while the connect is taking place. */
+
+        if (n == 0)
+                goto done;      /* connect completed immediately */
+
+        FD_ZERO(&rset);
+        FD_SET(sockfd, &rset);
+        wset = rset;
+        tval.tv_sec = nsec;
+        tval.tv_usec = 0;
+
+        if ( (n = select(sockfd+1, &rset, &wset, NULL,
+                                         nsec ? &tval : NULL)) == 0) {
+                close(sockfd);          /* timeout */
+                errno = ETIMEDOUT;
+                return(-1);
+        }
+
+        if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+                len = sizeof(error);
+                if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+                        return(-1);                     /* Solaris pending error */
+        } else
+                return(-1); /* err_quit("select error: sockfd not set"); */
+
+done:
+        fcntl(sockfd, F_SETFL, flags);  /* restore file status flags */
+
+        if (error) {
+                close(sockfd);          /* just in case */
+                errno = error;
+                return(-1);
+        }
+        return(0);
+}
+
 static void resetsession(struct session *session)
 {
     if (session->lhlo_domain != NULL)
@@ -478,13 +553,24 @@
     i = 0;
     do {
         bOk = TRUE;
-        if (connect(ctx->ns[i].s, ctx->ns[i].sa->sa_buf, ctx->ns[i].sa->sa_len) < 0) {
-            bOk = FALSE;
+        if (ctx->option_waittime > 0) {
+            if (connect_nonb(ctx->ns[i].s, ctx->ns[i].sa->sa_buf, ctx->ns[i].sa->sa_len, 
+                         ctx->option_waittime) < 0) {
+                bOk = FALSE;
+            }
+        }
+        else {
+            if (connect(ctx->ns[i].s, ctx->ns[i].sa->sa_buf, ctx->ns[i].sa->sa_len) < 0) {
+                bOk = FALSE;
+            }
         }
         if (bOk && ((ctx->ns[i].nntp = nntp_create(ctx->ns[i].s, ctx->ns[i].s, 
                                                    ctx->option_tracing ? &nntp_io : NULL)) == NULL)) {
             bOk = FALSE;
         }
+        if (bOk && ctx->option_waittime >= 0) {
+            nntp_timeout(ctx->ns[i].nntp, ctx->option_waittime);
+        }
         if (bOk && ((rc = nntp_init(ctx->ns[i].nntp)) != NNTP_OK)) {
             bOk = FALSE;
         }

CVSTrac 2.0.1