--- 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 <sys/utsname.h>
#include <sys/types.h>
#include <pwd.h>
+#include <time.h>
/* 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 <rse@engelschall.com>... 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] <notice> 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: <l2@localhost>
+ * | 250 2.1.0 <l2@localhost>... 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: <rse@engelschall.com>
+ * | 250 2.1.5 <rse@engelschall.com>... 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] <notice> 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 */
|