Aggregation of remote POP3 accounts is now working.
[citadel.git] / citadel / control.c
index bbf3bf6ef8310b8f23b0d27b031c9765bbe34b16..710c38d63035bc9d13039b480725f121fbc9cd54 100644 (file)
@@ -5,10 +5,6 @@
  *
  */
 
-#ifdef DLL_EXPORT
-#define IN_LIBCIT
-#endif
-
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <limits.h>
 #include <sys/types.h>
+#include <sys/file.h>
 #include "citadel.h"
 #include "server.h"
 #include "control.h"
-#include "serv_extensions.h"
 #include "sysdep_decls.h"
 #include "support.h"
 #include "config.h"
@@ -52,11 +48,41 @@ struct CitControl CitControl;
 extern struct config config;
 FILE *control_fp = NULL;
 
+
+
+/*
+ * lock_control  -  acquire a lock on the control record file.
+ *                  This keeps multiple citservers from running concurrently.
+ */
+void lock_control(void)
+{
+#ifdef HAVE_FLOCK
+/*
+ * TODO: solaris manpages describe this function, but the headers
+ * don't show it! 
+ */
+
+       if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) {
+               lprintf(CTDL_EMERG, "citserver: unable to lock %s.\n", file_citadel_control);
+               lprintf(CTDL_EMERG, "Is another citserver already running?\n");
+               exit(CTDLEXIT_CONTROL);
+       }
+#endif
+}
+
+
 /*
  * get_control  -  read the control record into memory.
  */
 void get_control(void)
 {
+       static int already_have_control = 0;
+
+       /*
+        * If we already have the control record in memory, there's no point
+        * in reading it from disk again.
+        */
+       if (already_have_control) return;
 
        /* Zero it out.  If the control record on disk is missing or short,
         * the system functions with all control record fields initialized
@@ -64,26 +90,16 @@ void get_control(void)
         */
        memset(&CitControl, 0, sizeof(struct CitControl));
        if (control_fp == NULL) {
-               control_fp = fopen(
-#ifndef HAVE_RUN_DIR
-                                                  "."
-#else
-                                                  RUN_DIR
-#endif
-                                                  "/citadel.control", "rb+");
+               control_fp = fopen(file_citadel_control, "rb+");
                if (control_fp != NULL) {
+                       lock_control();
                        fchown(fileno(control_fp), config.c_ctdluid, -1);
                }
        }
        if (control_fp == NULL) {
-               control_fp = fopen(
-#ifndef HAVE_RUN_DIR
-                                                  "."
-#else
-                                                  RUN_DIR
-#endif
-                                                  "/citadel.control", "wb+");
+               control_fp = fopen(file_citadel_control, "wb+");
                if (control_fp != NULL) {
+                       lock_control();
                        fchown(fileno(control_fp), config.c_ctdluid, -1);
                        memset(&CitControl, 0, sizeof(struct CitControl));
                        fwrite(&CitControl, sizeof(struct CitControl),
@@ -92,13 +108,15 @@ void get_control(void)
                }
        }
        if (control_fp == NULL) {
-               lprintf(CTDL_ALERT, "ERROR opening citadel.control: %s\n",
-                       strerror(errno));
+               lprintf(CTDL_ALERT, "ERROR opening %s: %s\n",
+                               file_citadel_control,
+                               strerror(errno));
                return;
        }
 
        rewind(control_fp);
        fread(&CitControl, sizeof(struct CitControl), 1, control_fp);
+       already_have_control = 1;
 }
 
 /*
@@ -115,18 +133,28 @@ void put_control(void)
        }
 }
 
+/**
+ * release_control - close our fd on exit
+ */
+void release_control(void)
+{
+       if (control_fp != NULL)
+               fclose(control_fp);
+       control_fp = NULL;
+}
 
 /*
  * get_new_message_number()  -  Obtain a new, unique ID to be used for a message.
  */
 long get_new_message_number(void)
 {
+       long retval = 0L;
        begin_critical_section(S_CONTROL);
        get_control();
-       ++CitControl.MMhighest;
+       retval = ++CitControl.MMhighest;
        put_control();
        end_critical_section(S_CONTROL);
-       return (CitControl.MMhighest);
+       return(retval);
 }
 
 
@@ -135,12 +163,13 @@ long get_new_message_number(void)
  */
 long get_new_user_number(void)
 {
+       long retval = 0L;
        begin_critical_section(S_CONTROL);
        get_control();
-       ++CitControl.MMnextuser;
+       retval = ++CitControl.MMnextuser;
        put_control();
        end_critical_section(S_CONTROL);
-       return (CitControl.MMnextuser);
+       return(retval);
 }
 
 
@@ -150,12 +179,13 @@ long get_new_user_number(void)
  */
 long get_new_room_number(void)
 {
+       long retval = 0L;
        begin_critical_section(S_CONTROL);
        get_control();
-       ++CitControl.MMnextroom;
+       retval = ++CitControl.MMnextroom;
        put_control();
        end_critical_section(S_CONTROL);
-       return (CitControl.MMnextroom);
+       return(retval);
 }
 
 
@@ -230,6 +260,18 @@ void cmd_conf(char *argbuf)
                cprintf("%d\n", config.c_auto_cull);
                cprintf("%d\n", config.c_instant_expunge);
                cprintf("%d\n", config.c_allow_spoofing);
+               cprintf("%d\n", config.c_journal_email);
+               cprintf("%d\n", config.c_journal_pubmsgs);
+               cprintf("%s\n", config.c_journal_dest);
+               cprintf("%s\n", config.c_default_cal_zone);
+               cprintf("%d\n", config.c_pftcpdict_port);
+               cprintf("%d\n", config.c_managesieve_port);
+               cprintf("%d\n", config.c_auth_mode);
+               cprintf("%s\n", config.c_funambol_host);
+               cprintf("%d\n", config.c_funambol_port);
+               cprintf("%s\n", config.c_funambol_source);
+               cprintf("%s\n", config.c_funambol_auth);
+               cprintf("%d\n", config.c_rbl_at_greeting);
                cprintf("000\n");
        }
 
