Index: ossp-pkg/lmtp2nntp/lmtp.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.c,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp.c,v' 2>/dev/null --- lmtp.c 2001/07/25 19:51:12 1.6 +++ lmtp.c 2001/07/26 15:18:57 1.7 @@ -432,7 +432,7 @@ res.statuscode = "220"; res.dsncode = NULL; - res.statusmsg = "LMTP server ready (lmtp2nntp)"; + res.statusmsg = "LMTP Service ready."; if ((rc = lmtp_response(lmtp, &res)) != LMTP_OK) return rc; Index: ossp-pkg/lmtp2nntp/lmtp2nntp.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp.c,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp.c,v' 2>/dev/null --- lmtp2nntp.c 2001/07/25 15:02:57 1.5 +++ lmtp2nntp.c 2001/07/26 15:18:57 1.6 @@ -37,6 +37,7 @@ #define ERR_DELIVERY -2 #define MESSAGE_MAXLEN 8*1024*1024 +#define STDSTRLEN 128 extern void lmtp_debug_dumplmtp(lmtp_t *lmtp); @@ -52,15 +53,16 @@ static lmtp_rc_t lmtp_cb_quit (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx); 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; + int option_verbose; + int option_tracing; + int option_mode; + char *azNewsgroups; + size_t asNewsgroups; + char *rfc822message; + int lhlo_seen; + char *lhlo_domain; + char *azRcpt; + size_t asRcpt; } lmtp2nntp_t; enum { @@ -128,7 +130,8 @@ ctx->azNewsgroups = NULL; ctx->asNewsgroups = 0; ctx->rfc822message = NULL; - ctx->saw_lhlo = FALSE; + ctx->lhlo_seen = FALSE; + ctx->lhlo_domain = ""; ctx->azRcpt = NULL; ctx->asRcpt = 0; @@ -217,25 +220,109 @@ * 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. * + * The first command in a session must be the HELO command. The HELO + * command may be used later in a session as well. If the HELO command + * argument is not acceptable a 501 failure reply must be returned and + * the receiver-SMTP must stay in the same state. + * + * If the transaction beginning command argument is not acceptable a 501 + * failure reply must be returned and the receiver-SMTP must stay in the + * same state. If the commands in a transaction are out of order a 503 + * failure reply must be returned and the receiver-SMTP must stay in the + * same state. + * + * HELO */ + lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx; lmtp_rc_t rc = LMTP_OK; lmtp_res_t res; - lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx; + char errorstring[STDSTRLEN]; + char *cp; + int FIXME; + + cp = NULL; + if (ctx->lhlo_seen == TRUE) { + res.statuscode = "503"; + res.dsncode = "5.0.0"; + res.statusmsg = "Duplicate LHLO."; + } else { + if (!str_parse(req->msg, + "^.+ (" - //FIXME use rset() not lmtp_cb_rset() - ctx->saw_lhlo = TRUE; + /* + ## + ## The mega Perl regular expression below is generated + ## with the following Perl program. This is only possible + ## because the given grammar is Chomsky-3 (right or left + ## linear grammar, but noth both). + ## + + # BNF grammar for according to RFC 821: + # ::= one, two, or three digits representing a decimal integer value in the range 0 through 255 + # ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case + # ::= any one of the ten digits 0 through 9 + # ::= | | "-" + # ::= | + # ::= | + # ::= "." "." "." + # ::= | + # ::= + # ::= | "#" | "[" "]" + # ::= | "." + + # corresponding Perl regular expression ($domain) + $snum = "(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"; + $d = "[0-9]"; + $a = "[A-Za-z]"; + $let_dig_hyp = "(?:$a|$d|-)"; + $let_dig = "(?:$a|$d)"; + $ldh_str = "${let_dig_hyp}+"; + $dotnum = "$snum\\.$snum\\.$snum\\.$snum"; + $number = "$d+"; + $name = "$a$ldh_str$let_dig"; + $element = "(?:$name|#$number|\\[$dotnum\\])"; + $domain = "(?:$element\.)*$element"; + + # translate into C string block suitable for passing to the Perl + # Compatible Regular Expressions (PCRE) based string library Str. + my $cregex = $domain; + $cregex =~ s|\\|\\\\|sg; + $cregex =~ s|(.{70})|"$1"\n|sg; + $cregex =~ s|\n([^\n]+)$|\n"$1"|s; + print "$cregex\n"; + */ + + "(?:(?:[A-Za-z](?:[A-Za-z]|[0-9]|-)+(?:[A-Za-z]|[0-9])|#[0-9]+|\\[(?:[0" + "-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0" + "-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0" + "-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5" + "])\\]).)*(?:[A-Za-z](?:[A-Za-z]|[0-9]|-)+(?:[A-Za-z]|[0-9])|#[0-9]+|\\" + "[(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]" + "{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{" + "2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|" + "25[0-5])\\])" - 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 - * RFC1854 = PIPELINING - * RFC1652 = 8BITMIME - */ + ")$", &cp, &ctx->lhlo_domain)) { + res.statuscode = "501"; + res.dsncode = "5.0.0"; + res.statusmsg = "Please identify yourself. See BNF in RFC821."; + } else { + ctx->lhlo_seen = TRUE; + printf("DEBUG: cp=***%s***, v1=***%s***\n", cp, ctx->lhlo_domain); + str_format(errorstring, sizeof(errorstring), "Hello ***%s***", ctx->lhlo_domain); + res.statuscode = "250"; + res.dsncode = NULL; /* DSN not used for greeting */ + res.statusmsg = "ENHANCEDSTATUSCODES\nDSN\nPIPELINING\n8BITMIME"; + /* + * RFC2034 = EHANCEDSTATUSCODES + * RFC1894 = DSN + * RFC1854 = PIPELINING + * RFC1652 = 8BITMIME + */ + } + } lmtp_response(lmtp, &res); + if (cp) free(cp); return rc; } @@ -245,7 +332,7 @@ lmtp_rc_t rc = LMTP_OK; lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx; - if (ctx->saw_lhlo == TRUE) { + if (ctx->lhlo_seen == TRUE) { res.statuscode = "250"; res.dsncode = "2.1.0"; res.statusmsg = "Sender ok FIXME"; @@ -281,7 +368,7 @@ lmtp_rc_t rc = LMTP_OK; lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx; char *buf; - char errorstring[128]; + char errorstring[STDSTRLEN]; char *rcpt; res.statuscode = "354"; @@ -349,7 +436,7 @@ lmtp_rc_t rc = LMTP_EOF; res.statuscode = "221"; res.dsncode = "2.0.0"; - res.statusmsg = "Closing connection."; + res.statusmsg = "LMTP Service closing transmission channel."; lmtp_response(lmtp, &res); return rc; }