]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_smtp.c
* Reworked some of the data structures to handle multiple recipients
[citadel.git] / citadel / serv_smtp.c
index 5108ed2faded27bf609b9d40df59955e5522d07d..34a96804776b1b7ca620112d186ef62fc6d9f05b 100644 (file)
@@ -1,7 +1,5 @@
 /* $Id$ */
 
-#define SMTP_PORT      2525
-
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -30,6 +28,7 @@
 #include "msgbase.h"
 #include "tools.h"
 #include "internet_addressing.h"
+#include "genstamp.h"
 
 
 struct citsmtp {               /* Information about the current session */
@@ -38,20 +37,27 @@ struct citsmtp {            /* Information about the current session */
        int vrfy_count;
        char vrfy_match[256];
        char from[256];
-       char recipient[256];
        int number_of_recipients;
+       int delivery_mode;
 };
 
+
 enum {                         /* Command states for login authentication */
        smtp_command,
        smtp_user,
        smtp_password
 };
 
-#define SMTP ((struct citsmtp *)CtdlGetUserData(SYM_SMTP))
+enum {                         /* Delivery modes */
+       smtp_deliver_local,
+       smtp_deliver_remote
+};
 
-long SYM_SMTP;
+#define SMTP           ((struct citsmtp *)CtdlGetUserData(SYM_SMTP))
+#define SMTP_RECP      ((char *)CtdlGetUserData(SYM_SMTP_RECP))
 
+long SYM_SMTP;
+long SYM_SMTP_RECP;
 
 /*
  * Here's where our SMTP session begins its happy day.
@@ -62,6 +68,8 @@ void smtp_greeting(void) {
        CC->internal_pgm = 1;
        CC->cs_flags |= CS_STEALTH;
        CtdlAllocUserData(SYM_SMTP, sizeof(struct citsmtp));
+       CtdlAllocUserData(SYM_SMTP_RECP, 256);
+       sprintf(SMTP_RECP, "%s", "");
 
        cprintf("220 Welcome to the Citadel/UX ESMTP server at %s\n",
                config.c_fqdn);
@@ -330,39 +338,60 @@ void smtp_rcpt(char *argbuf) {
        int cvt;
        char user[256];
        char node[256];
+       char recp[256];
+       int is_spam = 0;        /* FIX implement anti-spamming */
 
        if (strlen(SMTP->from) == 0) {
                cprintf("503 MAIL first, then RCPT.  Duh.\n");
                return;
        }
 
-       if (SMTP->number_of_recipients > 0) {
-               cprintf("552 Only one recipient allowed (FIX)\n");
-               return;
-       }
-
        if (strncasecmp(argbuf, "To:", 3)) {
                cprintf("501 Syntax error\n");
                return;
        }
 
-       strcpy(SMTP->recipient, &argbuf[3]);
-       striplt(SMTP->recipient);
+       strcpy(recp, &argbuf[3]);
+       striplt(recp);
+       alias(recp);
+
+       cvt = convert_internet_address(user, node, recp);
+       sprintf(recp, "%s@%s", user, node);
+
 
-       cvt = convert_internet_address(user, node, SMTP->recipient);
        switch(cvt) {
                case rfc822_address_locally_validated:
                        cprintf("250 %s is a valid recipient.\n", user);
                        ++SMTP->number_of_recipients;
+                       CtdlReallocUserData(SYM_SMTP_RECP,
+                               strlen(SMTP_RECP) + 1024 );
+                       strcat(SMTP_RECP, "local|");
+                       strcat(SMTP_RECP, user);
+                       strcat(SMTP_RECP, "|0\n");
                        return;
+
                case rfc822_no_such_user:
-                       cprintf("550 %s: no such user\n", SMTP->recipient);
-                       strcpy(SMTP->recipient, "");
+                       cprintf("550 %s: no such user\n", recp);
+                       return;
+
+               case rfc822_address_invalid:
+                       if (is_spam) {
+                               cprintf("551 Away with thee, spammer!\n");
+                       }
+                       else {
+                               cprintf("250 Remote recipient %s ok\n", recp);
+                               ++SMTP->number_of_recipients;
+                               CtdlReallocUserData(SYM_SMTP_RECP,
+                                       strlen(SMTP_RECP) + 1024 );
+                               strcat(SMTP_RECP, "remote|");
+                               strcat(SMTP_RECP, recp);
+                               strcat(SMTP_RECP, "|0\n");
+                               return;
+                       }
                        return;
        }
 
-       strcpy(SMTP->recipient, "");
-       cprintf("599 Unknown error (FIX)\n");
+       cprintf("599 Unknown error\n");
 }
 
 
