OSSP CVS Repository

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

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.13 -> 1.14

--- lmtp2nntp.c  2001/08/08 10:43:00     1.13
+++ lmtp2nntp.c  2001/08/13 06:41:41     1.14
@@ -24,6 +24,7 @@
 #include "lmtp.h"
 #include "nntp.h"
 #include "sa.h"
+#include "msg.h"
 
 #ifndef FALSE
 #define FALSE (1 != 1)
@@ -52,8 +53,6 @@
 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 lmtp_rc_t prepareheader(void *ctx);
-
 static int helo_rfc0821domain(char *msg, char **domain);
 static int helo_rfc1035domain(char *msg, char **domain);
 
@@ -65,19 +64,6 @@
 static void initsession(struct session *session);
 static void resetsession(struct session *session);
 
-struct message {
-    char   *cpMsg;      /* the wholly message to be received by DATA command */
-    char   *cpHeaders;  /* header part of message above */
-    char   *cpBody;     /* body part of message above */
-    char   *mail_from;
-    char   *azRcpt;
-    size_t  asRcpt;
-    char   *azHeaders;
-    size_t  asHeaders;
-};
-static void initmessage(struct message *message);
-static void resetmessage(struct message *message);
-
 struct ns {
     char *h;        /* host */
     char *p;        /* port */
@@ -97,7 +83,7 @@
     char   *azGroupfilters;
     size_t  asGroupfilters;
     struct  session session;
-    struct  message message;
+    msg_t  *msg;
 } lmtp2nntp_t;
 
 enum {
@@ -188,7 +174,7 @@
     ctx->azGroupfilters = NULL;
     ctx->asGroupfilters = 0;
     initsession(&ctx->session);
-    initmessage(&ctx->message);
+    ctx->msg = NULL;
 
     {
         char buf[1000];
@@ -315,38 +301,6 @@
     return;
 }
 
-static void resetmessage(struct message *message)
-{
-                                             //FIXME what about non-graceful aborts?
-    if (message->mail_from != NULL)
-        free(message->mail_from);
-    if (message->azRcpt != NULL)
-        free(message->azRcpt);
-    if (message->azHeaders != NULL)
-        free(message->azHeaders);
-    if (message->cpMsg != NULL)
-        free(message->cpMsg);
-    if (message->cpHeaders != NULL)
-        free(message->cpHeaders);
-    if (message->cpBody != NULL)
-        free(message->cpBody);
-    initmessage(message);
-    return;
-}
-
-static void initmessage(struct message *message)
-{
-    message->mail_from = NULL;
-    message->azRcpt = NULL;
-    message->asRcpt = 0;
-    message->azHeaders = NULL;
-    message->asHeaders = 0;
-    message->cpMsg = NULL;
-    message->cpHeaders = NULL;
-    message->cpBody = NULL;
-    return;
-}
-
 static lmtp_rc_t lmtp_cb_lhlo(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
 {
     /*  
@@ -568,36 +522,46 @@
 
 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;
     lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
+    lmtp_res_t res;
 
     if (ctx->session.lhlo_seen != TRUE) {
         res.statuscode = "553";
         res.dsncode    = "5.1.8";
         res.statusmsg  = "friendly people say LHLO to open a transmission channel.";
         lmtp_response(lmtp, &res);
+        return LMTP_OK;
     }
-    else if (ctx->message.mail_from != NULL) {
+
+    if (ctx->msg != NULL) {
         res.statuscode = "503";
         res.dsncode    = "5.5.0";
         res.statusmsg  = "Sender already specified.";
         lmtp_response(lmtp, &res);
+        return LMTP_OK;
+    }
+
+    if ((ctx->msg = msg_create()) == NULL) {
+        res.statuscode = "503"; // FIXME
+        res.dsncode    = "5.5.0";
+        res.statusmsg  = "Internal error - memory.";
+        lmtp_response(lmtp, &res);
+        return LMTP_ERR_MEM;
     }
-    else
-        if (!str_parse(req->msg, "m/^MAIL From: <(.+@.+)>$/i", &ctx->message.mail_from)) {
+
+    if (!str_parse(req->msg, "m/^MAIL From: <(.+@.+)>$/i", &ctx->msg->mail_from)) {
         res.statuscode = "553";
         res.dsncode    = "5.5.4";
         res.statusmsg  = "Domain name required for sender address.";
         lmtp_response(lmtp, &res);
+        return LMTP_OK;
     }
-    else {
-        res.statuscode = "250";
-        res.dsncode    = "2.1.0";
-        res.statusmsg  = "Sender ok.";
-        lmtp_response(lmtp, &res);
-    }
-    return rc;
+    
+    res.statuscode = "250";
+    res.dsncode    = "2.1.0";
+    res.statusmsg  = "Sender ok.";
+    lmtp_response(lmtp, &res);
+    return LMTP_OK;
 }
 
 static lmtp_rc_t lmtp_cb_rcpt(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *_ctx)
@@ -607,7 +571,7 @@
     char *cp;
     char *group;
 
-    if (ctx->message.mail_from == NULL) {
+    if (ctx->msg->mail_from == NULL) {
         res.statuscode = "503";
         res.dsncode    = "5.0.0";
         res.statusmsg  = "specify sender with MAIL first.";
@@ -658,8 +622,8 @@
         return LMTP_OK;
     }
 
-    fprintf(stderr, "DEBUG: cp=***%s***\n", cp);
-    argz_add(&ctx->message.azRcpt, &ctx->message.asRcpt, cp);
+    //fprintf(stderr, "DEBUG: cp=***%s***\n", cp);
+    argz_add(&ctx->msg->azRcpt, &ctx->msg->asRcpt, cp);
     argz_add(&ctx->azGroups, &ctx->asGroups, group);
     res.statuscode = "250";
     res.dsncode    = "2.1.5";
@@ -675,8 +639,9 @@
     lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
     char errorstring[STDSTRLEN];
     char *rcpt;
+    int i;
 
-    if (argz_count(ctx->message.azRcpt, ctx->message.asRcpt) == 0) {
+    if (argz_count(ctx->msg->azRcpt, ctx->msg->asRcpt) == 0) {
         res.statuscode = "503";
         res.dsncode    = "5.0.0";
         res.statusmsg  = "specify recipient with RCPT first.";
@@ -689,11 +654,11 @@
     res.statusmsg  = "Enter mail, end with \".\" on a line by itself";
     lmtp_response(lmtp, &res);
 
-    rc = lmtp_readmsg(lmtp, &ctx->message.cpMsg, MESSAGE_MAXLEN);
+    rc = lmtp_readmsg(lmtp, &ctx->msg->cpMsg, MESSAGE_MAXLEN);
 
     if (rc == LMTP_ERR_OVERFLOW) {
         rcpt = NULL;
-        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+        while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
             res.statuscode = "500";
             res.dsncode    = "5.0.0";
             res.statusmsg  = "Overflow reading message"; //FIXME temp or perm error?
@@ -704,7 +669,7 @@
 
     if (rc == LMTP_ERR_SYSTEM) {
         rcpt = NULL;
-        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+        while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
             res.statuscode = "500";
             res.dsncode    = "5.0.0";
             str_format(errorstring, sizeof(errorstring), "System error reading message: %s", strerror(errno));
@@ -716,7 +681,7 @@
 
     if(rc != LMTP_OK) {
         rcpt = NULL;
-        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+        while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
             res.statuscode = "500";
             res.dsncode    = "5.0.0";
             res.statusmsg  = "Unknown error reading message"; //FIXME call lmtp_error()?
@@ -725,14 +690,61 @@
         }
     }
 
-    /* manipulate headers
-     * - remove To: and Cc: headers
-     * - (re)create Newsgroups: header
-     */
-    prepareheader(ctx);
+#if 0
+    fprintf(stderr, "DEBUG: calling msg_split();\n");
+    fprintf(stderr, "DEBUG: msg_split() returned %s\n", msg_error(ctx->msg, msg_split(ctx->msg)));
+#endif
+    if (msg_split(ctx->msg) != MSG_OK) {
+        while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
+            res.statuscode = "500";
+            res.dsncode    = "5.0.0";
+            res.statusmsg  = "Error splitting message."; //FIXME call msg_error()?
+            lmtp_response(lmtp, &res);
+            return LMTP_OK;
+        }
+    }
+
+#if 0
+    { //FIXME just a debug paragraph
+        char *cp;
+        cp = NULL;
+        while((cp = argz_next(ctx->azGroups, ctx->asGroups, cp)) != NULL)
+            fprintf(stderr, "DEBUG: lmtp Groups: ***%s***\n", cp);
+    }
+#endif
+    ctx->msg->azNewsgroups = ctx->azGroups;
+    ctx->msg->asNewsgroups = ctx->asGroups;
+#if 0
+    { //FIXME just a debug paragraph
+        char *cp;
+        cp = NULL;
+        while((cp = argz_next(ctx->msg->azNewsgroups, ctx->msg->asNewsgroups, cp)) != NULL)
+            fprintf(stderr, "DEBUG: article Newsgroups: ***%s***\n", cp);
+        fprintf(stderr, "DEBUG: article Message-ID: ***%s***\n", ctx->msg->cpMsgid);
+    }
+#endif
+
+#if 0
+    fprintf(stderr, "DEBUG: calling msg_join();\n");
+    fprintf(stderr, "DEBUG: msg_join()  returned %s\n", msg_error(ctx->msg, msg_join(ctx->msg)));
+#endif
+    if (msg_join(ctx->msg) != MSG_OK) {
+        while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
+            res.statuscode = "500";
+            res.dsncode    = "5.0.0";
+            res.statusmsg  = "Error joining message."; //FIXME call msg_error()?
+            lmtp_response(lmtp, &res);
+            return LMTP_OK;
+        }
+    }
+
+    for (i=0; i < ctx->nsc; i++) {
+        fprintf(stderr, "DEBUG: trying service %s\n", ctx->ns[i].h);
+        (void)nntp_post(ctx->ns[i].nntp, ctx->msg);
+    }
 
     rcpt = NULL;
-    while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+    while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
         res.statuscode = "250";
         res.dsncode    = "2.0.0";
         str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt);
