OSSP CVS Repository

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

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.4 -> 1.5

--- lmtp2nntp.c  2001/07/25 11:29:38     1.4
+++ lmtp2nntp.c  2001/07/25 15:02:57     1.5
@@ -1,4 +1,3 @@
-
 /*
  * mail2nntp.c
  *
@@ -13,6 +12,7 @@
  */
 
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
@@ -21,15 +21,25 @@
 
 /* third party */
 #include "str.h"
+#include "argz.h"
 
 /* own headers */
 #include "lmtp.h"
 
+#ifndef FALSE
+#define FALSE (1 != 1)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
 #define ERR_EXECUTION -1
 #define ERR_DELIVERY -2
 
 #define MESSAGE_MAXLEN 8*1024*1024
 
+extern void lmtp_debug_dumplmtp(lmtp_t *lmtp);
+
 static ssize_t trace_read(int d, void *buf, size_t nbytes);
 static ssize_t trace_write(int d, const void *buf, size_t nbytes);
 
@@ -41,80 +51,25 @@
 static lmtp_rc_t lmtp_cb_rset   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
 static lmtp_rc_t lmtp_cb_quit   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
 
-static void usage(char *command);
-static void test(void);
-
-int main(int argc, char **argv)
-{
-    int i; /* general purpose scratch int, index ... */
-
-    {
-        char buf[1000];
-        int bufused = 0;
-        int tracefile;
-
-// printf("DEBUG: start of argdump\n", buf);
-        for (i=0; i<argc; i++) {
-// printf("DEBUG: [%d]=***%s***\n", i, argv[i]);
-            bufused+=sprintf(buf+bufused, "[%d]=\"%s\"\n", i, argv[i]);
-        }
-// printf("DEBUG: buffer ***%s***\n", buf);
-        if ((tracefile = open("/tmp/t", O_CREAT|O_WRONLY|O_APPEND, 0664)) != -1) {
-            write(tracefile, buf, bufused);
-// printf("DEBUG: writing\n", buf);
-            close(tracefile);
-        }
-// printf("DEBUG: end of argdump\n", buf);
-    }
-
-    /* read in the arguments */
-
-#if 0
-
-    while ((i = getopt(argc, argv, "p:l:h:m:tv")) != -1)
-        switch (i) {
-            case 'p': // -p protocol
-                break;
-            case 'l': // -l logtarget
-                break;
-            case 'h': // -h host[:port]
-                break;
-            case 'm': // -m mode
-                break;
-            case 'd': // -t (tracing)
-                break;
-            case 'v': // -v (verbose)
-                break;
-            case '?':
-            default:
-                //FIXME usage(argv[0]);
-                //FIXME exit(ERR_EXECUTION);
-        }
-    argc -= optind; argv += optind; // remaining args is/are newsgroup/s
-#endif
-    
-    //FIXME printf("Hello, World!\n");
-    test();
-    //FIXME printf("Hello, Again!\n");
-    return 0;
-}
-
-/*
- * print usage information
- *
- */
-
-static void usage(char *command)
-{
-    fprintf(stderr, "USAGE: %s [-p protocol] [-l logtarget] "\
-     "[-h host[:port]] [-m mode] [-t] [-v] newsgroup [newsgroup ...]\n",
-     command);
-    return;
-}
+typedef struct {
+    int option_verbose;
+    int option_tracing;
+    int option_mode;
+    char  *azNewsgroups;
+    size_t asNewsgroups;
+    char *rfc822message;
+    int saw_lhlo;
+    char  *azRcpt;
+    size_t asRcpt;
+} lmtp2nntp_t;
+
+enum {
+    MODE_ONCE,
+    MODE_MANY
+};
 
 /*
  * tracing
- *
  */
 ssize_t trace_read(int d, void *buf, size_t nbytes)
 {
@@ -143,72 +98,137 @@
 }
 
 /*
- * test a function
- *
+ * print usage information
  */
+static void usage(char *command)
+{
+    fprintf(stderr, 
+            "USAGE: %s [-p protocol] [-l logtarget] "
+            "[-h host[:port]] [-m mode] [-t] [-v] newsgroup [newsgroup ...]\n",
+            command);
+    return;
+}
 
