* This module handles shared rooms, inter-Citadel mail, and outbound
* mailing list processing.
*
- * Copyright (c) 2000-2011 by the citadel.org team
+ * Copyright (c) 2000-2012 by the citadel.org team
*
* This program is open source software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#endif
#ifdef HAVE_SYSCALL_H
# include <syscall.h>
-#else
+#else
# if HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
# endif
#include "context.h"
#include "netconfig.h"
#include "netspool.h"
+#include "netmail.h"
#include "ctdl_module.h"
/* Now generate the delivery instructions */
- /*
+ /*
* Figure out how big a buffer we need to allocate
*/
for (nptr = sc->digestrecps; nptr != NULL; nptr = nptr->next) {
recps_len = recps_len + strlen(nptr->name) + 2;
}
-
+
recps = malloc(recps_len);
if (recps == NULL) {
- syslog(LOG_EMERG, "Cannot allocate %ld bytes for recps...\n", (long)recps_len);
+ syslog(LOG_EMERG,
+ "Cannot allocate %ld bytes for recps...\n",
+ (long)recps_len);
abort();
}
strcat(recps, nptr->name);
}
- /* Where do we want bounces and other noise to be heard? Surely not the list members! */
+ /* Where do we want bounces and other noise to be heard?
+ *Surely not the list members! */
snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
/* Now submit the message */
/*
* Deliver list messages to everyone on the list ... efficiently
*/
-void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc) {
+void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char *RoomName) {
char *recps = NULL;
size_t recps_len = SIZ;
struct recptypes *valid;
/* Now generate the delivery instructions */
- /*
+ /*
* Figure out how big a buffer we need to allocate
*/
for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
recps_len = recps_len + strlen(nptr->name) + 2;
}
-
+
recps = malloc(recps_len);
if (recps == NULL) {
- syslog(LOG_EMERG, "Cannot allocate %ld bytes for recps...\n", (long)recps_len);
+ syslog(LOG_EMERG,
+ "Cannot allocate %ld bytes for recps...\n",
+ (long)recps_len);
abort();
}
strcat(recps, nptr->name);
}
- /* Where do we want bounces and other noise to be heard? Surely not the list members! */
+ /* Where do we want bounces and other noise to be heard?
+ * Surely not the list members! */
snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
/* Now submit the message */
if (valid != NULL) {
valid->bounce_to = strdup(bounce_to);
valid->envelope_from = strdup(bounce_to);
+ valid->sending_room = strdup(RoomName);
CtdlSubmitMsg(msg, valid, NULL, 0);
free_recipients(valid);
}
}
-
-
/*
* Spools out one message from the list.
*/
-void network_spool_msg(long msgnum,
- void *userdata,
- char *working_ignetcfg,
- NetMap *the_netmap)
+void network_spool_msg(long msgnum,
+ void *userdata)
{
+ StrBuf *Buf = NULL;
SpoolControl *sc;
int i;
char *newpath = NULL;
char *pCh;
StrBuf *Subject, *FlatSubject;
+ if (msg->cm_fields['K'] != NULL)
+ free(msg->cm_fields['K']);
if (msg->cm_fields['V'] == NULL){
/* local message, no enVelope */
StrBuf *Buf;
Buf = NewStrBuf();
- StrBufAppendBufPlain(Buf, msg->cm_fields['O'], -1, 0);
+ StrBufAppendBufPlain(Buf,
+ msg->cm_fields['O']
+ , -1, 0);
StrBufAppendBufPlain(Buf, HKEY("@"), 0);
StrBufAppendBufPlain(Buf, config.c_fqdn, -1, 0);
-
+
msg->cm_fields['K'] = SmashStrBuf(&Buf);
}
else {
- msg->cm_fields['K'] = strdup (msg->cm_fields['V']);
+ msg->cm_fields['K'] =
+ strdup (msg->cm_fields['V']);
}
/* Set the 'List-ID' header */
if (msg->cm_fields['L'] != NULL) {
Subject = NewStrBufPlain(HKEY("(no subject)"));
}
else {
- Subject = NewStrBufPlain(msg->cm_fields['U'], -1);
+ Subject = NewStrBufPlain(
+ msg->cm_fields['U'], -1);
}
FlatSubject = NewStrBufPlain(NULL, StrLength(Subject));
StrBuf_RFC822_to_Utf8(FlatSubject, Subject, NULL, NULL);
{
StrBuf *tmp;
StrBufPlain(Subject, HKEY("["));
- StrBufAppendBufPlain(Subject, CC->room.QRname, rlen, 0);
+ StrBufAppendBufPlain(Subject,
+ CC->room.QRname,
+ rlen, 0);
StrBufAppendBufPlain(Subject, HKEY("] "), 0);
StrBufAppendBuf(Subject, FlatSubject, 0);
- tmp = Subject; Subject = FlatSubject; FlatSubject = tmp; /* so we can free the right one... */
+ /* so we can free the right one swap them */
+ tmp = Subject;
+ Subject = FlatSubject;
+ FlatSubject = tmp;
StrBufRFC2047encode(&Subject, FlatSubject);
}
-
+
if (msg->cm_fields['U'] != NULL)
free (msg->cm_fields['U']);
msg->cm_fields['U'] = SmashStrBuf(&Subject);
FreeStrBuf(&FlatSubject);
- /* else we won't modify the buffer, since the roomname is already here. */
+ /* else we won't modify the buffer, since the
+ * roomname is already here.
+ */
- /* Set the recipient of the list message to the
- * email address of the room itself.
- * FIXME ... I want to be able to pick any address
+ /* if there is no other recipient, Set the recipient
+ * of the list message to the email address of the
+ * room itself.
*/
- if (msg->cm_fields['R'] != NULL) {
- free(msg->cm_fields['R']);
- }
- msg->cm_fields['R'] = malloc(256);
- snprintf(msg->cm_fields['R'], 256,
- "room_%s@%s", CC->room.QRname,
- config.c_fqdn);
- for (i=0; msg->cm_fields['R'][i]; ++i) {
- if (isspace(msg->cm_fields['R'][i])) {
- msg->cm_fields['R'][i] = '_';
+ if ((msg->cm_fields['R'] == NULL) ||
+ IsEmptyStr(msg->cm_fields['R']))
+ {
+ if (msg->cm_fields['R'] != NULL)
+ free(msg->cm_fields['R']);
+
+ msg->cm_fields['R'] = malloc(256);
+ snprintf(msg->cm_fields['R'], 256,
+ "room_%s@%s", CC->room.QRname,
+ config.c_fqdn);
+ for (i=0; msg->cm_fields['R'][i]; ++i) {
+ if (isspace(msg->cm_fields['R'][i])) {
+ msg->cm_fields['R'][i] = '_';
+ }
}
}
/* Handle delivery */
- network_deliver_list(msg, sc);
+ network_deliver_list(msg, sc, CC->room.QRname);
CtdlFreeMessage(msg);
}
}
if ((sc->digestrecps != NULL) && (sc->digestfp != NULL)) {
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
- fprintf(sc->digestfp, " -----------------------------------"
- "------------------------------------"
- "-------\n");
+ fprintf(sc->digestfp,
+ " -----------------------------------"
+ "------------------------------------"
+ "-------\n");
fprintf(sc->digestfp, "From: ");
if (msg->cm_fields['A'] != NULL) {
- fprintf(sc->digestfp, "%s ", msg->cm_fields['A']);
+ fprintf(sc->digestfp,
+ "%s ",
+ msg->cm_fields['A']);
}
if (msg->cm_fields['F'] != NULL) {
- fprintf(sc->digestfp, "<%s> ", msg->cm_fields['F']);
+ fprintf(sc->digestfp,
+ "<%s> ",
+ msg->cm_fields['F']);
}
else if (msg->cm_fields['N'] != NULL) {
- fprintf(sc->digestfp, "@%s ", msg->cm_fields['N']);
+ fprintf(sc->digestfp,
+ "@%s ",
+ msg->cm_fields['N']);
}
fprintf(sc->digestfp, "\n");
if (msg->cm_fields['U'] != NULL) {
- fprintf(sc->digestfp, "Subject: %s\n", msg->cm_fields['U']);
+ fprintf(sc->digestfp,
+ "Subject: %s\n",
+ msg->cm_fields['U']);
}
CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
-
- safestrncpy(CC->preferred_formats, "text/plain", sizeof CC->preferred_formats);
- CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_NONE, 0, 0, 0);
+
+ safestrncpy(CC->preferred_formats,
+ "text/plain",
+ sizeof CC->preferred_formats);
+
+ CtdlOutputPreLoadedMsg(msg,
+ MT_CITADEL,
+ HEADERS_NONE,
+ 0, 0, 0);
StrBufTrim(CC->redirect_buffer);
fwrite(HKEY("\n"), 1, sc->digestfp);
FreeStrBuf(&CC->redirect_buffer);
sc->num_msgs_spooled += 1;
- free(msg);
+ CtdlFreeMessage(msg);
}
}
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
- /* Only send messages which originated on our own Citadel
- * network, otherwise we'll end up sending the remote
- * mailing list's messages back to it, which is rude...
+ /* Only send messages which originated on our own
+ * Citadel network, otherwise we'll end up sending the
+ * remote mailing list's messages back to it, which
+ * is rude...
*/
ok_to_participate = 0;
if (msg->cm_fields['N'] != NULL) {
- if (!strcasecmp(msg->cm_fields['N'], config.c_nodename)) {
+ if (!strcasecmp(msg->cm_fields['N'],
+ config.c_nodename)) {
ok_to_participate = 1;
}
- if (is_valid_node(NULL,
- NULL,
- msg->cm_fields['N'],
- working_ignetcfg,
- the_netmap) == 0)
+
+ Buf = NewStrBufPlain(msg->cm_fields['N'], -1);
+ if (is_valid_node(NULL,
+ NULL,
+ Buf,
+ sc->working_ignetcfg,
+ sc->the_netmap) == 0)
{
ok_to_participate = 1;
}
free(msg->cm_fields['F']);
}
msg->cm_fields['F'] = malloc(SIZ);
- /* Replace the Internet email address of the actual
- * author with the email address of the room itself,
- * so the remote listserv doesn't reject us.
- * FIXME ... I want to be able to pick any address
- */
+ /* Replace the Internet email address of the
+ * actual author with the email address of the
+ * room itself, so the remote listserv doesn't
+ * reject us.
+ * FIXME I want to be able to pick any address
+ */
snprintf(msg->cm_fields['F'], SIZ,
"room_%s@%s", CC->room.QRname,
config.c_fqdn);
}
}
- /*
- * Figure out how big a buffer we need to allocate
- */
- for (nptr = sc->participates; nptr != NULL; nptr = nptr->next) {
-
- if (msg->cm_fields['R'] == NULL) {
+ /*
+ * Figure out how big a buffer we need to alloc
+ */
+ for (nptr = sc->participates;
+ nptr != NULL;
+ nptr = nptr->next)
+ {
+ if (msg->cm_fields['R'] != NULL) {
free(msg->cm_fields['R']);
}
- msg->cm_fields['R'] = strdup(nptr->name);
-
- valid = validate_recipients(nptr->name, NULL, 0);
+ msg->cm_fields['R'] =
+ strdup(nptr->name);
+
+ valid = validate_recipients(nptr->name,
+ NULL, 0);
+
CtdlSubmitMsg(msg, valid, "", 0);
free_recipients(valid);
}
-
}
CtdlFreeMessage(msg);
}
}
-
+
/*
* Process IGnet push shares
*/
mptr = mptr->next) {
send = 1;
-
+ if (Buf == NULL)
+ Buf = NewStrBufPlain(mptr->remote_nodename, -1);
+ else
+ StrBufPlain(Buf, mptr->remote_nodename, -1);
/* Check for valid node name */
- if (is_valid_node(NULL,
- NULL,
- mptr->remote_nodename,
- working_ignetcfg,
- the_netmap) != 0)
+ if (is_valid_node(NULL,
+ NULL,
+ Buf,
+ sc->working_ignetcfg,
+ sc->the_netmap) != 0)
{
- syslog(LOG_ERR, "Invalid node <%s>\n", mptr->remote_nodename);
+ syslog(LOG_ERR,
+ "Invalid node <%s>\n",
+ mptr->remote_nodename);
+
send = 0;
}
syslog(LOG_DEBUG, "Path is %s\n", msg->cm_fields['P']);
bang = num_tokens(msg->cm_fields['P'], '!');
if (bang > 1) for (i=0; i<(bang-1); ++i) {
- extract_token(buf, msg->cm_fields['P'], i, '!', sizeof buf);
+ extract_token(buf,
+ msg->cm_fields['P'],
+ i, '!',
+ sizeof buf);
+
syslog(LOG_DEBUG, "Compare <%s> to <%s>\n",
buf, mptr->remote_nodename) ;
if (!strcasecmp(buf, mptr->remote_nodename)) {
mptr->remote_nodename);
}
else {
- syslog(LOG_DEBUG, "Sending to %s\n", mptr->remote_nodename);
+ syslog(LOG_DEBUG,
+ "Sending to %s\n",
+ mptr->remote_nodename);
}
}
/* Send the message */
- if (send == 1) {
-
+ if (send == 1)
+ {
/*
- * Force the message to appear in the correct room
- * on the far end by setting the C field correctly
+ * Force the message to appear in the correct
+ * room on the far end by setting the C field
+ * correctly
*/
if (msg->cm_fields['C'] != NULL) {
free(msg->cm_fields['C']);
}
if (!IsEmptyStr(mptr->remote_roomname)) {
- msg->cm_fields['C'] = strdup(mptr->remote_roomname);
+ msg->cm_fields['C'] =
+ strdup(mptr->remote_roomname);
}
else {
- msg->cm_fields['C'] = strdup(CC->room.QRname);
+ msg->cm_fields['C'] =
+ strdup(CC->room.QRname);
}
/* serialize it for transmission */
if (sermsg.len > 0) {
/* write it to a spool file */
- snprintf(filename, sizeof filename,"%s/%s@%lx%x",
- ctdl_netout_dir,
- mptr->remote_nodename,
- time(NULL),
- rand()
+ snprintf(filename,
+ sizeof(filename),
+ "%s/%s@%lx%x",
+ ctdl_netout_dir,
+ mptr->remote_nodename,
+ time(NULL),
+ rand()
);
- syslog(LOG_DEBUG, "Appending to %s\n", filename);
+
+ syslog(LOG_DEBUG,
+ "Appending to %s\n",
+ filename);
+
fp = fopen(filename, "ab");
if (fp != NULL) {
fwrite(sermsg.ser,
fclose(fp);
}
else {
- syslog(LOG_ERR, "%s: %s\n", filename, strerror(errno));
+ syslog(LOG_ERR,
+ "%s: %s\n",
+ filename,
+ strerror(errno));
}
-
+
/* free the serialized version */
free(sermsg.ser);
}
if (delete_after_send) {
CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, "");
}
-
+ FreeStrBuf(&Buf);
}