--- 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";
|