cvt = convert_internet_address(user, node, recp);
sprintf(recp, "%s@%s", user, node);
-
+ lprintf(9, "cvt=%d, citaddr=<%s@%s>\n", cvt, user, node);
switch(cvt) {
case rfc822_address_locally_validated:
cprintf("550 %s: no such user\r\n", recp);
return;
- case rfc822_address_invalid:
+ case rfc822_address_on_citadel_network:
+ cprintf("250 %s is on the local network\r\n", recp);
+ ++SMTP->number_of_recipients;
+ CtdlReallocUserData(SYM_SMTP_RECP,
+ strlen(SMTP_RECP) + 1024 );
+ strcat(SMTP_RECP, "ignet|");
+ strcat(SMTP_RECP, user);
+ strcat(SMTP_RECP, "|");
+ strcat(SMTP_RECP, node);
+ strcat(SMTP_RECP, "|0|\n");
+ return;
+
+ case rfc822_address_nonlocal:
if (is_spam) {
cprintf("551 Away with thee, spammer!\r\n");
}
+/*
+ * Send a message out through the local network
+ * (This is kind of ugly. IGnet should be done using clean server-to-server
+ * code instead of the old style spool.)
+ */
+void smtp_deliver_ignet(struct CtdlMessage *msg, char *user, char *dest) {
+ struct ser_ret smr;
+ char *hold_R, *hold_D;
+ FILE *fp;
+ char filename[256];
+ static int seq = 0;
+
+ lprintf(9, "smtp_deliver_ignet(msg, %s, %s)\n", user, dest);
+
+ hold_R = msg->cm_fields['R'];
+ hold_D = msg->cm_fields['D'];
+ msg->cm_fields['R'] = user;
+ msg->cm_fields['D'] = dest;
+
+ serialize_message(&smr, msg);
+
+ msg->cm_fields['R'] = hold_R;
+ msg->cm_fields['D'] = hold_D;
+
+ if (smr.len != 0) {
+ sprintf(filename, "./network/spoolin/%s.%04x.%04x",
+ dest, getpid(), ++seq);
+ lprintf(9, "spool file name is <%s>\n", filename);
+ fp = fopen(filename, "wb");
+ if (fp != NULL) {
+ fwrite(smr.ser, smr.len, 1, fp);
+ fclose(fp);
+ }
+ phree(smr.ser);
+ }
+
+}
+
/*
++successful_saves;
}
+ /* Delivery over the local Citadel network (IGnet) */
+ if (!strcasecmp(dtype, "ignet")) {
+ extract(user, buf, 1);
+ extract(node, buf, 2);
+ smtp_deliver_ignet(msg, user, node);
+ }
+
/* Remote delivery */
if (!strcasecmp(dtype, "remote")) {
extract(user, buf, 1);
/* Parse out the host portion of the recipient address */
process_rfc822_addr(addr, user, node, name);
+
lprintf(9, "Attempting SMTP delivery to <%s> @ <%s> (%s)\n",
user, node, name);
if (buf[0] != '2') {
if (buf[0] == '4') {
*status = 4;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
if (buf[0] != '2') {
if (buf[0] == '4') {
*status = 4;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
if (buf[0] != '2') {
if (buf[0] == '4') {
*status = 4;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
if (buf[0] != '2') {
if (buf[0] == '4') {
*status = 4;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
if (buf[0] != '3') {
if (buf[0] == '4') {
*status = 3;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
if (buf[0] != '2') {
if (buf[0] == '4') {
*status = 4;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
else {
*status = 5;
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
goto bail;
}
}
/* We did it! */
- strcpy(dsn, &buf[4]);
+ safestrncpy(dsn, &buf[4], 1023);
*status = 2;
lprintf(9, ">QUIT\n");
* Run through the queue sending out messages.
*/
void smtp_do_queue(void) {
+ static int doing_queue = 0;
+
+ /*
+ * This is a simple concurrency check to make sure only one queue run
+ * is done at a time. We could do this with a mutex, but since we
+ * don't really require extremely fine granularity here, we'll do it
+ * with a static variable instead.
+ */
+ if (doing_queue) return;
+ doing_queue = 1;
+
+ /*
+ * Go ahead and run the queue
+ */
lprintf(5, "SMTP: processing outbound queue\n");
if (getroom(&CC->quickroom, SMTP_SPOOLOUT_ROOM) != 0) {
CtdlForEachMessage(MSGS_ALL, 0L, SPOOLMIME, NULL, smtp_do_procmsg);
lprintf(5, "SMTP: queue run completed\n");
+ doing_queue = 0;
}