OSSP CVS Repository

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

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.17 -> 1.18

--- lmtp2nntp.c  2001/08/14 14:42:41     1.17
+++ lmtp2nntp.c  2001/08/16 15:00:50     1.18
@@ -74,6 +74,9 @@
     int     option_verbose;
     int     option_tracing;
     int     option_groupmode;
+    int     option_deliverymode;
+    char   *option_deliverymodefakestatus;
+    char   *option_deliverymodefakedsn;
     int     nsc;
     struct  ns ns[MAXNEWSSERVICES];
     char   *azGroupargs;
@@ -88,6 +91,12 @@
     GROUPMODE_HEADER
 };
 
+enum {
+    DELIVERYMODE_FAKE,
+    DELIVERYMODE_POST,
+    DELIVERYMODE_FEED
+};
+
 /*
  * print usage information
  */
@@ -130,6 +139,9 @@
     ctx->option_verbose = FALSE;
     ctx->option_tracing = FALSE;
     ctx->option_groupmode = GROUPMODE_ARG;
+    ctx->option_deliverymode = DELIVERYMODE_FAKE;
+    ctx->option_deliverymodefakestatus = "553";   /* Requested action not taken: mailbox name not allowed */
+    ctx->option_deliverymodefakedsn    = "5.7.1"; /* Delivery not authorized, message refused */
     ctx->nsc = 0;
     for (i=0; i < MAXNEWSSERVICES; i++) {
         ctx->ns[i].h = "";
@@ -157,8 +169,48 @@
 #endif
 
     /* read in the arguments */
-    while ((i = getopt(argc, argv, "g:h:t:v")) != -1) {
+    while ((i = getopt(argc, argv, "d:g:h:t:v")) != -1) {
         switch (i) {
+            case 'd': /* -d deliverymode */
+                if      (strcasecmp(optarg, "post") == 0)
+                    ctx->option_deliverymode = DELIVERYMODE_POST;
+                else if (strcasecmp(optarg, "feed") == 0)
+                    ctx->option_deliverymode = DELIVERYMODE_FEED;
+                else {
+                    if (strlen(optarg) != 9) {
+                        fprintf(stderr, "%s:Error: Invalid format or length \"%s\" to option -d\n", progname, optarg);
+                        exit(ERR_EXECUTION);
+                    }
+
+                    if (optarg[3] != '/') {
+                        fprintf(stderr, "%s:Error: Invalid format or missing slash \"%s\" to option -d\n", progname, optarg);
+                        exit(ERR_EXECUTION);
+                    }
+
+                    optarg[3] = '\0';
+                    ctx->option_deliverymodefakestatus = &optarg[0];
+                    ctx->option_deliverymodefakedsn    = &optarg[4];
+
+                    if (   strlen(ctx->option_deliverymodefakestatus) != 3
+                        || !isdigit(ctx->option_deliverymodefakestatus[0])
+                        || !isdigit(ctx->option_deliverymodefakestatus[1])
+                        || !isdigit(ctx->option_deliverymodefakestatus[2])) {
+                            fprintf(stderr, "%s:Error: Invalid status in format \"%s\" to option -d\n", progname, optarg);
+                            exit(ERR_EXECUTION);
+                        }
+
+                    if (   (strlen(ctx->option_deliverymodefakedsn) != 5)
+                        || !isdigit(ctx->option_deliverymodefakedsn[0])
+                        || (ctx->option_deliverymodefakedsn[1] != '.')
+                        || !isdigit(ctx->option_deliverymodefakedsn[2])
+                        || (ctx->option_deliverymodefakedsn[3] != '.')
+                        || !isdigit(ctx->option_deliverymodefakedsn[4])
+                        || (ctx->option_deliverymodefakedsn[0] != ctx->option_deliverymodefakestatus[0])) {
+                            fprintf(stderr, "%s:Error: Invalid dsn in format \"%s\" to option -d\n", progname, optarg);
+                            exit(ERR_EXECUTION);
+                        }
+                    }
+                break;
             case 'g': /* -g groupmode */
                 if      (strcasecmp(optarg, "arg") == 0)
                     ctx->option_groupmode = GROUPMODE_ARG;
@@ -355,9 +407,17 @@
         }
     } while (i < ctx->nsc);
 
+    /*  RFC0821 4.2.1. REPLY CODES BY FUNCTION GROUPS
+     *  "421 <domain> Service not available, closing transmission channel [This
+     *  may be a reply to any command if the service knows it must shut down]"
+     *  
+     *  RFC1893 2. Status Codes, 3.5 Network and Routing Status
+     *  4.X.X   Persistent Transient Failure
+     *  X.4.1   No answer from host
+     */
     if (ctx->nsc == 0) {
-        res.statuscode = "501";
-        res.dsncode    = "5.0.0";
+        res.statuscode = "421";
+        res.dsncode    = "4.4.1";
         res.statusmsg  = "No connection to any NNTP Service."; //FIXME add error strings from above DEBUGs
         lmtp_response(lmtp, &res);
         return LMTP_OK;
@@ -715,26 +775,72 @@
     }
     //fprintf(stderr, "DEBUG: after msg_join\n");
 
-    bSuccess = FALSE;
+    bSuccess = NNTP_EOF; /* assume a hard error for the worst case */
     for (i = 0; i < ctx->nsc; i++) {
         //fprintf(stderr, "DEBUG: trying service %s\n", ctx->ns[i].h);
-        if ((rc = nntp_post(ctx->ns[i].nntp, ctx->msg)) == NNTP_OK)
-            bSuccess = TRUE;
+        switch (ctx->option_deliverymode) {
+            case DELIVERYMODE_FAKE:
+                break;
+            case DELIVERYMODE_POST:
+                rc = nntp_post(ctx->ns[i].nntp, ctx->msg);
+                break;
+            case DELIVERYMODE_FEED:
+                rc = nntp_feed(ctx->ns[i].nntp, ctx->msg);
+                break;
+        }
+        if (rc == NNTP_OK)
+            bSuccess = NNTP_OK;
+        if (   bSuccess != NNTP_OK
+            && (
+                   (rc == NNTP_TIMEOUT)
+                || (rc == NNTP_ERR_SYSTEM)
+                || (rc == NNTP_DEFER)
+                  )
+              )
+            bSuccess = NNTP_DEFER;
     }
     //FIXME rc has only last error
 
+    /*  RFC0821 4.2.1. REPLY CODES BY FUNCTION GROUPS
+     *  "250 Requested mail action okay, completed"
+     *  "451 Requested action aborted: local error in processing"
+     *  "554 Transaction failed"
+     *  
+     *  RFC1893 2. Status Codes
+     *  2.X.X   Success
+     *  4.X.X   Persistent Transient Failure
+     *  5.X.X   Permanent Failure
+     *  
+     *  RFC1893 3.5 Network and Routing Status
+     *  X.0.0   Other undefined Status
+     *  X.4.2   Bad connection
+     */
     rcpt = NULL;
     while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
-        if (bSuccess == TRUE) {
-            str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt);
-            res.statuscode = "250";
-            res.dsncode    = "2.0.0";
-            res.statusmsg  = errorstring;
+        if (ctx->option_deliverymode == DELIVERYMODE_FAKE) {
+                    res.statuscode = ctx->option_deliverymodefakestatus;
+                    res.dsncode    = ctx->option_deliverymodefakedsn;
+                    res.statusmsg  = "NNTP noop fake return";
         } else {
-            str_format(errorstring, sizeof(errorstring), "Last error posting message: %s", nntp_error(rc));
-            res.statuscode = "500";
-            res.dsncode    = "5.0.0";
-            res.statusmsg  = errorstring;
+            switch (bSuccess) {
+                case NNTP_OK:
+                    str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt);
+                    res.statuscode = "250";
+                    res.dsncode    = "2.0.0";
+                    res.statusmsg  = errorstring;
+                    break;
+                case NNTP_DEFER:
+                    res.statuscode = "451";
+                    res.dsncode    = "4.4.2";
+                    res.statusmsg  = "Requested action aborted, local error in processing.";
+                    lmtp_response(lmtp, &res);
+                    break;
+                default:
+                    str_format(errorstring, sizeof(errorstring), "Last error posting message: %s", nntp_error(rc));
+                    res.statuscode = "554";
+                    res.dsncode    = "5.4.2";
+                    res.statusmsg  = errorstring;
+            }
         }
         lmtp_response(lmtp, &res);
     }

CVSTrac 2.0.1