@@ -740,175 +752,10 @@
         lmtp_response(lmtp, &res);
     }
 
-    resetmessage(&ctx->message);
-    return rc;
-}
-
-lmtp_rc_t prepareheader(void *_ctx)
-{
-    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
-    char  *cpName;
-    char  *cpValue;
-    char  *cpRem;
-    char  *cp;
-    char  *azNewsgroups;
-    int    asNewsgroups;
-    char **aHeaders;
-    char  *cpMsgid;
-    int    i;
-    char  *cpCut;
-    char  *cpWrap;
-
-                                /****************
-                                 * PARSE HEADER *                                   FIXME make it nice
-                                 ****************/
-
-    if (!str_parse(ctx->message.cpMsg, "m/((?:.*?)\\n)\\n(.*)$/s", &ctx->message.cpHeaders, &ctx->message.cpBody))
-        return LMTP_ERR_ARG;
-
-    if (strlen(ctx->message.cpHeaders) < 4 + 1)
-        return LMTP_ERR_ARG;
-    memcpy(ctx->message.cpHeaders, "X-F:", 4); /* replace envelope From w/o colon by X-F: pseudotag */
-
-    // fprintf(stderr, "DEBUG: input ***%s***\n", ctx->message.cpHeaders);
-    while (str_parse(ctx->message.cpHeaders, "s/(.*?)\\n[ \\t]+(.*)/$1 $2/s", &cpRem)) { //FIXME poor man's s///g simulator
-        free(ctx->message.cpHeaders);
-        ctx->message.cpHeaders = cpRem;
-    }
-    /*
-     *  FIXME str enhancement requests and bugs to be fixed
-     *
-     *  - fix bug "not" [^...] working
-     *  - improve str_parse(foo, "...", &foo) should free foo() on it's own
-     *  - add "global" in s/search/replace/g
-     */
-    // fprintf(stderr, "DEBUG: unwrapped ***%s***\n", ctx->message.cpHeaders);
-
-    while (str_parse(ctx->message.cpHeaders, "m/^([\\w-]+?:)[ \\t]*(.*?)[ \\t]*\\n(.*)/s", &cpName, &cpValue, &cpRem)) {
-        free(ctx->message.cpHeaders);
-        ctx->message.cpHeaders = cpRem;
-        //fprintf(stderr, "DEBUG: raw    Name(%s) = Value(%s)\n", cpName, cpValue);
-        argz_add(&ctx->message.azHeaders, &ctx->message.asHeaders, cpName);
-        argz_add(&ctx->message.azHeaders, &ctx->message.asHeaders, cpValue);
-    }
-    memcpy(ctx->message.azHeaders, "From", 4); /* replace envelope X-F: pseudotag with From w/o colon */
-    // fprintf(stderr, "DEBUG: remainder ***%s***\n", ctx->message.cpHeaders);
-    // fprintf(stderr, "DEBUG: body ***%s***\n", ctx->message.cpBody);
-
-                                /*********************
-                                 * MANIPULATE HEADER *                              FIXME make it nice
-                                 *********************/
-
-    /* check for headers we care about and verfiy them, throw them away ... */
-    cpMsgid = NULL;
-    cp = ctx->message.azHeaders;
-    while (cp != NULL) {
-        fprintf(stderr, "DEBUG: checking header ***%s***\n", cp);
-        if (strcasecmp("To:", cp) == 0) {
-            argz_delete(&ctx->message.azHeaders, &ctx->message.asHeaders, cp); /* name  */
-            argz_delete(&ctx->message.azHeaders, &ctx->message.asHeaders, cp); /* value */
-            continue;
-        } //FIXME what bad things can happen here (odd number of argz, delete fails ...
-        if (strcasecmp("Cc:", cp) == 0) {
-            argz_delete(&ctx->message.azHeaders, &ctx->message.asHeaders, cp); /* name  */
-            argz_delete(&ctx->message.azHeaders, &ctx->message.asHeaders, cp); /* value */
-            continue;
-        } //FIXME what bad things can happen here (odd number of argz, delete fails ...
-        if (strcasecmp("Message-ID:", cp) == 0) {
-            if ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) == NULL)
-                break;
-            cpMsgid = cp;
-            if ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) == NULL)
-                break;
-            continue;
-        }
-        if ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) == NULL)
-            break;
-        if ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) == NULL)
-            break;
-    }
-    if (cpMsgid == NULL)
-        exit(1); //FIXME
-    else
-        fprintf(stderr, "DEBUG: Message-ID = ***%s***\n", cpMsgid);
-
-    /* create a proper Newsgroups: header */
-    cp = NULL;
-    azNewsgroups = NULL;
-    asNewsgroups = 0;
-    while ((cp = argz_next(ctx->azGroups, ctx->asGroups, cp)) != NULL) {
-        // fprintf(stderr, "DEBUG: Group(%s)\n", cp);
-        argz_add(&azNewsgroups, &asNewsgroups, cp);
-    }
-    argz_stringify(azNewsgroups, asNewsgroups, ',');
-    argz_add(&ctx->message.azHeaders, &ctx->message.asHeaders, "Newsgroups:");
-    argz_add(&ctx->message.azHeaders, &ctx->message.asHeaders, azNewsgroups);
-
-    /* merge name/value pairs into single string */
-    argz_add(&ctx->message.azHeaders, &ctx->message.asHeaders, ""); /* append empty string */
-    if ((aHeaders = (char **)malloc((argz_count(ctx->message.azHeaders,
-        ctx->message.asHeaders) + 1) * sizeof(char *))) == NULL)
-        exit(1); //FIXME
-    argz_extract(ctx->message.azHeaders, ctx->message.asHeaders, aHeaders);
-    i=0;
-    while(1) {
-        if ((cp = aHeaders[++i]) == NULL)
-            break;
-        *(cp-1) = ' ';
-        if ((cp = aHeaders[++i]) == NULL)
-            break;
-        // *(cp-1) = '\n';
-    }
-
-    /* fold headers */
-//FIXME where to place this defines best
-#define WRAPAT 120
-#define WRAPUSING "\n    "
-    cp = NULL;
-    while ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) != NULL) {
-        if (strlen(cp) >= WRAPAT) {
-            cpRem = cp;
-            cpWrap = NULL;
-            while (strlen(cpRem) >= WRAPAT) {
-                for (i = WRAPAT; i >= 1 && (cpRem[i] != ' ') && (cpRem[i] != '\t'); i--);
-                if (i == 0)
-                    i = WRAPAT; /* sorry, hard cut at non-whitespace */
-                if (i < WRAPAT)
-                    i++; /* we don't care about the whitespace itself */
-                cpCut = str_dup(cpRem, i);
-                //FIXME 1.) continue searching downwards skipping all whitespaces and 2.) as we know the length replace str_dup/ strcat/ free with strncat only
-                if (cpWrap == NULL) {
-                    if ((cpWrap = (char *)malloc(strlen(cpCut)+strlen(WRAPUSING)+1)) == NULL)
-                        exit(1); //FIXME
-                    *cpWrap = '\0';
-                }
-                else {
-                    if ((cpWrap = (char *)realloc(cpWrap, strlen(cpWrap)+strlen(cpCut)+strlen(WRAPUSING)+1)) == NULL)
-                        exit(1); //FIXME
-                    strcat(cpWrap, WRAPUSING);
-                }
-                strcat(cpWrap, cpCut);
-                free(cpCut);
-                cpRem += i;
-            }
-            for (i = 0; i < strlen(cpRem) && ((cpRem[i] == ' ') || (cpRem[i] == '\t')); i++);
-            cpRem += i;
-            if (strlen(cpRem) > 0) {
-                if ((cpWrap = (char *)realloc(cpWrap, strlen(cpWrap)+strlen(cpRem)+strlen(WRAPUSING)+1)) == NULL)
-                    exit(1); //FIXME
-                strcat(cpWrap, WRAPUSING);
-                strcat(cpWrap, cpRem);
-            }
-            argz_delete(&ctx->message.azHeaders, &ctx->message.asHeaders, cp);
-            argz_insert(&ctx->message.azHeaders, &ctx->message.asHeaders, cp, cpWrap);
-            free(cpWrap);
-        }
-    }
+    msg_destroy(ctx->msg);
+    ctx->msg = NULL;
 
-    argz_stringify(ctx->message.azHeaders, ctx->message.asHeaders, '\n');
-    fprintf(stderr, "DEBUG: flat headers = ***%s***\n", ctx->message.azHeaders);
-
-    return LMTP_OK;
+    return rc;
 }
 
 static lmtp_rc_t lmtp_cb_noop(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
@@ -929,7 +776,9 @@
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_OK;
 
-    resetmessage(&ctx->message);
+    msg_destroy(ctx->msg);
+    ctx->msg = NULL;
+
     res.statuscode = "250";
     res.dsncode    = "2.0.0";
     res.statusmsg  = "Reset state.";
@@ -943,7 +792,9 @@
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_EOF;
 
-    resetmessage(&ctx->message);
+    msg_destroy(ctx->msg);
+    ctx->msg = NULL;
+
     resetsession(&ctx->session);
     res.statuscode = "221";
     res.dsncode    = "2.0.0";

CVSTrac 2.0.1