-extern void lmtp_debug_dumplmtp(lmtp_t *lmtp);
-static void test(void)
+int main(int argc, char **argv)
 {
+    int rc = 0;
     lmtp_t *lmtp;
-    lmtp_rc_t rc;
-    lmtp_req_t req;
-    lmtp_res_t res;
-    lmtp_io_t io;
-#define BUFLEN 100
-    char buf[BUFLEN];
-    lmtp_cb_t oldcb = NULL;
-    
+    lmtp_io_t lmtp_io;
+    lmtp2nntp_t *ctx;
+    int i; /* general purpose scratch int, index ... */
 
-    io.read=trace_read;
-    io.write=trace_write;
-    io.select=select;
-    lmtp = lmtp_create(STDIN_FILENO, STDOUT_FILENO, &io);
-    // lmtp_debug_dumplmtp(lmtp);
-    lmtp_register(lmtp, "LHLO",         NULL, NULL,&oldcb,NULL); // printf("DEBUG: 1 oldcb=%d\n", (int)oldcb);
-    lmtp_register(lmtp, "LHLO", lmtp_cb_lhlo, NULL,&oldcb,NULL); // printf("DEBUG: 2 oldcb=%d\n", (int)oldcb);
-    lmtp_register(lmtp, "LHLO",         NULL, NULL,&oldcb,NULL); // printf("DEBUG: 3 oldcb=%d\n", (int)oldcb);
-    lmtp_register(lmtp, "MAIL", lmtp_cb_mail, NULL, NULL, NULL);
-    lmtp_register(lmtp, "RCPT", lmtp_cb_rcpt, NULL, NULL, NULL);
-    lmtp_register(lmtp, "DATA", lmtp_cb_data, NULL, NULL, NULL);
-    lmtp_register(lmtp, "NOOP", lmtp_cb_noop, NULL, NULL, NULL);
-    lmtp_register(lmtp, "RSET", lmtp_cb_rset, NULL, NULL, NULL);
-    lmtp_register(lmtp, "QUIT", lmtp_cb_quit, NULL, NULL, NULL);
-    // lmtp_debug_dumplmtp(lmtp);
-
-    /*
-    printf("DEBUG: 05 lmtp_response\n");    res.statuscode="123";
-                                            res.dsncode="1.2.3";
-                                            res.statusmsg="Hello,\nthis is a\nmultiline\nmessage";
-                                            lmtp_response(lmtp, &res);
-    */
-
-    /*
-    do { 
-        rc = lmtp_readline(lmtp, buf, BUFLEN);
-        printf("DEBUG: 06 lmtp_readline=%d ***%s***\n", rc, buf);
-    } while(rc == LMTP_OK);
-    */
-
-    /*
-    do {
-        rc = lmtp_request(lmtp, &req);
-        printf("DEBUG: 07 lmtp_request=%d ***%s***%s***\n", rc, req.verb, req.msg);
-    } while(rc == LMTP_OK || rc == LMTP_ERR_VERB);
-    */
+    char *progname = argv[0];
 
-    /* printf("DEBUG: 08 lmtp_loop=%d\n", */ lmtp_loop(lmtp) /*)*/;
+    /* create application context */
+    if ((ctx = (lmtp2nntp_t *)malloc(sizeof(lmtp2nntp_t))) == NULL)
+        exit(ERR_EXECUTION);
+    ctx->option_verbose = FALSE;
+    ctx->option_tracing = FALSE;
+    ctx->option_mode = MODE_MANY;
+    ctx->azNewsgroups = NULL;
+    ctx->asNewsgroups = 0;
+    ctx->rfc822message = NULL;
+    ctx->saw_lhlo = FALSE;
+    ctx->azRcpt = NULL;
+    ctx->asRcpt = 0;
 
-    /* printf("DEBUG: 99.\n"); */
-    return;
+    /* read in the arguments */
+    {
+        char buf[1000];
+        int bufused = 0;
+        int tracefile;
+
+        for (i=0; i<argc; i++)
+            bufused+=sprintf(buf+bufused, "[%d]=\"%s\"\n", i, argv[i]);
+        if ((tracefile = open("/tmp/t", O_CREAT|O_WRONLY|O_APPEND, 0664)) != -1) {
+            write(tracefile, buf, bufused);
+            close(tracefile);
+        }
+    }
+    while ((i = getopt(argc, argv, "p:l:h:m:tvo:c:i:t:")) != -1) {
+        switch (i) {
+            case 'p': // -p protocol
+                break;
+            case 'l': // -l logtarget
+                break;
+            case 'o': // FIXME
+                break;
+            case 'c': // FIXME
+                break;
+            case 'i': // FIXME
+                break;
+            case 't': // FIXME
+                break;
+            case 'h': // -h host[:port]
+                break;
+            case 'm': // -m mode
+                if (strcasecmp(argv[optind], "once") == 0)
+                    ctx->option_mode = MODE_ONCE;
+                else if (strcasecmp(argv[optind], "many") == 0)
+                    ctx->option_mode = MODE_MANY;
+                else {
+                    fprintf(stderr, "%s:Error: Invalid mode \"%s\" to option -m\n", progname, argv[optind]);
+                    exit(ERR_EXECUTION);
+                }
+                break;
+            case 'd': // -t (tracing)
+                ctx->option_tracing = TRUE;
+                break;
+            case 'v': // -v (verbose)
+                ctx->option_verbose = TRUE;
+                break;
+            case '?':
+            default:
+                usage(progname);
+                exit(ERR_EXECUTION);
+        }
+    }
+    /* remaining arguments are newsgroup names */
+    for (i = optind; i < argc; i++)
+        argz_add(&ctx->azNewsgroups, &ctx->asNewsgroups, argv[i]);
+
+    /* initialize LMTP context */
+    lmtp_io.read  = trace_read;
+    lmtp_io.write = trace_write;
+    if ((lmtp = lmtp_create(STDIN_FILENO, STDOUT_FILENO, &lmtp_io)) == NULL) {
+        fprintf(stderr, "%s:Error: Unable to initialize LMTP library\n", progname);
+        exit(ERR_EXECUTION);
+    }
+    lmtp_register(lmtp, "LHLO", lmtp_cb_lhlo, ctx, NULL, NULL); 
+    lmtp_register(lmtp, "MAIL", lmtp_cb_mail, ctx, NULL, NULL);
+    lmtp_register(lmtp, "RCPT", lmtp_cb_rcpt, ctx, NULL, NULL);
+    lmtp_register(lmtp, "DATA", lmtp_cb_data, ctx, NULL, NULL);
+    lmtp_register(lmtp, "NOOP", lmtp_cb_noop, ctx, NULL, NULL);
+    lmtp_register(lmtp, "RSET", lmtp_cb_rset, ctx, NULL, NULL);
+    lmtp_register(lmtp, "QUIT", lmtp_cb_quit, ctx, NULL, NULL);
+    
+    /* loop for LMTP protocol */
+    lmtp_loop(lmtp);
+
+    return 0;
 }
