Merge branch 'master' of ssh://git.citadel.org/appl/gitroot/citadel
authorWilfried Goesgens <willi@arangodb.com>
Sun, 11 Oct 2015 11:57:27 +0000 (13:57 +0200)
committerWilfried Goesgens <willi@arangodb.com>
Sun, 11 Oct 2015 11:57:27 +0000 (13:57 +0200)
86 files changed:
citadel/citadel.h
citadel/citserver.c
citadel/citserver.h
citadel/config.c
citadel/config.h
citadel/context.c
citadel/control.c
citadel/control.h
citadel/database.c
citadel/database.h
citadel/euidindex.c
citadel/event_client.c
citadel/housekeeping.c
citadel/ical_dezonify.c
citadel/include/ctdl_module.h
citadel/internet_addressing.c
citadel/journaling.c
citadel/ldap.c
citadel/modules/autocompletion/serv_autocompletion.c
citadel/modules/bio/serv_bio.c
citadel/modules/calendar/serv_calendar.c
citadel/modules/crypto/serv_crypto.c
citadel/modules/ctdlproto/serv_file.c
citadel/modules/ctdlproto/serv_messages.c
citadel/modules/ctdlproto/serv_rooms.c
citadel/modules/ctdlproto/serv_session.c
citadel/modules/ctdlproto/serv_user.c
citadel/modules/eventclient/serv_eventclient.c
citadel/modules/expire/expire_policy.c
citadel/modules/expire/serv_expire.c
citadel/modules/extnotify/extnotify_main.c
citadel/modules/extnotify/funambol65.c
citadel/modules/fulltext/serv_fulltext.c
citadel/modules/imap/imap_fetch.c
citadel/modules/imap/imap_misc.c
citadel/modules/imap/imap_search.c
citadel/modules/imap/serv_imap.c
citadel/modules/inetcfg/serv_inetcfg.c
citadel/modules/instmsg/serv_instmsg.c
citadel/modules/managesieve/serv_managesieve.c
citadel/modules/migrate/serv_migrate.c
citadel/modules/mrtg/serv_mrtg.c
citadel/modules/network/serv_netmail.c
citadel/modules/network/serv_netspool.c
citadel/modules/network/serv_network.c
citadel/modules/network/serv_network.h
citadel/modules/networkclient/serv_networkclient.c
citadel/modules/nntp/serv_nntp.c
citadel/modules/openid/serv_openid_rp.c
citadel/modules/pop3/serv_pop3.c
citadel/modules/pop3client/serv_pop3client.c
citadel/modules/rssclient/serv_rssclient.c
citadel/modules/rwho/serv_rwho.c
citadel/modules/sieve/serv_sieve.c
citadel/modules/smtp/serv_smtp.c
citadel/modules/smtp/serv_smtpqueue.c
citadel/modules/smtp/smtp_clienthandlers.c
citadel/modules/smtp/smtp_util.c
citadel/modules/spam/serv_spam.c
citadel/modules/upgrade/serv_upgrade.c
citadel/modules/vcard/serv_vcard.c
citadel/modules/wiki/serv_wiki.c
citadel/modules/xmpp/serv_xmpp.c
citadel/modules/xmpp/xmpp_presence.c
citadel/modules/xmpp/xmpp_query_namespace.c
citadel/msgbase.c
citadel/msgbase.h
citadel/netconfig.c
citadel/parsedate.c
citadel/room_ops.c
citadel/serv_extensions.c
citadel/server.h
citadel/server_main.c
citadel/sysdep.c
citadel/techdoc/hack.txt
citadel/threads.c
citadel/user_ops.c
citadel/utils/ctdlmigrate.c
libcitadel/lib/stringbuf.c
libcitadel/lib/tools.c
textclient/src/citadel.c
webcit/context_loop.c
webcit/serv_func.c
webcit/subst.c
webcit/webcit.c
webcit/webcit.h

index d1dd3598fd30257555632e2f552cc72ffe2b3721..f45b0ea7751a9dd7da14666123843505427a651e 100644 (file)
@@ -116,9 +116,7 @@ struct ctdluser {                   /* User record                       */
 };
 
 
-/* Bits which may appear in CitControl.MMflags.  Note that these don't
- * necessarily pertain to the message base -- it's just a good place to
- * store any global flags.
+/* Bits which may appear in MMflags.
  */
 #define MM_VALID       4               /* New users need validating        */
 
index 4a1070b23563876a03ca5b84c10951497888665f..9832b781276932dbab8d01c4bee2e1ae96c4effc 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Main source module for the Citadel server
  *
- * Copyright (c) 1987-2014 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -122,11 +122,9 @@ void master_startup(void) {
        
        syslog(LOG_DEBUG, "master_startup() started\n");
        time(&server_startup_time);
-       get_config();
-       validate_config();
 
        syslog(LOG_INFO, "Checking directory access");
-       if ((pw = getpwuid(CTDLUID)) == NULL) {
+       if ((pw = getpwuid(ctdluid)) == NULL) {
                gid = getgid();
        } else {
                gid = pw->pw_gid;
@@ -138,13 +136,21 @@ void master_startup(void) {
        }
        syslog(LOG_INFO, "Opening databases");
        open_databases();
+
+       /* Load site-specific configuration */
+       syslog(LOG_INFO, "Initializing configuration system");
+       initialize_config_system();
+       validate_config();
+       migrate_legacy_control_record();
+
+       /* Check floor reference counts */
        check_ref_counts();
 
        syslog(LOG_INFO, "Creating base rooms (if necessary)\n");
-       CtdlCreateRoom(config.c_baseroom,       0, "", 0, 1, 0, VIEW_BBS);
-       CtdlCreateRoom(AIDEROOM,                3, "", 0, 1, 0, VIEW_BBS);
-       CtdlCreateRoom(SYSCONFIGROOM,           3, "", 0, 1, 0, VIEW_BBS);
-       CtdlCreateRoom(config.c_twitroom,       0, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(CtdlGetConfigStr("c_baseroom"),  0, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(AIDEROOM,                        3, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(SYSCONFIGROOM,                   3, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(CtdlGetConfigStr("c_twitroom"),  0, "", 0, 1, 0, VIEW_BBS);
 
        /* The "Local System Configuration" room doesn't need to be visible */
         if (CtdlGetRoomLock(&qrbuf, SYSCONFIGROOM) == 0) {
@@ -174,8 +180,6 @@ void master_startup(void) {
        srand(seed);
        srandom(seed);
 
-       put_config();
-
        syslog(LOG_DEBUG, "master_startup() finished\n");
 }
 
@@ -200,6 +204,9 @@ void master_cleanup(int exitcode) {
 
        /* Do system-dependent stuff */
        sysdep_master_cleanup();
+
+       /* Close the configuration system */
+       shutdown_config_system();
        
        /* Close databases */
        syslog(LOG_INFO, "Closing databases\n");
@@ -214,8 +221,6 @@ void master_cleanup(int exitcode) {
                }
        }
        
-       release_control();
-
        /* Now go away. */
        syslog(LOG_NOTICE, "citserver: Exiting with status %d\n", exitcode);
        fflush(stdout); fflush(stderr);
@@ -289,7 +294,7 @@ int CtdlIsPublicClient(void)
                safestrncpy(public_clientspos, LOCALHOSTSTR, sizeof public_clients);
                public_clientspos += sizeof(LOCALHOSTSTR) - 1;
                
-               if (hostname_to_dotted_quad(addrbuf, config.c_fqdn) == 0) {
+               if (hostname_to_dotted_quad(addrbuf, CtdlGetConfigStr("c_fqdn")) == 0) {
                        *(public_clientspos++) = '|';
                        paddr = &addrbuf[0];
                        while (!IsEmptyStr (paddr) && 
@@ -351,12 +356,12 @@ void citproto_begin_session() {
        if (CC->nologin==1) {
                cprintf("%d %s: Too many users are already online (maximum is %d)\n",
                        ERROR + MAX_SESSIONS_EXCEEDED,
-                       config.c_nodename, config.c_maxsessions
+                       CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions")
                );
                CC->kill_me = KILLME_MAX_SESSIONS_EXCEEDED;
        }
        else {
-               cprintf("%d %s Citadel server ready.\n", CIT_OK, config.c_nodename);
+               cprintf("%d %s Citadel server ready.\n", CIT_OK, CtdlGetConfigStr("c_nodename"));
                CC->can_receive_im = 1;
        }
 }
@@ -364,7 +369,7 @@ void citproto_begin_session() {
 
 void citproto_begin_admin_session() {
        CC->internal_pgm = 1;
-       cprintf("%d %s Citadel server ADMIN CONNECTION ready.\n", CIT_OK, config.c_nodename);
+       cprintf("%d %s Citadel server ADMIN CONNECTION ready.\n", CIT_OK, CtdlGetConfigStr("c_nodename"));
 }
 
 
index 4224fcdcb3d56934b5a309575aeda98d6060d54a..997775bd2a50c4381c889b66e9ec7351aed2ea74 100644 (file)
@@ -1,13 +1,13 @@
 /*
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "serv_extensions.h"
index 34028abb0ee36b511a9fdcd7cbb9565b8f68ab37..b6c386b6e56dc7c0ee9d31ed8ea909860ca903c1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Read and write the citadel.config file
  *
- * Copyright (c) 1987-2014 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
 #include "config.h"
 #include "ctdl_module.h"
 
-struct config config;
-struct configlen configlen;
+long config_msgnum = 0;
+HashList *ctdlconfig = NULL;   // new configuration
+
+
+void config_warn_if_port_unset(char *key, int default_port)                    \
+{
+       int p = CtdlGetConfigInt(key);
+       if ((p < -1) || (p == 0) || (p > UINT16_MAX))
+       {
+               syslog(LOG_EMERG,
+                       "configuration setting %s is not -1 (disabled) or a valid TCP-Port - check your config! Default setting is: %d",
+                       key, default_port
+               );
+       }
+}
+
+
+void config_warn_if_empty(char *key)
+{
+       if (IsEmptyStr(CtdlGetConfigStr(key)))
+       {
+               syslog(LOG_EMERG, "configuration setting %s is empty, but must not - check your config!", key);
+       }
+}
 
-#define STR_NOT_EMPTY(CFG_FIELDNAME) if (IsEmptyStr(config.CFG_FIELDNAME)) \
-               syslog(LOG_EMERG, "configuration setting "#CFG_FIELDNAME" is empty, but must not - check your config!");
 
-#define TEST_PORT(CFG_PORT, DEFAULTPORT)                       \
-       if ((config.CFG_PORT < -1) ||           \
-           (config.CFG_PORT == 0) ||           \
-           (config.CFG_PORT > UINT16_MAX))     \
-               syslog(LOG_EMERG, "configuration setting "#CFG_PORT" is not -1 (disabled) or a valid TCP-Port - check your config! Default setting is: "#DEFAULTPORT);
-                       
 
 void validate_config(void) {
-/* these shouldn't be empty: */
-       STR_NOT_EMPTY(c_fqdn);
-
-       STR_NOT_EMPTY(c_baseroom);
-       STR_NOT_EMPTY(c_aideroom);
-       STR_NOT_EMPTY(c_twitroom);
-       STR_NOT_EMPTY(c_nodename);
-       STR_NOT_EMPTY(c_default_cal_zone);
-
-/* we bind a lot of ports: */
-       TEST_PORT(c_smtp_port, 25);
-       TEST_PORT(c_pop3_port, 110);
-       TEST_PORT(c_imap_port, 143);
-       TEST_PORT(c_msa_port, 587);
-       TEST_PORT(c_port_number, 504);
-       TEST_PORT(c_smtps_port, 465);
-       TEST_PORT(c_pop3s_port, 995);
-       TEST_PORT(c_imaps_port, 993);
-       TEST_PORT(c_pftcpdict_port, -1);
-       TEST_PORT(c_managesieve_port, 2020);
-       TEST_PORT(c_xmpp_c2s_port, 5222);
-       TEST_PORT(c_xmpp_s2s_port, 5269);
-       TEST_PORT(c_nntp_port, 119);
-       TEST_PORT(c_nntps_port, 563);
-
-       if (config.c_ctdluid == 0)
-               syslog(LOG_EMERG, "citadel should not be configured to run as root! Check the value of c_ctdluid");
-       else if (getpwuid(CTDLUID) == NULL)
-               syslog(LOG_EMERG, "The UID (%d) citadel is configured to use is not defined in your system (/etc/passwd?)! Check the value of c_ctdluid", CTDLUID);
+
+       /*
+        * these shouldn't be empty
+        */
+       config_warn_if_empty("c_fqdn");
+       config_warn_if_empty("c_baseroom");
+       config_warn_if_empty("c_aideroom");
+       config_warn_if_empty("c_twitroom");
+       config_warn_if_empty("c_nodename");
+       config_warn_if_empty("c_default_cal_zone");
+
+       /*
+        * Sanity check for port bindings
+        */
+       config_warn_if_port_unset("c_smtp_port", 25);
+       config_warn_if_port_unset("c_pop3_port", 110);
+       config_warn_if_port_unset("c_imap_port", 143);
+       config_warn_if_port_unset("c_msa_port", 587);
+       config_warn_if_port_unset("c_port_number", 504);
+       config_warn_if_port_unset("c_smtps_port", 465);
+       config_warn_if_port_unset("c_pop3s_port", 995);
+       config_warn_if_port_unset("c_imaps_port", 993);
+       config_warn_if_port_unset("c_pftcpdict_port", -1);
+       config_warn_if_port_unset("c_managesieve_port", 2020);
+       config_warn_if_port_unset("c_xmpp_c2s_port", 5222);
+       config_warn_if_port_unset("c_xmpp_s2s_port", 5269);
+       config_warn_if_port_unset("c_nntp_port", 119);
+       config_warn_if_port_unset("c_nntps_port", 563);
+
+       if (getpwuid(ctdluid) == NULL) {
+               syslog(LOG_EMERG, "The UID (%d) citadel is configured to use is not defined in your system (/etc/passwd?)!", ctdluid);
+       }
        
 }
 
@@ -70,110 +87,165 @@ void validate_config(void) {
  */
 void brand_new_installation_set_defaults(void) {
 
-       struct passwd *pw;
        struct utsname my_utsname;
        struct hostent *he;
+       char detected_hostname[256];
 
        /* Determine our host name, in case we need to use it as a default */
        uname(&my_utsname);
-       memset(&configlen, 0, sizeof(struct configlen));
+
        /* set some sample/default values in place of blanks... */
-       configlen.c_nodename = extract_token(config.c_nodename, my_utsname.nodename, 0, '.', sizeof config.c_nodename);
-       if (IsEmptyStr(config.c_fqdn) ) {
-               if ((he = gethostbyname(my_utsname.nodename)) != NULL) {
-                       configlen.c_fqdn = safestrncpy(config.c_fqdn, he->h_name, sizeof config.c_fqdn);
-               }
-               else {
-                       configlen.c_fqdn = safestrncpy(config.c_fqdn, my_utsname.nodename, sizeof config.c_fqdn);
-               }
-       }
+       extract_token(detected_hostname, my_utsname.nodename, 0, '.', sizeof detected_hostname);
+       CtdlSetConfigStr("c_nodename", detected_hostname);
 
-       configlen.c_humannode = safestrncpy(config.c_humannode, "Citadel Server", sizeof config.c_humannode);
-       configlen.c_phonenum = safestrncpy(config.c_phonenum, "US 800 555 1212", sizeof config.c_phonenum);
-       config.c_initax = 4;
-       configlen.c_moreprompt = safestrncpy(config.c_moreprompt, "<more>", sizeof config.c_moreprompt);
-       configlen.c_twitroom = safestrncpy(config.c_twitroom, "Trashcan", sizeof config.c_twitroom);
-       configlen.c_baseroom = safestrncpy(config.c_baseroom, BASEROOM, sizeof config.c_baseroom);
-       configlen.c_aideroom = safestrncpy(config.c_aideroom, "Aide", sizeof config.c_aideroom);
-       config.c_port_number = 504;
-       config.c_sleeping = 900;
-
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("citadel");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
+       if ((he = gethostbyname(my_utsname.nodename)) != NULL) {
+               CtdlSetConfigStr("c_fqdn", he->h_name);
        }
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("bbs");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
-       }
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("guest");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
+       else {
+               CtdlSetConfigStr("c_fqdn", my_utsname.nodename);
        }
-       if (config.c_createax == 0) {
-               config.c_createax = 3;
+
+       CtdlSetConfigStr("c_humannode",         "Citadel Server");
+       CtdlSetConfigInt("c_initax",            4);
+       CtdlSetConfigStr("c_moreprompt",        "<more>");
+       CtdlSetConfigStr("c_twitroom",          "Trashcan");
+       CtdlSetConfigStr("c_baseroom",          BASEROOM);
+       CtdlSetConfigStr("c_aideroom",          "Aide");
+       CtdlSetConfigInt("c_sleeping",          900);
+
+       if (CtdlGetConfigInt("c_createax") == 0) {
+               CtdlSetConfigInt("c_createax", 3);
        }
 
        /*
         * Default port numbers for various services
         */
-       config.c_smtp_port = 25;
-       config.c_pop3_port = 110;
-       config.c_imap_port = 143;
-       config.c_msa_port = 587;
-       config.c_smtps_port = 465;
-       config.c_pop3s_port = 995;
-       config.c_imaps_port = 993;
-       config.c_pftcpdict_port = -1 ;
-       config.c_managesieve_port = 2020;
-       config.c_xmpp_c2s_port = 5222;
-       config.c_xmpp_s2s_port = 5269;
-       config.c_nntp_port = 119;
-       config.c_nntps_port = 563;
+       CtdlSetConfigInt("c_port_number",       504);
+       CtdlSetConfigInt("c_smtp_port",         25);
+       CtdlSetConfigInt("c_pop3_port",         110);
+       CtdlSetConfigInt("c_imap_port",         143);
+       CtdlSetConfigInt("c_msa_port",          587);
+       CtdlSetConfigInt("c_smtps_port",        465);
+       CtdlSetConfigInt("c_pop3s_port",        995);
+       CtdlSetConfigInt("c_imaps_port",        993);
+       CtdlSetConfigInt("c_pftcpdict_port",    -1);
+       CtdlSetConfigInt("c_managesieve_port",  2020);
+       CtdlSetConfigInt("c_xmpp_c2s_port",     5222);
+       CtdlSetConfigInt("c_xmpp_s2s_port",     5269);
+       CtdlSetConfigInt("c_nntp_port",         119);
+       CtdlSetConfigInt("c_nntps_port",        563);
+
+       /*
+        * Prevent the "new installation, set defaults" behavior from occurring again
+        */
+       CtdlSetConfigLong("c_config_created_or_migrated", (long)time(NULL));
 }
 
-void setcfglen(void)
+
+
+/*
+ * Migrate a supplied legacy configuration to the new in-db format.
+ * No individual site should ever have to do this more than once.
+ */
+void migrate_legacy_config(struct legacy_config *lconfig)
 {
-       configlen.c_nodename = strlen(config.c_nodename);
-       configlen.c_fqdn = strlen(config.c_fqdn);
-       configlen.c_humannode = strlen(config.c_humannode);
-       configlen.c_phonenum = strlen(config.c_phonenum);
-       configlen.c_twitroom = strlen(config.c_twitroom);
-       configlen.c_moreprompt = strlen(config.c_moreprompt);
-       configlen.c_site_location = strlen(config.c_site_location);
-       configlen.c_sysadm = strlen(config.c_sysadm);
-       configlen.c_niu_2 = strlen(config.c_niu_2);
-       configlen.c_ip_addr = strlen(config.c_ip_addr);
-       configlen.c_logpages = strlen(config.c_logpages);
-       configlen.c_baseroom = strlen(config.c_baseroom);
-       configlen.c_aideroom = strlen(config.c_aideroom);
-       configlen.c_ldap_host = strlen(config.c_ldap_host);
-       configlen.c_ldap_base_dn = strlen(config.c_ldap_base_dn);
-       configlen.c_ldap_bind_dn = strlen(config.c_ldap_bind_dn);
-       configlen.c_ldap_bind_pw = strlen(config.c_ldap_bind_pw);
-       configlen.c_journal_dest = strlen(config.c_journal_dest);
-       configlen.c_default_cal_zone = strlen(config.c_default_cal_zone);
-       configlen.c_funambol_host = strlen(config.c_funambol_host);
-       configlen.c_funambol_source = strlen(config.c_funambol_source);
-       configlen.c_funambol_auth = strlen(config.c_funambol_auth);
-       configlen.c_master_user = strlen(config.c_master_user);
-       configlen.c_master_pass = strlen(config.c_master_pass);
-       configlen.c_pager_program = strlen(config.c_pager_program);
+       CtdlSetConfigStr(       "c_nodename"            ,       lconfig->c_nodename             );
+       CtdlSetConfigStr(       "c_fqdn"                ,       lconfig->c_fqdn                 );
+       CtdlSetConfigStr(       "c_humannode"           ,       lconfig->c_humannode            );
+       CtdlSetConfigInt(       "c_creataide"           ,       lconfig->c_creataide            );
+       CtdlSetConfigInt(       "c_sleeping"            ,       lconfig->c_sleeping             );
+       CtdlSetConfigInt(       "c_initax"              ,       lconfig->c_initax               );
+       CtdlSetConfigInt(       "c_regiscall"           ,       lconfig->c_regiscall            );
+       CtdlSetConfigInt(       "c_twitdetect"          ,       lconfig->c_twitdetect           );
+       CtdlSetConfigStr(       "c_twitroom"            ,       lconfig->c_twitroom             );
+       CtdlSetConfigStr(       "c_moreprompt"          ,       lconfig->c_moreprompt           );
+       CtdlSetConfigInt(       "c_restrict"            ,       lconfig->c_restrict             );
+       CtdlSetConfigStr(       "c_site_location"       ,       lconfig->c_site_location        );
+       CtdlSetConfigStr(       "c_sysadm"              ,       lconfig->c_sysadm               );
+       CtdlSetConfigInt(       "c_maxsessions"         ,       lconfig->c_maxsessions          );
+       CtdlSetConfigStr(       "c_ip_addr"             ,       lconfig->c_ip_addr              );
+       CtdlSetConfigInt(       "c_port_number"         ,       lconfig->c_port_number          );
+       CtdlSetConfigInt(       "c_ep_mode"             ,       lconfig->c_ep.expire_mode       );
+       CtdlSetConfigInt(       "c_ep_value"            ,       lconfig->c_ep.expire_value      );
+       CtdlSetConfigInt(       "c_userpurge"           ,       lconfig->c_userpurge            );
+       CtdlSetConfigInt(       "c_roompurge"           ,       lconfig->c_roompurge            );
+       CtdlSetConfigStr(       "c_logpages"            ,       lconfig->c_logpages             );
+       CtdlSetConfigInt(       "c_createax"            ,       lconfig->c_createax             );
+       CtdlSetConfigLong(      "c_maxmsglen"           ,       lconfig->c_maxmsglen            );
+       CtdlSetConfigInt(       "c_min_workers"         ,       lconfig->c_min_workers          );
+       CtdlSetConfigInt(       "c_max_workers"         ,       lconfig->c_max_workers          );
+       CtdlSetConfigInt(       "c_pop3_port"           ,       lconfig->c_pop3_port            );
+       CtdlSetConfigInt(       "c_smtp_port"           ,       lconfig->c_smtp_port            );
+       CtdlSetConfigInt(       "c_rfc822_strict_from"  ,       lconfig->c_rfc822_strict_from   );
+       CtdlSetConfigInt(       "c_aide_zap"            ,       lconfig->c_aide_zap             );
+       CtdlSetConfigInt(       "c_imap_port"           ,       lconfig->c_imap_port            );
+       CtdlSetConfigLong(      "c_net_freq"            ,       lconfig->c_net_freq             );
+       CtdlSetConfigInt(       "c_disable_newu"        ,       lconfig->c_disable_newu         );
+       CtdlSetConfigInt(       "c_enable_fulltext"     ,       lconfig->c_enable_fulltext      );
+       CtdlSetConfigStr(       "c_baseroom"            ,       lconfig->c_baseroom             );
+       CtdlSetConfigStr(       "c_aideroom"            ,       lconfig->c_aideroom             );
+       CtdlSetConfigInt(       "c_purge_hour"          ,       lconfig->c_purge_hour           );
+       CtdlSetConfigInt(       "c_mbxep_mode"          ,       lconfig->c_mbxep.expire_mode    );
+       CtdlSetConfigInt(       "c_mbxep_value"         ,       lconfig->c_mbxep.expire_value   );
+       CtdlSetConfigStr(       "c_ldap_host"           ,       lconfig->c_ldap_host            );
+       CtdlSetConfigInt(       "c_ldap_port"           ,       lconfig->c_ldap_port            );
+       CtdlSetConfigStr(       "c_ldap_base_dn"        ,       lconfig->c_ldap_base_dn         );
+       CtdlSetConfigStr(       "c_ldap_bind_dn"        ,       lconfig->c_ldap_bind_dn         );
+       CtdlSetConfigStr(       "c_ldap_bind_pw"        ,       lconfig->c_ldap_bind_pw         );
+       CtdlSetConfigInt(       "c_msa_port"            ,       lconfig->c_msa_port             );
+       CtdlSetConfigInt(       "c_imaps_port"          ,       lconfig->c_imaps_port           );
+       CtdlSetConfigInt(       "c_pop3s_port"          ,       lconfig->c_pop3s_port           );
+       CtdlSetConfigInt(       "c_smtps_port"          ,       lconfig->c_smtps_port           );
+       CtdlSetConfigInt(       "c_auto_cull"           ,       lconfig->c_auto_cull            );
+       CtdlSetConfigInt(       "c_allow_spoofing"      ,       lconfig->c_allow_spoofing       );
+       CtdlSetConfigInt(       "c_journal_email"       ,       lconfig->c_journal_email        );
+       CtdlSetConfigInt(       "c_journal_pubmsgs"     ,       lconfig->c_journal_pubmsgs      );
+       CtdlSetConfigStr(       "c_journal_dest"        ,       lconfig->c_journal_dest         );
+       CtdlSetConfigStr(       "c_default_cal_zone"    ,       lconfig->c_default_cal_zone     );
+       CtdlSetConfigInt(       "c_pftcpdict_port"      ,       lconfig->c_pftcpdict_port       );
+       CtdlSetConfigInt(       "c_managesieve_port"    ,       lconfig->c_managesieve_port     );
+       CtdlSetConfigInt(       "c_auth_mode"           ,       lconfig->c_auth_mode            );
+       CtdlSetConfigStr(       "c_funambol_host"       ,       lconfig->c_funambol_host        );
+       CtdlSetConfigInt(       "c_funambol_port"       ,       lconfig->c_funambol_port        );
+       CtdlSetConfigStr(       "c_funambol_source"     ,       lconfig->c_funambol_source      );
+       CtdlSetConfigStr(       "c_funambol_auth"       ,       lconfig->c_funambol_auth        );
+       CtdlSetConfigInt(       "c_rbl_at_greeting"     ,       lconfig->c_rbl_at_greeting      );
+       CtdlSetConfigStr(       "c_master_user"         ,       lconfig->c_master_user          );
+       CtdlSetConfigStr(       "c_master_pass"         ,       lconfig->c_master_pass          );
+       CtdlSetConfigStr(       "c_pager_program"       ,       lconfig->c_pager_program        );
+       CtdlSetConfigInt(       "c_imap_keep_from"      ,       lconfig->c_imap_keep_from       );
+       CtdlSetConfigInt(       "c_xmpp_c2s_port"       ,       lconfig->c_xmpp_c2s_port        );
+       CtdlSetConfigInt(       "c_xmpp_s2s_port"       ,       lconfig->c_xmpp_s2s_port        );
+       CtdlSetConfigLong(      "c_pop3_fetch"          ,       lconfig->c_pop3_fetch           );
+       CtdlSetConfigLong(      "c_pop3_fastest"        ,       lconfig->c_pop3_fastest         );
+       CtdlSetConfigInt(       "c_spam_flag_only"      ,       lconfig->c_spam_flag_only       );
+       CtdlSetConfigInt(       "c_guest_logins"        ,       lconfig->c_guest_logins         );
+       CtdlSetConfigInt(       "c_nntp_port"           ,       lconfig->c_nntp_port            );
+       CtdlSetConfigInt(       "c_nntps_port"          ,       lconfig->c_nntps_port           );
 }
 
+
+
 /*
- * get_config() is called during the initialization of Citadel server.
+ * Called during the initialization of Citadel server.
  * It verifies the system's integrity and reads citadel.config into memory.
  */
-void get_config(void) {
+void initialize_config_system(void) {
        FILE *cfp;
        int rv;
+       struct legacy_config lconfig;   // legacy configuration
+       ctdlconfig = NewHash(1, NULL);  // set up the real config system
+
+       /* Ensure that we are linked to the correct version of libcitadel */
+       if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) {
+               fprintf(stderr, "You are running libcitadel version %d.%02d\n",
+                       (libcitadel_version_number() / 100), (libcitadel_version_number() % 100)
+               );
+               fprintf(stderr, "citserver was compiled against version %d.%02d\n",
+                       (LIBCITADEL_VERSION_NUMBER / 100), (LIBCITADEL_VERSION_NUMBER % 100)
+               );
+               exit(CTDLEXIT_LIBCITADEL);
+       }
 
        if (chdir(ctdl_bbsbase_dir) != 0) {
                fprintf(stderr,
@@ -184,36 +256,47 @@ void get_config(void) {
                exit(CTDLEXIT_HOME);
        }
 
-       memset(&config, 0, sizeof(struct config));
+       memset(&lconfig, 0, sizeof(struct legacy_config));
        cfp = fopen(file_citadel_config, "rb");
        if (cfp != NULL) {
-               rv = fread((char *) &config, sizeof(struct config), 1, cfp);
+               if (CtdlGetConfigLong("c_config_created_or_migrated") > 0) {
+                       fprintf(stderr, "Citadel Server found BOTH legacy and new configurations present.\n");
+                       fprintf(stderr, "Exiting to prevent data corruption.\n");
+                       exit(CTDLEXIT_CONFIG);
+               }
+               rv = fread((char *) &lconfig, sizeof(struct legacy_config), 1, cfp);
                if (rv != 1)
                {
                        fprintf(stderr, 
-                               "Warning: The config file %s has unexpected size. \n",
+                               "Warning: Found a legacy config file %s has unexpected size. \n",
                                file_citadel_config
                        );
                }
+
+               migrate_legacy_config(&lconfig);
+
                fclose(cfp);
-               setcfglen();
-       }
-       else {
-               brand_new_installation_set_defaults();
+               if (unlink(file_citadel_config) != 0) {
+                       fprintf(stderr, "Unable to remove legacy config file %s after migrating it.\n", file_citadel_config);
+                       fprintf(stderr, "Exiting to prevent data corruption.\n");
+                       exit(CTDLEXIT_CONFIG);
+               }
+
+               /*
+                * Prevent migration/initialization from happening again.
+                */
+               CtdlSetConfigLong("c_config_created_or_migrated", (long)time(NULL));
+
        }
 
-       /* Ensure that we are linked to the correct version of libcitadel */
-       if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) {
-               fprintf(stderr, "    You are running libcitadel version %d.%02d\n",
-                       (libcitadel_version_number() / 100), (libcitadel_version_number() % 100));
-               fprintf(stderr, "citserver was compiled against version %d.%02d\n",
-                       (LIBCITADEL_VERSION_NUMBER / 100), (LIBCITADEL_VERSION_NUMBER % 100));
-               exit(CTDLEXIT_LIBCITADEL);
+       /* New installation?  Set up configuration */
+       if (CtdlGetConfigLong("c_config_created_or_migrated") <= 0) {
+               brand_new_installation_set_defaults();
        }
 
        /* Only allow LDAP auth mode if we actually have LDAP support */
 #ifndef HAVE_LDAP
-       if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
                fprintf(stderr, "Your system is configured for LDAP authentication,\n"
                                "but you are running a server built without OpenLDAP support.\n");
                exit(CTDL_EXIT_UNSUP_AUTH);
@@ -224,70 +307,169 @@ void get_config(void) {
         * configurable.  Also check to make sure the limit has not been
         * set below 8192 bytes.
          */
-        if (config.c_maxmsglen <= 0)
-                config.c_maxmsglen = 10485760;
-        if (config.c_maxmsglen < 8192)
-                config.c_maxmsglen = 8192;
+        if (CtdlGetConfigLong("c_maxmsglen") <= 0)     CtdlSetConfigLong("c_maxmsglen", 10485760);
+        if (CtdlGetConfigLong("c_maxmsglen") < 8192)   CtdlSetConfigLong("c_maxmsglen", 8192);
 
-        /* Default lower and upper limits on number of worker threads */
-
-       if (config.c_min_workers < 3)           /* no less than 3 */
-               config.c_min_workers = 5;
-
-       if (config.c_max_workers == 0)                  /* default maximum */
-               config.c_max_workers = 256;
-
-       if (config.c_max_workers < config.c_min_workers)   /* max >= min */
-               config.c_max_workers = config.c_min_workers;
+        /*
+        * Default lower and upper limits on number of worker threads
+        */
+       if (CtdlGetConfigInt("c_min_workers") < 5)      CtdlSetConfigInt("c_min_workers", 5);   // min
+       if (CtdlGetConfigInt("c_max_workers") == 0)     CtdlSetConfigInt("c_max_workers", 256); // default max
+       if (CtdlGetConfigInt("c_max_workers") < CtdlGetConfigInt("c_min_workers")) {
+               CtdlSetConfigInt("c_max_workers", CtdlGetConfigInt("c_min_workers"));           // max >= min
+       }
 
        /* Networking more than once every five minutes just isn't sane */
-       if (config.c_net_freq == 0L)
-               config.c_net_freq = 3600L;      /* once per hour default */
-       if (config.c_net_freq < 300L) 
-               config.c_net_freq = 300L;
+       if (CtdlGetConfigLong("c_net_freq") == 0)       CtdlSetConfigLong("c_net_freq", 3600);  // once per hour default
+       if (CtdlGetConfigLong("c_net_freq") < 300)      CtdlSetConfigLong("c_net_freq", 300);   // minimum 5 minutes
 
        /* Same goes for POP3 */
-       if (config.c_pop3_fetch == 0L)
-               config.c_pop3_fetch = 3600L;    /* once per hour default */
-       if (config.c_pop3_fetch < 300L) 
-               config.c_pop3_fetch = 300L;
-       if (config.c_pop3_fastest == 0L)
-               config.c_pop3_fastest = 3600L;  /* once per hour default */
-       if (config.c_pop3_fastest < 300L) 
-               config.c_pop3_fastest = 300L;
+       if (CtdlGetConfigLong("c_pop3_fetch") == 0)     CtdlSetConfigLong("c_pop3_fetch", 3600);        // once per hour default
+       if (CtdlGetConfigLong("c_pop3_fetch") < 300)    CtdlSetConfigLong("c_pop3_fetch", 300);         // 5 minutes min
+       if (CtdlGetConfigLong("c_pop3_fastest") == 0)   CtdlSetConfigLong("c_pop3_fastest", 3600);      // once per hour default
+       if (CtdlGetConfigLong("c_pop3_fastest") < 300)  CtdlSetConfigLong("c_pop3_fastest", 300);       // 5 minutes min
 
        /* "create new user" only works with native authentication mode */
-       if (config.c_auth_mode != AUTHMODE_NATIVE) {
-               config.c_disable_newu = 1;
+       if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) {
+               CtdlSetConfigInt("c_disable_newu", 1);
        }
 }
 
-long config_msgnum = 0;
+
 
 /*
- * Occasionally, we will need to write the config file, because some operations
- * change site-wide parameters.
+ * Called when Citadel server is shutting down.
+ * Clears out the config hash table.
  */
-void put_config(void)
+void shutdown_config_system(void) 
 {
-       FILE *cfp;
-       int blocks_written = 0;
+       DeleteHash(&ctdlconfig);
+}
 
-       cfp = fopen(file_citadel_config, "w");
-       if (cfp != NULL) {
-               blocks_written = fwrite((char *) &config, sizeof(struct config), 1, cfp);
-               if (blocks_written == 1) {
-                       chown(file_citadel_config, CTDLUID, (-1));
-                       chmod(file_citadel_config, 0600);
-                       fclose(cfp);
-                       return;
-               }
-               fclose(cfp);
+
+
+/*
+ * Set a system config value.  Simple key/value here.
+ */
+void CtdlSetConfigStr(char *key, char *value)
+{
+       int key_len = strlen(key);
+       int value_len = strlen(value);
+
+       /* FIXME we are noisy logging for now */
+       syslog(LOG_DEBUG, "\033[31mSET CONFIG: '%s' = '%s'\033[0m", key, value);
+
+       /* Save it in memory */
+       Put(ctdlconfig, key, key_len, strdup(value), NULL);
+
+       /* Also write it to the config database */
+
+       int dbv_size = key_len + value_len + 2;
+       char *dbv = malloc(dbv_size);
+       strcpy(dbv, key);
+       strcpy(&dbv[key_len + 1], value);
+       cdb_store(CDB_CONFIG, key, key_len, dbv, dbv_size);
+       free(dbv);
+}
+
+
+/*
+ * Set a numeric system config value (long integer)
+ */
+void CtdlSetConfigLong(char *key, long value)
+{
+       char longstr[256];
+       sprintf(longstr, "%ld", value);
+       CtdlSetConfigStr(key, longstr);
+}
+
+
+/*
+ * Set a numeric system config value (integer)
+ */
+void CtdlSetConfigInt(char *key, int value)
+{
+       char intstr[256];
+       sprintf(intstr, "%d", value);
+       CtdlSetConfigStr(key, intstr);
+}
+
+
+/*
+ * Fetch a system config value.  Caller does *not* own the returned value and may not alter it.
+ */
+char *CtdlGetConfigStr(char *key)
+{
+       char *value = NULL;
+       struct cdbdata *cdb;
+       int key_len = strlen(key);
+
+       if (IsEmptyStr(key)) return(NULL);
+
+       /* Temporary hack to make sure we didn't mess up any porting - FIXME remove this after testing thoroughly */
+       if (!strncmp(key, "config", 6)) {
+               syslog(LOG_EMERG, "You requested a key starting with 'config' which probably means a porting error: %s", key);
+               abort();
        }
-       syslog(LOG_EMERG, "%s: %s", file_citadel_config, strerror(errno));
+
+       /* First look in memory */
+       if (GetHash(ctdlconfig, key, key_len, (void *)&value))
+       {
+               if (strcmp(key, "c_min_workers")) syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = '%s'\033[0m", key, value);
+               return value;
+       }
+
+       /* Then look in the database. */
+
+       cdb = cdb_fetch(CDB_CONFIG, key, key_len);
+
+       if (cdb == NULL) {      /* nope, not there either. */
+               syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = NULL\033[0m", key);
+               return(NULL);
+       }
+
+       /* Got it.  Save it in memory for the next fetch. */
+       value = strdup(cdb->ptr + key_len + 1);         /* The key was stored there too; skip past it */
+       cdb_free(cdb);
+       Put(ctdlconfig, key, key_len, value, NULL);
+       syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = '%s'\033[0m", key, value);
+       return value;
+}
+
+
+/*
+ * Fetch a system config value - integer
+ */
+int CtdlGetConfigInt(char *key)
+{
+       char *s = CtdlGetConfigStr(key);
+       if (s) return atoi(s);
+       return 0;
 }
 
 
+/*
+ * Fetch a system config value - long integer
+ */
+long CtdlGetConfigLong(char *key)
+{
+       char *s = CtdlGetConfigStr(key);
+       if (s) return atol(s);
+       return 0;
+}
+
+
+
+/**********************************************************************/
+
+
+
+
+
+
+
+
+
 
 void CtdlGetSysConfigBackend(long msgnum, void *userdata) {
        config_msgnum = msgnum;
@@ -320,7 +502,7 @@ char *CtdlGetSysConfig(char *sysconfname) {
                conf = NULL;
        }
        else {
-               msg = CtdlFetchMessage(msgnum, 1);
+               msg = CtdlFetchMessage(msgnum, 1, 1);
                if (msg != NULL) {
                        conf = strdup(msg->cm_fields[eMesageText]);
                        CM_Free(msg);
index eb61711cc44339b857addc0dbafabeab54f200bf..293593b817a89763489ca1f272892e2c561abea6 100644 (file)
 /*
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "serv_extensions.h"
 #include "citadel_dirs.h"
 
 
-void get_config(void);
+
+/*
+ * This is the format of the legacy config file.  Do not attempt to do anything with it other
+ * than migrate it into the new format. 
+ */
+struct legacy_config {
+       char c_nodename[16];            /* short name of this node on a Citadel network */
+       char c_fqdn[64];                /* this site's fully qualified domain name */
+       char c_humannode[21];           /* human-readable site name */
+       char c_niu_7[16];
+       uid_t c_niu_6;
+       char c_creataide;               /* 1 = creating a room auto-grants room aide privileges */
+       int c_sleeping;                 /* watchdog timer (seconds) */
+       char c_initax;                  /* initial access level for new users */
+       char c_regiscall;               /* after c_regiscall logins user will be asked to register */
+       char c_twitdetect;              /* automatically move messages from problem users to trashcan */
+       char c_twitroom[ROOMNAMELEN];   /* name of trashcan */
+       char c_moreprompt[80];          /* paginator prompt */
+       char c_restrict;                /* require per-user permission to send Internet mail */
+       long c_niu_1;
+       char c_site_location[32];       /* geographic location of this Citadel site */
+       char c_sysadm[26];              /* name of system administrator */
+       char c_niu_2[15];
+       int c_niu_3;
+       int c_maxsessions;              /* maximum number of concurrent sessions allowed */
+       char c_ip_addr[20];             /* bind address for listening sockets */
+       int c_port_number;              /* port number for Citadel protocol (usually 504) */
+       int c_niu_4;
+       struct ExpirePolicy c_ep;       /* default expire policy for the entire site */
+       int c_userpurge;                /* user purge time (in days) */
+       int c_roompurge;                /* room purge time (in days) */
+       char c_logpages[ROOMNAMELEN];
+       char c_createax;
+       long c_maxmsglen;
+       int c_min_workers;
+       int c_max_workers;
+       int c_pop3_port;
+       int c_smtp_port;
+       int c_rfc822_strict_from;
+       int c_aide_zap;
+       int c_imap_port;
+       time_t c_net_freq;
+       char c_disable_newu;
+       char c_enable_fulltext;
+       char c_baseroom[ROOMNAMELEN];
+       char c_aideroom[ROOMNAMELEN];
+       int c_purge_hour;
+       struct ExpirePolicy c_mbxep;
+       char c_ldap_host[128];
+       int c_ldap_port;
+       char c_ldap_base_dn[256];
+       char c_ldap_bind_dn[256];
+       char c_ldap_bind_pw[256];
+       int c_msa_port;
+       int c_imaps_port;
+       int c_pop3s_port;
+       int c_smtps_port;
+       char c_auto_cull;
+       char c_niu_5;
+       char c_allow_spoofing;
+       char c_journal_email;
+       char c_journal_pubmsgs;
+       char c_journal_dest[128];
+       char c_default_cal_zone[128];
+       int c_pftcpdict_port;
+       int c_managesieve_port;
+       int c_auth_mode;
+       char c_funambol_host[256];
+       int c_funambol_port;
+       char c_funambol_source[256];
+       char c_funambol_auth[256];
+       char c_rbl_at_greeting;
+       char c_master_user[32];
+       char c_master_pass[32];
+       char c_pager_program[256];
+       char c_imap_keep_from;
+       int c_xmpp_c2s_port;
+       int c_xmpp_s2s_port;
+       time_t c_pop3_fetch;
+       time_t c_pop3_fastest;
+       int c_spam_flag_only;
+       int c_guest_logins;
+       int c_nntp_port;
+       int c_nntps_port;
+};
+
+
+
+
+void initialize_config_system(void);
+void shutdown_config_system(void);
 void put_config(void);
+void CtdlSetConfigStr(char *, char *);
+char *CtdlGetConfigStr(char *);
+int CtdlGetConfigInt(char *);
+long CtdlGetConfigLong(char *);
+void CtdlSetConfigInt(char *key, int value);
+void CtdlSetConfigLong(char *key, long value);
 
 char *CtdlGetSysConfig(char *sysconfname);
 void CtdlPutSysConfig(char *sysconfname, char *sysconfdata);
index 81b597850b1dbfbe00396ea6119ba1014ed80e3e..576e9359c7da3cc9efeea5b6f6644d8e740f174f 100644 (file)
@@ -2,7 +2,7 @@
  * Citadel context management stuff.
  * Here's where we (hopefully) have all the code that manipulates contexts.
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -22,6 +22,7 @@
 #include "locate_host.h"
 #include "context.h"
 #include "control.h"
+#include "config.h"
 
 int DebugSession = 0;
 
@@ -244,8 +245,8 @@ void terminate_idle_sessions(void)
        for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
                if (
                        (ccptr != CC)
-                       && (config.c_sleeping > 0)
-                       && (now - (ccptr->lastcmd) > config.c_sleeping)
+                       && (CtdlGetConfigLong("c_sleeping") > 0)
+                       && (now - (ccptr->lastcmd) > CtdlGetConfigLong("c_sleeping"))
                ) {
                        if (!ccptr->dont_term) {
                                ccptr->kill_me = KILLME_IDLE;
@@ -514,7 +515,7 @@ void begin_session(CitContext *con)
        *con->fake_hostname = '\0';
        *con->fake_roomname = '\0';
        *con->cs_clientinfo = '\0';
-       safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host);
+       safestrncpy(con->cs_host, CtdlGetConfigStr("c_fqdn"), sizeof con->cs_host);
        safestrncpy(con->cs_addr, "", sizeof con->cs_addr);
        con->cs_UDSclientUID = -1;
        con->cs_host[sizeof con->cs_host - 1] = 0;
@@ -566,7 +567,7 @@ void begin_session(CitContext *con)
        con->dl_is_net = 0;
 
        con->nologin = 0;
-       if (((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions)) || CtdlWantSingleUser()) {
+       if (((CtdlGetConfigInt("c_maxsessions") > 0)&&(num_sessions > CtdlGetConfigInt("c_maxsessions"))) || CtdlWantSingleUser()) {
                con->nologin = 1;
        }
 
index 2a608eee014a24a78887f6a0c9e62c593dc57208..24b643229edca506347d1dbbebf9c9a0e28b8794 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * This module handles states which are global to the entire server.
  *
- * Copyright (c) 1987-2014 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include <stdio.h>
 #include "citserver.h"
 #include "user_ops.h"
 
-struct CitControl CitControl;
-extern struct config config;
-FILE *control_fp = NULL;
 long control_highest_user = 0;
 
-
 /*
- * lock_control  -  acquire a lock on the control record file.
- *                  This keeps multiple citservers from running concurrently.
+ * This is the control record for the message base... 
  */
-void lock_control(void)
-{
-#if defined(LOCK_EX) && defined(LOCK_NB)
-       if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) {
-               syslog(LOG_EMERG, "citserver: unable to lock %s.\n", file_citadel_control);
-               syslog(LOG_EMERG, "Is another citserver already running?\n");
-               exit(CTDLEXIT_CONTROL);
-       }
-#endif
-}
+struct legacy_ctrl_format {
+       long MMhighest;                 /* highest message number in file   */
+       unsigned MMflags;               /* Global system flags              */
+       long MMnextuser;                /* highest user number on system    */
+       long MMnextroom;                /* highest room number on system    */
+       int MM_hosted_upgrade_level;    /* Server-hosted upgrade level      */
+       int MM_fulltext_wordbreaker;    /* ID of wordbreaker in use         */
+       long MMfulltext;                /* highest message number indexed   */
+       int MMdbversion;                /* Version of Berkeley DB used on previous server run */
+};
+
+
 
 /*
  * callback to get highest room number when rebuilding control file
@@ -55,9 +52,9 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data)
        int room_fixed = 0;
        int message_fixed = 0;
        
-       if (qrbuf->QRnumber > CitControl.MMnextroom)
+       if (qrbuf->QRnumber > CtdlGetConfigLong("MMnextroom"))
        {
-               CitControl.MMnextroom = qrbuf->QRnumber;
+               CtdlSetConfigLong("MMnextroom", qrbuf->QRnumber);
                room_fixed = 1;
        }
                
@@ -76,18 +73,20 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data)
        {
                for (c=0; c<num_msgs; c++)
                {
-                       if (msglist[c] > CitControl.MMhighest)
+                       if (msglist[c] > CtdlGetConfigLong("MMhighest"))
                        {
-                               CitControl.MMhighest = msglist[c];
+                               CtdlSetConfigLong("MMhighest", msglist[c]);
                                message_fixed = 1;
                        }
                }
        }
        cdb_free(cdbfr);
-       if (room_fixed)
+       if (room_fixed) {
                syslog(LOG_INFO, "Control record checking....Fixed room counter\n");
-       if (message_fixed)
+       }
+       if (message_fixed) {
                syslog(LOG_INFO, "Control record checking....Fixed message count\n");
+       }
        return;
 }
 
@@ -100,9 +99,9 @@ void control_find_user (struct ctdluser *EachUser, void *out_data)
 {
        int user_fixed = 0;
        
-       if (EachUser->usernum > CitControl.MMnextuser)
+       if (EachUser->usernum > CtdlGetConfigLong("MMnextuser"))
        {
-               CitControl.MMnextuser = EachUser->usernum;
+               CtdlSetConfigLong("MMnextuser", EachUser->usernum);
                user_fixed = 1;
        }
        if(user_fixed)
@@ -111,92 +110,34 @@ void control_find_user (struct ctdluser *EachUser, void *out_data)
 
 
 /*
- * get_control  -  read the control record into memory.
+ * If we have a legacy format control record on disk, import it.
  */
-void get_control(void)
+void migrate_legacy_control_record(void)
 {
-       static int already_have_control = 0;
-       int rv = 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
-        * to zero.
-        */
-       memset(&CitControl, 0, sizeof(struct CitControl));
-       if (control_fp == NULL) {
-               control_fp = fopen(file_citadel_control, "rb+");
-               if (control_fp != NULL) {
-                       lock_control();
-                       rv = fchown(fileno(control_fp), config.c_ctdluid, -1);
-                       if (rv == -1)
-                               syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", 
-                                      file_citadel_control, strerror(errno));
-                       rv = fchmod(fileno(control_fp), S_IRUSR|S_IWUSR);
-                       if (rv == -1)
-                               syslog(LOG_EMERG, "Failed to adjust accessrights of: %s [%s]\n", 
-                                      file_citadel_control, strerror(errno));
-               }
-       }
-       if (control_fp == NULL) {
-               control_fp = fopen(file_citadel_control, "wb+");
-               if (control_fp != NULL) {
-                       lock_control();
-                       memset(&CitControl, 0, sizeof(struct CitControl));
-
-                       rv = fchown(fileno(control_fp), config.c_ctdluid, -1);
-                       if (rv == -1)
-                               syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", 
-                                      file_citadel_control, strerror(errno));
-
-                       rv = fchmod(fileno(control_fp), S_IRUSR|S_IWUSR);
-                       if (rv == -1)
-                               syslog(LOG_EMERG, "Failed to adjust accessrights of: %s [%s]\n", 
-                                      file_citadel_control, strerror(errno));
-                       rv = fwrite(&CitControl, sizeof(struct CitControl), 1, control_fp);
-                       if (rv == -1)
-                               syslog(LOG_EMERG, "Failed to write: %s [%s]\n", 
-                                      file_citadel_control, strerror(errno));
-                       rewind(control_fp);
+       FILE *fp = NULL;
+       struct legacy_ctrl_format c;
+       memset(&c, 0, sizeof(c));
+
+       fp = fopen(file_citadel_control, "rb+");
+       if (fp != NULL) {
+               syslog(LOG_INFO, "Legacy format control record found -- importing to db");
+               fread(&c, sizeof(struct legacy_ctrl_format), 1, fp);
+               
+               CtdlSetConfigLong(      "MMhighest",                    c.MMhighest);
+               CtdlSetConfigInt(       "MMflags",                      c.MMflags);
+               CtdlSetConfigLong(      "MMnextuser",                   c.MMnextuser);
+               CtdlSetConfigLong(      "MMnextroom",                   c.MMnextroom);
+               CtdlSetConfigInt(       "MM_hosted_upgrade_level",      c.MM_hosted_upgrade_level);
+               CtdlSetConfigInt(       "MM_fulltext_wordbreaker",      c.MM_fulltext_wordbreaker);
+               CtdlSetConfigLong(      "MMfulltext",                   c.MMfulltext);
+
+               fclose(fp);
+               if (unlink(file_citadel_control) != 0) {
+                       fprintf(stderr, "Unable to remove legacy control record %s after migrating it.\n", file_citadel_control);
+                       fprintf(stderr, "Exiting to prevent data corruption.\n");
+                       exit(CTDLEXIT_CONFIG);
                }
        }
-       if (control_fp == NULL) {
-               syslog(LOG_ALERT, "ERROR opening %s: %s\n", file_citadel_control, strerror(errno));
-               return;
-       }
-
-       rewind(control_fp);
-       rv = fread(&CitControl, sizeof(struct CitControl), 1, control_fp);
-       if (rv == -1)
-               syslog(LOG_EMERG, "Failed to read Controlfile: %s [%s]\n", 
-                      file_citadel_control, strerror(errno));
-       already_have_control = 1;
-       rv = chown(file_citadel_control, config.c_ctdluid, (-1));
-       if (rv == -1)
-               syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", 
-                      file_citadel_control, strerror(errno));  
-}
-
-/*
- * put_control  -  write the control record to disk.
- */
-void put_control(void)
-{
-       int rv = 0;
-
-       if (control_fp != NULL) {
-               rewind(control_fp);
-               rv = fwrite(&CitControl, sizeof(struct CitControl), 1, control_fp);
-               if (rv == -1)
-                       syslog(LOG_EMERG, "Failed to write: %s [%s]\n", 
-                              file_citadel_control, strerror(errno));
-               fflush(control_fp);
-       }
 }
 
 
@@ -205,25 +146,12 @@ void put_control(void)
  */
 void check_control(void)
 {
-       syslog(LOG_INFO, "Checking/re-building control record\n");
-       get_control();
-       // Find highest room number and message number.
+       syslog(LOG_INFO, "Sanity checking the recorded highest message, user, and room numbers\n");
        CtdlForEachRoom(control_find_highest, NULL);
        ForEachUser(control_find_user, NULL);
-       put_control();
 }
 
 
-/*
- * 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.
@@ -232,9 +160,9 @@ long get_new_message_number(void)
 {
        long retval = 0L;
        begin_critical_section(S_CONTROL);
-       get_control();
-       retval = ++CitControl.MMhighest;
-       put_control();
+       retval = CtdlGetConfigLong("MMhighest");
+       ++retval;
+       CtdlSetConfigLong("MMhighest", retval);
        end_critical_section(S_CONTROL);
        return(retval);
 }
@@ -245,15 +173,12 @@ long get_new_message_number(void)
  * This provides a quick way to initialise a variable that might be used to indicate
  * messages that should not be processed. EG. a new Sieve script will use this
  * to record determine that messages older than this should not be processed.
+ *
+ * (Why is this function here?  Can't we just go straight to the config variable it fetches?)
  */
 long CtdlGetCurrentMessageNumber(void)
 {
-       long retval = 0L;
-       begin_critical_section(S_CONTROL);
-       get_control();
-       retval = CitControl.MMhighest;
-       end_critical_section(S_CONTROL);
-       return(retval);
+       return CtdlGetConfigLong("MMhighest");
 }
 
 
@@ -264,9 +189,9 @@ long get_new_user_number(void)
 {
        long retval = 0L;
        begin_critical_section(S_CONTROL);
-       get_control();
-       retval = ++CitControl.MMnextuser;
-       put_control();
+       retval = CtdlGetConfigLong("MMnextuser");
+       ++retval;
+       CtdlSetConfigLong("MMnextuser", retval);
        end_critical_section(S_CONTROL);
        return(retval);
 }
@@ -280,73 +205,87 @@ long get_new_room_number(void)
 {
        long retval = 0L;
        begin_critical_section(S_CONTROL);
-       get_control();
-       retval = ++CitControl.MMnextroom;
-       put_control();
+       retval = CtdlGetConfigLong("MMnextroom");
+       ++retval;
+       CtdlSetConfigLong("MMnextroom", retval);
        end_critical_section(S_CONTROL);
        return(retval);
 }
 
 
 
+/*
+ * Helper function for cmd_conf() to handle boolean values
+ */
+int confbool(char *v)
+{
+       if (IsEmptyStr(v)) return(0);
+       if (atoi(v) != 0) return(1);
+       return(0);
+}
+
+
 /* 
  * Get or set global configuration options
  *
  * IF YOU ADD OR CHANGE FIELDS HERE, YOU *MUST* DOCUMENT YOUR CHANGES AT:
- * http://www.citadel.org/doku.php?id=documentation:applicationprotocol
+ * http://www.citadel.org/doku.php/documentation:appproto:system_config
  *
  */
 void cmd_conf(char *argbuf)
 {
        char cmd[16];
-       char buf[256];
-       int a;
+       char buf[1024];
+       int a, i;
+       long ii;
        char *confptr;
        char confname[128];
 
        if (CtdlAccessCheck(ac_aide)) return;
 
        extract_token(cmd, argbuf, 0, '|', sizeof cmd);
+
+       // CONF GET - retrieve system configuration in legacy format (deprecated)
        if (!strcasecmp(cmd, "GET")) {
                cprintf("%d Configuration...\n", LISTING_FOLLOWS);
-               cprintf("%s\n", config.c_nodename);
-               cprintf("%s\n", config.c_fqdn);
-               cprintf("%s\n", config.c_humannode);
-               cprintf("%s\n", config.c_phonenum);
-               cprintf("%d\n", config.c_creataide);
-               cprintf("%d\n", config.c_sleeping);
-               cprintf("%d\n", config.c_initax);
-               cprintf("%d\n", config.c_regiscall);
-               cprintf("%d\n", config.c_twitdetect);
-               cprintf("%s\n", config.c_twitroom);
-               cprintf("%s\n", config.c_moreprompt);
-               cprintf("%d\n", config.c_restrict);
-               cprintf("%s\n", config.c_site_location);
-               cprintf("%s\n", config.c_sysadm);
-               cprintf("%d\n", config.c_maxsessions);
+               cprintf("%s\n",         CtdlGetConfigStr("c_nodename"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_fqdn"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_humannode"));
                cprintf("xxx\n"); /* placeholder -- field no longer in use */
-               cprintf("%d\n", config.c_userpurge);
-               cprintf("%d\n", config.c_roompurge);
-               cprintf("%s\n", config.c_logpages);
-               cprintf("%d\n", config.c_createax);
-               cprintf("%ld\n", config.c_maxmsglen);
-               cprintf("%d\n", config.c_min_workers);
-               cprintf("%d\n", config.c_max_workers);
-               cprintf("%d\n", config.c_pop3_port);
-               cprintf("%d\n", config.c_smtp_port);
-               cprintf("%d\n", config.c_rfc822_strict_from);
-               cprintf("%d\n", config.c_aide_zap);
-               cprintf("%d\n", config.c_imap_port);
-               cprintf("%ld\n", config.c_net_freq);
-               cprintf("%d\n", config.c_disable_newu);
+               cprintf("%d\n",         CtdlGetConfigInt("c_creataide"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_sleeping"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_initax"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_regiscall"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_twitdetect"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_twitroom"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_moreprompt"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_restrict"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_site_location"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_sysadm"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_maxsessions"));
+               cprintf("xxx\n"); /* placeholder -- field no longer in use */
+               cprintf("%d\n",         CtdlGetConfigInt("c_userpurge"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_roompurge"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_logpages"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_createax"));
+               cprintf("%ld\n",        CtdlGetConfigLong("c_maxmsglen"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_min_workers"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_max_workers"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_pop3_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_smtp_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_rfc822_strict_from"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_aide_zap"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_imap_port"));
+               cprintf("%ld\n",        CtdlGetConfigLong("c_net_freq"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_disable_newu"));
                cprintf("1\n"); /* niu */
-               cprintf("%d\n", config.c_purge_hour);
+               cprintf("%d\n",         CtdlGetConfigInt("c_purge_hour"));
 #ifdef HAVE_LDAP
-               cprintf("%s\n", config.c_ldap_host);
-               cprintf("%d\n", config.c_ldap_port);
-               cprintf("%s\n", config.c_ldap_base_dn);
-               cprintf("%s\n", config.c_ldap_bind_dn);
-               cprintf("%s\n", config.c_ldap_bind_pw);
+               cprintf("%s\n",         CtdlGetConfigStr("c_ldap_host"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_ldap_port"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_ldap_base_dn"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_ldap_bind_dn"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_ldap_bind_pw"));
 #else
                cprintf("\n");
                cprintf("0\n");
@@ -354,44 +293,45 @@ void cmd_conf(char *argbuf)
                cprintf("\n");
                cprintf("\n");
 #endif
-               cprintf("%s\n", config.c_ip_addr);
-               cprintf("%d\n", config.c_msa_port);
-               cprintf("%d\n", config.c_imaps_port);
-               cprintf("%d\n", config.c_pop3s_port);
-               cprintf("%d\n", config.c_smtps_port);
-               cprintf("%d\n", config.c_enable_fulltext);
-               cprintf("%d\n", config.c_auto_cull);
+               cprintf("%s\n",         CtdlGetConfigStr("c_ip_addr"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_msa_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_imaps_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_pop3s_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_smtps_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_enable_fulltext"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_auto_cull"));
                cprintf("1\n");
-               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("%s\n", config.c_master_user);
-               cprintf("%s\n", config.c_master_pass);
-               cprintf("%s\n", config.c_pager_program);
-               cprintf("%d\n", config.c_imap_keep_from);
-               cprintf("%d\n", config.c_xmpp_c2s_port);
-               cprintf("%d\n", config.c_xmpp_s2s_port);
-               cprintf("%ld\n", config.c_pop3_fetch);
-               cprintf("%ld\n", config.c_pop3_fastest);
-               cprintf("%d\n", config.c_spam_flag_only);
-               cprintf("%d\n", config.c_guest_logins);
-               cprintf("%d\n", config.c_port_number);
-               cprintf("%d\n", config.c_ctdluid);
-               cprintf("%d\n", config.c_nntp_port);
-               cprintf("%d\n", config.c_nntps_port);
+               cprintf("%d\n",         CtdlGetConfigInt("c_allow_spoofing"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_journal_email"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_journal_pubmsgs"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_journal_dest"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_default_cal_zone"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_pftcpdict_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_managesieve_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_auth_mode"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_funambol_host"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_funambol_port"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_funambol_source"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_funambol_auth"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_rbl_at_greeting"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_master_user"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_master_pass"));
+               cprintf("%s\n",         CtdlGetConfigStr("c_pager_program"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_imap_keep_from"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_xmpp_c2s_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_xmpp_s2s_port"));
+               cprintf("%ld\n",        CtdlGetConfigLong("c_pop3_fetch"));
+               cprintf("%ld\n",        CtdlGetConfigLong("c_pop3_fastest"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_spam_flag_only"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_guest_logins"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_port_number"));
+               cprintf("%d\n",         ctdluid);
+               cprintf("%d\n",         CtdlGetConfigInt("c_nntp_port"));
+               cprintf("%d\n",         CtdlGetConfigInt("c_nntps_port"));
                cprintf("000\n");
        }
 
+       // CONF SET - set system configuration in legacy format (really deprecated)
        else if (!strcasecmp(cmd, "SET")) {
                unbuffer_output();
                cprintf("%d Send configuration...\n", SEND_LISTING);
@@ -399,294 +339,262 @@ void cmd_conf(char *argbuf)
                while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) {
                        switch (a) {
                        case 0:
-                               configlen.c_nodename = safestrncpy(config.c_nodename, buf,
-                                                                  sizeof config.c_nodename);
+                               CtdlSetConfigStr("c_nodename", buf);
                                break;
                        case 1:
-                               configlen.c_fqdn = safestrncpy(config.c_fqdn, buf,
-                                                              sizeof config.c_fqdn);
+                               CtdlSetConfigStr("c_fqdn", buf);
                                break;
                        case 2:
-                               configlen.c_humannode = safestrncpy(config.c_humannode, buf,
-                                                                   sizeof config.c_humannode);
+                               CtdlSetConfigStr("c_humannode", buf);
                                break;
                        case 3:
-                               configlen.c_phonenum = safestrncpy(config.c_phonenum, buf,
-                                                                  sizeof config.c_phonenum);
+                               /* placeholder -- field no longer in use */
                                break;
                        case 4:
-                               config.c_creataide = atoi(buf);
+                               CtdlSetConfigInt("c_creataide", atoi(buf));
                                break;
                        case 5:
-                               config.c_sleeping = atoi(buf);
+                               CtdlSetConfigInt("c_sleeping", atoi(buf));
                                break;
                        case 6:
-                               config.c_initax = atoi(buf);
-                               if (config.c_initax < 1)
-                                       config.c_initax = 1;
-                               if (config.c_initax > 6)
-                                       config.c_initax = 6;
+                               i = atoi(buf);
+                               if (i < 1) i = 1;
+                               if (i > 6) i = 6;
+                               CtdlSetConfigInt("c_initax", i);
                                break;
                        case 7:
-                               config.c_regiscall = atoi(buf);
-                               if (config.c_regiscall != 0)
-                                       config.c_regiscall = 1;
+                               CtdlSetConfigInt("c_regiscall", confbool(buf));
                                break;
                        case 8:
-                               config.c_twitdetect = atoi(buf);
-                               if (config.c_twitdetect != 0)
-                                       config.c_twitdetect = 1;
+                               CtdlSetConfigInt("c_twitdetect", confbool(buf));
                                break;
                        case 9:
-                               configlen.c_twitroom = safestrncpy(config.c_twitroom, buf,
-                                                                  sizeof config.c_twitroom);
+                               CtdlSetConfigStr("c_twitroom", buf);
                                break;
                        case 10:
-                               configlen.c_moreprompt = safestrncpy(config.c_moreprompt, buf,
-                                                                    sizeof config.c_moreprompt);
+                               CtdlSetConfigStr("c_moreprompt", buf);
                                break;
                        case 11:
-                               config.c_restrict = atoi(buf);
-                               if (config.c_restrict != 0)
-                                       config.c_restrict = 1;
+                               CtdlSetConfigInt("c_restrict", confbool(buf));
                                break;
                        case 12:
-                               configlen.c_site_location = safestrncpy(
-                                       config.c_site_location, buf,
-                                       sizeof config.c_site_location);
+                               CtdlSetConfigInt("c_site_location", confbool(buf));
                                break;
                        case 13:
-                               configlen.c_sysadm = safestrncpy(config.c_sysadm, buf,
-                                                                sizeof config.c_sysadm);
+                               CtdlSetConfigInt("c_sysadm", confbool(buf));
                                break;
                        case 14:
-                               config.c_maxsessions = atoi(buf);
-                               if (config.c_maxsessions < 0)
-                                       config.c_maxsessions = 0;
+                               i = atoi(buf);
+                               if (i < 0) i = 0;
+                               CtdlSetConfigInt("c_maxsessions", i);
                                break;
                        case 15:
                                /* placeholder -- field no longer in use */
                                break;
                        case 16:
-                               config.c_userpurge = atoi(buf);
+                               CtdlSetConfigInt("c_userpurge", atoi(buf));
                                break;
                        case 17:
-                               config.c_roompurge = atoi(buf);
+                               CtdlSetConfigInt("c_roompurge", atoi(buf));
                                break;
                        case 18:
-                               configlen.c_logpages = safestrncpy(config.c_logpages, buf,
-                                                                  sizeof config.c_logpages);
+                               CtdlSetConfigStr("c_logpages", buf);
                                break;
                        case 19:
-                               config.c_createax = atoi(buf);
-                               if (config.c_createax < 1)
-                                       config.c_createax = 1;
-                               if (config.c_createax > 6)
-                                       config.c_createax = 6;
+                               i = atoi(buf);
+                               if (i < 1) i = 1;
+                               if (i > 6) i = 6;
+                               CtdlSetConfigInt("c_createax", i);
                                break;
                        case 20:
-                               if (atoi(buf) >= 8192)
-                                       config.c_maxmsglen = atoi(buf);
+                               ii = atol(buf);
+                               if (ii >= 8192) {
+                                       CtdlSetConfigLong("c_maxmsglen", ii);
+                               }
                                break;
                        case 21:
-                               if (atoi(buf) >= 2)
-                                       config.c_min_workers = atoi(buf);
+                               i = atoi(buf);
+                               if (i >= 3) {                                   // minimum value
+                                       CtdlSetConfigInt("c_min_workers", i);
+                               }
+                               break;
                        case 22:
-                               if (atoi(buf) >= config.c_min_workers)
-                                       config.c_max_workers = atoi(buf);
+                               i = atoi(buf);
+                               if (i >= CtdlGetConfigInt("c_min_workers")) {   // max must be >= min
+                                       CtdlSetConfigInt("c_max_workers", i);
+                               }
+                               break;
                        case 23:
-                               config.c_pop3_port = atoi(buf);
+                               CtdlSetConfigInt("c_pop3_port", atoi(buf));
                                break;
                        case 24:
-                               config.c_smtp_port = atoi(buf);
+                               CtdlSetConfigInt("c_smtp_port", atoi(buf));
                                break;
                        case 25:
-                               config.c_rfc822_strict_from = atoi(buf);
+                               CtdlSetConfigInt("c_rfc822_strict_from", atoi(buf));
                                break;
                        case 26:
-                               config.c_aide_zap = atoi(buf);
-                               if (config.c_aide_zap != 0)
-                                       config.c_aide_zap = 1;
+                               CtdlSetConfigInt("c_aide_zap", confbool(buf));
                                break;
                        case 27:
-                               config.c_imap_port = atoi(buf);
+                               CtdlSetConfigInt("c_imap_port", atoi(buf));
                                break;
                        case 28:
-                               config.c_net_freq = atol(buf);
+                               CtdlSetConfigLong("c_net_freq", atol(buf));
                                break;
                        case 29:
-                               config.c_disable_newu = atoi(buf);
-                               if (config.c_disable_newu != 0)
-                                       config.c_disable_newu = 1;
+                               CtdlSetConfigInt("c_disable_newu", confbool(buf));
                                break;
                        case 30:
                                /* niu */
                                break;
                        case 31:
-                               if ((config.c_purge_hour >= 0)
-                                   && (config.c_purge_hour <= 23)) {
-                                       config.c_purge_hour = atoi(buf);
+                               i = atoi(buf);
+                               if ((i >= 0) && (i <= 23)) {
+                                       CtdlSetConfigInt("c_purge_hour", i);
                                }
                                break;
-#ifdef HAVE_LDAP
                        case 32:
-                               configlen.c_ldap_host = safestrncpy(config.c_ldap_host, buf,
-                                                                   sizeof config.c_ldap_host);
+                               CtdlSetConfigStr("c_ldap_host", buf);
                                break;
                        case 33:
-                               config.c_ldap_port = atoi(buf);
+                               CtdlSetConfigInt("c_ldap_port", atoi(buf));
                                break;
                        case 34:
-                               configlen.c_ldap_base_dn = safestrncpy(config.c_ldap_base_dn, buf,
-                                                                      sizeof config.c_ldap_base_dn);
+                               CtdlSetConfigStr("c_ldap_base_dn", buf);
                                break;
                        case 35:
-                               configlen.c_ldap_bind_dn = safestrncpy(config.c_ldap_bind_dn, buf,
-                                                                      sizeof config.c_ldap_bind_dn);
+                               CtdlSetConfigStr("c_ldap_bind_dn", buf);
                                break;
                        case 36:
-                               configlen.c_ldap_bind_pw = safestrncpy(config.c_ldap_bind_pw, buf,
-                                                                      sizeof config.c_ldap_bind_pw);
+                               CtdlSetConfigStr("c_ldap_bind_pw", buf);
                                break;
-#endif
                        case 37:
-                               configlen.c_ip_addr = safestrncpy(config.c_ip_addr, buf,
-                                                                 sizeof config.c_ip_addr);
+                               CtdlSetConfigStr("c_ip_addr", buf);
+                               break;
                        case 38:
-                               config.c_msa_port = atoi(buf);
+                               CtdlSetConfigInt("c_msa_port", atoi(buf));
                                break;
                        case 39:
-                               config.c_imaps_port = atoi(buf);
+                               CtdlSetConfigInt("c_imaps_port", atoi(buf));
                                break;
                        case 40:
-                               config.c_pop3s_port = atoi(buf);
+                               CtdlSetConfigInt("c_pop3s_port", atoi(buf));
                                break;
                        case 41:
-                               config.c_smtps_port = atoi(buf);
+                               CtdlSetConfigInt("c_smtps_port", atoi(buf));
                                break;
                        case 42:
-                               config.c_enable_fulltext = atoi(buf);
+                               CtdlSetConfigInt("c_enable_fulltext", confbool(buf));
                                break;
                        case 43:
-                               config.c_auto_cull = atoi(buf);
+                               CtdlSetConfigInt("c_auto_cull", confbool(buf));
                                break;
                        case 44:
                                /* niu */
                                break;
                        case 45:
-                               config.c_allow_spoofing = atoi(buf);
+                               CtdlSetConfigInt("c_allow_spoofing", confbool(buf));
                                break;
                        case 46:
-                               config.c_journal_email = atoi(buf);
+                               CtdlSetConfigInt("c_journal_email", confbool(buf));
                                break;
                        case 47:
-                               config.c_journal_pubmsgs = atoi(buf);
+                               CtdlSetConfigInt("c_journal_pubmsgs", confbool(buf));
                                break;
                        case 48:
-                               configlen.c_journal_dest = safestrncpy(config.c_journal_dest, buf,
-                                                                      sizeof config.c_journal_dest);
+                               CtdlSetConfigStr("c_journal_dest", buf);
+                               break;
                        case 49:
-                               configlen.c_default_cal_zone = safestrncpy(
-                                       config.c_default_cal_zone, buf,
-                                       sizeof config.c_default_cal_zone);
+                               CtdlSetConfigStr("c_default_cal_zone", buf);
                                break;
                        case 50:
-                               config.c_pftcpdict_port = atoi(buf);
+                               CtdlSetConfigInt("c_pftcpdict_port", atoi(buf));
                                break;
                        case 51:
-                               config.c_managesieve_port = atoi(buf);
+                               CtdlSetConfigInt("c_managesieve_port", atoi(buf));
                                break;
                        case 52:
-                               config.c_auth_mode = atoi(buf);
+                               CtdlSetConfigInt("c_auth_mode", atoi(buf));
+                               break;
                        case 53:
-                               configlen.c_funambol_host = safestrncpy(
-                                       config.c_funambol_host, buf,
-                                       sizeof config.c_funambol_host);
+                               CtdlSetConfigStr("c_funambol_host", buf);
                                break;
                        case 54:
-                               config.c_funambol_port = atoi(buf);
+                               CtdlSetConfigInt("c_funambol_port", atoi(buf));
                                break;
                        case 55:
-                               configlen.c_funambol_source = safestrncpy(
-                                       config.c_funambol_source, buf, 
-                                       sizeof config.c_funambol_source);
+                               CtdlSetConfigStr("c_funambol_source", buf);
                                break;
                        case 56:
-                               configlen.c_funambol_auth = safestrncpy(
-                                       config.c_funambol_auth, buf,
-                                       sizeof config.c_funambol_auth);
+                               CtdlSetConfigStr("c_funambol_auth", buf);
                                break;
                        case 57:
-                               config.c_rbl_at_greeting = atoi(buf);
+                               CtdlSetConfigInt("c_rbl_at_greeting", confbool(buf));
                                break;
                        case 58:
-                               configlen.c_master_user = safestrncpy(
-                                       config.c_master_user,
-                                       buf, sizeof config.c_master_user);
+                               CtdlSetConfigStr("c_master_user", buf);
                                break;
                        case 59:
-                               configlen.c_master_pass = safestrncpy(
-                                       config.c_master_pass, buf, sizeof config.c_master_pass);
+                               CtdlSetConfigStr("c_master_pass", buf);
                                break;
                        case 60:
-                               configlen.c_pager_program = safestrncpy(
-                                       config.c_pager_program, buf, sizeof config.c_pager_program);
+                               CtdlSetConfigStr("c_pager_program", buf);
                                break;
                        case 61:
-                               config.c_imap_keep_from = atoi(buf);
+                               CtdlSetConfigInt("c_imap_keep_from", confbool(buf));
                                break;
                        case 62:
-                               config.c_xmpp_c2s_port = atoi(buf);
+                               CtdlSetConfigInt("c_xmpp_c2s_port", atoi(buf));
                                break;
                        case 63:
-                               config.c_xmpp_s2s_port = atoi(buf);
+                               CtdlSetConfigInt("c_xmpp_s2s_port", atoi(buf));
                                break;
                        case 64:
-                               config.c_pop3_fetch = atol(buf);
+                               CtdlSetConfigLong("c_pop3_fetch", atol(buf));
                                break;
                        case 65:
-                               config.c_pop3_fastest = atol(buf);
+                               CtdlSetConfigLong("c_pop3_fastest", atol(buf));
                                break;
                        case 66:
-                               config.c_spam_flag_only = atoi(buf);
+                               CtdlSetConfigInt("c_spam_flag_only", confbool(buf));
                                break;
                        case 67:
-                               config.c_guest_logins = atoi(buf);
+                               CtdlSetConfigInt("c_guest_logins", confbool(buf));
                                break;
                        case 68:
-                               config.c_port_number = atoi(buf);
+                               CtdlSetConfigInt("c_port_number", atoi(buf));
                                break;
                        case 69:
-                               config.c_ctdluid = atoi(buf);
+                               /* niu */
                                break;
                        case 70:
-                               config.c_nntp_port = atoi(buf);
+                               CtdlSetConfigInt("c_nntp_port", atoi(buf));
                                break;
                        case 71:
-                               config.c_nntps_port = atoi(buf);
+                               CtdlSetConfigInt("c_nntps_port", atoi(buf));
                                break;
                        }
                        ++a;
                }
-               put_config();
                snprintf(buf, sizeof buf,
                        "The global system configuration has been edited by %s.\n",
                         (CC->logged_in ? CC->curr_user : "an administrator")
                );
                CtdlAideMessage(buf,"Citadel Configuration Manager Message");
 
-               if (!IsEmptyStr(config.c_logpages))
-                       CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);
+               if (!IsEmptyStr(CtdlGetConfigStr("c_logpages")))
+                       CtdlCreateRoom(CtdlGetConfigStr("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) {
-                       CitControl.fulltext_wordbreaker = 0;
-                       put_control();
+               if (CtdlGetConfigInt("c_enable_fulltext") == 0) {
+                       CtdlSetConfigInt("MM_fulltext_wordbreaker", 0);
                }
        }
 
+       // CONF GETSYS - retrieve arbitrary system configuration stanzas stored in the message base
        else if (!strcasecmp(cmd, "GETSYS")) {
                extract_token(confname, argbuf, 1, '|', sizeof confname);
                confptr = CtdlGetSysConfig(confname);
@@ -706,18 +614,41 @@ void cmd_conf(char *argbuf)
                }
        }
 
+       // CONF PUTSYS - store arbitrary system configuration stanzas in the message base
        else if (!strcasecmp(cmd, "PUTSYS")) {
                extract_token(confname, argbuf, 1, '|', sizeof confname);
                unbuffer_output();
                cprintf("%d %s\n", SEND_LISTING, confname);
-               confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+               confptr = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0);
                CtdlPutSysConfig(confname, confptr);
                free(confptr);
        }
 
+       else if (!strcasecmp(cmd, "GETVAL")) {
+               extract_token(confname, argbuf, 1, '|', sizeof confname);
+               char *v = CtdlGetConfigStr(confname);
+               if (v) {
+                       cprintf("%d|%s|\n", CIT_OK, v);
+               }
+               else {
+                       cprintf("%d||\n", ERROR);
+               }
+       }
+
+       else if (!strcasecmp(cmd, "PUTVAL")) {
+               if (num_tokens(argbuf, '|') < 3) {
+                       cprintf("%d name and value required\n", ERROR);
+               }
+               else {
+                       extract_token(confname, argbuf, 1, '|', sizeof confname);
+                       extract_token(buf, argbuf, 2, '|', sizeof buf);
+                       CtdlSetConfigStr(confname, buf);
+                       cprintf("%d setting '%s' to '%s'\n", CIT_OK, confname, buf);
+               }
+       }
+
        else {
-               cprintf("%d Illegal option(s) specified.\n",
-                       ERROR + ILLEGAL_VALUE);
+               cprintf("%d Illegal option(s) specified.\n", ERROR + ILLEGAL_VALUE);
        }
 }
 
@@ -758,7 +689,7 @@ void cmd_gvdn(char *argbuf)
        void *vptr;
        
        List = NewHash(1, NULL);
-       Cfg = NewStrBufPlain(config.c_fqdn, -1);
+       Cfg = NewStrBufPlain(CtdlGetConfigStr("c_fqdn"), -1);
        Put(List, SKEY(Cfg), Cfg, HFreeStrBuf);
        Cfg = NULL;
 
index fa93bc03be306564667adc38101b29a7f0a02440..649d3fd85c1937ce79a5658d88be25d2d2c96c59 100644 (file)
@@ -1,19 +1,19 @@
 /*
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 void get_control (void);
 void put_control (void);
-void release_control(void);
 void check_control(void);
 long int get_new_message_number (void);
 long int get_new_user_number (void);
 long int get_new_room_number (void);
+void migrate_legacy_control_record(void);
index e89783f69faab825970c15a8258ee7b3ec2e8ea7..de1be0d2ca34666e5e9a53c308262353eafb3e56 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This is a data store backend for the Citadel server which uses Berkeley DB.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 3.
@@ -50,6 +50,7 @@
 #include "ctdl_module.h"
 #include "control.h"
 #include "citserver.h"
+#include "config.h"
 
 
 static DB *dbp[MAXCDB];                /* One DB handle for each Citadel database */
@@ -223,7 +224,7 @@ void cdb_checkpoint(void)
        }
 
        /* After a successful checkpoint, we can cull the unused logs */
-       if (config.c_auto_cull) {
+       if (CtdlGetConfigInt("c_auto_cull")) {
                cdb_cull_logs();
        }
 }
@@ -243,30 +244,10 @@ void open_databases(void)
        char dbfilename[32];
        u_int32_t flags = 0;
        int dbversion_major, dbversion_minor, dbversion_patch;
-       int current_dbversion = 0;
 
        syslog(LOG_DEBUG, "bdb(): open_databases() starting");
        syslog(LOG_DEBUG, "Compiled db: %s", DB_VERSION_STRING);
-       syslog(LOG_INFO, "  Linked db: %s",
-               db_version(&dbversion_major, &dbversion_minor, &dbversion_patch));
-
-       current_dbversion = (dbversion_major * 1000000) + (dbversion_minor * 1000) + dbversion_patch;
-
-       syslog(LOG_DEBUG, "Calculated dbversion: %d", current_dbversion);
-       syslog(LOG_DEBUG, "  Previous dbversion: %d", CitControl.MMdbversion);
-
-       if ( (getenv("SUPPRESS_DBVERSION_CHECK") == NULL)
-          && (CitControl.MMdbversion > current_dbversion) ) {
-               syslog(LOG_EMERG, "You are attempting to run the Citadel server using a version");
-               syslog(LOG_EMERG, "of Berkeley DB that is older than that which last created or");
-               syslog(LOG_EMERG, "updated the database.  Because this would probably cause data");
-               syslog(LOG_EMERG, "corruption or loss, the server is aborting execution now.");
-               exit(CTDLEXIT_DB);
-       }
-
-       CitControl.MMdbversion = current_dbversion;
-       put_control();
-
+       syslog(LOG_INFO, "  Linked db: %s", db_version(&dbversion_major, &dbversion_minor, &dbversion_patch));
        syslog(LOG_INFO, "Linked zlib: %s\n", zlibVersion());
 
        /*
@@ -935,8 +916,10 @@ time_t CheckIfAlreadySeen(const char *Facility,
                else
                {
                        if (cdbut) cdb_free(cdbut);
-
+                       
                        SEENM_syslog(LOG_DEBUG, "not Found");
+                       if (cType == eCheckUpdate)
+                               return 0;
                }
 
                if (cType == eCheckExist)
index 7b3b844b90b9b25d16b2d9c58addab941981b88f..e7acb31fbd9b44398a930a4c4a12fa069c1780f0 100644 (file)
@@ -54,10 +54,10 @@ struct CtdlCompressHeader {
 };
 
 typedef enum __eCheckType {
-       eCheckExist,
-       eCheckUpdate,
-       eUpdate,
-       eWrite
+       eCheckExist,   /* look up the item, return the timestamp if its there, 0 if not. */
+       eCheckUpdate,  /* if it exists, refresh in db timestamp. return the timstamp if its there, 0 if not. */
+       eUpdate,       /* insert/update the new value, return the old if its there, 0 if not. */
+       eWrite         /* write this to DB, unconditional. */
 }eCheckType;
 
 time_t CheckIfAlreadySeen(const char *Facility,
index aa41d50dcc8c0149a16e810683a56e4ae3dbd9b0..770c37c1a056bbd710731611f8385538a3ddfaa6 100644 (file)
@@ -127,7 +127,7 @@ void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) {
 void rebuild_euid_index_for_msg(long msgnum, void *userdata) {
        struct CtdlMessage *msg = NULL;
 
-       msg = CtdlFetchMessage(msgnum, 0);
+       msg = CtdlFetchMessage(msgnum, 0, 1);
        if (msg == NULL) return;
        if (!CM_IsEmpty(msg, eExclusiveID)) {
                index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgnum);
index 999c9e4546c1b989efc6fb93c6f6ab8df8394b8f..fad9eefeccaa5dea30651ba65cc482a1baa19d65 100644 (file)
@@ -27,6 +27,7 @@
 #include "ctdl_module.h"
 #include "event_client.h"
 #include "citserver.h"
+#include "config.h"
 
 ConstStr IOStates[] = {
        {HKEY("DB Queue")},
@@ -156,7 +157,7 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eDBNext);
-       IO->Now = ev_now(event_db);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_db);
        EV_syslog(LOG_DEBUG, "%s()", __FUNCTION__);
        become_session(IO->CitContext);
 
@@ -220,7 +221,7 @@ static void IO_abort_shutdown_callback(struct ev_loop *loop,
 
        SetEVState(IO, eIOAbort);
        EV_syslog(LOG_DEBUG, "EVENT Q: %s\n", __FUNCTION__);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        assert(IO->ShutdownAbort);
        IO->ShutdownAbort(IO);
 }
@@ -543,7 +544,7 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        AsyncIO *IO = watcher->data;
        const char *errmsg = NULL;
 
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        become_session(IO->CitContext);
 #ifdef BIGBAD_IODBG
        {
@@ -720,7 +721,7 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOTimeout);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        ev_timer_stop (event_base, &IO->rw_timeout);
        become_session(IO->CitContext);
 
@@ -749,7 +750,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOConnfail);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        ev_timer_stop (event_base, &IO->conn_fail);
 
        if (IO->SendBuf.fd != 0)
@@ -782,7 +783,7 @@ IO_connfailimmediate_callback(struct ev_loop *loop,
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOConnfailNow);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        ev_idle_stop (event_base, &IO->conn_fail_immediate);
 
        if (IO->SendBuf.fd != 0)
@@ -812,7 +813,7 @@ IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
         int             err;
 
        SetEVState(IO, eIOConnNow);
-        IO->Now = ev_now(event_base);
+        IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
         EVM_syslog(LOG_DEBUG, "connect() succeeded.\n");
 
         ev_io_stop(loop, &IO->conn_event);
@@ -846,7 +847,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        ssize_t nbytes;
        AsyncIO *IO = watcher->data;
 
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        switch (IO->NextState) {
        case eReadFile:
                nbytes = FileRecvChunked(&IO->IOB, &errmsg);
@@ -932,7 +933,7 @@ IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eCaresFinished);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        EV_syslog(LOG_DEBUG, "event: %s\n", __FUNCTION__);
        become_session(IO->CitContext);
        assert(IO->DNS.Query->PostDNS);
@@ -1059,8 +1060,8 @@ eNextState EvConnectSock(AsyncIO *IO,
        
                memset(&egress_sin, 0, sizeof(egress_sin));
                egress_sin.sin_family = AF_INET;
-               if (!IsEmptyStr(config.c_ip_addr)) {
-                       egress_sin.sin_addr.s_addr = inet_addr(config.c_ip_addr);
+               if (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) {
+                       egress_sin.sin_addr.s_addr = inet_addr(CtdlGetConfigStr("c_ip_addr"));
                        if (egress_sin.sin_addr.s_addr == !INADDR_ANY) {
                                egress_sin.sin_addr.s_addr = INADDR_ANY;
                        }
index 11be04e0092133b4cbee41498bce0abfe67cec04..92336277733acaaeaab8a0bd9145dfeea0cf7ee6 100644 (file)
@@ -129,3 +129,60 @@ void do_housekeeping(void) {
        housekeeping_in_progress = 0;
        end_critical_section(S_HOUSEKEEPING);
 }
+
+void CtdlDisableHouseKeeping(void)
+{
+       int ActiveBackgroundJobs;
+       int do_housekeeping_now = 0;
+       struct CitContext *nptr;
+       int nContexts, i;
+
+retry_block_housekeeping:
+       syslog(LOG_INFO, "trying to disable housekeeping services");
+       begin_critical_section(S_HOUSEKEEPING);
+       if (housekeeping_in_progress == 0) {
+               do_housekeeping_now = 1;
+               housekeeping_in_progress = 1;
+       }
+       end_critical_section(S_HOUSEKEEPING);
+       if (do_housekeeping_now == 0) {
+               usleep(1000000);
+               goto retry_block_housekeeping;
+       }
+       
+       syslog(LOG_INFO, "checking for running server Jobs");
+
+retry_wait_for_contexts:
+       /* So that we don't keep the context list locked for a long time
+        * we create a copy of it first
+        */
+       ActiveBackgroundJobs = 0;
+       nptr = CtdlGetContextArray(&nContexts) ;
+       if (nptr)
+       {
+               for (i=0; i<nContexts; i++) 
+               {
+                       if ((nptr[i].state != CON_SYS) || (nptr[i].IO == NULL) || (nptr[i].lastcmd == 0))
+                               continue;
+                       ActiveBackgroundJobs ++;
+                       syslog(LOG_INFO, "Job CC[%d] active; use TERM if you don't want to wait for it",nptr[i].cs_pid);
+               
+               }
+       
+               free(nptr);
+
+       }
+       if (ActiveBackgroundJobs != 0) {
+               syslog(LOG_INFO, "found %d running jobs, need to wait", ActiveBackgroundJobs);
+               usleep(5000000);
+               goto retry_wait_for_contexts;
+       }
+       syslog(LOG_INFO, "Housekeeping disabled now.");
+}
+
+void CtdlEnableHouseKeeping(void)
+{
+       begin_critical_section(S_HOUSEKEEPING);
+       housekeeping_in_progress = 0;
+       end_critical_section(S_HOUSEKEEPING);
+}
index 41c67a7e7556261649db1aac46e37e2b7f7e6d6e..cc3c60efc1b5d9ce3f1aae23ab5d4d7114425b30 100644 (file)
@@ -34,8 +34,7 @@
 icaltimezone *get_default_icaltimezone(void) {
 
         icaltimezone *zone = NULL;
-       char *default_zone_name = config.c_default_cal_zone;
-       //char *default_zone_name = "America/New_York";
+       char *default_zone_name = CtdlGetConfigStr("c_default_cal_zone");
 
         if (!zone) {
                 zone = icaltimezone_get_builtin_timezone(default_zone_name);
index 86255e2f304a410ed020e01ba689484b9a188b7d..17f88fc654177a9e0a12c72f7e7525439f7dc7fa 100644 (file)
@@ -168,6 +168,12 @@ void CtdlRegisterMaintenanceThread(char *name, void *(*thread_proc) (void *arg))
 
 void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name);
 
+/*
+ * if you say a) (which may take a while)
+ * don't forget to say b)
+ */
+void CtdlDisableHouseKeeping(void);
+void CtdlEnableHouseKeeping(void);
 
 /*
  * Directory services hooks for LDAP etc
@@ -234,7 +240,7 @@ unsigned CtdlCreateRoom(char *new_room_name,
                        int avoid_access,
                        int new_room_view);
 int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name);
-int CtdlGetRoomLock(struct ctdlroom *qrbuf, char *room_name);
+int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name);
 int CtdlDoIHavePermissionToDeleteThisRoom(struct ctdlroom *qr);
 void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *result, int *view);
 void CtdlPutRoomLock(struct ctdlroom *qrbuf);
@@ -293,134 +299,14 @@ enum {
  */
 void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name);
 
-/* 
- * Global system configuration
- */
-struct config {
-       char c_nodename[16];            /* short name of this node on a Citadel network */
-       char c_fqdn[64];                /* this site's fully qualified domain name */
-       char c_humannode[21];           /* human-readable site name */
-       char c_phonenum[16];            /* telephone number */
-       uid_t c_ctdluid;                /* uid of posix account under which Citadel will run */
-       char c_creataide;               /* 1 = creating a room auto-grants room aide privileges */
-       int c_sleeping;                 /* watchdog timer (seconds) */
-       char c_initax;                  /* initial access level for new users */
-       char c_regiscall;               /* after c_regiscall logins user will be asked to register */
-       char c_twitdetect;              /* automatically move messages from problem users to trashcan */
-       char c_twitroom[ROOMNAMELEN];   /* name of trashcan */
-       char c_moreprompt[80];          /* paginator prompt */
-       char c_restrict;                /* require per-user permission to send Internet mail */
-       long c_niu_1;
-       char c_site_location[32];       /* geographic location of this Citadel site */
-       char c_sysadm[26];              /* name of system administrator */
-       char c_niu_2[15];
-       int c_niu_3;
-       int c_maxsessions;              /* maximum number of concurrent sessions allowed */
-       char c_ip_addr[20];             /* bind address for listening sockets */
-       int c_port_number;              /* port number for Citadel protocol (usually 504) */
-       int c_niu_4;
-       struct ExpirePolicy c_ep;       /* default expire policy for the entire site */
-       int c_userpurge;                /* user purge time (in days) */
-       int c_roompurge;                /* room purge time (in days) */
-       char c_logpages[ROOMNAMELEN];
-       char c_createax;
-       long c_maxmsglen;
-       int c_min_workers;
-       int c_max_workers;
-       int c_pop3_port;
-       int c_smtp_port;
-       int c_rfc822_strict_from;
-       int c_aide_zap;
-       int c_imap_port;
-       time_t c_net_freq;
-       char c_disable_newu;
-       char c_enable_fulltext;
-       char c_baseroom[ROOMNAMELEN];
-       char c_aideroom[ROOMNAMELEN];
-       int c_purge_hour;
-       struct ExpirePolicy c_mbxep;
-       char c_ldap_host[128];
-       int c_ldap_port;
-       char c_ldap_base_dn[256];
-       char c_ldap_bind_dn[256];
-       char c_ldap_bind_pw[256];
-       int c_msa_port;
-       int c_imaps_port;
-       int c_pop3s_port;
-       int c_smtps_port;
-       char c_auto_cull;
-       char c_niu_5;
-       char c_allow_spoofing;
-       char c_journal_email;
-       char c_journal_pubmsgs;
-       char c_journal_dest[128];
-       char c_default_cal_zone[128];
-       int c_pftcpdict_port;
-       int c_managesieve_port;
-       int c_auth_mode;
-       char c_funambol_host[256];
-       int c_funambol_port;
-       char c_funambol_source[256];
-       char c_funambol_auth[256];
-       char c_rbl_at_greeting;
-       char c_master_user[32];
-       char c_master_pass[32];
-       char c_pager_program[256];
-       char c_imap_keep_from;
-       int c_xmpp_c2s_port;
-       int c_xmpp_s2s_port;
-       time_t c_pop3_fetch;
-       time_t c_pop3_fastest;
-       int c_spam_flag_only;
-       int c_guest_logins;
-       int c_nntp_port;
-       int c_nntps_port;
-};
-struct configlen {
-       long c_nodename;
-       long c_fqdn;
-       long c_humannode;
-       long c_phonenum;
-       long c_twitroom;
-       long c_moreprompt;
-       long c_site_location;
-       long c_sysadm;
-       long c_niu_2;
-       long c_ip_addr;
-       long c_logpages;
-       long c_baseroom;
-       long c_aideroom;
-       long c_ldap_host;
-       long c_ldap_base_dn;
-       long c_ldap_bind_dn;
-       long c_ldap_bind_pw;
-       long c_journal_dest;
-       long c_default_cal_zone;
-       long c_funambol_host;
-       long c_funambol_source;
-       long c_funambol_auth;
-       long c_master_user;
-       long c_master_pass;
-       long c_pager_program;
-};
-
-#define SET_CFGSTRBUF(which, buffer) configlen.which = safestrncpy(config.which, ChrPtr(buffer), sizeof(config.which))
-#define SET_CFGSTR(which, buffer) configlen.which = safestrncpy(config.which, buffer, sizeof(config.which))
-
-extern struct config config;
-extern struct configlen configlen;
-
-
-#define NODENAME               config.c_nodename
-#define FQDN                   config.c_fqdn
-#define CTDLUID                        config.c_ctdluid
-#define CREATAIDE              config.c_creataide
-#define REGISCALL              config.c_regiscall
-#define TWITDETECT             config.c_twitdetect
-#define TWITROOM               config.c_twitroom
-#define RESTRICT_INTERNET      config.c_restrict
-
-#define CFG_KEY(which) config.which, configlen.which
+#define NODENAME               CtdlGetConfigStr("c_nodename")
+#define FQDN                   CtdlGetConfigStr("c_fqdn")
+#define CTDLUID                        ctdluid
+#define CREATAIDE              CtdlGetConfigInt("c_creataide")
+#define REGISCALL              CtdlGetConfigInt("c_regiscall")
+#define TWITDETECT             CtdlGetConfigInt("c_twitdetect")
+#define TWITROOM               CtdlGetConfigStr("c_twitroom")
+#define RESTRICT_INTERNET      CtdlGetConfigInt("c_restrict")
 
 typedef void (*CfgLineParser)(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg);
 typedef void (*CfgLineSerializer)(const CfgLineType *ThisOne, StrBuf *OuptputBuffer, OneRoomNetCfg *rncfg, RoomNetCfgLine *data);
index c2131cbff46ce421a37225fb78b21772dbd9ceba..a8868e954c7a12320e4567113473ccd5bb82ef72 100644 (file)
@@ -1,8 +1,19 @@
 /*
  * This file contains functions which handle the mapping of Internet addresses
  * to users on the Citadel system.
+ *
+ * Copyright (c) 1987-2015 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
+
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -281,8 +292,8 @@ int CtdlHostAlias(char *fqdn) {
        if (fqdn == NULL) return(hostalias_nomatch);
        if (IsEmptyStr(fqdn)) return(hostalias_nomatch);
        if (!strcasecmp(fqdn, "localhost")) return(hostalias_localhost);
-       if (!strcasecmp(fqdn, config.c_fqdn)) return(hostalias_localhost);
-       if (!strcasecmp(fqdn, config.c_nodename)) return(hostalias_localhost);
+       if (!strcasecmp(fqdn, CtdlGetConfigStr("c_fqdn"))) return(hostalias_localhost);
+       if (!strcasecmp(fqdn, CtdlGetConfigStr("c_nodename"))) return(hostalias_localhost);
        if (inetcfg == NULL) return(hostalias_nomatch);
 
        config_lines = num_tokens(inetcfg, '\n');
@@ -633,7 +644,7 @@ recptypes *validate_recipients(const char *supplied_recipients,
                case MES_LOCAL:
                        if (!strcasecmp(this_recp, "sysop")) {
                                ++ret->num_room;
-                               strcpy(this_recp, config.c_aideroom);
+                               strcpy(this_recp, CtdlGetConfigStr("c_aideroom"));
                                if (!IsEmptyStr(ret->recp_room)) {
                                        strcat(ret->recp_room, "|");
                                }
@@ -1025,7 +1036,7 @@ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name)
        int a;
 
        strcpy(user, "");
-       strcpy(node, config.c_fqdn);
+       strcpy(node, CtdlGetConfigStr("c_fqdn"));
        strcpy(name, "");
 
        if (rfc822 == NULL) return;
@@ -1114,7 +1125,7 @@ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name)
                && (haschar(node, '%')==0)
                && (haschar(node, '!')==0)
        ) {
-               strcpy(node, config.c_nodename);
+               strcpy(node, CtdlGetConfigStr("c_nodename"));
        }
 
        else {
index eb9e378e7f76872b95d7291d946598bcf2bb8ad2..8af9afdca80668f96c3ddf8bea509c9d485fe9da 100644 (file)
@@ -1,5 +1,15 @@
 /*
  * Message journaling functions.
+ *
+ * Copyright (c) 1987-2015 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include <stdio.h>
@@ -8,6 +18,7 @@
 #include "ctdl_module.h"
 
 #include "citserver.h"
+#include "config.h"
 #include "user_ops.h"
 #include "serv_vcard.h"                        /* Needed for vcard_getuser and extract_inet_email_addrs */
 #include "internet_addressing.h"
@@ -100,7 +111,7 @@ void JournalRunQueueMsg(struct jnlq *jmsg) {
 
        if (jmsg == NULL)
                return;
-       journal_recps = validate_recipients(config.c_journal_dest, NULL, 0);
+       journal_recps = validate_recipients(CtdlGetConfigStr("c_journal_dest"), NULL, 0);
        if (journal_recps != NULL) {
 
                if (  (journal_recps->num_local > 0)
index 9d6ddf16389c57ebb76d44ab99e5c87caca1fd28..97288637fdcad3c2ec4660e1f579dd1544d57038 100644 (file)
@@ -2,7 +2,7 @@
  * These functions implement the portions of AUTHMODE_LDAP and AUTHMODE_LDAP_AD which
  * actually speak to the LDAP server.
  *
- * Copyright (c) 2011-2014 by the citadel.org development team.
+ * Copyright (c) 2011-2015 by the citadel.org development team.
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -22,6 +22,7 @@ int ctdl_require_ldap_version = 3;
 #include "citadel_ldap.h"
 #include "ctdl_module.h"
 #include "user_ops.h"
+#include "config.h"
 
 #ifdef HAVE_LDAP
 #define LDAP_DEPRECATED 1      /* Suppress libldap's warning that we are using deprecated API calls */
@@ -37,7 +38,7 @@ int ctdl_ldap_initialize(LDAP **ld) {
        char server_url[256];
        int ret;
 
-       snprintf(server_url, sizeof server_url, "ldap://%s:%d", config.c_ldap_host, config.c_ldap_port);
+       snprintf(server_url, sizeof server_url, "ldap://%s:%d", CtdlGetConfigStr("c_ldap_host"), CtdlGetConfigInt("c_ldap_port"));
        ret = ldap_initialize(ld, server_url);
        if (ret != LDAP_SUCCESS) {
                syslog(LOG_ALERT, "LDAP: Could not connect to %s : %s",
@@ -80,12 +81,12 @@ int CtdlTryUserLDAP(char *username,
        ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version);
        ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);
 
-       striplt(config.c_ldap_bind_dn);
-       striplt(config.c_ldap_bind_pw);
-       syslog(LOG_DEBUG, "LDAP bind DN: %s", config.c_ldap_bind_dn);
+       striplt(CtdlGetConfigStr("c_ldap_bind_dn"));
+       striplt(CtdlGetConfigStr("c_ldap_bind_pw"));
+       syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn"));
        i = ldap_simple_bind_s(ldserver,
-               (!IsEmptyStr(config.c_ldap_bind_dn) ? config.c_ldap_bind_dn : NULL),
-               (!IsEmptyStr(config.c_ldap_bind_pw) ? config.c_ldap_bind_pw : NULL)
+               (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL),
+               (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL)
        );
        if (i != LDAP_SUCCESS) {
                syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i);
@@ -95,7 +96,7 @@ int CtdlTryUserLDAP(char *username,
        tv.tv_sec = 10;
        tv.tv_usec = 0;
 
-       if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
                if (lookup_based_on_username != 0)
                        snprintf(searchstring, sizeof(searchstring), "(displayName=%s)",username);
                else
@@ -111,7 +112,7 @@ int CtdlTryUserLDAP(char *username,
        syslog(LOG_DEBUG, "LDAP search: %s", searchstring);
        (void) ldap_search_ext_s(
                ldserver,                                       /* ld                           */
-               config.c_ldap_base_dn,                          /* base                         */
+               CtdlGetConfigStr("c_ldap_base_dn"),             /* base                         */
                LDAP_SCOPE_SUBTREE,                             /* scope                        */
                searchstring,                                   /* filter                       */
                NULL,                                           /* attrs (all attributes)       */
@@ -143,7 +144,7 @@ int CtdlTryUserLDAP(char *username,
                        syslog(LOG_DEBUG, "dn = %s", user_dn);
                }
 
-               if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
+               if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
                        values = ldap_get_values(ldserver, search_result, "displayName");
                        if (values) {
                                if (values[0]) {
@@ -165,7 +166,7 @@ int CtdlTryUserLDAP(char *username,
                }
                /* If we know the username is the CN/displayName, we already set the uid*/
                if (lookup_based_on_username==0) {
-                       if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
+                       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
                                values = ldap_get_values(ldserver, search_result, "objectGUID");
                                if (values) {
                                        if (values[0]) {
@@ -322,12 +323,12 @@ int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v)
        ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version);
        ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);
 
-       striplt(config.c_ldap_bind_dn);
-       striplt(config.c_ldap_bind_pw);
-       syslog(LOG_DEBUG, "LDAP bind DN: %s", config.c_ldap_bind_dn);
+       striplt(CtdlGetConfigStr("c_ldap_bind_dn"));
+       striplt(CtdlGetConfigStr("c_ldap_bind_pw"));
+       syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn"));
        i = ldap_simple_bind_s(ldserver,
-               (!IsEmptyStr(config.c_ldap_bind_dn) ? config.c_ldap_bind_dn : NULL),
-               (!IsEmptyStr(config.c_ldap_bind_pw) ? config.c_ldap_bind_pw : NULL)
+               (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL),
+               (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL)
        );
        if (i != LDAP_SUCCESS) {
                syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i);
index 00e190839bda557cdfeb6baafb410bf0f52e4245..ca7c0ae426f61c32f7a971e0c481718d575532cd 100644 (file)
@@ -1,21 +1,21 @@
 /*
  * Autocompletion of email recipients, etc.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
-#include "ctdl_module.h"
 
 
+#include "ctdl_module.h"
 #include "serv_autocompletion.h"
-
+#include "config.h"
 
 
 /*
@@ -59,7 +59,7 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
        int i = 0;
        char *nnn = NULL;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
 
        v = vcard_load(msg->cm_fields[eMesageText]);
@@ -170,7 +170,7 @@ void cmd_auto(char *argbuf) {
        /*
         * Search-reduce the results if we have the full text index available
         */
-       if (config.c_enable_fulltext) {
+       if (CtdlGetConfigInt("c_enable_fulltext")) {
                CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, search_string, "fulltext");
                if (fts_msgs) {
                        for (i=0; i<num_msgs; ++i) {
index ea88b87d36da0ed953fb7a4d8b9cbbc94bb1c1d3..81a54b573914d230981ad2c063e5571ffff9f2b5 100644 (file)
@@ -2,7 +2,7 @@
  * This module implementsserver commands related to the display and
  * manipulation of user "bio" files.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
  */
 
 #include "ctdl_module.h"
+#include "config.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -45,7 +46,7 @@ void cmd_ebio(char *cmdbuf) {
        }
        cprintf("%d  \n",SEND_LISTING);
        while(client_getln(buf, sizeof buf) >= 0 && strcmp(buf,"000")) {
-               if (ftell(fp) < config.c_maxmsglen) {
+               if (ftell(fp) < CtdlGetConfigLong("c_maxmsglen")) {
                        fprintf(fp,"%s\n",buf);
                }
        }
index 1504fcc93bca1b92eb087fc44366bd2ed4894246..5fb86a2287fb12512fce7ecc532ce3fe34458358 100644 (file)
@@ -3,22 +3,15 @@
  * room on a Citadel server.  It handles iCalendar objects using the
  * iTIP protocol.  See RFCs 2445 and 2446.
  *
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #define PRODID "-//Citadel//NONSGML Citadel Calendar//EN"
@@ -33,6 +26,7 @@
 #include "room_ops.h"
 #include "euidindex.h"
 #include "ical_dezonify.h"
+#include "config.h"
 
 
 
@@ -149,8 +143,8 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) {
                msg->cm_format_type = 4;
                CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
                CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
-               CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-               CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
+               CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+               CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode")));
 
                MsgBody = NewStrBufPlain(NULL, serlen + 100);
                StrBufAppendBufPlain(MsgBody, HKEY("Content-type: text/calendar\r\n\r\n"), 0);
@@ -375,7 +369,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -636,7 +630,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
         * us the ability to load the event into memory so we can diddle the
         * attendees.
         */
-       msg = CtdlFetchMessage(msgnum_being_replaced, 1);
+       msg = CtdlFetchMessage(msgnum_being_replaced, 1, 1);
        if (msg == NULL) {
                return(2);                      /* internal error */
        }
@@ -716,7 +710,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -1154,7 +1148,7 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
 
        proposed_event = (icalcomponent *)data;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1215,7 +1209,7 @@ void ical_conflicts(long msgnum, char *partnum) {
        struct CtdlMessage *msg = NULL;
        struct ical_respond_data ird;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found\n",
                        ERROR + ILLEGAL_VALUE,
@@ -1402,7 +1396,7 @@ void ical_freebusy_backend(long msgnum, void *data) {
 
        fb = (icalcomponent *)data;             /* User-supplied data will be the VFREEBUSY component */
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1460,7 +1454,7 @@ void ical_freebusy(char *who) {
         * primary FQDN of this Citadel node.
         */
        if (found_user != 0) {
-               snprintf(buf, sizeof buf, "%s@%s", who, config.c_fqdn);
+               snprintf(buf, sizeof buf, "%s@%s", who, CtdlGetConfigStr("c_fqdn"));
                syslog(LOG_DEBUG, "Trying <%s>\n", buf);
                recp = validate_recipients(buf, NULL, 0);
                if (recp != NULL) {
@@ -1532,7 +1526,7 @@ void ical_freebusy(char *who) {
        sprintf(buf, "MAILTO:%s", who);
        if (strchr(buf, '@') == NULL) {
                strcat(buf, "@");
-               strcat(buf, config.c_fqdn);
+               strcat(buf, CtdlGetConfigStr("c_fqdn"));
        }
        for (i=0; buf[i]; ++i) {
                if (buf[i]==' ') buf[i] = '_';
@@ -1602,7 +1596,7 @@ void ical_getics_backend(long msgnum, void *data) {
 
        /* Look for the calendar event... */
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1755,7 +1749,7 @@ void ical_putics(void)
        }
 
        cprintf("%d Transmit data now\n", SEND_LISTING);
-       calstream = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+       calstream = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0);
        if (calstream == NULL) {
                return;
        }
index a9761a549e6adf267786151fcb617581686284fb..eea501d39207fe030b52815f32e2d5c083102099 100644 (file)
@@ -1,19 +1,13 @@
 /*
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include <string.h>
@@ -93,14 +87,13 @@ void init_ssl(void)
                RAND_egd(EGD_POOL);
 
        if (!RAND_status()) {
-               syslog(LOG_CRIT,
-                       "PRNG not adequately seeded, won't do SSL/TLS\n");
+               syslog(LOG_CRIT, "PRNG not adequately seeded, won't do SSL/TLS");
                return;
        }
        SSLCritters =
            malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t *));
        if (!SSLCritters) {
-               syslog(LOG_EMERG, "citserver: can't allocate memory!!\n");
+               syslog(LOG_EMERG, "citserver: can't allocate memory!!");
                /* Nothing's been initialized, just die */
                exit(1);
        } else {
@@ -109,8 +102,7 @@ void init_ssl(void)
                for (a = 0; a < CRYPTO_num_locks(); a++) {
                        SSLCritters[a] = malloc(sizeof(pthread_mutex_t));
                        if (!SSLCritters[a]) {
-                               syslog(LOG_EMERG,
-                                       "citserver: can't allocate memory!!\n");
+                               syslog(LOG_EMERG, "citserver: can't allocate memory!!");
                                /* Nothing's been initialized, just die */
                                exit(1);
                        }
@@ -125,12 +117,11 @@ void init_ssl(void)
        SSL_load_error_strings();
        ssl_method = SSLv23_server_method();
        if (!(ssl_ctx = SSL_CTX_new(ssl_method))) {
-               syslog(LOG_CRIT, "SSL_CTX_new failed: %s\n",
-                       ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "SSL_CTX_new failed: %s", ERR_reason_error_string(ERR_get_error()));
                return;
        }
        if (!(SSL_CTX_set_cipher_list(ssl_ctx, CIT_CIPHERS))) {
-               syslog(LOG_CRIT, "SSL: No ciphers available\n");
+               syslog(LOG_CRIT, "SSL: No ciphers available");
                SSL_CTX_free(ssl_ctx);
                ssl_ctx = NULL;
                return;
@@ -148,22 +139,19 @@ void init_ssl(void)
        /* Load DH parameters into the context */
        dh = DH_new();
        if (!dh) {
-               syslog(LOG_CRIT, "init_ssl() can't allocate a DH object: %s\n",
-                       ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "init_ssl() can't allocate a DH object: %s", ERR_reason_error_string(ERR_get_error()));
                SSL_CTX_free(ssl_ctx);
                ssl_ctx = NULL;
                return;
        }
        if (!(BN_hex2bn(&(dh->p), DH_P))) {
-               syslog(LOG_CRIT, "init_ssl() can't assign DH_P: %s\n",
-                       ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "init_ssl() can't assign DH_P: %s", ERR_reason_error_string(ERR_get_error()));
                SSL_CTX_free(ssl_ctx);
                ssl_ctx = NULL;
                return;
        }
        if (!(BN_hex2bn(&(dh->g), DH_G))) {
-               syslog(LOG_CRIT, "init_ssl() can't assign DH_G: %s\n",
-                       ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "init_ssl() can't assign DH_G: %s", ERR_reason_error_string(ERR_get_error()));
                SSL_CTX_free(ssl_ctx);
                ssl_ctx = NULL;
                return;
@@ -181,14 +169,13 @@ void init_ssl(void)
         * Generate a key pair if we don't have one.
         */
        if (access(file_crpt_file_key, R_OK) != 0) {
-               syslog(LOG_INFO, "Generating RSA key pair.\n");
+               syslog(LOG_INFO, "Generating RSA key pair.");
                rsa = RSA_generate_key(1024,    /* modulus size */
                                        65537,  /* exponent */
                                        NULL,   /* no callback */
                                        NULL);  /* no callback */
                if (rsa == NULL) {
-                       syslog(LOG_CRIT, "Key generation failed: %s\n",
-                               ERR_reason_error_string(ERR_get_error()));
+                       syslog(LOG_CRIT, "Key generation failed: %s", ERR_reason_error_string(ERR_get_error()));
                }
                if (rsa != NULL) {
                        fp = fopen(file_crpt_file_key, "w");
@@ -202,8 +189,7 @@ void init_ssl(void)
                                                        NULL,   /* no callbk */
                                                        NULL    /* no callbk */
                                ) != 1) {
-                                       syslog(LOG_CRIT, "Cannot write key: %s\n",
-                                               ERR_reason_error_string(ERR_get_error()));
+                                       syslog(LOG_CRIT, "Cannot write key: %s", ERR_reason_error_string(ERR_get_error()));
                                        unlink(file_crpt_file_key);
                                }
                                fclose(fp);
@@ -218,7 +204,7 @@ void init_ssl(void)
         * the CSR in this step so that the next step may commence.
         */
        if ( (access(file_crpt_file_cer, R_OK) != 0) && (access(file_crpt_file_csr, R_OK) != 0) ) {
-               syslog(LOG_INFO, "Generating a certificate signing request.\n");
+               syslog(LOG_INFO, "Generating a generic certificate signing request.");
 
                /*
                 * Read our key from the file.  No, we don't just keep this
@@ -246,42 +232,17 @@ void init_ssl(void)
                                        name = X509_REQ_get_subject_name(req);
 
                                        /* Tell it who we are */
-
-                                       /*
-                                       X509_NAME_add_entry_by_txt(name, "C",
-                                               MBSTRING_ASC, "US", -1, -1, 0);
-
-                                       X509_NAME_add_entry_by_txt(name, "ST",
-                                               MBSTRING_ASC, "New York", -1, -1, 0);
-
-                                       X509_NAME_add_entry_by_txt(name, "L",
-                                               MBSTRING_ASC, "Mount Kisco", -1, -1, 0);
-                                       */
-
-                                       X509_NAME_add_entry_by_txt(name, "O",
-                                                                  MBSTRING_ASC, 
-                                                                  (unsigned char*) config.c_humannode,
-                                                                  -1, -1, 0);
-
-                                       X509_NAME_add_entry_by_txt(name, "OU",
-                                                                  MBSTRING_ASC, 
-                                                                  (unsigned const char*)"Citadel server",
-                                                                  -1, -1, 0);
-
-                                       /* X509_NAME_add_entry_by_txt(name, "CN",
-                                               MBSTRING_ASC, config.c_fqdn, -1, -1, 0);
-                                       */
-
-                                       X509_NAME_add_entry_by_txt(name, 
-                                                                  "CN",
-                                                                  MBSTRING_ASC, 
-                                                                  (const unsigned char *)"*", -1, -1, 0);
-                               
+                                       X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned const char *)"ZZ", -1, -1, 0);
+                                       X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, (unsigned const char *)"The World", -1, -1, 0);
+                                       X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, (unsigned const char *)"My Location", -1, -1, 0);
+                                       X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned const char *)"Generic certificate", -1, -1, 0);
+                                       X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, (unsigned const char *)"Citadel server", -1, -1, 0);
+                                       X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned const char *)"*", -1, -1, 0);
                                        X509_REQ_set_subject_name(req, name);
 
                                        /* Sign the CSR */
                                        if (!X509_REQ_sign(req, pk, EVP_md5())) {
-                                               syslog(LOG_CRIT, "X509_REQ_sign(): error\n");
+                                               syslog(LOG_CRIT, "X509_REQ_sign(): error");
                                        }
                                        else {
                                                /* Write it to disk. */ 
@@ -301,7 +262,7 @@ void init_ssl(void)
                }
 
                else {
-                       syslog(LOG_CRIT, "Unable to read private key.\n");
+                       syslog(LOG_CRIT, "Unable to read private key.");
                }
        }
 
@@ -311,7 +272,7 @@ void init_ssl(void)
         * Generate a self-signed certificate if we don't have one.
         */
        if (access(file_crpt_file_cer, R_OK) != 0) {
-               syslog(LOG_INFO, "Generating a self-signed certificate.\n");
+               syslog(LOG_INFO, "Generating a generic self-signed certificate.");
 
                /* Same deal as before: always read the key from disk because
                 * it may or may not have just been generated.
@@ -351,7 +312,7 @@ void init_ssl(void)
                                        
                                        /* Sign the cert */
                                        if (!X509_sign(cer, pk, EVP_md5())) {
-                                               syslog(LOG_CRIT, "X509_sign(): error\n");
+                                               syslog(LOG_CRIT, "X509_sign(): error");
                                        }
                                        else {
                                                /* Write it to disk. */ 
@@ -377,8 +338,7 @@ void init_ssl(void)
         SSL_CTX_use_certificate_chain_file(ssl_ctx, file_crpt_file_cer);
         SSL_CTX_use_PrivateKey_file(ssl_ctx, file_crpt_file_key, SSL_FILETYPE_PEM);
         if ( !SSL_CTX_check_private_key(ssl_ctx) ) {
-               syslog(LOG_CRIT, "Cannot install certificate: %s\n",
-                               ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "Cannot install certificate: %s", ERR_reason_error_string(ERR_get_error()));
         }
 
        /* Finally let the server know we're here */
@@ -403,7 +363,7 @@ void client_write_ssl(const char *buf, int nbytes)
        while (nremain > 0) {
                if (SSL_want_write(CC->ssl)) {
                        if ((SSL_read(CC->ssl, junk, 0)) < 1) {
-                               syslog(LOG_DEBUG, "SSL_read in client_write: %s\n", ERR_reason_error_string(ERR_get_error()));
+                               syslog(LOG_DEBUG, "SSL_read in client_write: %s", ERR_reason_error_string(ERR_get_error()));
                        }
                }
                retval =
@@ -417,9 +377,9 @@ void client_write_ssl(const char *buf, int nbytes)
                                sleep(1);
                                continue;
                        }
-                       syslog(LOG_DEBUG, "SSL_write got error %ld, ret %d\n", errval, retval);
+                       syslog(LOG_DEBUG, "SSL_write got error %ld, ret %d", errval, retval);
                        if (retval == -1)
-                               syslog(LOG_DEBUG, "errno is %d\n", errno);
+                               syslog(LOG_DEBUG, "errno is %d", errno);
                        endtls();
                        client_write(&buf[nbytes - nremain], nremain);
                        return;
@@ -444,7 +404,7 @@ int client_read_sslbuffer(StrBuf *buf, int timeout)
        while (1) {
                if (SSL_want_read(pssl)) {
                        if ((SSL_write(pssl, junk, 0)) < 1) {
-                               syslog(LOG_DEBUG, "SSL_write in client_read\n");
+                               syslog(LOG_DEBUG, "SSL_write in client_read");
                        }
                }
                rlen = SSL_read(pssl, sbuf, sizeof(sbuf));
@@ -456,7 +416,7 @@ int client_read_sslbuffer(StrBuf *buf, int timeout)
                                sleep(1);
                                continue;
                        }
-                       syslog(LOG_DEBUG, "SSL_read got error %ld\n", errval);
+                       syslog(LOG_DEBUG, "SSL_read got error %ld", errval);
                        endtls();
                        return (-1);
                }
@@ -636,19 +596,18 @@ void CtdlStartTLS(char *ok_response, char *nosup_response,
        int retval, bits, alg_bits;
 
        if (!ssl_ctx) {
-               syslog(LOG_CRIT, "SSL failed: no ssl_ctx exists?\n");
+               syslog(LOG_CRIT, "SSL failed: no ssl_ctx exists?");
                if (nosup_response != NULL) cprintf("%s", nosup_response);
                return;
        }
        if (!(CC->ssl = SSL_new(ssl_ctx))) {
-               syslog(LOG_CRIT, "SSL_new failed: %s\n",
+               syslog(LOG_CRIT, "SSL_new failed: %s",
                                ERR_reason_error_string(ERR_get_error()));
                if (error_response != NULL) cprintf("%s", error_response);
                return;
        }
        if (!(SSL_set_fd(CC->ssl, CC->client_socket))) {
-               syslog(LOG_CRIT, "SSL_set_fd failed: %s\n",
-                       ERR_reason_error_string(ERR_get_error()));
+               syslog(LOG_CRIT, "SSL_set_fd failed: %s", ERR_reason_error_string(ERR_get_error()));
                SSL_free(CC->ssl);
                CC->ssl = NULL;
                if (error_response != NULL) cprintf("%s", error_response);
@@ -666,7 +625,7 @@ void CtdlStartTLS(char *ok_response, char *nosup_response,
                char error_string[128];
 
                errval = SSL_get_error(CC->ssl, retval);
-               syslog(LOG_CRIT, "SSL_accept failed: retval=%d, errval=%ld, err=%s\n",
+               syslog(LOG_CRIT, "SSL_accept failed: retval=%d, errval=%ld, err=%s",
                        retval,
                        errval,
                        ERR_error_string(errval, error_string)
@@ -677,7 +636,7 @@ void CtdlStartTLS(char *ok_response, char *nosup_response,
        }
        BIO_set_close(CC->ssl->rbio, BIO_NOCLOSE);
        bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(CC->ssl), &alg_bits);
-       syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)\n",
+       syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)",
                SSL_CIPHER_get_name(SSL_get_current_cipher(CC->ssl)),
                SSL_CIPHER_get_version(SSL_get_current_cipher(CC->ssl)),
                bits, alg_bits);
@@ -744,7 +703,7 @@ void endtls(void)
                return;
        }
 
-       syslog(LOG_INFO, "Ending SSL/TLS\n");
+       syslog(LOG_INFO, "Ending SSL/TLS");
        SSL_shutdown(CC->ssl);
        SSL_free(CC->ssl);
        CC->ssl = NULL;
index 15e43b46d1c0659b4c70b919fd7d8888c49d3189..50661c7c75d64187e97edcdbef00a4d88fcc4bce 100644 (file)
@@ -1,5 +1,15 @@
 /* 
  * Server functions which handle file transfers and room directories.
+ *
+ * Copyright (c) 1987-2015 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include <stdio.h>
@@ -9,8 +19,10 @@
 #include "ctdl_module.h"
 #include "citserver.h"
 #include "support.h"
+#include "config.h"
 #include "user_ops.h"
 
+
 /*
  * Server command to delete a file from a room's directory
  */
@@ -787,16 +799,15 @@ void do_help_subst(char *buffer)
 {
        char buf2[16];
 
-       help_subst(buffer, "^nodename", config.c_nodename);
-       help_subst(buffer, "^humannode", config.c_humannode);
-       help_subst(buffer, "^fqdn", config.c_fqdn);
+       help_subst(buffer, "^nodename", CtdlGetConfigStr("c_nodename"));
+       help_subst(buffer, "^humannode", CtdlGetConfigStr("c_humannode"));
+       help_subst(buffer, "^fqdn", CtdlGetConfigStr("c_fqdn"));
        help_subst(buffer, "^username", CC->user.fullname);
        snprintf(buf2, sizeof buf2, "%ld", CC->user.usernum);
        help_subst(buffer, "^usernum", buf2);
-       help_subst(buffer, "^sysadm", config.c_sysadm);
+       help_subst(buffer, "^sysadm", CtdlGetConfigStr("c_sysadm"));
        help_subst(buffer, "^variantname", CITADEL);
-       snprintf(buf2, sizeof buf2, "%d", config.c_maxsessions);
-       help_subst(buffer, "^maxsessions", buf2);
+       help_subst(buffer, "^maxsessions", CtdlGetConfigStr("c_maxsessions"));          // yes it's numeric but str is ok here
        help_subst(buffer, "^bbsdir", ctdl_message_dir);
 }
 
index 2d3208a221640a8c16f6ae0ce755e27de8c791df..31e48cb8c3077409ae9827f84b303e51208dd267 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * represent messages to the citadel clients
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
 #include "internet_addressing.h"
 #include "user_ops.h"
 #include "room_ops.h"
+#include "config.h"
 
 extern char *msgkeys[];
 
 
-
 /*
  * Back end for the MSGS command: output message number only.
  */
@@ -34,7 +34,6 @@ void simple_listing(long msgnum, void *userdata)
 }
 
 
-
 /*
  * Back end for the MSGS command: output header summary.
  */
@@ -42,7 +41,7 @@ void headers_listing(long msgnum, void *userdata)
 {
        struct CtdlMessage *msg;
 
-       msg = CtdlFetchMessage(msgnum, 0);
+       msg = CtdlFetchMessage(msgnum, 0, 1);
        if (msg == NULL) {
                cprintf("%ld|0|||||\n", msgnum);
                return;
@@ -66,7 +65,7 @@ void headers_euid(long msgnum, void *userdata)
 {
        struct CtdlMessage *msg;
 
-       msg = CtdlFetchMessage(msgnum, 0);
+       msg = CtdlFetchMessage(msgnum, 0, 1);
        if (msg == NULL) {
                cprintf("%ld||\n", msgnum);
                return;
@@ -137,7 +136,7 @@ void cmd_msgs(char *cmdbuf)
        else
                mode = MSGS_ALL;
 
-       if ( (mode == MSGS_SEARCH) && (!config.c_enable_fulltext) ) {
+       if ( (mode == MSGS_SEARCH) && (!CtdlGetConfigInt("c_enable_fulltext")) ) {
                cprintf("%d Full text index is not enabled on this server.\n",
                        ERROR + CMD_NOT_SUPPORTED);
                return;
@@ -228,7 +227,7 @@ void cmd_msg3(char *cmdbuf)
        }
 
        msgnum = extract_long(cmdbuf, 0);
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n", 
                        ERROR + MESSAGE_NOT_FOUND, msgnum);
index 14673274baabd90bd5e0318b7d4bf7ac3754cae2..51456ac03528ecae834bb62506128a2ce3d61fe7 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Server functions which perform operations on room objects.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -19,6 +19,7 @@
 #include "citserver.h"
 #include "ctdl_module.h"
 #include "room_ops.h"
+#include "config.h"
 
 /*
  * Back-back-end for all room listing commands
@@ -416,7 +417,7 @@ void cmd_rdir(char *cmdbuf)
                cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
                return;
        }
-       cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, config.c_fqdn, ctdl_file_dir, CC->room.QRdirname);
+       cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, CtdlGetConfigStr("c_fqdn"), ctdl_file_dir, CC->room.QRdirname);
        
        snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname);
        fd = fopen(buf, "r");
@@ -595,8 +596,7 @@ void cmd_setr(char *args)
                CC->room.QRflags |= QR_PRIVATE;
 
        /* Some changes can't apply to BASEROOM */
-       if (!strncasecmp(CC->room.QRname, config.c_baseroom,
-                        ROOMNAMELEN)) {
+       if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
                CC->room.QRorder = 0;
                CC->room.QRpasswd[0] = '\0';
                CC->room.QRflags &= ~(QR_PRIVATE & QR_PASSWORDED &
@@ -619,8 +619,7 @@ void cmd_setr(char *args)
                }
        }
        /* Some changes can't apply to AIDEROOM */
-       if (!strncasecmp(CC->room.QRname, config.c_baseroom,
-                        ROOMNAMELEN)) {
+       if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
                CC->room.QRorder = 0;
                CC->room.QRflags &= ~QR_MAILBOX;
                CC->room.QRflags |= QR_PERMANENT;
@@ -761,7 +760,7 @@ void cmd_kill(char *argbuf)
                CtdlScheduleRoomForDeletion(&CC->room);
 
                /* Return to the Lobby */
-               CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL);
+               CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL);
 
                /* tell the world what we did */
                snprintf(msg, sizeof msg, "The room \"%s\" has been deleted by %s.\n",
@@ -831,7 +830,7 @@ void cmd_cre8(char *args)
 
        if (CtdlAccessCheck(ac_logged_in)) return;
 
-       if (CC->user.axlevel < config.c_createax && !CC->internal_pgm) {
+       if (CC->user.axlevel < CtdlGetConfigInt("c_createax") && !CC->internal_pgm) {
                cprintf("%d You need higher access to create rooms.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
                return;
index 6c3914654475069572c3a981e96931c3ddd3ed6a..4aaba407226199187b100748f5114bf486e06a92 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Server functions which perform operations on user objects.
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License, version 3.
@@ -18,6 +18,7 @@
 #include "citserver.h"
 #include "svn_revision.h"
 #include "ctdl_module.h"
+#include "config.h"
 
 void cmd_noop(char *argbuf)
 {
@@ -52,15 +53,15 @@ void cmd_asyn(char *argbuf)
 void cmd_info(char *cmdbuf) {
        cprintf("%d Server info:\n", LISTING_FOLLOWS);
        cprintf("%d\n", CC->cs_pid);
-       cprintf("%s\n", config.c_nodename);
-       cprintf("%s\n", config.c_humannode);
-       cprintf("%s\n", config.c_fqdn);
+       cprintf("%s\n", CtdlGetConfigStr("c_nodename"));
+       cprintf("%s\n", CtdlGetConfigStr("c_humannode"));
+       cprintf("%s\n", CtdlGetConfigStr("c_fqdn"));
        cprintf("%s\n", CITADEL);
        cprintf("%d\n", REV_LEVEL);
-       cprintf("%s\n", config.c_site_location);
-       cprintf("%s\n", config.c_sysadm);
+       cprintf("%s\n", CtdlGetConfigStr("c_site_location"));
+       cprintf("%s\n", CtdlGetConfigStr("c_sysadm"));
        cprintf("%d\n", SERVER_TYPE);
-       cprintf("%s\n", config.c_moreprompt);
+       cprintf("%s\n", CtdlGetConfigStr("c_moreprompt"));
        cprintf("1\n"); /* 1 = yes, this system supports floors */
        cprintf("1\n"); /* 1 = we support the extended paging options */
        cprintf("\n");  /* nonce no longer supported */
@@ -72,16 +73,15 @@ void cmd_info(char *cmdbuf) {
        cprintf("0\n"); /* 1 = no, this server is not LDAP-enabled */
 #endif
 
-       if ((config.c_auth_mode == AUTHMODE_NATIVE) &&
-           (config.c_disable_newu == 0))
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) && (CtdlGetConfigInt("c_disable_newu") == 0))
        {
-               cprintf("%d\n", config.c_disable_newu);
+               cprintf("%d\n", CtdlGetConfigInt("c_disable_newu"));
        }
        else {
                cprintf("1\n"); /* "create new user" does not work with non-native auth modes */
        }
 
-       cprintf("%s\n", config.c_default_cal_zone);
+       cprintf("%s\n", CtdlGetConfigStr("c_default_cal_zone"));
 
        /* thread load averages -- temporarily disabled during refactoring of this code */
        cprintf("0\n");         /* load average */
@@ -89,17 +89,17 @@ void cmd_info(char *cmdbuf) {
        cprintf("0\n");         /* thread count */
 
        cprintf("1\n");         /* yes, Sieve mail filtering is supported */
-       cprintf("%d\n", config.c_enable_fulltext);
+       cprintf("%d\n", CtdlGetConfigInt("c_enable_fulltext"));
        cprintf("%s\n", svn_revision());
 
-       if (config.c_auth_mode == AUTHMODE_NATIVE) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) {
                cprintf("%d\n", openid_level_supported); /* OpenID is enabled when using native auth */
        }
        else {
                cprintf("0\n"); /* OpenID is disabled when using non-native auth */
        }
 
-       cprintf("%d\n", config.c_guest_logins);
+       cprintf("%d\n", CtdlGetConfigInt("c_guest_logins"));
        
        cprintf("000\n");
 }
@@ -116,7 +116,7 @@ void cmd_echo(char *etext)
  * get the paginator prompt
  */
 void cmd_more(char *argbuf) {
-       cprintf("%d %s\n", CIT_OK, config.c_moreprompt);
+       cprintf("%d %s\n", CIT_OK, CtdlGetConfigStr("c_moreprompt"));
 }
 
 
@@ -142,7 +142,7 @@ void cmd_iden(char *argbuf)
        rev_level = extract_int(argbuf,2);
        extract_token(desc, argbuf, 3, '|', sizeof desc);
 
-       safestrncpy(from_host, config.c_fqdn, sizeof from_host);
+       safestrncpy(from_host, CtdlGetConfigStr("c_fqdn"), sizeof from_host);
        from_host[sizeof from_host - 1] = 0;
        if (num_parms(argbuf)>=5) extract_token(from_host, argbuf, 4, '|', sizeof from_host);
 
index e98daad9fa9e26f6d9e8f3ff79b61362a1f80c76..51ea437b7241951c9c7fb7bffe77c8178ddbe421 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Server functions which perform operations on user objects.
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License, version 3.
 #include "support.h"
 #include "control.h"
 #include "ctdl_module.h"
-
 #include "citserver.h"
-
+#include "config.h"
 #include "user_ops.h"
 #include "internet_addressing.h"
 
 
-
 /*
  * USER cmd
  */
@@ -47,7 +45,7 @@ void cmd_user(char *cmdbuf)
                        "Too many users are already online "
                        "(maximum is %d)\n",
                        ERROR + MAX_SESSIONS_EXCEEDED,
-                       config.c_nodename, config.c_maxsessions);
+                       CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions"));
                return;
        case login_ok:
                cprintf("%d Password required for %s\n",
@@ -99,13 +97,13 @@ void cmd_newu(char *cmdbuf)
        long len;
        char username[SIZ];
 
-       if (config.c_auth_mode != AUTHMODE_NATIVE) {
+       if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) {
                cprintf("%d This system does not use native mode authentication.\n",
                        ERROR + NOT_HERE);
                return;
        }
 
-       if (config.c_disable_newu) {
+       if (CtdlGetConfigInt("c_disable_newu")) {
                cprintf("%d Self-service user account creation "
                        "is disabled on this system.\n", ERROR + NOT_HERE);
                return;
@@ -118,7 +116,7 @@ void cmd_newu(char *cmdbuf)
        if (CC->nologin) {
                cprintf("%d %s: Too many users are already online (maximum is %d)\n",
                        ERROR + MAX_SESSIONS_EXCEEDED,
-                       config.c_nodename, config.c_maxsessions);
+                       CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions"));
                return;
        }
        extract_token(username, cmdbuf, 0, '|', sizeof username);
@@ -232,7 +230,7 @@ void cmd_creu(char *cmdbuf)
        } else if (a == ERROR + ALREADY_EXISTS) {
                cprintf("%d '%s' already exists.\n", ERROR + ALREADY_EXISTS, username);
                return;
-       } else if ( (config.c_auth_mode != AUTHMODE_NATIVE) && (a == ERROR + NO_SUCH_USER) ) {
+       } else if ( (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) && (a == ERROR + NO_SUCH_USER) ) {
                cprintf("%d User accounts are not created within Citadel in host authentication mode.\n",
                        ERROR + NO_SUCH_USER);
                return;
@@ -242,23 +240,19 @@ void cmd_creu(char *cmdbuf)
 }
 
 
-
 /*
  * get user parameters
  */
 void cmd_getu(char *cmdbuf)
 {
-
        if (CtdlAccessCheck(ac_logged_in))
                return;
 
        CtdlGetUser(&CC->user, CC->curr_user);
-       cprintf("%d 80|24|%d|\n",
-               CIT_OK,
-               (CC->user.flags & US_USER_SET)
-       );
+       cprintf("%d 80|24|%d|\n", CIT_OK, (CC->user.flags & US_USER_SET));
 }
 
+
 /*
  * set user parameters
  */
@@ -372,7 +366,7 @@ void cmd_invt_kick(char *iuser, int op) {
                return;
        }
 
-       if (!strncasecmp(CC->room.QRname, config.c_baseroom,
+       if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"),
                         ROOMNAMELEN)) {
                cprintf("%d Can't add/remove users from this room.\n",
                        ERROR + NOT_HERE);
@@ -425,7 +419,7 @@ void cmd_gnur(char *argbuf)
                return;
        }
 
-       if ((CitControl.MMflags & MM_VALID) == 0) {
+       if ((CtdlGetConfigInt("MMflags") & MM_VALID) == 0) {
                cprintf("%d There are no unvalidated users.\n", CIT_OK);
                return;
        }
@@ -453,13 +447,12 @@ void cmd_gnur(char *argbuf)
         */
 
        begin_critical_section(S_CONTROL);
-       get_control();
-       CitControl.MMflags = CitControl.MMflags & (~MM_VALID);
-       put_control();
+       int flags;
+       flags = CtdlGetConfigInt("MMflags");
+       flags = flags & (~MM_VALID);
+       CtdlSetConfigInt("MMflags", flags);
        end_critical_section(S_CONTROL);
        cprintf("%d *** End of registration.\n", CIT_OK);
-
-
 }
 
 
@@ -535,9 +528,9 @@ void cmd_chek(char *argbuf)
                regis = 1;
 
        if (CC->user.axlevel >= AxAideU) {
-               get_control();
-               if (CitControl.MMflags & MM_VALID)
+               if (CtdlGetConfigInt("MMflags") & MM_VALID) {
                        vali = 1;
+               }
        }
 
        /* check for mail */
index f7e286a9ab14cf6188f352b52ac036224df99982..55d6fe6f217f043240edadb2febc8b76b66d9faa 100644 (file)
@@ -1,19 +1,13 @@
 /*
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -53,9 +47,8 @@
 #include "server.h"
 #include "citserver.h"
 #include "support.h"
-
 #include "ctdl_module.h"
-
+#include "config.h"
 #include "event_client.h"
 #include "serv_curl.h"
 
@@ -154,7 +147,7 @@ gotstatus(int nnrun)
 
                        EVCURLM_syslog(LOG_DEBUG, "request complete\n");
 
-                       IO->Now = ev_now(event_base);
+                       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
 
                        ev_io_stop(event_base, &IO->recv_event);
                        ev_io_stop(event_base, &IO->send_event);
@@ -188,6 +181,7 @@ gotstatus(int nnrun)
 
 
                        curl_slist_free_all(IO->HttpReq.headers);
+                       IO->HttpReq.headers = NULL;
                        msta = curl_multi_remove_handle(global.mhnd, chnd);
                        if (msta)
                                EVCURL_syslog(LOG_ERR,
@@ -289,7 +283,7 @@ gotdata(void *data, size_t size, size_t nmemb, void *cglobal)
        {
                IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ);
        }
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        return CurlFillStrBuf_callback(data,
                                       size,
                                       nmemb,
@@ -350,7 +344,7 @@ gotwatchsock(CURL *easy,
        }
 
        SetEVState(IO, eCurlGotIO);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
 
        Action = "";
        switch (action)
@@ -477,13 +471,13 @@ int evcurl_init(AsyncIO *IO)
        OPT(WRITEDATA, (void *)IO);
        OPT(ERRORBUFFER, IO->HttpReq.errdesc);
 
-       if ((!IsEmptyStr(config.c_ip_addr))
-               && (strcmp(config.c_ip_addr, "*"))
-               && (strcmp(config.c_ip_addr, "::"))
-               && (strcmp(config.c_ip_addr, "0.0.0.0"))
+       if ((!IsEmptyStr(CtdlGetConfigStr("c_ip_addr")))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "*"))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "::"))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "0.0.0.0"))
                )
        {
-               OPT(INTERFACE, config.c_ip_addr);
+               OPT(INTERFACE, CtdlGetConfigStr("c_ip_addr"));
        }
 
 #ifdef CURLOPT_HTTP_CONTENT_DECODING
@@ -509,10 +503,11 @@ static void IOcurl_abort_shutdown_callback(struct ev_loop *loop,
                return;
 
        SetEVState(IO, eCurlShutdown);
-       IO->Now = ev_now(event_base);
+       IO->CitContext->lastcmd = IO->Now = ev_now(event_base);
        EVCURL_syslog(LOG_DEBUG, "EVENT Curl: %s\n", __FUNCTION__);
 
        curl_slist_free_all(IO->HttpReq.headers);
+       IO->HttpReq.headers = NULL;
        msta = curl_multi_remove_handle(global.mhnd, IO->HttpReq.chnd);
        if (msta)
        {
@@ -530,6 +525,7 @@ static void IOcurl_abort_shutdown_callback(struct ev_loop *loop,
        assert(IO->ShutdownAbort);
        IO->ShutdownAbort(IO);
 }
+
 eNextState
 evcurl_handle_start(AsyncIO *IO)
 {
@@ -655,7 +651,7 @@ static void QueueEventAddCallback(EV_P_ ev_async *w, int revents)
                Ctx = h->IO->CitContext;
                become_session(Ctx);
 
-               h->IO->Now = Now;
+               h->IO->CitContext->lastcmd = h->IO->Now = Now;
                switch (h->EvAttch(h->IO))
                {
                case eReadMore:
@@ -805,7 +801,7 @@ static void DBQueueEventAddCallback(EV_P_ ev_async *w, int revents)
                IOID = h->IO->ID;
                if (h->IO->StartDB == 0.0)
                        h->IO->StartDB = Now;
-               h->IO->Now = Now;
+               h->IO->CitContext->lastcmd = h->IO->Now = Now;
 
                SetEVState(h->IO, eDBAttach);
                Ctx = h->IO->CitContext;
index bc4b772a72c1c28626a7b743d864d82ca8dcdbcb..76c6acb44a2a3ed10605da80491fefc41756bd03 100644 (file)
@@ -1,6 +1,6 @@
 /* 
  * Functions which manage expire policy for rooms
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -40,7 +40,6 @@
 #include "support.h"
 #include "msgbase.h"
 #include "citserver.h"
-
 #include "ctdl_module.h"
 #include "user_ops.h"
 
@@ -71,15 +70,16 @@ void GetExpirePolicy(struct ExpirePolicy *epbuf, struct ctdlroom *qrbuf) {
         * If there is a default policy for mailbox rooms, return it
         */
        if (qrbuf->QRflags & QR_MAILBOX) {
-               if (config.c_mbxep.expire_mode != 0) {
-                       memcpy(epbuf, &config.c_mbxep,
-                               sizeof(struct ExpirePolicy));
+               if (CtdlGetConfigInt("c_mbxep_mode") != 0) {
+                       epbuf->expire_mode = CtdlGetConfigInt("c_mbxep_mode");
+                       epbuf->expire_value = CtdlGetConfigInt("c_mbxep_value");
                        return;
                }
        }
 
        /* Otherwise, fall back on the system default */
-       memcpy(epbuf, &config.c_ep, sizeof(struct ExpirePolicy));
+       epbuf->expire_mode = CtdlGetConfigInt("c_ep_mode");
+       epbuf->expire_value = CtdlGetConfigInt("c_ep_value");
 }
 
 
@@ -91,23 +91,22 @@ void cmd_gpex(char *argbuf) {
        struct floor *fl;
        char which[128];
 
+       memset(&exp, 0, sizeof(struct ExpirePolicy));
        extract_token(which, argbuf, 0, '|', sizeof which);
-       if (!strcasecmp(which, strof(roompolicy))||
-           !strcasecmp(which, "room")) { /* Deprecated version */
+       if (!strcasecmp(which, strof(roompolicy)) || !strcasecmp(which, "room")) {
                memcpy(&exp, &CC->room.QRep, sizeof(struct ExpirePolicy));
        }
-       else if (!strcasecmp(which, strof(floorpolicy))||
-                !strcasecmp(which, "floor")) { /* Deprecated version */
+       else if (!strcasecmp(which, strof(floorpolicy)) || !strcasecmp(which, "floor")) {
                fl = CtdlGetCachedFloor(CC->room.QRfloor);
                memcpy(&exp, &fl->f_ep, sizeof(struct ExpirePolicy));
        }
-       else if (!strcasecmp(which, strof(mailboxespolicy))||
-                !strcasecmp(which, "mailboxes")) {/* Deprecated version */
-               memcpy(&exp, &config.c_mbxep, sizeof(struct ExpirePolicy));
+       else if (!strcasecmp(which, strof(mailboxespolicy)) || !strcasecmp(which, "mailboxes")) {
+               exp.expire_mode = CtdlGetConfigInt("c_mbxep_mode");
+               exp.expire_value = CtdlGetConfigInt("c_mbxep_value");
        }
-       else if (!strcasecmp(which, strof(sitepolicy))||
-                !strcasecmp(which, "site")) {/* Deprecated version */
-               memcpy(&exp, &config.c_ep, sizeof(struct ExpirePolicy));
+       else if (!strcasecmp(which, strof(sitepolicy)) || !strcasecmp(which, "site")) {
+               exp.expire_mode = CtdlGetConfigInt("c_ep_mode");
+               exp.expire_value = CtdlGetConfigInt("c_ep_value");
        }
        else {
                cprintf("%d Invalid keyword \"%s\"\n", ERROR + ILLEGAL_VALUE, which);
@@ -136,9 +135,8 @@ void cmd_spex(char *argbuf) {
                return;
        }
 
-       if (    (!strcasecmp(which, strof(roompolicy)))
-               || (!strcasecmp(which, "room"))
-       ) {
+       if ((!strcasecmp(which, strof(roompolicy))) || (!strcasecmp(which, "room")))
+       {
                if (!is_room_aide()) {
                        cprintf("%d Higher access required.\n", ERROR + HIGHER_ACCESS_REQUIRED);
                        return;
@@ -160,9 +158,8 @@ void cmd_spex(char *argbuf) {
                return;
        }
 
-       if (    (!strcasecmp(which, strof(floorpolicy)))
-               || (!strcasecmp(which, "floor"))
-       ) {
+       if ((!strcasecmp(which, strof(floorpolicy))) || (!strcasecmp(which, "floor")))
+       {
                lgetfloor(&flbuf, CC->room.QRfloor);
                memcpy(&flbuf.f_ep, &exp, sizeof(struct ExpirePolicy));
                lputfloor(&flbuf, CC->room.QRfloor);
@@ -170,25 +167,22 @@ void cmd_spex(char *argbuf) {
                return;
        }
 
-       else if (       (!strcasecmp(which, strof(mailboxespolicy)))
-                       || (!strcasecmp(which, "mailboxes"))
-               ) {
-               memcpy(&config.c_mbxep, &exp, sizeof(struct ExpirePolicy));
-               put_config();
+       else if ((!strcasecmp(which, strof(mailboxespolicy))) || (!strcasecmp(which, "mailboxes")))
+       {
+               CtdlSetConfigInt("c_mbxep_mode", exp.expire_mode);
+               CtdlSetConfigInt("c_mbxep_value", exp.expire_value);
                cprintf("%d Default expire policy for mailboxes set.\n", CIT_OK);
                return;
        }
 
-       else if (       (!strcasecmp(which, strof(sitepolicy)))
-                       || (!strcasecmp(which, "site"))
-               ) {
+       else if ((!strcasecmp(which, strof(sitepolicy))) || (!strcasecmp(which, "site")))
+       {
                if (exp.expire_mode == EXPIRE_NEXTLEVEL) {
-                       cprintf("%d Invalid policy (no higher level)\n",
-                               ERROR + ILLEGAL_VALUE);
+                       cprintf("%d Invalid policy (no higher level)\n", ERROR + ILLEGAL_VALUE);
                        return;
                }
-               memcpy(&config.c_ep, &exp, sizeof(struct ExpirePolicy));
-               put_config();
+               CtdlSetConfigInt("c_ep_mode", exp.expire_mode);
+               CtdlSetConfigInt("c_ep_value", exp.expire_value);
                cprintf("%d Site expire policy has been updated.\n", CIT_OK);
                return;
        }
index 583b86dd504019e844aa0ccbe9c5a906b246b976..76bd626fbada1a23cb473f0a03b799da95d2ff45 100644 (file)
@@ -3,7 +3,7 @@
  *
  * You might also see this module affectionately referred to as the DAP (the Dreaded Auto-Purger).
  *
- * Copyright (c) 1988-2011 by citadel.org (Art Cancro, Wilifried Goesgens, and others)
+ * Copyright (c) 1988-2015 by citadel.org (Art Cancro, Wilifried Goesgens, and others)
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
  * A brief technical discussion:
  *
  * Several of the purge operations found in this module operate in two
@@ -197,7 +192,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) {
                for (a=0; a<num_msgs; ++a) {
                        delnum = msglist[a];
 
-                       msg = CtdlFetchMessage(delnum, 0); /* dont need body */
+                       msg = CtdlFetchMessage(delnum, 0, 1); /* dont need body */
                        if (msg != NULL) {
                                xtime = atol(msg->cm_fields[eTimestamp]);
                                CM_Free(msg);
@@ -312,11 +307,11 @@ void DoPurgeRooms(struct ctdlroom *qrbuf, void *data) {
                if (qrbuf->QRmtime <= (time_t)0) return;
 
                /* If no room purge time is set, be safe and don't purge */
-               if (config.c_roompurge < 0) return;
+               if (CtdlGetConfigLong("c_roompurge") < 0) return;
 
                /* Otherwise, check the date of last modification */
                age = time(NULL) - (qrbuf->QRmtime);
-               purge_secs = (time_t)config.c_roompurge * (time_t)86400;
+               purge_secs = CtdlGetConfigLong("c_roompurge") * 86400;
                if (purge_secs <= (time_t)0) return;
                syslog(LOG_DEBUG, "<%s> is <%ld> seconds old", qrbuf->QRname, (long)age);
                if (age > purge_secs) do_purge = 1;
@@ -417,10 +412,10 @@ void do_user_purge(struct ctdluser *us, void *data) {
 
        /* Set purge time; if the user overrides the system default, use it */
        if (us->USuserpurge > 0) {
-               purge_time = ((time_t)us->USuserpurge) * 86400L;
+               purge_time = ((time_t)us->USuserpurge) * 86400;
        }
        else {
-               purge_time = ((time_t)config.c_userpurge) * 86400L;
+               purge_time = CtdlGetConfigLong("c_userpurge") * 86400;
        }
 
        /* The default rule is to not purge. */
@@ -429,7 +424,7 @@ void do_user_purge(struct ctdluser *us, void *data) {
        /* If the user hasn't called in two months and expiring of accounts is turned on, his/her account
         * has expired, so purge the record.
         */
-       if (config.c_userpurge > 0)
+       if (CtdlGetConfigLong("c_userpurge") > 0)
        {
                now = time(NULL);
                if ((now - us->lastcall) > purge_time) purge = 1;
@@ -528,7 +523,7 @@ int PurgeUsers(void) {
        syslog(LOG_DEBUG, "PurgeUsers() called");
        users_not_purged = 0;
 
-       switch(config.c_auth_mode) {
+       switch(CtdlGetConfigInt("c_auth_mode")) {
                case AUTHMODE_NATIVE:
                        ForEachUser(do_user_purge, NULL);
                        break;
@@ -536,8 +531,7 @@ int PurgeUsers(void) {
                        ForEachUser(do_uid_user_purge, NULL);
                        break;
                default:
-                       syslog(LOG_DEBUG, "User purge for auth mode %d is not implemented.",
-                               config.c_auth_mode);
+                       syslog(LOG_DEBUG, "User purge for auth mode %d is not implemented.", CtdlGetConfigInt("c_auth_mode"));
                        break;
        }
 
@@ -771,7 +765,7 @@ int PurgeEuidIndexTable(void) {
 
                memcpy(&msgnum, cdbei->ptr, sizeof(long));
 
-               msg = CtdlFetchMessage(msgnum, 0);
+               msg = CtdlFetchMessage(msgnum, 0, 1);
                if (msg != NULL) {
                        CM_Free(msg);   /* it still exists, so do nothing */
                }
@@ -870,10 +864,8 @@ void purge_databases(void)
         */
        now = time(NULL);
        localtime_r(&now, &tm);
-       if (
-               ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200))
-               && (force_purge_now == 0)
-       ) {
+       if (((tm.tm_hour != CtdlGetConfigInt("c_purge_hour")) || ((now - last_purge) < 43200)) && (force_purge_now == 0))
+       {
                        return;
        }
 
index 8eafc036a61b09e39fbbd54583cc2768dd59e10c..38b6ef1fa19cd1e65ac25dc16f9be541255d5aff 100644 (file)
@@ -8,7 +8,7 @@
  * Based on bits of serv_funambol
  * Contact: <matt@mcbridematt.dhs.org> / <matt@comalies>
  *
- * Copyright (c) 2008-2011
+ * Copyright (c) 2008-2015
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 
@@ -184,7 +180,7 @@ eNotifyType extNotify_getConfigMessage(char *username,
                return eNone;   /* No messages at all?  No further action. */
        }
        for (a = 0; a < num_msgs; ++a) {
-               msg = CtdlFetchMessage(msglist[a], 1);
+               msg = CtdlFetchMessage(msglist[a], 1, 1);
                if (msg != NULL) {
                        if (!CM_IsEmpty(msg, eMsgSubject) &&
                            (strncasecmp(msg->cm_fields[eMsgSubject],
@@ -279,7 +275,7 @@ void process_notify(long NotifyMsgnum, void *usrdata)
 
        Ctx = (NotifyContext*) usrdata;
 
-       msg = CtdlFetchMessage(NotifyMsgnum, 1);
+       msg = CtdlFetchMessage(NotifyMsgnum, 1, 1);
        if (!CM_IsEmpty(msg, eExtnotify))
        {
                Type = extNotify_getConfigMessage(
@@ -295,9 +291,9 @@ void process_notify(long NotifyMsgnum, void *usrdata)
                {
                case eFunambol:
                        snprintf(remoteurl, SIZ, "http://%s@%s:%d/%s",
-                                config.c_funambol_auth,
-                                config.c_funambol_host,
-                                config.c_funambol_port,
+                                CtdlGetConfigStr("c_funambol_auth"),
+                                CtdlGetConfigStr("c_funambol_host"),
+                                CtdlGetConfigInt("c_funambol_port"),
                                 FUNAMBOL_WS);
 
                        notify_http_server(remoteurl,
@@ -349,7 +345,7 @@ void process_notify(long NotifyMsgnum, void *usrdata)
                        int commandSiz;
                        char *command;
 
-                       commandSiz = sizeof(config.c_pager_program) +
+                       commandSiz = sizeof(CtdlGetConfigStr("c_pager_program")) +
                                strlen(PagerNo) +
                                msg->cm_lengths[eExtnotify] + 5;
 
@@ -358,7 +354,7 @@ void process_notify(long NotifyMsgnum, void *usrdata)
                        snprintf(command,
                                 commandSiz,
                                 "%s %s -u %s",
-                                config.c_pager_program,
+                                CtdlGetConfigStr("c_pager_program"),
                                 PagerNo,
                                 msg->cm_fields[eExtnotify]);
 
@@ -393,8 +389,8 @@ void do_extnotify_queue(void)
         * don't really require extremely fine granularity here, we'll do it
         * with a static variable instead.
         */
-       if (IsEmptyStr(config.c_pager_program) &&
-           IsEmptyStr(config.c_funambol_host))
+       if (IsEmptyStr(CtdlGetConfigStr("c_pager_program")) &&
+           IsEmptyStr(CtdlGetConfigStr("c_funambol_host")))
        {
                syslog(LOG_ERR,
                       "No external notifiers configured on system/user\n");
@@ -472,7 +468,7 @@ int extnotify_after_mbox_save(struct CtdlMessage *msg,
        /* If this is private, local mail, make a copy in the
         * recipient's mailbox and bump the reference count.
         */
-       if (!IsEmptyStr(config.c_funambol_host) || !IsEmptyStr(config.c_pager_program))
+       if (!IsEmptyStr(CtdlGetConfigStr("c_funambol_host")) || !IsEmptyStr(CtdlGetConfigStr("c_pager_program")))
        {
                /* Generate a instruction message for the Funambol notification
                 * server, in the same style as the SMTP queue
index 20246c90d02a38ac25193743a01440340b5fca48..1a109971988185f4b4ebeb44a1a3604fbdc5042c 100644 (file)
@@ -8,21 +8,15 @@
  * Based on bits of the previous serv_funambol
  * Contact: <matt@mcbridematt.dhs.org> / <matt@comalies>
  *
- * Copyright (c) 2008-2010
+ * Copyright (c) 2008-2015
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
- * 
- * 
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * 
- * 
- * 
  */
 
 #include <stdio.h>
@@ -146,8 +140,7 @@ int notify_http_server(char *remoteurl,
 
                // Do substitutions
                help_subst(SOAPMessage, "^notifyuser", user);
-               help_subst(SOAPMessage, "^syncsource",
-                          config.c_funambol_source);
+               help_subst(SOAPMessage, "^syncsource", CtdlGetConfigStr("c_funambol_source"));
                help_subst(SOAPMessage, "^msgid", msgid);
                help_subst(SOAPMessage, "^msgnum", msgnumstr);
 
@@ -182,7 +175,7 @@ int notify_http_server(char *remoteurl,
        }
        else {
                help_subst(remoteurl, "^notifyuser", user);
-               help_subst(remoteurl, "^syncsource", config.c_funambol_source);
+               help_subst(remoteurl, "^syncsource", CtdlGetConfigStr("c_funambol_source"));
                help_subst(remoteurl, "^msgid", msgid);
                help_subst(remoteurl, "^msgnum", msgnumstr);
 
index 6288bfc9ab99adb0a240c99b739aab54da32622e..3709ef6319398c3515143af9871a7e473e9fcdfc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This module handles fulltext indexing of the message base.
- * Copyright (c) 2005-2011 by the citadel.org team
+ * Copyright (c) 2005-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -120,7 +120,7 @@ void ft_index_message(long msgnum, int op) {
        int tok;
        struct CtdlMessage *msg = NULL;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                syslog(LOG_ERR, "ft_index_message() could not load msg %ld", msgnum);
                return;
@@ -210,7 +210,7 @@ void ft_index_message(long msgnum, int op) {
  */
 void ft_index_msg(long msgnum, void *userdata) {
 
-       if ((msgnum > CitControl.MMfulltext) && (msgnum <= ft_newhighest)) {
+       if ((msgnum > CtdlGetConfigLong("MMfulltext")) && (msgnum <= ft_newhighest)) {
                ++ft_num_msgs;
                if (ft_num_msgs > ft_num_alloc) {
                        ft_num_alloc += 1024;
@@ -251,7 +251,7 @@ void do_fulltext_indexing(void) {
        /*
         * Don't do this if the site doesn't have it enabled.
         */
-       if (!config.c_enable_fulltext) {
+       if (!CtdlGetConfigInt("c_enable_fulltext")) {
                return;
        }
 
@@ -268,7 +268,10 @@ void do_fulltext_indexing(void) {
         * Check to see whether the fulltext index is up to date; if there
         * are no messages to index, don't waste any more time trying.
         */
-       if ((CitControl.MMfulltext >= CitControl.MMhighest) && (CitControl.fulltext_wordbreaker == FT_WORDBREAKER_ID)) {
+       if (
+               (CtdlGetConfigLong("MMfulltext") >= CtdlGetConfigLong("MMhighest"))
+               && (CtdlGetConfigInt("MM_fulltext_wordbreaker") == FT_WORDBREAKER_ID)
+       ) {
                return;         /* nothing to do! */
        }
        
@@ -280,21 +283,20 @@ void do_fulltext_indexing(void) {
         * over.
         */
        begin_critical_section(S_CONTROL);
-       if (CitControl.fulltext_wordbreaker != FT_WORDBREAKER_ID) {
+       if (CtdlGetConfigInt("MM_fulltext_wordbreaker") != FT_WORDBREAKER_ID) {
                syslog(LOG_DEBUG, "wb ver on disk = %d, code ver = %d",
-                       CitControl.fulltext_wordbreaker, FT_WORDBREAKER_ID
+                       CtdlGetConfigInt("MM_fulltext_wordbreaker"), FT_WORDBREAKER_ID
                );
                syslog(LOG_INFO, "(re)initializing full text index");
                cdb_trunc(CDB_FULLTEXT);
-               CitControl.MMfulltext = 0L;
-               put_control();
+               CtdlSetConfigLong("MMfulltext", 0);
        }
        end_critical_section(S_CONTROL);
 
        /*
         * Now go through each room and find messages to index.
         */
-       ft_newhighest = CitControl.MMhighest;
+       ft_newhighest = CtdlGetConfigLong("MMhighest");
        CtdlForEachRoom(ft_index_room, NULL);   /* load all msg pointers */
 
        if (ft_num_msgs > 0) {
@@ -353,9 +355,8 @@ void do_fulltext_indexing(void) {
        /* Save our place so we don't have to do this again */
        ft_flush_cache();
        begin_critical_section(S_CONTROL);
-       CitControl.MMfulltext = ft_newhighest;
-       CitControl.fulltext_wordbreaker = FT_WORDBREAKER_ID;
-       put_control();
+       CtdlSetConfigLong("MMfulltext", ft_newhighest);
+       CtdlSetConfigInt("MM_fulltext_wordbreaker", FT_WORDBREAKER_ID);
        end_critical_section(S_CONTROL);
        last_index = time(NULL);
 
@@ -455,7 +456,7 @@ void cmd_srch(char *argbuf) {
 
        if (CtdlAccessCheck(ac_logged_in)) return;
 
-       if (!config.c_enable_fulltext) {
+       if (!CtdlGetConfigInt("c_enable_fulltext")) {
                cprintf("%d Full text index is not enabled on this server.\n",
                        ERROR + CMD_NOT_SUPPORTED);
                return;
@@ -489,7 +490,7 @@ void ft_delete_remove(char *room, long msgnum)
        if (room) return;
        
        /* Remove from fulltext index */
-       if (config.c_enable_fulltext) {
+       if (CtdlGetConfigInt("c_enable_fulltext")) {
                ft_index_message(msgnum, 0);
        }
 }
index 3f00d3f3f65c26380005589c3fc8d8d21bb1d37d..8fcd6bd813ab6c2bc3055f65cde7dbb176e4d288 100644 (file)
@@ -2,21 +2,17 @@
  * Implements the FETCH command in IMAP.
  * This is a good example of the protocol's gratuitous complexity.
  *
- * Copyright (c) 2001-2011 by the citadel.org team
+ * Copyright (c) 2001-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 
@@ -363,8 +359,8 @@ void imap_output_envelope_from(struct CtdlMessage *msg) {
                process_rfc822_addr(msg->cm_fields[erFc822Addr], user, node, name);
                IPutStr(user, strlen(user));            /* mailbox name (user id) */
                IAPuts(" ");
-               if (!strcasecmp(node, config.c_nodename)) {
-                       IPutStr(CFG_KEY(c_fqdn));
+               if (!strcasecmp(node, CtdlGetConfigStr("c_nodename"))) {
+                       IPutStr(CtdlGetConfigStr("c_fqdn"), strlen(CtdlGetConfigStr("c_fqdn")));
                }
                else {
                        IPutStr(node, strlen(node));            /* host name */
@@ -710,7 +706,7 @@ void imap_fetch_body(long msgnum, ConstStr item, int is_peek) {
        if (Imap->cached_body == NULL) {
                CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
                loading_body_now = 1;
-               msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0));
+               msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0), 1);
        }
 
        /* Now figure out what the client wants, and get it */
@@ -1085,7 +1081,7 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) {
                                msg = NULL;
                        }
                        if (msg == NULL) {
-                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                                body_loaded = 1;
                        }
                        imap_fetch_bodystructure(Imap->msgids[seq-1],
@@ -1093,14 +1089,14 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) {
                }
                else if (!strcasecmp(Cmd->Params[i].Key, "ENVELOPE")) {
                        if (msg == NULL) {
-                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 0);
+                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1);
                                body_loaded = 0;
                        }
                        imap_fetch_envelope(msg);
                }
                else if (!strcasecmp(Cmd->Params[i].Key, "INTERNALDATE")) {
                        if (msg == NULL) {
-                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 0);
+                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1);
                                body_loaded = 0;
                        }
                        imap_fetch_internaldate(msg);
index f4d501c9d3853dd56c8895e804ac0c5d943755ea..3665264554ddc574840d88acef5e64017c857a31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 
@@ -341,7 +337,7 @@ void imap_append(int num_parms, ConstStr *Params) {
        
        IUnbuffer ();
 
-       client_read_blob(Imap->TransmittedMessage, literal_length, config.c_sleeping);
+       client_read_blob(Imap->TransmittedMessage, literal_length, CtdlGetConfigInt("c_sleeping"));
 
        if ((ret < 0) || (StrLength(Imap->TransmittedMessage) < literal_length)) {
                IReply("NO Read failed.");
@@ -377,19 +373,15 @@ void imap_append(int num_parms, ConstStr *Params) {
        CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL);
 
        /* If the user is locally authenticated, FORCE the From: header to
-        * show up as the real sender.  FIXME do we really want to do this?
-        * Probably should make it site-definable or even room-definable.
-        *
-        * For now, we allow "forgeries" if the room is one of the user's
-        * private mailboxes.
+        * show up as the real sender.  (Configurable setting)
         */
        if (CCC->logged_in) {
-          if ( ((CCC->room.QRflags & QR_MAILBOX) == 0) && (config.c_imap_keep_from == 0)) {
-
-               CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
-               CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-               CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
-           }
+               if ( ((CCC->room.QRflags & QR_MAILBOX) == 0) && (CtdlGetConfigInt("c_imap_keep_from") == 0))
+               {
+                       CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
+                       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+                       CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode")));
+               }
        }
 
        /* 
index cad499ceb63ad2091768ae552a5d8c99b2243758..f1b7f73e993ce26cc246a3f3effcd7c8070c48aa 100644 (file)
@@ -1,21 +1,15 @@
 /*
  * Implements IMAP's gratuitously complex SEARCH command.
  *
- * Copyright (c) 2001-2012 by the citadel.org team
+ * Copyright (c) 2001-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "ctdl_module.h"
@@ -121,7 +115,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "BCC")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -138,7 +132,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -157,14 +151,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                /* If fulltext indexing is active, on this server,
                 *  all messages have already been qualified.
                 */
-               if (config.c_enable_fulltext) {
+               if (CtdlGetConfigInt("c_enable_fulltext")) {
                        match = 1;
                }
 
                /* Otherwise, we have to do a slow search. */
                else {
                        if (msg == NULL) {
-                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                               msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                                need_to_free_msg = 1;
                        }
                        if (msg != NULL) {
@@ -179,7 +173,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "CC")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -225,7 +219,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "FROM")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -247,7 +241,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                 * examining the message body.
                 */
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
 
@@ -277,7 +271,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "LARGER")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -304,7 +298,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "ON")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -334,7 +328,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -350,7 +344,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SENTON")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -366,7 +360,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -382,7 +376,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SINCE")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -398,7 +392,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -411,7 +405,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -424,7 +418,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "TEXT")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -439,7 +433,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 
        else if (!strcasecmp(itemlist[pos].Key, "TO")) {
                if (msg == NULL) {
-                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1);
+                       msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
@@ -571,7 +565,7 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
         * text index to disqualify messages that don't have any chance of
         * matching.  (Only do this if the index is enabled!!)
         */
-       if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) {
+       if (CtdlGetConfigInt("c_enable_fulltext")) for (i=0; i<(num_items-1); ++i) {
                if (!strcasecmp(itemlist[i].Key, "BODY")) {
                        CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext");
                        if (fts_num_msgs > 0) {
index 278cc73323392b3883c08ff8ee58b75d1b8fa163..60584df2750235c6f611586b144e94a09751e4ba 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * IMAP server for the Citadel system
  *
- * Copyright (C) 2000-2011 by Art Cancro and others.
+ * Copyright (C) 2000-2015 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
  *
  * WARNING: the IMAP protocol is badly designed.  No implementation of it
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
@@ -599,7 +595,7 @@ void imap_greeting(void)
 
        IAPuts("* OK [");
        imap_output_capability_string();
-       IAPrintf("] %s IMAP4rev1 %s ready\r\n", config.c_fqdn, CITADEL);
+       IAPrintf("] %s IMAP4rev1 %s ready\r\n", CtdlGetConfigStr("c_fqdn"), CITADEL);
        IUnbuffer();
 }
 
@@ -917,7 +913,7 @@ void imap_select(int num_parms, ConstStr *Params)
        IAPrintf("* %d RECENT\r\n", new);
 
        IAPrintf("* OK [UIDVALIDITY %ld] UID validity status\r\n", GLOBAL_UIDVALIDITY_VALUE);
-       IAPrintf("* OK [UIDNEXT %ld] Predicted next UID\r\n", CitControl.MMhighest + 1);
+       IAPrintf("* OK [UIDNEXT %ld] Predicted next UID\r\n", CtdlGetConfigLong("MMhighest") + 1);
 
        /* Technically, \Deleted is a valid flag, but not a permanent flag,
         * because we don't maintain its state across sessions.  Citadel
@@ -1220,7 +1216,7 @@ void imap_status(int num_parms, ConstStr *Params)
        IPutStr(imaproomname, len);
        IAPrintf(" (MESSAGES %d ", msgs);
        IAPrintf("RECENT %d ", new);    /* Initially, new==recent */
-       IAPrintf("UIDNEXT %ld ", CitControl.MMhighest + 1);
+       IAPrintf("UIDNEXT %ld ", CtdlGetConfigLong("MMhighest") + 1);
        IAPrintf("UNSEEN %d)\r\n", new);
        
        /*
@@ -1675,7 +1671,7 @@ void imap_logout(int num_parms, ConstStr *Params)
        if (IMAP->selected) {
                imap_do_expunge();      /* yes, we auto-expunge at logout */
        }
-       IAPrintf("* BYE %s logging out\r\n", config.c_fqdn);
+       IAPrintf("* BYE %s logging out\r\n", CtdlGetConfigStr("c_fqdn"));
        IReply("OK Citadel IMAP session ended.");
        CC->kill_me = KILLME_CLIENT_LOGGED_OUT;
        return;
@@ -1744,10 +1740,10 @@ CTDL_MODULE_INIT(imap)
        if (!threading)
        {
                CtdlRegisterDebugFlagHook(HKEY("imapsrv"), SetIMAPDebugEnabled, &IMAPDebugEnabled);
-               CtdlRegisterServiceHook(config.c_imap_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_imap_port"),
                                        NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP);
 #ifdef HAVE_OPENSSL
-               CtdlRegisterServiceHook(config.c_imaps_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_imaps_port"),
                                        NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS);
 #endif
                CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP, PRIO_STOP + 30);
index c37dd24fbdfcb103ea033bbb10fb5bdd2664b07c..615a48b42b76c03988f18a01d119c0debba87eac 100644 (file)
@@ -119,7 +119,7 @@ int inetcfg_aftersave(struct CtdlMessage *msg, recptypes *recp) {
 void inetcfg_init_backend(long msgnum, void *userdata) {
        struct CtdlMessage *msg;
 
-               msg = CtdlFetchMessage(msgnum, 1);
+               msg = CtdlFetchMessage(msgnum, 1, 1);
                if (msg != NULL) {
                inetcfg_setTo(msg);
                        CM_Free(msg);
index 2c28600b665cc01d437439c6f5442499e46bfc20..9884785373f4701758aabdef6031e2f6b2103b77 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This module handles instant messaging between users.
  * 
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -11,6 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -174,7 +175,7 @@ void cmd_gexp(char *argbuf) {
                (long)ptr->timestamp,                   /* time sent */
                ptr->flags,                             /* flags */
                ptr->sender,                            /* sender of msg */
-               config.c_nodename,                      /* static for now (and possibly deprecated) */
+               CtdlGetConfigStr("c_nodename"),         /* static for now (and possibly deprecated) */
                ptr->sender_email                       /* email or jid of sender */
        );
 
@@ -478,7 +479,7 @@ void flush_individual_conversation(struct imlog *im) {
        }
 
        CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM));
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        CM_SetAsFieldSB(msg, eMesageText, &FullMsgBuf); /* we own this memory now */
 
        /* Start with usernums[1] because it's guaranteed to be higher than usernums[0],
@@ -503,9 +504,9 @@ void flush_individual_conversation(struct imlog *im) {
        }
 
        /* Finally, if we're logging instant messages globally, do that now. */
-       if (!IsEmptyStr(config.c_logpages)) {
-               CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);
-               CtdlSaveMsgPointerInRoom(config.c_logpages, msgnum, 0, NULL);
+       if (!IsEmptyStr(CtdlGetConfigStr("c_logpages"))) {
+               CtdlCreateRoom(CtdlGetConfigStr("c_logpages"), 3, "", 0, 1, 1, VIEW_BBS);
+               CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_logpages"), msgnum, 0, NULL);
        }
 
 }
index 23f5f263c614b67b8db4ea489c3ff841bc33fae8..6bfe112643cc460a5a9d0c5958f971aa9a46a989 100644 (file)
@@ -6,7 +6,7 @@
  * as this draft expires with this writing, you might need to search for
  * the new one.
  *
- * Copyright (c) 2007-2012 by the citadel.org team
+ * Copyright (c) 2007-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -651,7 +651,7 @@ CTDL_MODULE_INIT(managesieve)
 {
        if (!threading)
        {
-               CtdlRegisterServiceHook(config.c_managesieve_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_managesieve_port"),
                                        NULL,
                                        managesieve_greeting,
                                        managesieve_command_loop,
index 97181a1c64763850523c23d60c07b99d29a87aa6..83173268239cbc2f69074ee6e24d7ce8f5c2f2f6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This module dumps and/or loads the Citadel database in XML format.
  *
- * Copyright (c) 1987-2014 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -16,8 +16,7 @@
  * Explanation of <progress> tags:
  *
  * 0%              nothing
- * 1%              finished exporting config
- * 2%              finished exporting control
+ * 2%              finished exporting configuration
  * 7%              finished exporting users
  * 12%             finished exporting openids
  * 17%             finished exporting rooms
@@ -61,7 +60,6 @@
 #include "database.h"
 #include "msgbase.h"
 #include "user_ops.h"
-#include "control.h"
 #include "euidindex.h"
 #include "ctdl_module.h"
 
@@ -73,9 +71,9 @@ FILE *migr_global_message_list;
 int total_msgs = 0;
 
 
-/*
- * Code which implements the export appears in this section
- */
+/******************************************************************************
+ *        Code which implements the export appears in this section            *
+ ******************************************************************************/
 
 /*
  * Output a string to the client with these characters escaped:  & < >
@@ -90,19 +88,19 @@ void xml_strout(char *str) {
 
        while (*c != 0) {
                if (*c == '\"') {
-                       client_write("&quot;", 6);
+                       client_write(HKEY("&quot;"));
                }
                else if (*c == '\'') {
-                       client_write("&apos;", 6);
+                       client_write(HKEY("&apos;"));
                }
                else if (*c == '<') {
-                       client_write("&lt;", 4);
+                       client_write(HKEY("&lt;"));
                }
                else if (*c == '>') {
-                       client_write("&gt;", 4);
+                       client_write(HKEY("&gt;"));
                }
                else if (*c == '&') {
-                       client_write("&amp;", 5);
+                       client_write(HKEY("&amp;"));
                }
                else {
                        client_write(c, 1);
@@ -116,10 +114,10 @@ void xml_strout(char *str) {
  * Export a user record as XML
  */
 void migr_export_users_backend(struct ctdluser *buf, void *data) {
-       client_write("<user>\n", 7);
+       client_write(HKEY("<user>\n"));
        cprintf("<u_version>%d</u_version>\n", buf->version);
        cprintf("<u_uid>%ld</u_uid>\n", (long)buf->uid);
-       client_write("<u_password>", 12);       xml_strout(buf->password);              client_write("</u_password>\n", 14);
+       client_write(HKEY("<u_password>"));     xml_strout(buf->password);              client_write(HKEY("</u_password>\n"));
        cprintf("<u_flags>%u</u_flags>\n", buf->flags);
        cprintf("<u_timescalled>%ld</u_timescalled>\n", buf->timescalled);
        cprintf("<u_posted>%ld</u_posted>\n", buf->posted);
@@ -127,8 +125,8 @@ void migr_export_users_backend(struct ctdluser *buf, void *data) {
        cprintf("<u_usernum>%ld</u_usernum>\n", buf->usernum);
        cprintf("<u_lastcall>%ld</u_lastcall>\n", (long)buf->lastcall);
        cprintf("<u_USuserpurge>%d</u_USuserpurge>\n", buf->USuserpurge);
-       client_write("<u_fullname>", 12);       xml_strout(buf->fullname);              client_write("</u_fullname>\n", 14);
-       client_write("</user>\n", 8);
+       client_write(HKEY("<u_fullname>"));     xml_strout(buf->fullname);              client_write(HKEY("</u_fullname>\n"));
+       client_write(HKEY("</user>\n"));
 }
 
 
@@ -144,17 +142,17 @@ void migr_export_room_msg(long msgnum, void *userdata) {
 
 
 void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
-       client_write("<room>\n", 7);
-       client_write("<QRname>", 8);    xml_strout(buf->QRname);        client_write("</QRname>\n", 10);
-       client_write("<QRpasswd>", 10); xml_strout(buf->QRpasswd);      client_write("</QRpasswd>\n", 12);
+       client_write(HKEY("<room>\n"));
+       client_write(HKEY("<QRname>")); xml_strout(buf->QRname);        client_write(HKEY("</QRname>\n"));
+       client_write(HKEY("<QRpasswd>"));       xml_strout(buf->QRpasswd);      client_write(HKEY("</QRpasswd>\n"));
        cprintf("<QRroomaide>%ld</QRroomaide>\n", buf->QRroomaide);
        cprintf("<QRhighest>%ld</QRhighest>\n", buf->QRhighest);
        cprintf("<QRgen>%ld</QRgen>\n", (long)buf->QRgen);
        cprintf("<QRflags>%u</QRflags>\n", buf->QRflags);
        if (buf->QRflags & QR_DIRECTORY) {
-               client_write("<QRdirname>", 11);
+               client_write(HKEY("<QRdirname>"));
                xml_strout(buf->QRdirname);
-               client_write("</QRdirname>\n", 13);
+               client_write(HKEY("</QRdirname>\n"));
        }
        cprintf("<QRinfo>%ld</QRinfo>\n", buf->QRinfo);
        cprintf("<QRfloor>%d</QRfloor>\n", buf->QRfloor);
@@ -165,17 +163,17 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
        cprintf("<QRorder>%d</QRorder>\n", buf->QRorder);
        cprintf("<QRflags2>%u</QRflags2>\n", buf->QRflags2);
        cprintf("<QRdefaultview>%d</QRdefaultview>\n", buf->QRdefaultview);
-       client_write("</room>\n", 8);
+       client_write(HKEY("</room>\n"));
 
        /* message list goes inside this tag */
 
        CtdlGetRoom(&CC->room, buf->QRname);
-       client_write("<room_messages>", 15);
-       client_write("<FRname>", 8);    xml_strout(CC->room.QRname);    client_write("</FRname>\n", 10);
-       client_write("<FRmsglist>", 11);
+       client_write(HKEY("<room_messages>"));
+       client_write(HKEY("<FRname>")); xml_strout(CC->room.QRname);    client_write(HKEY("</FRname>\n"));
+       client_write(HKEY("<FRmsglist>"));
        CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_export_room_msg, NULL);
-       client_write("</FRmsglist>\n", 13);
-       client_write("</room_messages>\n", 17);
+       client_write(HKEY("</FRmsglist>\n"));
+       client_write(HKEY("</room_messages>\n"));
 
 
 }
@@ -220,16 +218,16 @@ void migr_export_floors(void) {
         int i;
 
         for (i=0; i < MAXFLOORS; ++i) {
-               client_write("<floor>\n", 8);
+               client_write(HKEY("<floor>\n"));
                cprintf("<f_num>%d</f_num>\n", i);
                 CtdlGetFloor(&qfbuf, i);
                buf = &qfbuf;
                cprintf("<f_flags>%u</f_flags>\n", buf->f_flags);
-               client_write("<f_name>", 8); xml_strout(buf->f_name); client_write("</f_name>\n", 10);
+               client_write(HKEY("<f_name>")); xml_strout(buf->f_name); client_write(HKEY("</f_name>\n"));
                cprintf("<f_ref_count>%d</f_ref_count>\n", buf->f_ref_count);
                cprintf("<f_ep_expire_mode>%d</f_ep_expire_mode>\n", buf->f_ep.expire_mode);
                cprintf("<f_ep_expire_value>%d</f_ep_expire_value>\n", buf->f_ep.expire_value);
-               client_write("</floor>\n", 9);
+               client_write(HKEY("</floor>\n"));
        }
 }
 
@@ -268,29 +266,29 @@ void migr_export_visits(void) {
                        sizeof(visit) : cdbv->len));
                cdb_free(cdbv);
 
-               client_write("<visit>\n", 8);
+               client_write(HKEY("<visit>\n"));
                cprintf("<v_roomnum>%ld</v_roomnum>\n", vbuf.v_roomnum);
                cprintf("<v_roomgen>%ld</v_roomgen>\n", vbuf.v_roomgen);
                cprintf("<v_usernum>%ld</v_usernum>\n", vbuf.v_usernum);
 
-               client_write("<v_seen>", 8);
+               client_write(HKEY("<v_seen>"));
                if ( (!IsEmptyStr(vbuf.v_seen)) && (is_sequence_set(vbuf.v_seen)) ) {
                        xml_strout(vbuf.v_seen);
                }
                else {
                        cprintf("%ld", vbuf.v_lastseen);
                }
-               client_write("</v_seen>", 9);
+               client_write(HKEY("</v_seen>"));
 
                if ( (!IsEmptyStr(vbuf.v_answered)) && (is_sequence_set(vbuf.v_answered)) ) {
-                       client_write("<v_answered>", 12);
+                       client_write(HKEY("<v_answered>"));
                        xml_strout(vbuf.v_answered);
-                       client_write("</v_answered>\n", 14);
+                       client_write(HKEY("</v_answered>\n"));
                }
 
                cprintf("<v_flags>%u</v_flags>\n", vbuf.v_flags);
                cprintf("<v_view>%d</v_view>\n", vbuf.v_view);
-               client_write("</visit>\n", 9);
+               client_write(HKEY("</visit>\n"));
        }
 }
 
@@ -319,16 +317,18 @@ void migr_export_message(long msgnum) {
 
        /* Ok, here we go ... */
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 0);
        if (msg == NULL) return;        /* fail silently */
 
-       client_write("<message>\n", 10);
+       client_write(HKEY("<message>\n"));
        GetMetaData(&smi, msgnum);
        cprintf("<msg_msgnum>%ld</msg_msgnum>\n", msgnum);
        cprintf("<msg_meta_refcount>%d</msg_meta_refcount>\n", smi.meta_refcount);
-       client_write("<msg_meta_content_type>", 23); xml_strout(smi.meta_content_type); client_write("</msg_meta_content_type>\n", 25);
+       cprintf("<msg_meta_rfc822_length>%ld</msg_meta_rfc822_length>\n", smi.meta_rfc822_length);
+       client_write(HKEY("<msg_meta_content_type>")); xml_strout(smi.meta_content_type); client_write(HKEY("</msg_meta_content_type>\n"));
+       client_write(HKEY("<msg_mimetype>")); xml_strout(smi.mimetype); client_write(HKEY("</msg_mimetype>\n"));
 
-       client_write("<msg_text>", 10);
+       client_write(HKEY("<msg_text>"));
        CtdlSerializeMessage(&smr, msg);
        CM_Free(msg);
 
@@ -351,8 +351,8 @@ void migr_export_message(long msgnum) {
 
        free(smr.ser);
 
-       client_write("</msg_text>\n", 12);
-       client_write("</message>\n", 11);
+       client_write(HKEY("</msg_text>\n"));
+       client_write(HKEY("</message>\n"));
 }
 
 
@@ -365,20 +365,43 @@ void migr_export_openids(void) {
        cdb_rewind(CDB_OPENID);
        while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) {
                if (cdboi->len > sizeof(long)) {
-                       client_write("<openid>\n", 9);
+                       client_write(HKEY("<openid>\n"));
                        memcpy(&usernum, cdboi->ptr, sizeof(long));
                        snprintf(url, sizeof url, "%s", (cdboi->ptr)+sizeof(long) );
-                       client_write("<oid_url>", 9);
+                       client_write(HKEY("<oid_url>"));
                        xml_strout(url);
-                       client_write("</oid_url>\n", 11);
+                       client_write(HKEY("</oid_url>\n"));
                        cprintf("<oid_usernum>%ld</oid_usernum>\n", usernum);
-                       client_write("</openid>\n", 10);
+                       client_write(HKEY("</openid>\n"));
                }
                cdb_free(cdboi);
        }
 }
 
 
+void migr_export_configs(void) {
+       struct cdbdata *cdbcfg;
+       int keylen = 0;
+       char *key = NULL;
+       char *value = NULL;
+
+       cdb_rewind(CDB_CONFIG);
+       while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg != NULL) {
+
+               keylen = strlen(cdbcfg->ptr);
+               key = cdbcfg->ptr;
+               value = cdbcfg->ptr + keylen + 1;
+
+               client_write("<config key=\"", 13);
+               xml_strout(key);
+               client_write("\">", 2);
+               xml_strout(value);
+               client_write("</config>\n", 10);
+               cdb_free(cdbcfg);
+       }
+}
+
+
 
 
 void migr_export_messages(void) {
@@ -425,101 +448,15 @@ void migr_do_export(void) {
        cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS);
        Ctx->dont_term = 1;
 
-       client_write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", 40);
-       client_write("<citadel_migrate_data>\n", 23);
+       client_write(HKEY("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"));
+       client_write(HKEY("<citadel_migrate_data>\n"));
        cprintf("<version>%d</version>\n", REV_LEVEL);
        cprintf("<progress>%d</progress>\n", 0);
 
-       /* export the config file (this is done using x-macros) */
-       client_write("<config>\n", 9);
-       client_write("<c_nodename>", 12);       xml_strout(config.c_nodename);          client_write("</c_nodename>\n", 14);
-       client_write("<c_fqdn>", 8);            xml_strout(config.c_fqdn);              client_write("</c_fqdn>\n", 10);
-       client_write("<c_humannode>", 13);      xml_strout(config.c_humannode);         client_write("</c_humannode>\n", 15);
-       client_write("<c_phonenum>", 12);       xml_strout(config.c_phonenum);          client_write("</c_phonenum>\n", 14);
-       cprintf("<c_ctdluid>%d</c_ctdluid>\n", config.c_ctdluid);
-       cprintf("<c_creataide>%d</c_creataide>\n", config.c_creataide);
-       cprintf("<c_sleeping>%d</c_sleeping>\n", config.c_sleeping);
-       cprintf("<c_initax>%d</c_initax>\n", config.c_initax);
-       cprintf("<c_regiscall>%d</c_regiscall>\n", config.c_regiscall);
-       cprintf("<c_twitdetect>%d</c_twitdetect>\n", config.c_twitdetect);
-       client_write("<c_twitroom>", 12);       xml_strout(config.c_twitroom);          client_write("</c_twitroom>\n", 14);
-       client_write("<c_moreprompt>", 14);     xml_strout(config.c_moreprompt);        client_write("</c_moreprompt>\n", 16);
-       cprintf("<c_restrict>%d</c_restrict>\n", config.c_restrict);
-       client_write("<c_site_location>", 17);  xml_strout(config.c_site_location);     client_write("</c_site_location>\n", 19);
-       client_write("<c_sysadm>", 10);         xml_strout(config.c_sysadm);            client_write("</c_sysadm>\n", 12);
-       cprintf("<c_maxsessions>%d</c_maxsessions>\n", config.c_maxsessions);
-       client_write("<c_ip_addr>", 11);        xml_strout(config.c_ip_addr);           client_write("</c_ip_addr>\n", 13);
-       cprintf("<c_port_number>%d</c_port_number>\n", config.c_port_number);
-       cprintf("<c_ep_expire_mode>%d</c_ep_expire_mode>\n", config.c_ep.expire_mode);
-       cprintf("<c_ep_expire_value>%d</c_ep_expire_value>\n", config.c_ep.expire_value);
-       cprintf("<c_userpurge>%d</c_userpurge>\n", config.c_userpurge);
-       cprintf("<c_roompurge>%d</c_roompurge>\n", config.c_roompurge);
-       client_write("<c_logpages>", 12);       xml_strout(config.c_logpages);          client_write("</c_logpages>\n", 14);
-       cprintf("<c_createax>%d</c_createax>\n", config.c_createax);
-       cprintf("<c_maxmsglen>%ld</c_maxmsglen>\n", config.c_maxmsglen);
-       cprintf("<c_min_workers>%d</c_min_workers>\n", config.c_min_workers);
-       cprintf("<c_max_workers>%d</c_max_workers>\n", config.c_max_workers);
-       cprintf("<c_pop3_port>%d</c_pop3_port>\n", config.c_pop3_port);
-       cprintf("<c_smtp_port>%d</c_smtp_port>\n", config.c_smtp_port);
-       cprintf("<c_rfc822_strict_from>%d</c_rfc822_strict_from>\n", config.c_rfc822_strict_from);
-       cprintf("<c_aide_zap>%d</c_aide_zap>\n", config.c_aide_zap);
-       cprintf("<c_imap_port>%d</c_imap_port>\n", config.c_imap_port);
-       cprintf("<c_net_freq>%ld</c_net_freq>\n", config.c_net_freq);
-       cprintf("<c_disable_newu>%d</c_disable_newu>\n", config.c_disable_newu);
-       cprintf("<c_enable_fulltext>%d</c_enable_fulltext>\n", config.c_enable_fulltext);
-       client_write("<c_baseroom>", 12);       xml_strout(config.c_baseroom);          client_write("</c_baseroom>\n", 14);
-       client_write("<c_aideroom>", 12);       xml_strout(config.c_aideroom);          client_write("</c_aideroom>\n", 14);
-       cprintf("<c_purge_hour>%d</c_purge_hour>\n", config.c_purge_hour);
-       cprintf("<c_mbxep_expire_mode>%d</c_mbxep_expire_mode>\n", config.c_mbxep.expire_mode);
-       cprintf("<c_mbxep_expire_value>%d</c_mbxep_expire_value>\n", config.c_mbxep.expire_value);
-       client_write("<c_ldap_host>", 13);      xml_strout(config.c_ldap_host);         client_write("</c_ldap_host>\n", 15);
-       cprintf("<c_ldap_port>%d</c_ldap_port>\n", config.c_ldap_port);
-       client_write("<c_ldap_base_dn>", 16);   xml_strout(config.c_ldap_base_dn);      client_write("</c_ldap_base_dn>\n", 18);
-       client_write("<c_ldap_bind_dn>", 16);   xml_strout(config.c_ldap_bind_dn);      client_write("</c_ldap_bind_dn>\n", 18);
-       client_write("<c_ldap_bind_pw>", 16);   xml_strout(config.c_ldap_bind_pw);      client_write("</c_ldap_bind_pw>\n", 18);
-       cprintf("<c_msa_port>%d</c_msa_port>\n", config.c_msa_port);
-       cprintf("<c_imaps_port>%d</c_imaps_port>\n", config.c_imaps_port);
-       cprintf("<c_pop3s_port>%d</c_pop3s_port>\n", config.c_pop3s_port);
-       cprintf("<c_smtps_port>%d</c_smtps_port>\n", config.c_smtps_port);
-       cprintf("<c_auto_cull>%d</c_auto_cull>\n", config.c_auto_cull);
-       cprintf("<c_allow_spoofing>%d</c_allow_spoofing>\n", config.c_allow_spoofing);
-       cprintf("<c_journal_email>%d</c_journal_email>\n", config.c_journal_email);
-       cprintf("<c_journal_pubmsgs>%d</c_journal_pubmsgs>\n", config.c_journal_pubmsgs);
-       client_write("<c_journal_dest>", 16);   xml_strout(config.c_journal_dest);      client_write("</c_journal_dest>\n", 18);
-       client_write("<c_default_cal_zone>", 20);       xml_strout(config.c_default_cal_zone);  client_write("</c_default_cal_zone>\n", 22);
-       cprintf("<c_pftcpdict_port>%d</c_pftcpdict_port>\n", config.c_pftcpdict_port);
-       cprintf("<c_managesieve_port>%d</c_managesieve_port>\n", config.c_managesieve_port);
-       cprintf("<c_auth_mode>%d</c_auth_mode>\n", config.c_auth_mode);
-       client_write("<c_funambol_host>", 17);  xml_strout(config.c_funambol_host);     client_write("</c_funambol_host>\n", 19);
-       cprintf("<c_funambol_port>%d</c_funambol_port>\n", config.c_funambol_port);
-       client_write("<c_funambol_source>", 19);        xml_strout(config.c_funambol_source);   client_write("</c_funambol_source>\n", 21);
-       client_write("<c_funambol_auth>", 17);  xml_strout(config.c_funambol_auth);     client_write("</c_funambol_auth>\n", 19);
-       cprintf("<c_rbl_at_greeting>%d</c_rbl_at_greeting>\n", config.c_rbl_at_greeting);
-       client_write("<c_master_user>", 15);    xml_strout(config.c_master_user);               client_write("</c_master_user>\n", 17);
-       client_write("<c_master_pass>", 15);    xml_strout(config.c_master_pass);               client_write("</c_master_pass>\n", 17);
-       client_write("<c_pager_program>", 17);  xml_strout(config.c_pager_program);             client_write("</c_pager_program>\n", 19);
-       cprintf("<c_imap_keep_from>%d</c_imap_keep_from>\n", config.c_imap_keep_from);
-       cprintf("<c_xmpp_c2s_port>%d</c_xmpp_c2s_port>\n", config.c_xmpp_c2s_port);
-       cprintf("<c_xmpp_s2s_port>%d</c_xmpp_s2s_port>\n", config.c_xmpp_s2s_port);
-       cprintf("<c_pop3_fetch>%ld</c_pop3_fetch>\n", config.c_pop3_fetch);
-       cprintf("<c_pop3_fastest>%ld</c_pop3_fastest>\n", config.c_pop3_fastest);
-       cprintf("<c_spam_flag_only>%d</c_spam_flag_only>\n", config.c_spam_flag_only);
-       cprintf("<c_nntp_port>%d</c_nntp_port>\n", config.c_nntp_port);
-       cprintf("<c_nntps_port>%d</c_nntps_port>\n", config.c_nntps_port);
-       client_write("</config>\n", 10);
-       cprintf("<progress>%d</progress>\n", 1);
-       
-       /* Export the control file */
-       get_control();
-       client_write("<control>\n", 10);
-       cprintf("<control_highest>%ld</control_highest>\n", CitControl.MMhighest);
-       cprintf("<control_flags>%u</control_flags>\n", CitControl.MMflags);
-       cprintf("<control_nextuser>%ld</control_nextuser>\n", CitControl.MMnextuser);
-       cprintf("<control_nextroom>%ld</control_nextroom>\n", CitControl.MMnextroom);
-       cprintf("<control_version>%d</control_version>\n", CitControl.version);
-       client_write("</control>\n", 11);
+       /* export the configuration database */
+       migr_export_configs();
        cprintf("<progress>%d</progress>\n", 2);
-
+       
        if (Ctx->kill_me == 0)  migr_export_users();
        cprintf("<progress>%d</progress>\n", 7);
        if (Ctx->kill_me == 0)  migr_export_openids();
@@ -531,22 +468,22 @@ void migr_do_export(void) {
        if (Ctx->kill_me == 0)  migr_export_visits();
        cprintf("<progress>%d</progress>\n", 25);
        if (Ctx->kill_me == 0)  migr_export_messages();
-       client_write("</citadel_migrate_data>\n", 24);
+       client_write(HKEY("</citadel_migrate_data>\n"));
        cprintf("<progress>%d</progress>\n", 100);
-       client_write("000\n", 4);
+       client_write(HKEY("000\n"));
        Ctx->dont_term = 0;
 }
 
 
 
 
-       
-/*
- * Here's the code that implements the import side.  It's going to end up being
- * one big loop with lots of global variables.  I don't care.  You wouldn't run
- * multiple concurrent imports anyway.  If this offends your delicate sensibilities
- * then go rewrite it in Ruby on Rails or something.
- */
+/******************************************************************************
+ *                              Import code                                   *
+ *    Here's the code that implements the import side.  It's going to end up  *
+ *        being one big loop with lots of global variables.  I don't care.    *
+ * You wouldn't run multiple concurrent imports anyway.  If this offends your *
+ * delicate sensibilities  then go rewrite it in Ruby on Rails or something.  *
+ ******************************************************************************/
 
 
 int citadel_migrate_data = 0;          /* Are we inside a <citadel_migrate_data> tag pair? */
@@ -614,105 +551,9 @@ void migr_xml_start(void *data, const char *el, const char **attr) {
                memset(&smi, 0, sizeof (struct MetaData));
                import_msgnum = 0;
        }
-
-}
-
-
-int migr_config(void *data, const char *el)
-{
-       if (!strcasecmp(el, "c_nodename"))                      SET_CFGSTRBUF(c_nodename, migr_chardata);
-       else if (!strcasecmp(el, "c_fqdn"))                     SET_CFGSTRBUF(c_fqdn, migr_chardata);
-       else if (!strcasecmp(el, "c_humannode"))                SET_CFGSTRBUF(c_humannode, migr_chardata);
-       else if (!strcasecmp(el, "c_phonenum"))                 SET_CFGSTRBUF(c_phonenum, migr_chardata);
-       else if (!strcasecmp(el, "c_ctdluid"))                  config.c_ctdluid = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_creataide"))                config.c_creataide = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_sleeping"))                 config.c_sleeping = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_initax"))                   config.c_initax = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_regiscall"))                config.c_regiscall = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_twitdetect"))               config.c_twitdetect = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_twitroom"))                 SET_CFGSTRBUF(c_twitroom, migr_chardata);
-       else if (!strcasecmp(el, "c_moreprompt"))               SET_CFGSTRBUF(c_moreprompt, migr_chardata);
-       else if (!strcasecmp(el, "c_restrict"))                 config.c_restrict = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_site_location"))            SET_CFGSTRBUF(c_site_location, migr_chardata);
-       else if (!strcasecmp(el, "c_sysadm"))                   SET_CFGSTRBUF(c_sysadm, migr_chardata);
-       else if (!strcasecmp(el, "c_maxsessions"))              config.c_maxsessions = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_ip_addr"))                  SET_CFGSTRBUF(c_ip_addr, migr_chardata);
-       else if (!strcasecmp(el, "c_port_number"))              config.c_port_number = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_ep_expire_mode"))           config.c_ep.expire_mode = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_ep_expire_value"))          config.c_ep.expire_value = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_userpurge"))                config.c_userpurge = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_roompurge"))                config.c_roompurge = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_logpages"))                 SET_CFGSTRBUF(c_logpages, migr_chardata);
-       else if (!strcasecmp(el, "c_createax"))                 config.c_createax = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_maxmsglen"))                config.c_maxmsglen = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_min_workers"))              config.c_min_workers = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_max_workers"))              config.c_max_workers = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_pop3_port"))                config.c_pop3_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_smtp_port"))                config.c_smtp_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_rfc822_strict_from"))       config.c_rfc822_strict_from = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_aide_zap"))                 config.c_aide_zap = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_imap_port"))                config.c_imap_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_net_freq"))                 config.c_net_freq = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_disable_newu"))             config.c_disable_newu = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_enable_fulltext"))          config.c_enable_fulltext = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_baseroom"))                 SET_CFGSTRBUF(c_baseroom, migr_chardata);
-       else if (!strcasecmp(el, "c_aideroom"))                 SET_CFGSTRBUF(c_aideroom, migr_chardata);
-       else if (!strcasecmp(el, "c_purge_hour"))               config.c_purge_hour = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_mbxep_expire_mode"))        config.c_mbxep.expire_mode = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_mbxep_expire_value"))       config.c_mbxep.expire_value = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_ldap_host"))                SET_CFGSTRBUF(c_ldap_host, migr_chardata);
-       else if (!strcasecmp(el, "c_ldap_port"))                config.c_ldap_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_ldap_base_dn"))             SET_CFGSTRBUF(c_ldap_base_dn, migr_chardata);
-       else if (!strcasecmp(el, "c_ldap_bind_dn"))             SET_CFGSTRBUF(c_ldap_bind_dn, migr_chardata);
-       else if (!strcasecmp(el, "c_ldap_bind_pw"))             SET_CFGSTRBUF(c_ldap_bind_pw, migr_chardata);
-       else if (!strcasecmp(el, "c_msa_port"))                 config.c_msa_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_imaps_port"))               config.c_imaps_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_pop3s_port"))               config.c_pop3s_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_smtps_port"))               config.c_smtps_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_auto_cull"))                config.c_auto_cull = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_allow_spoofing"))           config.c_allow_spoofing = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_journal_email"))            config.c_journal_email = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_journal_pubmsgs"))          config.c_journal_pubmsgs = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_journal_dest"))             SET_CFGSTRBUF(c_journal_dest, migr_chardata);
-       else if (!strcasecmp(el, "c_default_cal_zone"))         SET_CFGSTRBUF(c_default_cal_zone, migr_chardata);
-       else if (!strcasecmp(el, "c_pftcpdict_port"))           config.c_pftcpdict_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_managesieve_port"))         config.c_managesieve_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_auth_mode"))                config.c_auth_mode = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_funambol_host"))            SET_CFGSTRBUF(c_funambol_host, migr_chardata);
-       else if (!strcasecmp(el, "c_funambol_port"))            config.c_funambol_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_funambol_source"))          SET_CFGSTRBUF(c_funambol_source, migr_chardata);
-       else if (!strcasecmp(el, "c_funambol_auth"))            SET_CFGSTRBUF(c_funambol_auth, migr_chardata);
-       else if (!strcasecmp(el, "c_rbl_at_greeting"))          config.c_rbl_at_greeting = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_master_user"))              SET_CFGSTRBUF(c_master_user, migr_chardata);
-       else if (!strcasecmp(el, "c_master_pass"))              SET_CFGSTRBUF(c_master_pass, migr_chardata);
-       else if (!strcasecmp(el, "c_pager_program"))            SET_CFGSTRBUF(c_pager_program, migr_chardata);
-       else if (!strcasecmp(el, "c_imap_keep_from"))           config.c_imap_keep_from = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_xmpp_c2s_port"))            config.c_xmpp_c2s_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_xmpp_s2s_port"))            config.c_xmpp_s2s_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_pop3_fetch"))               config.c_pop3_fetch = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_pop3_fastest"))             config.c_pop3_fastest = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_spam_flag_only"))           config.c_spam_flag_only = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_nntp_port"))                config.c_nntp_port = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "c_nntps_port"))               config.c_nntps_port = atoi(ChrPtr(migr_chardata));
-       else return 0;
-       return 1; /* Found above...*/
-}
-
-int migr_controlrecord(void *data, const char *el)
-{
-       if (!strcasecmp(el, "control_highest"))         CitControl.MMhighest = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "control_flags"))              CitControl.MMflags = atoi(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "control_nextuser"))           CitControl.MMnextuser = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "control_nextroom"))           CitControl.MMnextroom = atol(ChrPtr(migr_chardata));
-       else if (!strcasecmp(el, "control_version"))            CitControl.version = atoi(ChrPtr(migr_chardata));
-
-       else if (!strcasecmp(el, "control")) {
-               CitControl.MMfulltext = (-1L);  /* always flush */
-               put_control();
-               syslog(LOG_INFO, "Completed import of control record\n");
+       else if (!strcasecmp(el, "config")) {
+               syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG START ELEMENT FIXME\033\0m");
        }
-       else return 0;
-       return 1;
 
 }
 
@@ -794,6 +635,8 @@ int migr_visitrecord(void *data, const char *el)
        else return 0;
        return 1;
 }
+
+
 void migr_xml_end(void *data, const char *el)
 {
        const char *ptr;
@@ -817,20 +660,12 @@ void migr_xml_end(void *data, const char *el)
 
        /*** CONFIG ***/
 
-       if (!strcasecmp(el, "config")) {
-               config.c_enable_fulltext = 0;   /* always disable */
-               put_config();
-               syslog(LOG_INFO, "Completed import of server configuration\n");
+       if (!strcasecmp(el, "config"))
+       {
+               syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG END ELEMENT FIXME\033\0m");
+               CtdlSetConfigInt("c_enable_fulltext", 0);       /* always disable FIXME put this somewhere more appropriate */
        }
 
-       else if ((!strncasecmp(el, HKEY("c_"))) && 
-                migr_config(data, el))
-               ; /* Nothing to do anymore */
-               
-       /*** CONTROL ***/
-       else if ((!strncasecmp(el, HKEY("control"))) && 
-                migr_controlrecord(data, el))
-               ; /* Nothing to do anymore */
        /*** USER ***/
        else if ((!strncasecmp(el, HKEY("u_"))) && 
                 migr_userrecord(data, el))
@@ -931,31 +766,44 @@ void migr_xml_end(void *data, const char *el)
 
        /*** MESSAGES ***/
        
-       else if (!strcasecmp(el, "msg_msgnum"))                 import_msgnum = atol(ChrPtr(migr_chardata));
+       else if (!strcasecmp(el, "msg_msgnum"))                 smi.meta_msgnum = import_msgnum = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "msg_meta_refcount"))          smi.meta_refcount = atoi(ChrPtr(migr_chardata));
+       else if (!strcasecmp(el, "msg_meta_rfc822_length"))     smi.meta_rfc822_length = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "msg_meta_content_type"))      safestrncpy(smi.meta_content_type, ChrPtr(migr_chardata), sizeof smi.meta_content_type);
+       else if (!strcasecmp(el, "msg_mimetype"))               safestrncpy(smi.mimetype, ChrPtr(migr_chardata), sizeof smi.mimetype);
 
        else if (!strcasecmp(el, "msg_text"))
        {
+               long rc;
+               struct CtdlMessage *msg;
 
                FlushStrBuf(migr_MsgData);
-               StrBufDecodeBase64To(migr_MsgData, migr_MsgData);
-
-               cdb_store(CDB_MSGMAIN,
-                         &import_msgnum,
-                         sizeof(long),
-                         ChrPtr(migr_MsgData), 
-                         StrLength(migr_MsgData) + 1);
-
-               smi.meta_msgnum = import_msgnum;
-               PutMetaData(&smi);
+               StrBufDecodeBase64To(migr_chardata, migr_MsgData);
+
+               msg = CtdlDeserializeMessage(import_msgnum, -1,
+                                            ChrPtr(migr_MsgData), 
+                                            StrLength(migr_MsgData));
+               if (msg != NULL) {
+                       rc = CtdlSaveThisMessage(msg, import_msgnum, 0);
+                       if (rc == 0) {
+                               PutMetaData(&smi);
+                       }
+                       CM_Free(msg);
+               }
+               else {
+                       rc = -1;
+               }
 
                syslog(LOG_INFO,
-                      "Imported message #%ld, size=%d, refcount=%d, content-type: %s\n",
+                      "%s message #%ld, size=%d, refcount=%d, bodylength=%ld, content-type: %s / %s \n",
+                      (rc!= 0)?"failed to import ":"Imported ",
                       import_msgnum,
                       StrLength(migr_MsgData),
                       smi.meta_refcount,
-                      smi.meta_content_type);
+                      smi.meta_rfc822_length,
+                      smi.meta_content_type,
+                      smi.mimetype);
+               memset(&smi, 0, sizeof(smi));
        }
 
        /*** MORE GENERAL STUFF ***/
@@ -1022,6 +870,9 @@ void migr_do_import(void) {
 
 
 
+/******************************************************************************
+ *                         Dispatcher, Common code                            *
+ ******************************************************************************/
 /*
  * Dump out the pathnames of directories which can be copied "as is"
  */
@@ -1038,12 +889,200 @@ void migr_do_listdirs(void) {
        cprintf("000\n");
 }
 
+/******************************************************************************
+ *                    Repair database integrity                               *
+ ******************************************************************************/
 
-/*
- * Common code appears in this section
- */
+StrBuf *PlainMessageBuf = NULL;
+HashList *UsedMessageIDS = NULL;
+
+int migr_restore_message_metadata(long msgnum, int refcount)
+{
+       CitContext *CCC = MyContext();
+       struct MetaData smi;
+       struct CtdlMessage *msg;
+       char *mptr = NULL;
+
+       /* We can use a static buffer here because there will never be more than
+        * one of this operation happening at any given time, and it's really best
+        * to just keep it allocated once instead of torturing malloc/free.
+        * Call this function with msgnum "-1" to free the buffer when finished.
+        */
+       static int encoded_alloc = 0;
+       static char *encoded_msg = NULL;
 
+       if (msgnum < 0) {
+               if ((encoded_alloc == 0) && (encoded_msg != NULL)) {
+                       free(encoded_msg);
+                       encoded_alloc = 0;
+                       encoded_msg = NULL;
+                       // todo FreeStrBuf(&PlainMessageBuf); PlainMessageBuf = NULL;
+               }
+               return 0;
+       }
+
+       if (PlainMessageBuf == NULL) {
+               PlainMessageBuf = NewStrBufPlain(NULL, 10*SIZ);
+       }
 
+       /* Ok, here we go ... */
+
+       msg = CtdlFetchMessage(msgnum, 1, 0);
+       if (msg == NULL) {
+               return 1;
+       }
+
+       GetMetaData(&smi, msgnum);
+       smi.meta_msgnum = msgnum;
+       smi.meta_refcount = refcount;
+       
+       /* restore the content type from the message body: */
+       mptr = bmstrcasestr(msg->cm_fields[eMesageText], "Content-type:");
+       if (mptr != NULL) {
+               char *aptr;
+               safestrncpy(smi.meta_content_type, &mptr[13], sizeof smi.meta_content_type);
+               striplt(smi.meta_content_type);
+               aptr = smi.meta_content_type;
+               while (!IsEmptyStr(aptr)) {
+                       if ((*aptr == ';')
+                           || (*aptr == ' ')
+                           || (*aptr == 13)
+                           || (*aptr == 10)) {
+                               memset(aptr, 0, sizeof(smi.meta_content_type) - (aptr - smi.meta_content_type));
+                       }
+                       else aptr++;
+               }
+       }
+
+       CCC->redirect_buffer = PlainMessageBuf;
+       CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR);
+       smi.meta_rfc822_length = StrLength(CCC->redirect_buffer);
+       CCC->redirect_buffer = NULL;
+
+
+       syslog(LOG_INFO,
+              "Setting message #%ld meta data to: refcount=%d, bodylength=%ld, content-type: %s / %s \n",
+              smi.meta_msgnum,
+              smi.meta_refcount,
+              smi.meta_rfc822_length,
+              smi.meta_content_type,
+              smi.mimetype);
+
+       PutMetaData(&smi);
+
+       CM_Free(msg);
+
+       return 0;
+}
+
+void migr_check_room_msg(long msgnum, void *userdata) {
+       fprintf(migr_global_message_list, "%ld %s\n", msgnum, CC->room.QRname);
+}
+
+
+void migr_check_rooms_backend(struct ctdlroom *buf, void *data) {
+
+       /* message list goes inside this tag */
+
+       CtdlGetRoom(&CC->room, buf->QRname);
+       CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_check_room_msg, NULL);
+}
+
+void RemoveMessagesFromRooms(StrBuf *RoomNameVec, long msgnum) {
+       struct MetaData smi;
+       const char *Pos = NULL;
+       StrBuf *oneRoom = NewStrBuf();
+
+       syslog(LOG_INFO, "removing message pointer %ld from these rooms: %s", msgnum, ChrPtr(RoomNameVec));
+
+       while (Pos != StrBufNOTNULL){
+               StrBufExtract_NextToken(oneRoom, RoomNameVec, &Pos, '|');
+               CtdlDeleteMessages(ChrPtr(oneRoom), &msgnum, 1, "");
+       };
+       GetMetaData(&smi, msgnum);
+       TDAP_AdjRefCount(msgnum, -smi.meta_refcount);
+}
+
+void migr_do_restore_meta(void) {
+       char buf[SIZ];
+       int failGetMessage;
+       long msgnum;
+       int lastnum = 0;
+       int refcount = 0;
+       CitContext *Ctx;
+       char *prn;
+       StrBuf *RoomNames;
+       char cmd[SIZ];
+
+       migr_global_message_list = fopen(migr_tempfilename1, "w");
+       if (migr_global_message_list != NULL) {
+               CtdlForEachRoom(migr_check_rooms_backend, NULL);
+               fclose(migr_global_message_list);
+       }
+
+       /*
+        * Process the 'global' message list.  (Sort it and remove dups.
+        * Dups are ok because a message may be in more than one room, but
+        * this will be handled by exporting the reference count, not by
+        * exporting the message multiple times.)
+        */
+       snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2);
+       if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno);
+
+       RoomNames = NewStrBuf();
+       Ctx = CC;
+       migr_global_message_list = fopen(migr_tempfilename2, "r");
+       if (migr_global_message_list != NULL) {
+               syslog(LOG_INFO, "Opened %s\n", migr_tempfilename1);
+               while ((Ctx->kill_me == 0) && 
+                      (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) {
+                       msgnum = atol(buf);
+                       if (msgnum == 0L) 
+                               continue;
+                       if (lastnum == 0) {
+                               lastnum = msgnum;
+                       }
+                       prn = strchr(buf, ' ');
+                       if (lastnum != msgnum) {
+                               failGetMessage = migr_restore_message_metadata(lastnum, refcount);
+                               if (failGetMessage) {
+                                       RemoveMessagesFromRooms(RoomNames, lastnum);
+                               }
+                               refcount = 1;
+                               lastnum = msgnum;
+                               if (prn != NULL)
+                                       StrBufPlain(RoomNames, prn + 1, -1);
+                               StrBufTrim(RoomNames);
+                       }
+                       else {
+                               if (prn != NULL) {
+                                       if (StrLength(RoomNames) > 0)
+                                               StrBufAppendBufPlain(RoomNames, HKEY("|"), 0);
+                                       StrBufAppendBufPlain(RoomNames, prn, -1, 1);
+                                       StrBufTrim(RoomNames);
+                               }
+                               refcount ++;
+                       }
+                       lastnum = msgnum;
+               }
+               failGetMessage = migr_restore_message_metadata(msgnum, refcount);
+               if (failGetMessage) {
+                       RemoveMessagesFromRooms(RoomNames, lastnum);
+               }
+               fclose(migr_global_message_list);
+       }
+
+       migr_restore_message_metadata(-1L, -1); /* This frees the encoding buffer */
+       cprintf("%d system analysis completed", CIT_OK);
+       Ctx->kill_me = 1;
+}
+
+
+
+
+/******************************************************************************
+ *                         Dispatcher, Common code                            *
+ ******************************************************************************/
 void cmd_migr(char *cmdbuf) {
        char cmd[32];
        
@@ -1051,6 +1090,7 @@ void cmd_migr(char *cmdbuf) {
        
        if (CtdlTrySingleUser())
        {
+               CtdlDisableHouseKeeping();
                CtdlMakeTempFileName(migr_tempfilename1, sizeof migr_tempfilename1);
                CtdlMakeTempFileName(migr_tempfilename2, sizeof migr_tempfilename2);
 
@@ -1064,13 +1104,17 @@ void cmd_migr(char *cmdbuf) {
                else if (!strcasecmp(cmd, "listdirs")) {
                        migr_do_listdirs();
                }
+               else if (!strcasecmp(cmd, "restoremeta")) {
+                       migr_do_restore_meta();
+               }
                else {
                        cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE);
                }
 
                unlink(migr_tempfilename1);
                unlink(migr_tempfilename2);
-               
+
+               CtdlEnableHouseKeeping();
                CtdlEndSingleUser();
        }
        else
@@ -1079,6 +1123,9 @@ void cmd_migr(char *cmdbuf) {
        }
 }
 
+/******************************************************************************
+ *                              Module Hook                                  *
+ ******************************************************************************/
 
 CTDL_MODULE_INIT(migrate)
 {
index 6abd80cf10a80bb82a46cc3fa3f6b4540bff27ee..0402461db3ef08998cbc5b2b0ababa947e15ae73 100644 (file)
@@ -5,21 +5,15 @@
  * is available at http://www.mrtg.org that can fetch data using external
  * scripts.  This module supplies data in the format expected by MRTG.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -78,7 +72,7 @@ void mrtg_output(long value1, long value2) {
        cprintf("%ld\n", value2);
        cprintf("%d days, %d hours, %d minutes\n",
                uptime_days, uptime_hours, uptime_minutes);
-       cprintf("%s\n", config.c_humannode);
+       cprintf("%s\n", CtdlGetConfigStr("c_humannode"));
        cprintf("000\n");
 }
 
@@ -116,7 +110,7 @@ void mrtg_users(void) {
  * Volume of messages submitted
  */
 void mrtg_messages(void) {
-       mrtg_output(CitControl.MMhighest, 0L);
+       mrtg_output(CtdlGetConfigLong("MMhighest"), 0);
 }
 
 
index c4038869f7613a414fad4ab8de92bbfd62cf41bc..9ca6ba5a957af81458a21d1323a9a639e9f851af 100644 (file)
@@ -2,7 +2,7 @@
  * This module handles shared rooms, inter-Citadel mail, and outbound
  * mailing list processing.
  *
- * Copyright (c) 2000-2012 by the citadel.org team
+ * Copyright (c) 2000-2015 by the citadel.org team
  *
  *  This program is open source software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License, version 3.
@@ -218,7 +218,7 @@ void network_deliver_digest(SpoolControl *sc)
 
        /* Where do we want bounces and other noise to be heard?
         * Surely not the list members! */
-       snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
+       snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn"));
 
        /* Now submit the message */
        valid = validate_recipients(ChrPtr(sc->Users[digestrecp]), NULL, 0);
@@ -366,7 +366,7 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char
 
        /* Where do we want bounces and other noise to be heard?
         *  Surely not the list members! */
-       snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
+       snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn"));
 
        /* Now submit the message */
        valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0);
@@ -403,8 +403,8 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon
         */
        ok_to_participate = 0;
        if (!CM_IsEmpty(msg, eNodeName)) {
-               if (!strcasecmp(msg->cm_fields[eNodeName],
-                               config.c_nodename)) {
+               if (!strcasecmp(msg->cm_fields[eNodeName], CtdlGetConfigStr("c_nodename")))
+               {
                        ok_to_participate = 1;
                }
                
@@ -595,7 +595,7 @@ void network_spool_msg(long msgnum,
 
        sc = (SpoolControl *)userdata;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
 
        if (msg == NULL)
        {
index 0edb1f11efa0e240bcf7c7c3d79ead11d21b3934..eeb35ba71b8fd060254ca953c498ffcdfae5812c 100644 (file)
@@ -2,15 +2,15 @@
  * This module handles shared rooms, inter-Citadel mail, and outbound
  * mailing list processing.
  *
- * Copyright (c) 2000-2012 by the citadel.org team
+ * Copyright (c) 2000-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License, version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  * ** NOTE **   A word on the S_NETCONFIGS semaphore:
  * This is a fairly high-level type of critical section.  It ensures that no
 #endif
 
 
+/*
+ * Bounce a message back to the sender
+ */
+void network_bounce(struct CtdlMessage **pMsg, char *reason)
+{
+       struct CitContext *CCC = CC;
+       char buf[SIZ];
+       char bouncesource[SIZ];
+       char recipient[SIZ];
+       recptypes *valid = NULL;
+       char force_room[ROOMNAMELEN];
+       static int serialnum = 0;
+       long len;
+       struct CtdlMessage *msg = *pMsg;
+       *pMsg = NULL;
+       QNM_syslog(LOG_DEBUG, "entering network_bounce()\n");
+
+       if (msg == NULL) return;
+
+       snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, CtdlGetConfigStr("c_nodename"));
+
+       /* 
+        * Give it a fresh message ID
+        */
+       len = snprintf(buf, sizeof(buf),
+                      "%ld.%04lx.%04x@%s",
+                      (long)time(NULL),
+                      (long)getpid(),
+                      ++serialnum,
+                      CtdlGetConfigStr("c_fqdn"));
+
+       CM_SetField(msg, emessageId, buf, len);
+
+       /*
+        * FIXME ... right now we're just sending a bounce; we really want to
+        * include the text of the bounced message.
+        */
+       CM_SetField(msg, eMesageText, reason, strlen(reason));
+       msg->cm_format_type = 0;
+
+       /*
+        * Turn the message around
+        */
+       CM_FlushField(msg, eRecipient);
+       CM_FlushField(msg, eDestination);
+
+       len = snprintf(recipient, sizeof(recipient), "%s@%s",
+                      msg->cm_fields[eAuthor],
+                      msg->cm_fields[eNodeName]);
+
+       CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+       CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
+
+       Netmap_AddMe(msg, HKEY("unknown_user"));
+
+       /* Now submit the message */
+       valid = validate_recipients(recipient, NULL, 0);
+       if (valid != NULL) if (valid->num_error != 0) {
+               free_recipients(valid);
+               valid = NULL;
+       }
+       if ( (valid == NULL) || (!strcasecmp(recipient, bouncesource)) ) {
+               strcpy(force_room, CtdlGetConfigStr("c_aideroom"));
+       }
+       else {
+               strcpy(force_room, "");
+       }
+       if ( (valid == NULL) && IsEmptyStr(force_room) ) {
+               strcpy(force_room, CtdlGetConfigStr("c_aideroom"));
+       }
+       CtdlSubmitMsg(msg, valid, force_room, 0);
+
+       /* Clean up */
+       if (valid != NULL) free_recipients(valid);
+       CM_Free(msg);
+       QNM_syslog(LOG_DEBUG, "leaving network_bounce()\n");
+}
+
+
 void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
        RoomNetCfgLine *nptr;
@@ -168,10 +248,10 @@ void Netmap_AddMe(struct CtdlMessage *msg, const char *defl, long defllen)
        if (CM_IsEmpty(msg, eMessagePath)) {
                CM_SetField(msg, eMessagePath, defl, defllen);
        }
-       node_len = configlen.c_nodename;
+       node_len = strlen(CtdlGetConfigStr("c_nodename"));
        if (node_len >= SIZ) 
                node_len = SIZ - 1;
-       memcpy(buf, config.c_nodename, node_len);
+       memcpy(buf, CtdlGetConfigStr("c_nodename"), node_len);
        buf[node_len] = '!';
        buf[node_len + 1] = '\0';
        CM_PrependToField(msg, eMessagePath, buf, node_len + 1);
@@ -307,7 +387,7 @@ void CalcListID(SpoolControl *sc)
                StrBufAppendBufPlain(sc->ListID, HKEY("room_"), 0);
                StrBufAppendBuf(sc->ListID, RoomName, 0);
                StrBufAppendBufPlain(sc->ListID, HKEY("."), 0);
-               StrBufAppendBufPlain(sc->ListID, config.c_fqdn, -1, 0);
+               StrBufAppendBufPlain(sc->ListID, CtdlGetConfigStr("c_fqdn"), -1, 0);
                /*
                 * this used to be:
                 * roomname <Room-Number.list-id.fqdn>
@@ -325,7 +405,7 @@ void CalcListID(SpoolControl *sc)
                StrBufAppendBufPlain(sc->Users[roommailalias], HKEY("room_"), 0);
                StrBufAppendBuf(sc->Users[roommailalias], RoomName, 0);
                StrBufAppendBufPlain(sc->Users[roommailalias], HKEY("@"), 0);
-               StrBufAppendBufPlain(sc->Users[roommailalias], config.c_fqdn, -1, 0);
+               StrBufAppendBufPlain(sc->Users[roommailalias], CtdlGetConfigStr("c_fqdn"), -1, 0);
 
                StrBufLowerCase(sc->Users[roommailalias]);
        }
@@ -375,7 +455,7 @@ void network_spoolout_room(SpoolControl *sc)
        else
        {
                snprintf(buf, sizeof buf, "room_%s@%s",
-                        CCC->room.QRname, config.c_fqdn);
+                        CCC->room.QRname, CtdlGetConfigStr("c_fqdn"));
        }
 
        for (i=0; buf[i]; ++i) {
@@ -434,6 +514,53 @@ void network_spoolout_room(SpoolControl *sc)
        }
 }
 
+
+/*
+ * Check the use table.  This is a list of messages which have recently
+ * arrived on the system.  It is maintained and queried to prevent the same
+ * message from being entered into the database multiple times if it happens
+ * to arrive multiple times by accident.
+ */
+int network_usetable(struct CtdlMessage *msg)
+{
+       StrBuf *msgid;
+       struct CitContext *CCC = CC;
+       time_t now;
+
+       /* Bail out if we can't generate a message ID */
+       if ((msg == NULL) || CM_IsEmpty(msg, emessageId))
+       {
+               return(0);
+       }
+
+       /* Generate the message ID */
+       msgid = NewStrBufPlain(CM_KEY(msg, emessageId));
+       if (haschar(ChrPtr(msgid), '@') == 0) {
+               StrBufAppendBufPlain(msgid, HKEY("@"), 0);
+               if (!CM_IsEmpty(msg, eNodeName)) {
+                       StrBufAppendBufPlain(msgid, CM_KEY(msg, eNodeName), 0);
+               }
+               else {
+                       FreeStrBuf(&msgid);
+                       return(0);
+               }
+       }
+       now = time(NULL);
+       if (CheckIfAlreadySeen("Networker Import",
+                              msgid,
+                              now, 0,
+                              eUpdate,
+                              CCC->cs_pid, 0) != 0)
+       {
+               FreeStrBuf(&msgid);
+               return(1);
+       }
+       FreeStrBuf(&msgid);
+
+       return(0);
+}
+
+
 /*
  * Process a buffer containing a single message from a single file
  * from the inbound queue 
@@ -485,7 +612,7 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg,
 
        /* Check for message routing */
        if (!CM_IsEmpty(msg, eDestination)) {
-               if (strcasecmp(msg->cm_fields[eDestination], config.c_nodename)) {
+               if (strcasecmp(msg->cm_fields[eDestination], CtdlGetConfigStr("c_nodename"))) {
 
                        /* route the message */
                        Buf = NewStrBufPlain(CM_KEY(msg,eDestination));
@@ -530,10 +657,9 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg,
                        else {  /* invalid destination node name */
                                FreeStrBuf(&Buf);
 
-                               network_bounce(msg,
+                               network_bounce(&msg,
 "A message you sent could not be delivered due to an invalid destination node"
 " name.  Please check the address and try sending the message again.\n");
-                               msg = NULL;
                                return;
 
                        }
@@ -570,10 +696,9 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg,
        else if (!CM_IsEmpty(msg, eRecipient)) {
                recp = validate_recipients(msg->cm_fields[eRecipient], NULL, 0);
                if (recp != NULL) if (recp->num_error != 0) {
-                       network_bounce(msg,
+                       network_bounce(&msg,
                                "A message you sent could not be delivered due to an invalid address.\n"
                                "Please check the address and try sending the message again.\n");
-                       msg = NULL;
                        free_recipients(recp);
                        QNM_syslog(LOG_DEBUG, "Bouncing message due to invalid recipient address.\n");
                        return;
index 9fa82734e8a278d52ba71bf5669164250177b36c..1d843b46116d072f9b44f172df4689c1c5abf19a 100644 (file)
@@ -2,15 +2,15 @@
  * This module handles shared rooms, inter-Citadel mail, and outbound
  * mailing list processing.
  *
- * Copyright (c) 2000-2012 by the citadel.org team
+ * Copyright (c) 2000-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License, version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  * ** NOTE **   A word on the S_NETCONFIGS semaphore:
  * This is a fairly high-level type of critical section.  It ensures that no
@@ -96,54 +96,6 @@ typedef struct __roomlists {
 struct RoomProcList *rplist = NULL;
 
 
-
-/*
- * Check the use table.  This is a list of messages which have recently
- * arrived on the system.  It is maintained and queried to prevent the same
- * message from being entered into the database multiple times if it happens
- * to arrive multiple times by accident.
- */
-int network_usetable(struct CtdlMessage *msg)
-{
-       StrBuf *msgid;
-       struct CitContext *CCC = CC;
-       time_t now;
-
-       /* Bail out if we can't generate a message ID */
-       if ((msg == NULL) || CM_IsEmpty(msg, emessageId))
-       {
-               return(0);
-       }
-
-       /* Generate the message ID */
-       msgid = NewStrBufPlain(CM_KEY(msg, emessageId));
-       if (haschar(ChrPtr(msgid), '@') == 0) {
-               StrBufAppendBufPlain(msgid, HKEY("@"), 0);
-               if (!CM_IsEmpty(msg, eNodeName)) {
-                       StrBufAppendBufPlain(msgid, CM_KEY(msg, eNodeName), 0);
-               }
-               else {
-                       FreeStrBuf(&msgid);
-                       return(0);
-               }
-       }
-       now = time(NULL);
-       if (CheckIfAlreadySeen("Networker Import",
-                              msgid,
-                              now, 0,
-                              eCheckUpdate,
-                              CCC->cs_pid, 0) != 0)
-       {
-               FreeStrBuf(&msgid);
-               return(1);
-       }
-       FreeStrBuf(&msgid);
-
-       return(0);
-}
-
-
-
 /*
  * Send the *entire* contents of the current room to one specific network node,
  * ignoring anything we know about which messages have already undergone
@@ -340,87 +292,6 @@ void destroy_network_queue_room_locked (void)
 }
 
 
-
-/*
- * Bounce a message back to the sender
- */
-void network_bounce(struct CtdlMessage *msg, char *reason)
-{
-       struct CitContext *CCC = CC;
-       char buf[SIZ];
-       char bouncesource[SIZ];
-       char recipient[SIZ];
-       recptypes *valid = NULL;
-       char force_room[ROOMNAMELEN];
-       static int serialnum = 0;
-       long len;
-
-       QNM_syslog(LOG_DEBUG, "entering network_bounce()\n");
-
-       if (msg == NULL) return;
-
-       snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, config.c_nodename);
-
-       /* 
-        * Give it a fresh message ID
-        */
-       len = snprintf(buf, sizeof(buf),
-                      "%ld.%04lx.%04x@%s",
-                      (long)time(NULL),
-                      (long)getpid(),
-                      ++serialnum,
-                      config.c_fqdn);
-
-       CM_SetField(msg, emessageId, buf, len);
-
-       /*
-        * FIXME ... right now we're just sending a bounce; we really want to
-        * include the text of the bounced message.
-        */
-       CM_SetField(msg, eMesageText, reason, strlen(reason));
-       msg->cm_format_type = 0;
-
-       /*
-        * Turn the message around
-        */
-       CM_FlushField(msg, eRecipient);
-       CM_FlushField(msg, eDestination);
-
-       len = snprintf(recipient, sizeof(recipient), "%s@%s",
-                      msg->cm_fields[eAuthor],
-                      msg->cm_fields[eNodeName]);
-
-       CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE));
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-       CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
-
-       Netmap_AddMe(msg, HKEY("unknown_user"));
-
-       /* Now submit the message */
-       valid = validate_recipients(recipient, NULL, 0);
-       if (valid != NULL) if (valid->num_error != 0) {
-               free_recipients(valid);
-               valid = NULL;
-       }
-       if ( (valid == NULL) || (!strcasecmp(recipient, bouncesource)) ) {
-               strcpy(force_room, config.c_aideroom);
-       }
-       else {
-               strcpy(force_room, "");
-       }
-       if ( (valid == NULL) && IsEmptyStr(force_room) ) {
-               strcpy(force_room, config.c_aideroom);
-       }
-       CtdlSubmitMsg(msg, valid, force_room, 0);
-
-       /* Clean up */
-       if (valid != NULL) free_recipients(valid);
-       CM_Free(msg);
-       QNM_syslog(LOG_DEBUG, "leaving network_bounce()\n");
-}
-
-
-
 /*
  * network_do_queue()
  * 
@@ -442,10 +313,11 @@ void network_do_queue(void)
         * Run the full set of processing tasks no more frequently
         * than once every n seconds
         */
-       if ( (time(NULL) - last_run) < config.c_net_freq ) {
+       if ( (time(NULL) - last_run) < CtdlGetConfigLong("c_net_freq") )
+       {
                full_processing = 0;
                syslog(LOG_DEBUG, "Network full processing in %ld seconds.\n",
-                      config.c_net_freq - (time(NULL)- last_run)
+                      CtdlGetConfigLong("c_net_freq") - (time(NULL)- last_run)
                );
        }
 
index 7de793905f76699979d801c97b1f105940af756e..e23918e18dfba5f50412f264297e53145512f9ea 100644 (file)
@@ -39,6 +39,4 @@ void load_network_filter_list(void);
 
 void network_queue_room(struct ctdlroom *, void *);
 ////void destroy_network_queue_room(void);
-void network_bounce(struct CtdlMessage *msg, char *reason);
-int network_usetable(struct CtdlMessage *msg);
 
index 34ea669e5d6e8edf357f816fffad9dc65e57e621..0fe749d337a8a2aef81e3f653a32eb3ad24dda39 100644 (file)
@@ -2,15 +2,15 @@
  * This module handles shared rooms, inter-Citadel mail, and outbound
  * mailing list processing.
  *
- * Copyright (c) 2000-2012 by the citadel.org team
+ * Copyright (c) 2000-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License, version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  * ** NOTE **   A word on the S_NETCONFIGS semaphore:
  * This is a fairly high-level type of critical section.  It ensures that no
@@ -256,7 +256,7 @@ eNextState NWC_SendAuth(AsyncNetworker *NW)
        SetNWCState(IO, eNWCVSAuth);
        /* We're talking to the correct node.  Now identify ourselves. */
        StrBufPrintf(NW->IO.SendBuf.Buf, "NETP %s|%s\n", 
-                    config.c_nodename
+                    CtdlGetConfigStr("c_nodename")
                     ChrPtr(NW->secret));
        NWC_DBG_SEND();
        return eSendReply;
@@ -1117,10 +1117,11 @@ void network_do_clientqueue(void)
         * Run the full set of processing tasks no more frequently
         * than once every n seconds
         */
-       if ( (time(NULL) - last_run) < config.c_net_freq ) {
+       if ( (time(NULL) - last_run) < CtdlGetConfigLong("c_net_freq") )
+       {
                full_processing = 0;
                syslog(LOG_DEBUG, "Network full processing in %ld seconds.\n",
-                       config.c_net_freq - (time(NULL)- last_run)
+                       CtdlGetConfigLong("c_net_freq") - (time(NULL)- last_run)
                );
        }
 
index b5b91db791b8d02a1bb98212088a60005266633d..dee22bdfc4fedc72808d3be289d995fb8e7c2b6f 100644 (file)
@@ -1,7 +1,7 @@
 //
 // NNTP server module (RFC 3977)
 //
-// Copyright (c) 2014 by the citadel.org team
+// Copyright (c) 2014-2015 by the citadel.org team
 //
 // This program is open source software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 3.
@@ -200,7 +200,7 @@ void nntp_greeting(void)
        }
 
        // Display the standard greeting
-       cprintf("200 %s NNTP Citadel server is not finished yet\r\n", config.c_fqdn);
+       cprintf("200 %s NNTP Citadel server is not finished yet\r\n", CtdlGetConfigStr("c_fqdn"));
 }
 
 
@@ -284,7 +284,7 @@ void nntp_authinfo_user(const char *username)
                cprintf("482 Already logged in\r\n");
                return;
        case login_too_many_users:
-               cprintf("481 Too many users are already online (maximum is %d)\r\n", config.c_maxsessions);
+               cprintf("481 Too many users are already online (maximum is %d)\r\n", CtdlGetConfigInt("c_maxsessions"));
                return;
        case login_ok:
                cprintf("381 Password required for %s\r\n", CC->curr_user);
@@ -977,7 +977,7 @@ void nntp_xover_backend(long msgnum, void *userdata) {
        if (msgnum < lr->lo) return;
        if ((lr->hi != 0) && (msgnum > lr->hi)) return;
 
-       struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0);
+       struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0, 1);
        if (msg == NULL) {
                return;
        }
@@ -1178,7 +1178,7 @@ CTDL_MODULE_INIT(nntp)
 {
        if (!threading)
        {
-               CtdlRegisterServiceHook(config.c_nntp_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntp_port"),
                                        NULL,
                                        nntp_greeting,
                                        nntp_command_loop,
@@ -1186,7 +1186,7 @@ CTDL_MODULE_INIT(nntp)
                                        CitadelServiceNNTP);
 
 #ifdef HAVE_OPENSSL
-               CtdlRegisterServiceHook(config.c_nntps_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntps_port"),
                                        NULL,
                                        nntps_greeting,
                                        nntp_command_loop,
index d43448d8d1eb4fd7f80201475e994c3771d1406c..748da3bed81af4be1ee30a0e849bb4275ec343d5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This is an implementation of OpenID 2.0 relying party support in stateless mode.
  *
- * Copyright (c) 2007-2012 by the citadel.org team
+ * Copyright (c) 2007-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -211,7 +211,7 @@ void cmd_oidl(char *argbuf) {
        struct cdbdata *cdboi;
        long usernum = 0L;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -243,7 +243,7 @@ void cmd_oida(char *argbuf) {
        long usernum;
        struct ctdluser usbuf;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -278,7 +278,7 @@ void cmd_oida(char *argbuf) {
 void cmd_oidc(char *argbuf) {
        ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -311,7 +311,7 @@ void cmd_oidd(char *argbuf) {
        int this_is_mine = 0;
        long usernum = 0L;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -358,8 +358,8 @@ int openid_create_user_via_ax(StrBuf *claimed_id, HashList *sreg_keys)
        const char *Key;
        void *Value;
 
-       if (config.c_auth_mode != AUTHMODE_NATIVE) return(1);
-       if (config.c_disable_newu) return(2);
+       if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) return(1);
+       if (CtdlGetConfigInt("c_disable_newu")) return(2);
        if (CC->logged_in) return(3);
 
        HashPos *HashPos = GetNewHashPos(sreg_keys, 0);
@@ -553,12 +553,12 @@ CURL *ctdl_openid_curl_easy_init(char *errmsg) {
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);            /* die after 30 seconds */
 
        if (
-               (!IsEmptyStr(config.c_ip_addr))
-               && (strcmp(config.c_ip_addr, "*"))
-               && (strcmp(config.c_ip_addr, "::"))
-               && (strcmp(config.c_ip_addr, "0.0.0.0"))
+               (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr")))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "*"))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "::"))
+               && (strcmp(CtdlGetConfigStr("c_ip_addr"), "0.0.0.0"))
        ) {
-               curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
+               curl_easy_setopt(curl, CURLOPT_INTERFACE, CtdlGetConfigStr("c_ip_addr"));
        }
 
        return(curl);
@@ -832,7 +832,7 @@ void cmd_oids(char *argbuf) {
        ctdl_openid *oiddata;
        int discovery_succeeded = 0;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -963,7 +963,7 @@ void cmd_oidf(char *argbuf) {
        void *Value;
        ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;
 
-       if (config.c_disable_newu)
+       if (CtdlGetConfigInt("c_disable_newu"))
        {
                cprintf("%d this system does not support openid.\n",
                        ERROR + CMD_NOT_SUPPORTED);
@@ -1108,7 +1108,7 @@ void cmd_oidf(char *argbuf) {
                         * If this system does not allow self-service new user registration, the
                         * remaining modes do not apply, so fail here and now.
                         */
-                       else if (config.c_disable_newu) {
+                       else if (CtdlGetConfigInt("c_disable_newu")) {
                                cprintf("fail\n");
                                syslog(LOG_DEBUG, "Creating user failed due to local policy");
                        }
@@ -1169,7 +1169,7 @@ CTDL_MODULE_INIT(openid_rp)
 // evcurl call this for us. curl_global_init(CURL_GLOBAL_ALL);
 
                /* Only enable the OpenID command set when native mode authentication is in use. */
-               if (config.c_auth_mode == AUTHMODE_NATIVE) {
+               if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) {
                        CtdlRegisterProtoHook(cmd_oids, "OIDS", "Setup OpenID authentication");
                        CtdlRegisterProtoHook(cmd_oidf, "OIDF", "Finalize OpenID authentication");
                        CtdlRegisterProtoHook(cmd_oidl, "OIDL", "List OpenIDs associated with an account");
index d3e3e0b50efea70002f649b28b3d4fdea1e0ffb5..13230126320254368a75848633b13f2487d1a2a4 100644 (file)
@@ -1,21 +1,15 @@
 /*
  * POP3 service for the Citadel system
  *
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  * Current status of standards conformance:
  *
@@ -721,14 +715,14 @@ CTDL_MODULE_INIT(pop3)
        {
                CtdlRegisterDebugFlagHook(HKEY("pop3srv"), SetPOP3DebugEnabled, &POP3DebugEnabled);
 
-               CtdlRegisterServiceHook(config.c_pop3_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_pop3_port"),
                                        NULL,
                                        pop3_greeting,
                                        pop3_command_loop,
                                        NULL,
                                        CitadelServicePop3);
 #ifdef HAVE_OPENSSL
-               CtdlRegisterServiceHook(config.c_pop3s_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_pop3s_port"),
                                        NULL,
                                        pop3s_greeting,
                                        pop3_command_loop,
index 950436dd8ed65d5eaa4954b5cdbba915efc9af56..700c5741983a79d7b7f304ea2973c1d2c71d3875 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Consolidate mail from remote POP3 accounts.
  *
- * Copyright (c) 2007-2011 by the citadel.org team
+ * Copyright (c) 2007-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <stdlib.h>
@@ -418,6 +414,7 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO)
        const char *HKey;
        void *vData;
        pop3aggr *RecvMsg = (pop3aggr *) IO->Data;
+       time_t seenstamp = 0;
 
        SetPOP3State(IO, eUseTable);
 
@@ -431,13 +428,15 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO)
                if (server_shutting_down)
                        return eAbort;
 
-               if (CheckIfAlreadySeen("POP3 Item Seen",
-                                      RecvMsg->CurrMsg->MsgUID,
-                                      EvGetNow(IO),
-                                      EvGetNow(IO) - USETABLE_ANTIEXPIRE,
-                                      eCheckUpdate,
-                                      IO->ID, CCID)
-                   != 0)
+               RecvMsg->CurrMsg = (FetchItem*)vData;
+
+               seenstamp = CheckIfAlreadySeen("POP3 Item Seen",
+                                              RecvMsg->CurrMsg->MsgUID,
+                                              EvGetNow(IO),
+                                              EvGetNow(IO) - USETABLE_ANTIEXPIRE,
+                                              eCheckUpdate,
+                                              IO->ID, CCID);
+               if (seenstamp != 0)
                {
                        /* Item has already been seen */
                        RecvMsg->CurrMsg->NeedFetch = 0;
@@ -539,6 +538,8 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
 
        SetPOP3State(IO, eGetMsg);
 
+       EVP3CM_syslog(LOG_DEBUG, "fast forwarding to the next unknown message");
+
        RecvMsg->CurrMsg = NULL;
        while ((RecvMsg->Pos != NULL) && 
               GetNextHashPos(RecvMsg->MsgNumbers,
@@ -551,6 +552,7 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
 
        if ((RecvMsg->CurrMsg != NULL ) && (RecvMsg->CurrMsg->NeedFetch == 1))
        {
+               EVP3CM_syslog(LOG_DEBUG, "fetching next");
                /* Message has not been seen.
                 * Tell the server to fetch the message... */
                StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
@@ -559,6 +561,7 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
                return eReadMessage;
        }
        else {
+               EVP3CM_syslog(LOG_DEBUG, "no more messages to fetch.");
                RecvMsg->State = ReadQuitState;
                return POP3_C_DispatchWriteDone(&RecvMsg->IO);
        }
@@ -572,7 +575,7 @@ eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg)
        if (!POP3C_OK) return eTerminateConnection;
        RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
                                          RecvMsg->CurrMsg->MSGSize,
-                                         config.c_maxmsglen,
+                                         CtdlGetConfigLong("c_maxmsglen"),
                                          NULL, -1,
                                          1);
 
@@ -652,7 +655,7 @@ eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg)
        AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        RecvMsg->State = GetOneMessageIDState;
-       return eReadMessage;
+       return POP3_C_DispatchWriteDone(&RecvMsg->IO);
 }
 
 eNextState POP3C_SendQuit(pop3aggr *RecvMsg)
@@ -1148,10 +1151,10 @@ void pop3client_scan(void) {
 
        become_session(&pop3_client_CC);
 
-       if (config.c_pop3_fastest < config.c_pop3_fetch)
-               fastest_scan = config.c_pop3_fastest;
+       if (CtdlGetConfigLong("c_pop3_fastest") < CtdlGetConfigLong("c_pop3_fetch"))
+               fastest_scan = CtdlGetConfigLong("c_pop3_fastest");
        else
-               fastest_scan = config.c_pop3_fetch;
+               fastest_scan = CtdlGetConfigLong("c_pop3_fetch");
 
        /*
         * Run POP3 aggregation no more frequently than once every n seconds
@@ -1184,7 +1187,7 @@ void pop3client_scan(void) {
 
 /*
        if ((palist->interval && time(NULL) > (last_run + palist->interval))
-                       || (time(NULL) > last_run + config.c_pop3_fetch))
+                       || (time(NULL) > last_run + CtdlGetConfigLong("c_pop3_fetch")))
                        pop3_do_fetching(palist->roomname, palist->pop3host,
                        palist->pop3user, palist->pop3pass, palist->keep);
                pptr = palist;
index cc03230c9bccc3c3fcaa0dd22327b274477804f4..697b63b47b986111ca86f2e88609010b90e09f9b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Bring external RSS feeds into rooms.
  *
- * Copyright (c) 2007-2012 by the citadel.org team
+ * Copyright (c) 2007-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -365,7 +365,7 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg)
                CM_SetField(&SaveMsg->Msg, eAuthor, HKEY("rss"));
        }
 
-       CM_SetField(&SaveMsg->Msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(&SaveMsg->Msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        if (SaveMsg->title != NULL) {
                long len;
                char *Sbj;
@@ -685,7 +685,7 @@ eNextState RSSAggregator_AnalyseReply(AsyncIO *IO)
                               guid,
                               EvGetNow(IO),
                               EvGetNow(IO) - USETABLE_ANTIEXPIRE,
-                              eCheckUpdate,
+                              eUpdate,
                               CCID, IO->ID)
            != 0)
        {
index 4c2e28cdc80495e92c7254bdb2d8d84eec588f0a..5329bc70aaf9ab2aec92cd287a86759dc862b87b 100644 (file)
@@ -214,6 +214,70 @@ void cmd_rwho(char *argbuf) {
        cprintf("000\n");
 }
 
+/*
+ * check for async io jobs that are stuck (didn't ping back for 10 mins)
+ */
+void dead_io_check(void) {
+       struct CitContext *nptr;
+       int nContexts, i;
+       char real_room[ROOMNAMELEN];
+       
+       /* So that we don't keep the context list locked for a long time
+        * we create a copy of it first
+        */
+       nptr = CtdlGetContextArray(&nContexts) ;
+       if (!nptr)
+       {
+               /* Couldn't malloc so we have to bail but stick to the protocol */
+               return;
+       }
+
+       time_t now = time(NULL);
+       time_t idle;
+
+       for (i=0; i<nContexts; i++) 
+       {
+               if ((nptr[i].state != CON_SYS) || (nptr[i].IO == NULL) || (nptr[i].lastcmd == 0))
+                       continue;
+
+               if (nptr[i].kill_me != 0)
+                       continue;
+               idle = now - nptr[i].lastcmd;
+               if (idle < 600) 
+                       continue;
+
+               GenerateRoomDisplay(real_room, &nptr[i], CC);
+
+               syslog(LOG_WARNING,
+                      "Found stuck event context: CC[%d] "
+
+                      "Username: '%s' "
+                      "Room: '%s' "
+                      "while talking to host: '%s' "
+                      "Status: '%s' "
+                      "stuck in IO State: '%s' "
+
+                      "idle since: %d:%d "
+                      "Triggering context termination now!",
+
+                      nptr[i].cs_pid,
+
+                      nptr[i].curr_user,
+                      real_room,
+                      nptr[i].cs_host,
+                      nptr[i].cs_clientname,
+                      nptr[i].lastcmdname,
+
+                      (int) idle / 60,
+                      (int) idle % 60);
+
+               CtdlTerminateOtherSession(nptr[i].cs_pid);
+       }
+       
+       /* release out copy of the context list */
+       free(nptr);
+
+}
 
 /*
  * Masquerade roomname
@@ -317,6 +381,8 @@ CTDL_MODULE_INIT(rwho)
                CtdlRegisterProtoHook(cmd_rchg, "RCHG", "Masquerade roomname");
                CtdlRegisterProtoHook(cmd_uchg, "UCHG", "Masquerade username");
                CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
+               CtdlRegisterSessionHook(dead_io_check, EVT_TIMER, PRIO_QUEUE + 50);
+
        }
        
        /* return our module name for the log */
index ed69de8587f600d5cb00a265cc63d3085a7f9b32..94d8a5fa34a0738a7374df3e718a3088c1e5dfa9 100644 (file)
@@ -2,7 +2,7 @@
  * This module glues libSieve to the Citadel server in order to implement
  * the Sieve mailbox filtering language (RFC 3028).
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -124,7 +124,7 @@ int ctdl_redirect(sieve2_context_t *s, void *my)
                return SIEVE2_ERROR_BADARGS;
        }
 
-       msg = CtdlFetchMessage(cs->msgnum, 1);
+       msg = CtdlFetchMessage(cs->msgnum, 1, 1);
        if (msg == NULL) {
                SV_syslog(LOG_WARNING, "REDIRECT failed: unable to fetch msg %ld", cs->msgnum);
                free_recipients(valid);
@@ -553,7 +553,7 @@ void sieve_do_msg(long msgnum, void *userdata) {
        /*
         * Make sure you include message body so you can get those second-level headers ;)
         */
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
 
        /*
@@ -626,7 +626,7 @@ void sieve_do_msg(long msgnum, void *userdata) {
        }
        if (haschar(my.envelope_from, '@') == 0) {
                strcat(my.envelope_from, "@");
-               strcat(my.envelope_from, config.c_fqdn);
+               strcat(my.envelope_from, CtdlGetConfigStr("c_fqdn"));
        }
 
        /* Keep track of the envelope-to address (use body-to if not found) */
@@ -652,7 +652,7 @@ void sieve_do_msg(long msgnum, void *userdata) {
        }
        if (haschar(my.envelope_to, '@') == 0) {
                strcat(my.envelope_to, "@");
-               strcat(my.envelope_to, config.c_fqdn);
+               strcat(my.envelope_to, CtdlGetConfigStr("c_fqdn"));
        }
 
        CM_Free(msg);
@@ -749,7 +749,7 @@ void get_sieve_config_backend(long msgnum, void *userdata) {
        long conflen;
 
        u->config_msgnum = msgnum;
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                u->config_msgnum = (-1) ;
                return;
@@ -1185,7 +1185,7 @@ void cmd_msiv(char *argbuf) {
                extract_token(script_name, argbuf, 1, '|', sizeof script_name);
                if (!IsEmptyStr(script_name)) {
                        cprintf("%d Transmit script now\n", SEND_LISTING);
-                       script_content = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+                       script_content = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0);
                        msiv_putscript(&u, script_name, script_content);
                        changes_made = 1;
                }
index a93bb438e384231052681d5ac4346aba074e8feb..00f55e06a52c89d7be45603e731c0c709d778b24 100644 (file)
@@ -20,7 +20,7 @@
  * The VRFY and EXPN commands have been removed from this implementation
  * because nobody uses these commands anymore, except for spammers.
  *
- * Copyright (c) 1998-2013 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -154,7 +154,7 @@ void smtp_greeting(int is_msa)
        /* If this config option is set, reject connections from problem
         * addresses immediately instead of after they execute a RCPT
         */
-       if ( (config.c_rbl_at_greeting) && (sSMTP->is_msa == 0) ) {
+       if ( (CtdlGetConfigInt("c_rbl_at_greeting")) && (sSMTP->is_msa == 0) ) {
                if (rbl_check(message_to_spammer)) {
                        if (server_shutting_down)
                                cprintf("421 %s\r\n", message_to_spammer);
@@ -178,7 +178,7 @@ void smtp_greeting(int is_msa)
        /* Note: the FQDN *must* appear as the first thing after the 220 code.
         * Some clients (including citmail.c) depend on it being there.
         */
-       cprintf("220 %s ESMTP Citadel server ready.\r\n", config.c_fqdn);
+       cprintf("220 %s ESMTP Citadel server ready.\r\n", CtdlGetConfigStr("c_fqdn"));
 }
 
 
@@ -284,7 +284,7 @@ void smtp_hello(long offset, long which_command)
                        cprintf("250-Greetings and joyous salutations.\r\n");
                }
                cprintf("250-HELP\r\n");
-               cprintf("250-SIZE %ld\r\n", config.c_maxmsglen);
+               cprintf("250-SIZE %ld\r\n", CtdlGetConfigLong("c_maxmsglen"));
 
 #ifdef HAVE_OPENSSL
                /*
@@ -318,7 +318,7 @@ void smtp_webcit_preferences_hack_backend(long msgnum, void *userdata) {
                return; // already got it
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                return;
        }
@@ -674,7 +674,7 @@ void smtp_mail(long offset, long flags) {
        /* Otherwise, make sure outsiders aren't trying to forge mail from
         * this system (unless, of course, c_allow_spoofing is enabled)
         */
-       else if (config.c_allow_spoofing == 0) {
+       else if (CtdlGetConfigInt("c_allow_spoofing") == 0) {
                process_rfc822_addr(ChrPtr(sSMTP->from), user, node, name);
                syslog(LOG_DEBUG, "Claimed envelope sender is '%s' == '%s' @ '%s' ('%s')",
                        ChrPtr(sSMTP->from), user, node, name
@@ -730,7 +730,7 @@ void smtp_rcpt(long offset, long flags)
        /* RBL check */
        if ( (!CCC->logged_in)  /* Don't RBL authenticated users */
           && (!sSMTP->is_lmtp) ) {     /* Don't RBL LMTP clients */
-               if (config.c_rbl_at_greeting == 0) {    /* Don't RBL again if we already did it */
+               if (CtdlGetConfigInt("c_rbl_at_greeting") == 0) {       /* Don't RBL again if we already did it */
                        if (rbl_check(message_to_spammer)) {
                                if (server_shutting_down)
                                        cprintf("421 %s\r\n", message_to_spammer);
@@ -826,7 +826,7 @@ void smtp_data(long offset, long flags)
                                "       by %s; %s\n",
                                ChrPtr(sSMTP->helo_node),
                                (long int) CCC->cs_UDSclientUID,
-                               config.c_fqdn,
+                               CtdlGetConfigStr("c_fqdn"),
                                nowstamp);
                }
                else {
@@ -837,11 +837,11 @@ void smtp_data(long offset, long flags)
                                ChrPtr(sSMTP->helo_node),
                                CCC->cs_host,
                                CCC->cs_addr,
-                               config.c_fqdn,
+                               CtdlGetConfigStr("c_fqdn"),
                                nowstamp);
                }
        }
-       body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL);
+       body = CtdlReadMessageBodyBuf(HKEY("."), CtdlGetConfigLong("c_maxmsglen"), defbody, 1, NULL);
        FreeStrBuf(&defbody);
        if (body == NULL) {
                cprintf("550 Unable to save message: internal error.\r\n");
@@ -861,12 +861,12 @@ void smtp_data(long offset, long flags)
         * to something ugly like "0000058008.Sent Items>" when the message
         * is read with a Citadel client.
         */
-       if ( (CCC->logged_in) && (config.c_rfc822_strict_from != CFG_SMTP_FROM_NOFILTER) ) {
+       if ( (CCC->logged_in) && (CtdlGetConfigInt("c_rfc822_strict_from") != CFG_SMTP_FROM_NOFILTER) ) {
                int validemail = 0;
                
                if (!CM_IsEmpty(msg, erFc822Addr)       &&
-                   ((config.c_rfc822_strict_from == CFG_SMTP_FROM_CORRECT) || 
-                    (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT)    )  )
+                   ((CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_CORRECT) || 
+                    (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT)    )  )
                {
                        if (!IsEmptyStr(CCC->cs_inet_email))
                                validemail = strcmp(CCC->cs_inet_email, msg->cm_fields[erFc822Addr]) == 0;
@@ -884,14 +884,14 @@ void smtp_data(long offset, long flags)
                        }
                }
 
-               if (!validemail && (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT)) {
+               if (!validemail && (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT)) {
                        syslog(LOG_ERR, "invalid sender '%s' - rejecting this message", msg->cm_fields[erFc822Addr]);
                        cprintf("550 Invalid sender '%s' - rejecting this message.\r\n", msg->cm_fields[erFc822Addr]);
                        return;
                }
 
-               CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-               CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
+               CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+               CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode")));
                CM_SetField(msg, eOriginalRoom, HKEY(MAILROOM));
                if (sSMTP->preferred_sender_name != NULL)
                        CM_SetField(msg, eAuthor, SKEY(sSMTP->preferred_sender_name));
@@ -1143,7 +1143,7 @@ CTDL_MODULE_INIT(smtp)
 #endif
 
 
-               CtdlRegisterServiceHook(config.c_smtp_port,     /* SMTP MTA */
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtp_port"),        /* SMTP MTA */
                                        NULL,
                                        smtp_mta_greeting,
                                        smtp_command_loop,
@@ -1151,7 +1151,7 @@ CTDL_MODULE_INIT(smtp)
                                        CitadelServiceSMTP_MTA);
 
 #ifdef HAVE_OPENSSL
-               CtdlRegisterServiceHook(config.c_smtps_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtps_port"),       /* SMTPS MTA */
                                        NULL,
                                        smtps_greeting,
                                        smtp_command_loop,
@@ -1159,7 +1159,7 @@ CTDL_MODULE_INIT(smtp)
                                        CitadelServiceSMTPS_MTA);
 #endif
 
-               CtdlRegisterServiceHook(config.c_msa_port,      /* SMTP MSA */
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_msa_port"),         /* SMTP MSA */
                                        NULL,
                                        smtp_msa_greeting,
                                        smtp_command_loop,
index df04bdcc5f713f66ebdb138c9d2bc73ab1067458..d12e06aa58e2bd064939bdca6854393d9593cba5 100644 (file)
  * The VRFY and EXPN commands have been removed from this implementation
  * because nobody uses these commands anymore, except for spammers.
  *
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -606,7 +600,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
        boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
        StrBufAppendPrintf(boundary,
                           "%s_%04x%04x",
-                          config.c_fqdn,
+                          CtdlGetConfigStr("c_fqdn"),
                           getpid(),
                           ++seq);
 
@@ -703,7 +697,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
 
        CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
        CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
-       CM_SetField(bmsg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
        CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB);
 
@@ -725,7 +719,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
 
        /* If not, post it in the Aide> room */
        if (successful_bounce == 0) {
-               CtdlSubmitMsg(bmsg, NULL, config.c_aideroom, QP_EADDR);
+               CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR);
        }
 
        /* Free up the memory we used */
@@ -842,7 +836,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
        SMTPC_syslog(LOG_DEBUG, "smtp_do_procmsg(%ld)\n", msgnum);
        ///strcpy(envelope_from, "");
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                SMTPC_syslog(LOG_ERR, "tried %ld but no such message!\n",
                       msgnum);
index 198649e1f2c00522b2f738b7ee04cbf15e1840ef..960a6e0258a7ff8be83deb99daf87041df1093f7 100644 (file)
  * RFC 2822 - Internet Message Format
  * RFC 2920 - SMTP Service Extension for Command Pipelining
  *
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -144,8 +138,7 @@ eNextState SMTPC_send_EHLO(SmtpOutMsg *Msg)
        /* At this point we know we are talking to a real SMTP server */
 
        /* Do a EHLO command.  If it fails, try the HELO command. */
-       StrBufPrintf(Msg->IO.SendBuf.Buf,
-                    "EHLO %s\r\n", config.c_fqdn);
+       StrBufPrintf(Msg->IO.SendBuf.Buf, "EHLO %s\r\n", CtdlGetConfigStr("c_fqdn"));
 
        SMTP_DBG_SEND();
        return eReadMessage;
@@ -180,8 +173,7 @@ eNextState SMTPC_read_EHLO_reply(SmtpOutMsg *Msg)
 eNextState STMPC_send_HELO(SmtpOutMsg *Msg)
 {
        AsyncIO *IO = &Msg->IO;
-       StrBufPrintf(Msg->IO.SendBuf.Buf,
-                    "HELO %s\r\n", config.c_fqdn);
+       StrBufPrintf(Msg->IO.SendBuf.Buf, "HELO %s\r\n", CtdlGetConfigStr("c_fqdn"));
 
        SMTP_DBG_SEND();
        return eReadMessage;
index 8609f91133bcd86e71d7c0f73ebeec569fe7fc8e..1cca96e3afced7b091e5c96a7c65d051c3c1e209 100644 (file)
  * The VRFY and EXPN commands have been removed from this implementation
  * because nobody uses these commands anymore, except for spammers.
  *
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -129,11 +123,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
        strcpy(bounceto, "");
        boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
 
-       StrBufAppendPrintf(boundary,
-                          "%s_%04x%04x",
-                          config.c_fqdn,
-                          getpid(),
-                          ++seq);
+       StrBufAppendPrintf(boundary, "%s_%04x%04x", CtdlGetConfigStr("c_fqdn"), getpid(), ++seq);
 
        lines = num_tokens(instr, '\n');
 
@@ -163,11 +153,9 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
        bmsg->cm_format_type = FMT_RFC822;
        CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
        CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
-       CM_SetField(bmsg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
-       StrBufAppendBufPlain(
-               BounceMB,
-               HKEY("Content-type: multipart/mixed; boundary=\""), 0);
+       StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
        StrBufAppendBuf(BounceMB, boundary, 0);
        StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
        StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
@@ -310,7 +298,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
 
                /* If not, post it in the Aide> room */
                if (successful_bounce == 0) {
-                       CtdlSubmitMsg(bmsg, NULL, config.c_aideroom, QP_EADDR);
+                       CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR);
                }
 
                /* Free up the memory we used */
index f9a823d9ed5466994f25500ba924fd253effa8e6..df7f97e77d9a92f96f2c5e35d76218b343dc767d 100644 (file)
@@ -4,21 +4,15 @@
  * http://www.spamassassin.org (the SpamAssassin project is not in any way
  * affiliated with the Citadel project).
  *
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
- * 
- * 
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * 
- * 
- * 
  */
 
 #define SPAMASSASSIN_PORT       "783"
@@ -141,8 +135,8 @@ int spam_assassin(struct CtdlMessage *msg, recptypes *recp) {
                 goto bail;
         }
         syslog(LOG_DEBUG, "<%s\n", buf);
-        syslog(LOG_DEBUG, "c_spam_flag_only setting %d\n", config.c_spam_flag_only);
-        if (config.c_spam_flag_only) {
+        syslog(LOG_DEBUG, "c_spam_flag_only setting %d\n", CtdlGetConfigInt("c_spam_flag_only"));
+        if (CtdlGetConfigInt("c_spam_flag_only")) {
                int headerlen;
                char *cur;
                char sastatus[10];
index 085f5f046d1ebca105e936a0ab0ef61e237cf79a..06eb8bcae613b8d47eb1749085c5c55b91f664f0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Transparently handle the upgrading of server data formats.
  *
- * Copyright (c) 1987-2014 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 3.
@@ -245,8 +245,8 @@ void guess_time_zone(void) {
        if (fp) {
                if (fgets(buf, sizeof buf, fp) && (strlen(buf) > 2)) {
                        buf[strlen(buf)-1] = 0;
-                       safestrncpy(config.c_default_cal_zone, buf, sizeof config.c_default_cal_zone);
-                       syslog(LOG_INFO, "Configuring timezone: %s", config.c_default_cal_zone);
+                       CtdlSetConfigStr("c_default_cal_zone", buf);
+                       syslog(LOG_INFO, "Configuring timezone: %s", buf);
                }
                fclose(fp);
        }
@@ -260,47 +260,46 @@ void guess_time_zone(void) {
  * Note that if the previous version was 0 then this is a new installation running for the first time.
  */
 void update_config(void) {
-       get_config();
 
-       if (CitControl.version < 606) {
-               config.c_rfc822_strict_from = 0;
+       int oldver = CtdlGetConfigInt("MM_hosted_upgrade_level");
+
+       if (oldver < 606) {
+               CtdlSetConfigInt("c_rfc822_strict_from", 0);
        }
 
-       if (CitControl.version < 609) {
-               config.c_purge_hour = 3;
+       if (oldver < 609) {
+               CtdlSetConfigInt("c_purge_hour", 3);
        }
 
-       if (CitControl.version < 615) {
-               config.c_ldap_port = 389;
+       if (oldver < 615) {
+               CtdlSetConfigInt("c_ldap_port", 389);
        }
 
-       if (CitControl.version < 623) {
-               strcpy(config.c_ip_addr, "*");
+       if (oldver < 623) {
+               CtdlSetConfigStr("c_ip_addr", "*");
        }
 
-       if (CitControl.version < 650) {
-               config.c_enable_fulltext = 1;
+       if (oldver < 650) {
+               CtdlSetConfigInt("c_enable_fulltext", 1);
        }
 
-       if (CitControl.version < 652) {
-               config.c_auto_cull = 1;
+       if (oldver < 652) {
+               CtdlSetConfigInt("c_auto_cull", 1);
        }
 
-       if (CitControl.version < 725) {
-               config.c_xmpp_c2s_port = 5222;
-               config.c_xmpp_s2s_port = 5269;
+       if (oldver < 725) {
+               CtdlSetConfigInt("c_xmpp_c2s_port", 5222);
+               CtdlSetConfigInt("c_xmpp_s2s_port", 5269);
        }
 
-       if (CitControl.version < 830) {
-               config.c_nntp_port = 119;
-               config.c_nntps_port = 563;
+       if (oldver < 830) {
+               CtdlSetConfigInt("c_nntp_port", 119);
+               CtdlSetConfigInt("c_nntps_port", 563);
        }
 
-       if (IsEmptyStr(config.c_default_cal_zone)) {
+       if (IsEmptyStr(CtdlGetConfigStr("c_default_cal_zone"))) {
                guess_time_zone();
        }
-
-       put_config();
 }
 
 
@@ -311,13 +310,12 @@ void update_config(void) {
  */
 void check_server_upgrades(void) {
 
-       get_control();
        syslog(LOG_INFO, "Existing database version on disk is %d.%02d",
-               (CitControl.version / 100),
-               (CitControl.version % 100)
+               (CtdlGetConfigInt("MM_hosted_upgrade_level") / 100),
+               (CtdlGetConfigInt("MM_hosted_upgrade_level") % 100)
        );
 
-       if (CitControl.version < REV_LEVEL) {
+       if (CtdlGetConfigInt("MM_hosted_upgrade_level") < REV_LEVEL) {
                syslog(LOG_WARNING,
                        "Server hosted updates need to be processed at this time.  Please wait..."
                );
@@ -328,29 +326,29 @@ void check_server_upgrades(void) {
 
        update_config();
 
-       if ((CitControl.version > 000) && (CitControl.version < 555)) {
+       if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 555)) {
                syslog(LOG_EMERG, "This database is too old to be upgraded.  Citadel server will exit.");
                exit(EXIT_FAILURE);
        }
-       if ((CitControl.version > 000) && (CitControl.version < 591)) {
+       if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 591)) {
                bump_mailbox_generation_numbers();
        }
-       if ((CitControl.version > 000) && (CitControl.version < 608)) {
+       if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 608)) {
                convert_ctdluid_to_minusone();
        }
-       if ((CitControl.version > 000) && (CitControl.version < 659)) {
+       if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 659)) {
                rebuild_euid_index();
        }
-       if (CitControl.version < 735) {
+       if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 735) {
                fix_sys_user_name();
        }
-       if (CitControl.version < 736) {
+       if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 736) {
                rebuild_usersbynumber();
        }
-       if (CitControl.version < 790) {
+       if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 790) {
                remove_thread_users();
        }
-       if (CitControl.version < 810) {
+       if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 810) {
                struct ctdlroom QRoom;
                if (!CtdlGetRoom(&QRoom, SMTP_SPOOLOUT_ROOM)) {
                        QRoom.QRdefaultview = VIEW_QUEUE;
@@ -362,25 +360,23 @@ void check_server_upgrades(void) {
                }
        }
 
-       CitControl.version = REV_LEVEL;
+       CtdlSetConfigInt("MM_hosted_upgrade_level", REV_LEVEL);
 
        /*
         * Negative values for maxsessions are not allowed.
         */
-       if (config.c_maxsessions < 0) {
-               config.c_maxsessions = 0;
+       if (CtdlGetConfigInt("c_maxsessions") < 0) {
+               CtdlSetConfigInt("c_maxsessions", 0);
        }
 
        /* We need a system default message expiry policy, because this is
         * the top level and there's no 'higher' policy to fall back on.
         * By default, do not expire messages at all.
         */
-       if (config.c_ep.expire_mode == 0) {
-               config.c_ep.expire_mode = EXPIRE_MANUAL;
-               config.c_ep.expire_value = 0;
+       if (CtdlGetConfigInt("c_ep_mode") == 0) {
+               CtdlSetConfigInt("c_ep_mode", EXPIRE_MANUAL);
+               CtdlSetConfigInt("c_ep_value", 0);
        }
-
-       put_control();
 }
 
 
index 39820f7762dc7a821609c060995ec6ecb99c77c0..5c3a3a7259adfad4a3ef82f8963e23d3742e7a8b 100644 (file)
@@ -2,7 +2,7 @@
  * A server-side module for Citadel which supports address book information
  * using the standard vCard format.
  * 
- * Copyright (c) 1999-2012 by the citadel.org team
+ * Copyright (c) 1999-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
  * set global flag calling for an aide to validate new users
  */
 void set_mm_valid(void) {
+       int flags = 0;
+
        begin_critical_section(S_CONTROL);
-       get_control();
-       CitControl.MMflags = CitControl.MMflags | MM_VALID ;
-       put_control();
+       flags = CtdlGetConfigInt("MMflags");
+       flags = flags | MM_VALID ;
+       CtdlSetConfigInt("MMflags", flags);
        end_critical_section(S_CONTROL);
 }
 
@@ -185,7 +187,7 @@ int vcard_directory_add_user(char *internet_addr, char *citadel_addr) {
 void vcard_add_to_directory(long msgnum, void *data) {
        struct CtdlMessage *msg;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg != NULL) {
                vcard_extract_internet_addresses(msg, vcard_directory_add_user);
        }
@@ -385,7 +387,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
 
        /* If users cannot create their own accounts, they cannot re-register either. */
        if ( (yes_my_citadel_config) &&
-            (config.c_disable_newu) &&
+            (CtdlGetConfigInt("c_disable_newu")) &&
             (CCC->user.axlevel < AxAideU) &&
             (CCC->vcard_updated_by_ldap==0) )
        {
@@ -433,7 +435,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
        /* Insert or replace RFC2739-compliant free/busy URL */
        if (yes_my_citadel_config) {
                sprintf(buf, "http://%s/%s.vfb",
-                       config.c_fqdn,
+                       CtdlGetConfigStr("c_fqdn"),
                        usbuf.fullname);
                for (i=0; buf[i]; ++i) {
                        if (buf[i] == ' ') buf[i] = '_';
@@ -653,7 +655,7 @@ struct vCard *vcard_get_user(struct ctdluser *u) {
 
        if (VCmsgnum < 0L) return vcard_new();
 
-       msg = CtdlFetchMessage(VCmsgnum, 1);
+       msg = CtdlFetchMessage(VCmsgnum, 1, 1);
        if (msg == NULL) return vcard_new();
 
        v = vcard_load(msg->cm_fields[eMesageText]);
@@ -723,7 +725,7 @@ void cmd_regi(char *argbuf) {
        }
 
        /* If users cannot create their own accounts, they cannot re-register either. */
-       if ( (config.c_disable_newu) && (CCC->user.axlevel < AxAideU) ) {
+       if ( (CtdlGetConfigInt("c_disable_newu")) && (CCC->user.axlevel < AxAideU) ) {
                cprintf("%d Self-service registration is not allowed here.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
        }
@@ -865,7 +867,7 @@ void vcard_newuser(struct ctdluser *usbuf) {
 
 #ifdef HAVE_GETPWUID_R
        /* If using host auth mode, we add an email address based on the login */
-       if (config.c_auth_mode == AUTHMODE_HOST) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
                struct passwd pwd;
                char pwd_buffer[SIZ];
                
@@ -876,9 +878,9 @@ void vcard_newuser(struct ctdluser *usbuf) {
                syslog(LOG_DEBUG, "Searching for uid %d", usbuf->uid);
                if (getpwuid_r(usbuf->uid, &pwd, pwd_buffer, sizeof pwd_buffer, &result) == 0) {
 #endif // HAVE_GETPWUID_R
-                       snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, config.c_fqdn);
+                       snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, CtdlGetConfigStr("c_fqdn"));
                        vcard_add_prop(v, "email;internet", buf);
-                       need_default_vcard=0;
+                       need_default_vcard = 0;
                }
        }
 #endif
@@ -889,7 +891,7 @@ void vcard_newuser(struct ctdluser *usbuf) {
         * Is this an LDAP session?  If so, copy various LDAP attributes from the directory entry
         * into the user's vCard.
         */
-       if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
             //uid_t ldap_uid;
            int found_user;
             char ldap_cn[512];
@@ -899,7 +901,7 @@ void vcard_newuser(struct ctdluser *usbuf) {
                if (Ctdl_LDAP_to_vCard(ldap_dn, v)) {
                        /* Allow global address book and internet directory update without login long enough to write this. */
                        CC->vcard_updated_by_ldap++;  /* Otherwise we'll only update the user config. */
-                       need_default_vcard=0;
+                       need_default_vcard = 0;
                        syslog(LOG_DEBUG, "LDAP Created Initial Vcard for %s\n",usbuf->fullname);
                }
            }
@@ -907,7 +909,7 @@ void vcard_newuser(struct ctdluser *usbuf) {
 #endif
        if (need_default_vcard!=0) {
          /* Everyone gets an email address based on their display name */
-         snprintf(buf, sizeof buf, "%s@%s", usbuf->fullname, config.c_fqdn);
+         snprintf(buf, sizeof buf, "%s@%s", usbuf->fullname, CtdlGetConfigStr("c_fqdn"));
          for (i=0; buf[i]; ++i) {
                if (buf[i] == ' ') buf[i] = '_';
          }
@@ -938,7 +940,7 @@ void vcard_purge(struct ctdluser *usbuf) {
        msg->cm_format_type = 0;
        CM_SetField(msg, eAuthor, usbuf->fullname, strlen(usbuf->fullname));
        CM_SetField(msg, eOriginalRoom, HKEY(ADDRESS_BOOK_ROOM));
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        CM_SetField(msg, eMesageText, HKEY("Purge this vCard\n"));
 
        len = snprintf(buf, sizeof buf, VCARD_EXT_FORMAT,
@@ -1010,7 +1012,7 @@ void vcard_delete_remove(char *room, long msgnum) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
 
        if (CM_IsEmpty(msg, eMesageText))
@@ -1137,7 +1139,7 @@ void dvca_mime_callback(char *name, char *filename, char *partnum, char *disp,
 void dvca_callback(long msgnum, void *userdata) {
        struct CtdlMessage *msg = NULL;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        mime_parser(CM_RANGE(msg, eMesageText),
                    *dvca_mime_callback,        /* callback function */
@@ -1281,7 +1283,7 @@ void vcard_session_login_hook(void) {
         * Is this an LDAP session?  If so, copy various LDAP attributes from the directory entry
         * into the user's vCard.
         */
-       if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
                v = vcard_get_user(&CCC->user);
                if (v) {
                        if (Ctdl_LDAP_to_vCard(CCC->ldap_dn, v)) {
@@ -1361,7 +1363,7 @@ void strip_addresses_already_have(long msgnum, void *userdata) {
 
        collected_addresses = (char *)userdata;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        v = vcard_load(msg->cm_fields[eMesageText]);
        CM_Free(msg);
@@ -1553,7 +1555,7 @@ CTDL_MODULE_INIT(vcard)
                }
 
                /* for postfix tcpdict */
-               CtdlRegisterServiceHook(config.c_pftcpdict_port,        /* Postfix */
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_pftcpdict_port"),   /* Postfix */
                                        NULL,
                                        check_get_greeting,
                                        check_get,
index 79845fa8a341d0d25cbc24521b8138bbac54f1b5..4642d13d84d24c0b72ffbbc9399fc07e5c95db1a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Server-side module for Wiki rooms.  This handles things like version control. 
  * 
- * Copyright (c) 2009-2012 by the citadel.org team
+ * Copyright (c) 2009-2015 by the citadel.org team
  *
  * This program is open source software.  You can redistribute it and/or
  * modify it under the terms of the GNU General Public License, version 3.
@@ -127,7 +127,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
        /* See if we can retrieve the previous version. */
        old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room);
        if (old_msgnum > 0L) {
-               old_msg = CtdlFetchMessage(old_msgnum, 1);
+               old_msg = CtdlFetchMessage(old_msgnum, 1, 1);
        }
        else {
                old_msg = NULL;
@@ -208,7 +208,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
        history_msgnum = CtdlLocateMessageByEuid(history_page, &CCC->room);
        history_msg = NULL;
        if (history_msgnum > 0L) {
-               history_msg = CtdlFetchMessage(history_msgnum, 1);
+               history_msg = CtdlFetchMessage(history_msgnum, 1, 1);
        }
 
        /* Create a new history message if necessary */
@@ -303,7 +303,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
                                           uuid,
                                           Now,
                                           CCC->user.fullname,
-                                          config.c_nodename);
+                                          CtdlGetConfigStr("c_nodename"));
 
                        memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0);
 
@@ -390,7 +390,7 @@ void wiki_history(char *pagename) {
        snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename);
        msgnum = CtdlLocateMessageByEuid(history_page_name, &CC->room);
        if (msgnum > 0L) {
-               msg = CtdlFetchMessage(msgnum, 1);
+               msg = CtdlFetchMessage(msgnum, 1, 1);
        }
        else {
                msg = NULL;
@@ -522,7 +522,7 @@ void wiki_rev(char *pagename, char *rev, char *operation)
         */
        msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room);
        if (msgnum > 0L) {
-               msg = CtdlFetchMessage(msgnum, 1);
+               msg = CtdlFetchMessage(msgnum, 1, 1);
        }
        else {
                msg = NULL;
@@ -556,7 +556,7 @@ void wiki_rev(char *pagename, char *rev, char *operation)
        snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename);
        msgnum = CtdlLocateMessageByEuid(history_page_name, &CCC->room);
        if (msgnum > 0L) {
-               msg = CtdlFetchMessage(msgnum, 1);
+               msg = CtdlFetchMessage(msgnum, 1, 1);
        }
        else {
                msg = NULL;
@@ -643,7 +643,7 @@ void wiki_rev(char *pagename, char *rev, char *operation)
                        CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
                        CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email));
                        CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
-                       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+                       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
                        CM_SetField(msg, eExclusiveID, pagename, strlen(pagename));
                        msgnum = CtdlSubmitMsg(msg, NULL, "", 0);       /* Replace the current revision */
                }
index 64dc8b7aa2f4e723a1d8a75be85e536506a546b1..36b1d33ce998be92d06b708a6272cbaac6f13954 100644 (file)
@@ -668,7 +668,7 @@ extern void xmpp_cleanup_events(void);
 CTDL_MODULE_INIT(xmpp)
 {
        if (!threading) {
-               CtdlRegisterServiceHook(config.c_xmpp_c2s_port,
+               CtdlRegisterServiceHook(CtdlGetConfigInt("c_xmpp_c2s_port"),
                                        NULL,
                                        xmpp_greeting,
                                        xmpp_command_loop,
index d716d4b1a3b39b9bd4f35e3be040653dd51e23c9..a3be435f73e7c3799e8c1ec4775aa61c0916b6d8 100644 (file)
@@ -158,7 +158,7 @@ void xmpp_destroy_buddy(char *presence_jid, int aggressively) {
        );
        cprintf("<query xmlns=\"jabber:iq:roster\">");
        cprintf("<item jid=\"%s\" subscription=\"remove\">", xmlesc(xmlbuf1, presence_jid, sizeof xmlbuf1));
-       cprintf("<group>%s</group>", xmlesc(xmlbuf1, config.c_humannode, sizeof xmlbuf1));
+       cprintf("<group>%s</group>", xmlesc(xmlbuf1, CtdlGetConfigStr("c_humannode"), sizeof xmlbuf1));
        cprintf("</item>");
        cprintf("</query>"
                "</iq>"
@@ -229,7 +229,7 @@ void xmpp_fetch_mortuary_backend(long msgnum, void *userdata) {
        char *ptr = NULL;
        char *lasts = NULL;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                return;
        }
index df7671798a280cbccf6f04756c08fb5845315ca0..848fcc735897a79eceeab0c876098c399638155b 100644 (file)
@@ -61,7 +61,7 @@ void xmpp_roster_item(struct CitContext *cptr) {
                xmlesc(xmlbuf1, cptr->cs_inet_email, sizeof xmlbuf1),
                xmlesc(xmlbuf2, cptr->user.fullname, sizeof xmlbuf2)
        );
-       cprintf("<group>%s</group>", xmlesc(xmlbuf1, config.c_humannode, sizeof xmlbuf1));
+       cprintf("<group>%s</group>", xmlesc(xmlbuf1, CtdlGetConfigStr("c_humannode"), sizeof xmlbuf1));
        cprintf("</item>");
 }
 
index ddc12aafdba517bfa33030a5873582455138d836..d8b1ac9d2bd6b573806c92294731f0b81f4c1972 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Implements the message store.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3.
@@ -22,6 +22,7 @@
 #include "ctdl_module.h"
 #include "citserver.h"
 #include "control.h"
+#include "config.h"
 #include "clientsocket.h"
 #include "genstamp.h"
 #include "room_ops.h"
@@ -737,7 +738,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                                        free(msglist);
                                        return -1;
                                }
-                               msg = CtdlFetchMessage(msglist[a], 1);
+                               msg = CtdlFetchMessage(msglist[a], 1, 1);
                                if (msg != NULL) {
                                        if (CtdlMsgCmp(msg, compare)) {
                                                msglist[a] = 0L;
@@ -1083,33 +1084,18 @@ void mime_spew_section(char *name, char *filename, char *partnum, char *disp,
        }
 }
 
-
-/*
- * Load a message from disk into memory.
- * This is used by CtdlOutputMsg() and other fetch functions.
- *
- * NOTE: Caller is responsible for freeing the returned CtdlMessage struct
- *       using the CtdlMessageFree() function.
- */
-struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
+struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length)
 {
        struct CitContext *CCC = CC;
-       struct cdbdata *dmsgtext;
        struct CtdlMessage *ret = NULL;
-       char *mptr;
-       char *upper_bound;
+       const char *mptr;
+       const char *upper_bound;
        cit_uint8_t ch;
        cit_uint8_t field_header;
        eMsgField which;
 
-       MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body);
-       dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long));
-       if (dmsgtext == NULL) {
-               MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body);
-               return NULL;
-       }
-       mptr = dmsgtext->ptr;
-       upper_bound = mptr + dmsgtext->len;
+       mptr = Buffer;
+       upper_bound = Buffer + Length;
 
        /* Parse the three bytes that begin EVERY message on disk.
         * The first is always 0xFF, the on-disk magic number.
@@ -1119,7 +1105,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        ch = *mptr++;
        if (ch != 255) {
                MSG_syslog(LOG_ERR, "Message %ld appears to be corrupted.\n", msgnum);
-               cdb_free(dmsgtext);
                return NULL;
        }
        ret = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
@@ -1129,13 +1114,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        ret->cm_anon_type = *mptr++;    /* Anon type byte */
        ret->cm_format_type = *mptr++;  /* Format type byte */
 
-
-       if (dmsgtext->ptr[dmsgtext->len - 1] != '\0')
-       {
-               MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body);
-               dmsgtext->ptr[dmsgtext->len - 1] = '\0';
-       }
-
        /*
         * The rest is zero or more arbitrary fields.  Load them in.
         * We're done when we encounter either a zero-length field or
@@ -1165,8 +1143,44 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
 
        } while ((mptr < upper_bound) && (field_header != 'M'));
 
+       return (ret);
+}
+
+
+/*
+ * Load a message from disk into memory.
+ * This is used by CtdlOutputMsg() and other fetch functions.
+ *
+ * NOTE: Caller is responsible for freeing the returned CtdlMessage struct
+ *       using the CtdlMessageFree() function.
+ */
+struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks)
+{
+       struct CitContext *CCC = CC;
+       struct cdbdata *dmsgtext;
+       struct CtdlMessage *ret = NULL;
+
+       MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body);
+       dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long));
+       if (dmsgtext == NULL) {
+               MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body);
+               return NULL;
+       }
+
+       if (dmsgtext->ptr[dmsgtext->len - 1] != '\0')
+       {
+               MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body);
+               dmsgtext->ptr[dmsgtext->len - 1] = '\0';
+       }
+
+       ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext->ptr, dmsgtext->len);
+
        cdb_free(dmsgtext);
 
+       if (ret == NULL) {
+               return NULL;
+       }
+
        /* Always make sure there's something in the msg text field.  If
         * it's NULL, the message text is most likely stored separately,
         * so go ahead and fetch that.  Failing that, just set a dummy
@@ -1184,7 +1198,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        }
 
        /* Perform "before read" hooks (aborting if any return nonzero) */
-       if (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0) {
+       if (run_msg_hooks && (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0)) {
                CM_Free(ret);
                return NULL;
        }
@@ -1584,10 +1598,10 @@ int CtdlOutputMsg(long msg_num,         /* message number (local) to fetch */
         * request that we don't even bother loading the body into memory.
         */
        if (headers_only == HEADERS_FAST) {
-               TheMessage = CtdlFetchMessage(msg_num, 0);
+               TheMessage = CtdlFetchMessage(msg_num, 0, 1);
        }
        else {
-               TheMessage = CtdlFetchMessage(msg_num, 1);
+               TheMessage = CtdlFetchMessage(msg_num, 1, 1);
        }
 
        if (TheMessage == NULL) {
@@ -1818,7 +1832,7 @@ void OutputRFC822MsgHeaders(
                                if (haschar(mptr, '@') == 0)
                                {
                                        sanitize_truncated_recipient(mptr);
-                                       cprintf("To: %s@%s", mptr, config.c_fqdn);
+                                       cprintf("To: %s@%s", mptr, CtdlGetConfigStr("c_fqdn"));
                                        cprintf("%s", nl);
                                }
                                else
@@ -2166,7 +2180,7 @@ int CtdlOutputPreLoadedMsg(
        strcpy(suser, "");
        strcpy(luser, "");
        strcpy(fuser, "");
-       memcpy(snode, CFG_KEY(c_nodename) + 1);
+       memcpy(snode, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")) + 1);
        if (mode == MT_RFC822) 
                OutputRFC822MsgHeaders(
                        TheMessage,
@@ -2425,7 +2439,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
                                msg = supplied_msg;
                        }
                        else {
-                               msg = CtdlFetchMessage(msgid, 0);
+                               msg = CtdlFetchMessage(msgid, 0, 1);
                        }
        
                        if (msg != NULL) {
@@ -2491,75 +2505,101 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid,
  * called by server-side modules.
  *
  */
-long send_message(struct CtdlMessage *msg) {
+long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) {
        struct CitContext *CCC = CC;
-       long newmsgid;
        long retval;
-       char msgidbuf[256];
-       long msgidbuflen;
        struct ser_ret smr;
        int is_bigmsg = 0;
        char *holdM = NULL;
        long holdMLen = 0;
 
-       /* Get a new message number */
-       newmsgid = get_new_message_number();
-       msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s",
-                              (long unsigned int) time(NULL),
-                              (long unsigned int) newmsgid,
-                              config.c_fqdn
-               );
-
-       /* Generate an ID if we don't have one already */
-       if (CM_IsEmpty(msg, emessageId)) {
-               CM_SetField(msg, emessageId, msgidbuf, msgidbuflen);
-       }
-
-       /* If the message is big, set its body aside for storage elsewhere */
-       if (!CM_IsEmpty(msg, eMesageText)) {
-               if (msg->cm_lengths[eMesageText] > BIGMSG) {
-                       is_bigmsg = 1;
-                       holdM = msg->cm_fields[eMesageText];
-                       msg->cm_fields[eMesageText] = NULL;
-                       holdMLen = msg->cm_lengths[eMesageText];
-                       msg->cm_lengths[eMesageText] = 0;
-               }
+       /*
+        * If the message is big, set its body aside for storage elsewhere
+        * and we hide the message body from the serializer
+        */
+       if (!CM_IsEmpty(msg, eMesageText) && msg->cm_lengths[eMesageText] > BIGMSG)
+       {
+               is_bigmsg = 1;
+               holdM = msg->cm_fields[eMesageText];
+               msg->cm_fields[eMesageText] = NULL;
+               holdMLen = msg->cm_lengths[eMesageText];
+               msg->cm_lengths[eMesageText] = 0;
        }
 
        /* Serialize our data structure for storage in the database */  
        CtdlSerializeMessage(&smr, msg);
 
        if (is_bigmsg) {
+               /* put the message body back into the message */
                msg->cm_fields[eMesageText] = holdM;
                msg->cm_lengths[eMesageText] = holdMLen;
        }
 
        if (smr.len == 0) {
-               cprintf("%d Unable to serialize message\n",
-                       ERROR + INTERNAL_ERROR);
+               if (Reply) {
+                       cprintf("%d Unable to serialize message\n",
+                               ERROR + INTERNAL_ERROR);
+               }
+               else {
+                       MSGM_syslog(LOG_ERR, "CtdlSaveMessage() unable to serialize message");
+
+               }
                return (-1L);
        }
 
        /* Write our little bundle of joy into the message base */
-       if (cdb_store(CDB_MSGMAIN, &newmsgid, (int)sizeof(long),
-                     smr.ser, smr.len) < 0) {
-               MSGM_syslog(LOG_ERR, "Can't store message\n");
-               retval = 0L;
-       } else {
+       retval = cdb_store(CDB_MSGMAIN, &msgid, (int)sizeof(long),
+                          smr.ser, smr.len);
+       if (retval < 0) {
+               MSG_syslog(LOG_ERR, "Can't store message %ld: %ld", msgid, retval);
+       }
+       else {
                if (is_bigmsg) {
-                       cdb_store(CDB_BIGMSGS,
-                                 &newmsgid,
-                                 (int)sizeof(long),
-                                 holdM,
-                                 (holdMLen + 1)
+                       retval = cdb_store(CDB_BIGMSGS,
+                                          &msgid,
+                                          (int)sizeof(long),
+                                          holdM,
+                                          (holdMLen + 1)
                                );
+                       if (retval < 0) {
+                               MSG_syslog(LOG_ERR, "failed to store message body for msgid %ld:  %ld",
+                                          msgid, retval);
+                       }
                }
-               retval = newmsgid;
        }
 
        /* Free the memory we used for the serialized message */
        free(smr.ser);
 
+       return(retval);
+}
+
+long send_message(struct CtdlMessage *msg) {
+       long newmsgid;
+       long retval;
+       char msgidbuf[256];
+       long msgidbuflen;
+
+       /* Get a new message number */
+       newmsgid = get_new_message_number();
+
+       /* Generate an ID if we don't have one already */
+       if (CM_IsEmpty(msg, emessageId)) {
+               msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s",
+                                      (long unsigned int) time(NULL),
+                                      (long unsigned int) newmsgid,
+                                      CtdlGetConfigStr("c_fqdn")
+                       );
+
+               CM_SetField(msg, emessageId, msgidbuf, msgidbuflen);
+       }
+
+       retval = CtdlSaveThisMessage(msg, newmsgid, 1);
+
+       if (retval == 0) {
+               retval = newmsgid;
+       }
+
        /* Return the *local* message ID to the caller
         * (even if we're storing an incoming network message)
         */
@@ -2576,7 +2616,7 @@ long send_message(struct CtdlMessage *msg) {
  * serialized message in memory.  THE LATTER MUST BE FREED BY THE CALLER.
  */
 void CtdlSerializeMessage(struct ser_ret *ret,         /* return values */
-                      struct CtdlMessage *msg) /* unserialized msg */
+                         struct CtdlMessage *msg)      /* unserialized msg */
 {
        struct CitContext *CCC = CC;
        size_t wlen;
@@ -2767,7 +2807,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        if (TWITDETECT) {
                if (CCC->user.axlevel == AxProbU) {
                        strcpy(hold_rm, actual_rm);
-                       strcpy(actual_rm, config.c_twitroom);
+                       strcpy(actual_rm, CtdlGetConfigStr("c_twitroom"));
                        MSGM_syslog(LOG_DEBUG, "Diverting to twit room\n");
                }
        }
@@ -2850,7 +2890,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        if ((!CCC->internal_pgm) || (recps == NULL)) {
                if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) {
                        MSGM_syslog(LOG_ERR, "ERROR saving message pointer!\n");
-                       CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg);
+                       CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg);
                }
        }
 
@@ -2879,7 +2919,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        {
                if (CCC->logged_in) 
                        snprintf(bounce_to, sizeof bounce_to, "%s@%s",
-                                CCC->user.fullname, config.c_nodename);
+                                CCC->user.fullname, CtdlGetConfigStr("c_nodename"));
                else 
                        snprintf(bounce_to, sizeof bounce_to, "%s@%s",
                                 msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]);
@@ -2912,7 +2952,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                        }
                        else {
                                MSG_syslog(LOG_DEBUG, "No user <%s>\n", recipient);
-                               CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg);
+                               CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg);
                        }
                }
                recps->recp_local = pch;
@@ -2957,13 +2997,13 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
        }
        else {
                if (recps == NULL) {
-                       qualified_for_journaling = config.c_journal_pubmsgs;
+                       qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs");
                }
                else if (recps->num_local + recps->num_ignet + recps->num_internet > 0) {
-                       qualified_for_journaling = config.c_journal_email;
+                       qualified_for_journaling = CtdlGetConfigInt("c_journal_email");
                }
                else {
-                       qualified_for_journaling = config.c_journal_pubmsgs;
+                       qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs");
                }
        }
 
@@ -3026,7 +3066,7 @@ void quickie_message(const char *from,
 
        if (fromaddr != NULL) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr));
        if (room != NULL) CM_SetField(msg, eOriginalRoom, room, strlen(room));
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
        if (to != NULL) {
                CM_SetField(msg, eRecipient, to, strlen(to));
                recp = validate_recipients(to, NULL, 0);
@@ -3499,8 +3539,8 @@ struct CtdlMessage *CtdlMakeMessageLen(
                CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
        }
 
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-       CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+       CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode")));
 
        if (rcplen > 0) {
                CM_SetField(msg, eRecipient, recipient, rcplen);
@@ -3552,7 +3592,7 @@ struct CtdlMessage *CtdlMakeMessageLen(
        }
        else {
                StrBuf *MsgBody;
-               MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+               MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0);
                if (MsgBody != NULL) {
                        CM_SetAsFieldSB(msg, eMesageText, &MsgBody);
                }
@@ -3568,7 +3608,7 @@ struct CtdlMessage *CtdlMakeMessageLen(
  * API function to delete messages which match a set of criteria
  * (returns the actual number of messages deleted)
  */
-int CtdlDeleteMessages(char *room_name,                /* which room */
+int CtdlDeleteMessages(const char *room_name,          /* which room */
                       long *dmsgnums,          /* array of msg numbers to be deleted */
                       int num_dmsgnums,        /* number of msgs to be deleted, or 0 for "any" */
                       char *content_type       /* or "" for any.  regular expressions expected. */
@@ -4033,8 +4073,8 @@ void CtdlWriteObject(char *req_room,                      /* Room to stuff it in */
        msg->cm_format_type = 4;
        CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
        CM_SetField(msg, eOriginalRoom, req_room, strlen(req_room));
-       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
-       CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
+       CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+       CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode")));
        msg->cm_flags = flags;
        
        CM_SetAsFieldSB(msg, eMesageText, &encoded_message);
index 6d5f726baafd6fe68cd73aa999829c6b3631cbb1..4b53032eb75157e727d2b9bfcdcef85c9246f23b 100644 (file)
@@ -116,7 +116,7 @@ int CtdlForEachMessage(int mode,
                        struct CtdlMessage *compare,
                         ForEachMsgCallback CallBack,
                        void *userdata);
-int CtdlDeleteMessages(char *, long *, int, char *);
+int CtdlDeleteMessages(const char *, long *, int, char *);
 void CtdlWriteObject(char *req_room,                   /* Room to stuff it in */
                        char *content_type,             /* MIME type of this object */
                        char *raw_message,              /* Data to be written */
@@ -126,7 +126,7 @@ void CtdlWriteObject(char *req_room,                        /* Room to stuff it in */
                        int is_unique,                  /* Del others of this type? */
                        unsigned int flags              /* Internal save flags */
 );
-struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
+struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks);
 struct CtdlMessage * CM_Duplicate
                        (struct CtdlMessage *OrgMsg);
 int  CM_IsEmpty        (struct CtdlMessage *Msg, eMsgField which);
@@ -150,10 +150,12 @@ int  CM_IsValidMsg     (struct CtdlMessage *msg);
                Message->cm_fields[Which] + Message->cm_lengths[Which]
 
 void CtdlSerializeMessage(struct ser_ret *, struct CtdlMessage *);
+struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length);
 void ReplicationChecks(struct CtdlMessage *);
 int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs,
-                       int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj);
+                             int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj);
 int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *msg);
+long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply);
 char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, StrBuf *exist, int crlf, int *sock);
 StrBuf *CtdlReadMessageBodyBuf(char *terminator,       /* token signalling EOT */
                               long tlen,
@@ -265,12 +267,12 @@ extern int MessageDebugEnabled;
 #define CCCID CCC->cs_pid
 #define MSG_syslog(LEVEL, FORMAT, ...)                 \
        MSGDBGLOG(LEVEL) syslog(LEVEL,                  \
-                               "CC[%d]MSG" FORMAT,     \
+                               "CC[%d]MSG " FORMAT,    \
                                CCCID, __VA_ARGS__)
 
 #define MSGM_syslog(LEVEL, FORMAT)                     \
        MSGDBGLOG(LEVEL) syslog(LEVEL,                  \
-                               "CC[%d]MSG" FORMAT,     \
+                               "CC[%d]MSG " FORMAT,    \
                                CCCID)
 
 
index 3161b11003bbff3ad471401f3536b179fc459f22..14fe8be507fd25cfa7e262e68dde1f92820426e2 100644 (file)
@@ -262,7 +262,7 @@ int SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCfg, char *filename)
        else {
                OutBuffer = NewStrBuf();
                CfgIt = GetNewHashPos(CfgTypeHash, 1);
-               fchown(TmpFD, config.c_ctdluid, 0);
+               fchown(TmpFD, ctdluid, 0);
                for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++)
                {
                        const CfgLineType *pCfg;
index 85440207731cf32d74a5c4cc83d42a12dcc4f7ab..f26fd4a4b052a259617b7fadb8c2611e66ac36a3 100644 (file)
@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
+/* A Bison parser, made by GNU Bison 3.0.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-   
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
@@ -26,7 +26,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "3.0.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* Using locations.  */
-#define YYLSP_NEEDED 0
 
 
 
 /* Copy the first part of user declarations.  */
-
-/* Line 268 of yacc.c  */
-#line 1 "parsedate.y"
+#line 1 "parsedate.y" /* yacc.c:339  */
 
 /* $Revision$
 **
@@ -179,14 +175,15 @@ static time_t     yyRelSeconds;
 
 static void            date_error(char *);
 
+#line 179 "y.tab.c" /* yacc.c:339  */
 
-/* Line 268 of yacc.c  */
-#line 185 "y.tab.c"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -196,28 +193,30 @@ static void               date_error(char *);
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
 
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
 
-/* Tokens.  */
+/* Token type.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     tDAY = 258,
-     tDAYZONE = 259,
-     tMERIDIAN = 260,
-     tMONTH = 261,
-     tMONTH_UNIT = 262,
-     tSEC_UNIT = 263,
-     tSNUMBER = 264,
-     tUNUMBER = 265,
-     tZONE = 266
-   };
+  enum yytokentype
+  {
+    tDAY = 258,
+    tDAYZONE = 259,
+    tMERIDIAN = 260,
+    tMONTH = 261,
+    tMONTH_UNIT = 262,
+    tSEC_UNIT = 263,
+    tSNUMBER = 264,
+    tUNUMBER = 265,
+    tZONE = 266
+  };
 #endif
 /* Tokens.  */
 #define tDAY 258
@@ -230,35 +229,32 @@ static void               date_error(char *);
 #define tUNUMBER 265
 #define tZONE 266
 
-
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 293 of yacc.c  */
-#line 114 "parsedate.y"
+#line 114 "parsedate.y" /* yacc.c:355  */
 
     time_t             Number;
     enum _MERIDIAN     Meridian;
 
-
-
-/* Line 293 of yacc.c  */
-#line 250 "y.tab.c"
-} YYSTYPE;
+#line 243 "y.tab.c" /* yacc.c:355  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-/* Copy the second part of user declarations.  */
+extern YYSTYPE yylval;
+
+int yyparse (void);
 
 
-/* Line 343 of yacc.c  */
-#line 262 "y.tab.c"
+
+/* Copy the second part of user declarations.  */
+
+#line 258 "y.tab.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -272,11 +268,8 @@ typedef unsigned char yytype_uint8;
 
 #ifdef YYTYPE_INT8
 typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
 #else
-typedef short int yytype_int8;
+typedef signed char yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -296,8 +289,7 @@ typedef short int yytype_int16;
 #  define YYSIZE_T __SIZE_TYPE__
 # elif defined size_t
 #  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+# elif ! defined YYSIZE_T
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -311,39 +303,68 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
 #endif
 
-/* Identity function, used to suppress warnings about constant conditions.  */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
 #else
-static int
-YYID (yyi)
-    int yyi;
+# define YY_INITIAL_VALUE(Value) Value
 #endif
-{
-  return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
 #endif
 
+
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -361,9 +382,9 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
 #     ifndef EXIT_SUCCESS
 #      define EXIT_SUCCESS 0
 #     endif
@@ -373,8 +394,8 @@ YYID (yyi)
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
     /* The OS might guarantee only one guard page at the bottom of the stack,
        and a page size can be as small as 4096 bytes.  So we cannot safely
@@ -390,7 +411,7 @@ YYID (yyi)
 #  endif
 #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-            && (defined YYFREE || defined free)))
+             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
 #   ifndef EXIT_SUCCESS
 #    define EXIT_SUCCESS 0
@@ -398,15 +419,13 @@ YYID (yyi)
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined malloc && ! defined EXIT_SUCCESS
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined free && ! defined EXIT_SUCCESS
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -416,7 +435,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-        || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -441,35 +460,35 @@ union yyalloc
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
-    do                                                                 \
-      {                                                                        \
-       YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-       Stack = &yyptr->Stack_alloc;                                    \
-       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-       yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                        \
-    while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
 
 #endif
 
 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO.  The source and destination do
+/* Copy COUNT objects from SRC to DST.  The source and destination do
    not overlap.  */
 # ifndef YYCOPY
 #  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
 #  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         YYSIZE_T yyi;                         \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (YYID (0))
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
 #  endif
 # endif
 #endif /* !YYCOPY_NEEDED */
@@ -485,17 +504,19 @@ union yyalloc
 #define YYNNTS  9
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  30
-/* YYNRULES -- Number of states.  */
+/* YYNSTATES -- Number of states.  */
 #define YYNSTATES  44
 
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   266
 
-#define YYTRANSLATE(YYX)                                               \
+#define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -528,32 +549,7 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint8 yyprhs[] =
-{
-       0,     0,     3,     4,     7,     9,    12,    14,    16,    19,
-      24,    29,    36,    43,    45,    47,    50,    52,    54,    58,
-      64,    67,    72,    75,    79,    85,    88,    91,    94,    97,
-      98
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      16,     0,    -1,    -1,    16,    17,    -1,    18,    -1,    18,
-      19,    -1,    21,    -1,    22,    -1,    10,    23,    -1,    10,
-      12,    10,    23,    -1,    10,    12,    10,    20,    -1,    10,
-      12,    10,    12,    10,    23,    -1,    10,    12,    10,    12,
-      10,    20,    -1,    11,    -1,     4,    -1,    11,    20,    -1,
-      20,    -1,     9,    -1,    10,    13,    10,    -1,    10,    13,
-      10,    13,    10,    -1,     6,    10,    -1,     6,    10,    14,
-      10,    -1,    10,     6,    -1,    10,     6,    10,    -1,     3,
-      14,    10,     6,    10,    -1,     9,     8,    -1,    10,     8,
-      -1,     9,     7,    -1,    10,     7,    -1,    -1,     5,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   128,   128,   129,   132,   141,   145,   148,   153,   165,
@@ -563,7 +559,7 @@ static const yytype_uint16 yyrline[] =
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -571,13 +567,13 @@ static const char *const yytname[] =
   "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN",
   "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE",
   "':'", "'/'", "','", "$accept", "spec", "item", "time", "zone",
-  "numzone", "date", "rel", "o_merid", 0
+  "numzone", "date", "rel", "o_merid", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
@@ -585,27 +581,30 @@ static const yytype_uint16 yytoknum[] =
 };
 # endif
 
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    15,    16,    16,    17,    17,    17,    17,    18,    18,
-      18,    18,    18,    19,    19,    19,    19,    20,    21,    21,
-      21,    21,    21,    21,    21,    22,    22,    22,    22,    23,
-      23
-};
+#define YYPACT_NINF -29
 
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-29)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int8 yypact[] =
 {
-       0,     2,     0,     2,     1,     2,     1,     1,     2,     4,
-       4,     6,     6,     1,     1,     2,     1,     1,     3,     5,
-       2,     4,     2,     3,     5,     2,     2,     2,     2,     0,
-       1
+     -29,     1,   -29,   -11,    11,    20,    12,   -29,     4,   -29,
+     -29,    13,    16,   -29,   -29,   -29,    21,   -29,   -29,    22,
+      23,   -29,   -29,   -29,     5,   -29,   -29,    28,    25,   -29,
+      17,    24,   -29,    26,   -29,    29,   -29,   -29,    30,   -29,
+       0,   -29,   -29,   -29
 };
 
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
-   means the default is an error.  */
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
        2,     0,     1,     0,     0,     0,    29,     3,     4,     6,
@@ -615,34 +614,21 @@ static const yytype_uint8 yydefact[] =
       29,    19,    12,    11
 };
 
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
-{
-      -1,     1,     7,     8,    25,    26,     9,    10,    21
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -29
-static const yytype_int8 yypact[] =
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
 {
-     -29,     1,   -29,   -11,    11,    20,    12,   -29,     4,   -29,
-     -29,    13,    16,   -29,   -29,   -29,    21,   -29,   -29,    22,
-      23,   -29,   -29,   -29,     5,   -29,   -29,    28,    25,   -29,
-      17,    24,   -29,    26,   -29,    29,   -29,   -29,    30,   -29,
-       0,   -29,   -29,   -29
+     -29,   -29,   -29,   -29,   -29,   -24,   -29,   -29,   -28
 };
 
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
 {
-     -29,   -29,   -29,   -29,   -29,   -24,   -29,   -29,   -28
+      -1,     1,     7,     8,    25,    26,     9,    10,    21
 };
 
-/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -1
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
       32,     2,    37,    11,     3,    15,    36,     4,    22,    23,
@@ -652,12 +638,6 @@ static const yytype_uint8 yytable[] =
       41
 };
 
-#define yypact_value_is_default(yystate) \
-  ((yystate) == (-29))
-
-#define yytable_value_is_error(yytable_value) \
-  YYID (0)
-
 static const yytype_int8 yycheck[] =
 {
       24,     0,    30,    14,     3,     5,    30,     6,     4,     9,
@@ -667,8 +647,8 @@ static const yytype_int8 yycheck[] =
       10
 };
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
        0,    16,     0,     3,     6,     9,    10,    17,    18,    21,
@@ -678,94 +658,59 @@ static const yytype_uint8 yystos[] =
       10,    10,    20,    23
 };
 
-#define yyerrok                (yyerrstatus = 0)
-#define yyclearin      (yychar = YYEMPTY)
-#define YYEMPTY                (-2)
-#define YYEOF          0
-
-#define YYACCEPT       goto yyacceptlab
-#define YYABORT                goto yyabortlab
-#define YYERROR                goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
-
-#define YYFAIL         goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    15,    16,    16,    17,    17,    17,    17,    18,    18,
+      18,    18,    18,    19,    19,    19,    19,    20,    21,    21,
+      21,    21,    21,    21,    21,    22,    22,    22,    22,    23,
+      23
+};
 
-#define YYRECOVERING()  (!!yyerrstatus)
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     2,     1,     1,     2,     4,
+       4,     6,     6,     1,     1,     2,     1,     1,     3,     5,
+       2,     4,     2,     3,     5,     2,     2,     2,     2,     0,
+       1
+};
 
-#define YYBACKUP(Token, Value)                                 \
-do                                                             \
-  if (yychar == YYEMPTY && yylen == 1)                         \
-    {                                                          \
-      yychar = (Token);                                                \
-      yylval = (Value);                                                \
-      YYPOPSTACK (1);                                          \
-      goto yybackup;                                           \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                 \
-    }                                                          \
-while (YYID (0))
-
-
-#define YYTERROR       1
-#define YYERRCODE      256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
-    do                                                                 \
-      if (YYID (N))                                                    \
-       {                                                               \
-         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-       }                                                               \
-      else                                                             \
-       {                                                               \
-         (Current).first_line   = (Current).last_line   =              \
-           YYRHSLOC (Rhs, 0).last_line;                                \
-         (Current).first_column = (Current).last_column =              \
-           YYRHSLOC (Rhs, 0).last_column;                              \
-       }                                                               \
-    while (YYID (0))
-#endif
 
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
 
-/* This macro is provided for backward compatibility. */
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
 
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
 
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
+
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
 
-/* YYLEX -- calling `yylex' with the right arguments.  */
 
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
-#else
-# define YYLEX yylex ()
-#endif
 
 /* Enable debugging if requested.  */
 #if YYDEBUG
@@ -775,54 +720,46 @@ while (YYID (0))
 #  define YYFPRINTF fprintf
 # endif
 
-# define YYDPRINTF(Args)                       \
-do {                                           \
-  if (yydebug)                                 \
-    YYFPRINTF Args;                            \
-} while (YYID (0))
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
-do {                                                                     \
-  if (yydebug)                                                           \
-    {                                                                    \
-      YYFPRINTF (stderr, "%s ", Title);                                          \
-      yy_symbol_print (stderr,                                           \
-                 Type, Value); \
-      YYFPRINTF (stderr, "\n");                                                  \
-    }                                                                    \
-} while (YYID (0))
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT.  |
+`----------------------------------------*/
 
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-#endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-       break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -830,22 +767,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
 | Print this symbol on YYOUTPUT.  |
 `--------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-#endif
 {
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
   yy_symbol_value_print (yyoutput, yytype, yyvaluep);
   YYFPRINTF (yyoutput, ")");
@@ -856,16 +782,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -876,49 +794,42 @@ yy_stack_print (yybottom, yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)                           \
-do {                                                           \
-  if (yydebug)                                                 \
-    yy_stack_print ((Bottom), (Top));                          \
-} while (YYID (0))
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (0)
 
 
 /*------------------------------------------------.
 | Report that the YYRULE is going to be reduced.  |
 `------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule)
-    YYSTYPE *yyvsp;
-    int yyrule;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
 {
+  unsigned long int yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
-  unsigned long int yylno = yyrline[yyrule];
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-            yyrule - 1, yylno);
+             yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-                      &(yyvsp[(yyi + 1) - (yynrhs)])
-                                      );
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              );
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)         \
-do {                                   \
-  if (yydebug)                         \
-    yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -932,7 +843,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef        YYINITDEPTH
+#ifndef YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -955,15 +866,8 @@ int yydebug;
 #   define yystrlen strlen
 #  else
 /* Return the length of YYSTR.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static YYSIZE_T
 yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
-    const char *yystr;
-#endif
 {
   YYSIZE_T yylen;
   for (yylen = 0; yystr[yylen]; yylen++)
@@ -979,16 +883,8 @@ yystrlen (yystr)
 #  else
 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
    YYDEST.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static char *
 yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
-    char *yydest;
-    const char *yysrc;
-#endif
 {
   char *yyd = yydest;
   const char *yys = yysrc;
@@ -1018,27 +914,27 @@ yytnamerr (char *yyres, const char *yystr)
       char const *yyp = yystr;
 
       for (;;)
-       switch (*++yyp)
-         {
-         case '\'':
-         case ',':
-           goto do_not_strip_quotes;
-
-         case '\\':
-           if (*++yyp != '\\')
-             goto do_not_strip_quotes;
-           /* Fall through.  */
-         default:
-           if (yyres)
-             yyres[yyn] = *yyp;
-           yyn++;
-           break;
-
-         case '"':
-           if (yyres)
-             yyres[yyn] = '\0';
-           return yyn;
-         }
+        switch (*++yyp)
+          {
+          case '\'':
+          case ',':
+            goto do_not_strip_quotes;
+
+          case '\\':
+            if (*++yyp != '\\')
+              goto do_not_strip_quotes;
+            /* Fall through.  */
+          default:
+            if (yyres)
+              yyres[yyn] = *yyp;
+            yyn++;
+            break;
+
+          case '"':
+            if (yyres)
+              yyres[yyn] = '\0';
+            return yyn;
+          }
     do_not_strip_quotes: ;
     }
 
@@ -1061,12 +957,11 @@ static int
 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 yytype_int16 *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
   YYSIZE_T yysize = yysize0;
-  YYSIZE_T yysize1;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = 0;
+  const char *yyformat = YY_NULLPTR;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -1074,10 +969,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
   int yycount = 0;
 
   /* There are many possibilities here to consider:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
      - If this state is a consistent state with a default action, then
        the only way this function was invoked is if the default action
        is an error action.  In that case, don't check for expected
@@ -1126,11 +1017,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                     break;
                   }
                 yyarg[yycount++] = yytname[yyx];
-                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-                if (! (yysize <= yysize1
-                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                  return 2;
-                yysize = yysize1;
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
               }
         }
     }
@@ -1150,10 +1043,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 # undef YYCASE_
     }
 
-  yysize1 = yysize + yystrlen (yyformat);
-  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-    return 2;
-  yysize = yysize1;
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
 
   if (*yymsg_alloc < yysize)
     {
@@ -1190,48 +1085,20 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 | Release the memory associated to this symbol.  |
 `-----------------------------------------------*/
 
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-#endif
 {
   YYUSE (yyvaluep);
-
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-       break;
-    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
 
-/* Prevent warnings from -Wmissing-prototypes.  */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
 
 
 /* The lookahead symbol.  */
@@ -1239,7 +1106,6 @@ int yychar;
 
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
-
 /* Number of syntax errors so far.  */
 int yynerrs;
 
@@ -1248,37 +1114,18 @@ int yynerrs;
 | yyparse.  |
 `----------*/
 
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
-    void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 int
 yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
 {
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
     /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+       'yyss': related to states.
+       'yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1296,7 +1143,7 @@ yyparse ()
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1314,9 +1161,8 @@ yyparse ()
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1325,14 +1171,6 @@ yyparse ()
   yyerrstatus = 0;
   yynerrs = 0;
   yychar = YYEMPTY; /* Cause a token to be read.  */
-
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-  yyssp = yyss;
-  yyvsp = yyvs;
-
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1353,23 +1191,23 @@ yyparse ()
 
 #ifdef yyoverflow
       {
-       /* Give user a chance to reallocate the stack.  Use copies of
-          these so that the &'s don't force the real ones into
-          memory.  */
-       YYSTYPE *yyvs1 = yyvs;
-       yytype_int16 *yyss1 = yyss;
-
-       /* Each stack pointer address is followed by the size of the
-          data in use in that stack, in bytes.  This used to be a
-          conditional around just the two extra args, but that might
-          be undefined if yyoverflow is a macro.  */
-       yyoverflow (YY_("memory exhausted"),
-                   &yyss1, yysize * sizeof (*yyssp),
-                   &yyvs1, yysize * sizeof (*yyvsp),
-                   &yystacksize);
-
-       yyss = yyss1;
-       yyvs = yyvs1;
+        /* Give user a chance to reallocate the stack.  Use copies of
+           these so that the &'s don't force the real ones into
+           memory.  */
+        YYSTYPE *yyvs1 = yyvs;
+        yytype_int16 *yyss1 = yyss;
+
+        /* Each stack pointer address is followed by the size of the
+           data in use in that stack, in bytes.  This used to be a
+           conditional around just the two extra args, but that might
+           be undefined if yyoverflow is a macro.  */
+        yyoverflow (YY_("memory exhausted"),
+                    &yyss1, yysize * sizeof (*yyssp),
+                    &yyvs1, yysize * sizeof (*yyvsp),
+                    &yystacksize);
+
+        yyss = yyss1;
+        yyvs = yyvs1;
       }
 #else /* no yyoverflow */
 # ifndef YYSTACK_RELOCATE
@@ -1377,22 +1215,22 @@ yyparse ()
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-       goto yyexhaustedlab;
+        goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-       yystacksize = YYMAXDEPTH;
+        yystacksize = YYMAXDEPTH;
 
       {
-       yytype_int16 *yyss1 = yyss;
-       union yyalloc *yyptr =
-         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-       if (! yyptr)
-         goto yyexhaustedlab;
-       YYSTACK_RELOCATE (yyss_alloc, yyss);
-       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-       if (yyss1 != yyssa)
-         YYSTACK_FREE (yyss1);
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1401,10 +1239,10 @@ yyparse ()
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                 (unsigned long int) yystacksize));
+                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-       YYABORT;
+        YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1433,7 +1271,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+      yychar = yylex ();
     }
 
   if (yychar <= YYEOF)
@@ -1473,7 +1311,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1496,7 +1336,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
+     '$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1510,9 +1350,7 @@ yyreduce:
   switch (yyn)
     {
         case 4:
-
-/* Line 1806 of yacc.c  */
-#line 132 "parsedate.y"
+#line 132 "parsedate.y" /* yacc.c:1646  */
     {
            yyHaveTime++;
 #ifdef lint
@@ -1522,313 +1360,286 @@ yyreduce:
            }
 #endif /* lint */
        }
+#line 1364 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 5:
-
-/* Line 1806 of yacc.c  */
-#line 141 "parsedate.y"
+#line 141 "parsedate.y" /* yacc.c:1646  */
     {
            yyHaveTime++;
-           yyTimezone = (yyvsp[(2) - (2)].Number);
+           yyTimezone = (yyvsp[0].Number);
        }
+#line 1373 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 6:
-
-/* Line 1806 of yacc.c  */
-#line 145 "parsedate.y"
+#line 145 "parsedate.y" /* yacc.c:1646  */
     {
            yyHaveDate++;
        }
+#line 1381 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 7:
-
-/* Line 1806 of yacc.c  */
-#line 148 "parsedate.y"
+#line 148 "parsedate.y" /* yacc.c:1646  */
     {
            yyHaveRel = 1;
        }
+#line 1389 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 8:
-
-/* Line 1806 of yacc.c  */
-#line 153 "parsedate.y"
+#line 153 "parsedate.y" /* yacc.c:1646  */
     {
-           if ((yyvsp[(1) - (2)].Number) < 100) {
-               yyHour = (yyvsp[(1) - (2)].Number);
+           if ((yyvsp[-1].Number) < 100) {
+               yyHour = (yyvsp[-1].Number);
                yyMinutes = 0;
            }
            else {
-               yyHour = (yyvsp[(1) - (2)].Number) / 100;
-               yyMinutes = (yyvsp[(1) - (2)].Number) % 100;
+               yyHour = (yyvsp[-1].Number) / 100;
+               yyMinutes = (yyvsp[-1].Number) % 100;
            }
            yySeconds = 0;
-           yyMeridian = (yyvsp[(2) - (2)].Meridian);
+           yyMeridian = (yyvsp[0].Meridian);
        }
+#line 1406 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 9:
-
-/* Line 1806 of yacc.c  */
-#line 165 "parsedate.y"
+#line 165 "parsedate.y" /* yacc.c:1646  */
     {
-           yyHour = (yyvsp[(1) - (4)].Number);
-           yyMinutes = (yyvsp[(3) - (4)].Number);
+           yyHour = (yyvsp[-3].Number);
+           yyMinutes = (yyvsp[-1].Number);
            yySeconds = 0;
-           yyMeridian = (yyvsp[(4) - (4)].Meridian);
+           yyMeridian = (yyvsp[0].Meridian);
        }
+#line 1417 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 10:
-
-/* Line 1806 of yacc.c  */
-#line 171 "parsedate.y"
+#line 171 "parsedate.y" /* yacc.c:1646  */
     {
-           yyHour = (yyvsp[(1) - (4)].Number);
-           yyMinutes = (yyvsp[(3) - (4)].Number);
-           yyTimezone = (yyvsp[(4) - (4)].Number);
+           yyHour = (yyvsp[-3].Number);
+           yyMinutes = (yyvsp[-1].Number);
+           yyTimezone = (yyvsp[0].Number);
            yyMeridian = MER24;
            yyDSTmode = DSToff;
        }
+#line 1429 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 11:
-
-/* Line 1806 of yacc.c  */
-#line 178 "parsedate.y"
+#line 178 "parsedate.y" /* yacc.c:1646  */
     {
-           yyHour = (yyvsp[(1) - (6)].Number);
-           yyMinutes = (yyvsp[(3) - (6)].Number);
-           yySeconds = (yyvsp[(5) - (6)].Number);
-           yyMeridian = (yyvsp[(6) - (6)].Meridian);
+           yyHour = (yyvsp[-5].Number);
+           yyMinutes = (yyvsp[-3].Number);
+           yySeconds = (yyvsp[-1].Number);
+           yyMeridian = (yyvsp[0].Meridian);
        }
+#line 1440 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 12:
-
-/* Line 1806 of yacc.c  */
-#line 184 "parsedate.y"
+#line 184 "parsedate.y" /* yacc.c:1646  */
     {
-           yyHour = (yyvsp[(1) - (6)].Number);
-           yyMinutes = (yyvsp[(3) - (6)].Number);
-           yySeconds = (yyvsp[(5) - (6)].Number);
-           yyTimezone = (yyvsp[(6) - (6)].Number);
+           yyHour = (yyvsp[-5].Number);
+           yyMinutes = (yyvsp[-3].Number);
+           yySeconds = (yyvsp[-1].Number);
+           yyTimezone = (yyvsp[0].Number);
            yyMeridian = MER24;
            yyDSTmode = DSToff;
        }
+#line 1453 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 13:
-
-/* Line 1806 of yacc.c  */
-#line 194 "parsedate.y"
+#line 194 "parsedate.y" /* yacc.c:1646  */
     {
-           (yyval.Number) = (yyvsp[(1) - (1)].Number);
+           (yyval.Number) = (yyvsp[0].Number);
            yyDSTmode = DSToff;
        }
+#line 1462 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 14:
-
-/* Line 1806 of yacc.c  */
-#line 198 "parsedate.y"
+#line 198 "parsedate.y" /* yacc.c:1646  */
     {
-           (yyval.Number) = (yyvsp[(1) - (1)].Number);
+           (yyval.Number) = (yyvsp[0].Number);
            yyDSTmode = DSTon;
        }
+#line 1471 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 15:
-
-/* Line 1806 of yacc.c  */
-#line 202 "parsedate.y"
+#line 202 "parsedate.y" /* yacc.c:1646  */
     {
            /* Only allow "GMT+300" and "GMT-0800" */
-           if ((yyvsp[(1) - (2)].Number) != 0) {
+           if ((yyvsp[-1].Number) != 0) {
                YYABORT;
            }
-           (yyval.Number) = (yyvsp[(2) - (2)].Number);
+           (yyval.Number) = (yyvsp[0].Number);
            yyDSTmode = DSToff;
        }
+#line 1484 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 16:
-
-/* Line 1806 of yacc.c  */
-#line 210 "parsedate.y"
+#line 210 "parsedate.y" /* yacc.c:1646  */
     {
-           (yyval.Number) = (yyvsp[(1) - (1)].Number);
+           (yyval.Number) = (yyvsp[0].Number);
            yyDSTmode = DSToff;
        }
+#line 1493 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 17:
-
-/* Line 1806 of yacc.c  */
-#line 216 "parsedate.y"
+#line 216 "parsedate.y" /* yacc.c:1646  */
     {
            int         i;
 
            /* Unix and GMT and numeric timezones -- a little confusing. */
-           if ((yyvsp[(1) - (1)].Number) < 0) {
+           if ((yyvsp[0].Number) < 0) {
                /* Don't work with negative modulus. */
-               (yyvsp[(1) - (1)].Number) = -(yyvsp[(1) - (1)].Number);
-               if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) {
+               (yyvsp[0].Number) = -(yyvsp[0].Number);
+               if ((yyvsp[0].Number) > 9999 || (i = (yyvsp[0].Number) % 100) >= 60) {
                    YYABORT;
                }
-               (yyval.Number) = ((yyvsp[(1) - (1)].Number) / 100) * 60 + i;
+               (yyval.Number) = ((yyvsp[0].Number) / 100) * 60 + i;
            }
            else {
-               if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) {
+               if ((yyvsp[0].Number) > 9999 || (i = (yyvsp[0].Number) % 100) >= 60) {
                    YYABORT;
                }
-               (yyval.Number) = -(((yyvsp[(1) - (1)].Number) / 100) * 60 + i);
+               (yyval.Number) = -(((yyvsp[0].Number) / 100) * 60 + i);
            }
        }
+#line 1517 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 18:
-
-/* Line 1806 of yacc.c  */
-#line 237 "parsedate.y"
+#line 237 "parsedate.y" /* yacc.c:1646  */
     {
-           yyMonth = (yyvsp[(1) - (3)].Number);
-           yyDay = (yyvsp[(3) - (3)].Number);
+           yyMonth = (yyvsp[-2].Number);
+           yyDay = (yyvsp[0].Number);
        }
+#line 1526 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 19:
-
-/* Line 1806 of yacc.c  */
-#line 241 "parsedate.y"
+#line 241 "parsedate.y" /* yacc.c:1646  */
     {
-           if ((yyvsp[(1) - (5)].Number) > 100) {
-               yyYear = (yyvsp[(1) - (5)].Number);
-               yyMonth = (yyvsp[(3) - (5)].Number);
-               yyDay = (yyvsp[(5) - (5)].Number);
+           if ((yyvsp[-4].Number) > 100) {
+               yyYear = (yyvsp[-4].Number);
+               yyMonth = (yyvsp[-2].Number);
+               yyDay = (yyvsp[0].Number);
            }
            else {
-               yyMonth = (yyvsp[(1) - (5)].Number);
-               yyDay = (yyvsp[(3) - (5)].Number);
-               yyYear = (yyvsp[(5) - (5)].Number);
+               yyMonth = (yyvsp[-4].Number);
+               yyDay = (yyvsp[-2].Number);
+               yyYear = (yyvsp[0].Number);
            }
        }
+#line 1543 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 20:
-
-/* Line 1806 of yacc.c  */
-#line 253 "parsedate.y"
+#line 253 "parsedate.y" /* yacc.c:1646  */
     {
-           yyMonth = (yyvsp[(1) - (2)].Number);
-           yyDay = (yyvsp[(2) - (2)].Number);
+           yyMonth = (yyvsp[-1].Number);
+           yyDay = (yyvsp[0].Number);
        }
+#line 1552 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 21:
-
-/* Line 1806 of yacc.c  */
-#line 257 "parsedate.y"
+#line 257 "parsedate.y" /* yacc.c:1646  */
     {
-           yyMonth = (yyvsp[(1) - (4)].Number);
-           yyDay = (yyvsp[(2) - (4)].Number);
-           yyYear = (yyvsp[(4) - (4)].Number);
+           yyMonth = (yyvsp[-3].Number);
+           yyDay = (yyvsp[-2].Number);
+           yyYear = (yyvsp[0].Number);
        }
+#line 1562 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 22:
-
-/* Line 1806 of yacc.c  */
-#line 262 "parsedate.y"
+#line 262 "parsedate.y" /* yacc.c:1646  */
     {
-           yyDay = (yyvsp[(1) - (2)].Number);
-           yyMonth = (yyvsp[(2) - (2)].Number);
+           yyDay = (yyvsp[-1].Number);
+           yyMonth = (yyvsp[0].Number);
        }
+#line 1571 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 23:
-
-/* Line 1806 of yacc.c  */
-#line 266 "parsedate.y"
+#line 266 "parsedate.y" /* yacc.c:1646  */
     {
-           yyDay = (yyvsp[(1) - (3)].Number);
-           yyMonth = (yyvsp[(2) - (3)].Number);
-           yyYear = (yyvsp[(3) - (3)].Number);
+           yyDay = (yyvsp[-2].Number);
+           yyMonth = (yyvsp[-1].Number);
+           yyYear = (yyvsp[0].Number);
        }
+#line 1581 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 24:
-
-/* Line 1806 of yacc.c  */
-#line 271 "parsedate.y"
+#line 271 "parsedate.y" /* yacc.c:1646  */
     {
-           yyDay = (yyvsp[(3) - (5)].Number);
-           yyMonth = (yyvsp[(4) - (5)].Number);
-           yyYear = (yyvsp[(5) - (5)].Number);
+           yyDay = (yyvsp[-2].Number);
+           yyMonth = (yyvsp[-1].Number);
+           yyYear = (yyvsp[0].Number);
        }
+#line 1591 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 25:
-
-/* Line 1806 of yacc.c  */
-#line 278 "parsedate.y"
+#line 278 "parsedate.y" /* yacc.c:1646  */
     {
-           yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
+           yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number);
        }
+#line 1599 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 26:
-
-/* Line 1806 of yacc.c  */
-#line 281 "parsedate.y"
+#line 281 "parsedate.y" /* yacc.c:1646  */
     {
-           yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
+           yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number);
        }
+#line 1607 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 27:
-
-/* Line 1806 of yacc.c  */
-#line 284 "parsedate.y"
+#line 284 "parsedate.y" /* yacc.c:1646  */
     {
-           yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
+           yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number);
        }
+#line 1615 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 28:
-
-/* Line 1806 of yacc.c  */
-#line 287 "parsedate.y"
+#line 287 "parsedate.y" /* yacc.c:1646  */
     {
-           yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
+           yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number);
        }
+#line 1623 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 29:
-
-/* Line 1806 of yacc.c  */
-#line 292 "parsedate.y"
+#line 292 "parsedate.y" /* yacc.c:1646  */
     {
            (yyval.Meridian) = MER24;
        }
+#line 1631 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 30:
-
-/* Line 1806 of yacc.c  */
-#line 295 "parsedate.y"
+#line 295 "parsedate.y" /* yacc.c:1646  */
     {
-           (yyval.Meridian) = (yyvsp[(1) - (1)].Meridian);
+           (yyval.Meridian) = (yyvsp[0].Meridian);
        }
+#line 1639 "y.tab.c" /* yacc.c:1646  */
     break;
 
 
-
-/* Line 1806 of yacc.c  */
-#line 1832 "y.tab.c"
+#line 1643 "y.tab.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1850,7 +1661,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-  /* Now `shift' the result of the reduction.  Determine what state
+  /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
 
@@ -1865,9 +1676,9 @@ yyreduce:
   goto yynewstate;
 
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error |
+`--------------------------------------*/
 yyerrlab:
   /* Make sure we have latest lookahead translation.  See comments at
      user semantic actions for why this is necessary.  */
@@ -1918,20 +1729,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-        error, discard it.  */
+         error, discard it.  */
 
       if (yychar <= YYEOF)
-       {
-         /* Return failure if at end of input.  */
-         if (yychar == YYEOF)
-           YYABORT;
-       }
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
       else
-       {
-         yydestruct ("Error: discarding",
-                     yytoken, &yylval);
-         yychar = YYEMPTY;
-       }
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval);
+          yychar = YYEMPTY;
+        }
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -1950,7 +1761,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -1963,35 +1774,37 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
 
   for (;;)
     {
       yyn = yypact[yystate];
       if (!yypact_value_is_default (yyn))
-       {
-         yyn += YYTERROR;
-         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-           {
-             yyn = yytable[yyn];
-             if (0 < yyn)
-               break;
-           }
-       }
+        {
+          yyn += YYTERROR;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+            {
+              yyn = yytable[yyn];
+              if (0 < yyn)
+                break;
+            }
+        }
 
       /* Pop the current state because it cannot handle the error token.  */
       if (yyssp == yyss)
-       YYABORT;
+        YYABORT;
 
 
       yydestruct ("Error: popping",
-                 yystos[yystate], yyvsp);
+                  yystos[yystate], yyvsp);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2015,7 +1828,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2034,14 +1847,14 @@ yyreturn:
       yydestruct ("Cleanup: discarding lookahead",
                   yytoken, &yylval);
     }
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-                 yystos[*yyssp], yyvsp);
+                  yystos[*yyssp], yyvsp);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2052,14 +1865,9 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
+  return yyresult;
 }
-
-
-
-/* Line 2067 of yacc.c  */
-#line 300 "parsedate.y"
+#line 300 "parsedate.y" /* yacc.c:1906  */
 
 
 /* Month and day table. */
@@ -2567,4 +2375,3 @@ main(int ac, char *av[])
     /* NOTREACHED */
 }
 #endif /* TEST */
-
index 729846d3eb0e12010935922a1cc2ad3e67a66e5b..c545e4dde2abfcce76da25395fd131c8b4e65581 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Server functions which perform operations on room objects.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -32,7 +32,7 @@ struct floor *floorcache[MAXFLOORS];
 int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) {
        if (    (!(CC->logged_in))
                && (!(CC->internal_pgm))
-               && (!config.c_guest_logins)
+               && (!CtdlGetConfigInt("c_guest_logins"))
        ) {
                return(om_not_logged_in);
        }
@@ -139,7 +139,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
                is_me = 1;
        }
 
-       if ((is_me) && (config.c_guest_logins) && (!CC->logged_in)) {
+       if ((is_me) && (CtdlGetConfigInt("c_guest_logins")) && (!CC->logged_in)) {
                is_guest = 1;
        }
 
@@ -166,7 +166,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        }
 
        /* Force the properties of the Aide room */
-       if (!strcasecmp(roombuf->QRname, config.c_aideroom)) {
+       if (!strcasecmp(roombuf->QRname, CtdlGetConfigStr("c_aideroom"))) {
                if (userbuf->axlevel >= AxAideU) {
                        retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                } else {
@@ -339,9 +339,9 @@ void room_sanity_check(struct ctdlroom *qrbuf)
        /* Listing order of 0 is illegal except for base rooms */
        if (qrbuf->QRorder == 0)
                if (!(qrbuf->QRflags & QR_MAILBOX) &&
-                   strncasecmp(qrbuf->QRname, config.c_baseroom, ROOMNAMELEN)
+                   strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)
                    &&
-                   strncasecmp(qrbuf->QRname, config.c_aideroom, ROOMNAMELEN))
+                   strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN))
                        qrbuf->QRorder = 64;
 }
 
@@ -398,7 +398,7 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name)
 /*
  * CtdlGetRoomLock()  -  same as getroom() but locks the record (if supported)
  */
-int CtdlGetRoomLock(struct ctdlroom *qrbuf, char *room_name)
+int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name)
 {
        register int retval;
        retval = CtdlGetRoom(qrbuf, room_name);
@@ -819,8 +819,8 @@ void CtdlUserGoto(char *where, int display_result, int transiently,
        /* Know the room ... but not if it's the page log room, or if the
         * caller specified that we're only entering this room transiently.
         */
-       if ((strcasecmp(CCC->room.QRname, config.c_logpages))
-          && (transiently == 0) ) {
+       if ((strcasecmp(CCC->room.QRname, CtdlGetConfigStr("c_logpages"))) && (transiently == 0))
+       {
                vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
                vbuf.v_flags = vbuf.v_flags | V_ACCESS;
        }
@@ -945,7 +945,7 @@ void CtdlUserGoto(char *where, int display_result, int transiently,
  */
 void convert_room_name_macros(char *towhere, size_t maxlen) {
        if (!strcasecmp(towhere, "_BASEROOM_")) {
-               safestrncpy(towhere, config.c_baseroom, maxlen);
+               safestrncpy(towhere, CtdlGetConfigStr("c_baseroom"), maxlen);
        }
        else if (!strcasecmp(towhere, "_MAIL_")) {
                safestrncpy(towhere, MAILROOM, maxlen);
@@ -957,7 +957,7 @@ void convert_room_name_macros(char *towhere, size_t maxlen) {
                safestrncpy(towhere, USERDRAFTROOM, maxlen);
        }
        else if (!strcasecmp(towhere, "_BITBUCKET_")) {
-               safestrncpy(towhere, config.c_twitroom, maxlen);
+               safestrncpy(towhere, CtdlGetConfigStr("c_twitroom"), maxlen);
        }
        else if (!strcasecmp(towhere, "_CALENDAR_")) {
                safestrncpy(towhere, USERCALENDARROOM, maxlen);
@@ -1039,8 +1039,8 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
                }
 
                /* Reject change of floor for baseroom/aideroom */
-               if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN) ||
-                   !strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) {
+               if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN) ||
+                   !strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) {
                        new_floor = 0;
                }
 
@@ -1055,13 +1055,11 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
                begin_critical_section(S_CONFIG);
        
                /* If baseroom/aideroom name changes, update config */
-               if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN)) {
-                       safestrncpy(config.c_baseroom, new_name, ROOMNAMELEN);
-                       put_config();
+               if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
+                       CtdlSetConfigStr("c_baseroom", new_name);
                }
-               if (!strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) {
-                       safestrncpy(config.c_aideroom, new_name, ROOMNAMELEN);
-                       put_config();
+               if (!strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) {
+                       CtdlSetConfigStr("c_aideroom", new_name);
                }
        
                end_critical_section(S_CONFIG);
index 4b4e44c08ab958bdb32478fa6e1629dbaaf3cd8b..568d9a3ae0275032f977296793b288dabe8aa912 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Citadel Dynamic Loading Module
+ * Citadel Extension Loader
  * Written by Brian Costello <btx@calyx.net>
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -21,6 +21,7 @@
 
 #include "serv_extensions.h"
 #include "ctdl_module.h"
+#include "config.h"
 
 
 int DebugModules = 0;
@@ -1131,7 +1132,7 @@ void CtdlRegisterServiceHook(int tcp_port,
        newfcn->ServiceName = ServiceName;
 
        if (sockpath != NULL) {
-               newfcn->msock = ctdl_uds_server(sockpath, config.c_maxsessions, error);
+               newfcn->msock = ctdl_uds_server(sockpath, CtdlGetConfigInt("c_maxsessions"), error);
                snprintf(message, SIZ, "Unix domain socket '%s': ", sockpath);
        }
        else if (tcp_port <= 0) {       /* port -1 to disable */
@@ -1141,12 +1142,12 @@ void CtdlRegisterServiceHook(int tcp_port,
                return;
        }
        else {
-               newfcn->msock = ctdl_tcp_server(config.c_ip_addr,
+               newfcn->msock = ctdl_tcp_server(CtdlGetConfigStr("c_ip_addr"),
                                              tcp_port,
-                                             config.c_maxsessions
+                                             CtdlGetConfigInt("c_maxsessions")
                                              error);
                snprintf(message, SIZ, "TCP port %s:%d: (%s) ", 
-                        config.c_ip_addr, tcp_port, ServiceName);
+                        CtdlGetConfigStr("c_ip_addr"), tcp_port, ServiceName);
        }
 
        if (newfcn->msock > 0) {
index 6aedb546393124cce3a72d7e6259eea3740404c5..4a6dbc1d278f045e4e8c9f01b28e4790dc1c44b6 100644 (file)
@@ -1,3 +1,17 @@
+/* 
+ * Main declarations file for the Citadel server
+ *
+ * Copyright (c) 1987-2015 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
 #ifndef SERVER_H
 #define SERVER_H
 
@@ -66,6 +80,7 @@ typedef struct __recptypes {
 #define CTDLEXIT_DB            105     /* Unable to initialize database */
 #define CTDLEXIT_LIBCITADEL    106     /* Incorrect version of libcitadel */
 #define CTDL_EXIT_UNSUP_AUTH   107     /* Unsupported auth mode configured */
+#define CTDLEXIT_UNUSER                108     /* Could not determine uid to run as */
 
 /*
  * Reasons why a session would be terminated (set CC->kill_me to these values)
@@ -101,22 +116,8 @@ enum {
 #define CS_POSTING     4       /* Posting */
 
 
-/*
- * This is the control record for the message base... 
- */
-struct CitControl {
-       long MMhighest;                 /* highest message number in file   */
-       unsigned MMflags;               /* Global system flags              */
-       long MMnextuser;                /* highest user number on system    */
-       long MMnextroom;                /* highest room number on system    */
-       int version;                    /* Server-hosted upgrade level      */
-       int fulltext_wordbreaker;       /* ID of wordbreaker in use         */
-       long MMfulltext;                /* highest message number indexed   */
-       int MMdbversion;                /* Version of Berkeley DB used on previous server run */
-};
-
 extern int ScheduledShutdown;
-extern struct CitControl CitControl;
+extern uid_t ctdluid;
 
 struct ExpressMessage {
        struct ExpressMessage *next;
@@ -210,6 +211,7 @@ enum {
        CDB_EUIDINDEX,          /* locate msgs by EUID           */
        CDB_USERSBYNUMBER,      /* index of users by number      */
        CDB_OPENID,             /* associates OpenIDs with users */
+       CDB_CONFIG,             /* system configuration database */
        MAXCDB                  /* total number of CDB's defined */
 };
 
index 6a7d293fb8ef7cf6265fa3b4e4d044b1d117a339..a015876e5beedd803790e92aa0dda78093a5825d 100644 (file)
@@ -26,6 +26,7 @@
 #include "user_ops.h"
 #include "ecrash.h"
 
+uid_t ctdluid = 0;
 const char *CitadelServiceUDS="citadel-UDS";
 const char *CitadelServiceTCP="citadel-TCP";
 
@@ -51,6 +52,8 @@ int main(int argc, char **argv)
        char ctdldir[PATH_MAX]=CTDLDIR;
        int syslog_facility = LOG_DAEMON;
        const char *eDebuglist[] = {NULL, NULL};
+       uid_t u = 0;
+       struct passwd *p = NULL;
 #ifdef HAVE_RUN_DIR
        struct stat filestats;
 #endif
@@ -64,7 +67,7 @@ int main(int argc, char **argv)
        InitializeMasterTSD();
 
        /* parse command-line arguments */
-       while ((a=getopt(argc, argv, "l:dh:x:t:B:Dr")) != EOF) switch(a) {
+       while ((a=getopt(argc, argv, "l:dh:x:t:B:Dru:")) != EOF) switch(a) {
 
                case 'l':
                        safestrncpy(facility, optarg, sizeof(facility));
@@ -108,16 +111,57 @@ int main(int argc, char **argv)
                        drop_root_perms = 0;
                        break;
 
+               /* -u tells the server what uid to run under... */
+               case 'u':
+                       u = atoi(optarg);
+                       if (u > 0) {
+                               ctdluid = u;
+                       }
+                       else {
+                               p = getpwnam(optarg);
+                               if (p) {
+                                       u = p->pw_uid;
+                               }
+                       }
+                       if (u > 0) {
+                               ctdluid = u;
+                       }
+                       break;
+
                default:
                /* any other parameter makes it crash and burn */
                        fprintf(stderr, "citserver: usage: "
                                        "citserver "
                                        "[-l LogFacility] "
                                        "[-d] [-D] [-r] "
+                                       "[-u user] "
                                        "[-h HomeDir]\n"
                        );
                        exit(1);
        }
+
+       /* Last ditch effort to determine the user name ... if there's a user called "citadel" then use that */
+       if (ctdluid == 0) {
+               p = getpwnam("citadel");
+               if (!p) {
+                       p = getpwnam("bbs");
+               }
+               if (!p) {
+                       p = getpwnam("guest");
+               }
+               if (p) {
+                       u = p->pw_uid;
+               }
+               if (u > 0) {
+                       ctdluid = u;
+               }
+       }
+
+       if ((ctdluid == 0) && (drop_root_perms == 0)) {
+               fprintf(stderr, "citserver: cannot determine user to run as; please specify -r or -u options\n");
+               exit(CTDLEXIT_UNUSER);
+       }
+
        StartLibCitadel(basesize);
        openlog("citserver",
                ( running_as_daemon ? (LOG_PID) : (LOG_PID | LOG_PERROR) ),
@@ -161,25 +205,15 @@ int main(int argc, char **argv)
        syslog(LOG_DEBUG, "Called as: %s", argv[0]);
        syslog(LOG_INFO, "%s", libcitadel_version_string());
 
-       /* Load site-specific configuration */
-       syslog(LOG_INFO, "Loading citadel.config");
-       get_config();
-
-       /* get_control() MUST MUST MUST be called BEFORE the databases are opened!! */
-       syslog(LOG_INFO, "Acquiring control record");
-       get_control();
-
-       put_config();
-
 #ifdef HAVE_RUN_DIR
        /* on some dists rundir gets purged on startup. so we need to recreate it. */
 
        if (stat(ctdl_run_dir, &filestats)==-1){
 #ifdef HAVE_GETPWUID_R
 #ifdef SOLARIS_GETPWUID
-               pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf));
+               pwp = getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf));
 #else // SOLARIS_GETPWUID
-               getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
+               getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
 #endif // SOLARIS_GETPWUID
 #else // HAVE_GETPWUID_R
                pwp = NULL;
@@ -190,7 +224,7 @@ int main(int argc, char **argv)
                                      "unable to create run directory [%s]: %s", 
                                      ctdl_run_dir, strerror(errno));
 
-               if (chown(ctdl_run_dir, config.c_ctdluid, (pwp==NULL)?-1:pw.pw_gid) != 0)
+               if (chown(ctdl_run_dir, ctdluid, (pwp==NULL)?-1:pw.pw_gid) != 0)
                        syslog(LOG_EMERG, 
                                      "unable to set the access rights for [%s]: %s", 
                                      ctdl_run_dir, strerror(errno));
@@ -253,7 +287,7 @@ int main(int argc, char **argv)
        /*
         * Bind the server to our favorite TCP port (usually 504).
         */
-       CtdlRegisterServiceHook(config.c_port_number,
+       CtdlRegisterServiceHook(CtdlGetConfigInt("c_port_number"),
                                NULL,
                                citproto_begin_session,
                                do_command_loop,
@@ -276,7 +310,7 @@ int main(int argc, char **argv)
        /*
         * If we need host auth, start our chkpwd daemon.
         */
-       if (config.c_auth_mode == AUTHMODE_HOST) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
                start_chkpwd_daemon();
        }
 
@@ -297,9 +331,9 @@ int main(int argc, char **argv)
 
 #ifdef HAVE_GETPWUID_R
 #ifdef SOLARIS_GETPWUID
-               pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf));
+               pwp = getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf));
 #else // SOLARIS_GETPWUID
-               getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
+               getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
 #endif // SOLARIS_GETPWUID
 #else // HAVE_GETPWUID_R
                pwp = NULL;
index 787a93a3df8eae8cb16b3ab76232e1af009f8fea..0dda5bd55425d676a375b931635a416d6e6d361a 100644 (file)
@@ -7,7 +7,7 @@
  * If we ever port to a different platform and either have multiple
  * variants of this file or simply load it up with #ifdefs.
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -39,6 +39,7 @@
 #include <libcitadel.h>
 
 #include "citserver.h"
+#include "config.h"
 #include "ctdl_module.h"
 
 #include "sysdep_decls.h"
@@ -731,7 +732,7 @@ int HaveMoreLinesWaiting(CitContext *CCC)
  */
 INLINE int client_read(char *buf, int bytes)
 {
-       return(client_read_to(buf, bytes, config.c_sleeping));
+       return(client_read_to(buf, bytes, CtdlGetConfigInt("c_sleeping")));
 }
 
 int CtdlClientGetLine(StrBuf *Target)
@@ -1475,8 +1476,8 @@ SKIP_SELECT:
 
                pthread_mutex_lock(&ThreadCountMutex);
                --active_workers;
-               if ((active_workers + config.c_min_workers < num_workers) &&
-                   (num_workers > config.c_min_workers))
+               if ((active_workers + CtdlGetConfigInt("c_min_workers") < num_workers) &&
+                   (num_workers > CtdlGetConfigInt("c_min_workers")))
                {
                        num_workers--;
                        pthread_mutex_unlock(&ThreadCountMutex);
index f8843269005be7c038ab1b2f3d81fb2e5f424604..1af927555f80139ae118509743c5f3dd9773da18 100644 (file)
@@ -229,97 +229,97 @@ all software should be written to IGNORE fields not currently defined.
 
                  The type bytes currently defined are:
 
-BYTE   Mnemonic        Enum / Comments
-
-A      Author          eAuthor
-                       Name of originator of message.
-B      Big message     eBig_message
-                       This is a flag which indicates that the message is
-                       big, and Citadel is storing the body in a separate
-                       record.  You will never see this field because the
-                       internal API handles it.
-C      RemoteRoom      eRemoteRoom
-                       when sent via Citadel Networking, this is the room
-                       its going to be put on the remote site.
-D      Destination     eDestination
-                       Contains name of the system this message should
-                       be sent to, for mail routing (private mail only).
-E      Exclusive ID    eExclusiveID
-                       A persistent alphanumeric Message ID used for
-                       network replication.  When a message arrives that
-                       contains an Exclusive ID, any existing messages which
-                       contain the same Exclusive ID and are *older* than this
-                       message should be deleted.  If there exist any messages
-                       with the same Exclusive ID that are *newer*, then this
-                       message should be dropped.
-F      rFc822 address  erFc822Addr
-                       For Internet mail, this is the delivery address of the
-                       message author.
-H      Human node name eHumanNode
-                       Human-readable name of system message originated on.
-I      Message ID      emessageId
-                       An RFC822-compatible message ID for this message.
-J      Journal         eJournal
-                       The presence of this field indicates that the message
-                       is disqualified from being journaled, perhaps because
-                       it is itself a journalized message and we wish to
-                       avoid double journaling.
-K      Reply-To        eReplyTo
-                       the Reply-To header for mailinglist outbound messages
-L      List-ID         eListID
-                       Mailing list identification, as per RFC 2919
-M      Message Text    eMesageText
-                       Normal ASCII, newlines seperated by CR's or LF's,
-                       null terminated as always.
-N      Nodename        eNodeName
-                       Contains node name of system message originated on.
-O      Room            eOriginalRoom - Room of origin.
-P      Path            eMessagePath
-                       Complete path of message, as in the UseNet news
-                       standard.  A user should be able to send Internet mail
-                       to this path. (Note that your system name will not be
-                       tacked onto this until you're sending the message to
-                       someone else)
-R      Recipient       eRecipient - Only present in Mail messages.
-S      Special field   eSpecialField
-                       Only meaningful for messages being spooled over a
-                       network.  Usually means that the message isn't really
-                       a message, but rather some other network function:
-                       -> "S" followed by "FILE" (followed by a null, of
-                          course) means that the message text is actually an
-                          IGnet/Open file transfer.  (OBSOLETE)
-                       -> "S" followed by "CANCEL" means that this message
-                          should be deleted from the local message base once
-                          it has been replicated to all network systems.
-T      date/Time       eTimestamp
-                       Unix timestamp containing the creation date/time of
-                       the message.
-U      sUbject         eMsgSubject - Optional.
-                       Developers may choose whether they wish to
-                       generate or display subject fields.
-V      enVelope-to     eenVelopeTo
-                       The recipient specified in incoming SMTP messages.
-W      Wefewences      eWeferences
-                       Previous message ID's for conversation threading.  When
-                       converting from RFC822 we use References: if present, or
-                       In-Reply-To: otherwise.
-                       (Who in extnotify spool messages which don't need to know
-                       other message ids)
-Y      carbon copY     eCarbonCopY
-                       Optional, and only in Mail messages.
-0      Error           eErrorMsg
-                       This field is typically never found in a message on
-                       disk or in transit.  Message scanning modules are
-                       expected to fill in this field when rejecting a message
-                       with an explanation as to what happened (virus found,
-                       message looks like spam, etc.)
-1      suppress index  eSuppressIdx
-                       The presence of this field indicates that the message is
-                       disqualified from being added to the full text index.
-2      extnotify       eExtnotify - Used internally by the serv_extnotify module.
-3      msgnum          eVltMsgNum
-                       Used internally to pass the local message number in the
-                       database to after-save hooks.  Discarded afterwards.
+BYTE   Enum            Mnemonic        Enum / Comments
+                       
+A      eAuthor         Author          eAuthor
+                                       Name of originator of message.
+B      eBig_message    Big message     eBig_message
+                                       This is a flag which indicates that the message is
+                                       big, and Citadel is storing the body in a separate
+                                       record.  You will never see this field because the
+                                       internal API handles it.
+C      eRemoteRoom     RemoteRoom      eRemoteRoom
+                                       when sent via Citadel Networking, this is the room
+                                       its going to be put on the remote site.
+D      eDestination    Destination     eDestination
+                                       Contains name of the system this message should
+                                       be sent to, for mail routing (private mail only).
+E      eExclusiveID    Exclusive ID    eExclusiveID
+                                       A persistent alphanumeric Message ID used for
+                                       network replication.  When a message arrives that
+                                       contains an Exclusive ID, any existing messages which
+                                       contain the same Exclusive ID and are *older* than this
+                                       message should be deleted.  If there exist any messages
+                                       with the same Exclusive ID that are *newer*, then this
+                                       message should be dropped.
+F      erFc822Addr     rFc822 address  erFc822Addr
+                                       For Internet mail, this is the delivery address of the
+                                       message author.
+H      eHumanNode      Human node name eHumanNode
+                                       Human-readable name of system message originated on.
+I      emessageId      Message ID      emessageId
+                                       An RFC822-compatible message ID for this message.
+J      eJournal        Journal         eJournal
+                                       The presence of this field indicates that the message
+                                       is disqualified from being journaled, perhaps because
+                                       it is itself a journalized message and we wish to
+                                       avoid double journaling.
+K      eReplyTo        Reply-To        eReplyTo
+                                       the Reply-To header for mailinglist outbound messages
+L      eListID         List-ID         eListID
+                                       Mailing list identification, as per RFC 2919
+M      eMesageText     Message Text    eMesageText
+                                       Normal ASCII, newlines seperated by CR's or LF's,
+                                       null terminated as always.
+N      eNodeName       Nodename        eNodeName
+                                       Contains node name of system message originated on.
+O      eOriginalRoom   Room            eOriginalRoom - Room of origin.
+P      eMessagePath    Path            eMessagePath
+                                       Complete path of message, as in the UseNet news
+                                       standard.  A user should be able to send Internet mail
+                                       to this path. (Note that your system name will not be
+                                       tacked onto this until you're sending the message to
+                                       someone else)
+R      eRecipient      Recipient       eRecipient - Only present in Mail messages.
+S      eSpecialField   Special field   eSpecialField
+                                       Only meaningful for messages being spooled over a
+                                       network.  Usually means that the message isn't really
+                                       a message, but rather some other network function:
+                                       -> "S" followed by "FILE" (followed by a null, of
+                                          course) means that the message text is actually an
+                                          IGnet/Open file transfer.  (OBSOLETE)
+                                       -> "S" followed by "CANCEL" means that this message
+                                          should be deleted from the local message base once
+                                          it has been replicated to all network systems.
+T      eTimestamp      date/Time       eTimestamp
+                                       Unix timestamp containing the creation date/time of
+                                       the message.
+U      eMsgSubject     sUbject         eMsgSubject - Optional.
+                                       Developers may choose whether they wish to
+                                       generate or display subject fields.
+V      eenVelopeTo     enVelope-to     eenVelopeTo
+                                       The recipient specified in incoming SMTP messages.
+W      eWeferences     Wefewences      eWeferences
+                                       Previous message ID's for conversation threading.  When
+                                       converting from RFC822 we use References: if present, or
+                                       In-Reply-To: otherwise.
+                                       (Who in extnotify spool messages which don't need to know
+                                       other message ids)
+Y      eCarbonCopY     carbon copY     eCarbonCopY
+                                       Optional, and only in Mail messages.
+0      eErrorMsg       Error           eErrorMsg
+                                       This field is typically never found in a message on
+                                       disk or in transit.  Message scanning modules are
+                                       expected to fill in this field when rejecting a message
+                                       with an explanation as to what happened (virus found,
+                                       message looks like spam, etc.)
+1      eSuppressIdx    suppress index  eSuppressIdx
+                                       The presence of this field indicates that the message is
+                                       disqualified from being added to the full text index.
+2      eExtnotify      extnotify       eExtnotify - Used internally by the serv_extnotify module.
+3      eVltMsgNum      msgnum          eVltMsgNum
+                                       Used internally to pass the local message number in the
+                                       database to after-save hooks.  Discarded afterwards.
   
                        EXAMPLE
 
index 228a5b0aa6f85b6e7f908481f6fe6ffe862b3daf..5cb70334c0b9fc13703045236de963ac55c899de 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Thread handling stuff for Citadel server
  *
- * Copyright (c) 1987-2011 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -19,6 +19,7 @@
 #include "modules_init.h"
 #include "serv_extensions.h"
 #include "ctdl_module.h"
+#include "config.h"
 #include "context.h"
 #include "threads.h"
 
@@ -171,7 +172,7 @@ void go_threading(void)
         * they are all in use.
         */
        while (!server_shutting_down) {
-               if ((active_workers == num_workers) && (num_workers < config.c_max_workers)) {
+               if ((active_workers == num_workers) && (num_workers < CtdlGetConfigInt("c_max_workers"))) {
                        CtdlThreadCreate(worker_thread);
                }
                usleep(1000000);
index 6cce2a15bdf7c8bff110a0d75d794b25a2695aa5..1e8792d71d6a0cb9681c9bad800650a4da28e427 100644 (file)
@@ -19,6 +19,7 @@
 #include "control.h"
 #include "support.h"
 #include "citserver.h"
+#include "config.h"
 #include "citadel_ldap.h"
 #include "ctdl_module.h"
 #include "user_ops.h"
@@ -314,7 +315,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) {
        if (who->axlevel <= AxProbU) return(0);
 
        /* Globally enabled? */
-       if (config.c_restrict == 0) return(1);
+       if (CtdlGetConfigInt("c_restrict") == 0) return(1);
 
        /* User flagged ok? */
        if (who->flags & US_INTERNET) return(2);
@@ -338,7 +339,7 @@ int CtdlAccessCheck(int required_level)
                return(-1);
        }
 
-       if ((required_level >= ac_logged_in_or_guest) && (CC->logged_in == 0) && (!config.c_guest_logins)) {
+       if ((required_level >= ac_logged_in_or_guest) && (CC->logged_in == 0) && (CtdlGetConfigInt("c_guest_logins") == 0)) {
                cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
                return(-1);
        }
@@ -528,10 +529,10 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
 
        /* If a "master user" is defined, handle its authentication if specified */
        CC->is_master = 0;
-       if ((configlen.c_master_user > 0) && 
-           (configlen.c_master_pass > 0) &&
-           (authname != NULL) &&
-           (!strcasecmp(authname, config.c_master_user)))
+       if (    (!IsEmptyStr(CtdlGetConfigStr("c_master_user"))) && 
+               (!IsEmptyStr(CtdlGetConfigStr("c_master_pass"))) &&
+               (authname != NULL) &&
+               (!strcasecmp(authname, CtdlGetConfigStr("c_master_user"))) )
        {
                CC->is_master = 1;
        }
@@ -545,7 +546,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
                return login_not_found;
        }
 
-       if (config.c_auth_mode == AUTHMODE_HOST) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
 
                /* host auth mode */
 
@@ -586,7 +587,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
        }
 
 #ifdef HAVE_LDAP
-       else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       else if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
        
                /* LDAP auth mode */
 
@@ -670,14 +671,14 @@ void do_login(void)
        /* If this user's name is the name of the system administrator
         * (as specified in setup), automatically assign access level 6.
         */
-       if (!strcasecmp(CCC->user.fullname, config.c_sysadm)) {
+       if (!strcasecmp(CCC->user.fullname, CtdlGetConfigStr("c_sysadm"))) {
                CCC->user.axlevel = AxAideU;
        }
 
        /* If we're authenticating off the host system, automatically give
         * root the highest level of access.
         */
-       if (config.c_auth_mode == AUTHMODE_HOST) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
                if (CCC->user.uid == 0) {
                        CCC->user.axlevel = AxAideU;
                }
@@ -691,7 +692,7 @@ void do_login(void)
         * the vCard module's login hook runs.
         */
        snprintf(CCC->cs_inet_email, sizeof CCC->cs_inet_email, "%s@%s",
-               CCC->user.fullname, config.c_fqdn);
+               CCC->user.fullname, CtdlGetConfigStr("c_fqdn"));
        convert_spaces_to_underscores(CCC->cs_inet_email);
 
        /* Create any personal rooms required by the system.
@@ -706,7 +707,7 @@ void do_login(void)
        PerformSessionHooks(EVT_LOGIN);
 
        /* Enter the lobby */
-       CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL);
+       CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL);
 }
 
 
@@ -877,10 +878,10 @@ int CtdlTryPassword(const char *password, long len)
        }
 
        if (CCC->is_master) {
-               code = strcmp(password, config.c_master_pass);
+               code = strcmp(password, CtdlGetConfigStr("c_master_pass"));
        }
 
-       else if (config.c_auth_mode == AUTHMODE_HOST) {
+       else if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
 
                /* host auth mode */
 
@@ -910,7 +911,7 @@ int CtdlTryPassword(const char *password, long len)
        }
 
 #ifdef HAVE_LDAP
-       else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       else if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
 
                /* LDAP auth mode */
 
@@ -1052,7 +1053,7 @@ int internal_create_user (const char *username, long len, struct ctdluser *usbuf
 
        usbuf->timescalled = 0;
        usbuf->posted = 0;
-       usbuf->axlevel = config.c_initax;
+       usbuf->axlevel = CtdlGetConfigInt("c_initax");
        usbuf->lastcall = time(NULL);
 
        /* fetch a new user number */
@@ -1089,7 +1090,7 @@ int create_user(const char *newusername, long len, int become_user)
        strproc(username);
 
        
-       if (config.c_auth_mode == AUTHMODE_HOST) {
+       if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
 
                /* host auth mode */
 
@@ -1121,7 +1122,7 @@ int create_user(const char *newusername, long len, int become_user)
        }
 
 #ifdef HAVE_LDAP
-       if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
                if (CtdlTryUserLDAP(username, NULL, 0, username, sizeof username, &uid, 0) != 0) {
                        return(ERROR + NO_SUCH_USER);
                }
@@ -1239,7 +1240,7 @@ int CtdlForgetThisRoom(void) {
        visit vbuf;
 
        /* On some systems, Admins are not allowed to forget rooms */
-       if (is_aide() && (config.c_aide_zap == 0)
+       if (is_aide() && (CtdlGetConfigInt("c_aide_zap") == 0)
           && ((CC->room.QRflags & QR_MAILBOX) == 0)  ) {
                return(1);
        }
@@ -1254,7 +1255,7 @@ int CtdlForgetThisRoom(void) {
        CtdlPutUserLock(&CC->user);
 
        /* Return to the Lobby, so we don't end up in an undefined room */
-       CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL);
+       CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL);
        return(0);
 
 }
index 5a5d0c47498b6a1b79da6f0c985f5e5c83a3eb28..baa5f6de70231f27fec183bb886f413ee8642175 100644 (file)
@@ -137,10 +137,14 @@ int main(int argc, char *argv[])
                "(example: ctdl.foo.org)\n"
                "--> ");
        getz(remote_host);
+
+get_remote_user:
        printf("\nEnter the name of a user on %s who has full access to Citadel files\n"
                "(usually root)\n--> ",
                remote_host);
        getz(remote_user);
+       if (IsEmptyStr(remote_user))
+               goto get_remote_user;
 
        printf("\nEstablishing an SSH connection to the source system...\n\n");
        unlink(socket_path);
@@ -194,6 +198,8 @@ int main(int argc, char *argv[])
        }
 
        printf("ctdlmigrate will now begin a database migration...\n");
+       printf("  if the system doesn't start working, \n");
+       printf("  have a look at the syslog for pending jobs needing to be terminated.\n");
 
        snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s -w3600 MIGR export",
                socket_path, remote_user, remote_host, remote_sendcommand);
index 134ff47794a32e8790522a25d75a3e80b1bff960..0340ce4d44fb51e6edd50578e5d31c3a90eef890 100644 (file)
@@ -2827,7 +2827,7 @@ int StrBufDecodeBase64To(const StrBuf *BufIn, StrBuf *BufOut)
                return -1;
 
        if (BufOut->BufSize < BufIn->BufUsed)
-               IncreaseBuf(BufOut, BufIn->BufUsed, 0);
+               IncreaseBuf(BufOut, 0, BufIn->BufUsed);
 
        BufOut->BufUsed = CtdlDecodeBase64(BufOut->buf,
                                           BufIn->buf,
index ff35f9ecae04b9e7408cf9322bb17848fca7216d..14e43071a1761d6c02ed248ae6fdc6e70d82c7c7 100644 (file)
@@ -292,7 +292,6 @@ size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int li
        int breaklength = 68;
        int readlength = 3 * breaklength / 4;
 
-       int t;
        int destoffset;
        int sourceoffset;
        int sourceremaining;
@@ -318,7 +317,6 @@ size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int li
                        dest[destoffset++] = '\n';
                }
 
-               t = destoffset;
                destoffset += base64_encode_blockend(&(dest[destoffset]), &_state);
        }
        else {
index d5f187c3d45fcbf1226312184b281a0dd663ed68..c06f9ff0570e0434a8f56777e7875412d8f862fa 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Main source module for the client program.
  *
- * Copyright (c) 1987-2012 by the citadel.org team
+ * Copyright (c) 1987-2015 by the citadel.org team
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -1007,11 +1007,10 @@ void system_info(CtdlIPC *ipc)
        scr_printf("You are connected to %s (%s) @%s\n", ipc->ServInfo.nodename, ipc->ServInfo.humannode, ipc->ServInfo.fqdn);
        scr_printf("running %s with text client v%.2f,\n", ipc->ServInfo.software, (float)CLIENT_VERSION/100);
        scr_printf("server build %s,\n", ipc->ServInfo.svn_revision, (float)CLIENT_VERSION/100);
-    scr_printf("and located in %s.\n", ipc->ServInfo.site_location);
-    scr_printf("Connected users %d / Active users %d / Highest message #%ld\n", mrtg_users, mrtg_active_users, mrtg_himessage);
-    scr_printf("Server uptime: %s\n", mrtg_server_uptime);
-    scr_printf("Your system administrator is %s.\n", ipc->ServInfo.sysadm);
-    scr_printf("Copyright (C)1987-2009 by the Citadel development team\n");
+       scr_printf("and located in %s.\n", ipc->ServInfo.site_location);
+       scr_printf("Connected users %d / Active users %d / Highest message #%ld\n", mrtg_users, mrtg_active_users, mrtg_himessage);
+       scr_printf("Server uptime: %s\n", mrtg_server_uptime);
+       scr_printf("Your system administrator is %s.\n", ipc->ServInfo.sysadm);
 }
 
 /*
index bf3ac7def2171edb0ee1a074978670aaa492ff9e..fd13b97f1151c72d14ef893391ded2f721e9c849 100644 (file)
@@ -603,6 +603,7 @@ void context_loop(ParsedHttpHdrs *Hdr)
        pthread_setspecific(MyConKey, (void *)TheSession);
        
        TheSession->inuse = 1;                          /* mark the session as bound */
+       TheSession->isFailure = 0;                      /* reset evntually existing error flags */
        TheSession->lastreq = now;                      /* log */
        TheSession->Hdr = Hdr;
 
index dd1cc4deef70c1247a727dc9710237506682a481..f6642325f27026f73f65a0c802911bbda16e1996 100644 (file)
@@ -187,7 +187,7 @@ int GetConnected (void)
 
                /* Server isn't ready for us? */
                if (short_status != 2) {
-                       if (Status == 571) {
+                       if (Status == 551) {
                                hprintf("HTTP/1.1 503 Service Unavailable\r\n");
                                hprintf("Content-type: text/plain; charset=utf-8\r\n");
                                wc_printf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time.  Please try again later or contact your system administrator."));
index fd72242b2f7c37cfce01b6d399b13bc70326666f..688299b23c977d583ae709f0178e739e4d23c5bf 100644 (file)
@@ -1907,6 +1907,8 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
 
 }
 
+
+StrBuf *textPlainType;
 /**
  * \brief Display a variable-substituted template
  * \param templatename template file to load
@@ -1933,23 +1935,28 @@ const StrBuf *DoTemplate(const char *templatename, long len, StrBuf *Target, WCT
        {
                syslog(LOG_WARNING, "Can't to load a template with empty name!\n");
                StrBufAppendPrintf(Target, "<pre>\nCan't to load a template with empty name!\n</pre>");
-               return NULL;
+               return textPlainType;
        }
 
        if (!GetHash(StaticLocal, templatename, len, &vTmpl) &&
            !GetHash(Static, templatename, len, &vTmpl)) {
-               syslog(LOG_WARNING, "didn't find Template [%s] %ld %ld\n", templatename, len , (long)strlen(templatename));
+               StrBuf *escapedString = NewStrBufPlain(NULL, len);
+               
+               StrHtmlEcmaEscAppend(escapedString, NULL, templatename, 1, 1);
+               syslog(LOG_WARNING, "didn't find Template [%s] %ld %ld\n", ChrPtr(escapedString), len , (long)strlen(templatename));
                StrBufAppendPrintf(Target, "<pre>\ndidn't find Template [%s] %ld %ld\n</pre>", 
-                                  templatename, len, 
+                                  ChrPtr(escapedString), len, 
                                   (long)strlen(templatename));
+               WC->isFailure = 1;
 #if 0
                dbg_PrintHash(Static, PrintTemplate, NULL);
                PrintHash(Static, VarPrintTransition, PrintTemplate);
 #endif
-               return NULL;
+               FreeStrBuf(&escapedString);
+               return textPlainType;
        }
        if (vTmpl == NULL) 
-               return NULL;
+               return textPlainType;
        return ProcessTemplate(vTmpl, Target, TP);
 
 }
@@ -2988,9 +2995,9 @@ void
 ServerStartModule_SUBST
 (void)
 {
+       textPlainType = NewStrBufPlain(HKEY("text/plain"));
        LocalTemplateCache = NewHash(1, NULL);
        TemplateCache = NewHash(1, NULL);
-
        GlobalNS = NewHash(1, NULL);
        Iterators = NewHash(1, NULL);
        Conditionals = NewHash(1, NULL);
@@ -3016,9 +3023,11 @@ void
 ServerShutdownModule_SUBST
 (void)
 {
+       FreeStrBuf(&textPlainType);
+
        DeleteHash(&TemplateCache);
        DeleteHash(&LocalTemplateCache);
-
+       
        DeleteHash(&GlobalNS);
        DeleteHash(&Iterators);
        DeleteHash(&Conditionals);
index 91fc47e26424c64bf0d85a0ec173554fed1cb5ec..bca779a3ad331009fd6355ce5da49a13f3f83577 100644 (file)
@@ -141,7 +141,9 @@ void output_headers(        int do_httpheaders,     /* 1 = output HTTP headers                        */
        wcsession *WCC = WC;
        char httpnow[128];
 
-       if (WCC->Hdr->HaveRange > 1)
+       if (WCC->isFailure) 
+               hprintf("HTTP/2.2 500 Internal Server Error");
+       else if (WCC->Hdr->HaveRange > 1)
                hprintf("HTTP/1.1 206 Partial Content\r\n");
        else
                hprintf("HTTP/1.1 200 OK\r\n");
index a087d5f37599b9514eeadc9ebfd38c237de08428..8913f4fed01a8fa73efe673522ce4bd6635283df 100644 (file)
@@ -422,6 +422,7 @@ struct wcsession {
        int ctdl_pid;                           /* Session ID on the Citadel server */
        int nonce;                              /* session nonce (to prevent session riding) */
        int inuse;                              /* set to nonzero if bound to a running thread */
+       int isFailure;                          /* Http 2xx or 5xx? */
 
 /* Session local Members */
        int serv_sock;                          /* Client socket to Citadel server */