* This module handles shared rooms, inter-Citadel mail, and outbound
* mailing list processing.
*
- * Copyright (C) 2000-2005 by Art Cancro and others.
- * This code is released under the terms of the GNU General Public License.
+ * Copyright (c) 2000-2009 by the citadel.org team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ** NOTE ** A word on the S_NETCONFIGS semaphore:
* This is a fairly high-level type of critical section. It ensures that no
void cmd_gnet(char *argbuf) {
- char filename[SIZ];
+ char filename[PATH_MAX];
char buf[SIZ];
FILE *fp;
void cmd_snet(char *argbuf) {
- char tempfilename[SIZ];
- char filename[SIZ];
+ char tempfilename[PATH_MAX];
+ char filename[PATH_MAX];
char buf[SIZ];
FILE *fp, *newfp;
size_t recps_len = SIZ;
struct recptypes *valid;
namelist *nptr;
+ char bounce_to[256];
if (sc->num_msgs_spooled < 1) {
fclose(sc->digestfp);
msg->cm_fields['F'] = strdup(buf);
msg->cm_fields['R'] = strdup(buf);
+ /* Set the 'List-ID' header */
+ msg->cm_fields['L'] = malloc(1024);
+ snprintf(msg->cm_fields['L'], 1024,
+ "%s <%ld.list-id.%s>",
+ CC->room.QRname,
+ CC->room.QRnumber,
+ config.c_fqdn
+ );
+
/*
* Go fetch the contents of the digest
*/
strcat(recps, nptr->name);
}
+ /* 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 */
valid = validate_recipients(recps, NULL, 0);
free(recps);
- CtdlSubmitMsg(msg, valid, NULL, 0);
+ if (valid != NULL) {
+ valid->bounce_to = strdup(bounce_to);
+ valid->envelope_from = strdup(bounce_to);
+ CtdlSubmitMsg(msg, valid, NULL, 0);
+ }
CtdlFreeMessage(msg);
free_recipients(valid);
}
size_t recps_len = SIZ;
struct recptypes *valid;
namelist *nptr;
+ char bounce_to[256];
/* Don't do this if there were no recipients! */
if (sc->listrecps == NULL) return;
strcat(recps, nptr->name);
}
+ /* 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 */
valid = validate_recipients(recps, NULL, 0);
free(recps);
- CtdlSubmitMsg(msg, valid, NULL, 0);
- free_recipients(valid);
+ if (valid != NULL) {
+ valid->bounce_to = strdup(bounce_to);
+ valid->envelope_from = strdup(bounce_to);
+ CtdlSubmitMsg(msg, valid, NULL, 0);
+ free_recipients(valid);
+ }
/* Do not call CtdlFreeMessage(msg) here; the caller will free it. */
}
maplist *mptr;
struct ser_ret sermsg;
FILE *fp;
- char filename[SIZ];
+ char filename[PATH_MAX];
char buf[SIZ];
int bang = 0;
int send = 1;
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
+ /* Set the 'List-ID' header */
+ if (msg->cm_fields['L'] != NULL) {
+ free(msg->cm_fields['L']);
+ }
+ msg->cm_fields['L'] = malloc(1024);
+ snprintf(msg->cm_fields['L'], 1024,
+ "%s <%ld.list-id.%s>",
+ CC->room.QRname,
+ CC->room.QRnumber,
+ config.c_fqdn
+ );
+
/* Prepend "[List name]" to the subject */
if (msg->cm_fields['U'] == NULL) {
msg->cm_fields['U'] = strdup("(no subject)");
*/
void network_spoolout_room(char *room_to_spool) {
char buf[SIZ];
- char filename[SIZ];
+ char filename[PATH_MAX];
SpoolControl *sc;
int i;
}
assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
-
- CtdlLogPrintf(CTDL_INFO, "Networking started for <%s>\n", CC->room.QRname);
begin_critical_section(S_NETCONFIGS);
/* Only do net processing for rooms that have netconfigs */
-
if (!read_spoolcontrol_file(&sc, filename))
{
end_critical_section(S_NETCONFIGS);
return;
}
+ CtdlLogPrintf(CTDL_INFO, "Networking started for <%s>\n", CC->room.QRname);
/* If there are digest recipients, we have to build a digest */
if (sc->digestrecps != NULL) {
char sc_type[256];
char sc_node[256];
char sc_room[256];
- char filename[256];
+ char filename[PATH_MAX];
FILE *fp;
/* Grab the configuration line we're looking for */
char target_room[ROOMNAMELEN];
struct ser_ret sermsg;
char *oldpath = NULL;
- char filename[SIZ];
+ char filename[PATH_MAX];
FILE *fp;
char nexthop[SIZ];
unsigned char firstbyte;
DIR *dp;
struct dirent *d;
struct stat statbuf;
- char filename[256];
+ char filename[PATH_MAX];
static time_t last_spoolin_mtime = 0L;
/*
void network_purge_spoolout(void) {
DIR *dp;
struct dirent *d;
- char filename[256];
+ char filename[PATH_MAX];
char nexthop[256];
int i;
struct CitContext networkerCC;
/* Give the networker its own private CitContext */
- memset(&networkerCC, 0, sizeof(struct CitContext));
- networkerCC.internal_pgm = 1;
- networkerCC.cs_pid = 0;
- pthread_setspecific(MyConKey, (void *)&networkerCC );
+ CtdlFillSystemContext(&networkerCC, "network");
+ citthread_setspecific(MyConKey, (void *)&networkerCC );
/*
* Run the full set of processing tasks no more frequently
extract_token(pass, cmdbuf, 1, '|', sizeof pass);
if (doing_queue) {
- CtdlLogPrintf(CTDL_WARNING, "Network node <%s> refused - spooling", node);
- cprintf("%d spooling - try again in a few minutes\n",
- ERROR + RESOURCE_BUSY);
+ CtdlLogPrintf(CTDL_WARNING, "Network node <%s> refused - spooling\n", node);
+ cprintf("%d spooling - try again in a few minutes\n", ERROR + RESOURCE_BUSY);
return;
}
v = is_valid_node(nexthop, secret, node);
if (v != 0) {
- snprintf (err_buf, sizeof(err_buf), "Unknown node <%s>\n", node);
+ snprintf(err_buf, sizeof err_buf,
+ "An unknown Citadel server called \"%s\" attempted to connect from %s [%s].\n",
+ node, CC->cs_host, CC->cs_addr
+ );
CtdlLogPrintf(CTDL_WARNING, err_buf);
- cprintf("%d authentication failed\n",
- ERROR + PASSWORD_REQUIRED);
+ cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED);
aide_message(err_buf, "IGNet Networking.");
return;
}
if (strcasecmp(pass, secret)) {
- snprintf (err_buf, sizeof(err_buf), "Bad password for network node <%s>", node);
+ snprintf(err_buf, sizeof err_buf,
+ "A Citadel server at %s [%s] failed to authenticate as network node \"%s\".\n",
+ CC->cs_host, CC->cs_addr, node
+ );
CtdlLogPrintf(CTDL_WARNING, err_buf);
cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED);
aide_message(err_buf, "IGNet Networking.");
safestrncpy(CC->net_node, node, sizeof CC->net_node);
network_talking_to(node, NTT_ADD);
- CtdlLogPrintf(CTDL_NOTICE, "Network node <%s> logged in\n", CC->net_node);
- cprintf("%d authenticated as network node '%s'\n", CIT_OK,
- CC->net_node);
+ CtdlLogPrintf(CTDL_NOTICE, "Network node <%s> logged in from %s [%s]\n",
+ CC->net_node, CC->cs_host, CC->cs_addr
+ );
+ cprintf("%d authenticated as network node '%s'\n", CIT_OK, CC->net_node);
}
+
int network_room_handler (struct ctdlroom *room)
{
network_queue_room(room, NULL);
return 0;
}
+
/*
* Module entry point
*/