-static lmtp_rc_t lmtp_cb_lhlo(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
+
+static lmtp_rc_t lmtp_cb_lhlo(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
-    lmtp_res_t res;
+    /*  
+     *  RFC821 [excerpt] 4.1. SMTP COMMANDS
+     *  4.1.1.  COMMAND SEMANTICS, HELO
+     *  This command and an OK reply to it confirm that both the sender-SMTP
+     *  and the receiver-SMTP are in the initial state, that is, there is no
+     *  transaction in progress and all state tables and buffers are cleared.
+     * 
+     */
     lmtp_rc_t rc = LMTP_OK;
+    lmtp_res_t res;
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
+
+    //FIXME use rset() not lmtp_cb_rset()
+    ctx->saw_lhlo = TRUE;
+
     res.statuscode = "250";
     res.dsncode    = NULL; /* DSN not used for greeting */
     res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\nPIPELINING\n8BITMIME";
+    res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\n8BITMIME";
         /*
          *  RFC2034 = EHANCEDSTATUSCODES
          *  RFC1894 = DSN
@@ -219,71 +239,80 @@
     return rc;
 }
 
-static lmtp_rc_t lmtp_cb_mail(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
+static lmtp_rc_t lmtp_cb_mail(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_OK;
-    res.statuscode = "553";
-    res.dsncode    = "5.1.8";
-    res.statusmsg  = "Bad sender FIXME";
-    res.statuscode = "250";
-    res.dsncode    = "2.1.0";
-    res.statusmsg  = "Sender ok FIXME";
-    lmtp_response(lmtp, &res);
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
+
+    if (ctx->saw_lhlo == TRUE) {
+        res.statuscode = "250";
+        res.dsncode    = "2.1.0";
+        res.statusmsg  = "Sender ok FIXME";
+        lmtp_response(lmtp, &res);
+    } else {
+        res.statuscode = "553";
+        res.dsncode    = "5.1.8";
+        res.statusmsg  = "friendly people say LHLO to open a transmission channel";
+        lmtp_response(lmtp, &res);
+    }
     return rc;
 }
 
-static lmtp_rc_t lmtp_cb_rcpt(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
+static lmtp_rc_t lmtp_cb_rcpt(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
     lmtp_rc_t rc = LMTP_OK;
     lmtp_res_t res;
-    char **cp;
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
 
+    argz_add(&ctx->azRcpt, &ctx->asRcpt, req->msg);
     res.statuscode = "250";
     res.dsncode    = "2.1.5";
     res.statusmsg  = "Recipient ok FIXME";
     lmtp_response(lmtp, &res);
 
-    cp = lmtp_message(lmtp, "RCPT");
-    if (cp == NULL) {
-        printf("DEBUG: cp=NULL\n");
-    } else {
-        printf("DEBUG: cp=%d\n", cp);
-    }
-
     return rc;
 }
 
 
-static lmtp_rc_t lmtp_cb_data(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
+static lmtp_rc_t lmtp_cb_data(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_OK;
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
     char *buf;
     char errorstring[128];
+    char *rcpt;
 
     res.statuscode = "354";
     res.dsncode    = NULL; /* DSN not used for data */
     res.statusmsg  = "Enter mail, end with \".\" on a line by itself";
     lmtp_response(lmtp, &res);
     rc = lmtp_readmsg(lmtp, &buf, MESSAGE_MAXLEN);
-    if(rc == LMTP_OK) {
-// printf("DEBUG: message=***%s***\n", buf);
-        res.statuscode = "250";
-        res.dsncode    = "2.0.0";
-        res.statusmsg  = "Message accepted for delivery";
-    } else if (rc == LMTP_ERR_OVERFLOW) {
-        res.statuscode = "500";
-        res.dsncode    = "5.0.0";
-        res.statusmsg  = "Message accepted for delivery";
-    } else if (rc == LMTP_ERR_SYSTEM) {
-        res.statuscode = "500";
-        res.dsncode    = "5.0.0";
-        str_format(errorstring, sizeof(errorstring),
-                   "Message accepted for delivery %s", strerror(errno));
-        res.statusmsg  = errorstring;
+
+    rcpt = NULL;
+    while ((rcpt = argz_next(ctx->azRcpt, ctx->asRcpt, rcpt)) != NULL)
+    {
+        if(rc == LMTP_OK) {
+            res.statuscode = "250";
+            res.dsncode    = "2.0.0";
+            // res.statusmsg  = "Message accepted for delivery";
+            str_format(errorstring, sizeof(errorstring),
+                       "Message accepted for delivery to %s", rcpt);
+            res.statusmsg  = errorstring;
+        } else if (rc == LMTP_ERR_OVERFLOW) {
+            res.statuscode = "500";
+            res.dsncode    = "5.0.0";
+            res.statusmsg  = "Message accepted for delivery";
+        } else if (rc == LMTP_ERR_SYSTEM) {
+            res.statuscode = "500";
+            res.dsncode    = "5.0.0";
+            str_format(errorstring, sizeof(errorstring),
+                       "Message accepted for delivery %s", strerror(errno));
+            res.statusmsg  = errorstring;
+        }
+        lmtp_response(lmtp, &res);
     }
-    lmtp_response(lmtp, &res);
     return rc;
 }
 
@@ -297,10 +326,17 @@
     lmtp_response(lmtp, &res);
     return rc;
 }
-static lmtp_rc_t lmtp_cb_rset(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
+static lmtp_rc_t lmtp_cb_rset(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_OK;
+
+    if (ctx->azRcpt != NULL) {
+        free(ctx->azRcpt);
+        ctx->azRcpt = NULL;
+        ctx->asRcpt = 0;
+    }
     res.statuscode = "250";
     res.dsncode    = "2.0.0";
     res.statusmsg  = "Reset state.";

CVSTrac 2.0.1