]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_network.c
* Bugfixes and cosmetic changes to listsub system
[citadel.git] / citadel / serv_network.c
index 00b044d09e9c2036a8f86be0094a1a19f409c3ab..5694055b8e16f386f7f847495e7e7cabbd4c3a4c 100644 (file)
@@ -7,6 +7,13 @@
  * Copyright (C) 2000-2002 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
  *
+ * ** NOTE **   A word on the S_NETCONFIGS semaphore:
+ * This is a fairly high-level type of critical section.  It ensures that no
+ * two threads work on the netconfigs files at the same time.  Since we do
+ * so many things inside these, here are the rules:
+ *  1. begin_critical_section(S_NETCONFIGS) *before* begin_ any others.
+ *  2. Do *not* perform any I/O with the client during these sections.
+ *
  */
 
 /*
  * Don't allow polls during network processing
  */
 
+/*
+ * Duration of time (in seconds) after which pending list subscribe/unsubscribe
+ * requests that have not been confirmed will be deleted.
+ */
+#define EXP    259200  /* three days */
+
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -372,7 +385,9 @@ void cmd_snet(char *argbuf) {
         */
        unlink(filename);
        snprintf(buf, sizeof buf, "/bin/mv %s %s", tempfilename, filename);
+       begin_critical_section(S_NETCONFIGS);
        system(buf);
+       end_critical_section(S_NETCONFIGS);
 }
 
 
@@ -459,9 +474,9 @@ void network_spool_msg(long msgnum, void *userdata) {
        if ((sc->digestrecps != NULL) && (sc->digestfp != NULL)) {
                fprintf(sc->digestfp,   " -----------------------------------"
                                        "------------------------------------"
-                                       "-------\r\n");
+                                       "-------\n");
                CtdlRedirectOutput(sc->digestfp, -1);
-               CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1);
+               CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 0);
                CtdlRedirectOutput(NULL, -1);
                sc->num_msgs_spooled += 1;
        }
@@ -595,7 +610,8 @@ void network_deliver_digest(struct SpoolControl *sc) {
 
        sprintf(buf, "%ld", time(NULL));
        msg->cm_fields['T'] = strdoop(buf);
-
+       msg->cm_fields['A'] = strdoop(CC->quickroom.QRname);
+       msg->cm_fields['U'] = strdoop(CC->quickroom.QRname);
        sprintf(buf, "room_%s@%s", CC->quickroom.QRname, config.c_fqdn);
        for (i=0; i<strlen(buf); ++i) {
                if (isspace(buf[i])) buf[i]='_';
@@ -603,8 +619,6 @@ void network_deliver_digest(struct SpoolControl *sc) {
        }
        msg->cm_fields['F'] = strdoop(buf);
 
-       msg->cm_fields['A'] = strdoop(CC->quickroom.QRname);
-
        fseek(sc->digestfp, 0L, SEEK_END);
        msglen = ftell(sc->digestfp);
 
@@ -677,6 +691,10 @@ void network_spoolout_room(char *room_to_spool) {
        FILE *fp;
        struct SpoolControl sc;
        struct namelist *nptr;
+       size_t miscsize = 0;
+       size_t linesize = 0;
+       int skipthisline = 0;
+       int i;
 
        lprintf(7, "Spooling <%s>\n", room_to_spool);
        if (getroom(&CC->quickroom, room_to_spool) != 0) {
@@ -687,10 +705,14 @@ void network_spoolout_room(char *room_to_spool) {
        memset(&sc, 0, sizeof(struct SpoolControl));
        assoc_file_name(filename, sizeof filename, &CC->quickroom, "netconfigs");
 
+       begin_critical_section(S_NETCONFIGS);
+       end_critical_section(S_NETCONFIGS);
+
        fp = fopen(filename, "r");
        if (fp == NULL) {
                lprintf(7, "Outbound batch processing skipped for <%s>\n",
                        CC->quickroom.QRname);
+               end_critical_section(S_NETCONFIGS);
                return;
        }
 
@@ -725,6 +747,31 @@ void network_spoolout_room(char *room_to_spool) {
                        extract(nptr->name, buf, 1);
                        sc.ignet_push_shares = nptr;
                }
+               else {
+                       /* Preserve 'other' lines ... *unless* they happen to
+                        * be subscribe/unsubscribe pendings with expired
+                        * timestamps.
+                        */
+                       skipthisline = 0;
+                       if (!strncasecmp(buf, "subpending|", 11)) {
+                               if (time(NULL) - extract_long(buf, 4) > EXP) {
+                                       skipthisline = 1;
+                               }
+                       }
+                       if (!strncasecmp(buf, "unsubpending|", 13)) {
+                               if (time(NULL) - extract_long(buf, 3) > EXP) {
+                                       skipthisline = 1;
+                               }
+                       }
+
+                       if (skipthisline == 0) {
+                               linesize = strlen(buf);
+                               sc.misc = realloc(sc.misc,
+                                       (miscsize + linesize + 2) );
+                               sprintf(&sc.misc[miscsize], "%s\n", buf);
+                               miscsize = miscsize + linesize + 1;
+                       }
+               }
 
 
        }
@@ -733,7 +780,7 @@ void network_spoolout_room(char *room_to_spool) {
        /* If there are digest recipients, we have to build a digest */
        if (sc.digestrecps != NULL) {
                sc.digestfp = tmpfile();
-               fprintf(sc.digestfp, "Content-type: text/plain\r\n\r\n");
+               fprintf(sc.digestfp, "Content-type: text/plain\n\n");
        }
 
        /* Do something useful */
@@ -741,14 +788,20 @@ void network_spoolout_room(char *room_to_spool) {
                network_spool_msg, &sc);
 
        /* If we wrote a digest, deliver it and then close it */
+       snprintf(buf, sizeof buf, "room_%s@%s",
+               CC->quickroom.QRname, config.c_fqdn);
+       for (i=0; i<strlen(buf); ++i) {
+               buf[i] = tolower(buf[i]);
+               if (isspace(buf[i])) buf[i] = '_';
+       }
        if (sc.digestfp != NULL) {
                fprintf(sc.digestfp,    " -----------------------------------"
                                        "------------------------------------"
-                                       "-------\r\n"
+                                       "-------\n"
                                        "You are subscribed to the '%s' "
-                                       "list.\r\nTo unsubscribe, blah blah "
-                                       "blah FIXME.\r\n",
-                                       CC->quickroom.QRname
+                                       "list.\n"
+                                       "To post to the list: %s\n",
+                                       CC->quickroom.QRname, buf
                );
                network_deliver_digest(&sc);    /* deliver and close */
        }
@@ -785,9 +838,14 @@ void network_spoolout_room(char *room_to_spool) {
                        phree(sc.ignet_push_shares);
                        sc.ignet_push_shares = nptr;
                }
+               if (sc.misc != NULL) {
+                       fwrite(sc.misc, strlen(sc.misc), 1, fp);
+               }
+               phree(sc.misc);
 
                fclose(fp);
        }
+       end_critical_section(S_NETCONFIGS);
 
        lprintf(5, "Outbound batch processing finished for <%s>\n",
                CC->quickroom.QRname);