/*
* 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);
+ }
}
*/
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 (config.c_ctdluid == 0) {
- pw = getpwnam("bbs");
- 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("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,
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);
* 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;
-
- /* Default lower and upper limits on number of worker threads */
+ if (CtdlGetConfigLong("c_maxmsglen") <= 0) CtdlSetConfigLong("c_maxmsglen", 10485760);
+ if (CtdlGetConfigLong("c_maxmsglen") < 8192) CtdlSetConfigLong("c_maxmsglen", 8192);
- 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();
+ }
+
+ /* 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);
}
- syslog(LOG_EMERG, "%s: %s", file_citadel_config, strerror(errno));
+
+ /* 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;
conf = NULL;
}
else {
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg != NULL) {
conf = strdup(msg->cm_fields[eMesageText]);
CM_Free(msg);
/*
* 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
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;
}
{
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;
}
{
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)
/*
- * 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);
- }
}
-
-
-
/*
* check_control - check the control record has sensible values for message, user and room numbers
*/
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.
{
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);
}
* 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");
}
{
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);
}
{
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
*
{
char cmd[16];
char buf[256];
- int a;
+ int a, i;
+ long ii;
char *confptr;
char confname[128];
extract_token(cmd, argbuf, 0, '|', sizeof cmd);
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", 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", 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_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");
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");
}
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);
}
}
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);
}
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;
/*
* 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.
#include "ctdl_module.h"
#include "control.h"
#include "citserver.h"
+ #include "config.h"
static DB *dbp[MAXCDB]; /* One DB handle for each Citadel database */
}
/* After a successful checkpoint, we can cull the unused logs */
- if (config.c_auto_cull) {
+ if (CtdlGetConfigInt("c_auto_cull")) {
cdb_cull_logs();
}
}
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());
/*
else
{
if (cdbut) cdb_free(cdbut);
-
+
SEENM_syslog(LOG_DEBUG, "not Found");
+ if (cType == eCheckUpdate)
+ return 0;
}
if (cType == eCheckExist)
* Function to go through an ical component set and convert all non-UTC
* date/time properties to UTC. It also strips out any VTIMEZONE
* subcomponents afterwards, because they're irrelevant.
- *
- * 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.
*/
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);
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);
*/
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);
/*
* 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"
/*
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]);
/*
* 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) {
* 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"
#include "room_ops.h"
#include "euidindex.h"
#include "ical_dezonify.h"
+ #include "config.h"
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);
return;
}
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) {
cprintf("%d Message %ld not found.\n",
ERROR + ILLEGAL_VALUE,
* 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 */
}
return;
}
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) {
cprintf("%d Message %ld not found.\n",
ERROR + ILLEGAL_VALUE,
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_");
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,
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_");
* 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) {
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] = '_';
/* 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_");
}
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;
}
/*
* 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.
*/
}
-
/*
* Back end for the MSGS command: output header summary.
*/
{
struct CtdlMessage *msg;
- msg = CtdlFetchMessage(msgnum, 0);
+ msg = CtdlFetchMessage(msgnum, 0, 1);
if (msg == NULL) {
cprintf("%ld|0|||||\n", msgnum);
return;
{
struct CtdlMessage *msg;
- msg = CtdlFetchMessage(msgnum, 0);
+ msg = CtdlFetchMessage(msgnum, 0, 1);
if (msg == NULL) {
cprintf("%ld||\n", msgnum);
return;
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;
}
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);
*
* 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
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);
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;
/* 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. */
/* 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;
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;
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;
}
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 */
}
*/
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;
}
* 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
*/
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],
Ctx = (NotifyContext*) usrdata;
- msg = CtdlFetchMessage(NotifyMsgnum, 1);
+ msg = CtdlFetchMessage(NotifyMsgnum, 1, 1);
if (!CM_IsEmpty(msg, eExtnotify))
{
Type = extNotify_getConfigMessage(
{
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,
int commandSiz;
char *command;
- commandSiz = sizeof(config.c_pager_program) +
+ commandSiz = sizeof(CtdlGetConfigStr("c_pager_program")) +
strlen(PagerNo) +
msg->cm_lengths[eExtnotify] + 5;
snprintf(command,
commandSiz,
"%s %s -u %s",
- config.c_pager_program,
+ CtdlGetConfigStr("c_pager_program"),
PagerNo,
msg->cm_fields[eExtnotify]);
* 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");
/* 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
/*
* 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
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;
*/
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;
/*
* Don't do this if the site doesn't have it enabled.
*/
- if (!config.c_enable_fulltext) {
+ if (!CtdlGetConfigInt("c_enable_fulltext")) {
return;
}
* 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! */
}
* 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) {
/* 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);
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;
if (room) return;
/* Remove from fulltext index */
- if (config.c_enable_fulltext) {
+ if (CtdlGetConfigInt("c_enable_fulltext")) {
ft_index_message(msgnum, 0);
}
}
* 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.
*/
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 */
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 */
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],
}
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);
/*
* 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"
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) {
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) {
/* 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) {
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) {
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) {
* 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;
}
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
* 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) {
/*
* 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.
* 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
#include "database.h"
#include "msgbase.h"
#include "user_ops.h"
- #include "control.h"
#include "euidindex.h"
#include "ctdl_module.h"
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: & < >
while (*c != 0) {
if (*c == '\"') {
- client_write(""", 6);
+ client_write(HKEY("""));
}
else if (*c == '\'') {
- client_write("'", 6);
+ client_write(HKEY("'"));
}
else if (*c == '<') {
- client_write("<", 4);
+ client_write(HKEY("<"));
}
else if (*c == '>') {
- client_write(">", 4);
+ client_write(HKEY(">"));
}
else if (*c == '&') {
- client_write("&", 5);
+ client_write(HKEY("&"));
}
else {
client_write(c, 1);
* 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);
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"));
}
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);
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"));
}
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"));
}
}
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"));
}
}
/* 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);
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"));
}
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) {
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(HKEY("<config>\n"));
- client_write(HKEY("<c_nodename>")); xml_strout(config.c_nodename); client_write(HKEY("</c_nodename>\n"));
- client_write(HKEY("<c_fqdn>")); xml_strout(config.c_fqdn); client_write(HKEY("</c_fqdn>\n"));
- client_write(HKEY("<c_humannode>")); xml_strout(config.c_humannode); client_write(HKEY("</c_humannode>\n"));
- client_write(HKEY("<c_phonenum>")); xml_strout(config.c_phonenum); client_write(HKEY("</c_phonenum>\n"));
- 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(HKEY("<c_twitroom>")); xml_strout(config.c_twitroom); client_write(HKEY("</c_twitroom>\n"));
- client_write(HKEY("<c_moreprompt>")); xml_strout(config.c_moreprompt); client_write(HKEY("</c_moreprompt>\n"));
- cprintf("<c_restrict>%d</c_restrict>\n", config.c_restrict);
- client_write(HKEY("<c_site_location>")); xml_strout(config.c_site_location); client_write(HKEY("</c_site_location>\n"));
- client_write(HKEY("<c_sysadm>")); xml_strout(config.c_sysadm); client_write(HKEY("</c_sysadm>\n"));
- cprintf("<c_maxsessions>%d</c_maxsessions>\n", config.c_maxsessions);
- client_write(HKEY("<c_ip_addr>")); xml_strout(config.c_ip_addr); client_write(HKEY("</c_ip_addr>\n"));
- 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(HKEY("<c_logpages>")); xml_strout(config.c_logpages); client_write(HKEY("</c_logpages>\n"));
- 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(HKEY("<c_baseroom>")); xml_strout(config.c_baseroom); client_write(HKEY("</c_baseroom>\n"));
- client_write(HKEY("<c_aideroom>")); xml_strout(config.c_aideroom); client_write(HKEY("</c_aideroom>\n"));
- 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(HKEY("<c_ldap_host>")); xml_strout(config.c_ldap_host); client_write(HKEY("</c_ldap_host>\n"));
- cprintf("<c_ldap_port>%d</c_ldap_port>\n", config.c_ldap_port);
- client_write(HKEY("<c_ldap_base_dn>")); xml_strout(config.c_ldap_base_dn); client_write(HKEY("</c_ldap_base_dn>\n"));
- client_write(HKEY("<c_ldap_bind_dn>")); xml_strout(config.c_ldap_bind_dn); client_write(HKEY("</c_ldap_bind_dn>\n"));
- client_write(HKEY("<c_ldap_bind_pw>")); xml_strout(config.c_ldap_bind_pw); client_write(HKEY("</c_ldap_bind_pw>\n"));
- 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(HKEY("<c_journal_dest>")); xml_strout(config.c_journal_dest); client_write(HKEY("</c_journal_dest>\n"));
- client_write(HKEY("<c_default_cal_zone>")); xml_strout(config.c_default_cal_zone); client_write(HKEY("</c_default_cal_zone>\n"));
- 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(HKEY("<c_funambol_host>")); xml_strout(config.c_funambol_host); client_write(HKEY("</c_funambol_host>\n"));
- cprintf("<c_funambol_port>%d</c_funambol_port>\n", config.c_funambol_port);
- client_write(HKEY("<c_funambol_source>")); xml_strout(config.c_funambol_source); client_write(HKEY("</c_funambol_source>\n"));
- client_write(HKEY("<c_funambol_auth>")); xml_strout(config.c_funambol_auth); client_write(HKEY("</c_funambol_auth>\n"));
- cprintf("<c_rbl_at_greeting>%d</c_rbl_at_greeting>\n", config.c_rbl_at_greeting);
- client_write(HKEY("<c_master_user>")); xml_strout(config.c_master_user); client_write(HKEY("</c_master_user>\n"));
- client_write(HKEY("<c_master_pass>")); xml_strout(config.c_master_pass); client_write(HKEY("</c_master_pass>\n"));
- client_write(HKEY("<c_pager_program>")); xml_strout(config.c_pager_program); client_write(HKEY("</c_pager_program>\n"));
- 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(HKEY("</config>\n"));
- cprintf("<progress>%d</progress>\n", 1);
-
- /* Export the control file */
- get_control();
- client_write(HKEY("<control>\n"));
- 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(HKEY("</control>\n"));
+ /* 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();
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? */
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;
}
else return 0;
return 1;
}
+
+
void migr_xml_end(void *data, const char *el)
{
const char *ptr;
/*** 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))
/*** 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 ***/
+/******************************************************************************
+ * Dispatcher, Common code *
+ ******************************************************************************/
/*
* Dump out the pathnames of directories which can be copied "as is"
*/
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];
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);
}
}
}
+/******************************************************************************
+ * Module Hook *
+ ******************************************************************************/
CTDL_MODULE_INIT(migrate)
{
* 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.
/* 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);
/* 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);
*/
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;
}
sc = (SpoolControl *)userdata;
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL)
{
* 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
- snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, config.c_nodename);
+/*
+ * 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;
+
- config.c_fqdn);
++ 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,
- CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
++ 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));
- strcpy(force_room, config.c_aideroom);
++ 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, config.c_aideroom);
++ 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;
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);
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>
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]);
}
}
else
{
- snprintf(buf, sizeof buf, "room_%s@%s", CCC->room.QRname, CtdlGetConfigStr("c_fqdn"));
+ 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) {
}
}
+
+/*
+ * 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
/* 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));
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;
}
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;
* 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
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
}
-
-/*
- * 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, 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");
-}
-
-
-
/*
* network_do_queue()
*
* 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)
);
}
//
// 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.
}
// 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"));
}
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);
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;
}
{
if (!threading)
{
- CtdlRegisterServiceHook(config.c_nntp_port,
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntp_port"),
NULL,
nntp_greeting,
nntp_command_loop,
CitadelServiceNNTP);
#ifdef HAVE_OPENSSL
- CtdlRegisterServiceHook(config.c_nntps_port,
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntps_port"),
NULL,
nntps_greeting,
nntp_command_loop,
/*
* 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>
const char *HKey;
void *vData;
pop3aggr *RecvMsg = (pop3aggr *) IO->Data;
+ time_t seenstamp = 0;
SetPOP3State(IO, eUseTable);
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;
SetPOP3State(IO, eGetMsg);
+ EVP3CM_syslog(LOG_DEBUG, "fast forwarding to the next unknown message");
+
RecvMsg->CurrMsg = NULL;
while ((RecvMsg->Pos != NULL) &&
GetNextHashPos(RecvMsg->MsgNumbers,
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,
return eReadMessage;
}
else {
+ EVP3CM_syslog(LOG_DEBUG, "no more messages to fetch.");
RecvMsg->State = ReadQuitState;
return POP3_C_DispatchWriteDone(&RecvMsg->IO);
}
if (!POP3C_OK) return eTerminateConnection;
RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
RecvMsg->CurrMsg->MSGSize,
- config.c_maxmsglen,
+ CtdlGetConfigLong("c_maxmsglen"),
NULL, -1,
1);
AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
RecvMsg->State = GetOneMessageIDState;
- return eReadMessage;
+ return POP3_C_DispatchWriteDone(&RecvMsg->IO);
}
eNextState POP3C_SendQuit(pop3aggr *RecvMsg)
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
/*
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;
/*
* 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.
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;
guid,
EvGetNow(IO),
EvGetNow(IO) - USETABLE_ANTIEXPIRE,
- eCheckUpdate,
+ eUpdate,
CCID, IO->ID)
!= 0)
{
* 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.
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);
/*
* 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;
/*
}
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) */
}
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);
long conflen;
u->config_msgnum = msgnum;
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) {
u->config_msgnum = (-1) ;
return;
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;
}
* 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.
/* 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);
/* 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"));
}
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
/*
return; // already got it
}
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) {
return;
}
/* 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
/* 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);
" by %s; %s\n",
ChrPtr(sSMTP->helo_node),
(long int) CCC->cs_UDSclientUID,
- config.c_fqdn,
+ CtdlGetConfigStr("c_fqdn"),
nowstamp);
}
else {
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");
* 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;
}
}
- 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));
#endif
- CtdlRegisterServiceHook(config.c_smtp_port, /* SMTP MTA */
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtp_port"), /* SMTP MTA */
NULL,
smtp_mta_greeting,
smtp_command_loop,
CitadelServiceSMTP_MTA);
#ifdef HAVE_OPENSSL
- CtdlRegisterServiceHook(config.c_smtps_port,
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtps_port"), /* SMTPS MTA */
NULL,
smtps_greeting,
smtp_command_loop,
CitadelServiceSMTPS_MTA);
#endif
- CtdlRegisterServiceHook(config.c_msa_port, /* SMTP MSA */
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_msa_port"), /* SMTP MSA */
NULL,
smtp_msa_greeting,
smtp_command_loop,
* 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"
boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
StrBufAppendPrintf(boundary,
"%s_%04x%04x",
- config.c_fqdn,
+ CtdlGetConfigStr("c_fqdn"),
getpid(),
++seq);
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);
/* 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 */
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);
* 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);
}
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);
}
/* 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) )
{
/* 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] = '_';
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]);
}
/* 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);
}
#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];
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;
}
* 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];
#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] = '_';
}
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,
return;
}
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) return;
if (CM_IsEmpty(msg, eMesageText))
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 */
* 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)) {
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);
}
/* for postfix tcpdict */
- CtdlRegisterServiceHook(config.c_pftcpdict_port, /* Postfix */
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_pftcpdict_port"), /* Postfix */
NULL,
check_get_greeting,
check_get,
/*
* 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.
/* 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;
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 */
uuid,
Now,
CCC->user.fullname,
- config.c_nodename);
+ CtdlGetConfigStr("c_nodename"));
memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0);
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;
*/
msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room);
if (msgnum > 0L) {
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
}
else {
msg = NULL;
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;
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 */
}
);
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>"
char *ptr = NULL;
char *lasts = NULL;
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
if (msg == NULL) {
return;
}
/*
* 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.
#include "ctdl_module.h"
#include "citserver.h"
#include "control.h"
+ #include "config.h"
#include "clientsocket.h"
#include "genstamp.h"
#include "room_ops.h"
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;
}
}
-
-/*
- * 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.
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));
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
} 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
}
/* 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;
}
* 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) {
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
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,
msg = supplied_msg;
}
else {
- msg = CtdlFetchMessage(msgid, 0);
+ msg = CtdlFetchMessage(msgid, 0, 1);
}
if (msg != NULL) {
* 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,
- CtdlGetConfigStr("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);
- config.c_fqdn
+ 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)
*/
* 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;
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");
}
}
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);
}
}
{
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]);
}
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;
}
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");
}
}
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);
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);
}
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);
}
* 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. */
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);
/*
* 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.
int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) {
if ( (!(CC->logged_in))
&& (!(CC->internal_pgm))
- && (!config.c_guest_logins)
+ && (!CtdlGetConfigInt("c_guest_logins"))
) {
return(om_not_logged_in);
}
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;
}
}
/* 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 {
/* 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;
}
/*
* 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);
/* 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))
+ 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;
*/
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);
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);
}
/* 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;
}
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);
#include "user_ops.h"
#include "ecrash.h"
+ uid_t ctdluid = 0;
const char *CitadelServiceUDS="citadel-UDS";
const char *CitadelServiceTCP="citadel-TCP";
+
+
+
void go_threading(void);
/*
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
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));
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) ),
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;
"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));
/*
* 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,
/*
* 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();
}
#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;