CtdlAllocUserData(SYM_SMTP, sizeof(struct citsmtp));
CtdlAllocUserData(SYM_SMTP_RECPS, SIZ);
CtdlAllocUserData(SYM_SMTP_ROOMS, SIZ);
- sprintf(SMTP_RECPS, "%s", "");
- sprintf(SMTP_ROOMS, "%s", "");
+ snprintf(SMTP_RECPS, SIZ, "%s", "");
+ snprintf(SMTP_ROOMS, SIZ, "%s", "");
cprintf("220 %s ESMTP Citadel/UX server ready.\r\n", config.c_fqdn);
}
long msgnum;
char nowstamp[SIZ];
struct recptypes *valid;
+ int scan_errors;
if (strlen(SMTP->from) == 0) {
cprintf("503 Need MAIL command first.\r\n");
/* Submit the message into the Citadel system. */
valid = validate_recipients(SMTP->recipients);
- msgnum = CtdlSubmitMsg(msg, valid, "");
- CtdlFreeMessage(msg);
- phree(valid);
- if (msgnum > 0L) {
- cprintf("250 Message accepted.\r\n");
+ /* If there are modules that want to scan this message before final
+ * submission (such as virus checkers or spam filters), call them now
+ * and give them an opportunity to reject the message.
+ */
+ scan_errors = PerformMessageHooks(msg, EVT_SMTPSCAN);
+
+ if (scan_errors > 0) { /* We don't want this message! */
+
+ if (msg->cm_fields['0'] == NULL) {
+ msg->cm_fields['0'] = strdoop(
+ "Message rejected by filter");
+ }
+
+ cprintf("552 %s\r\n", msg->cm_fields['0']);
}
- else {
- cprintf("550 Internal delivery error\r\n");
+
+ else { /* Ok, we'll accept this message. */
+ msgnum = CtdlSubmitMsg(msg, valid, "");
+ if (msgnum > 0L) {
+ cprintf("250 Message accepted.\r\n");
+ }
+ else {
+ cprintf("550 Internal delivery error\r\n");
+ }
}
+ CtdlFreeMessage(msg);
+ phree(valid);
smtp_data_clear(); /* clear out the buffers now */
}
* Called by smtp_do_procmsg() to attempt delivery to one SMTP host
*
*/
-void smtp_try(char *key, char *addr, int *status, char *dsn, long msgnum)
+void smtp_try(const char *key, const char *addr, int *status,
+ char *dsn, size_t n, long msgnum)
{
int sock = (-1);
char mxhosts[1024];
msg_fp = tmpfile();
if (msg_fp == NULL) {
*status = 4;
- sprintf(dsn, "Error creating temporary file");
+ snprintf(dsn, n, "Error creating temporary file");
return;
}
else {
--i;
--lines;
lprintf(9, "SMTP: Trying <%s>\n", addr);
- smtp_try(key, addr, &status, dsn, text_msgid);
+ smtp_try(key, addr, &status, dsn, sizeof dsn, text_msgid);
if (status != 2) {
if (results == NULL) {
results = mallok(1024);
results = reallok(results,
strlen(results) + 1024);
}
- sprintf(&results[strlen(results)],
+ snprintf(&results[strlen(results)], 1024,
"%s|%s|%d|%s\n",
key, addr, status, dsn);
}
lprintf(3, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
return;
}
- CtdlForEachMessage(MSGS_ALL, 0L, (-127),
+ CtdlForEachMessage(MSGS_ALL, 0L,
SPOOLMIME, NULL, smtp_do_procmsg, NULL);
lprintf(7, "SMTP: queue run completed\n");
else if (!strcasecmp(cmd, "runqueue")) {
run_queue_now = 1;
- cprintf("%d All outbound SMTP will be retried now.\n", OK);
+ cprintf("%d All outbound SMTP will be retried now.\n", CIT_OK);
return;
}
smtp_greeting,
smtp_command_loop);
- create_room(SMTP_SPOOLOUT_ROOM, 3, "", 0, 1);
+ create_room(SMTP_SPOOLOUT_ROOM, 3, "", 0, 1, 0);
CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER);
CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands");
return "$Id$";