]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_network.c
* New UI for mailing list setup
[citadel.git] / citadel / serv_network.c
index aef3fdca829a7a3b10a2f9483bf46d4628e3f8e1..aedb73ecea3d8d979405f3edfb6677f20f8a78e2 100644 (file)
@@ -1,20 +1,14 @@
 /*
  * $Id$ 
  *
- * This module will eventually replace netproc and some of its utilities.
- * Copyright (C) 2000 by Art Cancro and others.
+ * This module will eventually replace netproc and some of its utilities.  In
+ * the meantime, it serves as a mailing list manager.
+ *
+ * Copyright (C) 2000-2001 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
  *
  */
 
-
-/* FIXME
-
-there's stuff in here that makes the assumption that /tmp is on the same
-filesystem as Citadel, and makes calls to link() on that basis.  fix this.
-
-*/
-
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -24,13 +18,23 @@ filesystem as Citadel, and makes calls to link() on that basis.  fix this.
 #include <pwd.h>
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
 #include <sys/wait.h>
 #include <string.h>
 #include <limits.h>
 #include "citadel.h"
 #include "server.h"
-#include <time.h>
 #include "sysdep_decls.h"
 #include "citserver.h"
 #include "support.h"
@@ -47,8 +51,8 @@ filesystem as Citadel, and makes calls to link() on that basis.  fix this.
 
 
 void cmd_gnet(char *argbuf) {
-       char filename[256];
-       char buf[256];
+       char filename[SIZ];
+       char buf[SIZ];
        FILE *fp;
 
        if (CtdlAccessCheck(ac_room_aide)) return;
@@ -71,9 +75,9 @@ void cmd_gnet(char *argbuf) {
 
 
 void cmd_snet(char *argbuf) {
-       char tempfilename[256];
-       char filename[256];
-       char buf[256];
+       char tempfilename[SIZ];
+       char filename[SIZ];
+       char buf[SIZ];
        FILE *fp;
 
        if (CtdlAccessCheck(ac_room_aide)) return;
@@ -94,10 +98,13 @@ void cmd_snet(char *argbuf) {
        }
        fclose(fp);
 
-       /* Now that we've got the whole file, put it in place */
+       /* Now copy the temp file to its permanent location
+        * (We use /bin/mv instead of link() because they may be on
+        * different filesystems)
+        */
        unlink(filename);
-       link(tempfilename, filename);
-       unlink(tempfilename);
+       snprintf(buf, sizeof buf, "/bin/mv %s %s", tempfilename, filename);
+       system(buf);
 }
 
 
@@ -110,7 +117,7 @@ void network_spool_msg(long msgnum, void *userdata) {
        struct namelist *nptr;
        int err;
        char *instr = NULL;
-       int instr_len = 0;
+       size_t instr_len = SIZ;
        struct CtdlMessage *imsg;
 
        sc = (struct SpoolControl *)userdata;
@@ -124,14 +131,37 @@ void network_spool_msg(long msgnum, void *userdata) {
        err = CtdlSaveMsgPointerInRoom(SMTP_SPOOLOUT_ROOM, msgnum, 0);
        if (err != 0) return;
 
+       /* 
+        * Figure out how big a buffer we need to allocate
+        */
+       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
+               instr_len = instr_len + strlen(nptr->name);
+       }
+
+       /*
+        * allocate...
+        */
        lprintf(9, "Generating delivery instructions\n");
-       instr_len = 4096;
        instr = mallok(instr_len);
+       if (instr == NULL) {
+               lprintf(1, "Cannot allocate %d bytes for instr...\n",
+                       instr_len);
+               abort();
+       }
        sprintf(instr,
                "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
                "bounceto|postmaster@%s\n" ,
                SPOOLMIME, msgnum, time(NULL), config.c_fqdn );
 
+       /* Generate delivery instructions for each recipient */
+       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
+               sprintf(&instr[strlen(instr)], "remote|%s|0||\n",
+                       nptr->name);
+       }
+
+       /*
+        * Generate a message from the instructions
+        */
                imsg = mallok(sizeof(struct CtdlMessage));
        memset(imsg, 0, sizeof(struct CtdlMessage));
        imsg->cm_magic = CTDLMESSAGE_MAGIC;
@@ -140,16 +170,6 @@ void network_spool_msg(long msgnum, void *userdata) {
        imsg->cm_fields['A'] = strdoop("Citadel");
        imsg->cm_fields['M'] = instr;
 
-       /* Generate delivery instructions for each recipient */
-       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
-               if (instr_len - strlen(instr) < 256) {
-                       instr_len = instr_len * 2;
-                       instr = reallok(instr, instr_len);
-               }
-               sprintf(&instr[strlen(instr)], "remote|%s|0||\n",
-                       nptr->name);
-       }
-
        /* Save delivery instructions in spoolout room */
        CtdlSaveMsg(imsg, "", SMTP_SPOOLOUT_ROOM, MES_LOCAL);
        CtdlFreeMessage(imsg);
@@ -164,15 +184,17 @@ void network_spool_msg(long msgnum, void *userdata) {
 /*
  * Batch up and send all outbound traffic from the current room
  */
-void network_spoolout_current_room(void) {
-       char filename[256];
-       char buf[256];
-       char instr[256];
+void network_spoolout_room(struct quickroom *qrbuf, void *data) {
+       char filename[SIZ];
+       char buf[SIZ];
+       char instr[SIZ];
        FILE *fp;
        struct SpoolControl sc;
        /* struct namelist *digestrecps = NULL; */
        struct namelist *nptr;
 
+       memcpy(&CC->quickroom, qrbuf, sizeof(struct quickroom));
+
        memset(&sc, 0, sizeof(struct SpoolControl));
        assoc_file_name(filename, &CC->quickroom, "netconfigs");
 
@@ -207,7 +229,7 @@ void network_spoolout_current_room(void) {
 
 
        /* Do something useful */
-       CtdlForEachMessage(MSGS_ALL, 0L, (-63), NULL, NULL,
+       CtdlForEachMessage(MSGS_GT, sc.lastsent, (-63), NULL, NULL,
                network_spool_msg, &sc);
 
 
@@ -238,27 +260,45 @@ void network_spoolout_current_room(void) {
 }
 
 
+/*
+ * network_do_queue()
+ * 
+ * Run through the rooms doing various types of network stuff.
+ */
+void network_do_queue(void) {
+       static int doing_queue = 0;
+       static time_t last_run = 0L;
 
-/* FIXME temporary server command for batch send */
-void cmd_batc(char *argbuf) {
-       if (CtdlAccessCheck(ac_aide)) return;
+#define NETWORK_QUEUE_FREQUENCY 3600   /* one hour ... FIXME put in config */
+       /*
+        * Run no more frequently than once every n seconds
+        */
+       if ( (time(NULL) - last_run) < NETWORK_QUEUE_FREQUENCY ) return;
 
-       network_spoolout_current_room();
+       /*
+        * 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;
+       last_run = time(NULL);
 
-       cprintf("%d FIXME cmd_batc() ok\n", OK);
+       /* 
+        * Go ahead and run the queue
+        */
+       lprintf(7, "network: processing outbound queue\n");
+       ForEachRoom(network_spoolout_room, NULL);
+       lprintf(7, "network: queue run completed\n");
+       doing_queue = 0;
 }
 
 
-
 char *Dynamic_Module_Init(void)
 {
        CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
        CtdlRegisterProtoHook(cmd_snet, "SNET", "Get network config");
-
-       /* FIXME
-          temporary server command for batch send
-        */
-       CtdlRegisterProtoHook(cmd_batc, "BATC", "send out batch (temp)");
-
+       CtdlRegisterSessionHook(network_do_queue, EVT_TIMER);
        return "$Id$";
 }