OSSP CVS Repository

ossp - Check-in [618]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 618
Date: 2001-Aug-07 16:58:02 (local)
2001-Aug-07 14:58:02 (UTC)
User:thl
Branch:
Comment: headers now exctracted and manipulated
Tickets:
Inspections:
Files:
ossp-pkg/lmtp2nntp/lmtp2nntp.c      1.10 -> 1.11     173 inserted, 39 deleted

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.10 -> 1.11

--- lmtp2nntp.c  2001/08/07 09:21:49     1.10
+++ lmtp2nntp.c  2001/08/07 14:58:02     1.11
@@ -52,6 +52,8 @@
 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);
 
@@ -59,15 +61,21 @@
     int     lhlo_seen;
     char   *lhlo_domain;
 };
-static void resetsession(struct session *session);
 
+static void initsession(struct session *session);
+static void resetsession(struct session *session);
 
 struct message {
-    char   *rfc822message;
+    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 {
@@ -179,8 +187,8 @@
     ctx->asGroups = 0;
     ctx->azGroupfilters = NULL;
     ctx->asGroupfilters = 0;
-    resetsession(&ctx->session);
-    resetmessage(&ctx->message);
+    initsession(&ctx->session);
+    initmessage(&ctx->message);
 
     {
         char buf[1000];
@@ -293,36 +301,49 @@
 
 static void resetsession(struct session *session)
 {
+                                             //FIXME what about non-graceful aborts?
+    if (session->lhlo_domain != NULL)
+        free(session->lhlo_domain);         
+    initsession(session);
+    return;
+}
 
+static void initsession(struct session *session)
+{
     session->lhlo_seen = FALSE;
-
-    // fprintf(stderr, "DEBUG: session->lhlo_domain=***%s***\n", session->lhlo_domain);
-    if (session->lhlo_domain != NULL)
-        free(session->lhlo_domain); //FIXME what about non-graceful aborts?
     session->lhlo_domain = NULL;
-
     return;
 }
 
 static void resetmessage(struct message *message)
 {
-    // fprintf(stderr, "DEBUG: message->mail_from=***%s***\n", message->mail_from);
+                                             //FIXME what about non-graceful aborts?
     if (message->mail_from != NULL)
-        free(message->mail_from); //FIXME what about non-graceful aborts?
-    message->mail_from = NULL;
-
-    // fprintf(stderr, "DEBUG: message->azRcpt=***%s***\n", message->azRcpt);
+        free(message->mail_from);
     if (message->azRcpt != NULL)
-        free(message->azRcpt); //FIXME what about non-graceful aborts?
-    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;
-
-    // fprintf(stderr, "DEBUG: message->rfc822message=***%s***\n", message->rfc822message);
-    if (message->rfc822message != NULL)
-        free(message->rfc822message); //FIXME what about non-graceful aborts?
-    message->rfc822message = NULL;
-
+    message->azHeaders = NULL;
+    message->asHeaders = 0;
+    message->cpMsg = NULL;
+    message->cpHeaders = NULL;
+    message->cpBody = NULL;
     return;
 }
 
@@ -618,8 +639,7 @@
             lmtp_response(lmtp, &res);
             return LMTP_OK;
         }
-        cp = group;
-        // fprintf(stderr, "DEBUG: after  transform cp=***%s***\n", cp);
+        // fprintf(stderr, "DEBUG: after  transform group=***%s***\n", group);
         //FIXME do additional transform and checking
         if (0) {
             res.statuscode = "550";
@@ -638,8 +658,9 @@
         return LMTP_OK;
     }
 
-    // fprintf(stderr, "DEBUG: cp=***%s***\n", cp);
+    fprintf(stderr, "DEBUG: cp=***%s***\n", cp);
     argz_add(&ctx->message.azRcpt, &ctx->message.asRcpt, cp);
+    argz_add(&ctx->azGroups, &ctx->asGroups, group);
     res.statuscode = "250";
     res.dsncode    = "2.1.5";
     res.statusmsg  = "Recipient/ Group accepted";
@@ -652,7 +673,6 @@
     lmtp_res_t res;
     lmtp_rc_t rc = LMTP_OK;
     lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
-    char *buf;
     char errorstring[STDSTRLEN];
     char *rcpt;
 
@@ -668,32 +688,146 @@
     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);
 
-    rcpt = NULL;
-    while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL)
-    {
-        if(rc == LMTP_OK) {
-            res.statuscode = "250";
-            res.dsncode    = "2.0.0";
-            str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt);
-            res.statusmsg  = errorstring;
-        } else if (rc == LMTP_ERR_OVERFLOW) {
+    rc = lmtp_readmsg(lmtp, &ctx->message.cpMsg, MESSAGE_MAXLEN);
+
+    if (rc == LMTP_ERR_OVERFLOW) {
+        rcpt = NULL;
+        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
             res.statuscode = "500";
             res.dsncode    = "5.0.0";
-            res.statusmsg  = "FIXME overflow";
-        } else if (rc == LMTP_ERR_SYSTEM) {
+            res.statusmsg  = "Overflow reading message"; //FIXME temp or perm error?
+            lmtp_response(lmtp, &res);
+            return LMTP_OK;
+        }
+    }
+
+    if (rc == LMTP_ERR_SYSTEM) {
+        rcpt = NULL;
+        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
             res.statuscode = "500";
             res.dsncode    = "5.0.0";
-            str_format(errorstring, sizeof(errorstring), "Message accepted for delivery %s", strerror(errno));
+            str_format(errorstring, sizeof(errorstring), "System error reading message: %s", strerror(errno));
             res.statusmsg  = errorstring;
+            lmtp_response(lmtp, &res);
+            return LMTP_OK;
         }
+    }
+
+    if(rc != LMTP_OK) {
+        rcpt = NULL;
+        while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+            res.statuscode = "500";
+            res.dsncode    = "5.0.0";
+            res.statusmsg  = "Unknown error reading message"; //FIXME call lmtp_error()?
+            lmtp_response(lmtp, &res);
+            return LMTP_OK;
+        }
+    }
+
+    /* manipulate headers
+     * - remove To: and Cc: headers
+     * - (re)create Newsgroups: header
+     */
+    prepareheader(ctx);
+
+    rcpt = NULL;
+    while ((rcpt = argz_next(ctx->message.azRcpt, ctx->message.asRcpt, rcpt)) != NULL) {
+        res.statuscode = "250";
+        res.dsncode    = "2.0.0";
+        str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt);
+        res.statusmsg  = errorstring;
         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;
+
+                                /****************
+                                 * 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-]+?:)\\s*([\\S \\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
+                                 *********************/
+
+    cp = NULL;
+    while ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) != NULL) {
+        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 */
+        } //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 */
+        } //FIXME what bad things can happen here (odd number of argz, delete fails ...
+    }
+
+    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);
+
+    cp = NULL;
+    while ((cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp)) != NULL) {
+        cpName = cp;
+        cp = argz_next(ctx->message.azHeaders, ctx->message.asHeaders, cp);
+        cpValue = cp;
+        fprintf(stderr, "DEBUG: cooked Name(%s) = Value(%s)\n", cpName, cpValue);
+    }
+
+    return LMTP_OK;
+}
+
 static lmtp_rc_t lmtp_cb_noop(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
 {
     lmtp_res_t res;

CVSTrac 2.0.1