Index: ossp-pkg/l2/l2_ch_smtp.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_smtp.c,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_smtp.c,v' 2>/dev/null --- l2_ch_smtp.c 2001/09/12 09:42:34 1.2 +++ l2_ch_smtp.c 2001/09/14 12:55:20 1.3 @@ -34,6 +34,7 @@ #include #include #include +#include /* declare private channel configuration */ typedef struct { @@ -129,7 +130,7 @@ /* configure socket parameters */ sa_timeout(cfg->saServer, cfg->nTimeout, 0); - sa_buffers(cfg->saServer, 1024, 1024); + sa_buffers(cfg->saServer, 4096, 4096); return L2_OK; } @@ -140,18 +141,18 @@ { l2_ch_smtp_t *cfg = (l2_ch_smtp_t *)ctx->vp; char caLine[1024]; - int bSent; sa_t *sa; sa_addr_t *saa; - sa_rc_t rc; + l2_result_t rv = L2_OK; + sa_rc_t sa_rv; size_t n; + const char *cpB; + const char *cpE; + const char *cpL; + struct tm *tm; + time_t t; + char caDate[80]; - /* establish connection to server */ - saa = cfg->saaServer; - sa = cfg->saServer; - if ((rc = sa_connect(sa, saa)) != SA_OK) - return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); - /* * Sample SMTP transaction for reference: * @@ -164,70 +165,118 @@ * | 250 2.1.5 ... Recipient ok * | DATA * | 354 Enter mail, end with "." on a line by itself - * | From: l2@localhost + * | Date: Fri, 14 Sep 2001 14:50:51 CEST + * | From: rse@en1.engelschall.com * | To: rse@engelschall.com - * | Subject: [L2] SMTP channel output + * | Subject: [L2] log channel output on en1.engelschall.com + * | User-Agent: L2/0.1.0 * | - * | test log entry + * | A program of user rse on host en1.engelschall.com logged: + * | [2001-09-10/01:02:03] sample logging message * | . * | 250 2.0.0 f88Aev847031 Message accepted for delivery * | QUIT * | 221 2.0.0 en1.engelschall.com closing connection * - * For more details about SMTP, see RFC 2821: - * Simple Mail Transfer Protocol; J. Klensin; April 2001. + * For more details read: + * RFC 2821: Simple Mail Transfer Protocol; J. Klensin; April 2001. + * RFC 2822: Internet Message Format; P. Resnick; April 2001. */ - bSent = FALSE; - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 220) { - sa_printf(sa, "HELO %s\r\n", cfg->cpLocalHost); - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 250) { - sa_printf(sa, "MAIL FROM:<%s>\r\n", cfg->cpFrom); - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 250) { - sa_printf(sa, "RCPT TO:<%s>\r\n", cfg->cpRcpt); - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 250) { - sa_printf(sa, "DATA\r\n"); - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 354) { - sa_printf(sa, "From: %s\r\n", cfg->cpFrom); - sa_printf(sa, "To: %s\r\n", cfg->cpRcpt); - sa_printf(sa, "Subject: %s\r\n", cfg->cpSubject); - if (cfg->cpLocalProg != NULL) - sa_printf(sa, "User-Agent: %s, %s\r\n", - cfg->cpLocalProg, l2_version.v_gnu); - else - sa_printf(sa, "User-Agent: %s\r\n", l2_version.v_gnu); - sa_printf(sa, "\r\n"); - if (cfg->cpLocalProg != NULL) - sa_printf(sa, "Program %s of user %s on host %s logged:\r\n", - cfg->cpLocalProg, cfg->cpLocalUser, cfg->cpLocalHost); - else - sa_printf(sa, "A program of user %s on host %s logged:\r\n", - cfg->cpLocalUser, cfg->cpLocalHost); - /* FIXME: dot-escaping and remove doubled newline */ - sa_write(sa, buf, buf_size, &n); - sa_printf(sa, "\r\n"); - sa_printf(sa, ".\r\n"); - if (sa_readline(sa, caLine, sizeof(caLine), &n) == SA_OK - && n > 3 && atoi(caLine) == 250) { - sa_printf(sa, "QUIT\r\n"); - sa_readline(sa, caLine, sizeof(caLine), &n); - bSent = TRUE; - } - } - } - } - } + /* establish connection to server */ + saa = cfg->saaServer; + sa = cfg->saServer; + if ((sa_rv = sa_connect(sa, saa)) != SA_OK) + cu(sa_rv == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); + + /* | 220 en1.engelschall.com ESMTP SMTP Sendmail 8.11.0+ ready */ + sa_rv = sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 220), L2_ERR_IO); + + /* | HELO l2 + * | 250 en1.engelschall.com Hello en1.engelschall.com [141.1.129.1], pleased to meet you */ + sa_printf(sa, "HELO %s\r\n", cfg->cpLocalHost); + sa_rv = sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 250), L2_ERR_IO); + + /* | MAIL From: + * | 250 2.1.0 ... Sender ok */ + sa_printf(sa, "MAIL FROM:<%s>\r\n", cfg->cpFrom); + sa_rv = sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 250), L2_ERR_IO); + + /* | RCPT To: + * | 250 2.1.5 ... Recipient ok */ + sa_printf(sa, "RCPT TO:<%s>\r\n", cfg->cpRcpt); + sa_rv = sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 250), L2_ERR_IO); + + /* | DATA + * | 354 Enter mail, end with "." on a line by itself */ + sa_printf(sa, "DATA\r\n"); + sa_rv = sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 354), L2_ERR_IO); + + /* | Date: Fri, 14 Sep 2001 14:50:51 CEST + * | From: rse@en1.engelschall.com + * | To: rse@engelschall.com + * | Subject: [L2] log channel output on en1.engelschall.com + * | User-Agent: L2/0.1.0 + * | */ + t = time(NULL); + tm = localtime(&t); + strftime(caDate, sizeof(caDate), "%a, %d %b %Y %H:%M:%S %Z", tm); + sa_printf(sa, "Date: %s\r\n", caDate); + sa_printf(sa, "From: %s\r\n", cfg->cpFrom); + sa_printf(sa, "To: %s\r\n", cfg->cpRcpt); + sa_printf(sa, "Subject: %s\r\n", cfg->cpSubject); + if (cfg->cpLocalProg != NULL) + sa_printf(sa, "User-Agent: %s (%s)\r\n", + l2_version.v_web, cfg->cpLocalProg); + else + sa_printf(sa, "User-Agent: %s\r\n", l2_version.v_web); + sa_write(sa, "\r\n", 2, NULL); + + /* | A program of user rse on host en1.engelschall.com logged: + * | [2001-09-10/01:02:03] sample logging message */ + if (cfg->cpLocalProg != NULL) + sa_printf(sa, "Program %s of user %s on host %s logged:\r\n", + cfg->cpLocalProg, cfg->cpLocalUser, cfg->cpLocalHost); + else + sa_printf(sa, "A program of user %s on host %s logged:\r\n", + cfg->cpLocalUser, cfg->cpLocalHost); + cpB = buf; + cpE = buf; + cpL = buf+buf_size; + while (cpB < cpL) { + for (cpE = cpB; cpE < cpL && (*cpE != '\r' && *cpE != '\n'); cpE++) + ; + if (*cpB == '.') + sa_write(sa, ".", 1, NULL); + sa_write(sa, cpB, cpE-cpB, NULL); + sa_write(sa, "\r\n", 2, NULL); + for (; cpE < cpL && (*cpE == '\r' || *cpE == '\n'); cpE++) + ; + cpB = cpE; } + /* | . + * | 250 2.0.0 f88Aev847031 Message accepted for delivery */ + sa_write(sa, ".\r\n", 3, NULL); + sa_readline(sa, caLine, sizeof(caLine), &n); + cu_on(!(sa_rv == SA_OK && n > 3 && atoi(caLine) == 250), L2_ERR_IO); + + /* | QUIT + * | 221 2.0.0 en1.engelschall.com closing connection */ + sa_printf(sa, "QUIT\r\n"); + sa_readline(sa, caLine, sizeof(caLine), &n); + + cus: + /* shutdown connection to server */ sa_shutdown(sa, "rw"); - return (bSent ? L2_OK : L2_ERR_IO); + return rv; } /* close channel */