@@ -416,22 +458,63 @@ void cmd_conf(char *argbuf)
                        case 45:
                                config.c_allow_spoofing = atoi(buf);
                                break;
+                       case 46:
+                               config.c_journal_email = atoi(buf);
+                               break;
+                       case 47:
+                               config.c_journal_pubmsgs = atoi(buf);
+                               break;
+                       case 48:
+                               safestrncpy(config.c_journal_dest, buf,
+                                               sizeof config.c_journal_dest);
+                       case 49:
+                               safestrncpy(config.c_default_cal_zone, buf,
+                                               sizeof config.c_default_cal_zone);
+                               break;
+                       case 50:
+                               config.c_pftcpdict_port = atoi(buf);
+                               break;
+                       case 51:
+                               config.c_managesieve_port = atoi(buf);
+                               break;
+                       case 52:
+                               config.c_auth_mode = atoi(buf);
+                       case 53:
+                               safestrncpy(config.c_funambol_host, buf,
+                                       sizeof config.c_funambol_host);
+                               break;
+                       case 54:
+                               config.c_funambol_port = atoi(buf);
+                               break;
+                       case 55:
+                               safestrncpy(config.c_funambol_source,
+                                       buf, 
+                                       sizeof config.c_funambol_source);
+                               break;
+                       case 56:
+                               safestrncpy(config.c_funambol_auth,
+                                       buf,
+                                       sizeof config.c_funambol_auth);
+                               break;
+                       case 57:
+                               config.c_rbl_at_greeting = atoi(buf);
+                               break;
                        }
                        ++a;
                }
                put_config();
                snprintf(buf, sizeof buf,
-                        "Global system configuration edited by %s\n",
+                        "The global system configuration has been edited by %s.\n",
                         CC->curr_user);
-               aide_message(buf);
+               aide_message(buf,"Citadel Configuration Manager Message");
 
-               if (strlen(config.c_logpages) > 0)
+               if (!IsEmptyStr(config.c_logpages))
                        create_room(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);
 
                /* If full text indexing has been disabled, invalidate the
                 * index so it doesn't try to use it later.
                 */
-               if (!config.c_enable_fulltext == 0) {
+               if (config.c_enable_fulltext == 0) {
                        CitControl.fulltext_wordbreaker = 0;
                        put_control();
                }
@@ -457,8 +540,7 @@ void cmd_conf(char *argbuf)
                extract_token(confname, argbuf, 1, '|', sizeof confname);
                unbuffer_output();
                cprintf("%d %s\n", SEND_LISTING, confname);
-               confptr = CtdlReadMessageBody("000",
-                               config.c_maxmsglen, NULL, 0);
+               confptr = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
                CtdlPutSysConfig(confname, confptr);
                free(confptr);
        }