long SYM_SMTP;
long SYM_SMTP_RECP;
+
+
+/*****************************************************************************/
+/* SMTP SERVER (INBOUND) STUFF */
+/*****************************************************************************/
+
+
/*
* Here's where our SMTP session begins its happy day.
*/
lprintf(9, "Trying <%s>\n", password);
if (CtdlTryPassword(password) == pass_ok) {
cprintf("235 Authentication successful.\r\n");
- lprintf(9, "SMTP auth login successful\n");
+ lprintf(9, "SMTP authenticated login successful\n");
CC->internal_pgm = 0;
CC->cs_flags &= ~CS_STEALTH;
}
strlen(SMTP_RECP) + 1024 );
strcat(SMTP_RECP, "room|");
strcat(SMTP_RECP, user);
- strcat(SMTP_RECP, "|0\n");
+ strcat(SMTP_RECP, "|0|\n");
return;
case rfc822_no_such_user:
strlen(SMTP_RECP) + 1024 );
strcat(SMTP_RECP, "remote|");
strcat(SMTP_RECP, recp);
- strcat(SMTP_RECP, "|0\n");
+ strcat(SMTP_RECP, "|0|\n");
return;
}
return;
++successful_saves;
instr = mallok(1024);
- sprintf(instr, "Content-type: %s\n\nmsgid|%ld\n",
- SPOOLMIME, msgid);
+ sprintf(instr, "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n",
+ SPOOLMIME, msgid, time(NULL) );
for (i=0; i<SMTP->number_of_recipients; ++i) {
extract_token(buf, SMTP_RECP, i, '\n');
}
+
+
+/*****************************************************************************/
+/* SMTP CLIENT (OUTBOUND PROCESSING) STUFF */
+/*****************************************************************************/
+
+
+
+/*
+ * smtp_try()
+ *
+ * Called by smtp_do_procmsg() to attempt delivery to one SMTP host
+ *
+ */
+void smtp_try(char *key, char *addr, int *status, char *dsn) {
+
+ *status = 3;
+ strcpy(dsn, "smtp_try() is not finished yet");
+}
+
+
+
+/*
+ * smtp_do_procmsg()
+ *
+ * Called by smtp_do_queue() to handle an individual message.
+ */
+void smtp_do_procmsg(long msgnum) {
+ struct CtdlMessage *msg;
+ char *instr = NULL;
+ char *results = NULL;
+ int i;
+ int lines;
+ int status;
+ char buf[1024];
+ char key[1024];
+ char addr[1024];
+ char dsn[1024];
+ long text_msgid = (-1);
+
+ msg = CtdlFetchMessage(msgnum);
+ if (msg == NULL) {
+ lprintf(3, "SMTP: tried %ld but no such message!\n", msgnum);
+ return;
+ }
+
+ instr = strdoop(msg->cm_fields['M']);
+ CtdlFreeMessage(msg);
+
+ /* Strip out the headers amd any other non-instruction line */
+ lines = num_tokens(instr, '\n');
+ for (i=0; i<lines; ++i) {
+ extract_token(buf, instr, i, '\n');
+ if (num_tokens(buf, '|') < 2) {
+ lprintf(9, "removing <%s>\n", buf);
+ remove_token(instr, i, '|');
+ --lines;
+ --i;
+ }
+ }
+
+ /* Learn the message ID */
+ lines = num_tokens(instr, '\n');
+ for (i=0; i<lines; ++i) {
+ extract_token(buf, instr, i, '\n');
+ extract(key, buf, 0);
+ if (!strcasecmp(key, "msgid")) {
+ text_msgid = extract_long(buf, 1);
+ }
+ }
+
+ if (text_msgid < 0L) {
+ lprintf(3, "SMTP: no 'msgid' directive found!\n", msgnum);
+ phree(instr);
+ return;
+ }
+
+ /* Plow through the instructions looking for 'remote' directives and
+ * a status of 0 (no delivery yet attempted) or 3 (transient errors
+ * were experienced and it's time to try again)
+ */
+ lines = num_tokens(instr, '\n');
+ for (i=0; i<lines; ++i) {
+ extract_token(buf, instr, i, '\n');
+ extract(key, buf, 0);
+ extract(addr, buf, 1);
+ status = extract_int(buf, 2);
+ extract(dsn, buf, 3);
+ if ( (!strcasecmp(key, "remote"))
+ && ((status==0)||(status==3)) ) {
+ remove_token(instr, i, '\n');
+ --i;
+ --lines;
+ lprintf(9, "SMTP: Trying <%s>\n", addr);
+ smtp_try(key, addr, &status, dsn);
+ if (status != 2) {
+ if (results == NULL) {
+ results = mallok(1024);
+ memset(results, 0, 1024);
+ }
+ else {
+ results = reallok(results,
+ strlen(results) + 1024);
+ }
+ sprintf(&results[strlen(results)],
+ "%s|%s|%d|%s\n",
+ key, addr, status, dsn);
+ }
+ }
+ }
+
+ if (results != NULL) {
+ instr = reallok(instr, strlen(instr) + strlen(results) + 2);
+ strcat(instr, results);
+ phree(results);
+ }
+
+ /* Delete the instructions and replace with the updated ones */
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, NULL);
+ msg = mallok(sizeof(struct CtdlMessage));
+ memset(msg, 0, sizeof(struct CtdlMessage));
+ msg->cm_magic = CTDLMESSAGE_MAGIC;
+ msg->cm_anon_type = MES_NORMAL;
+ msg->cm_format_type = FMT_RFC822;
+ msg->cm_fields['M'] = instr;
+ CtdlSaveMsg(msg, "", SMTP_SPOOLOUT_ROOM, MES_LOCAL, 1);
+ CtdlFreeMessage(msg);
+}
+
+
+
+/*
+ * smtp_do_queue()
+ *
+ * Run through the queue sending out messages.
+ */
+void smtp_do_queue(void) {
+ lprintf(5, "SMTP: processing outbound queue\n");
+
+ if (getroom(&CC->quickroom, SMTP_SPOOLOUT_ROOM) != 0) {
+ lprintf(3, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
+ return;
+ }
+ CtdlForEachMessage(MSGS_ALL, 0L, SPOOLMIME, NULL, smtp_do_procmsg);
+
+ lprintf(5, "SMTP: queue run completed\n");
+}
+
+
+
+
+
+/*****************************************************************************/
+/* MODULE INITIALIZATION STUFF */
+/*****************************************************************************/
+
+
char *Dynamic_Module_Init(void)
{
SYM_SMTP = CtdlGetDynamicSymbol();