Index: ossp-pkg/lmtp2nntp/lmtp.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.c,v rcsdiff -q -kk '-r1.9' '-r1.10' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.c,v' 2>/dev/null --- lmtp.c 2001/08/14 08:15:25 1.9 +++ lmtp.c 2001/08/14 14:42:41 1.10 @@ -344,7 +344,7 @@ return rc; } -char *lmtp_error(lmtp_t *lmtp, lmtp_rc_t rc) +char *lmtp_error(lmtp_rc_t rc) { /* get an error message matching the given lmtp_rc_t code usually * returned by a previously called function Index: ossp-pkg/lmtp2nntp/lmtp.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.h,v rcsdiff -q -kk '-r1.7' '-r1.8' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.h,v' 2>/dev/null --- lmtp.h 2001/08/14 08:15:25 1.7 +++ lmtp.h 2001/08/14 14:42:41 1.8 @@ -73,7 +73,7 @@ lmtp_rc_t lmtp_readmsg (lmtp_t *, char **, size_t); lmtp_rc_t lmtp_request (lmtp_t *, lmtp_req_t *); lmtp_rc_t lmtp_response(lmtp_t *, lmtp_res_t *); -char *lmtp_error (lmtp_t *, lmtp_rc_t); +char *lmtp_error (lmtp_rc_t); lmtp_rc_t lmtp_register(lmtp_t *, char *, lmtp_cb_t, void *, lmtp_cb_t *, void **); lmtp_rc_t lmtp_loop (lmtp_t *); Index: ossp-pkg/lmtp2nntp/lmtp2nntp.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp.c,v rcsdiff -q -kk '-r1.16' '-r1.17' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp.c,v' 2>/dev/null --- lmtp2nntp.c 2001/08/14 08:15:25 1.16 +++ lmtp2nntp.c 2001/08/14 14:42:41 1.17 @@ -76,10 +76,8 @@ int option_groupmode; int nsc; struct ns ns[MAXNEWSSERVICES]; - char *azGroups; - size_t asGroups; - char *azGroupfilters; - size_t asGroupfilters; + char *azGroupargs; + size_t asGroupargs; struct session session; msg_t *msg; } lmtp2nntp_t; @@ -104,7 +102,7 @@ int main(int argc, char **argv) { - //FIXME int rc = 0; + int rc = 0; lmtp_t *lmtp; lmtp_io_t lmtp_io; lmtp2nntp_t *ctx; @@ -138,10 +136,8 @@ ctx->ns[i].s = -1; ctx->ns[i].nntp = NULL; } - ctx->azGroups = NULL; - ctx->asGroups = 0; - ctx->azGroupfilters = NULL; - ctx->asGroupfilters = 0; + ctx->azGroupargs = NULL; + ctx->asGroupargs = 0; initsession(&ctx->session); ctx->msg = NULL; @@ -230,12 +226,11 @@ exit(ERR_EXECUTION); } } - /* remaining arguments are groups or group filters */ - for (i = optind; i < argc; i++) - if (ctx->option_groupmode == GROUPMODE_ENVELOPE) - argz_add(&ctx->azGroupfilters, &ctx->asGroupfilters, argv[i]); - else - argz_add(&ctx->azGroups, &ctx->asGroups, argv[i]); + /* remaining arguments are Groupargs */ + for (i = optind; i < argc; i++) { + //fprintf(stderr, "DEBUG: argv[i] = ***%s***\n", argv[i]); + argz_add(&ctx->azGroupargs, &ctx->asGroupargs, argv[i]); + } /* initialize LMTP context */ lmtp_io.select = NULL; @@ -256,7 +251,7 @@ /* loop for LMTP protocol */ lmtp_loop(lmtp); - return 0; + return rc; } static void resetsession(struct session *session) @@ -348,7 +343,7 @@ bOk = FALSE; } if (bOk && ((rc = nntp_init(ctx->ns[i].nntp)) != NNTP_OK)) { - //fprintf(stderr, "DEBUG: nntp_init failed: %s\n", nntp_error(ctx->ns[i].nntp, rc)); + //fprintf(stderr, "DEBUG: nntp_init failed: %s\n", nntp_error(rc)); bOk = FALSE; } if (bOk) @@ -529,7 +524,8 @@ return LMTP_ERR_MEM; } - if (!str_parse(req->msg, "m/^MAIL From: <(.+@.+)>$/i", &ctx->msg->mail_from)) { + if (!str_parse(req->msg, "m/^MAIL From:\\s*<(.+@.+)>$/i", &ctx->msg->mail_from)) { + //FIXME ^^^^ is this space required/ valid? Sendmail skips them! res.statuscode = "553"; res.dsncode = "5.5.4"; res.statusmsg = "Domain name required for sender address."; @@ -559,7 +555,8 @@ return LMTP_OK; } - if (!str_parse(req->msg, "m/^RCPT To: (.+)$/i", &cp)) { + if (!str_parse(req->msg, "m/^RCPT To:\\s*(.+)$/i", &cp)) { + //FIXME ^^^^ is this space required/ valid? Sendmail skips them! res.statuscode = "501"; res.dsncode = "5.5.2"; res.statusmsg = "Syntax error in parameters."; @@ -567,6 +564,14 @@ return LMTP_OK; } + if ((cp == NULL) || (strlen(cp) == 0)) { + res.statuscode = "550"; + res.dsncode = "5.1.1"; + res.statusmsg = "nul Recipient/ Group."; + lmtp_response(lmtp, &res); + return LMTP_OK; + } + /* FIXME * in GROUPMODE = ARG|HEADER recipient must be acknowledged and stored to * give proper pipelining responses. in GROUPMODE = ENVELOPE recipient is @@ -592,19 +597,11 @@ lmtp_response(lmtp, &res); return LMTP_OK; } + argz_add(&ctx->msg->azEnvgroups, &ctx->msg->asEnvgroups, group); } - if ((cp == NULL) || (strlen(cp) == 0)) { - res.statuscode = "550"; - res.dsncode = "5.1.1"; - res.statusmsg = "nul Recipient/ Group."; - lmtp_response(lmtp, &res); - return LMTP_OK; - } - //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"; res.statusmsg = "Recipient/ Group accepted"; @@ -638,89 +635,114 @@ rc = lmtp_readmsg(lmtp, &ctx->msg->cpMsg, MESSAGE_MAXLEN); if (rc == LMTP_ERR_OVERFLOW) { + str_format(errorstring, sizeof(errorstring), "Overflow reading message: %s", lmtp_error(rc)); + res.statuscode = "500"; + res.dsncode = "5.0.0"; + res.statusmsg = errorstring; //FIXME temp or perm error? 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? lmtp_response(lmtp, &res); - return LMTP_OK; } + return LMTP_OK; } if (rc == LMTP_ERR_SYSTEM) { + str_format(errorstring, sizeof(errorstring), "System error reading message: %s", strerror(errno)); + res.statuscode = "500"; + res.dsncode = "5.0.0"; + res.statusmsg = errorstring; 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)); - res.statusmsg = errorstring; lmtp_response(lmtp, &res); - return LMTP_OK; } + return LMTP_OK; } if(rc != LMTP_OK) { + str_format(errorstring, sizeof(errorstring), "Unknown error reading message: %s", lmtp_error(rc)); + res.statuscode = "500"; + res.dsncode = "5.0.0"; + res.statusmsg = errorstring; 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()? lmtp_response(lmtp, &res); - return LMTP_OK; } + return LMTP_OK; } - if (msg_split(ctx->msg) != MSG_OK) { + //fprintf(stderr, "DEBUG: before msg_split\n"); + if ((rc = msg_split(ctx->msg)) != MSG_OK) { + str_format(errorstring, sizeof(errorstring), "Error splitting message: %s", msg_error(rc)); + res.statuscode = "500"; + res.dsncode = "5.0.0"; + res.statusmsg = errorstring; + rcpt = NULL; 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; } + return LMTP_OK; } + //fprintf(stderr, "DEBUG: after msg_split\n"); - ctx->msg->azNewsgroups = ctx->azGroups; - ctx->msg->asNewsgroups = ctx->asGroups; + if (ctx->option_groupmode == GROUPMODE_ENVELOPE) { + ctx->msg->azNewsgroups = memcpy(malloc(ctx->msg->asEnvgroups + 1), ctx->msg->azEnvgroups, ctx->msg->asEnvgroups); //FIXME strdup == NULL + ctx->msg->asNewsgroups = ctx->msg->asEnvgroups; + } + else if (ctx->option_groupmode == GROUPMODE_ARG) { + ctx->msg->azNewsgroups = memcpy(malloc(ctx->asGroupargs + 1), ctx->azGroupargs, ctx->asGroupargs); //FIXME strdup == NULL + ctx->msg->asNewsgroups = ctx->asGroupargs; + } + /* else keep == GROUPMODE_HEADERS */ + +#if 0 //FIXME debug paragraph + rcpt = NULL; + while ((rcpt = argz_next(ctx->msg->azNewsgroups, ctx->msg->asNewsgroups, rcpt)) != NULL) { + fprintf(stderr, "DEBUG: commited group ***%s***\n", rcpt); + } +#endif - if (msg_join(ctx->msg) != MSG_OK) { + //fprintf(stderr, "DEBUG: before msg_join\n"); + if ((rc = msg_join(ctx->msg)) != MSG_OK) { + str_format(errorstring, sizeof(errorstring), "Error joining message: %s", msg_error(rc)); + res.statuscode = "500"; + res.dsncode = "5.0.0"; + res.statusmsg = errorstring; + rcpt = NULL; 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; } + return LMTP_OK; } + //fprintf(stderr, "DEBUG: after msg_join\n"); bSuccess = FALSE; for (i = 0; i < ctx->nsc; i++) { //fprintf(stderr, "DEBUG: trying service %s\n", ctx->ns[i].h); - if (nntp_post(ctx->ns[i].nntp, ctx->msg) == NNTP_OK) + if ((rc = nntp_post(ctx->ns[i].nntp, ctx->msg)) == NNTP_OK) bSuccess = TRUE; } + //FIXME rc has only last error 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"; - str_format(errorstring, sizeof(errorstring), "Message accepted for delivery to %s", rcpt); res.statusmsg = errorstring; - lmtp_response(lmtp, &res); } else { + str_format(errorstring, sizeof(errorstring), "Last error posting message: %s", nntp_error(rc)); res.statuscode = "500"; res.dsncode = "5.0.0"; - res.statusmsg = "Error posting message."; //FIXME call nntp_error()? - lmtp_response(lmtp, &res); + res.statusmsg = errorstring; } + lmtp_response(lmtp, &res); } msg_destroy(ctx->msg); ctx->msg = NULL; - return rc; + return LMTP_OK; } static lmtp_rc_t lmtp_cb_noop(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx) Index: ossp-pkg/lmtp2nntp/msg.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/msg.c,v rcsdiff -q -kk '-r1.3' '-r1.4' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/msg.c,v' 2>/dev/null --- msg.c 2001/08/14 08:15:25 1.3 +++ msg.c 2001/08/14 14:42:41 1.4 @@ -12,6 +12,8 @@ if ((msg = (msg_t *)malloc(sizeof(msg_t))) == NULL) return NULL; + msg->azEnvgroups = NULL; + msg->asEnvgroups = 0; msg->cpMsg = NULL; msg->azHeaders = NULL; msg->asHeaders = 0; @@ -31,6 +33,8 @@ if (msg == NULL) return; //FIXME what about non-graceful aborts? + if (msg->azEnvgroups != NULL) + free(msg->azEnvgroups); if (msg->cpMsg != NULL) free(msg->cpMsg); if (msg->azHeaders != NULL) @@ -69,10 +73,10 @@ * * msg->azHeaders, msg->asHeaders contains the headers in argz format, one * logical '\0'-terminated line per header which might be wrapped into - * multiple '\n'-ended physical lines. The "From " envelope, "To:" and - * "Cc:" headers are removed silently. The "Newsgroups:" and "Message-ID" - * headers are removed and their values are stored in separate structures - * (see below). + * multiple '\n'-ended physical lines. The "From " envelope, "Received:", + * "To:" and "Cc:" headers are removed silently. The "Newsgroups:" and + * "Message-ID" headers are removed and their values are stored in + * separate structures (see below). * * msg->cpBody * contains the unmodified body of the message, '\0'-terminated, no @@ -93,13 +97,10 @@ /* replace envelope From w/o colon by X-F: pseudotag. This eliminates the * special case of having one header, which is really an embedded * envelope, not ending with a colon while all others do. After splitting - * headers into name and value pairs this action is reversed. + * headers into name and value pairs this envelope ist stripped off. */ - if (strlen(cpHeaders) < 4) - return MSG_ERR_SPLITLEN; - if (strncasecmp(cpHeaders, "From", 4) != 0) - return MSG_ERR_SPLITMISSINGFROM; - memcpy(cpHeaders, "X-F:", 4); + if (strncasecmp(cpHeaders, "From", 4) == 0) + memcpy(cpHeaders, "X-F:", 4); /* unwrap header lines */ //FIXME poor man's s///g simulator as current str library doesn't support //global substitution @@ -120,16 +121,18 @@ argz_add(&msg->azHeaders, &msg->asHeaders, cpValue); } - /* reverse the 'From ' to 'X-F: ' replacement */ - memcpy(msg->azHeaders, "From", 4); /* replace envelope X-F: pseudotag with From w/o colon */ - /* check for headers we care about and do whatever neccessary */ msg->cpMsgid = NULL; msg->azNewsgroups = NULL; msg->asNewsgroups = 0; cp = msg->azHeaders; while (cp != NULL) { - if (strcasecmp("From", cp) == 0) { + if (strcasecmp("X-F:", cp) == 0) { + argz_delete(&msg->azHeaders, &msg->asHeaders, cp); /* del name */ + argz_delete(&msg->azHeaders, &msg->asHeaders, cp); /* del value */ + continue; + } + if (strcasecmp("Received:", cp) == 0) { argz_delete(&msg->azHeaders, &msg->asHeaders, cp); /* del name */ argz_delete(&msg->azHeaders, &msg->asHeaders, cp); /* del value */ continue; @@ -350,7 +353,7 @@ return MSG_OK; } -char *msg_error(msg_t *msg, msg_rc_t rc) +char *msg_error(msg_rc_t rc) { char *str; str = "MSG: no description"; Index: ossp-pkg/lmtp2nntp/msg.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/msg.h,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/msg.h,v' 2>/dev/null --- msg.h 2001/08/14 08:15:25 1.2 +++ msg.h 2001/08/14 14:42:41 1.3 @@ -5,6 +5,8 @@ #include typedef struct { + char *azEnvgroups; /* Groups according to Envelope in GROUPMODE_ENVELOPE */ + size_t asEnvgroups; char *cpMsg; /* the wholly message to be received by DATA command */ char *azHeaders; /* header part of message above */ size_t asHeaders; @@ -40,7 +42,7 @@ msg_rc_t msg_split(msg_t *); msg_rc_t msg_join(msg_t *); void msg_destroy(msg_t *); -char *msg_error(msg_t *, msg_rc_t); +char *msg_error(msg_rc_t); #endif /* __MSG_H__ */ Index: ossp-pkg/lmtp2nntp/nntp.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/nntp.c,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/nntp.c,v' 2>/dev/null --- nntp.c 2001/08/14 08:15:25 1.6 +++ nntp.c 2001/08/14 14:42:41 1.7 @@ -231,12 +231,14 @@ * * In other words, INN *requires* the use of "MODE READER". */ + //fprintf(stderr, "DEBUG: before MODE READER\n"); *line = '\0'; strcat(line, "MODE READER"); if ((rc = nntp_writeline(nntp, line)) != NNTP_OK) return rc; if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK) return rc; + //fprintf(stderr, "DEBUG: after MODE READER\n"); /* A 200 response means posting ok, 201 means posting not allowed. We * don't care about 5xx errors, they simply mean the server doesn't know @@ -255,7 +257,6 @@ * < 223 yes, article already known * < 430 no, i don't know the article, yet */ -#if 0 *line = '\0'; strcat(line, "STAT "); strcat(line, msg->cpMsgid); @@ -267,7 +268,6 @@ return NNTP_OK; if (strncmp(line, "430", 3) != 0) return NNTP_ERR_POST; -#endif /* post the article * > POST @@ -293,6 +293,7 @@ * 441 437 Too old * 441 Duplicate "Newsgroups" header * 441 Required "Subject" header is missing + * 441 Obsolete "Received" header * * In other words, INN uses 441 for other status messages as well. */ @@ -312,7 +313,7 @@ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK) return rc; - //fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(nntp, rc)); + //fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc)); if ( (strncmp(line, "240", 3) == 0) || (strncmp(line, "441", 3) == 0) ) @@ -329,7 +330,7 @@ #endif } -char *nntp_error(nntp_t *nntp, nntp_rc_t rc) +char *nntp_error(nntp_rc_t rc) { char *str; str = "NNTP: errorcode has no description"; Index: ossp-pkg/lmtp2nntp/nntp.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/nntp.h,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/nntp.h,v' 2>/dev/null --- nntp.h 2001/08/13 15:16:32 1.4 +++ nntp.h 2001/08/14 14:42:41 1.5 @@ -64,7 +64,7 @@ nntp_rc_t nntp_readline (nntp_t *, char *, size_t); nntp_rc_t nntp_writeline(nntp_t *, char *); nntp_rc_t nntp_post (nntp_t *, msg_t *msg); -char *nntp_error (nntp_t *, nntp_rc_t); +char *nntp_error (nntp_rc_t); #endif /* __NNTP_H__ */ Index: ossp-pkg/lmtp2nntp/test/run.sh RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/test/Attic/run.sh,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/test/Attic/run.sh,v' 2>/dev/null --- run.sh 2001/08/14 11:26:43 1.4 +++ run.sh 2001/08/14 14:42:41 1.5 @@ -1,26 +1,65 @@ #/bin/sh -if [ -e /tmp/tracing ] -then - ssh -t -x root@localhost exec rm -f /tmp/t -fi +before () +{ + if [ -e /tmp/tracing ] + then + ssh -t -x root@localhost exec rm -f /tmp/tracing + fi + touch /tmp/tracing +} + +post1000 () +{ + for h in 0 1 2 3 4 5 6 7 8 9 + do + for z in 0 1 2 3 4 5 6 7 8 9 + do + for e in 0 1 2 3 4 5 6 7 8 9 + do + echo -n $h$z$e + awk \" } \ + !/Message-ID/ { print \$0 } \ + " \ + | sendmail -i posting+$h$z$e@dev12.dev.de.cw.net + done + done + done +} + +postdup () +{ + echo ----------------------------------------------------------- #./lmtp2nntp -h news-muc1.de.cw.net -h news-ffm2.de.cw.net -h news-dus2.de.cw.net -h news-ecrc.de #clear ; ./lmtp2nntp \" } \ - !/Message-ID/ { print \$0 } \ - " \ - | tee /tmp/reusetestmessage \ - | ./lmtp2nntp -g envelope -h dev16 -cat /tmp/reusetestmessage | ./lmtp2nntp -t /tmp/tracing -g envelope -h dev16 -echo ----------------------------------------------------------- -exit - -if [ -r /tmp/tracing ] -then - cat /tmp/tracing -fi + awk \" } \ + !/Message-ID/ { print \$0 } \ + " \ + >/tmp/testmessage + echo ----------------------------------------------------------- + cat /tmp/testmessage \ + | sendmail -i posting+x@dev12.dev.de.cw.net + echo ----------------------------------------------------------- + cat /tmp/testmessage \ + | sendmail -i posting+x@dev12.dev.de.cw.net + echo ----------------------------------------------------------- +} + +after () +{ + if [ -r /tmp/tracing ] + then + echo tail -f /tmp/tracing + tail -f /tmp/tracing + fi +} + +before +post1000 +after +exit 0