@@ -380,7 +409,6 @@ int smtp_message_delivery(struct CtdlMessage *msg) {
        int successful_saves = 0;
        int failed_saves = 0;
        long msgid = (-1L);
-       int cvt;
 
        lprintf(9, "smtp_message_delivery() called\n");
 
@@ -390,31 +418,18 @@ int smtp_message_delivery(struct CtdlMessage *msg) {
        if (msg->cm_fields['N']==NULL) msg->cm_fields['N'] = strdoop(node);
        if (msg->cm_fields['H']==NULL) msg->cm_fields['H'] = strdoop(name);
 
-       /* Stuff the boxes */
-       /* FIX modify to handle multiple recipients */
-       cvt = convert_internet_address(user, node, SMTP->recipient);
-       switch(cvt) {
-               case rfc822_address_locally_validated:
-                       lprintf(9, "Delivering to %s\n", user);
-
-                       if (msgid < 0L) {
-                               CtdlSaveMsg(msg,
-                                       user,
-                                       "",
-                                       MES_LOCAL,
-                                       1);
-                       }
-                       else {
-                               /* FIX copy the msgid to another room */
-                       }
-
-                       ++successful_saves;
-                       break;
+       /* Save the message in the queue */
+       msgid = CtdlSaveMsg(msg,
+               "",
+               SMTP_SPOOLOUT_ROOM,
+               MES_LOCAL,
+               1);
+       ++successful_saves;
 
-               case rfc822_no_such_user:
-                       ++failed_saves;
-                       break;
-       }
+               /* FIX go thru each local user and save to boxes
+                       then stuff remote users in queue list
+                       then delete from queue if num remote users is 0
+               */
 
        return(failed_saves);
 }
@@ -428,6 +443,7 @@ void smtp_data(void) {
        char *body;
        struct CtdlMessage *msg;
        int retval;
+       char nowstamp[256];
 
        if (strlen(SMTP->from) == 0) {
                cprintf("503 Need MAIL command first.\n");
@@ -440,7 +456,18 @@ void smtp_data(void) {
        }
 
        cprintf("354 Transmit message now; terminate with '.' by itself\n");
-       body = CtdlReadMessageBody(".", config.c_maxmsglen);
+       
+       generate_rfc822_datestamp(nowstamp, time(NULL));
+       body = mallok(4096);
+       if (body != NULL) sprintf(body,
+               "Received: from %s\n"
+               "       by %s;\n"
+               "       %s\n",
+                       "FIX.FIX.com",
+                       config.c_fqdn,
+                       nowstamp);
+       
+       body = CtdlReadMessageBody(".", config.c_maxmsglen, body);
        if (body == NULL) {
                cprintf("550 Unable to save message text: internal error.\n");
                return;
@@ -556,12 +583,14 @@ void smtp_command_loop(void) {
 }
 
 
-
 char *Dynamic_Module_Init(void)
 {
        SYM_SMTP = CtdlGetDynamicSymbol();
+       SYM_SMTP_RECP = CtdlGetDynamicSymbol();
        CtdlRegisterServiceHook(SMTP_PORT,
                                smtp_greeting,
                                smtp_command_loop);
+       create_room(SMTP_SPOOLOUT_ROOM, 3, "", 0);
        return "$Id$";
 }
+