/*
* When we do network processing, it's accomplished in two passes; one to
* gather a list of rooms and one to actually do them. It's ok that rplist
- * is global; this process *only* runs as part of the housekeeping loop and
- * therefore only one will run at a time.
+ * is global; we have a mutex that keeps it safe.
*/
struct RoomProcList *rplist = NULL;
void network_deliver_digest(struct SpoolControl *sc) {
char buf[SIZ];
int i;
- struct CtdlMessage *msg;
+ struct CtdlMessage *msg = NULL;
long msglen;
long msgnum;
char *instr = NULL;
size_t instr_len = SIZ;
- struct CtdlMessage *imsg;
+ struct CtdlMessage *imsg = NULL;
struct namelist *nptr;
if (sc->num_msgs_spooled < 1) {
long msgnum;
char *instr = NULL;
size_t instr_len = SIZ;
- struct CtdlMessage *imsg;
+ struct CtdlMessage *imsg = NULL;
struct namelist *nptr;
/* Don't do this if there were no recipients! */
/* Delete this message if delete-after-send is set */
if (delete_after_send) {
- CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
+ CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, "");
}
}
int skipthisline = 0;
int i;
+ /*
+ * 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 (getroom(&CC->room, room_to_spool) != 0) {
lprintf(CTDL_CRIT, "ERROR: cannot load <%s>\n", room_to_spool);
return;
begin_critical_section(S_NETCONFIGS);
+ /* Only do net processing for rooms that have netconfigs */
fp = fopen(filename, "r");
if (fp == NULL) {
end_critical_section(S_NETCONFIGS);
}
/* Do something useful */
- CtdlForEachMessage(MSGS_GT, sc.lastsent, NULL, NULL,
+ CtdlForEachMessage(MSGS_GT, sc.lastsent, NULL, NULL, NULL,
network_spool_msg, &sc);
/* If we wrote a digest, deliver it and then close it */
if (!found_node) return(-1);
/* Send ALL messages */
- num_spooled = CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL,
+ num_spooled = CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL,
network_spool_msg, &sc);
/* Concise cleanup because we know there's only one node in the sc */
if (ptr == NULL) return;
safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
+ begin_critical_section(S_RPLIST);
ptr->next = rplist;
rplist = ptr;
+ end_critical_section(S_RPLIST);
}
* from the inbound queue
*/
void network_process_buffer(char *buffer, long size) {
- struct CtdlMessage *msg;
+ struct CtdlMessage *msg = NULL;
long pos;
int field;
struct recptypes *recp = NULL;
if (full_processing) {
lprintf(CTDL_DEBUG, "network: loading outbound queue\n");
ForEachRoom(network_queue_room, NULL);
+ }
+ if (rplist != NULL) {
lprintf(CTDL_DEBUG, "network: running outbound queue\n");
while (rplist != NULL) {
- network_spoolout_room(rplist->name);
+ char spoolroomname[ROOMNAMELEN];
+ safestrncpy(spoolroomname, rplist->name, sizeof spoolroomname);
+ begin_critical_section(S_RPLIST);
+
+ /* pop this record off the list */
ptr = rplist;
rplist = rplist->next;
free(ptr);
+
+ /* invalidate any duplicate entries to prevent double processing */
+ for (ptr=rplist; ptr!=NULL; ptr=ptr->next) {
+ if (!strcasecmp(ptr->name, spoolroomname)) {
+ ptr->name[0] = 0;
+ }
+ }
+
+ end_critical_section(S_RPLIST);
+ if (spoolroomname[0] != 0) {
+ network_spoolout_room(spoolroomname);
+ }
}
}