/*
* Figure out how big a buffer we need to allocate
*/
- for (nptr = sc->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) {
+ for (nptr = sc->RNCfg->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) {
recps_len = recps_len + StrLength(nptr->Value[0]) + 2;
}
}
/* Each recipient */
- for (nptr = sc->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) {
- if (nptr != sc->NetConfigs[digestrecp]) {
+ for (nptr = sc->RNCfg->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) {
+ if (nptr != sc->RNCfg->NetConfigs[digestrecp]) {
StrBufAppendBufPlain(recps, HKEY(","), 0);
}
StrBufAppendBuf(recps, nptr->Value[0], 0);
char bounce_to[256];
/* Don't do this if there were no recipients! */
- if (sc->NetConfigs[listrecp] == NULL) return;
+ if (sc->RNCfg->NetConfigs[listrecp] == NULL) return;
/* Now generate the delivery instructions */
/*
* Figure out how big a buffer we need to allocate
*/
- for (nptr = sc->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) {
+ for (nptr = sc->RNCfg->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) {
recps_len = recps_len + StrLength(nptr->Value[0]) + 2;
}
}
/* Each recipient */
- for (nptr = sc->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) {
- if (nptr != sc->NetConfigs[listrecp]) {
+ for (nptr = sc->RNCfg->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) {
+ if (nptr != sc->RNCfg->NetConfigs[listrecp]) {
StrBufAppendBufPlain(recps, HKEY(","), 0);
}
StrBufAppendBuf(recps, nptr->Value[0], 0);
/*
* Process mailing list recipients
*/
- if (sc->NetConfigs[listrecp] != NULL) {
+ if (sc->RNCfg->NetConfigs[listrecp] != NULL) {
/* Fetch the message. We're going to need to modify it
* in order to insert the [list name] in it, etc.
*/
/*
* Process digest recipients
*/
- if ((sc->NetConfigs[digestrecp] != NULL) && (sc->digestfp != NULL)) {
+ if ((sc->RNCfg->NetConfigs[digestrecp] != NULL) && (sc->digestfp != NULL)) {
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
fprintf(sc->digestfp,
/*
* Process client-side list participations for this room
*/
- if (sc->NetConfigs[participate] != NULL) {
+ if (sc->RNCfg->NetConfigs[participate] != NULL) {
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
/*
* Figure out how big a buffer we need to alloc
*/
- for (nptr = sc->NetConfigs[participate];
+ for (nptr = sc->RNCfg->NetConfigs[participate];
nptr != NULL;
nptr = nptr->next)
{
}
}
- /*
- * Process IGnet push shares
- */
- msg = CtdlFetchMessage(msgnum, 1);
- if (msg != NULL) {
- size_t newpath_len;
-
- /* Prepend our node name to the Path field whenever
- * sending a message to another IGnet node
- */
- if (msg->cm_fields['P'] == NULL) {
- msg->cm_fields['P'] = strdup("username");
- }
- newpath_len = strlen(msg->cm_fields['P']) +
- strlen(config.c_nodename) + 2;
- newpath = malloc(newpath_len);
- snprintf(newpath, newpath_len, "%s!%s",
- config.c_nodename, msg->cm_fields['P']);
- free(msg->cm_fields['P']);
- msg->cm_fields['P'] = newpath;
-
+ if (sc->RNCfg->NetConfigs[ignet_push_share] != NULL)
+ {
/*
- * Determine if this message is set to be deleted
- * after sending out on the network
+ * Process IGnet push shares
*/
- if (msg->cm_fields['S'] != NULL) {
- if (!strcasecmp(msg->cm_fields['S'], "CANCEL")) {
- delete_after_send = 1;
- }
- }
-
- /* Now send it to every node */
- if (sc->NetConfigs[ignet_push_share] != NULL)
- for (mptr = sc->NetConfigs[ignet_push_share]; mptr != NULL;
- mptr = mptr->next) {
-
- send = 1;
- NewStrBufDupAppendFlush(&Buf, mptr->Value[0], NULL, 1);
-
- /* Check for valid node name */
- if (CtdlIsValidNode(NULL,
- NULL,
- Buf,
- sc->working_ignetcfg,
- sc->the_netmap) != 0)
- {
- QN_syslog(LOG_ERR,
- "Invalid node <%s>\n",
- ChrPtr(mptr->Value[0]));
+ msg = CtdlFetchMessage(msgnum, 1);
+ if (msg != NULL) {
+ size_t newpath_len;
- send = 0;
+ /* Prepend our node name to the Path field whenever
+ * sending a message to another IGnet node
+ */
+ if (msg->cm_fields['P'] == NULL) {
+ msg->cm_fields['P'] = strdup("username");
}
-
- /* Check for split horizon */
- QN_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);
-
- QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n",
- buf, ChrPtr(mptr->Value[0])) ;
- if (!strcasecmp(buf, ChrPtr(mptr->Value[0]))) {
- send = 0;
- break;
- }
+ newpath_len = strlen(msg->cm_fields['P']) +
+ strlen(config.c_nodename) + 2;
+ newpath = malloc(newpath_len);
+ snprintf(newpath, newpath_len, "%s!%s",
+ config.c_nodename, msg->cm_fields['P']);
+ free(msg->cm_fields['P']);
+ msg->cm_fields['P'] = newpath;
+
+ /*
+ * Determine if this message is set to be deleted
+ * after sending out on the network
+ */
+ if (msg->cm_fields['S'] != NULL) {
+ if (!strcasecmp(msg->cm_fields['S'], "CANCEL")) {
+ delete_after_send = 1;
}
-
- QN_syslog(LOG_INFO,
- "%sSending to %s\n",
- (send)?"":"Not ",
- ChrPtr(mptr->Value[0]));
}
- /* Send the message */
- if (send == 1)
- {
- /*
- * 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 (StrLength(mptr->Value[0]) > 0) {
- msg->cm_fields['C'] =
- strdup(ChrPtr(mptr->Value[0]));
- }
- else {
- msg->cm_fields['C'] =
- strdup(CC->room.QRname);
- }
+ /* Now send it to every node */
+ if (sc->RNCfg->NetConfigs[ignet_push_share] != NULL)
+ for (mptr = sc->RNCfg->NetConfigs[ignet_push_share]; mptr != NULL;
+ mptr = mptr->next) {
+
+ send = 1;
+ NewStrBufDupAppendFlush(&Buf, mptr->Value[0], NULL, 1);
+
+ /* Check for valid node name */
+ if (CtdlIsValidNode(NULL,
+ NULL,
+ Buf,
+ sc->working_ignetcfg,
+ sc->the_netmap) != 0)
+ {
+ QN_syslog(LOG_ERR,
+ "Invalid node <%s>\n",
+ ChrPtr(mptr->Value[0]));
- /* serialize it for transmission */
- serialize_message(&sermsg, msg);
- if (sermsg.len > 0) {
-
- /* write it to a spool file */
- snprintf(filename,
- sizeof(filename),
- "%s/%s@%lx%x",
- ctdl_netout_dir,
- ChrPtr(mptr->Value[0]),
- time(NULL),
- rand()
- );
-
- QN_syslog(LOG_DEBUG,
- "Appending to %s\n",
- filename);
-
- fp = fopen(filename, "ab");
- if (fp != NULL) {
- fwrite(sermsg.ser,
- sermsg.len, 1, fp);
- fclose(fp);
+ send = 0;
}
- else {
- QN_syslog(LOG_ERR,
- "%s: %s\n",
- filename,
- strerror(errno));
+
+ /* Check for split horizon */
+ QN_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);
+
+ QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n",
+ buf, ChrPtr(mptr->Value[0])) ;
+ if (!strcasecmp(buf, ChrPtr(mptr->Value[0]))) {
+ send = 0;
+ break;
+ }
+ }
+
+ QN_syslog(LOG_INFO,
+ "%sSending to %s\n",
+ (send)?"":"Not ",
+ ChrPtr(mptr->Value[0]));
}
- /* free the serialized version */
- free(sermsg.ser);
- }
+ /* Send the message */
+ if (send == 1)
+ {
+ /*
+ * 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 (StrLength(mptr->Value[0]) > 0) {
+ msg->cm_fields['C'] =
+ strdup(ChrPtr(mptr->Value[0]));
+ }
+ else {
+ msg->cm_fields['C'] =
+ strdup(CC->room.QRname);
+ }
+
+ /* serialize it for transmission */
+ serialize_message(&sermsg, msg);
+ if (sermsg.len > 0) {
+
+ /* write it to a spool file */
+ snprintf(filename,
+ sizeof(filename),
+ "%s/%s@%lx%x",
+ ctdl_netout_dir,
+ ChrPtr(mptr->Value[0]),
+ time(NULL),
+ rand()
+ );
+
+ QN_syslog(LOG_DEBUG,
+ "Appending to %s\n",
+ filename);
+
+ fp = fopen(filename, "ab");
+ if (fp != NULL) {
+ fwrite(sermsg.ser,
+ sermsg.len, 1, fp);
+ fclose(fp);
+ }
+ else {
+ QN_syslog(LOG_ERR,
+ "%s: %s\n",
+ filename,
+ strerror(errno));
+ }
+
+ /* free the serialized version */
+ free(sermsg.ser);
+ }
- }
+ }
+ }
+ CtdlFreeMessage(msg);
}
- CtdlFreeMessage(msg);
}
-
/* update lastsent */
///sc->lastsent = msgnum; ////// TODO
HashList *working_ignetcfg,
HashList *the_netmap)
{
+ struct CitContext *CCC = CC;
char buf[SIZ];
- char filename[PATH_MAX];
- SpoolControl *sc;
+ SpoolControl sc;
int i;
+ if ((sc.RNCfg->NetConfigs[listrecp] == NULL) &&
+ (sc.RNCfg->NetConfigs[digestrecp] == NULL) &&
+ (sc.RNCfg->NetConfigs[participate] == NULL) &&
+ (sc.RNCfg->NetConfigs[ignet_push_share] == NULL))
+ {
+ /* nothing to do for this room... */
+ return;
+ }
+
/*
* If the room doesn't exist, don't try to perform its networking tasks.
* Normally this should never happen, but once in a while maybe a room gets
* queued for networking and then deleted before it can happen.
*/
- if (CtdlGetRoom(&CC->room, room_to_spool->name) != 0) {
+ if (CtdlGetRoom(&CCC->room, room_to_spool->name) != 0) {
syslog(LOG_CRIT, "ERROR: cannot load <%s>\n", room_to_spool->name);
return;
}
- assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
- begin_critical_section(S_NETCONFIGS);
-
- /* Only do net processing for rooms that have netconfigs */
- if (!ReadRoomNetConfigFile(&sc, filename))
- {
- end_critical_section(S_NETCONFIGS);
- return;
- }
- syslog(LOG_INFO, "Networking started for <%s>\n", CC->room.QRname);
-
- sc->working_ignetcfg = working_ignetcfg;
- sc->the_netmap = the_netmap;
+
+ syslog(LOG_INFO, "Networking started for <%s>\n", CCC->room.QRname);
+ sc.RNCfg = room_to_spool->OneRNCfg;
+ sc.lastsent = room_to_spool->OneRNCfg->lastsent;
+ sc.working_ignetcfg = working_ignetcfg;
+ sc.the_netmap = the_netmap;
/* If there are digest recipients, we have to build a digest */
- if (sc->NetConfigs[digestrecp] != NULL) {
- sc->digestfp = tmpfile();
- fprintf(sc->digestfp, "Content-type: text/plain\n\n");
+ if (sc.RNCfg->NetConfigs[digestrecp] != NULL) {
+ sc.digestfp = tmpfile();
+ fprintf(sc.digestfp, "Content-type: text/plain\n\n");
}
/* Do something useful */
- CtdlForEachMessage(MSGS_GT, sc->lastsent, NULL, NULL, NULL,
- network_spool_msg, sc);
+ CtdlForEachMessage(MSGS_GT, sc.lastsent, NULL, NULL, NULL,
+ network_spool_msg, &sc);
/* If we wrote a digest, deliver it and then close it */
- snprintf(buf, sizeof buf, "room_%s@%s",
- CC->room.QRname, config.c_fqdn);
+ if (StrLength(sc.RNCfg->Sender) > 0)
+ {
+ long len;
+ len = StrLength(sc.RNCfg->Sender);
+ if (len + 1 > sizeof(buf))
+ len = sizeof(buf) - 1;
+ memcpy(buf, ChrPtr(sc.RNCfg->Sender), len);
+ buf[len] = '\0';
+ }
+ else
+ {
+ snprintf(buf, sizeof buf, "room_%s@%s",
+ CCC->room.QRname, config.c_fqdn);
+ }
+
for (i=0; buf[i]; ++i) {
buf[i] = tolower(buf[i]);
if (isspace(buf[i])) buf[i] = '_';
}
- if (sc->digestfp != NULL) {
- fprintf(sc->digestfp, " -----------------------------------"
- "------------------------------------"
- "-------\n"
- "You are subscribed to the '%s' "
- "list.\n"
- "To post to the list: %s\n",
- CC->room.QRname, buf
+ if (sc.digestfp != NULL) {
+ fprintf(sc.digestfp,
+ " -----------------------------------"
+ "------------------------------------"
+ "-------\n"
+ "You are subscribed to the '%s' "
+ "list.\n"
+ "To post to the list: %s\n",
+ CCC->room.QRname, buf
);
- network_deliver_digest(sc); /* deliver and close */
+ network_deliver_digest(&sc); /* deliver and close */
}
/* Now rewrite the config file */
- //// todo writenfree_spoolcontrol_file(&sc, filename);
+ if (sc.lastsent != room_to_spool->OneRNCfg->lastsent)
+ {
+ room_to_spool->OneRNCfg->lastsent = sc.lastsent;
+ room_to_spool->OneRNCfg->changed = 1;
+ }
end_critical_section(S_NETCONFIGS);
}
typedef struct __roomlists {
RoomProcList *rplist;
- HashList *RoomsInterestedIn;
}roomlists;
/*
* When we do network processing, it's accomplished in two passes; one to
int network_sync_to(char *target_node, long len)
{
struct CitContext *CCC = CC;
- const OneRoomNetCfg *OneRNCFG;
+ OneRoomNetCfg OneRNCFG;
+ OneRoomNetCfg *pRNCFG;
const RoomNetCfgLine *pCfgLine;
SpoolControl sc;
int num_spooled = 0;
/* Grab the configuration line we're looking for */
begin_critical_section(S_NETCONFIGS);
- OneRNCFG = CtdlGetNetCfgForRoom(CCC->room.QRnumber);
- if ((OneRNCFG == NULL) ||
- (OneRNCFG->NetConfigs[ignet_push_share] == NULL))
+ pRNCFG = CtdlGetNetCfgForRoom(CCC->room.QRnumber);
+ if ((pRNCFG == NULL) ||
+ (pRNCFG->NetConfigs[ignet_push_share] == NULL))
{
return -1;
}
- pCfgLine = OneRNCFG->NetConfigs[ignet_push_share];
+ pCfgLine = pRNCFG->NetConfigs[ignet_push_share];
while (pCfgLine != NULL)
{
if (strcmp(ChrPtr(pCfgLine->Value[0]), target_node))
return -1;
}
memset(&sc, 0, sizeof(SpoolControl));
-
- sc.NetConfigs[ignet_push_share] = DuplicateOneGenericCfgLine(pCfgLine);
+ memset(&OneRNCFG, 0, sizeof(OneRoomNetCfg));
+ sc.RNCfg = &OneRNCFG;
+ sc.RNCfg->NetConfigs[ignet_push_share] = DuplicateOneGenericCfgLine(pCfgLine);
end_critical_section(S_NETCONFIGS);
network_spool_msg, &sc);
/* Concise cleanup because we know there's only one node in the sc */
- DeleteGenericCfgLine(NULL/*TODO*/, &sc.NetConfigs[ignet_push_share]);
+ DeleteGenericCfgLine(NULL/*TODO*/, &sc.RNCfg->NetConfigs[ignet_push_share]);
DeleteHash(&sc.working_ignetcfg);
DeleteHash(&sc.the_netmap);
ptr->lcname[ptr->namelen] = '\0';
ptr->key = hashlittle(ptr->lcname, ptr->namelen, 9872345);
- ptr->OneRNCFG = OneRNCFG;
+ ptr->OneRNCfg = OneRNCFG;
return ptr;
}
void network_do_queue(void)
{
struct CitContext *CCC = CC;
- static int doing_queue = 0;
static time_t last_run = 0L;
int full_processing = 1;
HashList *working_ignetcfg;
);
}
- /*
- * 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;
-
become_session(&networker_spool_CC);
begin_critical_section(S_RPLIST);
RL.rplist = rplist;
while (ptr != NULL && !server_shutting_down) {
cmp = ptr->next;
-
+ /* filter duplicates from the list... */
while (cmp != NULL) {
if ((cmp->namelen > 0) &&
(cmp->key == ptr->key) &&
if (full_processing) {
last_run = time(NULL);
}
- DeleteHash(&RL.RoomsInterestedIn);
destroy_network_queue_room(RL.rplist);
- doing_queue = 0;
}