$Log$
+Revision 1.436 2000/01/08 05:00:09 ajc
+* Reworked some of the data structures to handle multiple recipients
+* Began implementation of the delivery queue
+* Added CtdlReallocUserData()
+* CtdlSaveMsg() now returns the local message ID in the database
+
Revision 1.435 2000/01/06 03:50:34 ajc
* Replaced citmail.c with a new one that simply SMTP-forwards to Citadel
* Started outbound SMTP queue work
Fri Jul 10 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
* Initial CVS import
-
}
+/*
+ * Change the size of a buffer allocated with CtdlAllocUserData()
+ */
+void CtdlReallocUserData(unsigned long requested_sym, size_t num_bytes)
+{
+ struct CtdlSessData *ptr;
+
+ for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next) {
+ if (ptr->sym_id == requested_sym) {
+ ptr->sym_data = reallok(ptr->sym_data, num_bytes);
+ return;
+ }
+ }
+
+ lprintf(2, "CtdlReallocUserData() ERROR: symbol %ld not found!\n",
+ requested_sym);
+}
+
+
void deallocate_user_data(struct CitContext *con);
void *CtdlGetUserData(unsigned long requested_sym);
void CtdlAllocUserData(unsigned long requested_sym, size_t num_bytes);
+void CtdlReallocUserData(unsigned long requested_sym, size_t num_bytes);
int CtdlGetDynamicSymbol(void);
void enter_housekeeping_cmd(char *);
void do_command_loop(void);
strcpy(node, config.c_nodename);
}
- /* Return an error condition if the node is not known.
- * FIX ... make this work for non-local systems
- */
- if (strcasecmp(node, config.c_nodename)) {
- return(rfc822_address_invalid);
- }
-
/* Now try to resolve the name
* FIX ... do the multiple-addresses thing
*/
return(rfc822_address_locally_validated);
}
+ strcpy(destuser, user);
+ strcpy(desthost, node);
return(rfc822_address_invalid); /* unknown error */
}
/*
* Save a message to disk
*/
-void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
+long CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
char *rec, /* Recipient (mail) */
char *force, /* force a particular room? */
int mailtype, /* local or remote type */
static int seqnum = 1;
lprintf(9, "CtdlSaveMsg() called\n");
- if (is_valid_message(msg) == 0) return; /* self check */
+ if (is_valid_message(msg) == 0) return(-1); /* self check */
/* If this message has no timestamp, we take the liberty of
* giving it one, right now.
/* Perform "before save" hooks (aborting if any return nonzero) */
lprintf(9, "Performing before-save hooks\n");
- if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return;
+ if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return(-1);
/* If this message has an Extended ID, perform replication checks */
lprintf(9, "Performing replication checks\n");
- if (ReplicationChecks(msg) > 0) return;
+ if (ReplicationChecks(msg) > 0) return(-1);
/* Network mail - send a copy to the network program. */
if ((strlen(recipient) > 0) && (mailtype == MES_BINARY)) {
system("exec nohup ./netproc -i >/dev/null 2>&1 &");
}
- if (newmsgid <= 0L) return;
+ if (newmsgid <= 0L) return(-1);
/* Write a supplemental message info record. This doesn't have to
* be a critical section because nobody else knows about this message
lprintf(9, "Returning to original room\n");
if (strcasecmp(hold_rm, CC->quickroom.QRname))
getroom(&CC->quickroom, hold_rm);
+
+ return(newmsgid);
}
void cmd_opna (char *cmdbuf);
long send_message (struct CtdlMessage *, int, FILE *);
void loadtroom (void);
-void CtdlSaveMsg(struct CtdlMessage *, char *, char *, int, int);
+long CtdlSaveMsg(struct CtdlMessage *, char *, char *, int, int);
void quickie_message (char *, char *, char *, char *);
struct CtdlMessage *make_message (struct usersupp *, char *,
char *, int, int, int, char *);
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_deliver_remote
};
-#define SMTP ((struct citsmtp *)CtdlGetUserData(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.
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);
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);
- alias(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");
}
int successful_saves = 0;
int failed_saves = 0;
long msgid = (-1L);
- int cvt;
lprintf(9, "smtp_message_delivery() called\n");
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);
}
char *Dynamic_Module_Init(void)
{
SYM_SMTP = CtdlGetDynamicSymbol();
+ SYM_SMTP_RECP = CtdlGetDynamicSymbol();
CtdlRegisterServiceHook(SMTP_PORT,
smtp_greeting,
smtp_command_loop);