From: Wilfried Goesgens Date: Wed, 7 Oct 2015 12:37:52 +0000 (+0200) Subject: Merge branch 'master' of ssh://git.citadel.org/appl/gitroot/citadel X-Git-Tag: Release_902~156^2~1 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=9571de81331e169c042c630800bff1bde499c8a9;hp=c51a64e8f8b42b6efd85f17c91178437d73a9c3d Merge branch 'master' of ssh://git.citadel.org/appl/gitroot/citadel --- diff --git a/citadel/auth.c b/citadel/auth.c index 07f4e9fa7..74fa9ebc3 100644 --- a/citadel/auth.c +++ b/citadel/auth.c @@ -104,19 +104,19 @@ int validate_password(uid_t uid, const char *pass) #endif struct passwd *pw; int retval = 0; - int flags = 0; - -#ifdef PAM_DATA_SILENT - flags = PAM_DATA_SILENT; -#else - flags = 0; -#endif /* PAM_DATA_SILENT */ if ((pw = getpwuid(uid)) == NULL) { return retval; } #ifdef HAVE_PAM_START + +#ifdef PAM_DATA_SILENT + int flags = PAM_DATA_SILENT; +#else + int flags = 0; +#endif /* PAM_DATA_SILENT */ + pc.conv = conv; pc.appdata_ptr = &data; data.name = pw->pw_name; diff --git a/citadel/citadel.h b/citadel/citadel.h index 9198d4a28..f45b0ea77 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -1,7 +1,7 @@ /* * Main Citadel header 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. @@ -45,10 +45,10 @@ extern "C" { * usually more strict because you're not really supposed to dump/load and * upgrade at the same time. */ -#define REV_LEVEL 830 /* This version */ +#define REV_LEVEL 901 /* This version */ #define REV_MIN 591 /* Oldest compatible database */ #define EXPORT_REV_MIN 760 /* Oldest compatible export files */ -#define LIBCITADEL_MIN 829 /* Minimum required version of libcitadel */ +#define LIBCITADEL_MIN 901 /* Minimum required version of libcitadel */ #define SERVER_TYPE 0 /* zero for stock Citadel; other developers please obtain SERVER_TYPE codes for your implementations */ @@ -116,9 +116,7 @@ struct ctdluser { /* User record */ }; -/* Bits which may appear in CitControl.MMflags. Note that these don't - * necessarily pertain to the message base -- it's just a good place to - * store any global flags. +/* Bits which may appear in MMflags. */ #define MM_VALID 4 /* New users need validating */ diff --git a/citadel/citserver.c b/citadel/citserver.c index 4a1070b23..9832b7812 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -1,7 +1,7 @@ /* * Main source module for the Citadel server * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -122,11 +122,9 @@ void master_startup(void) { syslog(LOG_DEBUG, "master_startup() started\n"); time(&server_startup_time); - get_config(); - validate_config(); syslog(LOG_INFO, "Checking directory access"); - if ((pw = getpwuid(CTDLUID)) == NULL) { + if ((pw = getpwuid(ctdluid)) == NULL) { gid = getgid(); } else { gid = pw->pw_gid; @@ -138,13 +136,21 @@ void master_startup(void) { } syslog(LOG_INFO, "Opening databases"); open_databases(); + + /* Load site-specific configuration */ + syslog(LOG_INFO, "Initializing configuration system"); + initialize_config_system(); + validate_config(); + migrate_legacy_control_record(); + + /* Check floor reference counts */ check_ref_counts(); syslog(LOG_INFO, "Creating base rooms (if necessary)\n"); - CtdlCreateRoom(config.c_baseroom, 0, "", 0, 1, 0, VIEW_BBS); - CtdlCreateRoom(AIDEROOM, 3, "", 0, 1, 0, VIEW_BBS); - CtdlCreateRoom(SYSCONFIGROOM, 3, "", 0, 1, 0, VIEW_BBS); - CtdlCreateRoom(config.c_twitroom, 0, "", 0, 1, 0, VIEW_BBS); + CtdlCreateRoom(CtdlGetConfigStr("c_baseroom"), 0, "", 0, 1, 0, VIEW_BBS); + CtdlCreateRoom(AIDEROOM, 3, "", 0, 1, 0, VIEW_BBS); + CtdlCreateRoom(SYSCONFIGROOM, 3, "", 0, 1, 0, VIEW_BBS); + CtdlCreateRoom(CtdlGetConfigStr("c_twitroom"), 0, "", 0, 1, 0, VIEW_BBS); /* The "Local System Configuration" room doesn't need to be visible */ if (CtdlGetRoomLock(&qrbuf, SYSCONFIGROOM) == 0) { @@ -174,8 +180,6 @@ void master_startup(void) { srand(seed); srandom(seed); - put_config(); - syslog(LOG_DEBUG, "master_startup() finished\n"); } @@ -200,6 +204,9 @@ void master_cleanup(int exitcode) { /* Do system-dependent stuff */ sysdep_master_cleanup(); + + /* Close the configuration system */ + shutdown_config_system(); /* Close databases */ syslog(LOG_INFO, "Closing databases\n"); @@ -214,8 +221,6 @@ void master_cleanup(int exitcode) { } } - release_control(); - /* Now go away. */ syslog(LOG_NOTICE, "citserver: Exiting with status %d\n", exitcode); fflush(stdout); fflush(stderr); @@ -289,7 +294,7 @@ int CtdlIsPublicClient(void) safestrncpy(public_clientspos, LOCALHOSTSTR, sizeof public_clients); public_clientspos += sizeof(LOCALHOSTSTR) - 1; - if (hostname_to_dotted_quad(addrbuf, config.c_fqdn) == 0) { + if (hostname_to_dotted_quad(addrbuf, CtdlGetConfigStr("c_fqdn")) == 0) { *(public_clientspos++) = '|'; paddr = &addrbuf[0]; while (!IsEmptyStr (paddr) && @@ -351,12 +356,12 @@ void citproto_begin_session() { if (CC->nologin==1) { cprintf("%d %s: Too many users are already online (maximum is %d)\n", ERROR + MAX_SESSIONS_EXCEEDED, - config.c_nodename, config.c_maxsessions + CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions") ); CC->kill_me = KILLME_MAX_SESSIONS_EXCEEDED; } else { - cprintf("%d %s Citadel server ready.\n", CIT_OK, config.c_nodename); + cprintf("%d %s Citadel server ready.\n", CIT_OK, CtdlGetConfigStr("c_nodename")); CC->can_receive_im = 1; } } @@ -364,7 +369,7 @@ void citproto_begin_session() { void citproto_begin_admin_session() { CC->internal_pgm = 1; - cprintf("%d %s Citadel server ADMIN CONNECTION ready.\n", CIT_OK, config.c_nodename); + cprintf("%d %s Citadel server ADMIN CONNECTION ready.\n", CIT_OK, CtdlGetConfigStr("c_nodename")); } diff --git a/citadel/citserver.h b/citadel/citserver.h index 4224fcdcb..997775bd2 100644 --- a/citadel/citserver.h +++ b/citadel/citserver.h @@ -1,13 +1,13 @@ /* - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "serv_extensions.h" diff --git a/citadel/config.c b/citadel/config.c index 34028abb0..b6c386b6e 100644 --- a/citadel/config.c +++ b/citadel/config.c @@ -1,7 +1,7 @@ /* * Read and write the citadel.config file * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -19,49 +19,66 @@ #include "config.h" #include "ctdl_module.h" -struct config config; -struct configlen configlen; +long config_msgnum = 0; +HashList *ctdlconfig = NULL; // new configuration + + +void config_warn_if_port_unset(char *key, int default_port) \ +{ + int p = CtdlGetConfigInt(key); + if ((p < -1) || (p == 0) || (p > UINT16_MAX)) + { + syslog(LOG_EMERG, + "configuration setting %s is not -1 (disabled) or a valid TCP-Port - check your config! Default setting is: %d", + key, default_port + ); + } +} + + +void config_warn_if_empty(char *key) +{ + if (IsEmptyStr(CtdlGetConfigStr(key))) + { + syslog(LOG_EMERG, "configuration setting %s is empty, but must not - check your config!", key); + } +} -#define STR_NOT_EMPTY(CFG_FIELDNAME) if (IsEmptyStr(config.CFG_FIELDNAME)) \ - syslog(LOG_EMERG, "configuration setting "#CFG_FIELDNAME" is empty, but must not - check your config!"); -#define TEST_PORT(CFG_PORT, DEFAULTPORT) \ - if ((config.CFG_PORT < -1) || \ - (config.CFG_PORT == 0) || \ - (config.CFG_PORT > UINT16_MAX)) \ - syslog(LOG_EMERG, "configuration setting "#CFG_PORT" is not -1 (disabled) or a valid TCP-Port - check your config! Default setting is: "#DEFAULTPORT); - void validate_config(void) { -/* these shouldn't be empty: */ - STR_NOT_EMPTY(c_fqdn); - - STR_NOT_EMPTY(c_baseroom); - STR_NOT_EMPTY(c_aideroom); - STR_NOT_EMPTY(c_twitroom); - STR_NOT_EMPTY(c_nodename); - STR_NOT_EMPTY(c_default_cal_zone); - -/* we bind a lot of ports: */ - TEST_PORT(c_smtp_port, 25); - TEST_PORT(c_pop3_port, 110); - TEST_PORT(c_imap_port, 143); - TEST_PORT(c_msa_port, 587); - TEST_PORT(c_port_number, 504); - TEST_PORT(c_smtps_port, 465); - TEST_PORT(c_pop3s_port, 995); - TEST_PORT(c_imaps_port, 993); - TEST_PORT(c_pftcpdict_port, -1); - TEST_PORT(c_managesieve_port, 2020); - TEST_PORT(c_xmpp_c2s_port, 5222); - TEST_PORT(c_xmpp_s2s_port, 5269); - TEST_PORT(c_nntp_port, 119); - TEST_PORT(c_nntps_port, 563); - - if (config.c_ctdluid == 0) - syslog(LOG_EMERG, "citadel should not be configured to run as root! Check the value of c_ctdluid"); - else if (getpwuid(CTDLUID) == NULL) - syslog(LOG_EMERG, "The UID (%d) citadel is configured to use is not defined in your system (/etc/passwd?)! Check the value of c_ctdluid", CTDLUID); + + /* + * these shouldn't be empty + */ + config_warn_if_empty("c_fqdn"); + config_warn_if_empty("c_baseroom"); + config_warn_if_empty("c_aideroom"); + config_warn_if_empty("c_twitroom"); + config_warn_if_empty("c_nodename"); + config_warn_if_empty("c_default_cal_zone"); + + /* + * Sanity check for port bindings + */ + config_warn_if_port_unset("c_smtp_port", 25); + config_warn_if_port_unset("c_pop3_port", 110); + config_warn_if_port_unset("c_imap_port", 143); + config_warn_if_port_unset("c_msa_port", 587); + config_warn_if_port_unset("c_port_number", 504); + config_warn_if_port_unset("c_smtps_port", 465); + config_warn_if_port_unset("c_pop3s_port", 995); + config_warn_if_port_unset("c_imaps_port", 993); + config_warn_if_port_unset("c_pftcpdict_port", -1); + config_warn_if_port_unset("c_managesieve_port", 2020); + config_warn_if_port_unset("c_xmpp_c2s_port", 5222); + config_warn_if_port_unset("c_xmpp_s2s_port", 5269); + config_warn_if_port_unset("c_nntp_port", 119); + config_warn_if_port_unset("c_nntps_port", 563); + + if (getpwuid(ctdluid) == NULL) { + syslog(LOG_EMERG, "The UID (%d) citadel is configured to use is not defined in your system (/etc/passwd?)!", ctdluid); + } } @@ -70,110 +87,165 @@ void validate_config(void) { */ void brand_new_installation_set_defaults(void) { - struct passwd *pw; struct utsname my_utsname; struct hostent *he; + char detected_hostname[256]; /* Determine our host name, in case we need to use it as a default */ uname(&my_utsname); - memset(&configlen, 0, sizeof(struct configlen)); + /* set some sample/default values in place of blanks... */ - configlen.c_nodename = extract_token(config.c_nodename, my_utsname.nodename, 0, '.', sizeof config.c_nodename); - if (IsEmptyStr(config.c_fqdn) ) { - if ((he = gethostbyname(my_utsname.nodename)) != NULL) { - configlen.c_fqdn = safestrncpy(config.c_fqdn, he->h_name, sizeof config.c_fqdn); - } - else { - configlen.c_fqdn = safestrncpy(config.c_fqdn, my_utsname.nodename, sizeof config.c_fqdn); - } - } + extract_token(detected_hostname, my_utsname.nodename, 0, '.', sizeof detected_hostname); + CtdlSetConfigStr("c_nodename", detected_hostname); - configlen.c_humannode = safestrncpy(config.c_humannode, "Citadel Server", sizeof config.c_humannode); - configlen.c_phonenum = safestrncpy(config.c_phonenum, "US 800 555 1212", sizeof config.c_phonenum); - config.c_initax = 4; - configlen.c_moreprompt = safestrncpy(config.c_moreprompt, "", sizeof config.c_moreprompt); - configlen.c_twitroom = safestrncpy(config.c_twitroom, "Trashcan", sizeof config.c_twitroom); - configlen.c_baseroom = safestrncpy(config.c_baseroom, BASEROOM, sizeof config.c_baseroom); - configlen.c_aideroom = safestrncpy(config.c_aideroom, "Aide", sizeof config.c_aideroom); - config.c_port_number = 504; - config.c_sleeping = 900; - - if (config.c_ctdluid == 0) { - pw = getpwnam("citadel"); - if (pw != NULL) { - config.c_ctdluid = pw->pw_uid; - } + if ((he = gethostbyname(my_utsname.nodename)) != NULL) { + CtdlSetConfigStr("c_fqdn", he->h_name); } - if (config.c_ctdluid == 0) { - pw = getpwnam("bbs"); - if (pw != NULL) { - config.c_ctdluid = pw->pw_uid; - } - } - if (config.c_ctdluid == 0) { - pw = getpwnam("guest"); - if (pw != NULL) { - config.c_ctdluid = pw->pw_uid; - } + else { + CtdlSetConfigStr("c_fqdn", my_utsname.nodename); } - if (config.c_createax == 0) { - config.c_createax = 3; + + CtdlSetConfigStr("c_humannode", "Citadel Server"); + CtdlSetConfigInt("c_initax", 4); + CtdlSetConfigStr("c_moreprompt", ""); + CtdlSetConfigStr("c_twitroom", "Trashcan"); + CtdlSetConfigStr("c_baseroom", BASEROOM); + CtdlSetConfigStr("c_aideroom", "Aide"); + CtdlSetConfigInt("c_sleeping", 900); + + if (CtdlGetConfigInt("c_createax") == 0) { + CtdlSetConfigInt("c_createax", 3); } /* * Default port numbers for various services */ - config.c_smtp_port = 25; - config.c_pop3_port = 110; - config.c_imap_port = 143; - config.c_msa_port = 587; - config.c_smtps_port = 465; - config.c_pop3s_port = 995; - config.c_imaps_port = 993; - config.c_pftcpdict_port = -1 ; - config.c_managesieve_port = 2020; - config.c_xmpp_c2s_port = 5222; - config.c_xmpp_s2s_port = 5269; - config.c_nntp_port = 119; - config.c_nntps_port = 563; + CtdlSetConfigInt("c_port_number", 504); + CtdlSetConfigInt("c_smtp_port", 25); + CtdlSetConfigInt("c_pop3_port", 110); + CtdlSetConfigInt("c_imap_port", 143); + CtdlSetConfigInt("c_msa_port", 587); + CtdlSetConfigInt("c_smtps_port", 465); + CtdlSetConfigInt("c_pop3s_port", 995); + CtdlSetConfigInt("c_imaps_port", 993); + CtdlSetConfigInt("c_pftcpdict_port", -1); + CtdlSetConfigInt("c_managesieve_port", 2020); + CtdlSetConfigInt("c_xmpp_c2s_port", 5222); + CtdlSetConfigInt("c_xmpp_s2s_port", 5269); + CtdlSetConfigInt("c_nntp_port", 119); + CtdlSetConfigInt("c_nntps_port", 563); + + /* + * Prevent the "new installation, set defaults" behavior from occurring again + */ + CtdlSetConfigLong("c_config_created_or_migrated", (long)time(NULL)); } -void setcfglen(void) + + +/* + * Migrate a supplied legacy configuration to the new in-db format. + * No individual site should ever have to do this more than once. + */ +void migrate_legacy_config(struct legacy_config *lconfig) { - configlen.c_nodename = strlen(config.c_nodename); - configlen.c_fqdn = strlen(config.c_fqdn); - configlen.c_humannode = strlen(config.c_humannode); - configlen.c_phonenum = strlen(config.c_phonenum); - configlen.c_twitroom = strlen(config.c_twitroom); - configlen.c_moreprompt = strlen(config.c_moreprompt); - configlen.c_site_location = strlen(config.c_site_location); - configlen.c_sysadm = strlen(config.c_sysadm); - configlen.c_niu_2 = strlen(config.c_niu_2); - configlen.c_ip_addr = strlen(config.c_ip_addr); - configlen.c_logpages = strlen(config.c_logpages); - configlen.c_baseroom = strlen(config.c_baseroom); - configlen.c_aideroom = strlen(config.c_aideroom); - configlen.c_ldap_host = strlen(config.c_ldap_host); - configlen.c_ldap_base_dn = strlen(config.c_ldap_base_dn); - configlen.c_ldap_bind_dn = strlen(config.c_ldap_bind_dn); - configlen.c_ldap_bind_pw = strlen(config.c_ldap_bind_pw); - configlen.c_journal_dest = strlen(config.c_journal_dest); - configlen.c_default_cal_zone = strlen(config.c_default_cal_zone); - configlen.c_funambol_host = strlen(config.c_funambol_host); - configlen.c_funambol_source = strlen(config.c_funambol_source); - configlen.c_funambol_auth = strlen(config.c_funambol_auth); - configlen.c_master_user = strlen(config.c_master_user); - configlen.c_master_pass = strlen(config.c_master_pass); - configlen.c_pager_program = strlen(config.c_pager_program); + CtdlSetConfigStr( "c_nodename" , lconfig->c_nodename ); + CtdlSetConfigStr( "c_fqdn" , lconfig->c_fqdn ); + CtdlSetConfigStr( "c_humannode" , lconfig->c_humannode ); + CtdlSetConfigInt( "c_creataide" , lconfig->c_creataide ); + CtdlSetConfigInt( "c_sleeping" , lconfig->c_sleeping ); + CtdlSetConfigInt( "c_initax" , lconfig->c_initax ); + CtdlSetConfigInt( "c_regiscall" , lconfig->c_regiscall ); + CtdlSetConfigInt( "c_twitdetect" , lconfig->c_twitdetect ); + CtdlSetConfigStr( "c_twitroom" , lconfig->c_twitroom ); + CtdlSetConfigStr( "c_moreprompt" , lconfig->c_moreprompt ); + CtdlSetConfigInt( "c_restrict" , lconfig->c_restrict ); + CtdlSetConfigStr( "c_site_location" , lconfig->c_site_location ); + CtdlSetConfigStr( "c_sysadm" , lconfig->c_sysadm ); + CtdlSetConfigInt( "c_maxsessions" , lconfig->c_maxsessions ); + CtdlSetConfigStr( "c_ip_addr" , lconfig->c_ip_addr ); + CtdlSetConfigInt( "c_port_number" , lconfig->c_port_number ); + CtdlSetConfigInt( "c_ep_mode" , lconfig->c_ep.expire_mode ); + CtdlSetConfigInt( "c_ep_value" , lconfig->c_ep.expire_value ); + CtdlSetConfigInt( "c_userpurge" , lconfig->c_userpurge ); + CtdlSetConfigInt( "c_roompurge" , lconfig->c_roompurge ); + CtdlSetConfigStr( "c_logpages" , lconfig->c_logpages ); + CtdlSetConfigInt( "c_createax" , lconfig->c_createax ); + CtdlSetConfigLong( "c_maxmsglen" , lconfig->c_maxmsglen ); + CtdlSetConfigInt( "c_min_workers" , lconfig->c_min_workers ); + CtdlSetConfigInt( "c_max_workers" , lconfig->c_max_workers ); + CtdlSetConfigInt( "c_pop3_port" , lconfig->c_pop3_port ); + CtdlSetConfigInt( "c_smtp_port" , lconfig->c_smtp_port ); + CtdlSetConfigInt( "c_rfc822_strict_from" , lconfig->c_rfc822_strict_from ); + CtdlSetConfigInt( "c_aide_zap" , lconfig->c_aide_zap ); + CtdlSetConfigInt( "c_imap_port" , lconfig->c_imap_port ); + CtdlSetConfigLong( "c_net_freq" , lconfig->c_net_freq ); + CtdlSetConfigInt( "c_disable_newu" , lconfig->c_disable_newu ); + CtdlSetConfigInt( "c_enable_fulltext" , lconfig->c_enable_fulltext ); + CtdlSetConfigStr( "c_baseroom" , lconfig->c_baseroom ); + CtdlSetConfigStr( "c_aideroom" , lconfig->c_aideroom ); + CtdlSetConfigInt( "c_purge_hour" , lconfig->c_purge_hour ); + CtdlSetConfigInt( "c_mbxep_mode" , lconfig->c_mbxep.expire_mode ); + CtdlSetConfigInt( "c_mbxep_value" , lconfig->c_mbxep.expire_value ); + CtdlSetConfigStr( "c_ldap_host" , lconfig->c_ldap_host ); + CtdlSetConfigInt( "c_ldap_port" , lconfig->c_ldap_port ); + CtdlSetConfigStr( "c_ldap_base_dn" , lconfig->c_ldap_base_dn ); + CtdlSetConfigStr( "c_ldap_bind_dn" , lconfig->c_ldap_bind_dn ); + CtdlSetConfigStr( "c_ldap_bind_pw" , lconfig->c_ldap_bind_pw ); + CtdlSetConfigInt( "c_msa_port" , lconfig->c_msa_port ); + CtdlSetConfigInt( "c_imaps_port" , lconfig->c_imaps_port ); + CtdlSetConfigInt( "c_pop3s_port" , lconfig->c_pop3s_port ); + CtdlSetConfigInt( "c_smtps_port" , lconfig->c_smtps_port ); + CtdlSetConfigInt( "c_auto_cull" , lconfig->c_auto_cull ); + CtdlSetConfigInt( "c_allow_spoofing" , lconfig->c_allow_spoofing ); + CtdlSetConfigInt( "c_journal_email" , lconfig->c_journal_email ); + CtdlSetConfigInt( "c_journal_pubmsgs" , lconfig->c_journal_pubmsgs ); + CtdlSetConfigStr( "c_journal_dest" , lconfig->c_journal_dest ); + CtdlSetConfigStr( "c_default_cal_zone" , lconfig->c_default_cal_zone ); + CtdlSetConfigInt( "c_pftcpdict_port" , lconfig->c_pftcpdict_port ); + CtdlSetConfigInt( "c_managesieve_port" , lconfig->c_managesieve_port ); + CtdlSetConfigInt( "c_auth_mode" , lconfig->c_auth_mode ); + CtdlSetConfigStr( "c_funambol_host" , lconfig->c_funambol_host ); + CtdlSetConfigInt( "c_funambol_port" , lconfig->c_funambol_port ); + CtdlSetConfigStr( "c_funambol_source" , lconfig->c_funambol_source ); + CtdlSetConfigStr( "c_funambol_auth" , lconfig->c_funambol_auth ); + CtdlSetConfigInt( "c_rbl_at_greeting" , lconfig->c_rbl_at_greeting ); + CtdlSetConfigStr( "c_master_user" , lconfig->c_master_user ); + CtdlSetConfigStr( "c_master_pass" , lconfig->c_master_pass ); + CtdlSetConfigStr( "c_pager_program" , lconfig->c_pager_program ); + CtdlSetConfigInt( "c_imap_keep_from" , lconfig->c_imap_keep_from ); + CtdlSetConfigInt( "c_xmpp_c2s_port" , lconfig->c_xmpp_c2s_port ); + CtdlSetConfigInt( "c_xmpp_s2s_port" , lconfig->c_xmpp_s2s_port ); + CtdlSetConfigLong( "c_pop3_fetch" , lconfig->c_pop3_fetch ); + CtdlSetConfigLong( "c_pop3_fastest" , lconfig->c_pop3_fastest ); + CtdlSetConfigInt( "c_spam_flag_only" , lconfig->c_spam_flag_only ); + CtdlSetConfigInt( "c_guest_logins" , lconfig->c_guest_logins ); + CtdlSetConfigInt( "c_nntp_port" , lconfig->c_nntp_port ); + CtdlSetConfigInt( "c_nntps_port" , lconfig->c_nntps_port ); } + + /* - * get_config() is called during the initialization of Citadel server. + * Called during the initialization of Citadel server. * It verifies the system's integrity and reads citadel.config into memory. */ -void get_config(void) { +void initialize_config_system(void) { FILE *cfp; int rv; + struct legacy_config lconfig; // legacy configuration + ctdlconfig = NewHash(1, NULL); // set up the real config system + + /* Ensure that we are linked to the correct version of libcitadel */ + if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) { + fprintf(stderr, "You are running libcitadel version %d.%02d\n", + (libcitadel_version_number() / 100), (libcitadel_version_number() % 100) + ); + fprintf(stderr, "citserver was compiled against version %d.%02d\n", + (LIBCITADEL_VERSION_NUMBER / 100), (LIBCITADEL_VERSION_NUMBER % 100) + ); + exit(CTDLEXIT_LIBCITADEL); + } if (chdir(ctdl_bbsbase_dir) != 0) { fprintf(stderr, @@ -184,36 +256,47 @@ void get_config(void) { exit(CTDLEXIT_HOME); } - memset(&config, 0, sizeof(struct config)); + memset(&lconfig, 0, sizeof(struct legacy_config)); cfp = fopen(file_citadel_config, "rb"); if (cfp != NULL) { - rv = fread((char *) &config, sizeof(struct config), 1, cfp); + if (CtdlGetConfigLong("c_config_created_or_migrated") > 0) { + fprintf(stderr, "Citadel Server found BOTH legacy and new configurations present.\n"); + fprintf(stderr, "Exiting to prevent data corruption.\n"); + exit(CTDLEXIT_CONFIG); + } + rv = fread((char *) &lconfig, sizeof(struct legacy_config), 1, cfp); if (rv != 1) { fprintf(stderr, - "Warning: The config file %s has unexpected size. \n", + "Warning: Found a legacy config file %s has unexpected size. \n", file_citadel_config ); } + + migrate_legacy_config(&lconfig); + fclose(cfp); - setcfglen(); - } - else { - brand_new_installation_set_defaults(); + if (unlink(file_citadel_config) != 0) { + fprintf(stderr, "Unable to remove legacy config file %s after migrating it.\n", file_citadel_config); + fprintf(stderr, "Exiting to prevent data corruption.\n"); + exit(CTDLEXIT_CONFIG); + } + + /* + * Prevent migration/initialization from happening again. + */ + CtdlSetConfigLong("c_config_created_or_migrated", (long)time(NULL)); + } - /* Ensure that we are linked to the correct version of libcitadel */ - if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) { - fprintf(stderr, " You are running libcitadel version %d.%02d\n", - (libcitadel_version_number() / 100), (libcitadel_version_number() % 100)); - fprintf(stderr, "citserver was compiled against version %d.%02d\n", - (LIBCITADEL_VERSION_NUMBER / 100), (LIBCITADEL_VERSION_NUMBER % 100)); - exit(CTDLEXIT_LIBCITADEL); + /* New installation? Set up configuration */ + if (CtdlGetConfigLong("c_config_created_or_migrated") <= 0) { + brand_new_installation_set_defaults(); } /* Only allow LDAP auth mode if we actually have LDAP support */ #ifndef HAVE_LDAP - if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { fprintf(stderr, "Your system is configured for LDAP authentication,\n" "but you are running a server built without OpenLDAP support.\n"); exit(CTDL_EXIT_UNSUP_AUTH); @@ -224,70 +307,169 @@ void get_config(void) { * configurable. Also check to make sure the limit has not been * set below 8192 bytes. */ - if (config.c_maxmsglen <= 0) - config.c_maxmsglen = 10485760; - if (config.c_maxmsglen < 8192) - config.c_maxmsglen = 8192; + if (CtdlGetConfigLong("c_maxmsglen") <= 0) CtdlSetConfigLong("c_maxmsglen", 10485760); + if (CtdlGetConfigLong("c_maxmsglen") < 8192) CtdlSetConfigLong("c_maxmsglen", 8192); - /* Default lower and upper limits on number of worker threads */ - - if (config.c_min_workers < 3) /* no less than 3 */ - config.c_min_workers = 5; - - if (config.c_max_workers == 0) /* default maximum */ - config.c_max_workers = 256; - - if (config.c_max_workers < config.c_min_workers) /* max >= min */ - config.c_max_workers = config.c_min_workers; + /* + * Default lower and upper limits on number of worker threads + */ + if (CtdlGetConfigInt("c_min_workers") < 5) CtdlSetConfigInt("c_min_workers", 5); // min + if (CtdlGetConfigInt("c_max_workers") == 0) CtdlSetConfigInt("c_max_workers", 256); // default max + if (CtdlGetConfigInt("c_max_workers") < CtdlGetConfigInt("c_min_workers")) { + CtdlSetConfigInt("c_max_workers", CtdlGetConfigInt("c_min_workers")); // max >= min + } /* Networking more than once every five minutes just isn't sane */ - if (config.c_net_freq == 0L) - config.c_net_freq = 3600L; /* once per hour default */ - if (config.c_net_freq < 300L) - config.c_net_freq = 300L; + if (CtdlGetConfigLong("c_net_freq") == 0) CtdlSetConfigLong("c_net_freq", 3600); // once per hour default + if (CtdlGetConfigLong("c_net_freq") < 300) CtdlSetConfigLong("c_net_freq", 300); // minimum 5 minutes /* Same goes for POP3 */ - if (config.c_pop3_fetch == 0L) - config.c_pop3_fetch = 3600L; /* once per hour default */ - if (config.c_pop3_fetch < 300L) - config.c_pop3_fetch = 300L; - if (config.c_pop3_fastest == 0L) - config.c_pop3_fastest = 3600L; /* once per hour default */ - if (config.c_pop3_fastest < 300L) - config.c_pop3_fastest = 300L; + if (CtdlGetConfigLong("c_pop3_fetch") == 0) CtdlSetConfigLong("c_pop3_fetch", 3600); // once per hour default + if (CtdlGetConfigLong("c_pop3_fetch") < 300) CtdlSetConfigLong("c_pop3_fetch", 300); // 5 minutes min + if (CtdlGetConfigLong("c_pop3_fastest") == 0) CtdlSetConfigLong("c_pop3_fastest", 3600); // once per hour default + if (CtdlGetConfigLong("c_pop3_fastest") < 300) CtdlSetConfigLong("c_pop3_fastest", 300); // 5 minutes min /* "create new user" only works with native authentication mode */ - if (config.c_auth_mode != AUTHMODE_NATIVE) { - config.c_disable_newu = 1; + if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) { + CtdlSetConfigInt("c_disable_newu", 1); } } -long config_msgnum = 0; + /* - * Occasionally, we will need to write the config file, because some operations - * change site-wide parameters. + * Called when Citadel server is shutting down. + * Clears out the config hash table. */ -void put_config(void) +void shutdown_config_system(void) { - FILE *cfp; - int blocks_written = 0; + DeleteHash(&ctdlconfig); +} - cfp = fopen(file_citadel_config, "w"); - if (cfp != NULL) { - blocks_written = fwrite((char *) &config, sizeof(struct config), 1, cfp); - if (blocks_written == 1) { - chown(file_citadel_config, CTDLUID, (-1)); - chmod(file_citadel_config, 0600); - fclose(cfp); - return; - } - fclose(cfp); + + +/* + * Set a system config value. Simple key/value here. + */ +void CtdlSetConfigStr(char *key, char *value) +{ + int key_len = strlen(key); + int value_len = strlen(value); + + /* FIXME we are noisy logging for now */ + syslog(LOG_DEBUG, "\033[31mSET CONFIG: '%s' = '%s'\033[0m", key, value); + + /* Save it in memory */ + Put(ctdlconfig, key, key_len, strdup(value), NULL); + + /* Also write it to the config database */ + + int dbv_size = key_len + value_len + 2; + char *dbv = malloc(dbv_size); + strcpy(dbv, key); + strcpy(&dbv[key_len + 1], value); + cdb_store(CDB_CONFIG, key, key_len, dbv, dbv_size); + free(dbv); +} + + +/* + * Set a numeric system config value (long integer) + */ +void CtdlSetConfigLong(char *key, long value) +{ + char longstr[256]; + sprintf(longstr, "%ld", value); + CtdlSetConfigStr(key, longstr); +} + + +/* + * Set a numeric system config value (integer) + */ +void CtdlSetConfigInt(char *key, int value) +{ + char intstr[256]; + sprintf(intstr, "%d", value); + CtdlSetConfigStr(key, intstr); +} + + +/* + * Fetch a system config value. Caller does *not* own the returned value and may not alter it. + */ +char *CtdlGetConfigStr(char *key) +{ + char *value = NULL; + struct cdbdata *cdb; + int key_len = strlen(key); + + if (IsEmptyStr(key)) return(NULL); + + /* Temporary hack to make sure we didn't mess up any porting - FIXME remove this after testing thoroughly */ + if (!strncmp(key, "config", 6)) { + syslog(LOG_EMERG, "You requested a key starting with 'config' which probably means a porting error: %s", key); + abort(); } - syslog(LOG_EMERG, "%s: %s", file_citadel_config, strerror(errno)); + + /* First look in memory */ + if (GetHash(ctdlconfig, key, key_len, (void *)&value)) + { + if (strcmp(key, "c_min_workers")) syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = '%s'\033[0m", key, value); + return value; + } + + /* Then look in the database. */ + + cdb = cdb_fetch(CDB_CONFIG, key, key_len); + + if (cdb == NULL) { /* nope, not there either. */ + syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = NULL\033[0m", key); + return(NULL); + } + + /* Got it. Save it in memory for the next fetch. */ + value = strdup(cdb->ptr + key_len + 1); /* The key was stored there too; skip past it */ + cdb_free(cdb); + Put(ctdlconfig, key, key_len, value, NULL); + syslog(LOG_DEBUG, "\033[32mGET CONFIG: '%s' = '%s'\033[0m", key, value); + return value; +} + + +/* + * Fetch a system config value - integer + */ +int CtdlGetConfigInt(char *key) +{ + char *s = CtdlGetConfigStr(key); + if (s) return atoi(s); + return 0; } +/* + * Fetch a system config value - long integer + */ +long CtdlGetConfigLong(char *key) +{ + char *s = CtdlGetConfigStr(key); + if (s) return atol(s); + return 0; +} + + + +/**********************************************************************/ + + + + + + + + + void CtdlGetSysConfigBackend(long msgnum, void *userdata) { config_msgnum = msgnum; @@ -320,7 +502,7 @@ char *CtdlGetSysConfig(char *sysconfname) { conf = NULL; } else { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { conf = strdup(msg->cm_fields[eMesageText]); CM_Free(msg); diff --git a/citadel/config.h b/citadel/config.h index eb61711cc..293593b81 100644 --- a/citadel/config.h +++ b/citadel/config.h @@ -1,21 +1,117 @@ /* - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "serv_extensions.h" #include "citadel_dirs.h" -void get_config(void); + +/* + * This is the format of the legacy config file. Do not attempt to do anything with it other + * than migrate it into the new format. + */ +struct legacy_config { + char c_nodename[16]; /* short name of this node on a Citadel network */ + char c_fqdn[64]; /* this site's fully qualified domain name */ + char c_humannode[21]; /* human-readable site name */ + char c_niu_7[16]; + uid_t c_niu_6; + char c_creataide; /* 1 = creating a room auto-grants room aide privileges */ + int c_sleeping; /* watchdog timer (seconds) */ + char c_initax; /* initial access level for new users */ + char c_regiscall; /* after c_regiscall logins user will be asked to register */ + char c_twitdetect; /* automatically move messages from problem users to trashcan */ + char c_twitroom[ROOMNAMELEN]; /* name of trashcan */ + char c_moreprompt[80]; /* paginator prompt */ + char c_restrict; /* require per-user permission to send Internet mail */ + long c_niu_1; + char c_site_location[32]; /* geographic location of this Citadel site */ + char c_sysadm[26]; /* name of system administrator */ + char c_niu_2[15]; + int c_niu_3; + int c_maxsessions; /* maximum number of concurrent sessions allowed */ + char c_ip_addr[20]; /* bind address for listening sockets */ + int c_port_number; /* port number for Citadel protocol (usually 504) */ + int c_niu_4; + struct ExpirePolicy c_ep; /* default expire policy for the entire site */ + int c_userpurge; /* user purge time (in days) */ + int c_roompurge; /* room purge time (in days) */ + char c_logpages[ROOMNAMELEN]; + char c_createax; + long c_maxmsglen; + int c_min_workers; + int c_max_workers; + int c_pop3_port; + int c_smtp_port; + int c_rfc822_strict_from; + int c_aide_zap; + int c_imap_port; + time_t c_net_freq; + char c_disable_newu; + char c_enable_fulltext; + char c_baseroom[ROOMNAMELEN]; + char c_aideroom[ROOMNAMELEN]; + int c_purge_hour; + struct ExpirePolicy c_mbxep; + char c_ldap_host[128]; + int c_ldap_port; + char c_ldap_base_dn[256]; + char c_ldap_bind_dn[256]; + char c_ldap_bind_pw[256]; + int c_msa_port; + int c_imaps_port; + int c_pop3s_port; + int c_smtps_port; + char c_auto_cull; + char c_niu_5; + char c_allow_spoofing; + char c_journal_email; + char c_journal_pubmsgs; + char c_journal_dest[128]; + char c_default_cal_zone[128]; + int c_pftcpdict_port; + int c_managesieve_port; + int c_auth_mode; + char c_funambol_host[256]; + int c_funambol_port; + char c_funambol_source[256]; + char c_funambol_auth[256]; + char c_rbl_at_greeting; + char c_master_user[32]; + char c_master_pass[32]; + char c_pager_program[256]; + char c_imap_keep_from; + int c_xmpp_c2s_port; + int c_xmpp_s2s_port; + time_t c_pop3_fetch; + time_t c_pop3_fastest; + int c_spam_flag_only; + int c_guest_logins; + int c_nntp_port; + int c_nntps_port; +}; + + + + +void initialize_config_system(void); +void shutdown_config_system(void); void put_config(void); +void CtdlSetConfigStr(char *, char *); +char *CtdlGetConfigStr(char *); +int CtdlGetConfigInt(char *); +long CtdlGetConfigLong(char *); +void CtdlSetConfigInt(char *key, int value); +void CtdlSetConfigLong(char *key, long value); char *CtdlGetSysConfig(char *sysconfname); void CtdlPutSysConfig(char *sysconfname, char *sysconfdata); diff --git a/citadel/configure.ac b/citadel/configure.ac index aa900202e..3a4fbe69c 100644 --- a/citadel/configure.ac +++ b/citadel/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.52) -AC_INIT([Citadel], [8.29], [http://www.citadel.org/]) +AC_INIT([Citadel], [9.01], [http://www.citadel.org/]) AC_REVISION([$Revision: 5108 $]) AC_CONFIG_SRCDIR([citserver.c]) AC_CONFIG_HEADER(sysdep.h) diff --git a/citadel/context.c b/citadel/context.c index 81b597850..576e9359c 100644 --- a/citadel/context.c +++ b/citadel/context.c @@ -2,7 +2,7 @@ * Citadel context management stuff. * Here's where we (hopefully) have all the code that manipulates contexts. * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -22,6 +22,7 @@ #include "locate_host.h" #include "context.h" #include "control.h" +#include "config.h" int DebugSession = 0; @@ -244,8 +245,8 @@ void terminate_idle_sessions(void) for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if ( (ccptr != CC) - && (config.c_sleeping > 0) - && (now - (ccptr->lastcmd) > config.c_sleeping) + && (CtdlGetConfigLong("c_sleeping") > 0) + && (now - (ccptr->lastcmd) > CtdlGetConfigLong("c_sleeping")) ) { if (!ccptr->dont_term) { ccptr->kill_me = KILLME_IDLE; @@ -514,7 +515,7 @@ void begin_session(CitContext *con) *con->fake_hostname = '\0'; *con->fake_roomname = '\0'; *con->cs_clientinfo = '\0'; - safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host); + safestrncpy(con->cs_host, CtdlGetConfigStr("c_fqdn"), sizeof con->cs_host); safestrncpy(con->cs_addr, "", sizeof con->cs_addr); con->cs_UDSclientUID = -1; con->cs_host[sizeof con->cs_host - 1] = 0; @@ -566,7 +567,7 @@ void begin_session(CitContext *con) con->dl_is_net = 0; con->nologin = 0; - if (((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions)) || CtdlWantSingleUser()) { + if (((CtdlGetConfigInt("c_maxsessions") > 0)&&(num_sessions > CtdlGetConfigInt("c_maxsessions"))) || CtdlWantSingleUser()) { con->nologin = 1; } diff --git a/citadel/control.c b/citadel/control.c index 2a608eee0..24b643229 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -1,15 +1,15 @@ /* * This module handles states which are global to the entire server. * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -21,26 +21,23 @@ #include "citserver.h" #include "user_ops.h" -struct CitControl CitControl; -extern struct config config; -FILE *control_fp = NULL; long control_highest_user = 0; - /* - * lock_control - acquire a lock on the control record file. - * This keeps multiple citservers from running concurrently. + * This is the control record for the message base... */ -void lock_control(void) -{ -#if defined(LOCK_EX) && defined(LOCK_NB) - if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) { - syslog(LOG_EMERG, "citserver: unable to lock %s.\n", file_citadel_control); - syslog(LOG_EMERG, "Is another citserver already running?\n"); - exit(CTDLEXIT_CONTROL); - } -#endif -} +struct legacy_ctrl_format { + long MMhighest; /* highest message number in file */ + unsigned MMflags; /* Global system flags */ + long MMnextuser; /* highest user number on system */ + long MMnextroom; /* highest room number on system */ + int MM_hosted_upgrade_level; /* Server-hosted upgrade level */ + int MM_fulltext_wordbreaker; /* ID of wordbreaker in use */ + long MMfulltext; /* highest message number indexed */ + int MMdbversion; /* Version of Berkeley DB used on previous server run */ +}; + + /* * callback to get highest room number when rebuilding control file @@ -55,9 +52,9 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) int room_fixed = 0; int message_fixed = 0; - if (qrbuf->QRnumber > CitControl.MMnextroom) + if (qrbuf->QRnumber > CtdlGetConfigLong("MMnextroom")) { - CitControl.MMnextroom = qrbuf->QRnumber; + CtdlSetConfigLong("MMnextroom", qrbuf->QRnumber); room_fixed = 1; } @@ -76,18 +73,20 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) { for (c=0; c CitControl.MMhighest) + if (msglist[c] > CtdlGetConfigLong("MMhighest")) { - CitControl.MMhighest = msglist[c]; + CtdlSetConfigLong("MMhighest", msglist[c]); message_fixed = 1; } } } cdb_free(cdbfr); - if (room_fixed) + if (room_fixed) { syslog(LOG_INFO, "Control record checking....Fixed room counter\n"); - if (message_fixed) + } + if (message_fixed) { syslog(LOG_INFO, "Control record checking....Fixed message count\n"); + } return; } @@ -100,9 +99,9 @@ void control_find_user (struct ctdluser *EachUser, void *out_data) { int user_fixed = 0; - if (EachUser->usernum > CitControl.MMnextuser) + if (EachUser->usernum > CtdlGetConfigLong("MMnextuser")) { - CitControl.MMnextuser = EachUser->usernum; + CtdlSetConfigLong("MMnextuser", EachUser->usernum); user_fixed = 1; } if(user_fixed) @@ -111,92 +110,34 @@ void control_find_user (struct ctdluser *EachUser, void *out_data) /* - * get_control - read the control record into memory. + * If we have a legacy format control record on disk, import it. */ -void get_control(void) +void migrate_legacy_control_record(void) { - static int already_have_control = 0; - int rv = 0; - - /* - * If we already have the control record in memory, there's no point - * in reading it from disk again. - */ - if (already_have_control) return; - - /* Zero it out. If the control record on disk is missing or short, - * the system functions with all control record fields initialized - * to zero. - */ - memset(&CitControl, 0, sizeof(struct CitControl)); - if (control_fp == NULL) { - control_fp = fopen(file_citadel_control, "rb+"); - if (control_fp != NULL) { - lock_control(); - rv = fchown(fileno(control_fp), config.c_ctdluid, -1); - if (rv == -1) - syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", - file_citadel_control, strerror(errno)); - rv = fchmod(fileno(control_fp), S_IRUSR|S_IWUSR); - if (rv == -1) - syslog(LOG_EMERG, "Failed to adjust accessrights of: %s [%s]\n", - file_citadel_control, strerror(errno)); - } - } - if (control_fp == NULL) { - control_fp = fopen(file_citadel_control, "wb+"); - if (control_fp != NULL) { - lock_control(); - memset(&CitControl, 0, sizeof(struct CitControl)); - - rv = fchown(fileno(control_fp), config.c_ctdluid, -1); - if (rv == -1) - syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", - file_citadel_control, strerror(errno)); - - rv = fchmod(fileno(control_fp), S_IRUSR|S_IWUSR); - if (rv == -1) - syslog(LOG_EMERG, "Failed to adjust accessrights of: %s [%s]\n", - file_citadel_control, strerror(errno)); - rv = fwrite(&CitControl, sizeof(struct CitControl), 1, control_fp); - if (rv == -1) - syslog(LOG_EMERG, "Failed to write: %s [%s]\n", - file_citadel_control, strerror(errno)); - rewind(control_fp); + FILE *fp = NULL; + struct legacy_ctrl_format c; + memset(&c, 0, sizeof(c)); + + fp = fopen(file_citadel_control, "rb+"); + if (fp != NULL) { + syslog(LOG_INFO, "Legacy format control record found -- importing to db"); + fread(&c, sizeof(struct legacy_ctrl_format), 1, fp); + + CtdlSetConfigLong( "MMhighest", c.MMhighest); + CtdlSetConfigInt( "MMflags", c.MMflags); + CtdlSetConfigLong( "MMnextuser", c.MMnextuser); + CtdlSetConfigLong( "MMnextroom", c.MMnextroom); + CtdlSetConfigInt( "MM_hosted_upgrade_level", c.MM_hosted_upgrade_level); + CtdlSetConfigInt( "MM_fulltext_wordbreaker", c.MM_fulltext_wordbreaker); + CtdlSetConfigLong( "MMfulltext", c.MMfulltext); + + fclose(fp); + if (unlink(file_citadel_control) != 0) { + fprintf(stderr, "Unable to remove legacy control record %s after migrating it.\n", file_citadel_control); + fprintf(stderr, "Exiting to prevent data corruption.\n"); + exit(CTDLEXIT_CONFIG); } } - if (control_fp == NULL) { - syslog(LOG_ALERT, "ERROR opening %s: %s\n", file_citadel_control, strerror(errno)); - return; - } - - rewind(control_fp); - rv = fread(&CitControl, sizeof(struct CitControl), 1, control_fp); - if (rv == -1) - syslog(LOG_EMERG, "Failed to read Controlfile: %s [%s]\n", - file_citadel_control, strerror(errno)); - already_have_control = 1; - rv = chown(file_citadel_control, config.c_ctdluid, (-1)); - if (rv == -1) - syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", - file_citadel_control, strerror(errno)); -} - -/* - * put_control - write the control record to disk. - */ -void put_control(void) -{ - int rv = 0; - - if (control_fp != NULL) { - rewind(control_fp); - rv = fwrite(&CitControl, sizeof(struct CitControl), 1, control_fp); - if (rv == -1) - syslog(LOG_EMERG, "Failed to write: %s [%s]\n", - file_citadel_control, strerror(errno)); - fflush(control_fp); - } } @@ -205,25 +146,12 @@ void put_control(void) */ void check_control(void) { - syslog(LOG_INFO, "Checking/re-building control record\n"); - get_control(); - // Find highest room number and message number. + syslog(LOG_INFO, "Sanity checking the recorded highest message, user, and room numbers\n"); CtdlForEachRoom(control_find_highest, NULL); ForEachUser(control_find_user, NULL); - put_control(); } -/* - * release_control - close our fd on exit - */ -void release_control(void) -{ - if (control_fp != NULL) { - fclose(control_fp); - } - control_fp = NULL; -} /* * get_new_message_number() - Obtain a new, unique ID to be used for a message. @@ -232,9 +160,9 @@ long get_new_message_number(void) { long retval = 0L; begin_critical_section(S_CONTROL); - get_control(); - retval = ++CitControl.MMhighest; - put_control(); + retval = CtdlGetConfigLong("MMhighest"); + ++retval; + CtdlSetConfigLong("MMhighest", retval); end_critical_section(S_CONTROL); return(retval); } @@ -245,15 +173,12 @@ long get_new_message_number(void) * This provides a quick way to initialise a variable that might be used to indicate * messages that should not be processed. EG. a new Sieve script will use this * to record determine that messages older than this should not be processed. + * + * (Why is this function here? Can't we just go straight to the config variable it fetches?) */ long CtdlGetCurrentMessageNumber(void) { - long retval = 0L; - begin_critical_section(S_CONTROL); - get_control(); - retval = CitControl.MMhighest; - end_critical_section(S_CONTROL); - return(retval); + return CtdlGetConfigLong("MMhighest"); } @@ -264,9 +189,9 @@ long get_new_user_number(void) { long retval = 0L; begin_critical_section(S_CONTROL); - get_control(); - retval = ++CitControl.MMnextuser; - put_control(); + retval = CtdlGetConfigLong("MMnextuser"); + ++retval; + CtdlSetConfigLong("MMnextuser", retval); end_critical_section(S_CONTROL); return(retval); } @@ -280,73 +205,87 @@ long get_new_room_number(void) { long retval = 0L; begin_critical_section(S_CONTROL); - get_control(); - retval = ++CitControl.MMnextroom; - put_control(); + retval = CtdlGetConfigLong("MMnextroom"); + ++retval; + CtdlSetConfigLong("MMnextroom", retval); end_critical_section(S_CONTROL); return(retval); } +/* + * Helper function for cmd_conf() to handle boolean values + */ +int confbool(char *v) +{ + if (IsEmptyStr(v)) return(0); + if (atoi(v) != 0) return(1); + return(0); +} + + /* * Get or set global configuration options * * IF YOU ADD OR CHANGE FIELDS HERE, YOU *MUST* DOCUMENT YOUR CHANGES AT: - * http://www.citadel.org/doku.php?id=documentation:applicationprotocol + * http://www.citadel.org/doku.php/documentation:appproto:system_config * */ void cmd_conf(char *argbuf) { char cmd[16]; - char buf[256]; - int a; + char buf[1024]; + int a, i; + long ii; char *confptr; char confname[128]; if (CtdlAccessCheck(ac_aide)) return; extract_token(cmd, argbuf, 0, '|', sizeof cmd); + + // CONF GET - retrieve system configuration in legacy format (deprecated) if (!strcasecmp(cmd, "GET")) { cprintf("%d Configuration...\n", LISTING_FOLLOWS); - cprintf("%s\n", config.c_nodename); - cprintf("%s\n", config.c_fqdn); - cprintf("%s\n", config.c_humannode); - cprintf("%s\n", config.c_phonenum); - cprintf("%d\n", config.c_creataide); - cprintf("%d\n", config.c_sleeping); - cprintf("%d\n", config.c_initax); - cprintf("%d\n", config.c_regiscall); - cprintf("%d\n", config.c_twitdetect); - cprintf("%s\n", config.c_twitroom); - cprintf("%s\n", config.c_moreprompt); - cprintf("%d\n", config.c_restrict); - cprintf("%s\n", config.c_site_location); - cprintf("%s\n", config.c_sysadm); - cprintf("%d\n", config.c_maxsessions); + cprintf("%s\n", CtdlGetConfigStr("c_nodename")); + cprintf("%s\n", CtdlGetConfigStr("c_fqdn")); + cprintf("%s\n", CtdlGetConfigStr("c_humannode")); cprintf("xxx\n"); /* placeholder -- field no longer in use */ - cprintf("%d\n", config.c_userpurge); - cprintf("%d\n", config.c_roompurge); - cprintf("%s\n", config.c_logpages); - cprintf("%d\n", config.c_createax); - cprintf("%ld\n", config.c_maxmsglen); - cprintf("%d\n", config.c_min_workers); - cprintf("%d\n", config.c_max_workers); - cprintf("%d\n", config.c_pop3_port); - cprintf("%d\n", config.c_smtp_port); - cprintf("%d\n", config.c_rfc822_strict_from); - cprintf("%d\n", config.c_aide_zap); - cprintf("%d\n", config.c_imap_port); - cprintf("%ld\n", config.c_net_freq); - cprintf("%d\n", config.c_disable_newu); + cprintf("%d\n", CtdlGetConfigInt("c_creataide")); + cprintf("%d\n", CtdlGetConfigInt("c_sleeping")); + cprintf("%d\n", CtdlGetConfigInt("c_initax")); + cprintf("%d\n", CtdlGetConfigInt("c_regiscall")); + cprintf("%d\n", CtdlGetConfigInt("c_twitdetect")); + cprintf("%s\n", CtdlGetConfigStr("c_twitroom")); + cprintf("%s\n", CtdlGetConfigStr("c_moreprompt")); + cprintf("%d\n", CtdlGetConfigInt("c_restrict")); + cprintf("%s\n", CtdlGetConfigStr("c_site_location")); + cprintf("%s\n", CtdlGetConfigStr("c_sysadm")); + cprintf("%d\n", CtdlGetConfigInt("c_maxsessions")); + cprintf("xxx\n"); /* placeholder -- field no longer in use */ + cprintf("%d\n", CtdlGetConfigInt("c_userpurge")); + cprintf("%d\n", CtdlGetConfigInt("c_roompurge")); + cprintf("%s\n", CtdlGetConfigStr("c_logpages")); + cprintf("%d\n", CtdlGetConfigInt("c_createax")); + cprintf("%ld\n", CtdlGetConfigLong("c_maxmsglen")); + cprintf("%d\n", CtdlGetConfigInt("c_min_workers")); + cprintf("%d\n", CtdlGetConfigInt("c_max_workers")); + cprintf("%d\n", CtdlGetConfigInt("c_pop3_port")); + cprintf("%d\n", CtdlGetConfigInt("c_smtp_port")); + cprintf("%d\n", CtdlGetConfigInt("c_rfc822_strict_from")); + cprintf("%d\n", CtdlGetConfigInt("c_aide_zap")); + cprintf("%d\n", CtdlGetConfigInt("c_imap_port")); + cprintf("%ld\n", CtdlGetConfigLong("c_net_freq")); + cprintf("%d\n", CtdlGetConfigInt("c_disable_newu")); cprintf("1\n"); /* niu */ - cprintf("%d\n", config.c_purge_hour); + cprintf("%d\n", CtdlGetConfigInt("c_purge_hour")); #ifdef HAVE_LDAP - cprintf("%s\n", config.c_ldap_host); - cprintf("%d\n", config.c_ldap_port); - cprintf("%s\n", config.c_ldap_base_dn); - cprintf("%s\n", config.c_ldap_bind_dn); - cprintf("%s\n", config.c_ldap_bind_pw); + cprintf("%s\n", CtdlGetConfigStr("c_ldap_host")); + cprintf("%d\n", CtdlGetConfigInt("c_ldap_port")); + cprintf("%s\n", CtdlGetConfigStr("c_ldap_base_dn")); + cprintf("%s\n", CtdlGetConfigStr("c_ldap_bind_dn")); + cprintf("%s\n", CtdlGetConfigStr("c_ldap_bind_pw")); #else cprintf("\n"); cprintf("0\n"); @@ -354,44 +293,45 @@ void cmd_conf(char *argbuf) cprintf("\n"); cprintf("\n"); #endif - cprintf("%s\n", config.c_ip_addr); - cprintf("%d\n", config.c_msa_port); - cprintf("%d\n", config.c_imaps_port); - cprintf("%d\n", config.c_pop3s_port); - cprintf("%d\n", config.c_smtps_port); - cprintf("%d\n", config.c_enable_fulltext); - cprintf("%d\n", config.c_auto_cull); + cprintf("%s\n", CtdlGetConfigStr("c_ip_addr")); + cprintf("%d\n", CtdlGetConfigInt("c_msa_port")); + cprintf("%d\n", CtdlGetConfigInt("c_imaps_port")); + cprintf("%d\n", CtdlGetConfigInt("c_pop3s_port")); + cprintf("%d\n", CtdlGetConfigInt("c_smtps_port")); + cprintf("%d\n", CtdlGetConfigInt("c_enable_fulltext")); + cprintf("%d\n", CtdlGetConfigInt("c_auto_cull")); cprintf("1\n"); - cprintf("%d\n", config.c_allow_spoofing); - cprintf("%d\n", config.c_journal_email); - cprintf("%d\n", config.c_journal_pubmsgs); - cprintf("%s\n", config.c_journal_dest); - cprintf("%s\n", config.c_default_cal_zone); - cprintf("%d\n", config.c_pftcpdict_port); - cprintf("%d\n", config.c_managesieve_port); - cprintf("%d\n", config.c_auth_mode); - cprintf("%s\n", config.c_funambol_host); - cprintf("%d\n", config.c_funambol_port); - cprintf("%s\n", config.c_funambol_source); - cprintf("%s\n", config.c_funambol_auth); - cprintf("%d\n", config.c_rbl_at_greeting); - cprintf("%s\n", config.c_master_user); - cprintf("%s\n", config.c_master_pass); - cprintf("%s\n", config.c_pager_program); - cprintf("%d\n", config.c_imap_keep_from); - cprintf("%d\n", config.c_xmpp_c2s_port); - cprintf("%d\n", config.c_xmpp_s2s_port); - cprintf("%ld\n", config.c_pop3_fetch); - cprintf("%ld\n", config.c_pop3_fastest); - cprintf("%d\n", config.c_spam_flag_only); - cprintf("%d\n", config.c_guest_logins); - cprintf("%d\n", config.c_port_number); - cprintf("%d\n", config.c_ctdluid); - cprintf("%d\n", config.c_nntp_port); - cprintf("%d\n", config.c_nntps_port); + cprintf("%d\n", CtdlGetConfigInt("c_allow_spoofing")); + cprintf("%d\n", CtdlGetConfigInt("c_journal_email")); + cprintf("%d\n", CtdlGetConfigInt("c_journal_pubmsgs")); + cprintf("%s\n", CtdlGetConfigStr("c_journal_dest")); + cprintf("%s\n", CtdlGetConfigStr("c_default_cal_zone")); + cprintf("%d\n", CtdlGetConfigInt("c_pftcpdict_port")); + cprintf("%d\n", CtdlGetConfigInt("c_managesieve_port")); + cprintf("%d\n", CtdlGetConfigInt("c_auth_mode")); + cprintf("%s\n", CtdlGetConfigStr("c_funambol_host")); + cprintf("%d\n", CtdlGetConfigInt("c_funambol_port")); + cprintf("%s\n", CtdlGetConfigStr("c_funambol_source")); + cprintf("%s\n", CtdlGetConfigStr("c_funambol_auth")); + cprintf("%d\n", CtdlGetConfigInt("c_rbl_at_greeting")); + cprintf("%s\n", CtdlGetConfigStr("c_master_user")); + cprintf("%s\n", CtdlGetConfigStr("c_master_pass")); + cprintf("%s\n", CtdlGetConfigStr("c_pager_program")); + cprintf("%d\n", CtdlGetConfigInt("c_imap_keep_from")); + cprintf("%d\n", CtdlGetConfigInt("c_xmpp_c2s_port")); + cprintf("%d\n", CtdlGetConfigInt("c_xmpp_s2s_port")); + cprintf("%ld\n", CtdlGetConfigLong("c_pop3_fetch")); + cprintf("%ld\n", CtdlGetConfigLong("c_pop3_fastest")); + cprintf("%d\n", CtdlGetConfigInt("c_spam_flag_only")); + cprintf("%d\n", CtdlGetConfigInt("c_guest_logins")); + cprintf("%d\n", CtdlGetConfigInt("c_port_number")); + cprintf("%d\n", ctdluid); + cprintf("%d\n", CtdlGetConfigInt("c_nntp_port")); + cprintf("%d\n", CtdlGetConfigInt("c_nntps_port")); cprintf("000\n"); } + // CONF SET - set system configuration in legacy format (really deprecated) else if (!strcasecmp(cmd, "SET")) { unbuffer_output(); cprintf("%d Send configuration...\n", SEND_LISTING); @@ -399,294 +339,262 @@ void cmd_conf(char *argbuf) while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) { switch (a) { case 0: - configlen.c_nodename = safestrncpy(config.c_nodename, buf, - sizeof config.c_nodename); + CtdlSetConfigStr("c_nodename", buf); break; case 1: - configlen.c_fqdn = safestrncpy(config.c_fqdn, buf, - sizeof config.c_fqdn); + CtdlSetConfigStr("c_fqdn", buf); break; case 2: - configlen.c_humannode = safestrncpy(config.c_humannode, buf, - sizeof config.c_humannode); + CtdlSetConfigStr("c_humannode", buf); break; case 3: - configlen.c_phonenum = safestrncpy(config.c_phonenum, buf, - sizeof config.c_phonenum); + /* placeholder -- field no longer in use */ break; case 4: - config.c_creataide = atoi(buf); + CtdlSetConfigInt("c_creataide", atoi(buf)); break; case 5: - config.c_sleeping = atoi(buf); + CtdlSetConfigInt("c_sleeping", atoi(buf)); break; case 6: - config.c_initax = atoi(buf); - if (config.c_initax < 1) - config.c_initax = 1; - if (config.c_initax > 6) - config.c_initax = 6; + i = atoi(buf); + if (i < 1) i = 1; + if (i > 6) i = 6; + CtdlSetConfigInt("c_initax", i); break; case 7: - config.c_regiscall = atoi(buf); - if (config.c_regiscall != 0) - config.c_regiscall = 1; + CtdlSetConfigInt("c_regiscall", confbool(buf)); break; case 8: - config.c_twitdetect = atoi(buf); - if (config.c_twitdetect != 0) - config.c_twitdetect = 1; + CtdlSetConfigInt("c_twitdetect", confbool(buf)); break; case 9: - configlen.c_twitroom = safestrncpy(config.c_twitroom, buf, - sizeof config.c_twitroom); + CtdlSetConfigStr("c_twitroom", buf); break; case 10: - configlen.c_moreprompt = safestrncpy(config.c_moreprompt, buf, - sizeof config.c_moreprompt); + CtdlSetConfigStr("c_moreprompt", buf); break; case 11: - config.c_restrict = atoi(buf); - if (config.c_restrict != 0) - config.c_restrict = 1; + CtdlSetConfigInt("c_restrict", confbool(buf)); break; case 12: - configlen.c_site_location = safestrncpy( - config.c_site_location, buf, - sizeof config.c_site_location); + CtdlSetConfigInt("c_site_location", confbool(buf)); break; case 13: - configlen.c_sysadm = safestrncpy(config.c_sysadm, buf, - sizeof config.c_sysadm); + CtdlSetConfigInt("c_sysadm", confbool(buf)); break; case 14: - config.c_maxsessions = atoi(buf); - if (config.c_maxsessions < 0) - config.c_maxsessions = 0; + i = atoi(buf); + if (i < 0) i = 0; + CtdlSetConfigInt("c_maxsessions", i); break; case 15: /* placeholder -- field no longer in use */ break; case 16: - config.c_userpurge = atoi(buf); + CtdlSetConfigInt("c_userpurge", atoi(buf)); break; case 17: - config.c_roompurge = atoi(buf); + CtdlSetConfigInt("c_roompurge", atoi(buf)); break; case 18: - configlen.c_logpages = safestrncpy(config.c_logpages, buf, - sizeof config.c_logpages); + CtdlSetConfigStr("c_logpages", buf); break; case 19: - config.c_createax = atoi(buf); - if (config.c_createax < 1) - config.c_createax = 1; - if (config.c_createax > 6) - config.c_createax = 6; + i = atoi(buf); + if (i < 1) i = 1; + if (i > 6) i = 6; + CtdlSetConfigInt("c_createax", i); break; case 20: - if (atoi(buf) >= 8192) - config.c_maxmsglen = atoi(buf); + ii = atol(buf); + if (ii >= 8192) { + CtdlSetConfigLong("c_maxmsglen", ii); + } break; case 21: - if (atoi(buf) >= 2) - config.c_min_workers = atoi(buf); + i = atoi(buf); + if (i >= 3) { // minimum value + CtdlSetConfigInt("c_min_workers", i); + } + break; case 22: - if (atoi(buf) >= config.c_min_workers) - config.c_max_workers = atoi(buf); + i = atoi(buf); + if (i >= CtdlGetConfigInt("c_min_workers")) { // max must be >= min + CtdlSetConfigInt("c_max_workers", i); + } + break; case 23: - config.c_pop3_port = atoi(buf); + CtdlSetConfigInt("c_pop3_port", atoi(buf)); break; case 24: - config.c_smtp_port = atoi(buf); + CtdlSetConfigInt("c_smtp_port", atoi(buf)); break; case 25: - config.c_rfc822_strict_from = atoi(buf); + CtdlSetConfigInt("c_rfc822_strict_from", atoi(buf)); break; case 26: - config.c_aide_zap = atoi(buf); - if (config.c_aide_zap != 0) - config.c_aide_zap = 1; + CtdlSetConfigInt("c_aide_zap", confbool(buf)); break; case 27: - config.c_imap_port = atoi(buf); + CtdlSetConfigInt("c_imap_port", atoi(buf)); break; case 28: - config.c_net_freq = atol(buf); + CtdlSetConfigLong("c_net_freq", atol(buf)); break; case 29: - config.c_disable_newu = atoi(buf); - if (config.c_disable_newu != 0) - config.c_disable_newu = 1; + CtdlSetConfigInt("c_disable_newu", confbool(buf)); break; case 30: /* niu */ break; case 31: - if ((config.c_purge_hour >= 0) - && (config.c_purge_hour <= 23)) { - config.c_purge_hour = atoi(buf); + i = atoi(buf); + if ((i >= 0) && (i <= 23)) { + CtdlSetConfigInt("c_purge_hour", i); } break; -#ifdef HAVE_LDAP case 32: - configlen.c_ldap_host = safestrncpy(config.c_ldap_host, buf, - sizeof config.c_ldap_host); + CtdlSetConfigStr("c_ldap_host", buf); break; case 33: - config.c_ldap_port = atoi(buf); + CtdlSetConfigInt("c_ldap_port", atoi(buf)); break; case 34: - configlen.c_ldap_base_dn = safestrncpy(config.c_ldap_base_dn, buf, - sizeof config.c_ldap_base_dn); + CtdlSetConfigStr("c_ldap_base_dn", buf); break; case 35: - configlen.c_ldap_bind_dn = safestrncpy(config.c_ldap_bind_dn, buf, - sizeof config.c_ldap_bind_dn); + CtdlSetConfigStr("c_ldap_bind_dn", buf); break; case 36: - configlen.c_ldap_bind_pw = safestrncpy(config.c_ldap_bind_pw, buf, - sizeof config.c_ldap_bind_pw); + CtdlSetConfigStr("c_ldap_bind_pw", buf); break; -#endif case 37: - configlen.c_ip_addr = safestrncpy(config.c_ip_addr, buf, - sizeof config.c_ip_addr); + CtdlSetConfigStr("c_ip_addr", buf); + break; case 38: - config.c_msa_port = atoi(buf); + CtdlSetConfigInt("c_msa_port", atoi(buf)); break; case 39: - config.c_imaps_port = atoi(buf); + CtdlSetConfigInt("c_imaps_port", atoi(buf)); break; case 40: - config.c_pop3s_port = atoi(buf); + CtdlSetConfigInt("c_pop3s_port", atoi(buf)); break; case 41: - config.c_smtps_port = atoi(buf); + CtdlSetConfigInt("c_smtps_port", atoi(buf)); break; case 42: - config.c_enable_fulltext = atoi(buf); + CtdlSetConfigInt("c_enable_fulltext", confbool(buf)); break; case 43: - config.c_auto_cull = atoi(buf); + CtdlSetConfigInt("c_auto_cull", confbool(buf)); break; case 44: /* niu */ break; case 45: - config.c_allow_spoofing = atoi(buf); + CtdlSetConfigInt("c_allow_spoofing", confbool(buf)); break; case 46: - config.c_journal_email = atoi(buf); + CtdlSetConfigInt("c_journal_email", confbool(buf)); break; case 47: - config.c_journal_pubmsgs = atoi(buf); + CtdlSetConfigInt("c_journal_pubmsgs", confbool(buf)); break; case 48: - configlen.c_journal_dest = safestrncpy(config.c_journal_dest, buf, - sizeof config.c_journal_dest); + CtdlSetConfigStr("c_journal_dest", buf); + break; case 49: - configlen.c_default_cal_zone = safestrncpy( - config.c_default_cal_zone, buf, - sizeof config.c_default_cal_zone); + CtdlSetConfigStr("c_default_cal_zone", buf); break; case 50: - config.c_pftcpdict_port = atoi(buf); + CtdlSetConfigInt("c_pftcpdict_port", atoi(buf)); break; case 51: - config.c_managesieve_port = atoi(buf); + CtdlSetConfigInt("c_managesieve_port", atoi(buf)); break; case 52: - config.c_auth_mode = atoi(buf); + CtdlSetConfigInt("c_auth_mode", atoi(buf)); + break; case 53: - configlen.c_funambol_host = safestrncpy( - config.c_funambol_host, buf, - sizeof config.c_funambol_host); + CtdlSetConfigStr("c_funambol_host", buf); break; case 54: - config.c_funambol_port = atoi(buf); + CtdlSetConfigInt("c_funambol_port", atoi(buf)); break; case 55: - configlen.c_funambol_source = safestrncpy( - config.c_funambol_source, buf, - sizeof config.c_funambol_source); + CtdlSetConfigStr("c_funambol_source", buf); break; case 56: - configlen.c_funambol_auth = safestrncpy( - config.c_funambol_auth, buf, - sizeof config.c_funambol_auth); + CtdlSetConfigStr("c_funambol_auth", buf); break; case 57: - config.c_rbl_at_greeting = atoi(buf); + CtdlSetConfigInt("c_rbl_at_greeting", confbool(buf)); break; case 58: - configlen.c_master_user = safestrncpy( - config.c_master_user, - buf, sizeof config.c_master_user); + CtdlSetConfigStr("c_master_user", buf); break; case 59: - configlen.c_master_pass = safestrncpy( - config.c_master_pass, buf, sizeof config.c_master_pass); + CtdlSetConfigStr("c_master_pass", buf); break; case 60: - configlen.c_pager_program = safestrncpy( - config.c_pager_program, buf, sizeof config.c_pager_program); + CtdlSetConfigStr("c_pager_program", buf); break; case 61: - config.c_imap_keep_from = atoi(buf); + CtdlSetConfigInt("c_imap_keep_from", confbool(buf)); break; case 62: - config.c_xmpp_c2s_port = atoi(buf); + CtdlSetConfigInt("c_xmpp_c2s_port", atoi(buf)); break; case 63: - config.c_xmpp_s2s_port = atoi(buf); + CtdlSetConfigInt("c_xmpp_s2s_port", atoi(buf)); break; case 64: - config.c_pop3_fetch = atol(buf); + CtdlSetConfigLong("c_pop3_fetch", atol(buf)); break; case 65: - config.c_pop3_fastest = atol(buf); + CtdlSetConfigLong("c_pop3_fastest", atol(buf)); break; case 66: - config.c_spam_flag_only = atoi(buf); + CtdlSetConfigInt("c_spam_flag_only", confbool(buf)); break; case 67: - config.c_guest_logins = atoi(buf); + CtdlSetConfigInt("c_guest_logins", confbool(buf)); break; case 68: - config.c_port_number = atoi(buf); + CtdlSetConfigInt("c_port_number", atoi(buf)); break; case 69: - config.c_ctdluid = atoi(buf); + /* niu */ break; case 70: - config.c_nntp_port = atoi(buf); + CtdlSetConfigInt("c_nntp_port", atoi(buf)); break; case 71: - config.c_nntps_port = atoi(buf); + CtdlSetConfigInt("c_nntps_port", atoi(buf)); break; } ++a; } - put_config(); snprintf(buf, sizeof buf, "The global system configuration has been edited by %s.\n", (CC->logged_in ? CC->curr_user : "an administrator") ); CtdlAideMessage(buf,"Citadel Configuration Manager Message"); - if (!IsEmptyStr(config.c_logpages)) - CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS); + if (!IsEmptyStr(CtdlGetConfigStr("c_logpages"))) + CtdlCreateRoom(CtdlGetConfigStr("c_logpages"), 3, "", 0, 1, 1, VIEW_BBS); /* If full text indexing has been disabled, invalidate the * index so it doesn't try to use it later. */ - if (config.c_enable_fulltext == 0) { - CitControl.fulltext_wordbreaker = 0; - put_control(); + if (CtdlGetConfigInt("c_enable_fulltext") == 0) { + CtdlSetConfigInt("MM_fulltext_wordbreaker", 0); } } + // CONF GETSYS - retrieve arbitrary system configuration stanzas stored in the message base else if (!strcasecmp(cmd, "GETSYS")) { extract_token(confname, argbuf, 1, '|', sizeof confname); confptr = CtdlGetSysConfig(confname); @@ -706,18 +614,41 @@ void cmd_conf(char *argbuf) } } + // CONF PUTSYS - store arbitrary system configuration stanzas in the message base else if (!strcasecmp(cmd, "PUTSYS")) { extract_token(confname, argbuf, 1, '|', sizeof confname); unbuffer_output(); cprintf("%d %s\n", SEND_LISTING, confname); - confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + confptr = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); CtdlPutSysConfig(confname, confptr); free(confptr); } + else if (!strcasecmp(cmd, "GETVAL")) { + extract_token(confname, argbuf, 1, '|', sizeof confname); + char *v = CtdlGetConfigStr(confname); + if (v) { + cprintf("%d|%s|\n", CIT_OK, v); + } + else { + cprintf("%d||\n", ERROR); + } + } + + else if (!strcasecmp(cmd, "PUTVAL")) { + if (num_tokens(argbuf, '|') < 3) { + cprintf("%d name and value required\n", ERROR); + } + else { + extract_token(confname, argbuf, 1, '|', sizeof confname); + extract_token(buf, argbuf, 2, '|', sizeof buf); + CtdlSetConfigStr(confname, buf); + cprintf("%d setting '%s' to '%s'\n", CIT_OK, confname, buf); + } + } + else { - cprintf("%d Illegal option(s) specified.\n", - ERROR + ILLEGAL_VALUE); + cprintf("%d Illegal option(s) specified.\n", ERROR + ILLEGAL_VALUE); } } @@ -758,7 +689,7 @@ void cmd_gvdn(char *argbuf) void *vptr; List = NewHash(1, NULL); - Cfg = NewStrBufPlain(config.c_fqdn, -1); + Cfg = NewStrBufPlain(CtdlGetConfigStr("c_fqdn"), -1); Put(List, SKEY(Cfg), Cfg, HFreeStrBuf); Cfg = NULL; diff --git a/citadel/control.h b/citadel/control.h index fa93bc03b..649d3fd85 100644 --- a/citadel/control.h +++ b/citadel/control.h @@ -1,19 +1,19 @@ /* - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ void get_control (void); void put_control (void); -void release_control(void); void check_control(void); long int get_new_message_number (void); long int get_new_user_number (void); long int get_new_room_number (void); +void migrate_legacy_control_record(void); diff --git a/citadel/database.c b/citadel/database.c index e89783f69..de1be0d2c 100644 --- a/citadel/database.c +++ b/citadel/database.c @@ -1,7 +1,7 @@ /* * This is a data store backend for the Citadel server which uses Berkeley DB. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 3. @@ -50,6 +50,7 @@ #include "ctdl_module.h" #include "control.h" #include "citserver.h" +#include "config.h" static DB *dbp[MAXCDB]; /* One DB handle for each Citadel database */ @@ -223,7 +224,7 @@ void cdb_checkpoint(void) } /* After a successful checkpoint, we can cull the unused logs */ - if (config.c_auto_cull) { + if (CtdlGetConfigInt("c_auto_cull")) { cdb_cull_logs(); } } @@ -243,30 +244,10 @@ void open_databases(void) char dbfilename[32]; u_int32_t flags = 0; int dbversion_major, dbversion_minor, dbversion_patch; - int current_dbversion = 0; syslog(LOG_DEBUG, "bdb(): open_databases() starting"); syslog(LOG_DEBUG, "Compiled db: %s", DB_VERSION_STRING); - syslog(LOG_INFO, " Linked db: %s", - db_version(&dbversion_major, &dbversion_minor, &dbversion_patch)); - - current_dbversion = (dbversion_major * 1000000) + (dbversion_minor * 1000) + dbversion_patch; - - syslog(LOG_DEBUG, "Calculated dbversion: %d", current_dbversion); - syslog(LOG_DEBUG, " Previous dbversion: %d", CitControl.MMdbversion); - - if ( (getenv("SUPPRESS_DBVERSION_CHECK") == NULL) - && (CitControl.MMdbversion > current_dbversion) ) { - syslog(LOG_EMERG, "You are attempting to run the Citadel server using a version"); - syslog(LOG_EMERG, "of Berkeley DB that is older than that which last created or"); - syslog(LOG_EMERG, "updated the database. Because this would probably cause data"); - syslog(LOG_EMERG, "corruption or loss, the server is aborting execution now."); - exit(CTDLEXIT_DB); - } - - CitControl.MMdbversion = current_dbversion; - put_control(); - + syslog(LOG_INFO, " Linked db: %s", db_version(&dbversion_major, &dbversion_minor, &dbversion_patch)); syslog(LOG_INFO, "Linked zlib: %s\n", zlibVersion()); /* @@ -935,8 +916,10 @@ time_t CheckIfAlreadySeen(const char *Facility, else { if (cdbut) cdb_free(cdbut); - + SEENM_syslog(LOG_DEBUG, "not Found"); + if (cType == eCheckUpdate) + return 0; } if (cType == eCheckExist) diff --git a/citadel/database.h b/citadel/database.h index 7b3b844b9..e7acb31fb 100644 --- a/citadel/database.h +++ b/citadel/database.h @@ -54,10 +54,10 @@ struct CtdlCompressHeader { }; typedef enum __eCheckType { - eCheckExist, - eCheckUpdate, - eUpdate, - eWrite + eCheckExist, /* look up the item, return the timestamp if its there, 0 if not. */ + eCheckUpdate, /* if it exists, refresh in db timestamp. return the timstamp if its there, 0 if not. */ + eUpdate, /* insert/update the new value, return the old if its there, 0 if not. */ + eWrite /* write this to DB, unconditional. */ }eCheckType; time_t CheckIfAlreadySeen(const char *Facility, diff --git a/citadel/debian/changelog b/citadel/debian/changelog index a421eed7e..9d8b4a8ba 100644 --- a/citadel/debian/changelog +++ b/citadel/debian/changelog @@ -1,3 +1,9 @@ +citadel (9.01-1) stable; urgency=low + + * new release + + -- Wilfried Goesgens Wed, 01 Apr 2015 12:56:30 -0400 + citadel (8.29-1) stable; urgency=low * development prerelease diff --git a/citadel/euidindex.c b/citadel/euidindex.c index aa41d50dc..770c37c1a 100644 --- a/citadel/euidindex.c +++ b/citadel/euidindex.c @@ -127,7 +127,7 @@ void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) { void rebuild_euid_index_for_msg(long msgnum, void *userdata) { struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) return; if (!CM_IsEmpty(msg, eExclusiveID)) { index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgnum); diff --git a/citadel/event_client.c b/citadel/event_client.c index 999c9e454..fad9eefec 100644 --- a/citadel/event_client.c +++ b/citadel/event_client.c @@ -27,6 +27,7 @@ #include "ctdl_module.h" #include "event_client.h" #include "citserver.h" +#include "config.h" ConstStr IOStates[] = { {HKEY("DB Queue")}, @@ -156,7 +157,7 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents) AsyncIO *IO = watcher->data; SetEVState(IO, eDBNext); - IO->Now = ev_now(event_db); + IO->CitContext->lastcmd = IO->Now = ev_now(event_db); EV_syslog(LOG_DEBUG, "%s()", __FUNCTION__); become_session(IO->CitContext); @@ -220,7 +221,7 @@ static void IO_abort_shutdown_callback(struct ev_loop *loop, SetEVState(IO, eIOAbort); EV_syslog(LOG_DEBUG, "EVENT Q: %s\n", __FUNCTION__); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); assert(IO->ShutdownAbort); IO->ShutdownAbort(IO); } @@ -543,7 +544,7 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) AsyncIO *IO = watcher->data; const char *errmsg = NULL; - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); become_session(IO->CitContext); #ifdef BIGBAD_IODBG { @@ -720,7 +721,7 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents) AsyncIO *IO = watcher->data; SetEVState(IO, eIOTimeout); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); ev_timer_stop (event_base, &IO->rw_timeout); become_session(IO->CitContext); @@ -749,7 +750,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents) AsyncIO *IO = watcher->data; SetEVState(IO, eIOConnfail); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); ev_timer_stop (event_base, &IO->conn_fail); if (IO->SendBuf.fd != 0) @@ -782,7 +783,7 @@ IO_connfailimmediate_callback(struct ev_loop *loop, AsyncIO *IO = watcher->data; SetEVState(IO, eIOConnfailNow); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); ev_idle_stop (event_base, &IO->conn_fail_immediate); if (IO->SendBuf.fd != 0) @@ -812,7 +813,7 @@ IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents) int err; SetEVState(IO, eIOConnNow); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); EVM_syslog(LOG_DEBUG, "connect() succeeded.\n"); ev_io_stop(loop, &IO->conn_event); @@ -846,7 +847,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) ssize_t nbytes; AsyncIO *IO = watcher->data; - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); switch (IO->NextState) { case eReadFile: nbytes = FileRecvChunked(&IO->IOB, &errmsg); @@ -932,7 +933,7 @@ IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents) AsyncIO *IO = watcher->data; SetEVState(IO, eCaresFinished); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); EV_syslog(LOG_DEBUG, "event: %s\n", __FUNCTION__); become_session(IO->CitContext); assert(IO->DNS.Query->PostDNS); @@ -1059,8 +1060,8 @@ eNextState EvConnectSock(AsyncIO *IO, memset(&egress_sin, 0, sizeof(egress_sin)); egress_sin.sin_family = AF_INET; - if (!IsEmptyStr(config.c_ip_addr)) { - egress_sin.sin_addr.s_addr = inet_addr(config.c_ip_addr); + if (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) { + egress_sin.sin_addr.s_addr = inet_addr(CtdlGetConfigStr("c_ip_addr")); if (egress_sin.sin_addr.s_addr == !INADDR_ANY) { egress_sin.sin_addr.s_addr = INADDR_ANY; } diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index 11be04e00..923362777 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -129,3 +129,60 @@ void do_housekeeping(void) { housekeeping_in_progress = 0; end_critical_section(S_HOUSEKEEPING); } + +void CtdlDisableHouseKeeping(void) +{ + int ActiveBackgroundJobs; + int do_housekeeping_now = 0; + struct CitContext *nptr; + int nContexts, i; + +retry_block_housekeeping: + syslog(LOG_INFO, "trying to disable housekeeping services"); + begin_critical_section(S_HOUSEKEEPING); + if (housekeeping_in_progress == 0) { + do_housekeeping_now = 1; + housekeeping_in_progress = 1; + } + end_critical_section(S_HOUSEKEEPING); + if (do_housekeeping_now == 0) { + usleep(1000000); + goto retry_block_housekeeping; + } + + syslog(LOG_INFO, "checking for running server Jobs"); + +retry_wait_for_contexts: + /* So that we don't keep the context list locked for a long time + * we create a copy of it first + */ + ActiveBackgroundJobs = 0; + nptr = CtdlGetContextArray(&nContexts) ; + if (nptr) + { + for (i=0; i #include @@ -281,8 +292,8 @@ int CtdlHostAlias(char *fqdn) { if (fqdn == NULL) return(hostalias_nomatch); if (IsEmptyStr(fqdn)) return(hostalias_nomatch); if (!strcasecmp(fqdn, "localhost")) return(hostalias_localhost); - if (!strcasecmp(fqdn, config.c_fqdn)) return(hostalias_localhost); - if (!strcasecmp(fqdn, config.c_nodename)) return(hostalias_localhost); + if (!strcasecmp(fqdn, CtdlGetConfigStr("c_fqdn"))) return(hostalias_localhost); + if (!strcasecmp(fqdn, CtdlGetConfigStr("c_nodename"))) return(hostalias_localhost); if (inetcfg == NULL) return(hostalias_nomatch); config_lines = num_tokens(inetcfg, '\n'); @@ -633,7 +644,7 @@ recptypes *validate_recipients(const char *supplied_recipients, case MES_LOCAL: if (!strcasecmp(this_recp, "sysop")) { ++ret->num_room; - strcpy(this_recp, config.c_aideroom); + strcpy(this_recp, CtdlGetConfigStr("c_aideroom")); if (!IsEmptyStr(ret->recp_room)) { strcat(ret->recp_room, "|"); } @@ -1025,7 +1036,7 @@ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) int a; strcpy(user, ""); - strcpy(node, config.c_fqdn); + strcpy(node, CtdlGetConfigStr("c_fqdn")); strcpy(name, ""); if (rfc822 == NULL) return; @@ -1114,7 +1125,7 @@ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) && (haschar(node, '%')==0) && (haschar(node, '!')==0) ) { - strcpy(node, config.c_nodename); + strcpy(node, CtdlGetConfigStr("c_nodename")); } else { diff --git a/citadel/journaling.c b/citadel/journaling.c index eb9e378e7..8af9afdca 100644 --- a/citadel/journaling.c +++ b/citadel/journaling.c @@ -1,5 +1,15 @@ /* * Message journaling functions. + * + * Copyright (c) 1987-2015 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -8,6 +18,7 @@ #include "ctdl_module.h" #include "citserver.h" +#include "config.h" #include "user_ops.h" #include "serv_vcard.h" /* Needed for vcard_getuser and extract_inet_email_addrs */ #include "internet_addressing.h" @@ -100,7 +111,7 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { if (jmsg == NULL) return; - journal_recps = validate_recipients(config.c_journal_dest, NULL, 0); + journal_recps = validate_recipients(CtdlGetConfigStr("c_journal_dest"), NULL, 0); if (journal_recps != NULL) { if ( (journal_recps->num_local > 0) diff --git a/citadel/ldap.c b/citadel/ldap.c index 58a8fa137..97288637f 100644 --- a/citadel/ldap.c +++ b/citadel/ldap.c @@ -2,7 +2,7 @@ * These functions implement the portions of AUTHMODE_LDAP and AUTHMODE_LDAP_AD which * actually speak to the LDAP server. * - * Copyright (c) 2011-2014 by the citadel.org development team. + * Copyright (c) 2011-2015 by the citadel.org development team. * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -22,6 +22,7 @@ int ctdl_require_ldap_version = 3; #include "citadel_ldap.h" #include "ctdl_module.h" #include "user_ops.h" +#include "config.h" #ifdef HAVE_LDAP #define LDAP_DEPRECATED 1 /* Suppress libldap's warning that we are using deprecated API calls */ @@ -37,7 +38,7 @@ int ctdl_ldap_initialize(LDAP **ld) { char server_url[256]; int ret; - snprintf(server_url, sizeof server_url, "ldap://%s:%d", config.c_ldap_host, config.c_ldap_port); + snprintf(server_url, sizeof server_url, "ldap://%s:%d", CtdlGetConfigStr("c_ldap_host"), CtdlGetConfigInt("c_ldap_port")); ret = ldap_initialize(ld, server_url); if (ret != LDAP_SUCCESS) { syslog(LOG_ALERT, "LDAP: Could not connect to %s : %s", @@ -60,7 +61,7 @@ int ctdl_ldap_initialize(LDAP **ld) { int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size, - uid_t *uid, int lookup_based_on_uid) + uid_t *uid, int lookup_based_on_username) { LDAP *ldserver = NULL; int i; @@ -80,12 +81,12 @@ int CtdlTryUserLDAP(char *username, ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version); ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF); - striplt(config.c_ldap_bind_dn); - striplt(config.c_ldap_bind_pw); - syslog(LOG_DEBUG, "LDAP bind DN: %s", config.c_ldap_bind_dn); + striplt(CtdlGetConfigStr("c_ldap_bind_dn")); + striplt(CtdlGetConfigStr("c_ldap_bind_pw")); + syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn")); i = ldap_simple_bind_s(ldserver, - (!IsEmptyStr(config.c_ldap_bind_dn) ? config.c_ldap_bind_dn : NULL), - (!IsEmptyStr(config.c_ldap_bind_pw) ? config.c_ldap_bind_pw : NULL) + (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL), + (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL) ); if (i != LDAP_SUCCESS) { syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i); @@ -95,15 +96,15 @@ int CtdlTryUserLDAP(char *username, tv.tv_sec = 10; tv.tv_usec = 0; - if (config.c_auth_mode == AUTHMODE_LDAP_AD) { - if (lookup_based_on_uid!=0) - snprintf(searchstring, sizeof(searchstring), "(objectGUID=%d)",*uid); + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { + if (lookup_based_on_username != 0) + snprintf(searchstring, sizeof(searchstring), "(displayName=%s)",username); else snprintf(searchstring, sizeof(searchstring), "(sAMAccountName=%s)", username); } else { - if (lookup_based_on_uid!=0) - snprintf(searchstring, sizeof(searchstring), "(uidNumber=%d)",*uid); + if (lookup_based_on_username != 0) + snprintf(searchstring, sizeof(searchstring), "(cn=%s)",username); else snprintf(searchstring, sizeof(searchstring), "(&(objectclass=posixAccount)(uid=%s))", username); } @@ -111,7 +112,7 @@ int CtdlTryUserLDAP(char *username, syslog(LOG_DEBUG, "LDAP search: %s", searchstring); (void) ldap_search_ext_s( ldserver, /* ld */ - config.c_ldap_base_dn, /* base */ + CtdlGetConfigStr("c_ldap_base_dn"), /* base */ LDAP_SCOPE_SUBTREE, /* scope */ searchstring, /* filter */ NULL, /* attrs (all attributes) */ @@ -143,7 +144,7 @@ int CtdlTryUserLDAP(char *username, syslog(LOG_DEBUG, "dn = %s", user_dn); } - if (config.c_auth_mode == AUTHMODE_LDAP_AD) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { values = ldap_get_values(ldserver, search_result, "displayName"); if (values) { if (values[0]) { @@ -163,9 +164,9 @@ int CtdlTryUserLDAP(char *username, ldap_value_free(values); } } - - if (lookup_based_on_uid==0) { - if (config.c_auth_mode == AUTHMODE_LDAP_AD) { + /* If we know the username is the CN/displayName, we already set the uid*/ + if (lookup_based_on_username==0) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { values = ldap_get_values(ldserver, search_result, "objectGUID"); if (values) { if (values[0]) { @@ -245,13 +246,14 @@ int CtdlTryPasswordLDAP(char *user_dn, const char *password) //return !0 iff property changed. int vcard_set_props_iff_different(struct vCard *v,char *propname,int numvals, char **vals) { int i; - char *oldval; + char *oldval = ""; for(i=0;icm_fields[eMesageText]); @@ -170,7 +170,7 @@ void cmd_auto(char *argbuf) { /* * Search-reduce the results if we have the full text index available */ - if (config.c_enable_fulltext) { + if (CtdlGetConfigInt("c_enable_fulltext")) { CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, search_string, "fulltext"); if (fts_msgs) { for (i=0; i #include @@ -45,7 +46,7 @@ void cmd_ebio(char *cmdbuf) { } cprintf("%d \n",SEND_LISTING); while(client_getln(buf, sizeof buf) >= 0 && strcmp(buf,"000")) { - if (ftell(fp) < config.c_maxmsglen) { + if (ftell(fp) < CtdlGetConfigLong("c_maxmsglen")) { fprintf(fp,"%s\n",buf); } } diff --git a/citadel/modules/calendar/serv_calendar.c b/citadel/modules/calendar/serv_calendar.c index 1504fcc93..5fb86a228 100644 --- a/citadel/modules/calendar/serv_calendar.c +++ b/citadel/modules/calendar/serv_calendar.c @@ -3,22 +3,15 @@ * room on a Citadel server. It handles iCalendar objects using the * iTIP protocol. See RFCs 2445 and 2446. * + * Copyright (c) 1987-2015 by the citadel.org team * - * Copyright (c) 1987-2011 by the citadel.org team + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #define PRODID "-//Citadel//NONSGML Citadel Calendar//EN" @@ -33,6 +26,7 @@ #include "room_ops.h" #include "euidindex.h" #include "ical_dezonify.h" +#include "config.h" @@ -149,8 +143,8 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { msg->cm_format_type = 4; CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); MsgBody = NewStrBufPlain(NULL, serlen + 100); StrBufAppendBufPlain(MsgBody, HKEY("Content-type: text/calendar\r\n\r\n"), 0); @@ -375,7 +369,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -636,7 +630,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) { * us the ability to load the event into memory so we can diddle the * attendees. */ - msg = CtdlFetchMessage(msgnum_being_replaced, 1); + msg = CtdlFetchMessage(msgnum_being_replaced, 1, 1); if (msg == NULL) { return(2); /* internal error */ } @@ -716,7 +710,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -1154,7 +1148,7 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) { proposed_event = (icalcomponent *)data; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); @@ -1215,7 +1209,7 @@ void ical_conflicts(long msgnum, char *partnum) { struct CtdlMessage *msg = NULL; struct ical_respond_data ird; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found\n", ERROR + ILLEGAL_VALUE, @@ -1402,7 +1396,7 @@ void ical_freebusy_backend(long msgnum, void *data) { fb = (icalcomponent *)data; /* User-supplied data will be the VFREEBUSY component */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); @@ -1460,7 +1454,7 @@ void ical_freebusy(char *who) { * primary FQDN of this Citadel node. */ if (found_user != 0) { - snprintf(buf, sizeof buf, "%s@%s", who, config.c_fqdn); + snprintf(buf, sizeof buf, "%s@%s", who, CtdlGetConfigStr("c_fqdn")); syslog(LOG_DEBUG, "Trying <%s>\n", buf); recp = validate_recipients(buf, NULL, 0); if (recp != NULL) { @@ -1532,7 +1526,7 @@ void ical_freebusy(char *who) { sprintf(buf, "MAILTO:%s", who); if (strchr(buf, '@') == NULL) { strcat(buf, "@"); - strcat(buf, config.c_fqdn); + strcat(buf, CtdlGetConfigStr("c_fqdn")); } for (i=0; buf[i]; ++i) { if (buf[i]==' ') buf[i] = '_'; @@ -1602,7 +1596,7 @@ void ical_getics_backend(long msgnum, void *data) { /* Look for the calendar event... */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); @@ -1755,7 +1749,7 @@ void ical_putics(void) } cprintf("%d Transmit data now\n", SEND_LISTING); - calstream = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + calstream = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); if (calstream == NULL) { return; } diff --git a/citadel/modules/crypto/serv_crypto.c b/citadel/modules/crypto/serv_crypto.c index a9761a549..eea501d39 100644 --- a/citadel/modules/crypto/serv_crypto.c +++ b/citadel/modules/crypto/serv_crypto.c @@ -1,19 +1,13 @@ /* - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -93,14 +87,13 @@ void init_ssl(void) RAND_egd(EGD_POOL); if (!RAND_status()) { - syslog(LOG_CRIT, - "PRNG not adequately seeded, won't do SSL/TLS\n"); + syslog(LOG_CRIT, "PRNG not adequately seeded, won't do SSL/TLS"); return; } SSLCritters = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t *)); if (!SSLCritters) { - syslog(LOG_EMERG, "citserver: can't allocate memory!!\n"); + syslog(LOG_EMERG, "citserver: can't allocate memory!!"); /* Nothing's been initialized, just die */ exit(1); } else { @@ -109,8 +102,7 @@ void init_ssl(void) for (a = 0; a < CRYPTO_num_locks(); a++) { SSLCritters[a] = malloc(sizeof(pthread_mutex_t)); if (!SSLCritters[a]) { - syslog(LOG_EMERG, - "citserver: can't allocate memory!!\n"); + syslog(LOG_EMERG, "citserver: can't allocate memory!!"); /* Nothing's been initialized, just die */ exit(1); } @@ -125,12 +117,11 @@ void init_ssl(void) SSL_load_error_strings(); ssl_method = SSLv23_server_method(); if (!(ssl_ctx = SSL_CTX_new(ssl_method))) { - syslog(LOG_CRIT, "SSL_CTX_new failed: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "SSL_CTX_new failed: %s", ERR_reason_error_string(ERR_get_error())); return; } if (!(SSL_CTX_set_cipher_list(ssl_ctx, CIT_CIPHERS))) { - syslog(LOG_CRIT, "SSL: No ciphers available\n"); + syslog(LOG_CRIT, "SSL: No ciphers available"); SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; return; @@ -148,22 +139,19 @@ void init_ssl(void) /* Load DH parameters into the context */ dh = DH_new(); if (!dh) { - syslog(LOG_CRIT, "init_ssl() can't allocate a DH object: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "init_ssl() can't allocate a DH object: %s", ERR_reason_error_string(ERR_get_error())); SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; return; } if (!(BN_hex2bn(&(dh->p), DH_P))) { - syslog(LOG_CRIT, "init_ssl() can't assign DH_P: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "init_ssl() can't assign DH_P: %s", ERR_reason_error_string(ERR_get_error())); SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; return; } if (!(BN_hex2bn(&(dh->g), DH_G))) { - syslog(LOG_CRIT, "init_ssl() can't assign DH_G: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "init_ssl() can't assign DH_G: %s", ERR_reason_error_string(ERR_get_error())); SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; return; @@ -181,14 +169,13 @@ void init_ssl(void) * Generate a key pair if we don't have one. */ if (access(file_crpt_file_key, R_OK) != 0) { - syslog(LOG_INFO, "Generating RSA key pair.\n"); + syslog(LOG_INFO, "Generating RSA key pair."); rsa = RSA_generate_key(1024, /* modulus size */ 65537, /* exponent */ NULL, /* no callback */ NULL); /* no callback */ if (rsa == NULL) { - syslog(LOG_CRIT, "Key generation failed: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "Key generation failed: %s", ERR_reason_error_string(ERR_get_error())); } if (rsa != NULL) { fp = fopen(file_crpt_file_key, "w"); @@ -202,8 +189,7 @@ void init_ssl(void) NULL, /* no callbk */ NULL /* no callbk */ ) != 1) { - syslog(LOG_CRIT, "Cannot write key: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "Cannot write key: %s", ERR_reason_error_string(ERR_get_error())); unlink(file_crpt_file_key); } fclose(fp); @@ -218,7 +204,7 @@ void init_ssl(void) * the CSR in this step so that the next step may commence. */ if ( (access(file_crpt_file_cer, R_OK) != 0) && (access(file_crpt_file_csr, R_OK) != 0) ) { - syslog(LOG_INFO, "Generating a certificate signing request.\n"); + syslog(LOG_INFO, "Generating a generic certificate signing request."); /* * Read our key from the file. No, we don't just keep this @@ -246,42 +232,17 @@ void init_ssl(void) name = X509_REQ_get_subject_name(req); /* Tell it who we are */ - - /* - X509_NAME_add_entry_by_txt(name, "C", - MBSTRING_ASC, "US", -1, -1, 0); - - X509_NAME_add_entry_by_txt(name, "ST", - MBSTRING_ASC, "New York", -1, -1, 0); - - X509_NAME_add_entry_by_txt(name, "L", - MBSTRING_ASC, "Mount Kisco", -1, -1, 0); - */ - - X509_NAME_add_entry_by_txt(name, "O", - MBSTRING_ASC, - (unsigned char*) config.c_humannode, - -1, -1, 0); - - X509_NAME_add_entry_by_txt(name, "OU", - MBSTRING_ASC, - (unsigned const char*)"Citadel server", - -1, -1, 0); - - /* X509_NAME_add_entry_by_txt(name, "CN", - MBSTRING_ASC, config.c_fqdn, -1, -1, 0); - */ - - X509_NAME_add_entry_by_txt(name, - "CN", - MBSTRING_ASC, - (const unsigned char *)"*", -1, -1, 0); - + X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned const char *)"ZZ", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, (unsigned const char *)"The World", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, (unsigned const char *)"My Location", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned const char *)"Generic certificate", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, (unsigned const char *)"Citadel server", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned const char *)"*", -1, -1, 0); X509_REQ_set_subject_name(req, name); /* Sign the CSR */ if (!X509_REQ_sign(req, pk, EVP_md5())) { - syslog(LOG_CRIT, "X509_REQ_sign(): error\n"); + syslog(LOG_CRIT, "X509_REQ_sign(): error"); } else { /* Write it to disk. */ @@ -301,7 +262,7 @@ void init_ssl(void) } else { - syslog(LOG_CRIT, "Unable to read private key.\n"); + syslog(LOG_CRIT, "Unable to read private key."); } } @@ -311,7 +272,7 @@ void init_ssl(void) * Generate a self-signed certificate if we don't have one. */ if (access(file_crpt_file_cer, R_OK) != 0) { - syslog(LOG_INFO, "Generating a self-signed certificate.\n"); + syslog(LOG_INFO, "Generating a generic self-signed certificate."); /* Same deal as before: always read the key from disk because * it may or may not have just been generated. @@ -351,7 +312,7 @@ void init_ssl(void) /* Sign the cert */ if (!X509_sign(cer, pk, EVP_md5())) { - syslog(LOG_CRIT, "X509_sign(): error\n"); + syslog(LOG_CRIT, "X509_sign(): error"); } else { /* Write it to disk. */ @@ -377,8 +338,7 @@ void init_ssl(void) SSL_CTX_use_certificate_chain_file(ssl_ctx, file_crpt_file_cer); SSL_CTX_use_PrivateKey_file(ssl_ctx, file_crpt_file_key, SSL_FILETYPE_PEM); if ( !SSL_CTX_check_private_key(ssl_ctx) ) { - syslog(LOG_CRIT, "Cannot install certificate: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "Cannot install certificate: %s", ERR_reason_error_string(ERR_get_error())); } /* Finally let the server know we're here */ @@ -403,7 +363,7 @@ void client_write_ssl(const char *buf, int nbytes) while (nremain > 0) { if (SSL_want_write(CC->ssl)) { if ((SSL_read(CC->ssl, junk, 0)) < 1) { - syslog(LOG_DEBUG, "SSL_read in client_write: %s\n", ERR_reason_error_string(ERR_get_error())); + syslog(LOG_DEBUG, "SSL_read in client_write: %s", ERR_reason_error_string(ERR_get_error())); } } retval = @@ -417,9 +377,9 @@ void client_write_ssl(const char *buf, int nbytes) sleep(1); continue; } - syslog(LOG_DEBUG, "SSL_write got error %ld, ret %d\n", errval, retval); + syslog(LOG_DEBUG, "SSL_write got error %ld, ret %d", errval, retval); if (retval == -1) - syslog(LOG_DEBUG, "errno is %d\n", errno); + syslog(LOG_DEBUG, "errno is %d", errno); endtls(); client_write(&buf[nbytes - nremain], nremain); return; @@ -444,7 +404,7 @@ int client_read_sslbuffer(StrBuf *buf, int timeout) while (1) { if (SSL_want_read(pssl)) { if ((SSL_write(pssl, junk, 0)) < 1) { - syslog(LOG_DEBUG, "SSL_write in client_read\n"); + syslog(LOG_DEBUG, "SSL_write in client_read"); } } rlen = SSL_read(pssl, sbuf, sizeof(sbuf)); @@ -456,7 +416,7 @@ int client_read_sslbuffer(StrBuf *buf, int timeout) sleep(1); continue; } - syslog(LOG_DEBUG, "SSL_read got error %ld\n", errval); + syslog(LOG_DEBUG, "SSL_read got error %ld", errval); endtls(); return (-1); } @@ -636,19 +596,18 @@ void CtdlStartTLS(char *ok_response, char *nosup_response, int retval, bits, alg_bits; if (!ssl_ctx) { - syslog(LOG_CRIT, "SSL failed: no ssl_ctx exists?\n"); + syslog(LOG_CRIT, "SSL failed: no ssl_ctx exists?"); if (nosup_response != NULL) cprintf("%s", nosup_response); return; } if (!(CC->ssl = SSL_new(ssl_ctx))) { - syslog(LOG_CRIT, "SSL_new failed: %s\n", + syslog(LOG_CRIT, "SSL_new failed: %s", ERR_reason_error_string(ERR_get_error())); if (error_response != NULL) cprintf("%s", error_response); return; } if (!(SSL_set_fd(CC->ssl, CC->client_socket))) { - syslog(LOG_CRIT, "SSL_set_fd failed: %s\n", - ERR_reason_error_string(ERR_get_error())); + syslog(LOG_CRIT, "SSL_set_fd failed: %s", ERR_reason_error_string(ERR_get_error())); SSL_free(CC->ssl); CC->ssl = NULL; if (error_response != NULL) cprintf("%s", error_response); @@ -666,7 +625,7 @@ void CtdlStartTLS(char *ok_response, char *nosup_response, char error_string[128]; errval = SSL_get_error(CC->ssl, retval); - syslog(LOG_CRIT, "SSL_accept failed: retval=%d, errval=%ld, err=%s\n", + syslog(LOG_CRIT, "SSL_accept failed: retval=%d, errval=%ld, err=%s", retval, errval, ERR_error_string(errval, error_string) @@ -677,7 +636,7 @@ void CtdlStartTLS(char *ok_response, char *nosup_response, } BIO_set_close(CC->ssl->rbio, BIO_NOCLOSE); bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(CC->ssl), &alg_bits); - syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)\n", + syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)", SSL_CIPHER_get_name(SSL_get_current_cipher(CC->ssl)), SSL_CIPHER_get_version(SSL_get_current_cipher(CC->ssl)), bits, alg_bits); @@ -744,7 +703,7 @@ void endtls(void) return; } - syslog(LOG_INFO, "Ending SSL/TLS\n"); + syslog(LOG_INFO, "Ending SSL/TLS"); SSL_shutdown(CC->ssl); SSL_free(CC->ssl); CC->ssl = NULL; diff --git a/citadel/modules/ctdlproto/serv_file.c b/citadel/modules/ctdlproto/serv_file.c index 15e43b46d..50661c7c7 100644 --- a/citadel/modules/ctdlproto/serv_file.c +++ b/citadel/modules/ctdlproto/serv_file.c @@ -1,5 +1,15 @@ /* * Server functions which handle file transfers and room directories. + * + * Copyright (c) 1987-2015 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -9,8 +19,10 @@ #include "ctdl_module.h" #include "citserver.h" #include "support.h" +#include "config.h" #include "user_ops.h" + /* * Server command to delete a file from a room's directory */ @@ -787,16 +799,15 @@ void do_help_subst(char *buffer) { char buf2[16]; - help_subst(buffer, "^nodename", config.c_nodename); - help_subst(buffer, "^humannode", config.c_humannode); - help_subst(buffer, "^fqdn", config.c_fqdn); + help_subst(buffer, "^nodename", CtdlGetConfigStr("c_nodename")); + help_subst(buffer, "^humannode", CtdlGetConfigStr("c_humannode")); + help_subst(buffer, "^fqdn", CtdlGetConfigStr("c_fqdn")); help_subst(buffer, "^username", CC->user.fullname); snprintf(buf2, sizeof buf2, "%ld", CC->user.usernum); help_subst(buffer, "^usernum", buf2); - help_subst(buffer, "^sysadm", config.c_sysadm); + help_subst(buffer, "^sysadm", CtdlGetConfigStr("c_sysadm")); help_subst(buffer, "^variantname", CITADEL); - snprintf(buf2, sizeof buf2, "%d", config.c_maxsessions); - help_subst(buffer, "^maxsessions", buf2); + help_subst(buffer, "^maxsessions", CtdlGetConfigStr("c_maxsessions")); // yes it's numeric but str is ok here help_subst(buffer, "^bbsdir", ctdl_message_dir); } diff --git a/citadel/modules/ctdlproto/serv_messages.c b/citadel/modules/ctdlproto/serv_messages.c index 2d3208a22..31e48cb8c 100644 --- a/citadel/modules/ctdlproto/serv_messages.c +++ b/citadel/modules/ctdlproto/serv_messages.c @@ -1,7 +1,7 @@ /* * represent messages to the citadel clients * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -20,11 +20,11 @@ #include "internet_addressing.h" #include "user_ops.h" #include "room_ops.h" +#include "config.h" extern char *msgkeys[]; - /* * Back end for the MSGS command: output message number only. */ @@ -34,7 +34,6 @@ void simple_listing(long msgnum, void *userdata) } - /* * Back end for the MSGS command: output header summary. */ @@ -42,7 +41,7 @@ void headers_listing(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { cprintf("%ld|0|||||\n", msgnum); return; @@ -66,7 +65,7 @@ void headers_euid(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { cprintf("%ld||\n", msgnum); return; @@ -137,7 +136,7 @@ void cmd_msgs(char *cmdbuf) else mode = MSGS_ALL; - if ( (mode == MSGS_SEARCH) && (!config.c_enable_fulltext) ) { + if ( (mode == MSGS_SEARCH) && (!CtdlGetConfigInt("c_enable_fulltext")) ) { cprintf("%d Full text index is not enabled on this server.\n", ERROR + CMD_NOT_SUPPORTED); return; @@ -228,7 +227,7 @@ void cmd_msg3(char *cmdbuf) } msgnum = extract_long(cmdbuf, 0); - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + MESSAGE_NOT_FOUND, msgnum); diff --git a/citadel/modules/ctdlproto/serv_rooms.c b/citadel/modules/ctdlproto/serv_rooms.c index 14673274b..51456ac03 100644 --- a/citadel/modules/ctdlproto/serv_rooms.c +++ b/citadel/modules/ctdlproto/serv_rooms.c @@ -1,7 +1,7 @@ /* * Server functions which perform operations on room objects. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -19,6 +19,7 @@ #include "citserver.h" #include "ctdl_module.h" #include "room_ops.h" +#include "config.h" /* * Back-back-end for all room listing commands @@ -416,7 +417,7 @@ void cmd_rdir(char *cmdbuf) cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED); return; } - cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, config.c_fqdn, ctdl_file_dir, CC->room.QRdirname); + cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, CtdlGetConfigStr("c_fqdn"), ctdl_file_dir, CC->room.QRdirname); snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname); fd = fopen(buf, "r"); @@ -595,8 +596,7 @@ void cmd_setr(char *args) CC->room.QRflags |= QR_PRIVATE; /* Some changes can't apply to BASEROOM */ - if (!strncasecmp(CC->room.QRname, config.c_baseroom, - ROOMNAMELEN)) { + if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) { CC->room.QRorder = 0; CC->room.QRpasswd[0] = '\0'; CC->room.QRflags &= ~(QR_PRIVATE & QR_PASSWORDED & @@ -619,8 +619,7 @@ void cmd_setr(char *args) } } /* Some changes can't apply to AIDEROOM */ - if (!strncasecmp(CC->room.QRname, config.c_baseroom, - ROOMNAMELEN)) { + if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) { CC->room.QRorder = 0; CC->room.QRflags &= ~QR_MAILBOX; CC->room.QRflags |= QR_PERMANENT; @@ -761,7 +760,7 @@ void cmd_kill(char *argbuf) CtdlScheduleRoomForDeletion(&CC->room); /* Return to the Lobby */ - CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL); + CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL); /* tell the world what we did */ snprintf(msg, sizeof msg, "The room \"%s\" has been deleted by %s.\n", @@ -831,7 +830,7 @@ void cmd_cre8(char *args) if (CtdlAccessCheck(ac_logged_in)) return; - if (CC->user.axlevel < config.c_createax && !CC->internal_pgm) { + if (CC->user.axlevel < CtdlGetConfigInt("c_createax") && !CC->internal_pgm) { cprintf("%d You need higher access to create rooms.\n", ERROR + HIGHER_ACCESS_REQUIRED); return; diff --git a/citadel/modules/ctdlproto/serv_session.c b/citadel/modules/ctdlproto/serv_session.c index 6c3914654..4aaba4072 100644 --- a/citadel/modules/ctdlproto/serv_session.c +++ b/citadel/modules/ctdlproto/serv_session.c @@ -1,7 +1,7 @@ /* * Server functions which perform operations on user objects. * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License, version 3. @@ -18,6 +18,7 @@ #include "citserver.h" #include "svn_revision.h" #include "ctdl_module.h" +#include "config.h" void cmd_noop(char *argbuf) { @@ -52,15 +53,15 @@ void cmd_asyn(char *argbuf) void cmd_info(char *cmdbuf) { cprintf("%d Server info:\n", LISTING_FOLLOWS); cprintf("%d\n", CC->cs_pid); - cprintf("%s\n", config.c_nodename); - cprintf("%s\n", config.c_humannode); - cprintf("%s\n", config.c_fqdn); + cprintf("%s\n", CtdlGetConfigStr("c_nodename")); + cprintf("%s\n", CtdlGetConfigStr("c_humannode")); + cprintf("%s\n", CtdlGetConfigStr("c_fqdn")); cprintf("%s\n", CITADEL); cprintf("%d\n", REV_LEVEL); - cprintf("%s\n", config.c_site_location); - cprintf("%s\n", config.c_sysadm); + cprintf("%s\n", CtdlGetConfigStr("c_site_location")); + cprintf("%s\n", CtdlGetConfigStr("c_sysadm")); cprintf("%d\n", SERVER_TYPE); - cprintf("%s\n", config.c_moreprompt); + cprintf("%s\n", CtdlGetConfigStr("c_moreprompt")); cprintf("1\n"); /* 1 = yes, this system supports floors */ cprintf("1\n"); /* 1 = we support the extended paging options */ cprintf("\n"); /* nonce no longer supported */ @@ -72,16 +73,15 @@ void cmd_info(char *cmdbuf) { cprintf("0\n"); /* 1 = no, this server is not LDAP-enabled */ #endif - if ((config.c_auth_mode == AUTHMODE_NATIVE) && - (config.c_disable_newu == 0)) + if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) && (CtdlGetConfigInt("c_disable_newu") == 0)) { - cprintf("%d\n", config.c_disable_newu); + cprintf("%d\n", CtdlGetConfigInt("c_disable_newu")); } else { cprintf("1\n"); /* "create new user" does not work with non-native auth modes */ } - cprintf("%s\n", config.c_default_cal_zone); + cprintf("%s\n", CtdlGetConfigStr("c_default_cal_zone")); /* thread load averages -- temporarily disabled during refactoring of this code */ cprintf("0\n"); /* load average */ @@ -89,17 +89,17 @@ void cmd_info(char *cmdbuf) { cprintf("0\n"); /* thread count */ cprintf("1\n"); /* yes, Sieve mail filtering is supported */ - cprintf("%d\n", config.c_enable_fulltext); + cprintf("%d\n", CtdlGetConfigInt("c_enable_fulltext")); cprintf("%s\n", svn_revision()); - if (config.c_auth_mode == AUTHMODE_NATIVE) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) { cprintf("%d\n", openid_level_supported); /* OpenID is enabled when using native auth */ } else { cprintf("0\n"); /* OpenID is disabled when using non-native auth */ } - cprintf("%d\n", config.c_guest_logins); + cprintf("%d\n", CtdlGetConfigInt("c_guest_logins")); cprintf("000\n"); } @@ -116,7 +116,7 @@ void cmd_echo(char *etext) * get the paginator prompt */ void cmd_more(char *argbuf) { - cprintf("%d %s\n", CIT_OK, config.c_moreprompt); + cprintf("%d %s\n", CIT_OK, CtdlGetConfigStr("c_moreprompt")); } @@ -142,7 +142,7 @@ void cmd_iden(char *argbuf) rev_level = extract_int(argbuf,2); extract_token(desc, argbuf, 3, '|', sizeof desc); - safestrncpy(from_host, config.c_fqdn, sizeof from_host); + safestrncpy(from_host, CtdlGetConfigStr("c_fqdn"), sizeof from_host); from_host[sizeof from_host - 1] = 0; if (num_parms(argbuf)>=5) extract_token(from_host, argbuf, 4, '|', sizeof from_host); diff --git a/citadel/modules/ctdlproto/serv_user.c b/citadel/modules/ctdlproto/serv_user.c index 5a7162977..51ea437b7 100644 --- a/citadel/modules/ctdlproto/serv_user.c +++ b/citadel/modules/ctdlproto/serv_user.c @@ -1,7 +1,7 @@ /* * Server functions which perform operations on user objects. * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License, version 3. @@ -15,14 +15,12 @@ #include "support.h" #include "control.h" #include "ctdl_module.h" - #include "citserver.h" - +#include "config.h" #include "user_ops.h" #include "internet_addressing.h" - /* * USER cmd */ @@ -47,7 +45,7 @@ void cmd_user(char *cmdbuf) "Too many users are already online " "(maximum is %d)\n", ERROR + MAX_SESSIONS_EXCEEDED, - config.c_nodename, config.c_maxsessions); + CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions")); return; case login_ok: cprintf("%d Password required for %s\n", @@ -99,13 +97,13 @@ void cmd_newu(char *cmdbuf) long len; char username[SIZ]; - if (config.c_auth_mode != AUTHMODE_NATIVE) { + if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) { cprintf("%d This system does not use native mode authentication.\n", ERROR + NOT_HERE); return; } - if (config.c_disable_newu) { + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d Self-service user account creation " "is disabled on this system.\n", ERROR + NOT_HERE); return; @@ -118,7 +116,8 @@ void cmd_newu(char *cmdbuf) if (CC->nologin) { cprintf("%d %s: Too many users are already online (maximum is %d)\n", ERROR + MAX_SESSIONS_EXCEEDED, - config.c_nodename, config.c_maxsessions); + CtdlGetConfigStr("c_nodename"), CtdlGetConfigInt("c_maxsessions")); + return; } extract_token(username, cmdbuf, 0, '|', sizeof username); strproc(username); @@ -231,7 +230,7 @@ void cmd_creu(char *cmdbuf) } else if (a == ERROR + ALREADY_EXISTS) { cprintf("%d '%s' already exists.\n", ERROR + ALREADY_EXISTS, username); return; - } else if ( (config.c_auth_mode != AUTHMODE_NATIVE) && (a == ERROR + NO_SUCH_USER) ) { + } else if ( (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) && (a == ERROR + NO_SUCH_USER) ) { cprintf("%d User accounts are not created within Citadel in host authentication mode.\n", ERROR + NO_SUCH_USER); return; @@ -241,23 +240,19 @@ void cmd_creu(char *cmdbuf) } - /* * get user parameters */ void cmd_getu(char *cmdbuf) { - if (CtdlAccessCheck(ac_logged_in)) return; CtdlGetUser(&CC->user, CC->curr_user); - cprintf("%d 80|24|%d|\n", - CIT_OK, - (CC->user.flags & US_USER_SET) - ); + cprintf("%d 80|24|%d|\n", CIT_OK, (CC->user.flags & US_USER_SET)); } + /* * set user parameters */ @@ -371,7 +366,7 @@ void cmd_invt_kick(char *iuser, int op) { return; } - if (!strncasecmp(CC->room.QRname, config.c_baseroom, + if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) { cprintf("%d Can't add/remove users from this room.\n", ERROR + NOT_HERE); @@ -424,7 +419,7 @@ void cmd_gnur(char *argbuf) return; } - if ((CitControl.MMflags & MM_VALID) == 0) { + if ((CtdlGetConfigInt("MMflags") & MM_VALID) == 0) { cprintf("%d There are no unvalidated users.\n", CIT_OK); return; } @@ -452,13 +447,12 @@ void cmd_gnur(char *argbuf) */ begin_critical_section(S_CONTROL); - get_control(); - CitControl.MMflags = CitControl.MMflags & (~MM_VALID); - put_control(); + int flags; + flags = CtdlGetConfigInt("MMflags"); + flags = flags & (~MM_VALID); + CtdlSetConfigInt("MMflags", flags); end_critical_section(S_CONTROL); cprintf("%d *** End of registration.\n", CIT_OK); - - } @@ -534,9 +528,9 @@ void cmd_chek(char *argbuf) regis = 1; if (CC->user.axlevel >= AxAideU) { - get_control(); - if (CitControl.MMflags & MM_VALID) + if (CtdlGetConfigInt("MMflags") & MM_VALID) { vali = 1; + } } /* check for mail */ diff --git a/citadel/modules/eventclient/serv_eventclient.c b/citadel/modules/eventclient/serv_eventclient.c index f7e286a9a..55d6fe6f2 100644 --- a/citadel/modules/eventclient/serv_eventclient.c +++ b/citadel/modules/eventclient/serv_eventclient.c @@ -1,19 +1,13 @@ /* - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -53,9 +47,8 @@ #include "server.h" #include "citserver.h" #include "support.h" - #include "ctdl_module.h" - +#include "config.h" #include "event_client.h" #include "serv_curl.h" @@ -154,7 +147,7 @@ gotstatus(int nnrun) EVCURLM_syslog(LOG_DEBUG, "request complete\n"); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); ev_io_stop(event_base, &IO->recv_event); ev_io_stop(event_base, &IO->send_event); @@ -188,6 +181,7 @@ gotstatus(int nnrun) curl_slist_free_all(IO->HttpReq.headers); + IO->HttpReq.headers = NULL; msta = curl_multi_remove_handle(global.mhnd, chnd); if (msta) EVCURL_syslog(LOG_ERR, @@ -289,7 +283,7 @@ gotdata(void *data, size_t size, size_t nmemb, void *cglobal) { IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ); } - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); return CurlFillStrBuf_callback(data, size, nmemb, @@ -350,7 +344,7 @@ gotwatchsock(CURL *easy, } SetEVState(IO, eCurlGotIO); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); Action = ""; switch (action) @@ -477,13 +471,13 @@ int evcurl_init(AsyncIO *IO) OPT(WRITEDATA, (void *)IO); OPT(ERRORBUFFER, IO->HttpReq.errdesc); - if ((!IsEmptyStr(config.c_ip_addr)) - && (strcmp(config.c_ip_addr, "*")) - && (strcmp(config.c_ip_addr, "::")) - && (strcmp(config.c_ip_addr, "0.0.0.0")) + if ((!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "*")) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "::")) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "0.0.0.0")) ) { - OPT(INTERFACE, config.c_ip_addr); + OPT(INTERFACE, CtdlGetConfigStr("c_ip_addr")); } #ifdef CURLOPT_HTTP_CONTENT_DECODING @@ -509,10 +503,11 @@ static void IOcurl_abort_shutdown_callback(struct ev_loop *loop, return; SetEVState(IO, eCurlShutdown); - IO->Now = ev_now(event_base); + IO->CitContext->lastcmd = IO->Now = ev_now(event_base); EVCURL_syslog(LOG_DEBUG, "EVENT Curl: %s\n", __FUNCTION__); curl_slist_free_all(IO->HttpReq.headers); + IO->HttpReq.headers = NULL; msta = curl_multi_remove_handle(global.mhnd, IO->HttpReq.chnd); if (msta) { @@ -530,6 +525,7 @@ static void IOcurl_abort_shutdown_callback(struct ev_loop *loop, assert(IO->ShutdownAbort); IO->ShutdownAbort(IO); } + eNextState evcurl_handle_start(AsyncIO *IO) { @@ -655,7 +651,7 @@ static void QueueEventAddCallback(EV_P_ ev_async *w, int revents) Ctx = h->IO->CitContext; become_session(Ctx); - h->IO->Now = Now; + h->IO->CitContext->lastcmd = h->IO->Now = Now; switch (h->EvAttch(h->IO)) { case eReadMore: @@ -805,7 +801,7 @@ static void DBQueueEventAddCallback(EV_P_ ev_async *w, int revents) IOID = h->IO->ID; if (h->IO->StartDB == 0.0) h->IO->StartDB = Now; - h->IO->Now = Now; + h->IO->CitContext->lastcmd = h->IO->Now = Now; SetEVState(h->IO, eDBAttach); Ctx = h->IO->CitContext; diff --git a/citadel/modules/expire/expire_policy.c b/citadel/modules/expire/expire_policy.c index bc4b772a7..76c6acb44 100644 --- a/citadel/modules/expire/expire_policy.c +++ b/citadel/modules/expire/expire_policy.c @@ -1,6 +1,6 @@ /* * Functions which manage expire policy for rooms - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -40,7 +40,6 @@ #include "support.h" #include "msgbase.h" #include "citserver.h" - #include "ctdl_module.h" #include "user_ops.h" @@ -71,15 +70,16 @@ void GetExpirePolicy(struct ExpirePolicy *epbuf, struct ctdlroom *qrbuf) { * If there is a default policy for mailbox rooms, return it */ if (qrbuf->QRflags & QR_MAILBOX) { - if (config.c_mbxep.expire_mode != 0) { - memcpy(epbuf, &config.c_mbxep, - sizeof(struct ExpirePolicy)); + if (CtdlGetConfigInt("c_mbxep_mode") != 0) { + epbuf->expire_mode = CtdlGetConfigInt("c_mbxep_mode"); + epbuf->expire_value = CtdlGetConfigInt("c_mbxep_value"); return; } } /* Otherwise, fall back on the system default */ - memcpy(epbuf, &config.c_ep, sizeof(struct ExpirePolicy)); + epbuf->expire_mode = CtdlGetConfigInt("c_ep_mode"); + epbuf->expire_value = CtdlGetConfigInt("c_ep_value"); } @@ -91,23 +91,22 @@ void cmd_gpex(char *argbuf) { struct floor *fl; char which[128]; + memset(&exp, 0, sizeof(struct ExpirePolicy)); extract_token(which, argbuf, 0, '|', sizeof which); - if (!strcasecmp(which, strof(roompolicy))|| - !strcasecmp(which, "room")) { /* Deprecated version */ + if (!strcasecmp(which, strof(roompolicy)) || !strcasecmp(which, "room")) { memcpy(&exp, &CC->room.QRep, sizeof(struct ExpirePolicy)); } - else if (!strcasecmp(which, strof(floorpolicy))|| - !strcasecmp(which, "floor")) { /* Deprecated version */ + else if (!strcasecmp(which, strof(floorpolicy)) || !strcasecmp(which, "floor")) { fl = CtdlGetCachedFloor(CC->room.QRfloor); memcpy(&exp, &fl->f_ep, sizeof(struct ExpirePolicy)); } - else if (!strcasecmp(which, strof(mailboxespolicy))|| - !strcasecmp(which, "mailboxes")) {/* Deprecated version */ - memcpy(&exp, &config.c_mbxep, sizeof(struct ExpirePolicy)); + else if (!strcasecmp(which, strof(mailboxespolicy)) || !strcasecmp(which, "mailboxes")) { + exp.expire_mode = CtdlGetConfigInt("c_mbxep_mode"); + exp.expire_value = CtdlGetConfigInt("c_mbxep_value"); } - else if (!strcasecmp(which, strof(sitepolicy))|| - !strcasecmp(which, "site")) {/* Deprecated version */ - memcpy(&exp, &config.c_ep, sizeof(struct ExpirePolicy)); + else if (!strcasecmp(which, strof(sitepolicy)) || !strcasecmp(which, "site")) { + exp.expire_mode = CtdlGetConfigInt("c_ep_mode"); + exp.expire_value = CtdlGetConfigInt("c_ep_value"); } else { cprintf("%d Invalid keyword \"%s\"\n", ERROR + ILLEGAL_VALUE, which); @@ -136,9 +135,8 @@ void cmd_spex(char *argbuf) { return; } - if ( (!strcasecmp(which, strof(roompolicy))) - || (!strcasecmp(which, "room")) - ) { + if ((!strcasecmp(which, strof(roompolicy))) || (!strcasecmp(which, "room"))) + { if (!is_room_aide()) { cprintf("%d Higher access required.\n", ERROR + HIGHER_ACCESS_REQUIRED); return; @@ -160,9 +158,8 @@ void cmd_spex(char *argbuf) { return; } - if ( (!strcasecmp(which, strof(floorpolicy))) - || (!strcasecmp(which, "floor")) - ) { + if ((!strcasecmp(which, strof(floorpolicy))) || (!strcasecmp(which, "floor"))) + { lgetfloor(&flbuf, CC->room.QRfloor); memcpy(&flbuf.f_ep, &exp, sizeof(struct ExpirePolicy)); lputfloor(&flbuf, CC->room.QRfloor); @@ -170,25 +167,22 @@ void cmd_spex(char *argbuf) { return; } - else if ( (!strcasecmp(which, strof(mailboxespolicy))) - || (!strcasecmp(which, "mailboxes")) - ) { - memcpy(&config.c_mbxep, &exp, sizeof(struct ExpirePolicy)); - put_config(); + else if ((!strcasecmp(which, strof(mailboxespolicy))) || (!strcasecmp(which, "mailboxes"))) + { + CtdlSetConfigInt("c_mbxep_mode", exp.expire_mode); + CtdlSetConfigInt("c_mbxep_value", exp.expire_value); cprintf("%d Default expire policy for mailboxes set.\n", CIT_OK); return; } - else if ( (!strcasecmp(which, strof(sitepolicy))) - || (!strcasecmp(which, "site")) - ) { + else if ((!strcasecmp(which, strof(sitepolicy))) || (!strcasecmp(which, "site"))) + { if (exp.expire_mode == EXPIRE_NEXTLEVEL) { - cprintf("%d Invalid policy (no higher level)\n", - ERROR + ILLEGAL_VALUE); + cprintf("%d Invalid policy (no higher level)\n", ERROR + ILLEGAL_VALUE); return; } - memcpy(&config.c_ep, &exp, sizeof(struct ExpirePolicy)); - put_config(); + CtdlSetConfigInt("c_ep_mode", exp.expire_mode); + CtdlSetConfigInt("c_ep_value", exp.expire_value); cprintf("%d Site expire policy has been updated.\n", CIT_OK); return; } diff --git a/citadel/modules/expire/serv_expire.c b/citadel/modules/expire/serv_expire.c index 583b86dd5..76bd626fb 100644 --- a/citadel/modules/expire/serv_expire.c +++ b/citadel/modules/expire/serv_expire.c @@ -3,7 +3,7 @@ * * You might also see this module affectionately referred to as the DAP (the Dreaded Auto-Purger). * - * Copyright (c) 1988-2011 by citadel.org (Art Cancro, Wilifried Goesgens, and others) + * Copyright (c) 1988-2015 by citadel.org (Art Cancro, Wilifried Goesgens, and others) * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -15,11 +15,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * * A brief technical discussion: * * Several of the purge operations found in this module operate in two @@ -197,7 +192,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { for (a=0; acm_fields[eTimestamp]); CM_Free(msg); @@ -312,11 +307,11 @@ void DoPurgeRooms(struct ctdlroom *qrbuf, void *data) { if (qrbuf->QRmtime <= (time_t)0) return; /* If no room purge time is set, be safe and don't purge */ - if (config.c_roompurge < 0) return; + if (CtdlGetConfigLong("c_roompurge") < 0) return; /* Otherwise, check the date of last modification */ age = time(NULL) - (qrbuf->QRmtime); - purge_secs = (time_t)config.c_roompurge * (time_t)86400; + purge_secs = CtdlGetConfigLong("c_roompurge") * 86400; if (purge_secs <= (time_t)0) return; syslog(LOG_DEBUG, "<%s> is <%ld> seconds old", qrbuf->QRname, (long)age); if (age > purge_secs) do_purge = 1; @@ -417,10 +412,10 @@ void do_user_purge(struct ctdluser *us, void *data) { /* Set purge time; if the user overrides the system default, use it */ if (us->USuserpurge > 0) { - purge_time = ((time_t)us->USuserpurge) * 86400L; + purge_time = ((time_t)us->USuserpurge) * 86400; } else { - purge_time = ((time_t)config.c_userpurge) * 86400L; + purge_time = CtdlGetConfigLong("c_userpurge") * 86400; } /* The default rule is to not purge. */ @@ -429,7 +424,7 @@ void do_user_purge(struct ctdluser *us, void *data) { /* If the user hasn't called in two months and expiring of accounts is turned on, his/her account * has expired, so purge the record. */ - if (config.c_userpurge > 0) + if (CtdlGetConfigLong("c_userpurge") > 0) { now = time(NULL); if ((now - us->lastcall) > purge_time) purge = 1; @@ -528,7 +523,7 @@ int PurgeUsers(void) { syslog(LOG_DEBUG, "PurgeUsers() called"); users_not_purged = 0; - switch(config.c_auth_mode) { + switch(CtdlGetConfigInt("c_auth_mode")) { case AUTHMODE_NATIVE: ForEachUser(do_user_purge, NULL); break; @@ -536,8 +531,7 @@ int PurgeUsers(void) { ForEachUser(do_uid_user_purge, NULL); break; default: - syslog(LOG_DEBUG, "User purge for auth mode %d is not implemented.", - config.c_auth_mode); + syslog(LOG_DEBUG, "User purge for auth mode %d is not implemented.", CtdlGetConfigInt("c_auth_mode")); break; } @@ -771,7 +765,7 @@ int PurgeEuidIndexTable(void) { memcpy(&msgnum, cdbei->ptr, sizeof(long)); - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg != NULL) { CM_Free(msg); /* it still exists, so do nothing */ } @@ -870,10 +864,8 @@ void purge_databases(void) */ now = time(NULL); localtime_r(&now, &tm); - if ( - ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200)) - && (force_purge_now == 0) - ) { + if (((tm.tm_hour != CtdlGetConfigInt("c_purge_hour")) || ((now - last_purge) < 43200)) && (force_purge_now == 0)) + { return; } diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 8eafc036a..38b6ef1fa 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -8,7 +8,7 @@ * Based on bits of serv_funambol * Contact: / * - * 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 @@ -19,10 +19,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -184,7 +180,7 @@ eNotifyType extNotify_getConfigMessage(char *username, return eNone; /* No messages at all? No further action. */ } for (a = 0; a < num_msgs; ++a) { - msg = CtdlFetchMessage(msglist[a], 1); + msg = CtdlFetchMessage(msglist[a], 1, 1); if (msg != NULL) { if (!CM_IsEmpty(msg, eMsgSubject) && (strncasecmp(msg->cm_fields[eMsgSubject], @@ -279,7 +275,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) Ctx = (NotifyContext*) usrdata; - msg = CtdlFetchMessage(NotifyMsgnum, 1); + msg = CtdlFetchMessage(NotifyMsgnum, 1, 1); if (!CM_IsEmpty(msg, eExtnotify)) { Type = extNotify_getConfigMessage( @@ -295,9 +291,9 @@ void process_notify(long NotifyMsgnum, void *usrdata) { case eFunambol: snprintf(remoteurl, SIZ, "http://%s@%s:%d/%s", - config.c_funambol_auth, - config.c_funambol_host, - config.c_funambol_port, + CtdlGetConfigStr("c_funambol_auth"), + CtdlGetConfigStr("c_funambol_host"), + CtdlGetConfigInt("c_funambol_port"), FUNAMBOL_WS); notify_http_server(remoteurl, @@ -349,7 +345,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) int commandSiz; char *command; - commandSiz = sizeof(config.c_pager_program) + + commandSiz = sizeof(CtdlGetConfigStr("c_pager_program")) + strlen(PagerNo) + msg->cm_lengths[eExtnotify] + 5; @@ -358,7 +354,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) snprintf(command, commandSiz, "%s %s -u %s", - config.c_pager_program, + CtdlGetConfigStr("c_pager_program"), PagerNo, msg->cm_fields[eExtnotify]); @@ -393,8 +389,8 @@ void do_extnotify_queue(void) * don't really require extremely fine granularity here, we'll do it * with a static variable instead. */ - if (IsEmptyStr(config.c_pager_program) && - IsEmptyStr(config.c_funambol_host)) + if (IsEmptyStr(CtdlGetConfigStr("c_pager_program")) && + IsEmptyStr(CtdlGetConfigStr("c_funambol_host"))) { syslog(LOG_ERR, "No external notifiers configured on system/user\n"); @@ -472,7 +468,7 @@ int extnotify_after_mbox_save(struct CtdlMessage *msg, /* If this is private, local mail, make a copy in the * recipient's mailbox and bump the reference count. */ - if (!IsEmptyStr(config.c_funambol_host) || !IsEmptyStr(config.c_pager_program)) + if (!IsEmptyStr(CtdlGetConfigStr("c_funambol_host")) || !IsEmptyStr(CtdlGetConfigStr("c_pager_program"))) { /* Generate a instruction message for the Funambol notification * server, in the same style as the SMTP queue diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index 20246c90d..1a1099719 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -8,21 +8,15 @@ * Based on bits of the previous serv_funambol * Contact: / * - * Copyright (c) 2008-2010 + * Copyright (c) 2008-2015 * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. - * - * * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * - * - * */ #include @@ -146,8 +140,7 @@ int notify_http_server(char *remoteurl, // Do substitutions help_subst(SOAPMessage, "^notifyuser", user); - help_subst(SOAPMessage, "^syncsource", - config.c_funambol_source); + help_subst(SOAPMessage, "^syncsource", CtdlGetConfigStr("c_funambol_source")); help_subst(SOAPMessage, "^msgid", msgid); help_subst(SOAPMessage, "^msgnum", msgnumstr); @@ -182,7 +175,7 @@ int notify_http_server(char *remoteurl, } else { help_subst(remoteurl, "^notifyuser", user); - help_subst(remoteurl, "^syncsource", config.c_funambol_source); + help_subst(remoteurl, "^syncsource", CtdlGetConfigStr("c_funambol_source")); help_subst(remoteurl, "^msgid", msgid); help_subst(remoteurl, "^msgnum", msgnumstr); diff --git a/citadel/modules/fulltext/serv_fulltext.c b/citadel/modules/fulltext/serv_fulltext.c index 6288bfc9a..3709ef631 100644 --- a/citadel/modules/fulltext/serv_fulltext.c +++ b/citadel/modules/fulltext/serv_fulltext.c @@ -1,6 +1,6 @@ /* * This module handles fulltext indexing of the message base. - * Copyright (c) 2005-2011 by the citadel.org team + * Copyright (c) 2005-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -120,7 +120,7 @@ void ft_index_message(long msgnum, int op) { int tok; struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { syslog(LOG_ERR, "ft_index_message() could not load msg %ld", msgnum); return; @@ -210,7 +210,7 @@ void ft_index_message(long msgnum, int op) { */ void ft_index_msg(long msgnum, void *userdata) { - if ((msgnum > CitControl.MMfulltext) && (msgnum <= ft_newhighest)) { + if ((msgnum > CtdlGetConfigLong("MMfulltext")) && (msgnum <= ft_newhighest)) { ++ft_num_msgs; if (ft_num_msgs > ft_num_alloc) { ft_num_alloc += 1024; @@ -251,7 +251,7 @@ void do_fulltext_indexing(void) { /* * Don't do this if the site doesn't have it enabled. */ - if (!config.c_enable_fulltext) { + if (!CtdlGetConfigInt("c_enable_fulltext")) { return; } @@ -268,7 +268,10 @@ void do_fulltext_indexing(void) { * Check to see whether the fulltext index is up to date; if there * are no messages to index, don't waste any more time trying. */ - if ((CitControl.MMfulltext >= CitControl.MMhighest) && (CitControl.fulltext_wordbreaker == FT_WORDBREAKER_ID)) { + if ( + (CtdlGetConfigLong("MMfulltext") >= CtdlGetConfigLong("MMhighest")) + && (CtdlGetConfigInt("MM_fulltext_wordbreaker") == FT_WORDBREAKER_ID) + ) { return; /* nothing to do! */ } @@ -280,21 +283,20 @@ void do_fulltext_indexing(void) { * over. */ begin_critical_section(S_CONTROL); - if (CitControl.fulltext_wordbreaker != FT_WORDBREAKER_ID) { + if (CtdlGetConfigInt("MM_fulltext_wordbreaker") != FT_WORDBREAKER_ID) { syslog(LOG_DEBUG, "wb ver on disk = %d, code ver = %d", - CitControl.fulltext_wordbreaker, FT_WORDBREAKER_ID + CtdlGetConfigInt("MM_fulltext_wordbreaker"), FT_WORDBREAKER_ID ); syslog(LOG_INFO, "(re)initializing full text index"); cdb_trunc(CDB_FULLTEXT); - CitControl.MMfulltext = 0L; - put_control(); + CtdlSetConfigLong("MMfulltext", 0); } end_critical_section(S_CONTROL); /* * Now go through each room and find messages to index. */ - ft_newhighest = CitControl.MMhighest; + ft_newhighest = CtdlGetConfigLong("MMhighest"); CtdlForEachRoom(ft_index_room, NULL); /* load all msg pointers */ if (ft_num_msgs > 0) { @@ -353,9 +355,8 @@ void do_fulltext_indexing(void) { /* Save our place so we don't have to do this again */ ft_flush_cache(); begin_critical_section(S_CONTROL); - CitControl.MMfulltext = ft_newhighest; - CitControl.fulltext_wordbreaker = FT_WORDBREAKER_ID; - put_control(); + CtdlSetConfigLong("MMfulltext", ft_newhighest); + CtdlSetConfigInt("MM_fulltext_wordbreaker", FT_WORDBREAKER_ID); end_critical_section(S_CONTROL); last_index = time(NULL); @@ -455,7 +456,7 @@ void cmd_srch(char *argbuf) { if (CtdlAccessCheck(ac_logged_in)) return; - if (!config.c_enable_fulltext) { + if (!CtdlGetConfigInt("c_enable_fulltext")) { cprintf("%d Full text index is not enabled on this server.\n", ERROR + CMD_NOT_SUPPORTED); return; @@ -489,7 +490,7 @@ void ft_delete_remove(char *room, long msgnum) if (room) return; /* Remove from fulltext index */ - if (config.c_enable_fulltext) { + if (CtdlGetConfigInt("c_enable_fulltext")) { ft_index_message(msgnum, 0); } } diff --git a/citadel/modules/imap/imap_fetch.c b/citadel/modules/imap/imap_fetch.c index 3f00d3f3f..8fcd6bd81 100644 --- a/citadel/modules/imap/imap_fetch.c +++ b/citadel/modules/imap/imap_fetch.c @@ -2,21 +2,17 @@ * Implements the FETCH command in IMAP. * This is a good example of the protocol's gratuitous complexity. * - * Copyright (c) 2001-2011 by the citadel.org team + * Copyright (c) 2001-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ @@ -363,8 +359,8 @@ void imap_output_envelope_from(struct CtdlMessage *msg) { process_rfc822_addr(msg->cm_fields[erFc822Addr], user, node, name); IPutStr(user, strlen(user)); /* mailbox name (user id) */ IAPuts(" "); - if (!strcasecmp(node, config.c_nodename)) { - IPutStr(CFG_KEY(c_fqdn)); + if (!strcasecmp(node, CtdlGetConfigStr("c_nodename"))) { + IPutStr(CtdlGetConfigStr("c_fqdn"), strlen(CtdlGetConfigStr("c_fqdn"))); } else { IPutStr(node, strlen(node)); /* host name */ @@ -710,7 +706,7 @@ void imap_fetch_body(long msgnum, ConstStr item, int is_peek) { if (Imap->cached_body == NULL) { CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); loading_body_now = 1; - msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0)); + msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0), 1); } /* Now figure out what the client wants, and get it */ @@ -1085,7 +1081,7 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) { msg = NULL; } if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); body_loaded = 1; } imap_fetch_bodystructure(Imap->msgids[seq-1], @@ -1093,14 +1089,14 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) { } else if (!strcasecmp(Cmd->Params[i].Key, "ENVELOPE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 0); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1); body_loaded = 0; } imap_fetch_envelope(msg); } else if (!strcasecmp(Cmd->Params[i].Key, "INTERNALDATE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 0); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1); body_loaded = 0; } imap_fetch_internaldate(msg); diff --git a/citadel/modules/imap/imap_misc.c b/citadel/modules/imap/imap_misc.c index f4d501c9d..366526455 100644 --- a/citadel/modules/imap/imap_misc.c +++ b/citadel/modules/imap/imap_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -10,10 +10,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -341,7 +337,7 @@ void imap_append(int num_parms, ConstStr *Params) { IUnbuffer (); - client_read_blob(Imap->TransmittedMessage, literal_length, config.c_sleeping); + client_read_blob(Imap->TransmittedMessage, literal_length, CtdlGetConfigInt("c_sleeping")); if ((ret < 0) || (StrLength(Imap->TransmittedMessage) < literal_length)) { IReply("NO Read failed."); @@ -377,19 +373,15 @@ void imap_append(int num_parms, ConstStr *Params) { CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL); /* If the user is locally authenticated, FORCE the From: header to - * show up as the real sender. FIXME do we really want to do this? - * Probably should make it site-definable or even room-definable. - * - * For now, we allow "forgeries" if the room is one of the user's - * private mailboxes. + * show up as the real sender. (Configurable setting) */ if (CCC->logged_in) { - if ( ((CCC->room.QRflags & QR_MAILBOX) == 0) && (config.c_imap_keep_from == 0)) { - - CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); - } + if ( ((CCC->room.QRflags & QR_MAILBOX) == 0) && (CtdlGetConfigInt("c_imap_keep_from") == 0)) + { + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); + } } /* diff --git a/citadel/modules/imap/imap_search.c b/citadel/modules/imap/imap_search.c index cad499ceb..f1b7f73e9 100644 --- a/citadel/modules/imap/imap_search.c +++ b/citadel/modules/imap/imap_search.c @@ -1,21 +1,15 @@ /* * Implements IMAP's gratuitously complex SEARCH command. * - * Copyright (c) 2001-2012 by the citadel.org team + * Copyright (c) 2001-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "ctdl_module.h" @@ -121,7 +115,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "BCC")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -138,7 +132,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -157,14 +151,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, /* If fulltext indexing is active, on this server, * all messages have already been qualified. */ - if (config.c_enable_fulltext) { + if (CtdlGetConfigInt("c_enable_fulltext")) { match = 1; } /* Otherwise, we have to do a slow search. */ else { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -179,7 +173,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "CC")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -225,7 +219,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "FROM")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -247,7 +241,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * examining the message body. */ if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } @@ -277,7 +271,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "LARGER")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -304,7 +298,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "ON")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -334,7 +328,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -350,7 +344,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTON")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -366,7 +360,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -382,7 +376,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -398,7 +392,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -411,7 +405,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -424,7 +418,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "TEXT")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -439,7 +433,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "TO")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -571,7 +565,7 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) { * text index to disqualify messages that don't have any chance of * matching. (Only do this if the index is enabled!!) */ - if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) { + if (CtdlGetConfigInt("c_enable_fulltext")) for (i=0; i<(num_items-1); ++i) { if (!strcasecmp(itemlist[i].Key, "BODY")) { CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext"); if (fts_num_msgs > 0) { diff --git a/citadel/modules/imap/serv_imap.c b/citadel/modules/imap/serv_imap.c index 278cc7332..60584df27 100644 --- a/citadel/modules/imap/serv_imap.c +++ b/citadel/modules/imap/serv_imap.c @@ -1,7 +1,7 @@ /* * IMAP server for the Citadel system * - * Copyright (C) 2000-2011 by Art Cancro and others. + * Copyright (C) 2000-2015 by Art Cancro and others. * This code is released under the terms of the GNU General Public License. * * WARNING: the IMAP protocol is badly designed. No implementation of it @@ -17,10 +17,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -599,7 +595,7 @@ void imap_greeting(void) IAPuts("* OK ["); imap_output_capability_string(); - IAPrintf("] %s IMAP4rev1 %s ready\r\n", config.c_fqdn, CITADEL); + IAPrintf("] %s IMAP4rev1 %s ready\r\n", CtdlGetConfigStr("c_fqdn"), CITADEL); IUnbuffer(); } @@ -917,7 +913,7 @@ void imap_select(int num_parms, ConstStr *Params) IAPrintf("* %d RECENT\r\n", new); IAPrintf("* OK [UIDVALIDITY %ld] UID validity status\r\n", GLOBAL_UIDVALIDITY_VALUE); - IAPrintf("* OK [UIDNEXT %ld] Predicted next UID\r\n", CitControl.MMhighest + 1); + IAPrintf("* OK [UIDNEXT %ld] Predicted next UID\r\n", CtdlGetConfigLong("MMhighest") + 1); /* Technically, \Deleted is a valid flag, but not a permanent flag, * because we don't maintain its state across sessions. Citadel @@ -1220,7 +1216,7 @@ void imap_status(int num_parms, ConstStr *Params) IPutStr(imaproomname, len); IAPrintf(" (MESSAGES %d ", msgs); IAPrintf("RECENT %d ", new); /* Initially, new==recent */ - IAPrintf("UIDNEXT %ld ", CitControl.MMhighest + 1); + IAPrintf("UIDNEXT %ld ", CtdlGetConfigLong("MMhighest") + 1); IAPrintf("UNSEEN %d)\r\n", new); /* @@ -1675,7 +1671,7 @@ void imap_logout(int num_parms, ConstStr *Params) if (IMAP->selected) { imap_do_expunge(); /* yes, we auto-expunge at logout */ } - IAPrintf("* BYE %s logging out\r\n", config.c_fqdn); + IAPrintf("* BYE %s logging out\r\n", CtdlGetConfigStr("c_fqdn")); IReply("OK Citadel IMAP session ended."); CC->kill_me = KILLME_CLIENT_LOGGED_OUT; return; @@ -1744,10 +1740,10 @@ CTDL_MODULE_INIT(imap) if (!threading) { CtdlRegisterDebugFlagHook(HKEY("imapsrv"), SetIMAPDebugEnabled, &IMAPDebugEnabled); - CtdlRegisterServiceHook(config.c_imap_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_imap_port"), NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_imaps_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_imaps_port"), NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS); #endif CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP, PRIO_STOP + 30); diff --git a/citadel/modules/inetcfg/serv_inetcfg.c b/citadel/modules/inetcfg/serv_inetcfg.c index c37dd24fb..615a48b42 100644 --- a/citadel/modules/inetcfg/serv_inetcfg.c +++ b/citadel/modules/inetcfg/serv_inetcfg.c @@ -119,7 +119,7 @@ int inetcfg_aftersave(struct CtdlMessage *msg, recptypes *recp) { void inetcfg_init_backend(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { inetcfg_setTo(msg); CM_Free(msg); diff --git a/citadel/modules/instmsg/serv_instmsg.c b/citadel/modules/instmsg/serv_instmsg.c index 2c28600b6..988478537 100644 --- a/citadel/modules/instmsg/serv_instmsg.c +++ b/citadel/modules/instmsg/serv_instmsg.c @@ -1,7 +1,7 @@ /* * This module handles instant messaging between users. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -11,6 +11,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include "sysdep.h" #include #include @@ -174,7 +175,7 @@ void cmd_gexp(char *argbuf) { (long)ptr->timestamp, /* time sent */ ptr->flags, /* flags */ ptr->sender, /* sender of msg */ - config.c_nodename, /* static for now (and possibly deprecated) */ + CtdlGetConfigStr("c_nodename"), /* static for now (and possibly deprecated) */ ptr->sender_email /* email or jid of sender */ ); @@ -478,7 +479,7 @@ void flush_individual_conversation(struct imlog *im) { } CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetAsFieldSB(msg, eMesageText, &FullMsgBuf); /* we own this memory now */ /* Start with usernums[1] because it's guaranteed to be higher than usernums[0], @@ -503,9 +504,9 @@ void flush_individual_conversation(struct imlog *im) { } /* Finally, if we're logging instant messages globally, do that now. */ - if (!IsEmptyStr(config.c_logpages)) { - CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS); - CtdlSaveMsgPointerInRoom(config.c_logpages, msgnum, 0, NULL); + if (!IsEmptyStr(CtdlGetConfigStr("c_logpages"))) { + CtdlCreateRoom(CtdlGetConfigStr("c_logpages"), 3, "", 0, 1, 1, VIEW_BBS); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_logpages"), msgnum, 0, NULL); } } diff --git a/citadel/modules/managesieve/serv_managesieve.c b/citadel/modules/managesieve/serv_managesieve.c index 23f5f263c..6bfe11264 100644 --- a/citadel/modules/managesieve/serv_managesieve.c +++ b/citadel/modules/managesieve/serv_managesieve.c @@ -6,7 +6,7 @@ * as this draft expires with this writing, you might need to search for * the new one. * - * Copyright (c) 2007-2012 by the citadel.org team + * Copyright (c) 2007-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -651,7 +651,7 @@ CTDL_MODULE_INIT(managesieve) { if (!threading) { - CtdlRegisterServiceHook(config.c_managesieve_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_managesieve_port"), NULL, managesieve_greeting, managesieve_command_loop, diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index 97181a1c6..831732682 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -1,7 +1,7 @@ /* * This module dumps and/or loads the Citadel database in XML format. * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -16,8 +16,7 @@ * Explanation of tags: * * 0% nothing - * 1% finished exporting config - * 2% finished exporting control + * 2% finished exporting configuration * 7% finished exporting users * 12% finished exporting openids * 17% finished exporting rooms @@ -61,7 +60,6 @@ #include "database.h" #include "msgbase.h" #include "user_ops.h" -#include "control.h" #include "euidindex.h" #include "ctdl_module.h" @@ -73,9 +71,9 @@ FILE *migr_global_message_list; int total_msgs = 0; -/* - * Code which implements the export appears in this section - */ +/****************************************************************************** + * Code which implements the export appears in this section * + ******************************************************************************/ /* * Output a string to the client with these characters escaped: & < > @@ -90,19 +88,19 @@ void xml_strout(char *str) { while (*c != 0) { if (*c == '\"') { - client_write(""", 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); @@ -116,10 +114,10 @@ void xml_strout(char *str) { * Export a user record as XML */ void migr_export_users_backend(struct ctdluser *buf, void *data) { - client_write("\n", 7); + client_write(HKEY("\n")); cprintf("%d\n", buf->version); cprintf("%ld\n", (long)buf->uid); - client_write("", 12); xml_strout(buf->password); client_write("\n", 14); + client_write(HKEY("")); xml_strout(buf->password); client_write(HKEY("\n")); cprintf("%u\n", buf->flags); cprintf("%ld\n", buf->timescalled); cprintf("%ld\n", buf->posted); @@ -127,8 +125,8 @@ void migr_export_users_backend(struct ctdluser *buf, void *data) { cprintf("%ld\n", buf->usernum); cprintf("%ld\n", (long)buf->lastcall); cprintf("%d\n", buf->USuserpurge); - client_write("", 12); xml_strout(buf->fullname); client_write("\n", 14); - client_write("\n", 8); + client_write(HKEY("")); xml_strout(buf->fullname); client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -144,17 +142,17 @@ void migr_export_room_msg(long msgnum, void *userdata) { void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { - client_write("\n", 7); - client_write("", 8); xml_strout(buf->QRname); client_write("\n", 10); - client_write("", 10); xml_strout(buf->QRpasswd); client_write("\n", 12); + client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(buf->QRname); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(buf->QRpasswd); client_write(HKEY("\n")); cprintf("%ld\n", buf->QRroomaide); cprintf("%ld\n", buf->QRhighest); cprintf("%ld\n", (long)buf->QRgen); cprintf("%u\n", buf->QRflags); if (buf->QRflags & QR_DIRECTORY) { - client_write("", 11); + client_write(HKEY("")); xml_strout(buf->QRdirname); - client_write("\n", 13); + client_write(HKEY("\n")); } cprintf("%ld\n", buf->QRinfo); cprintf("%d\n", buf->QRfloor); @@ -165,17 +163,17 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { cprintf("%d\n", buf->QRorder); cprintf("%u\n", buf->QRflags2); cprintf("%d\n", buf->QRdefaultview); - client_write("\n", 8); + client_write(HKEY("\n")); /* message list goes inside this tag */ CtdlGetRoom(&CC->room, buf->QRname); - client_write("", 15); - client_write("", 8); xml_strout(CC->room.QRname); client_write("\n", 10); - client_write("", 11); + client_write(HKEY("")); + client_write(HKEY("")); xml_strout(CC->room.QRname); client_write(HKEY("\n")); + client_write(HKEY("")); CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_export_room_msg, NULL); - client_write("\n", 13); - client_write("\n", 17); + client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -220,16 +218,16 @@ void migr_export_floors(void) { int i; for (i=0; i < MAXFLOORS; ++i) { - client_write("\n", 8); + client_write(HKEY("\n")); cprintf("%d\n", i); CtdlGetFloor(&qfbuf, i); buf = &qfbuf; cprintf("%u\n", buf->f_flags); - client_write("", 8); xml_strout(buf->f_name); client_write("\n", 10); + client_write(HKEY("")); xml_strout(buf->f_name); client_write(HKEY("\n")); cprintf("%d\n", buf->f_ref_count); cprintf("%d\n", buf->f_ep.expire_mode); cprintf("%d\n", buf->f_ep.expire_value); - client_write("\n", 9); + client_write(HKEY("\n")); } } @@ -268,29 +266,29 @@ void migr_export_visits(void) { sizeof(visit) : cdbv->len)); cdb_free(cdbv); - client_write("\n", 8); + client_write(HKEY("\n")); cprintf("%ld\n", vbuf.v_roomnum); cprintf("%ld\n", vbuf.v_roomgen); cprintf("%ld\n", vbuf.v_usernum); - client_write("", 8); + client_write(HKEY("")); if ( (!IsEmptyStr(vbuf.v_seen)) && (is_sequence_set(vbuf.v_seen)) ) { xml_strout(vbuf.v_seen); } else { cprintf("%ld", vbuf.v_lastseen); } - client_write("", 9); + client_write(HKEY("")); if ( (!IsEmptyStr(vbuf.v_answered)) && (is_sequence_set(vbuf.v_answered)) ) { - client_write("", 12); + client_write(HKEY("")); xml_strout(vbuf.v_answered); - client_write("\n", 14); + client_write(HKEY("\n")); } cprintf("%u\n", vbuf.v_flags); cprintf("%d\n", vbuf.v_view); - client_write("\n", 9); + client_write(HKEY("\n")); } } @@ -319,16 +317,18 @@ void migr_export_message(long msgnum) { /* Ok, here we go ... */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 0); if (msg == NULL) return; /* fail silently */ - client_write("\n", 10); + client_write(HKEY("\n")); GetMetaData(&smi, msgnum); cprintf("%ld\n", msgnum); cprintf("%d\n", smi.meta_refcount); - client_write("", 23); xml_strout(smi.meta_content_type); client_write("\n", 25); + cprintf("%ld\n", smi.meta_rfc822_length); + client_write(HKEY("")); xml_strout(smi.meta_content_type); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(smi.mimetype); client_write(HKEY("\n")); - client_write("", 10); + client_write(HKEY("")); CtdlSerializeMessage(&smr, msg); CM_Free(msg); @@ -351,8 +351,8 @@ void migr_export_message(long msgnum) { free(smr.ser); - client_write("\n", 12); - client_write("\n", 11); + client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -365,20 +365,43 @@ void migr_export_openids(void) { cdb_rewind(CDB_OPENID); while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) { if (cdboi->len > sizeof(long)) { - client_write("\n", 9); + client_write(HKEY("\n")); memcpy(&usernum, cdboi->ptr, sizeof(long)); snprintf(url, sizeof url, "%s", (cdboi->ptr)+sizeof(long) ); - client_write("", 9); + client_write(HKEY("")); xml_strout(url); - client_write("\n", 11); + client_write(HKEY("\n")); cprintf("%ld\n", usernum); - client_write("\n", 10); + client_write(HKEY("\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("", 2); + xml_strout(value); + client_write("\n", 10); + cdb_free(cdbcfg); + } +} + + void migr_export_messages(void) { @@ -425,101 +448,15 @@ void migr_do_export(void) { cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS); Ctx->dont_term = 1; - client_write("\n", 40); - client_write("\n", 23); + client_write(HKEY("\n")); + client_write(HKEY("\n")); cprintf("%d\n", REV_LEVEL); cprintf("%d\n", 0); - /* export the config file (this is done using x-macros) */ - client_write("\n", 9); - client_write("", 12); xml_strout(config.c_nodename); client_write("\n", 14); - client_write("", 8); xml_strout(config.c_fqdn); client_write("\n", 10); - client_write("", 13); xml_strout(config.c_humannode); client_write("\n", 15); - client_write("", 12); xml_strout(config.c_phonenum); client_write("\n", 14); - cprintf("%d\n", config.c_ctdluid); - 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); - client_write("", 12); xml_strout(config.c_twitroom); client_write("\n", 14); - client_write("", 14); xml_strout(config.c_moreprompt); client_write("\n", 16); - cprintf("%d\n", config.c_restrict); - client_write("", 17); xml_strout(config.c_site_location); client_write("\n", 19); - client_write("", 10); xml_strout(config.c_sysadm); client_write("\n", 12); - cprintf("%d\n", config.c_maxsessions); - client_write("", 11); xml_strout(config.c_ip_addr); client_write("\n", 13); - cprintf("%d\n", config.c_port_number); - cprintf("%d\n", config.c_ep.expire_mode); - cprintf("%d\n", config.c_ep.expire_value); - cprintf("%d\n", config.c_userpurge); - cprintf("%d\n", config.c_roompurge); - client_write("", 12); xml_strout(config.c_logpages); client_write("\n", 14); - 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", config.c_enable_fulltext); - client_write("", 12); xml_strout(config.c_baseroom); client_write("\n", 14); - client_write("", 12); xml_strout(config.c_aideroom); client_write("\n", 14); - cprintf("%d\n", config.c_purge_hour); - cprintf("%d\n", config.c_mbxep.expire_mode); - cprintf("%d\n", config.c_mbxep.expire_value); - client_write("", 13); xml_strout(config.c_ldap_host); client_write("\n", 15); - cprintf("%d\n", config.c_ldap_port); - client_write("", 16); xml_strout(config.c_ldap_base_dn); client_write("\n", 18); - client_write("", 16); xml_strout(config.c_ldap_bind_dn); client_write("\n", 18); - client_write("", 16); xml_strout(config.c_ldap_bind_pw); client_write("\n", 18); - 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_auto_cull); - cprintf("%d\n", config.c_allow_spoofing); - cprintf("%d\n", config.c_journal_email); - cprintf("%d\n", config.c_journal_pubmsgs); - client_write("", 16); xml_strout(config.c_journal_dest); client_write("\n", 18); - client_write("", 20); xml_strout(config.c_default_cal_zone); client_write("\n", 22); - cprintf("%d\n", config.c_pftcpdict_port); - cprintf("%d\n", config.c_managesieve_port); - cprintf("%d\n", config.c_auth_mode); - client_write("", 17); xml_strout(config.c_funambol_host); client_write("\n", 19); - cprintf("%d\n", config.c_funambol_port); - client_write("", 19); xml_strout(config.c_funambol_source); client_write("\n", 21); - client_write("", 17); xml_strout(config.c_funambol_auth); client_write("\n", 19); - cprintf("%d\n", config.c_rbl_at_greeting); - client_write("", 15); xml_strout(config.c_master_user); client_write("\n", 17); - client_write("", 15); xml_strout(config.c_master_pass); client_write("\n", 17); - client_write("", 17); xml_strout(config.c_pager_program); client_write("\n", 19); - 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_nntp_port); - cprintf("%d\n", config.c_nntps_port); - client_write("\n", 10); - cprintf("%d\n", 1); - - /* Export the control file */ - get_control(); - client_write("\n", 10); - cprintf("%ld\n", CitControl.MMhighest); - cprintf("%u\n", CitControl.MMflags); - cprintf("%ld\n", CitControl.MMnextuser); - cprintf("%ld\n", CitControl.MMnextroom); - cprintf("%d\n", CitControl.version); - client_write("\n", 11); + /* export the configuration database */ + migr_export_configs(); cprintf("%d\n", 2); - + if (Ctx->kill_me == 0) migr_export_users(); cprintf("%d\n", 7); if (Ctx->kill_me == 0) migr_export_openids(); @@ -531,22 +468,22 @@ void migr_do_export(void) { if (Ctx->kill_me == 0) migr_export_visits(); cprintf("%d\n", 25); if (Ctx->kill_me == 0) migr_export_messages(); - client_write("\n", 24); + client_write(HKEY("\n")); cprintf("%d\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 tag pair? */ @@ -614,105 +551,9 @@ void migr_xml_start(void *data, const char *el, const char **attr) { memset(&smi, 0, sizeof (struct MetaData)); import_msgnum = 0; } - -} - - -int migr_config(void *data, const char *el) -{ - if (!strcasecmp(el, "c_nodename")) SET_CFGSTRBUF(c_nodename, migr_chardata); - else if (!strcasecmp(el, "c_fqdn")) SET_CFGSTRBUF(c_fqdn, migr_chardata); - else if (!strcasecmp(el, "c_humannode")) SET_CFGSTRBUF(c_humannode, migr_chardata); - else if (!strcasecmp(el, "c_phonenum")) SET_CFGSTRBUF(c_phonenum, migr_chardata); - else if (!strcasecmp(el, "c_ctdluid")) config.c_ctdluid = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_creataide")) config.c_creataide = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_sleeping")) config.c_sleeping = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_initax")) config.c_initax = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_regiscall")) config.c_regiscall = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_twitdetect")) config.c_twitdetect = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_twitroom")) SET_CFGSTRBUF(c_twitroom, migr_chardata); - else if (!strcasecmp(el, "c_moreprompt")) SET_CFGSTRBUF(c_moreprompt, migr_chardata); - else if (!strcasecmp(el, "c_restrict")) config.c_restrict = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_site_location")) SET_CFGSTRBUF(c_site_location, migr_chardata); - else if (!strcasecmp(el, "c_sysadm")) SET_CFGSTRBUF(c_sysadm, migr_chardata); - else if (!strcasecmp(el, "c_maxsessions")) config.c_maxsessions = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ip_addr")) SET_CFGSTRBUF(c_ip_addr, migr_chardata); - else if (!strcasecmp(el, "c_port_number")) config.c_port_number = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ep_expire_mode")) config.c_ep.expire_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ep_expire_value")) config.c_ep.expire_value = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_userpurge")) config.c_userpurge = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_roompurge")) config.c_roompurge = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_logpages")) SET_CFGSTRBUF(c_logpages, migr_chardata); - else if (!strcasecmp(el, "c_createax")) config.c_createax = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_maxmsglen")) config.c_maxmsglen = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_min_workers")) config.c_min_workers = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_max_workers")) config.c_max_workers = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_port")) config.c_pop3_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_smtp_port")) config.c_smtp_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_rfc822_strict_from")) config.c_rfc822_strict_from = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_aide_zap")) config.c_aide_zap = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_imap_port")) config.c_imap_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_net_freq")) config.c_net_freq = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_disable_newu")) config.c_disable_newu = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_enable_fulltext")) config.c_enable_fulltext = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_baseroom")) SET_CFGSTRBUF(c_baseroom, migr_chardata); - else if (!strcasecmp(el, "c_aideroom")) SET_CFGSTRBUF(c_aideroom, migr_chardata); - else if (!strcasecmp(el, "c_purge_hour")) config.c_purge_hour = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_mbxep_expire_mode")) config.c_mbxep.expire_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_mbxep_expire_value")) config.c_mbxep.expire_value = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ldap_host")) SET_CFGSTRBUF(c_ldap_host, migr_chardata); - else if (!strcasecmp(el, "c_ldap_port")) config.c_ldap_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ldap_base_dn")) SET_CFGSTRBUF(c_ldap_base_dn, migr_chardata); - else if (!strcasecmp(el, "c_ldap_bind_dn")) SET_CFGSTRBUF(c_ldap_bind_dn, migr_chardata); - else if (!strcasecmp(el, "c_ldap_bind_pw")) SET_CFGSTRBUF(c_ldap_bind_pw, migr_chardata); - else if (!strcasecmp(el, "c_msa_port")) config.c_msa_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_imaps_port")) config.c_imaps_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3s_port")) config.c_pop3s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_smtps_port")) config.c_smtps_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_auto_cull")) config.c_auto_cull = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_allow_spoofing")) config.c_allow_spoofing = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_email")) config.c_journal_email = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_pubmsgs")) config.c_journal_pubmsgs = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_dest")) SET_CFGSTRBUF(c_journal_dest, migr_chardata); - else if (!strcasecmp(el, "c_default_cal_zone")) SET_CFGSTRBUF(c_default_cal_zone, migr_chardata); - else if (!strcasecmp(el, "c_pftcpdict_port")) config.c_pftcpdict_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_managesieve_port")) config.c_managesieve_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_auth_mode")) config.c_auth_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_funambol_host")) SET_CFGSTRBUF(c_funambol_host, migr_chardata); - else if (!strcasecmp(el, "c_funambol_port")) config.c_funambol_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_funambol_source")) SET_CFGSTRBUF(c_funambol_source, migr_chardata); - else if (!strcasecmp(el, "c_funambol_auth")) SET_CFGSTRBUF(c_funambol_auth, migr_chardata); - else if (!strcasecmp(el, "c_rbl_at_greeting")) config.c_rbl_at_greeting = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_master_user")) SET_CFGSTRBUF(c_master_user, migr_chardata); - else if (!strcasecmp(el, "c_master_pass")) SET_CFGSTRBUF(c_master_pass, migr_chardata); - else if (!strcasecmp(el, "c_pager_program")) SET_CFGSTRBUF(c_pager_program, migr_chardata); - else if (!strcasecmp(el, "c_imap_keep_from")) config.c_imap_keep_from = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_xmpp_c2s_port")) config.c_xmpp_c2s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_xmpp_s2s_port")) config.c_xmpp_s2s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_fetch")) config.c_pop3_fetch = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_fastest")) config.c_pop3_fastest = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_spam_flag_only")) config.c_spam_flag_only = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_nntp_port")) config.c_nntp_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_nntps_port")) config.c_nntps_port = atoi(ChrPtr(migr_chardata)); - else return 0; - return 1; /* Found above...*/ -} - -int migr_controlrecord(void *data, const char *el) -{ - if (!strcasecmp(el, "control_highest")) CitControl.MMhighest = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_flags")) CitControl.MMflags = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_nextuser")) CitControl.MMnextuser = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_nextroom")) CitControl.MMnextroom = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_version")) CitControl.version = atoi(ChrPtr(migr_chardata)); - - else if (!strcasecmp(el, "control")) { - CitControl.MMfulltext = (-1L); /* always flush */ - put_control(); - syslog(LOG_INFO, "Completed import of control record\n"); + else if (!strcasecmp(el, "config")) { + syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG START ELEMENT FIXME\033\0m"); } - else return 0; - return 1; } @@ -794,6 +635,8 @@ int migr_visitrecord(void *data, const char *el) else return 0; return 1; } + + void migr_xml_end(void *data, const char *el) { const char *ptr; @@ -817,20 +660,12 @@ void migr_xml_end(void *data, const char *el) /*** CONFIG ***/ - if (!strcasecmp(el, "config")) { - config.c_enable_fulltext = 0; /* always disable */ - put_config(); - syslog(LOG_INFO, "Completed import of server configuration\n"); + if (!strcasecmp(el, "config")) + { + syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG END ELEMENT FIXME\033\0m"); + CtdlSetConfigInt("c_enable_fulltext", 0); /* always disable FIXME put this somewhere more appropriate */ } - else if ((!strncasecmp(el, HKEY("c_"))) && - migr_config(data, el)) - ; /* Nothing to do anymore */ - - /*** CONTROL ***/ - else if ((!strncasecmp(el, HKEY("control"))) && - migr_controlrecord(data, el)) - ; /* Nothing to do anymore */ /*** USER ***/ else if ((!strncasecmp(el, HKEY("u_"))) && migr_userrecord(data, el)) @@ -931,31 +766,44 @@ void migr_xml_end(void *data, const char *el) /*** MESSAGES ***/ - else if (!strcasecmp(el, "msg_msgnum")) import_msgnum = atol(ChrPtr(migr_chardata)); + else if (!strcasecmp(el, "msg_msgnum")) smi.meta_msgnum = import_msgnum = atol(ChrPtr(migr_chardata)); else if (!strcasecmp(el, "msg_meta_refcount")) smi.meta_refcount = atoi(ChrPtr(migr_chardata)); + else if (!strcasecmp(el, "msg_meta_rfc822_length")) smi.meta_rfc822_length = atoi(ChrPtr(migr_chardata)); else if (!strcasecmp(el, "msg_meta_content_type")) safestrncpy(smi.meta_content_type, ChrPtr(migr_chardata), sizeof smi.meta_content_type); + else if (!strcasecmp(el, "msg_mimetype")) safestrncpy(smi.mimetype, ChrPtr(migr_chardata), sizeof smi.mimetype); else if (!strcasecmp(el, "msg_text")) { + long rc; + struct CtdlMessage *msg; FlushStrBuf(migr_MsgData); - StrBufDecodeBase64To(migr_MsgData, migr_MsgData); - - cdb_store(CDB_MSGMAIN, - &import_msgnum, - sizeof(long), - ChrPtr(migr_MsgData), - StrLength(migr_MsgData) + 1); - - smi.meta_msgnum = import_msgnum; - PutMetaData(&smi); + StrBufDecodeBase64To(migr_chardata, migr_MsgData); + + msg = CtdlDeserializeMessage(import_msgnum, -1, + ChrPtr(migr_MsgData), + StrLength(migr_MsgData)); + if (msg != NULL) { + rc = CtdlSaveThisMessage(msg, import_msgnum, 0); + if (rc == 0) { + PutMetaData(&smi); + } + CM_Free(msg); + } + else { + rc = -1; + } syslog(LOG_INFO, - "Imported message #%ld, size=%d, refcount=%d, content-type: %s\n", + "%s message #%ld, size=%d, refcount=%d, bodylength=%ld, content-type: %s / %s \n", + (rc!= 0)?"failed to import ":"Imported ", import_msgnum, StrLength(migr_MsgData), smi.meta_refcount, - smi.meta_content_type); + smi.meta_rfc822_length, + smi.meta_content_type, + smi.mimetype); + memset(&smi, 0, sizeof(smi)); } /*** MORE GENERAL STUFF ***/ @@ -1022,6 +870,9 @@ void migr_do_import(void) { +/****************************************************************************** + * Dispatcher, Common code * + ******************************************************************************/ /* * Dump out the pathnames of directories which can be copied "as is" */ @@ -1038,12 +889,200 @@ void migr_do_listdirs(void) { cprintf("000\n"); } +/****************************************************************************** + * Repair database integrity * + ******************************************************************************/ -/* - * Common code appears in this section - */ +StrBuf *PlainMessageBuf = NULL; +HashList *UsedMessageIDS = NULL; + +int migr_restore_message_metadata(long msgnum, int refcount) +{ + CitContext *CCC = MyContext(); + struct MetaData smi; + struct CtdlMessage *msg; + char *mptr = NULL; + + /* We can use a static buffer here because there will never be more than + * one of this operation happening at any given time, and it's really best + * to just keep it allocated once instead of torturing malloc/free. + * Call this function with msgnum "-1" to free the buffer when finished. + */ + static int encoded_alloc = 0; + static char *encoded_msg = NULL; + if (msgnum < 0) { + if ((encoded_alloc == 0) && (encoded_msg != NULL)) { + free(encoded_msg); + encoded_alloc = 0; + encoded_msg = NULL; + // todo FreeStrBuf(&PlainMessageBuf); PlainMessageBuf = NULL; + } + return 0; + } + + if (PlainMessageBuf == NULL) { + PlainMessageBuf = NewStrBufPlain(NULL, 10*SIZ); + } + /* Ok, here we go ... */ + + msg = CtdlFetchMessage(msgnum, 1, 0); + if (msg == NULL) { + return 1; + } + + GetMetaData(&smi, msgnum); + smi.meta_msgnum = msgnum; + smi.meta_refcount = refcount; + + /* restore the content type from the message body: */ + mptr = bmstrcasestr(msg->cm_fields[eMesageText], "Content-type:"); + if (mptr != NULL) { + char *aptr; + safestrncpy(smi.meta_content_type, &mptr[13], sizeof smi.meta_content_type); + striplt(smi.meta_content_type); + aptr = smi.meta_content_type; + while (!IsEmptyStr(aptr)) { + if ((*aptr == ';') + || (*aptr == ' ') + || (*aptr == 13) + || (*aptr == 10)) { + memset(aptr, 0, sizeof(smi.meta_content_type) - (aptr - smi.meta_content_type)); + } + else aptr++; + } + } + + CCC->redirect_buffer = PlainMessageBuf; + CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR); + smi.meta_rfc822_length = StrLength(CCC->redirect_buffer); + CCC->redirect_buffer = NULL; + + + syslog(LOG_INFO, + "Setting message #%ld meta data to: refcount=%d, bodylength=%ld, content-type: %s / %s \n", + smi.meta_msgnum, + smi.meta_refcount, + smi.meta_rfc822_length, + smi.meta_content_type, + smi.mimetype); + + PutMetaData(&smi); + + CM_Free(msg); + + return 0; +} + +void migr_check_room_msg(long msgnum, void *userdata) { + fprintf(migr_global_message_list, "%ld %s\n", msgnum, CC->room.QRname); +} + + +void migr_check_rooms_backend(struct ctdlroom *buf, void *data) { + + /* message list goes inside this tag */ + + CtdlGetRoom(&CC->room, buf->QRname); + CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_check_room_msg, NULL); +} + +void RemoveMessagesFromRooms(StrBuf *RoomNameVec, long msgnum) { + struct MetaData smi; + const char *Pos = NULL; + StrBuf *oneRoom = NewStrBuf(); + + syslog(LOG_INFO, "removing message pointer %ld from these rooms: %s", msgnum, ChrPtr(RoomNameVec)); + + while (Pos != StrBufNOTNULL){ + StrBufExtract_NextToken(oneRoom, RoomNameVec, &Pos, '|'); + CtdlDeleteMessages(ChrPtr(oneRoom), &msgnum, 1, ""); + }; + GetMetaData(&smi, msgnum); + TDAP_AdjRefCount(msgnum, -smi.meta_refcount); +} + +void migr_do_restore_meta(void) { + char buf[SIZ]; + int failGetMessage; + long msgnum; + int lastnum = 0; + int refcount = 0; + CitContext *Ctx; + char *prn; + StrBuf *RoomNames; + char cmd[SIZ]; + + migr_global_message_list = fopen(migr_tempfilename1, "w"); + if (migr_global_message_list != NULL) { + CtdlForEachRoom(migr_check_rooms_backend, NULL); + fclose(migr_global_message_list); + } + + /* + * Process the 'global' message list. (Sort it and remove dups. + * Dups are ok because a message may be in more than one room, but + * this will be handled by exporting the reference count, not by + * exporting the message multiple times.) + */ + snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2); + if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno); + + RoomNames = NewStrBuf(); + Ctx = CC; + migr_global_message_list = fopen(migr_tempfilename2, "r"); + if (migr_global_message_list != NULL) { + syslog(LOG_INFO, "Opened %s\n", migr_tempfilename1); + while ((Ctx->kill_me == 0) && + (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) { + msgnum = atol(buf); + if (msgnum == 0L) + continue; + if (lastnum == 0) { + lastnum = msgnum; + } + prn = strchr(buf, ' '); + if (lastnum != msgnum) { + failGetMessage = migr_restore_message_metadata(lastnum, refcount); + if (failGetMessage) { + RemoveMessagesFromRooms(RoomNames, lastnum); + } + refcount = 1; + lastnum = msgnum; + if (prn != NULL) + StrBufPlain(RoomNames, prn + 1, -1); + StrBufTrim(RoomNames); + } + else { + if (prn != NULL) { + if (StrLength(RoomNames) > 0) + StrBufAppendBufPlain(RoomNames, HKEY("|"), 0); + StrBufAppendBufPlain(RoomNames, prn, -1, 1); + StrBufTrim(RoomNames); + } + refcount ++; + } + lastnum = msgnum; + } + failGetMessage = migr_restore_message_metadata(msgnum, refcount); + if (failGetMessage) { + RemoveMessagesFromRooms(RoomNames, lastnum); + } + fclose(migr_global_message_list); + } + + migr_restore_message_metadata(-1L, -1); /* This frees the encoding buffer */ + cprintf("%d system analysis completed", CIT_OK); + Ctx->kill_me = 1; +} + + + + +/****************************************************************************** + * Dispatcher, Common code * + ******************************************************************************/ void cmd_migr(char *cmdbuf) { char cmd[32]; @@ -1051,6 +1090,7 @@ void cmd_migr(char *cmdbuf) { if (CtdlTrySingleUser()) { + CtdlDisableHouseKeeping(); CtdlMakeTempFileName(migr_tempfilename1, sizeof migr_tempfilename1); CtdlMakeTempFileName(migr_tempfilename2, sizeof migr_tempfilename2); @@ -1064,13 +1104,17 @@ void cmd_migr(char *cmdbuf) { else if (!strcasecmp(cmd, "listdirs")) { migr_do_listdirs(); } + else if (!strcasecmp(cmd, "restoremeta")) { + migr_do_restore_meta(); + } else { cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE); } unlink(migr_tempfilename1); unlink(migr_tempfilename2); - + + CtdlEnableHouseKeeping(); CtdlEndSingleUser(); } else @@ -1079,6 +1123,9 @@ void cmd_migr(char *cmdbuf) { } } +/****************************************************************************** + * Module Hook * + ******************************************************************************/ CTDL_MODULE_INIT(migrate) { diff --git a/citadel/modules/mrtg/serv_mrtg.c b/citadel/modules/mrtg/serv_mrtg.c index 6abd80cf1..0402461db 100644 --- a/citadel/modules/mrtg/serv_mrtg.c +++ b/citadel/modules/mrtg/serv_mrtg.c @@ -5,21 +5,15 @@ * is available at http://www.mrtg.org that can fetch data using external * scripts. This module supplies data in the format expected by MRTG. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -78,7 +72,7 @@ void mrtg_output(long value1, long value2) { cprintf("%ld\n", value2); cprintf("%d days, %d hours, %d minutes\n", uptime_days, uptime_hours, uptime_minutes); - cprintf("%s\n", config.c_humannode); + cprintf("%s\n", CtdlGetConfigStr("c_humannode")); cprintf("000\n"); } @@ -116,7 +110,7 @@ void mrtg_users(void) { * Volume of messages submitted */ void mrtg_messages(void) { - mrtg_output(CitControl.MMhighest, 0L); + mrtg_output(CtdlGetConfigLong("MMhighest"), 0); } diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index c4038869f..9ca6ba5a9 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -2,7 +2,7 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -218,7 +218,7 @@ void network_deliver_digest(SpoolControl *sc) /* Where do we want bounces and other noise to be heard? * Surely not the list members! */ - snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn); + snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn")); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[digestrecp]), NULL, 0); @@ -366,7 +366,7 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char /* Where do we want bounces and other noise to be heard? * Surely not the list members! */ - snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn); + snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn")); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0); @@ -403,8 +403,8 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon */ ok_to_participate = 0; if (!CM_IsEmpty(msg, eNodeName)) { - if (!strcasecmp(msg->cm_fields[eNodeName], - config.c_nodename)) { + if (!strcasecmp(msg->cm_fields[eNodeName], CtdlGetConfigStr("c_nodename"))) + { ok_to_participate = 1; } @@ -595,7 +595,7 @@ void network_spool_msg(long msgnum, sc = (SpoolControl *)userdata; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { diff --git a/citadel/modules/network/serv_netspool.c b/citadel/modules/network/serv_netspool.c index 0edb1f11e..eeb35ba71 100644 --- a/citadel/modules/network/serv_netspool.c +++ b/citadel/modules/network/serv_netspool.c @@ -2,15 +2,15 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * ** NOTE ** A word on the S_NETCONFIGS semaphore: * This is a fairly high-level type of critical section. It ensures that no @@ -93,6 +93,86 @@ #endif +/* + * Bounce a message back to the sender + */ +void network_bounce(struct CtdlMessage **pMsg, char *reason) +{ + struct CitContext *CCC = CC; + char buf[SIZ]; + char bouncesource[SIZ]; + char recipient[SIZ]; + recptypes *valid = NULL; + char force_room[ROOMNAMELEN]; + static int serialnum = 0; + long len; + struct CtdlMessage *msg = *pMsg; + *pMsg = NULL; + QNM_syslog(LOG_DEBUG, "entering network_bounce()\n"); + + if (msg == NULL) return; + + snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, CtdlGetConfigStr("c_nodename")); + + /* + * Give it a fresh message ID + */ + len = snprintf(buf, sizeof(buf), + "%ld.%04lx.%04x@%s", + (long)time(NULL), + (long)getpid(), + ++serialnum, + CtdlGetConfigStr("c_fqdn")); + + CM_SetField(msg, emessageId, buf, len); + + /* + * FIXME ... right now we're just sending a bounce; we really want to + * include the text of the bounced message. + */ + CM_SetField(msg, eMesageText, reason, strlen(reason)); + msg->cm_format_type = 0; + + /* + * Turn the message around + */ + CM_FlushField(msg, eRecipient); + CM_FlushField(msg, eDestination); + + len = snprintf(recipient, sizeof(recipient), "%s@%s", + msg->cm_fields[eAuthor], + msg->cm_fields[eNodeName]); + + CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); + + Netmap_AddMe(msg, HKEY("unknown_user")); + + /* Now submit the message */ + valid = validate_recipients(recipient, NULL, 0); + if (valid != NULL) if (valid->num_error != 0) { + free_recipients(valid); + valid = NULL; + } + if ( (valid == NULL) || (!strcasecmp(recipient, bouncesource)) ) { + strcpy(force_room, CtdlGetConfigStr("c_aideroom")); + } + else { + strcpy(force_room, ""); + } + if ( (valid == NULL) && IsEmptyStr(force_room) ) { + strcpy(force_room, CtdlGetConfigStr("c_aideroom")); + } + CtdlSubmitMsg(msg, valid, force_room, 0); + + /* Clean up */ + if (valid != NULL) free_recipients(valid); + CM_Free(msg); + QNM_syslog(LOG_DEBUG, "leaving network_bounce()\n"); +} + + void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG) { RoomNetCfgLine *nptr; @@ -168,10 +248,10 @@ void Netmap_AddMe(struct CtdlMessage *msg, const char *defl, long defllen) if (CM_IsEmpty(msg, eMessagePath)) { CM_SetField(msg, eMessagePath, defl, defllen); } - node_len = configlen.c_nodename; + node_len = strlen(CtdlGetConfigStr("c_nodename")); if (node_len >= SIZ) node_len = SIZ - 1; - memcpy(buf, config.c_nodename, node_len); + memcpy(buf, CtdlGetConfigStr("c_nodename"), node_len); buf[node_len] = '!'; buf[node_len + 1] = '\0'; CM_PrependToField(msg, eMessagePath, buf, node_len + 1); @@ -307,7 +387,7 @@ void CalcListID(SpoolControl *sc) StrBufAppendBufPlain(sc->ListID, HKEY("room_"), 0); StrBufAppendBuf(sc->ListID, RoomName, 0); StrBufAppendBufPlain(sc->ListID, HKEY("."), 0); - StrBufAppendBufPlain(sc->ListID, config.c_fqdn, -1, 0); + StrBufAppendBufPlain(sc->ListID, CtdlGetConfigStr("c_fqdn"), -1, 0); /* * this used to be: * roomname @@ -325,7 +405,7 @@ void CalcListID(SpoolControl *sc) StrBufAppendBufPlain(sc->Users[roommailalias], HKEY("room_"), 0); StrBufAppendBuf(sc->Users[roommailalias], RoomName, 0); StrBufAppendBufPlain(sc->Users[roommailalias], HKEY("@"), 0); - StrBufAppendBufPlain(sc->Users[roommailalias], config.c_fqdn, -1, 0); + StrBufAppendBufPlain(sc->Users[roommailalias], CtdlGetConfigStr("c_fqdn"), -1, 0); StrBufLowerCase(sc->Users[roommailalias]); } @@ -375,7 +455,7 @@ void network_spoolout_room(SpoolControl *sc) else { snprintf(buf, sizeof buf, "room_%s@%s", - CCC->room.QRname, config.c_fqdn); + CCC->room.QRname, CtdlGetConfigStr("c_fqdn")); } for (i=0; buf[i]; ++i) { @@ -434,6 +514,53 @@ void network_spoolout_room(SpoolControl *sc) } } + +/* + * Check the use table. This is a list of messages which have recently + * arrived on the system. It is maintained and queried to prevent the same + * message from being entered into the database multiple times if it happens + * to arrive multiple times by accident. + */ +int network_usetable(struct CtdlMessage *msg) +{ + StrBuf *msgid; + struct CitContext *CCC = CC; + time_t now; + + /* Bail out if we can't generate a message ID */ + if ((msg == NULL) || CM_IsEmpty(msg, emessageId)) + { + return(0); + } + + /* Generate the message ID */ + msgid = NewStrBufPlain(CM_KEY(msg, emessageId)); + if (haschar(ChrPtr(msgid), '@') == 0) { + StrBufAppendBufPlain(msgid, HKEY("@"), 0); + if (!CM_IsEmpty(msg, eNodeName)) { + StrBufAppendBufPlain(msgid, CM_KEY(msg, eNodeName), 0); + } + else { + FreeStrBuf(&msgid); + return(0); + } + } + now = time(NULL); + if (CheckIfAlreadySeen("Networker Import", + msgid, + now, 0, + eUpdate, + CCC->cs_pid, 0) != 0) + { + FreeStrBuf(&msgid); + return(1); + } + FreeStrBuf(&msgid); + + return(0); +} + + /* * Process a buffer containing a single message from a single file * from the inbound queue @@ -485,7 +612,7 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, /* Check for message routing */ if (!CM_IsEmpty(msg, eDestination)) { - if (strcasecmp(msg->cm_fields[eDestination], config.c_nodename)) { + if (strcasecmp(msg->cm_fields[eDestination], CtdlGetConfigStr("c_nodename"))) { /* route the message */ Buf = NewStrBufPlain(CM_KEY(msg,eDestination)); @@ -530,10 +657,9 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, else { /* invalid destination node name */ FreeStrBuf(&Buf); - network_bounce(msg, + network_bounce(&msg, "A message you sent could not be delivered due to an invalid destination node" " name. Please check the address and try sending the message again.\n"); - msg = NULL; return; } @@ -570,10 +696,9 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, else if (!CM_IsEmpty(msg, eRecipient)) { recp = validate_recipients(msg->cm_fields[eRecipient], NULL, 0); if (recp != NULL) if (recp->num_error != 0) { - network_bounce(msg, + network_bounce(&msg, "A message you sent could not be delivered due to an invalid address.\n" "Please check the address and try sending the message again.\n"); - msg = NULL; free_recipients(recp); QNM_syslog(LOG_DEBUG, "Bouncing message due to invalid recipient address.\n"); return; diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index 9fa82734e..1d843b461 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -2,15 +2,15 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * ** NOTE ** A word on the S_NETCONFIGS semaphore: * This is a fairly high-level type of critical section. It ensures that no @@ -96,54 +96,6 @@ typedef struct __roomlists { struct RoomProcList *rplist = NULL; - -/* - * Check the use table. This is a list of messages which have recently - * arrived on the system. It is maintained and queried to prevent the same - * message from being entered into the database multiple times if it happens - * to arrive multiple times by accident. - */ -int network_usetable(struct CtdlMessage *msg) -{ - StrBuf *msgid; - struct CitContext *CCC = CC; - time_t now; - - /* Bail out if we can't generate a message ID */ - if ((msg == NULL) || CM_IsEmpty(msg, emessageId)) - { - return(0); - } - - /* Generate the message ID */ - msgid = NewStrBufPlain(CM_KEY(msg, emessageId)); - if (haschar(ChrPtr(msgid), '@') == 0) { - StrBufAppendBufPlain(msgid, HKEY("@"), 0); - if (!CM_IsEmpty(msg, eNodeName)) { - StrBufAppendBufPlain(msgid, CM_KEY(msg, eNodeName), 0); - } - else { - FreeStrBuf(&msgid); - return(0); - } - } - now = time(NULL); - if (CheckIfAlreadySeen("Networker Import", - msgid, - now, 0, - eCheckUpdate, - CCC->cs_pid, 0) != 0) - { - FreeStrBuf(&msgid); - return(1); - } - FreeStrBuf(&msgid); - - return(0); -} - - - /* * Send the *entire* contents of the current room to one specific network node, * ignoring anything we know about which messages have already undergone @@ -340,87 +292,6 @@ void destroy_network_queue_room_locked (void) } - -/* - * Bounce a message back to the sender - */ -void network_bounce(struct CtdlMessage *msg, char *reason) -{ - struct CitContext *CCC = CC; - char buf[SIZ]; - char bouncesource[SIZ]; - char recipient[SIZ]; - recptypes *valid = NULL; - char force_room[ROOMNAMELEN]; - static int serialnum = 0; - long len; - - QNM_syslog(LOG_DEBUG, "entering network_bounce()\n"); - - if (msg == NULL) return; - - snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, config.c_nodename); - - /* - * Give it a fresh message ID - */ - len = snprintf(buf, sizeof(buf), - "%ld.%04lx.%04x@%s", - (long)time(NULL), - (long)getpid(), - ++serialnum, - config.c_fqdn); - - CM_SetField(msg, emessageId, buf, len); - - /* - * FIXME ... right now we're just sending a bounce; we really want to - * include the text of the bounced message. - */ - CM_SetField(msg, eMesageText, reason, strlen(reason)); - msg->cm_format_type = 0; - - /* - * Turn the message around - */ - CM_FlushField(msg, eRecipient); - CM_FlushField(msg, eDestination); - - len = snprintf(recipient, sizeof(recipient), "%s@%s", - msg->cm_fields[eAuthor], - msg->cm_fields[eNodeName]); - - CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); - - Netmap_AddMe(msg, HKEY("unknown_user")); - - /* Now submit the message */ - valid = validate_recipients(recipient, NULL, 0); - if (valid != NULL) if (valid->num_error != 0) { - free_recipients(valid); - valid = NULL; - } - if ( (valid == NULL) || (!strcasecmp(recipient, bouncesource)) ) { - strcpy(force_room, config.c_aideroom); - } - else { - strcpy(force_room, ""); - } - if ( (valid == NULL) && IsEmptyStr(force_room) ) { - strcpy(force_room, config.c_aideroom); - } - CtdlSubmitMsg(msg, valid, force_room, 0); - - /* Clean up */ - if (valid != NULL) free_recipients(valid); - CM_Free(msg); - QNM_syslog(LOG_DEBUG, "leaving network_bounce()\n"); -} - - - /* * network_do_queue() * @@ -442,10 +313,11 @@ void network_do_queue(void) * Run the full set of processing tasks no more frequently * than once every n seconds */ - if ( (time(NULL) - last_run) < config.c_net_freq ) { + if ( (time(NULL) - last_run) < CtdlGetConfigLong("c_net_freq") ) + { full_processing = 0; syslog(LOG_DEBUG, "Network full processing in %ld seconds.\n", - config.c_net_freq - (time(NULL)- last_run) + CtdlGetConfigLong("c_net_freq") - (time(NULL)- last_run) ); } diff --git a/citadel/modules/network/serv_network.h b/citadel/modules/network/serv_network.h index 7de793905..e23918e18 100644 --- a/citadel/modules/network/serv_network.h +++ b/citadel/modules/network/serv_network.h @@ -39,6 +39,4 @@ void load_network_filter_list(void); void network_queue_room(struct ctdlroom *, void *); ////void destroy_network_queue_room(void); -void network_bounce(struct CtdlMessage *msg, char *reason); -int network_usetable(struct CtdlMessage *msg); diff --git a/citadel/modules/networkclient/serv_networkclient.c b/citadel/modules/networkclient/serv_networkclient.c index 34ea669e5..0fe749d33 100644 --- a/citadel/modules/networkclient/serv_networkclient.c +++ b/citadel/modules/networkclient/serv_networkclient.c @@ -2,15 +2,15 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * ** NOTE ** A word on the S_NETCONFIGS semaphore: * This is a fairly high-level type of critical section. It ensures that no @@ -256,7 +256,7 @@ eNextState NWC_SendAuth(AsyncNetworker *NW) SetNWCState(IO, eNWCVSAuth); /* We're talking to the correct node. Now identify ourselves. */ StrBufPrintf(NW->IO.SendBuf.Buf, "NETP %s|%s\n", - config.c_nodename, + CtdlGetConfigStr("c_nodename"), ChrPtr(NW->secret)); NWC_DBG_SEND(); return eSendReply; @@ -1117,10 +1117,11 @@ void network_do_clientqueue(void) * Run the full set of processing tasks no more frequently * than once every n seconds */ - if ( (time(NULL) - last_run) < config.c_net_freq ) { + if ( (time(NULL) - last_run) < CtdlGetConfigLong("c_net_freq") ) + { full_processing = 0; syslog(LOG_DEBUG, "Network full processing in %ld seconds.\n", - config.c_net_freq - (time(NULL)- last_run) + CtdlGetConfigLong("c_net_freq") - (time(NULL)- last_run) ); } diff --git a/citadel/modules/nntp/serv_nntp.c b/citadel/modules/nntp/serv_nntp.c index b5b91db79..dee22bdfc 100644 --- a/citadel/modules/nntp/serv_nntp.c +++ b/citadel/modules/nntp/serv_nntp.c @@ -1,7 +1,7 @@ // // NNTP server module (RFC 3977) // -// Copyright (c) 2014 by the citadel.org team +// Copyright (c) 2014-2015 by the citadel.org team // // This program is open source software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 3. @@ -200,7 +200,7 @@ void nntp_greeting(void) } // Display the standard greeting - cprintf("200 %s NNTP Citadel server is not finished yet\r\n", config.c_fqdn); + cprintf("200 %s NNTP Citadel server is not finished yet\r\n", CtdlGetConfigStr("c_fqdn")); } @@ -284,7 +284,7 @@ void nntp_authinfo_user(const char *username) cprintf("482 Already logged in\r\n"); return; case login_too_many_users: - cprintf("481 Too many users are already online (maximum is %d)\r\n", config.c_maxsessions); + cprintf("481 Too many users are already online (maximum is %d)\r\n", CtdlGetConfigInt("c_maxsessions")); return; case login_ok: cprintf("381 Password required for %s\r\n", CC->curr_user); @@ -977,7 +977,7 @@ void nntp_xover_backend(long msgnum, void *userdata) { if (msgnum < lr->lo) return; if ((lr->hi != 0) && (msgnum > lr->hi)) return; - struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0); + struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { return; } @@ -1178,7 +1178,7 @@ CTDL_MODULE_INIT(nntp) { if (!threading) { - CtdlRegisterServiceHook(config.c_nntp_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntp_port"), NULL, nntp_greeting, nntp_command_loop, @@ -1186,7 +1186,7 @@ CTDL_MODULE_INIT(nntp) CitadelServiceNNTP); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_nntps_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntps_port"), NULL, nntps_greeting, nntp_command_loop, diff --git a/citadel/modules/openid/serv_openid_rp.c b/citadel/modules/openid/serv_openid_rp.c index d43448d8d..748da3bed 100644 --- a/citadel/modules/openid/serv_openid_rp.c +++ b/citadel/modules/openid/serv_openid_rp.c @@ -1,7 +1,7 @@ /* * This is an implementation of OpenID 2.0 relying party support in stateless mode. * - * Copyright (c) 2007-2012 by the citadel.org team + * Copyright (c) 2007-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -211,7 +211,7 @@ void cmd_oidl(char *argbuf) { struct cdbdata *cdboi; long usernum = 0L; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -243,7 +243,7 @@ void cmd_oida(char *argbuf) { long usernum; struct ctdluser usbuf; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -278,7 +278,7 @@ void cmd_oida(char *argbuf) { void cmd_oidc(char *argbuf) { ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -311,7 +311,7 @@ void cmd_oidd(char *argbuf) { int this_is_mine = 0; long usernum = 0L; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -358,8 +358,8 @@ int openid_create_user_via_ax(StrBuf *claimed_id, HashList *sreg_keys) const char *Key; void *Value; - if (config.c_auth_mode != AUTHMODE_NATIVE) return(1); - if (config.c_disable_newu) return(2); + if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) return(1); + if (CtdlGetConfigInt("c_disable_newu")) return(2); if (CC->logged_in) return(3); HashPos *HashPos = GetNewHashPos(sreg_keys, 0); @@ -553,12 +553,12 @@ CURL *ctdl_openid_curl_easy_init(char *errmsg) { curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); /* die after 30 seconds */ if ( - (!IsEmptyStr(config.c_ip_addr)) - && (strcmp(config.c_ip_addr, "*")) - && (strcmp(config.c_ip_addr, "::")) - && (strcmp(config.c_ip_addr, "0.0.0.0")) + (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "*")) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "::")) + && (strcmp(CtdlGetConfigStr("c_ip_addr"), "0.0.0.0")) ) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr); + curl_easy_setopt(curl, CURLOPT_INTERFACE, CtdlGetConfigStr("c_ip_addr")); } return(curl); @@ -832,7 +832,7 @@ void cmd_oids(char *argbuf) { ctdl_openid *oiddata; int discovery_succeeded = 0; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -963,7 +963,7 @@ void cmd_oidf(char *argbuf) { void *Value; ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data; - if (config.c_disable_newu) + if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); @@ -1108,7 +1108,7 @@ void cmd_oidf(char *argbuf) { * If this system does not allow self-service new user registration, the * remaining modes do not apply, so fail here and now. */ - else if (config.c_disable_newu) { + else if (CtdlGetConfigInt("c_disable_newu")) { cprintf("fail\n"); syslog(LOG_DEBUG, "Creating user failed due to local policy"); } @@ -1169,7 +1169,7 @@ CTDL_MODULE_INIT(openid_rp) // evcurl call this for us. curl_global_init(CURL_GLOBAL_ALL); /* Only enable the OpenID command set when native mode authentication is in use. */ - if (config.c_auth_mode == AUTHMODE_NATIVE) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_NATIVE) { CtdlRegisterProtoHook(cmd_oids, "OIDS", "Setup OpenID authentication"); CtdlRegisterProtoHook(cmd_oidf, "OIDF", "Finalize OpenID authentication"); CtdlRegisterProtoHook(cmd_oidl, "OIDL", "List OpenIDs associated with an account"); diff --git a/citadel/modules/pop3/serv_pop3.c b/citadel/modules/pop3/serv_pop3.c index d3e3e0b50..132301263 100644 --- a/citadel/modules/pop3/serv_pop3.c +++ b/citadel/modules/pop3/serv_pop3.c @@ -1,21 +1,15 @@ /* * POP3 service for the Citadel system * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * Current status of standards conformance: * @@ -721,14 +715,14 @@ CTDL_MODULE_INIT(pop3) { CtdlRegisterDebugFlagHook(HKEY("pop3srv"), SetPOP3DebugEnabled, &POP3DebugEnabled); - CtdlRegisterServiceHook(config.c_pop3_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_pop3_port"), NULL, pop3_greeting, pop3_command_loop, NULL, CitadelServicePop3); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_pop3s_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_pop3s_port"), NULL, pop3s_greeting, pop3_command_loop, diff --git a/citadel/modules/pop3client/serv_pop3client.c b/citadel/modules/pop3client/serv_pop3client.c index 950436dd8..700c57419 100644 --- a/citadel/modules/pop3client/serv_pop3client.c +++ b/citadel/modules/pop3client/serv_pop3client.c @@ -1,7 +1,7 @@ /* * Consolidate mail from remote POP3 accounts. * - * Copyright (c) 2007-2011 by the citadel.org team + * Copyright (c) 2007-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -12,10 +12,6 @@ * 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 @@ -418,6 +414,7 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) const char *HKey; void *vData; pop3aggr *RecvMsg = (pop3aggr *) IO->Data; + time_t seenstamp = 0; SetPOP3State(IO, eUseTable); @@ -431,13 +428,15 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) if (server_shutting_down) return eAbort; - if (CheckIfAlreadySeen("POP3 Item Seen", - RecvMsg->CurrMsg->MsgUID, - EvGetNow(IO), - EvGetNow(IO) - USETABLE_ANTIEXPIRE, - eCheckUpdate, - IO->ID, CCID) - != 0) + RecvMsg->CurrMsg = (FetchItem*)vData; + + seenstamp = CheckIfAlreadySeen("POP3 Item Seen", + RecvMsg->CurrMsg->MsgUID, + EvGetNow(IO), + EvGetNow(IO) - USETABLE_ANTIEXPIRE, + eCheckUpdate, + IO->ID, CCID); + if (seenstamp != 0) { /* Item has already been seen */ RecvMsg->CurrMsg->NeedFetch = 0; @@ -539,6 +538,8 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg) SetPOP3State(IO, eGetMsg); + EVP3CM_syslog(LOG_DEBUG, "fast forwarding to the next unknown message"); + RecvMsg->CurrMsg = NULL; while ((RecvMsg->Pos != NULL) && GetNextHashPos(RecvMsg->MsgNumbers, @@ -551,6 +552,7 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg) if ((RecvMsg->CurrMsg != NULL ) && (RecvMsg->CurrMsg->NeedFetch == 1)) { + EVP3CM_syslog(LOG_DEBUG, "fetching next"); /* Message has not been seen. * Tell the server to fetch the message... */ StrBufPrintf(RecvMsg->IO.SendBuf.Buf, @@ -559,6 +561,7 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg) return eReadMessage; } else { + EVP3CM_syslog(LOG_DEBUG, "no more messages to fetch."); RecvMsg->State = ReadQuitState; return POP3_C_DispatchWriteDone(&RecvMsg->IO); } @@ -572,7 +575,7 @@ eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg) if (!POP3C_OK) return eTerminateConnection; RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."), RecvMsg->CurrMsg->MSGSize, - config.c_maxmsglen, + CtdlGetConfigLong("c_maxmsglen"), NULL, -1, 1); @@ -652,7 +655,7 @@ eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg) AsyncIO *IO = &RecvMsg->IO; POP3C_DBG_READ(); RecvMsg->State = GetOneMessageIDState; - return eReadMessage; + return POP3_C_DispatchWriteDone(&RecvMsg->IO); } eNextState POP3C_SendQuit(pop3aggr *RecvMsg) @@ -1148,10 +1151,10 @@ void pop3client_scan(void) { become_session(&pop3_client_CC); - if (config.c_pop3_fastest < config.c_pop3_fetch) - fastest_scan = config.c_pop3_fastest; + if (CtdlGetConfigLong("c_pop3_fastest") < CtdlGetConfigLong("c_pop3_fetch")) + fastest_scan = CtdlGetConfigLong("c_pop3_fastest"); else - fastest_scan = config.c_pop3_fetch; + fastest_scan = CtdlGetConfigLong("c_pop3_fetch"); /* * Run POP3 aggregation no more frequently than once every n seconds @@ -1184,7 +1187,7 @@ void pop3client_scan(void) { /* if ((palist->interval && time(NULL) > (last_run + palist->interval)) - || (time(NULL) > last_run + config.c_pop3_fetch)) + || (time(NULL) > last_run + CtdlGetConfigLong("c_pop3_fetch"))) pop3_do_fetching(palist->roomname, palist->pop3host, palist->pop3user, palist->pop3pass, palist->keep); pptr = palist; diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index cc03230c9..697b63b47 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -1,7 +1,7 @@ /* * Bring external RSS feeds into rooms. * - * Copyright (c) 2007-2012 by the citadel.org team + * Copyright (c) 2007-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -365,7 +365,7 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg) CM_SetField(&SaveMsg->Msg, eAuthor, HKEY("rss")); } - CM_SetField(&SaveMsg->Msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(&SaveMsg->Msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); if (SaveMsg->title != NULL) { long len; char *Sbj; @@ -685,7 +685,7 @@ eNextState RSSAggregator_AnalyseReply(AsyncIO *IO) guid, EvGetNow(IO), EvGetNow(IO) - USETABLE_ANTIEXPIRE, - eCheckUpdate, + eUpdate, CCID, IO->ID) != 0) { diff --git a/citadel/modules/rwho/serv_rwho.c b/citadel/modules/rwho/serv_rwho.c index 4c2e28cdc..5329bc70a 100644 --- a/citadel/modules/rwho/serv_rwho.c +++ b/citadel/modules/rwho/serv_rwho.c @@ -214,6 +214,70 @@ void cmd_rwho(char *argbuf) { cprintf("000\n"); } +/* + * check for async io jobs that are stuck (didn't ping back for 10 mins) + */ +void dead_io_check(void) { + struct CitContext *nptr; + int nContexts, i; + char real_room[ROOMNAMELEN]; + + /* So that we don't keep the context list locked for a long time + * we create a copy of it first + */ + nptr = CtdlGetContextArray(&nContexts) ; + if (!nptr) + { + /* Couldn't malloc so we have to bail but stick to the protocol */ + return; + } + + time_t now = time(NULL); + time_t idle; + + for (i=0; imsgnum, 1); + msg = CtdlFetchMessage(cs->msgnum, 1, 1); if (msg == NULL) { SV_syslog(LOG_WARNING, "REDIRECT failed: unable to fetch msg %ld", cs->msgnum); free_recipients(valid); @@ -553,7 +553,7 @@ void sieve_do_msg(long msgnum, void *userdata) { /* * Make sure you include message body so you can get those second-level headers ;) */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; /* @@ -626,7 +626,7 @@ void sieve_do_msg(long msgnum, void *userdata) { } if (haschar(my.envelope_from, '@') == 0) { strcat(my.envelope_from, "@"); - strcat(my.envelope_from, config.c_fqdn); + strcat(my.envelope_from, CtdlGetConfigStr("c_fqdn")); } /* Keep track of the envelope-to address (use body-to if not found) */ @@ -652,7 +652,7 @@ void sieve_do_msg(long msgnum, void *userdata) { } if (haschar(my.envelope_to, '@') == 0) { strcat(my.envelope_to, "@"); - strcat(my.envelope_to, config.c_fqdn); + strcat(my.envelope_to, CtdlGetConfigStr("c_fqdn")); } CM_Free(msg); @@ -749,7 +749,7 @@ void get_sieve_config_backend(long msgnum, void *userdata) { long conflen; u->config_msgnum = msgnum; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { u->config_msgnum = (-1) ; return; @@ -1185,7 +1185,7 @@ void cmd_msiv(char *argbuf) { extract_token(script_name, argbuf, 1, '|', sizeof script_name); if (!IsEmptyStr(script_name)) { cprintf("%d Transmit script now\n", SEND_LISTING); - script_content = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + script_content = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); msiv_putscript(&u, script_name, script_content); changes_made = 1; } diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index a93bb438e..00f55e06a 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -20,7 +20,7 @@ * The VRFY and EXPN commands have been removed from this implementation * because nobody uses these commands anymore, except for spammers. * - * Copyright (c) 1998-2013 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -154,7 +154,7 @@ void smtp_greeting(int is_msa) /* If this config option is set, reject connections from problem * addresses immediately instead of after they execute a RCPT */ - if ( (config.c_rbl_at_greeting) && (sSMTP->is_msa == 0) ) { + if ( (CtdlGetConfigInt("c_rbl_at_greeting")) && (sSMTP->is_msa == 0) ) { if (rbl_check(message_to_spammer)) { if (server_shutting_down) cprintf("421 %s\r\n", message_to_spammer); @@ -178,7 +178,7 @@ void smtp_greeting(int is_msa) /* Note: the FQDN *must* appear as the first thing after the 220 code. * Some clients (including citmail.c) depend on it being there. */ - cprintf("220 %s ESMTP Citadel server ready.\r\n", config.c_fqdn); + cprintf("220 %s ESMTP Citadel server ready.\r\n", CtdlGetConfigStr("c_fqdn")); } @@ -284,7 +284,7 @@ void smtp_hello(long offset, long which_command) cprintf("250-Greetings and joyous salutations.\r\n"); } cprintf("250-HELP\r\n"); - cprintf("250-SIZE %ld\r\n", config.c_maxmsglen); + cprintf("250-SIZE %ld\r\n", CtdlGetConfigLong("c_maxmsglen")); #ifdef HAVE_OPENSSL /* @@ -318,7 +318,7 @@ void smtp_webcit_preferences_hack_backend(long msgnum, void *userdata) { return; // already got it } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { return; } @@ -674,7 +674,7 @@ void smtp_mail(long offset, long flags) { /* Otherwise, make sure outsiders aren't trying to forge mail from * this system (unless, of course, c_allow_spoofing is enabled) */ - else if (config.c_allow_spoofing == 0) { + else if (CtdlGetConfigInt("c_allow_spoofing") == 0) { process_rfc822_addr(ChrPtr(sSMTP->from), user, node, name); syslog(LOG_DEBUG, "Claimed envelope sender is '%s' == '%s' @ '%s' ('%s')", ChrPtr(sSMTP->from), user, node, name @@ -730,7 +730,7 @@ void smtp_rcpt(long offset, long flags) /* RBL check */ if ( (!CCC->logged_in) /* Don't RBL authenticated users */ && (!sSMTP->is_lmtp) ) { /* Don't RBL LMTP clients */ - if (config.c_rbl_at_greeting == 0) { /* Don't RBL again if we already did it */ + if (CtdlGetConfigInt("c_rbl_at_greeting") == 0) { /* Don't RBL again if we already did it */ if (rbl_check(message_to_spammer)) { if (server_shutting_down) cprintf("421 %s\r\n", message_to_spammer); @@ -826,7 +826,7 @@ void smtp_data(long offset, long flags) " by %s; %s\n", ChrPtr(sSMTP->helo_node), (long int) CCC->cs_UDSclientUID, - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), nowstamp); } else { @@ -837,11 +837,11 @@ void smtp_data(long offset, long flags) ChrPtr(sSMTP->helo_node), CCC->cs_host, CCC->cs_addr, - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), nowstamp); } } - body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL); + body = CtdlReadMessageBodyBuf(HKEY("."), CtdlGetConfigLong("c_maxmsglen"), defbody, 1, NULL); FreeStrBuf(&defbody); if (body == NULL) { cprintf("550 Unable to save message: internal error.\r\n"); @@ -861,12 +861,12 @@ void smtp_data(long offset, long flags) * to something ugly like "0000058008.Sent Items>" when the message * is read with a Citadel client. */ - if ( (CCC->logged_in) && (config.c_rfc822_strict_from != CFG_SMTP_FROM_NOFILTER) ) { + if ( (CCC->logged_in) && (CtdlGetConfigInt("c_rfc822_strict_from") != CFG_SMTP_FROM_NOFILTER) ) { int validemail = 0; if (!CM_IsEmpty(msg, erFc822Addr) && - ((config.c_rfc822_strict_from == CFG_SMTP_FROM_CORRECT) || - (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT) ) ) + ((CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_CORRECT) || + (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT) ) ) { if (!IsEmptyStr(CCC->cs_inet_email)) validemail = strcmp(CCC->cs_inet_email, msg->cm_fields[erFc822Addr]) == 0; @@ -884,14 +884,14 @@ void smtp_data(long offset, long flags) } } - if (!validemail && (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT)) { + if (!validemail && (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT)) { syslog(LOG_ERR, "invalid sender '%s' - rejecting this message", msg->cm_fields[erFc822Addr]); cprintf("550 Invalid sender '%s' - rejecting this message.\r\n", msg->cm_fields[erFc822Addr]); return; } - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); CM_SetField(msg, eOriginalRoom, HKEY(MAILROOM)); if (sSMTP->preferred_sender_name != NULL) CM_SetField(msg, eAuthor, SKEY(sSMTP->preferred_sender_name)); @@ -1143,7 +1143,7 @@ CTDL_MODULE_INIT(smtp) #endif - CtdlRegisterServiceHook(config.c_smtp_port, /* SMTP MTA */ + CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtp_port"), /* SMTP MTA */ NULL, smtp_mta_greeting, smtp_command_loop, @@ -1151,7 +1151,7 @@ CTDL_MODULE_INIT(smtp) CitadelServiceSMTP_MTA); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_smtps_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtps_port"), /* SMTPS MTA */ NULL, smtps_greeting, smtp_command_loop, @@ -1159,7 +1159,7 @@ CTDL_MODULE_INIT(smtp) CitadelServiceSMTPS_MTA); #endif - CtdlRegisterServiceHook(config.c_msa_port, /* SMTP MSA */ + CtdlRegisterServiceHook(CtdlGetConfigInt("c_msa_port"), /* SMTP MSA */ NULL, smtp_msa_greeting, smtp_command_loop, diff --git a/citadel/modules/smtp/serv_smtpqueue.c b/citadel/modules/smtp/serv_smtpqueue.c index df04bdcc5..d12e06aa5 100644 --- a/citadel/modules/smtp/serv_smtpqueue.c +++ b/citadel/modules/smtp/serv_smtpqueue.c @@ -20,21 +20,15 @@ * The VRFY and EXPN commands have been removed from this implementation * because nobody uses these commands anymore, except for spammers. * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -606,7 +600,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay) boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_")); StrBufAppendPrintf(boundary, "%s_%04x%04x", - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), getpid(), ++seq); @@ -703,7 +697,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay) CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); CM_SetField(bmsg, eAuthor, HKEY("Citadel")); - CM_SetField(bmsg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB); @@ -725,7 +719,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay) /* If not, post it in the Aide> room */ if (successful_bounce == 0) { - CtdlSubmitMsg(bmsg, NULL, config.c_aideroom, QP_EADDR); + CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR); } /* Free up the memory we used */ @@ -842,7 +836,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { SMTPC_syslog(LOG_DEBUG, "smtp_do_procmsg(%ld)\n", msgnum); ///strcpy(envelope_from, ""); - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { SMTPC_syslog(LOG_ERR, "tried %ld but no such message!\n", msgnum); diff --git a/citadel/modules/smtp/smtp_clienthandlers.c b/citadel/modules/smtp/smtp_clienthandlers.c index 198649e1f..960a6e025 100644 --- a/citadel/modules/smtp/smtp_clienthandlers.c +++ b/citadel/modules/smtp/smtp_clienthandlers.c @@ -17,21 +17,15 @@ * RFC 2822 - Internet Message Format * RFC 2920 - SMTP Service Extension for Command Pipelining * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -144,8 +138,7 @@ eNextState SMTPC_send_EHLO(SmtpOutMsg *Msg) /* At this point we know we are talking to a real SMTP server */ /* Do a EHLO command. If it fails, try the HELO command. */ - StrBufPrintf(Msg->IO.SendBuf.Buf, - "EHLO %s\r\n", config.c_fqdn); + StrBufPrintf(Msg->IO.SendBuf.Buf, "EHLO %s\r\n", CtdlGetConfigStr("c_fqdn")); SMTP_DBG_SEND(); return eReadMessage; @@ -180,8 +173,7 @@ eNextState SMTPC_read_EHLO_reply(SmtpOutMsg *Msg) eNextState STMPC_send_HELO(SmtpOutMsg *Msg) { AsyncIO *IO = &Msg->IO; - StrBufPrintf(Msg->IO.SendBuf.Buf, - "HELO %s\r\n", config.c_fqdn); + StrBufPrintf(Msg->IO.SendBuf.Buf, "HELO %s\r\n", CtdlGetConfigStr("c_fqdn")); SMTP_DBG_SEND(); return eReadMessage; diff --git a/citadel/modules/smtp/smtp_util.c b/citadel/modules/smtp/smtp_util.c index 8609f9113..1cca96e3a 100644 --- a/citadel/modules/smtp/smtp_util.c +++ b/citadel/modules/smtp/smtp_util.c @@ -20,21 +20,15 @@ * The VRFY and EXPN commands have been removed from this implementation * because nobody uses these commands anymore, except for spammers. * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -129,11 +123,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) strcpy(bounceto, ""); boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_")); - StrBufAppendPrintf(boundary, - "%s_%04x%04x", - config.c_fqdn, - getpid(), - ++seq); + StrBufAppendPrintf(boundary, "%s_%04x%04x", CtdlGetConfigStr("c_fqdn"), getpid(), ++seq); lines = num_tokens(instr, '\n'); @@ -163,11 +153,9 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) bmsg->cm_format_type = FMT_RFC822; CM_SetField(bmsg, eAuthor, HKEY("Citadel")); CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); - CM_SetField(bmsg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); - StrBufAppendBufPlain( - BounceMB, - HKEY("Content-type: multipart/mixed; boundary=\""), 0); + StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0); @@ -310,7 +298,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) /* If not, post it in the Aide> room */ if (successful_bounce == 0) { - CtdlSubmitMsg(bmsg, NULL, config.c_aideroom, QP_EADDR); + CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR); } /* Free up the memory we used */ diff --git a/citadel/modules/spam/serv_spam.c b/citadel/modules/spam/serv_spam.c index f9a823d9e..df7f97e77 100644 --- a/citadel/modules/spam/serv_spam.c +++ b/citadel/modules/spam/serv_spam.c @@ -4,21 +4,15 @@ * http://www.spamassassin.org (the SpamAssassin project is not in any way * affiliated with the Citadel project). * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. - * - * * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * - * - * */ #define SPAMASSASSIN_PORT "783" @@ -141,8 +135,8 @@ int spam_assassin(struct CtdlMessage *msg, recptypes *recp) { goto bail; } syslog(LOG_DEBUG, "<%s\n", buf); - syslog(LOG_DEBUG, "c_spam_flag_only setting %d\n", config.c_spam_flag_only); - if (config.c_spam_flag_only) { + syslog(LOG_DEBUG, "c_spam_flag_only setting %d\n", CtdlGetConfigInt("c_spam_flag_only")); + if (CtdlGetConfigInt("c_spam_flag_only")) { int headerlen; char *cur; char sastatus[10]; diff --git a/citadel/modules/upgrade/serv_upgrade.c b/citadel/modules/upgrade/serv_upgrade.c index 085f5f046..06eb8bcae 100644 --- a/citadel/modules/upgrade/serv_upgrade.c +++ b/citadel/modules/upgrade/serv_upgrade.c @@ -1,7 +1,7 @@ /* * Transparently handle the upgrading of server data formats. * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 3. @@ -245,8 +245,8 @@ void guess_time_zone(void) { if (fp) { if (fgets(buf, sizeof buf, fp) && (strlen(buf) > 2)) { buf[strlen(buf)-1] = 0; - safestrncpy(config.c_default_cal_zone, buf, sizeof config.c_default_cal_zone); - syslog(LOG_INFO, "Configuring timezone: %s", config.c_default_cal_zone); + CtdlSetConfigStr("c_default_cal_zone", buf); + syslog(LOG_INFO, "Configuring timezone: %s", buf); } fclose(fp); } @@ -260,47 +260,46 @@ void guess_time_zone(void) { * Note that if the previous version was 0 then this is a new installation running for the first time. */ void update_config(void) { - get_config(); - if (CitControl.version < 606) { - config.c_rfc822_strict_from = 0; + int oldver = CtdlGetConfigInt("MM_hosted_upgrade_level"); + + if (oldver < 606) { + CtdlSetConfigInt("c_rfc822_strict_from", 0); } - if (CitControl.version < 609) { - config.c_purge_hour = 3; + if (oldver < 609) { + CtdlSetConfigInt("c_purge_hour", 3); } - if (CitControl.version < 615) { - config.c_ldap_port = 389; + if (oldver < 615) { + CtdlSetConfigInt("c_ldap_port", 389); } - if (CitControl.version < 623) { - strcpy(config.c_ip_addr, "*"); + if (oldver < 623) { + CtdlSetConfigStr("c_ip_addr", "*"); } - if (CitControl.version < 650) { - config.c_enable_fulltext = 1; + if (oldver < 650) { + CtdlSetConfigInt("c_enable_fulltext", 1); } - if (CitControl.version < 652) { - config.c_auto_cull = 1; + if (oldver < 652) { + CtdlSetConfigInt("c_auto_cull", 1); } - if (CitControl.version < 725) { - config.c_xmpp_c2s_port = 5222; - config.c_xmpp_s2s_port = 5269; + if (oldver < 725) { + CtdlSetConfigInt("c_xmpp_c2s_port", 5222); + CtdlSetConfigInt("c_xmpp_s2s_port", 5269); } - if (CitControl.version < 830) { - config.c_nntp_port = 119; - config.c_nntps_port = 563; + if (oldver < 830) { + CtdlSetConfigInt("c_nntp_port", 119); + CtdlSetConfigInt("c_nntps_port", 563); } - if (IsEmptyStr(config.c_default_cal_zone)) { + if (IsEmptyStr(CtdlGetConfigStr("c_default_cal_zone"))) { guess_time_zone(); } - - put_config(); } @@ -311,13 +310,12 @@ void update_config(void) { */ void check_server_upgrades(void) { - get_control(); syslog(LOG_INFO, "Existing database version on disk is %d.%02d", - (CitControl.version / 100), - (CitControl.version % 100) + (CtdlGetConfigInt("MM_hosted_upgrade_level") / 100), + (CtdlGetConfigInt("MM_hosted_upgrade_level") % 100) ); - if (CitControl.version < REV_LEVEL) { + if (CtdlGetConfigInt("MM_hosted_upgrade_level") < REV_LEVEL) { syslog(LOG_WARNING, "Server hosted updates need to be processed at this time. Please wait..." ); @@ -328,29 +326,29 @@ void check_server_upgrades(void) { update_config(); - if ((CitControl.version > 000) && (CitControl.version < 555)) { + if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 555)) { syslog(LOG_EMERG, "This database is too old to be upgraded. Citadel server will exit."); exit(EXIT_FAILURE); } - if ((CitControl.version > 000) && (CitControl.version < 591)) { + if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 591)) { bump_mailbox_generation_numbers(); } - if ((CitControl.version > 000) && (CitControl.version < 608)) { + if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 608)) { convert_ctdluid_to_minusone(); } - if ((CitControl.version > 000) && (CitControl.version < 659)) { + if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 659)) { rebuild_euid_index(); } - if (CitControl.version < 735) { + if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 735) { fix_sys_user_name(); } - if (CitControl.version < 736) { + if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 736) { rebuild_usersbynumber(); } - if (CitControl.version < 790) { + if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 790) { remove_thread_users(); } - if (CitControl.version < 810) { + if (CtdlGetConfigInt("MM_hosted_upgrade_level") < 810) { struct ctdlroom QRoom; if (!CtdlGetRoom(&QRoom, SMTP_SPOOLOUT_ROOM)) { QRoom.QRdefaultview = VIEW_QUEUE; @@ -362,25 +360,23 @@ void check_server_upgrades(void) { } } - CitControl.version = REV_LEVEL; + CtdlSetConfigInt("MM_hosted_upgrade_level", REV_LEVEL); /* * Negative values for maxsessions are not allowed. */ - if (config.c_maxsessions < 0) { - config.c_maxsessions = 0; + if (CtdlGetConfigInt("c_maxsessions") < 0) { + CtdlSetConfigInt("c_maxsessions", 0); } /* We need a system default message expiry policy, because this is * the top level and there's no 'higher' policy to fall back on. * By default, do not expire messages at all. */ - if (config.c_ep.expire_mode == 0) { - config.c_ep.expire_mode = EXPIRE_MANUAL; - config.c_ep.expire_value = 0; + if (CtdlGetConfigInt("c_ep_mode") == 0) { + CtdlSetConfigInt("c_ep_mode", EXPIRE_MANUAL); + CtdlSetConfigInt("c_ep_value", 0); } - - put_control(); } diff --git a/citadel/modules/vcard/serv_vcard.c b/citadel/modules/vcard/serv_vcard.c index 77e4b06a9..5c3a3a725 100644 --- a/citadel/modules/vcard/serv_vcard.c +++ b/citadel/modules/vcard/serv_vcard.c @@ -2,7 +2,7 @@ * A server-side module for Citadel which supports address book information * using the standard vCard format. * - * Copyright (c) 1999-2012 by the citadel.org team + * Copyright (c) 1999-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -73,10 +73,12 @@ * set global flag calling for an aide to validate new users */ void set_mm_valid(void) { + int flags = 0; + begin_critical_section(S_CONTROL); - get_control(); - CitControl.MMflags = CitControl.MMflags | MM_VALID ; - put_control(); + flags = CtdlGetConfigInt("MMflags"); + flags = flags | MM_VALID ; + CtdlSetConfigInt("MMflags", flags); end_critical_section(S_CONTROL); } @@ -185,7 +187,7 @@ int vcard_directory_add_user(char *internet_addr, char *citadel_addr) { void vcard_add_to_directory(long msgnum, void *data) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { vcard_extract_internet_addresses(msg, vcard_directory_add_user); } @@ -385,7 +387,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { /* If users cannot create their own accounts, they cannot re-register either. */ if ( (yes_my_citadel_config) && - (config.c_disable_newu) && + (CtdlGetConfigInt("c_disable_newu")) && (CCC->user.axlevel < AxAideU) && (CCC->vcard_updated_by_ldap==0) ) { @@ -433,7 +435,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { /* Insert or replace RFC2739-compliant free/busy URL */ if (yes_my_citadel_config) { sprintf(buf, "http://%s/%s.vfb", - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), usbuf.fullname); for (i=0; buf[i]; ++i) { if (buf[i] == ' ') buf[i] = '_'; @@ -441,18 +443,19 @@ int vcard_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { vcard_set_prop(v, "FBURL;PREF", buf, 0); } - /* If the vCard has no UID, then give it one. */ + s = vcard_get_prop(v, "UID", 1, 0, 0); - if (s == NULL) { + if (s == NULL) { /* Note LDAP auth sets UID from the LDAP UUID, use that if it exists. */ + /* Enforce local UID policy if applicable */ + if (yes_my_citadel_config) { + snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, msg->cm_fields[eAuthor], NODENAME); + } else { + /* If the vCard has no UID, then give it one. */ generate_uuid(buf); - vcard_set_prop(v, "UID", buf, 0); - } + } + vcard_set_prop(v, "UID", buf, 0); + } - /* Enforce local UID policy if applicable */ - if (yes_my_citadel_config) { - snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, msg->cm_fields[eAuthor], NODENAME); - vcard_set_prop(v, "UID", buf, 0); - } /* * Set the EUID of the message to the UID of the vCard. @@ -652,7 +655,7 @@ struct vCard *vcard_get_user(struct ctdluser *u) { if (VCmsgnum < 0L) return vcard_new(); - msg = CtdlFetchMessage(VCmsgnum, 1); + msg = CtdlFetchMessage(VCmsgnum, 1, 1); if (msg == NULL) return vcard_new(); v = vcard_load(msg->cm_fields[eMesageText]); @@ -722,7 +725,7 @@ void cmd_regi(char *argbuf) { } /* If users cannot create their own accounts, they cannot re-register either. */ - if ( (config.c_disable_newu) && (CCC->user.axlevel < AxAideU) ) { + if ( (CtdlGetConfigInt("c_disable_newu")) && (CCC->user.axlevel < AxAideU) ) { cprintf("%d Self-service registration is not allowed here.\n", ERROR + HIGHER_ACCESS_REQUIRED); } @@ -864,7 +867,7 @@ void vcard_newuser(struct ctdluser *usbuf) { #ifdef HAVE_GETPWUID_R /* If using host auth mode, we add an email address based on the login */ - if (config.c_auth_mode == AUTHMODE_HOST) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { struct passwd pwd; char pwd_buffer[SIZ]; @@ -875,7 +878,7 @@ void vcard_newuser(struct ctdluser *usbuf) { syslog(LOG_DEBUG, "Searching for uid %d", usbuf->uid); if (getpwuid_r(usbuf->uid, &pwd, pwd_buffer, sizeof pwd_buffer, &result) == 0) { #endif // HAVE_GETPWUID_R - snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, config.c_fqdn); + snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, CtdlGetConfigStr("c_fqdn")); vcard_add_prop(v, "email;internet", buf); need_default_vcard = 0; } @@ -888,12 +891,12 @@ void vcard_newuser(struct ctdluser *usbuf) { * Is this an LDAP session? If so, copy various LDAP attributes from the directory entry * into the user's vCard. */ - if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { //uid_t ldap_uid; int found_user; char ldap_cn[512]; char ldap_dn[512]; - found_user = CtdlTryUserLDAP(usbuf->fullname, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &usbuf->uid, 1); + found_user = CtdlTryUserLDAP(usbuf->fullname, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &usbuf->uid,1); if (found_user == 0) { if (Ctdl_LDAP_to_vCard(ldap_dn, v)) { /* Allow global address book and internet directory update without login long enough to write this. */ @@ -904,10 +907,10 @@ void vcard_newuser(struct ctdluser *usbuf) { } } #endif - if (need_default_vcard != 0) { + 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); - for (i = 0; buf[i]; i++) { + snprintf(buf, sizeof buf, "%s@%s", usbuf->fullname, CtdlGetConfigStr("c_fqdn")); + for (i=0; buf[i]; ++i) { if (buf[i] == ' ') buf[i] = '_'; } vcard_add_prop(v, "email;internet", buf); @@ -937,7 +940,7 @@ void vcard_purge(struct ctdluser *usbuf) { msg->cm_format_type = 0; CM_SetField(msg, eAuthor, usbuf->fullname, strlen(usbuf->fullname)); CM_SetField(msg, eOriginalRoom, HKEY(ADDRESS_BOOK_ROOM)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(msg, eMesageText, HKEY("Purge this vCard\n")); len = snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, @@ -1009,7 +1012,7 @@ void vcard_delete_remove(char *room, long msgnum) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; if (CM_IsEmpty(msg, eMesageText)) @@ -1136,7 +1139,7 @@ void dvca_mime_callback(char *name, char *filename, char *partnum, char *disp, void dvca_callback(long msgnum, void *userdata) { struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; mime_parser(CM_RANGE(msg, eMesageText), *dvca_mime_callback, /* callback function */ @@ -1280,7 +1283,7 @@ void vcard_session_login_hook(void) { * Is this an LDAP session? If so, copy various LDAP attributes from the directory entry * into the user's vCard. */ - if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { v = vcard_get_user(&CCC->user); if (v) { if (Ctdl_LDAP_to_vCard(CCC->ldap_dn, v)) { @@ -1360,7 +1363,7 @@ void strip_addresses_already_have(long msgnum, void *userdata) { collected_addresses = (char *)userdata; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; v = vcard_load(msg->cm_fields[eMesageText]); CM_Free(msg); @@ -1552,7 +1555,7 @@ CTDL_MODULE_INIT(vcard) } /* for postfix tcpdict */ - CtdlRegisterServiceHook(config.c_pftcpdict_port, /* Postfix */ + CtdlRegisterServiceHook(CtdlGetConfigInt("c_pftcpdict_port"), /* Postfix */ NULL, check_get_greeting, check_get, diff --git a/citadel/modules/wiki/serv_wiki.c b/citadel/modules/wiki/serv_wiki.c index 79845fa8a..4642d13d8 100644 --- a/citadel/modules/wiki/serv_wiki.c +++ b/citadel/modules/wiki/serv_wiki.c @@ -1,7 +1,7 @@ /* * Server-side module for Wiki rooms. This handles things like version control. * - * Copyright (c) 2009-2012 by the citadel.org team + * Copyright (c) 2009-2015 by the citadel.org team * * This program is open source software. You can redistribute it and/or * modify it under the terms of the GNU General Public License, version 3. @@ -127,7 +127,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { /* See if we can retrieve the previous version. */ old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room); if (old_msgnum > 0L) { - old_msg = CtdlFetchMessage(old_msgnum, 1); + old_msg = CtdlFetchMessage(old_msgnum, 1, 1); } else { old_msg = NULL; @@ -208,7 +208,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { history_msgnum = CtdlLocateMessageByEuid(history_page, &CCC->room); history_msg = NULL; if (history_msgnum > 0L) { - history_msg = CtdlFetchMessage(history_msgnum, 1); + history_msg = CtdlFetchMessage(history_msgnum, 1, 1); } /* Create a new history message if necessary */ @@ -303,7 +303,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { uuid, Now, CCC->user.fullname, - config.c_nodename); + CtdlGetConfigStr("c_nodename")); memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0); @@ -390,7 +390,7 @@ void wiki_history(char *pagename) { snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename); msgnum = CtdlLocateMessageByEuid(history_page_name, &CC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; @@ -522,7 +522,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) */ msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; @@ -556,7 +556,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename); msgnum = CtdlLocateMessageByEuid(history_page_name, &CCC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; @@ -643,7 +643,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(msg, eExclusiveID, pagename, strlen(pagename)); msgnum = CtdlSubmitMsg(msg, NULL, "", 0); /* Replace the current revision */ } diff --git a/citadel/modules/xmpp/serv_xmpp.c b/citadel/modules/xmpp/serv_xmpp.c index 64dc8b7aa..36b1d33ce 100644 --- a/citadel/modules/xmpp/serv_xmpp.c +++ b/citadel/modules/xmpp/serv_xmpp.c @@ -668,7 +668,7 @@ extern void xmpp_cleanup_events(void); CTDL_MODULE_INIT(xmpp) { if (!threading) { - CtdlRegisterServiceHook(config.c_xmpp_c2s_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_xmpp_c2s_port"), NULL, xmpp_greeting, xmpp_command_loop, diff --git a/citadel/modules/xmpp/xmpp_presence.c b/citadel/modules/xmpp/xmpp_presence.c index d716d4b1a..a3be435f7 100644 --- a/citadel/modules/xmpp/xmpp_presence.c +++ b/citadel/modules/xmpp/xmpp_presence.c @@ -158,7 +158,7 @@ void xmpp_destroy_buddy(char *presence_jid, int aggressively) { ); cprintf(""); cprintf("", xmlesc(xmlbuf1, presence_jid, sizeof xmlbuf1)); - cprintf("%s", xmlesc(xmlbuf1, config.c_humannode, sizeof xmlbuf1)); + cprintf("%s", xmlesc(xmlbuf1, CtdlGetConfigStr("c_humannode"), sizeof xmlbuf1)); cprintf(""); cprintf("" "" @@ -229,7 +229,7 @@ void xmpp_fetch_mortuary_backend(long msgnum, void *userdata) { char *ptr = NULL; char *lasts = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { return; } diff --git a/citadel/modules/xmpp/xmpp_query_namespace.c b/citadel/modules/xmpp/xmpp_query_namespace.c index df7671798..848fcc735 100644 --- a/citadel/modules/xmpp/xmpp_query_namespace.c +++ b/citadel/modules/xmpp/xmpp_query_namespace.c @@ -61,7 +61,7 @@ void xmpp_roster_item(struct CitContext *cptr) { xmlesc(xmlbuf1, cptr->cs_inet_email, sizeof xmlbuf1), xmlesc(xmlbuf2, cptr->user.fullname, sizeof xmlbuf2) ); - cprintf("%s", xmlesc(xmlbuf1, config.c_humannode, sizeof xmlbuf1)); + cprintf("%s", xmlesc(xmlbuf1, CtdlGetConfigStr("c_humannode"), sizeof xmlbuf1)); cprintf(""); } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index ddc12aafd..d8b1ac9d2 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1,7 +1,7 @@ /* * Implements the message store. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -22,6 +22,7 @@ #include "ctdl_module.h" #include "citserver.h" #include "control.h" +#include "config.h" #include "clientsocket.h" #include "genstamp.h" #include "room_ops.h" @@ -737,7 +738,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, free(msglist); return -1; } - msg = CtdlFetchMessage(msglist[a], 1); + msg = CtdlFetchMessage(msglist[a], 1, 1); if (msg != NULL) { if (CtdlMsgCmp(msg, compare)) { msglist[a] = 0L; @@ -1083,33 +1084,18 @@ void mime_spew_section(char *name, char *filename, char *partnum, char *disp, } } - -/* - * Load a message from disk into memory. - * This is used by CtdlOutputMsg() and other fetch functions. - * - * NOTE: Caller is responsible for freeing the returned CtdlMessage struct - * using the CtdlMessageFree() function. - */ -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) +struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length) { struct CitContext *CCC = CC; - struct cdbdata *dmsgtext; struct CtdlMessage *ret = NULL; - char *mptr; - char *upper_bound; + const char *mptr; + const char *upper_bound; cit_uint8_t ch; cit_uint8_t field_header; eMsgField which; - MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body); - dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); - if (dmsgtext == NULL) { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body); - return NULL; - } - mptr = dmsgtext->ptr; - upper_bound = mptr + dmsgtext->len; + mptr = Buffer; + upper_bound = Buffer + Length; /* Parse the three bytes that begin EVERY message on disk. * The first is always 0xFF, the on-disk magic number. @@ -1119,7 +1105,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) ch = *mptr++; if (ch != 255) { MSG_syslog(LOG_ERR, "Message %ld appears to be corrupted.\n", msgnum); - cdb_free(dmsgtext); return NULL; } ret = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); @@ -1129,13 +1114,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) ret->cm_anon_type = *mptr++; /* Anon type byte */ ret->cm_format_type = *mptr++; /* Format type byte */ - - if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') - { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); - dmsgtext->ptr[dmsgtext->len - 1] = '\0'; - } - /* * The rest is zero or more arbitrary fields. Load them in. * We're done when we encounter either a zero-length field or @@ -1165,8 +1143,44 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) } while ((mptr < upper_bound) && (field_header != 'M')); + return (ret); +} + + +/* + * Load a message from disk into memory. + * This is used by CtdlOutputMsg() and other fetch functions. + * + * NOTE: Caller is responsible for freeing the returned CtdlMessage struct + * using the CtdlMessageFree() function. + */ +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks) +{ + struct CitContext *CCC = CC; + struct cdbdata *dmsgtext; + struct CtdlMessage *ret = NULL; + + MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body); + dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); + if (dmsgtext == NULL) { + MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body); + return NULL; + } + + if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') + { + MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); + dmsgtext->ptr[dmsgtext->len - 1] = '\0'; + } + + ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext->ptr, dmsgtext->len); + cdb_free(dmsgtext); + if (ret == NULL) { + return NULL; + } + /* Always make sure there's something in the msg text field. If * it's NULL, the message text is most likely stored separately, * so go ahead and fetch that. Failing that, just set a dummy @@ -1184,7 +1198,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) } /* Perform "before read" hooks (aborting if any return nonzero) */ - if (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0) { + if (run_msg_hooks && (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0)) { CM_Free(ret); return NULL; } @@ -1584,10 +1598,10 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ * request that we don't even bother loading the body into memory. */ if (headers_only == HEADERS_FAST) { - TheMessage = CtdlFetchMessage(msg_num, 0); + TheMessage = CtdlFetchMessage(msg_num, 0, 1); } else { - TheMessage = CtdlFetchMessage(msg_num, 1); + TheMessage = CtdlFetchMessage(msg_num, 1, 1); } if (TheMessage == NULL) { @@ -1818,7 +1832,7 @@ void OutputRFC822MsgHeaders( if (haschar(mptr, '@') == 0) { sanitize_truncated_recipient(mptr); - cprintf("To: %s@%s", mptr, config.c_fqdn); + cprintf("To: %s@%s", mptr, CtdlGetConfigStr("c_fqdn")); cprintf("%s", nl); } else @@ -2166,7 +2180,7 @@ int CtdlOutputPreLoadedMsg( strcpy(suser, ""); strcpy(luser, ""); strcpy(fuser, ""); - memcpy(snode, CFG_KEY(c_nodename) + 1); + memcpy(snode, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")) + 1); if (mode == MT_RFC822) OutputRFC822MsgHeaders( TheMessage, @@ -2425,7 +2439,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms msg = supplied_msg; } else { - msg = CtdlFetchMessage(msgid, 0); + msg = CtdlFetchMessage(msgid, 0, 1); } if (msg != NULL) { @@ -2491,75 +2505,101 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, * called by server-side modules. * */ -long send_message(struct CtdlMessage *msg) { +long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { struct CitContext *CCC = CC; - long newmsgid; long retval; - char msgidbuf[256]; - long msgidbuflen; struct ser_ret smr; int is_bigmsg = 0; char *holdM = NULL; long holdMLen = 0; - /* Get a new message number */ - newmsgid = get_new_message_number(); - msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", - (long unsigned int) time(NULL), - (long unsigned int) newmsgid, - config.c_fqdn - ); - - /* Generate an ID if we don't have one already */ - if (CM_IsEmpty(msg, emessageId)) { - CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); - } - - /* If the message is big, set its body aside for storage elsewhere */ - if (!CM_IsEmpty(msg, eMesageText)) { - if (msg->cm_lengths[eMesageText] > BIGMSG) { - is_bigmsg = 1; - holdM = msg->cm_fields[eMesageText]; - msg->cm_fields[eMesageText] = NULL; - holdMLen = msg->cm_lengths[eMesageText]; - msg->cm_lengths[eMesageText] = 0; - } + /* + * If the message is big, set its body aside for storage elsewhere + * and we hide the message body from the serializer + */ + if (!CM_IsEmpty(msg, eMesageText) && msg->cm_lengths[eMesageText] > BIGMSG) + { + is_bigmsg = 1; + holdM = msg->cm_fields[eMesageText]; + msg->cm_fields[eMesageText] = NULL; + holdMLen = msg->cm_lengths[eMesageText]; + msg->cm_lengths[eMesageText] = 0; } /* Serialize our data structure for storage in the database */ CtdlSerializeMessage(&smr, msg); if (is_bigmsg) { + /* put the message body back into the message */ msg->cm_fields[eMesageText] = holdM; msg->cm_lengths[eMesageText] = holdMLen; } if (smr.len == 0) { - cprintf("%d Unable to serialize message\n", - ERROR + INTERNAL_ERROR); + if (Reply) { + cprintf("%d Unable to serialize message\n", + ERROR + INTERNAL_ERROR); + } + else { + MSGM_syslog(LOG_ERR, "CtdlSaveMessage() unable to serialize message"); + + } return (-1L); } /* Write our little bundle of joy into the message base */ - if (cdb_store(CDB_MSGMAIN, &newmsgid, (int)sizeof(long), - smr.ser, smr.len) < 0) { - MSGM_syslog(LOG_ERR, "Can't store message\n"); - retval = 0L; - } else { + retval = cdb_store(CDB_MSGMAIN, &msgid, (int)sizeof(long), + smr.ser, smr.len); + if (retval < 0) { + MSG_syslog(LOG_ERR, "Can't store message %ld: %ld", msgid, retval); + } + else { if (is_bigmsg) { - cdb_store(CDB_BIGMSGS, - &newmsgid, - (int)sizeof(long), - holdM, - (holdMLen + 1) + retval = cdb_store(CDB_BIGMSGS, + &msgid, + (int)sizeof(long), + holdM, + (holdMLen + 1) ); + if (retval < 0) { + MSG_syslog(LOG_ERR, "failed to store message body for msgid %ld: %ld", + msgid, retval); + } } - retval = newmsgid; } /* Free the memory we used for the serialized message */ free(smr.ser); + return(retval); +} + +long send_message(struct CtdlMessage *msg) { + long newmsgid; + long retval; + char msgidbuf[256]; + long msgidbuflen; + + /* Get a new message number */ + newmsgid = get_new_message_number(); + + /* Generate an ID if we don't have one already */ + if (CM_IsEmpty(msg, emessageId)) { + msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", + (long unsigned int) time(NULL), + (long unsigned int) newmsgid, + CtdlGetConfigStr("c_fqdn") + ); + + CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); + } + + retval = CtdlSaveThisMessage(msg, newmsgid, 1); + + if (retval == 0) { + retval = newmsgid; + } + /* Return the *local* message ID to the caller * (even if we're storing an incoming network message) */ @@ -2576,7 +2616,7 @@ long send_message(struct CtdlMessage *msg) { * serialized message in memory. THE LATTER MUST BE FREED BY THE CALLER. */ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ - struct CtdlMessage *msg) /* unserialized msg */ + struct CtdlMessage *msg) /* unserialized msg */ { struct CitContext *CCC = CC; size_t wlen; @@ -2767,7 +2807,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ if (TWITDETECT) { if (CCC->user.axlevel == AxProbU) { strcpy(hold_rm, actual_rm); - strcpy(actual_rm, config.c_twitroom); + strcpy(actual_rm, CtdlGetConfigStr("c_twitroom")); MSGM_syslog(LOG_DEBUG, "Diverting to twit room\n"); } } @@ -2850,7 +2890,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ if ((!CCC->internal_pgm) || (recps == NULL)) { if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) { MSGM_syslog(LOG_ERR, "ERROR saving message pointer!\n"); - CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2879,7 +2919,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ { if (CCC->logged_in) snprintf(bounce_to, sizeof bounce_to, "%s@%s", - CCC->user.fullname, config.c_nodename); + CCC->user.fullname, CtdlGetConfigStr("c_nodename")); else snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); @@ -2912,7 +2952,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } else { MSG_syslog(LOG_DEBUG, "No user <%s>\n", recipient); - CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } recps->recp_local = pch; @@ -2957,13 +2997,13 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } else { if (recps == NULL) { - qualified_for_journaling = config.c_journal_pubmsgs; + qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs"); } else if (recps->num_local + recps->num_ignet + recps->num_internet > 0) { - qualified_for_journaling = config.c_journal_email; + qualified_for_journaling = CtdlGetConfigInt("c_journal_email"); } else { - qualified_for_journaling = config.c_journal_pubmsgs; + qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs"); } } @@ -3026,7 +3066,7 @@ void quickie_message(const char *from, if (fromaddr != NULL) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr)); if (room != NULL) CM_SetField(msg, eOriginalRoom, room, strlen(room)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); if (to != NULL) { CM_SetField(msg, eRecipient, to, strlen(to)); recp = validate_recipients(to, NULL, 0); @@ -3499,8 +3539,8 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); if (rcplen > 0) { CM_SetField(msg, eRecipient, recipient, rcplen); @@ -3552,7 +3592,7 @@ struct CtdlMessage *CtdlMakeMessageLen( } else { StrBuf *MsgBody; - MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); if (MsgBody != NULL) { CM_SetAsFieldSB(msg, eMesageText, &MsgBody); } @@ -3568,7 +3608,7 @@ struct CtdlMessage *CtdlMakeMessageLen( * API function to delete messages which match a set of criteria * (returns the actual number of messages deleted) */ -int CtdlDeleteMessages(char *room_name, /* which room */ +int CtdlDeleteMessages(const char *room_name, /* which room */ long *dmsgnums, /* array of msg numbers to be deleted */ int num_dmsgnums, /* number of msgs to be deleted, or 0 for "any" */ char *content_type /* or "" for any. regular expressions expected. */ @@ -4033,8 +4073,8 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ msg->cm_format_type = 4; CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); CM_SetField(msg, eOriginalRoom, req_room, strlen(req_room)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); msg->cm_flags = flags; CM_SetAsFieldSB(msg, eMesageText, &encoded_message); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 6d5f726ba..4b53032eb 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -116,7 +116,7 @@ int CtdlForEachMessage(int mode, struct CtdlMessage *compare, ForEachMsgCallback CallBack, void *userdata); -int CtdlDeleteMessages(char *, long *, int, char *); +int CtdlDeleteMessages(const char *, long *, int, char *); void CtdlWriteObject(char *req_room, /* Room to stuff it in */ char *content_type, /* MIME type of this object */ char *raw_message, /* Data to be written */ @@ -126,7 +126,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ int is_unique, /* Del others of this type? */ unsigned int flags /* Internal save flags */ ); -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body); +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks); struct CtdlMessage * CM_Duplicate (struct CtdlMessage *OrgMsg); int CM_IsEmpty (struct CtdlMessage *Msg, eMsgField which); @@ -150,10 +150,12 @@ int CM_IsValidMsg (struct CtdlMessage *msg); Message->cm_fields[Which] + Message->cm_lengths[Which] void CtdlSerializeMessage(struct ser_ret *, struct CtdlMessage *); +struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length); void ReplicationChecks(struct CtdlMessage *); int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs, - int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj); + int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj); int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *msg); +long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply); char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, StrBuf *exist, int crlf, int *sock); StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ long tlen, @@ -265,12 +267,12 @@ extern int MessageDebugEnabled; #define CCCID CCC->cs_pid #define MSG_syslog(LEVEL, FORMAT, ...) \ MSGDBGLOG(LEVEL) syslog(LEVEL, \ - "CC[%d]MSG" FORMAT, \ + "CC[%d]MSG " FORMAT, \ CCCID, __VA_ARGS__) #define MSGM_syslog(LEVEL, FORMAT) \ MSGDBGLOG(LEVEL) syslog(LEVEL, \ - "CC[%d]MSG" FORMAT, \ + "CC[%d]MSG " FORMAT, \ CCCID) diff --git a/citadel/netconfig.c b/citadel/netconfig.c index 3161b1100..14fe8be50 100644 --- a/citadel/netconfig.c +++ b/citadel/netconfig.c @@ -262,7 +262,7 @@ int SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCfg, char *filename) else { OutBuffer = NewStrBuf(); CfgIt = GetNewHashPos(CfgTypeHash, 1); - fchown(TmpFD, config.c_ctdluid, 0); + fchown(TmpFD, ctdluid, 0); for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++) { const CfgLineType *pCfg; diff --git a/citadel/parsedate.c b/citadel/parsedate.c index 854402077..f26fd4a4b 100644 --- a/citadel/parsedate.c +++ b/citadel/parsedate.c @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 3.0.2. */ /* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.5" +#define YYBISON_VERSION "3.0.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -58,15 +58,11 @@ /* Pull parsers. */ #define YYPULL 1 -/* Using locations. */ -#define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ - -/* Line 268 of yacc.c */ -#line 1 "parsedate.y" +#line 1 "parsedate.y" /* yacc.c:339 */ /* $Revision$ ** @@ -179,14 +175,15 @@ static time_t yyRelSeconds; static void date_error(char *); +#line 179 "y.tab.c" /* yacc.c:339 */ -/* Line 268 of yacc.c */ -#line 185 "y.tab.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE @@ -196,28 +193,30 @@ static void date_error(char *); # define YYERROR_VERBOSE 0 #endif -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif -/* Tokens. */ +/* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tDAY = 258, - tDAYZONE = 259, - tMERIDIAN = 260, - tMONTH = 261, - tMONTH_UNIT = 262, - tSEC_UNIT = 263, - tSNUMBER = 264, - tUNUMBER = 265, - tZONE = 266 - }; + enum yytokentype + { + tDAY = 258, + tDAYZONE = 259, + tMERIDIAN = 260, + tMONTH = 261, + tMONTH_UNIT = 262, + tSEC_UNIT = 263, + tSNUMBER = 264, + tUNUMBER = 265, + tZONE = 266 + }; #endif /* Tokens. */ #define tDAY 258 @@ -230,35 +229,32 @@ static void date_error(char *); #define tUNUMBER 265 #define tZONE 266 - - - +/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE +typedef union YYSTYPE YYSTYPE; +union YYSTYPE { - -/* Line 293 of yacc.c */ -#line 114 "parsedate.y" +#line 114 "parsedate.y" /* yacc.c:355 */ time_t Number; enum _MERIDIAN Meridian; - - -/* Line 293 of yacc.c */ -#line 250 "y.tab.c" -} YYSTYPE; +#line 243 "y.tab.c" /* yacc.c:355 */ +}; # define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif -/* Copy the second part of user declarations. */ +extern YYSTYPE yylval; + +int yyparse (void); -/* Line 343 of yacc.c */ -#line 262 "y.tab.c" + +/* Copy the second part of user declarations. */ + +#line 258 "y.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -272,11 +268,8 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; #else -typedef short int yytype_int8; +typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 @@ -296,8 +289,7 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -311,39 +303,68 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") #else -static int -YYID (yyi) - int yyi; +# define YY_INITIAL_VALUE(Value) Value #endif -{ - return yyi; -} +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif + #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -361,9 +382,9 @@ YYID (yyi) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif @@ -373,8 +394,8 @@ YYID (yyi) # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -390,7 +411,7 @@ YYID (yyi) # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 @@ -398,15 +419,13 @@ YYID (yyi) # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -416,7 +435,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -441,35 +460,35 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from FROM to TO. The source and destination do +/* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ @@ -485,17 +504,19 @@ union yyalloc #define YYNNTS 9 /* YYNRULES -- Number of rules. */ #define YYNRULES 30 -/* YYNRULES -- Number of states. */ +/* YYNSTATES -- Number of states. */ #define YYNSTATES 44 -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 266 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -528,32 +549,7 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 12, 14, 16, 19, - 24, 29, 36, 43, 45, 47, 50, 52, 54, 58, - 64, 67, 72, 75, 79, 85, 88, 91, 94, 97, - 98 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 16, 0, -1, -1, 16, 17, -1, 18, -1, 18, - 19, -1, 21, -1, 22, -1, 10, 23, -1, 10, - 12, 10, 23, -1, 10, 12, 10, 20, -1, 10, - 12, 10, 12, 10, 23, -1, 10, 12, 10, 12, - 10, 20, -1, 11, -1, 4, -1, 11, 20, -1, - 20, -1, 9, -1, 10, 13, 10, -1, 10, 13, - 10, 13, 10, -1, 6, 10, -1, 6, 10, 14, - 10, -1, 10, 6, -1, 10, 6, 10, -1, 3, - 14, 10, 6, 10, -1, 9, 8, -1, 10, 8, - -1, 9, 7, -1, 10, 7, -1, -1, 5, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 128, 128, 129, 132, 141, 145, 148, 153, 165, @@ -563,7 +559,7 @@ static const yytype_uint16 yyrline[] = }; #endif -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +#if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -571,13 +567,13 @@ static const char *const yytname[] = "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN", "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE", "':'", "'/'", "','", "$accept", "spec", "item", "time", "zone", - "numzone", "date", "rel", "o_merid", 0 + "numzone", "date", "rel", "o_merid", YY_NULLPTR }; #endif # ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, @@ -585,27 +581,30 @@ static const yytype_uint16 yytoknum[] = }; # endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 15, 16, 16, 17, 17, 17, 17, 18, 18, - 18, 18, 18, 19, 19, 19, 19, 20, 21, 21, - 21, 21, 21, 21, 21, 22, 22, 22, 22, 23, - 23 -}; +#define YYPACT_NINF -29 -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-29))) + +#define YYTABLE_NINF -1 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = { - 0, 2, 0, 2, 1, 2, 1, 1, 2, 4, - 4, 6, 6, 1, 1, 2, 1, 1, 3, 5, - 2, 4, 2, 3, 5, 2, 2, 2, 2, 0, - 1 + -29, 1, -29, -11, 11, 20, 12, -29, 4, -29, + -29, 13, 16, -29, -29, -29, 21, -29, -29, 22, + 23, -29, -29, -29, 5, -29, -29, 28, 25, -29, + 17, 24, -29, 26, -29, 29, -29, -29, 30, -29, + 0, -29, -29, -29 }; -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ static const yytype_uint8 yydefact[] = { 2, 0, 1, 0, 0, 0, 29, 3, 4, 6, @@ -615,34 +614,21 @@ static const yytype_uint8 yydefact[] = 29, 19, 12, 11 }; -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 1, 7, 8, 25, 26, 9, 10, 21 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -29 -static const yytype_int8 yypact[] = + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = { - -29, 1, -29, -11, 11, 20, 12, -29, 4, -29, - -29, 13, 16, -29, -29, -29, 21, -29, -29, 22, - 23, -29, -29, -29, 5, -29, -29, 28, 25, -29, - 17, 24, -29, 26, -29, 29, -29, -29, 30, -29, - 0, -29, -29, -29 + -29, -29, -29, -29, -29, -24, -29, -29, -28 }; -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = { - -29, -29, -29, -29, -29, -24, -29, -29, -28 + -1, 1, 7, 8, 25, 26, 9, 10, 21 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { 32, 2, 37, 11, 3, 15, 36, 4, 22, 23, @@ -652,12 +638,6 @@ static const yytype_uint8 yytable[] = 41 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-29)) - -#define yytable_value_is_error(yytable_value) \ - YYID (0) - static const yytype_int8 yycheck[] = { 24, 0, 30, 14, 3, 5, 30, 6, 4, 9, @@ -667,8 +647,8 @@ static const yytype_int8 yycheck[] = 10 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 16, 0, 3, 6, 9, 10, 17, 18, 21, @@ -678,94 +658,59 @@ static const yytype_uint8 yystos[] = 10, 10, 20, 23 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 15, 16, 16, 17, 17, 17, 17, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 20, 21, 21, + 21, 21, 21, 21, 21, 22, 22, 22, 22, 23, + 23 +}; -#define YYRECOVERING() (!!yyerrstatus) + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 2, 1, 1, 2, 4, + 4, 6, 6, 1, 1, 2, 1, 1, 3, 5, + 2, 4, 2, 3, 5, 2, 2, 2, 2, 0, + 1 +}; -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -/* This macro is provided for backward compatibility. */ +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif /* Enable debugging if requested. */ #if YYDEBUG @@ -775,54 +720,46 @@ while (YYID (0)) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { + FILE *yyo = yyoutput; + YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -830,22 +767,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) | Print this symbol on YYOUTPUT. | `--------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); @@ -856,16 +782,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) | TOP (included). | `------------------------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -876,49 +794,42 @@ yy_stack_print (yybottom, yytop) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { + unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -932,7 +843,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -955,15 +866,8 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -979,16 +883,8 @@ yystrlen (yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1018,27 +914,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1061,12 +957,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = 0; + const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1074,10 +969,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, int yycount = 0; /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected @@ -1126,11 +1017,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1150,10 +1043,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1190,48 +1085,20 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, | Release the memory associated to this symbol. | `-----------------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif { YYUSE (yyvaluep); - if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END } -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ @@ -1239,7 +1106,6 @@ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; - /* Number of syntax errors so far. */ int yynerrs; @@ -1248,37 +1114,18 @@ int yynerrs; | yyparse. | `----------*/ -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) int yyparse (void) -#else -int -yyparse () - -#endif -#endif { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. + 'yyss': related to states. + 'yyvs': related to semantic values. - Refer to the stacks thru separate pointers, to allow yyoverflow + Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ @@ -1296,7 +1143,7 @@ yyparse () int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ - int yytoken; + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; @@ -1314,9 +1161,8 @@ yyparse () Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -1325,14 +1171,6 @@ yyparse () yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - goto yysetstate; /*------------------------------------------------------------. @@ -1353,23 +1191,23 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1377,22 +1215,22 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1401,10 +1239,10 @@ yyparse () yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1433,7 +1271,7 @@ yybackup: if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; + yychar = yylex (); } if (yychar <= YYEOF) @@ -1473,7 +1311,9 @@ yybackup: yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -1496,7 +1336,7 @@ yyreduce: yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1510,9 +1350,7 @@ yyreduce: switch (yyn) { case 4: - -/* Line 1806 of yacc.c */ -#line 132 "parsedate.y" +#line 132 "parsedate.y" /* yacc.c:1646 */ { yyHaveTime++; #ifdef lint @@ -1522,313 +1360,286 @@ yyreduce: } #endif /* lint */ } +#line 1364 "y.tab.c" /* yacc.c:1646 */ break; case 5: - -/* Line 1806 of yacc.c */ -#line 141 "parsedate.y" +#line 141 "parsedate.y" /* yacc.c:1646 */ { yyHaveTime++; - yyTimezone = (yyvsp[(2) - (2)].Number); + yyTimezone = (yyvsp[0].Number); } +#line 1373 "y.tab.c" /* yacc.c:1646 */ break; case 6: - -/* Line 1806 of yacc.c */ -#line 145 "parsedate.y" +#line 145 "parsedate.y" /* yacc.c:1646 */ { yyHaveDate++; } +#line 1381 "y.tab.c" /* yacc.c:1646 */ break; case 7: - -/* Line 1806 of yacc.c */ -#line 148 "parsedate.y" +#line 148 "parsedate.y" /* yacc.c:1646 */ { yyHaveRel = 1; } +#line 1389 "y.tab.c" /* yacc.c:1646 */ break; case 8: - -/* Line 1806 of yacc.c */ -#line 153 "parsedate.y" +#line 153 "parsedate.y" /* yacc.c:1646 */ { - if ((yyvsp[(1) - (2)].Number) < 100) { - yyHour = (yyvsp[(1) - (2)].Number); + if ((yyvsp[-1].Number) < 100) { + yyHour = (yyvsp[-1].Number); yyMinutes = 0; } else { - yyHour = (yyvsp[(1) - (2)].Number) / 100; - yyMinutes = (yyvsp[(1) - (2)].Number) % 100; + yyHour = (yyvsp[-1].Number) / 100; + yyMinutes = (yyvsp[-1].Number) % 100; } yySeconds = 0; - yyMeridian = (yyvsp[(2) - (2)].Meridian); + yyMeridian = (yyvsp[0].Meridian); } +#line 1406 "y.tab.c" /* yacc.c:1646 */ break; case 9: - -/* Line 1806 of yacc.c */ -#line 165 "parsedate.y" +#line 165 "parsedate.y" /* yacc.c:1646 */ { - yyHour = (yyvsp[(1) - (4)].Number); - yyMinutes = (yyvsp[(3) - (4)].Number); + yyHour = (yyvsp[-3].Number); + yyMinutes = (yyvsp[-1].Number); yySeconds = 0; - yyMeridian = (yyvsp[(4) - (4)].Meridian); + yyMeridian = (yyvsp[0].Meridian); } +#line 1417 "y.tab.c" /* yacc.c:1646 */ break; case 10: - -/* Line 1806 of yacc.c */ -#line 171 "parsedate.y" +#line 171 "parsedate.y" /* yacc.c:1646 */ { - yyHour = (yyvsp[(1) - (4)].Number); - yyMinutes = (yyvsp[(3) - (4)].Number); - yyTimezone = (yyvsp[(4) - (4)].Number); + yyHour = (yyvsp[-3].Number); + yyMinutes = (yyvsp[-1].Number); + yyTimezone = (yyvsp[0].Number); yyMeridian = MER24; yyDSTmode = DSToff; } +#line 1429 "y.tab.c" /* yacc.c:1646 */ break; case 11: - -/* Line 1806 of yacc.c */ -#line 178 "parsedate.y" +#line 178 "parsedate.y" /* yacc.c:1646 */ { - yyHour = (yyvsp[(1) - (6)].Number); - yyMinutes = (yyvsp[(3) - (6)].Number); - yySeconds = (yyvsp[(5) - (6)].Number); - yyMeridian = (yyvsp[(6) - (6)].Meridian); + yyHour = (yyvsp[-5].Number); + yyMinutes = (yyvsp[-3].Number); + yySeconds = (yyvsp[-1].Number); + yyMeridian = (yyvsp[0].Meridian); } +#line 1440 "y.tab.c" /* yacc.c:1646 */ break; case 12: - -/* Line 1806 of yacc.c */ -#line 184 "parsedate.y" +#line 184 "parsedate.y" /* yacc.c:1646 */ { - yyHour = (yyvsp[(1) - (6)].Number); - yyMinutes = (yyvsp[(3) - (6)].Number); - yySeconds = (yyvsp[(5) - (6)].Number); - yyTimezone = (yyvsp[(6) - (6)].Number); + yyHour = (yyvsp[-5].Number); + yyMinutes = (yyvsp[-3].Number); + yySeconds = (yyvsp[-1].Number); + yyTimezone = (yyvsp[0].Number); yyMeridian = MER24; yyDSTmode = DSToff; } +#line 1453 "y.tab.c" /* yacc.c:1646 */ break; case 13: - -/* Line 1806 of yacc.c */ -#line 194 "parsedate.y" +#line 194 "parsedate.y" /* yacc.c:1646 */ { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyDSTmode = DSToff; } +#line 1462 "y.tab.c" /* yacc.c:1646 */ break; case 14: - -/* Line 1806 of yacc.c */ -#line 198 "parsedate.y" +#line 198 "parsedate.y" /* yacc.c:1646 */ { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyDSTmode = DSTon; } +#line 1471 "y.tab.c" /* yacc.c:1646 */ break; case 15: - -/* Line 1806 of yacc.c */ -#line 202 "parsedate.y" +#line 202 "parsedate.y" /* yacc.c:1646 */ { /* Only allow "GMT+300" and "GMT-0800" */ - if ((yyvsp[(1) - (2)].Number) != 0) { + if ((yyvsp[-1].Number) != 0) { YYABORT; } - (yyval.Number) = (yyvsp[(2) - (2)].Number); + (yyval.Number) = (yyvsp[0].Number); yyDSTmode = DSToff; } +#line 1484 "y.tab.c" /* yacc.c:1646 */ break; case 16: - -/* Line 1806 of yacc.c */ -#line 210 "parsedate.y" +#line 210 "parsedate.y" /* yacc.c:1646 */ { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyDSTmode = DSToff; } +#line 1493 "y.tab.c" /* yacc.c:1646 */ break; case 17: - -/* Line 1806 of yacc.c */ -#line 216 "parsedate.y" +#line 216 "parsedate.y" /* yacc.c:1646 */ { int i; /* Unix and GMT and numeric timezones -- a little confusing. */ - if ((yyvsp[(1) - (1)].Number) < 0) { + if ((yyvsp[0].Number) < 0) { /* Don't work with negative modulus. */ - (yyvsp[(1) - (1)].Number) = -(yyvsp[(1) - (1)].Number); - if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) { + (yyvsp[0].Number) = -(yyvsp[0].Number); + if ((yyvsp[0].Number) > 9999 || (i = (yyvsp[0].Number) % 100) >= 60) { YYABORT; } - (yyval.Number) = ((yyvsp[(1) - (1)].Number) / 100) * 60 + i; + (yyval.Number) = ((yyvsp[0].Number) / 100) * 60 + i; } else { - if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) { + if ((yyvsp[0].Number) > 9999 || (i = (yyvsp[0].Number) % 100) >= 60) { YYABORT; } - (yyval.Number) = -(((yyvsp[(1) - (1)].Number) / 100) * 60 + i); + (yyval.Number) = -(((yyvsp[0].Number) / 100) * 60 + i); } } +#line 1517 "y.tab.c" /* yacc.c:1646 */ break; case 18: - -/* Line 1806 of yacc.c */ -#line 237 "parsedate.y" +#line 237 "parsedate.y" /* yacc.c:1646 */ { - yyMonth = (yyvsp[(1) - (3)].Number); - yyDay = (yyvsp[(3) - (3)].Number); + yyMonth = (yyvsp[-2].Number); + yyDay = (yyvsp[0].Number); } +#line 1526 "y.tab.c" /* yacc.c:1646 */ break; case 19: - -/* Line 1806 of yacc.c */ -#line 241 "parsedate.y" +#line 241 "parsedate.y" /* yacc.c:1646 */ { - if ((yyvsp[(1) - (5)].Number) > 100) { - yyYear = (yyvsp[(1) - (5)].Number); - yyMonth = (yyvsp[(3) - (5)].Number); - yyDay = (yyvsp[(5) - (5)].Number); + if ((yyvsp[-4].Number) > 100) { + yyYear = (yyvsp[-4].Number); + yyMonth = (yyvsp[-2].Number); + yyDay = (yyvsp[0].Number); } else { - yyMonth = (yyvsp[(1) - (5)].Number); - yyDay = (yyvsp[(3) - (5)].Number); - yyYear = (yyvsp[(5) - (5)].Number); + yyMonth = (yyvsp[-4].Number); + yyDay = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); } } +#line 1543 "y.tab.c" /* yacc.c:1646 */ break; case 20: - -/* Line 1806 of yacc.c */ -#line 253 "parsedate.y" +#line 253 "parsedate.y" /* yacc.c:1646 */ { - yyMonth = (yyvsp[(1) - (2)].Number); - yyDay = (yyvsp[(2) - (2)].Number); + yyMonth = (yyvsp[-1].Number); + yyDay = (yyvsp[0].Number); } +#line 1552 "y.tab.c" /* yacc.c:1646 */ break; case 21: - -/* Line 1806 of yacc.c */ -#line 257 "parsedate.y" +#line 257 "parsedate.y" /* yacc.c:1646 */ { - yyMonth = (yyvsp[(1) - (4)].Number); - yyDay = (yyvsp[(2) - (4)].Number); - yyYear = (yyvsp[(4) - (4)].Number); + yyMonth = (yyvsp[-3].Number); + yyDay = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); } +#line 1562 "y.tab.c" /* yacc.c:1646 */ break; case 22: - -/* Line 1806 of yacc.c */ -#line 262 "parsedate.y" +#line 262 "parsedate.y" /* yacc.c:1646 */ { - yyDay = (yyvsp[(1) - (2)].Number); - yyMonth = (yyvsp[(2) - (2)].Number); + yyDay = (yyvsp[-1].Number); + yyMonth = (yyvsp[0].Number); } +#line 1571 "y.tab.c" /* yacc.c:1646 */ break; case 23: - -/* Line 1806 of yacc.c */ -#line 266 "parsedate.y" +#line 266 "parsedate.y" /* yacc.c:1646 */ { - yyDay = (yyvsp[(1) - (3)].Number); - yyMonth = (yyvsp[(2) - (3)].Number); - yyYear = (yyvsp[(3) - (3)].Number); + yyDay = (yyvsp[-2].Number); + yyMonth = (yyvsp[-1].Number); + yyYear = (yyvsp[0].Number); } +#line 1581 "y.tab.c" /* yacc.c:1646 */ break; case 24: - -/* Line 1806 of yacc.c */ -#line 271 "parsedate.y" +#line 271 "parsedate.y" /* yacc.c:1646 */ { - yyDay = (yyvsp[(3) - (5)].Number); - yyMonth = (yyvsp[(4) - (5)].Number); - yyYear = (yyvsp[(5) - (5)].Number); + yyDay = (yyvsp[-2].Number); + yyMonth = (yyvsp[-1].Number); + yyYear = (yyvsp[0].Number); } +#line 1591 "y.tab.c" /* yacc.c:1646 */ break; case 25: - -/* Line 1806 of yacc.c */ -#line 278 "parsedate.y" +#line 278 "parsedate.y" /* yacc.c:1646 */ { - yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number); + yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); } +#line 1599 "y.tab.c" /* yacc.c:1646 */ break; case 26: - -/* Line 1806 of yacc.c */ -#line 281 "parsedate.y" +#line 281 "parsedate.y" /* yacc.c:1646 */ { - yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number); + yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); } +#line 1607 "y.tab.c" /* yacc.c:1646 */ break; case 27: - -/* Line 1806 of yacc.c */ -#line 284 "parsedate.y" +#line 284 "parsedate.y" /* yacc.c:1646 */ { - yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number); + yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); } +#line 1615 "y.tab.c" /* yacc.c:1646 */ break; case 28: - -/* Line 1806 of yacc.c */ -#line 287 "parsedate.y" +#line 287 "parsedate.y" /* yacc.c:1646 */ { - yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number); + yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); } +#line 1623 "y.tab.c" /* yacc.c:1646 */ break; case 29: - -/* Line 1806 of yacc.c */ -#line 292 "parsedate.y" +#line 292 "parsedate.y" /* yacc.c:1646 */ { (yyval.Meridian) = MER24; } +#line 1631 "y.tab.c" /* yacc.c:1646 */ break; case 30: - -/* Line 1806 of yacc.c */ -#line 295 "parsedate.y" +#line 295 "parsedate.y" /* yacc.c:1646 */ { - (yyval.Meridian) = (yyvsp[(1) - (1)].Meridian); + (yyval.Meridian) = (yyvsp[0].Meridian); } +#line 1639 "y.tab.c" /* yacc.c:1646 */ break; - -/* Line 1806 of yacc.c */ -#line 1832 "y.tab.c" +#line 1643 "y.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1850,7 +1661,7 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state + /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -1865,9 +1676,9 @@ yyreduce: goto yynewstate; -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ @@ -1918,20 +1729,20 @@ yyerrlab: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } } /* Else will try to reuse lookahead token after shifting the error @@ -1950,7 +1761,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -1963,35 +1774,37 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -2015,7 +1828,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined(yyoverflow) || YYERROR_VERBOSE +#if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2034,14 +1847,14 @@ yyreturn: yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2052,14 +1865,9 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + return yyresult; } - - - -/* Line 2067 of yacc.c */ -#line 300 "parsedate.y" +#line 300 "parsedate.y" /* yacc.c:1906 */ /* Month and day table. */ @@ -2567,4 +2375,3 @@ main(int ac, char *av[]) /* NOTREACHED */ } #endif /* TEST */ - diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 729846d3e..c545e4dde 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -1,7 +1,7 @@ /* * Server functions which perform operations on room objects. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -32,7 +32,7 @@ struct floor *floorcache[MAXFLOORS]; int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) { if ( (!(CC->logged_in)) && (!(CC->internal_pgm)) - && (!config.c_guest_logins) + && (!CtdlGetConfigInt("c_guest_logins")) ) { return(om_not_logged_in); } @@ -139,7 +139,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, is_me = 1; } - if ((is_me) && (config.c_guest_logins) && (!CC->logged_in)) { + if ((is_me) && (CtdlGetConfigInt("c_guest_logins")) && (!CC->logged_in)) { is_guest = 1; } @@ -166,7 +166,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, } /* Force the properties of the Aide room */ - if (!strcasecmp(roombuf->QRname, config.c_aideroom)) { + if (!strcasecmp(roombuf->QRname, CtdlGetConfigStr("c_aideroom"))) { if (userbuf->axlevel >= AxAideU) { retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED; } else { @@ -339,9 +339,9 @@ void room_sanity_check(struct ctdlroom *qrbuf) /* Listing order of 0 is illegal except for base rooms */ if (qrbuf->QRorder == 0) if (!(qrbuf->QRflags & QR_MAILBOX) && - strncasecmp(qrbuf->QRname, config.c_baseroom, ROOMNAMELEN) + strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN) && - strncasecmp(qrbuf->QRname, config.c_aideroom, ROOMNAMELEN)) + strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) qrbuf->QRorder = 64; } @@ -398,7 +398,7 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) /* * CtdlGetRoomLock() - same as getroom() but locks the record (if supported) */ -int CtdlGetRoomLock(struct ctdlroom *qrbuf, char *room_name) +int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name) { register int retval; retval = CtdlGetRoom(qrbuf, room_name); @@ -819,8 +819,8 @@ void CtdlUserGoto(char *where, int display_result, int transiently, /* Know the room ... but not if it's the page log room, or if the * caller specified that we're only entering this room transiently. */ - if ((strcasecmp(CCC->room.QRname, config.c_logpages)) - && (transiently == 0) ) { + if ((strcasecmp(CCC->room.QRname, CtdlGetConfigStr("c_logpages"))) && (transiently == 0)) + { vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT; vbuf.v_flags = vbuf.v_flags | V_ACCESS; } @@ -945,7 +945,7 @@ void CtdlUserGoto(char *where, int display_result, int transiently, */ void convert_room_name_macros(char *towhere, size_t maxlen) { if (!strcasecmp(towhere, "_BASEROOM_")) { - safestrncpy(towhere, config.c_baseroom, maxlen); + safestrncpy(towhere, CtdlGetConfigStr("c_baseroom"), maxlen); } else if (!strcasecmp(towhere, "_MAIL_")) { safestrncpy(towhere, MAILROOM, maxlen); @@ -957,7 +957,7 @@ void convert_room_name_macros(char *towhere, size_t maxlen) { safestrncpy(towhere, USERDRAFTROOM, maxlen); } else if (!strcasecmp(towhere, "_BITBUCKET_")) { - safestrncpy(towhere, config.c_twitroom, maxlen); + safestrncpy(towhere, CtdlGetConfigStr("c_twitroom"), maxlen); } else if (!strcasecmp(towhere, "_CALENDAR_")) { safestrncpy(towhere, USERCALENDARROOM, maxlen); @@ -1039,8 +1039,8 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) { } /* Reject change of floor for baseroom/aideroom */ - if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN) || - !strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) { + if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN) || + !strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) { new_floor = 0; } @@ -1055,13 +1055,11 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) { begin_critical_section(S_CONFIG); /* If baseroom/aideroom name changes, update config */ - if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN)) { - safestrncpy(config.c_baseroom, new_name, ROOMNAMELEN); - put_config(); + if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) { + CtdlSetConfigStr("c_baseroom", new_name); } - if (!strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) { - safestrncpy(config.c_aideroom, new_name, ROOMNAMELEN); - put_config(); + if (!strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) { + CtdlSetConfigStr("c_aideroom", new_name); } end_critical_section(S_CONFIG); diff --git a/citadel/serv_extensions.c b/citadel/serv_extensions.c index 4b4e44c08..568d9a3ae 100644 --- a/citadel/serv_extensions.c +++ b/citadel/serv_extensions.c @@ -1,8 +1,8 @@ /* - * Citadel Dynamic Loading Module + * Citadel Extension Loader * Written by Brian Costello * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -21,6 +21,7 @@ #include "serv_extensions.h" #include "ctdl_module.h" +#include "config.h" int DebugModules = 0; @@ -1131,7 +1132,7 @@ void CtdlRegisterServiceHook(int tcp_port, newfcn->ServiceName = ServiceName; if (sockpath != NULL) { - newfcn->msock = ctdl_uds_server(sockpath, config.c_maxsessions, error); + newfcn->msock = ctdl_uds_server(sockpath, CtdlGetConfigInt("c_maxsessions"), error); snprintf(message, SIZ, "Unix domain socket '%s': ", sockpath); } else if (tcp_port <= 0) { /* port -1 to disable */ @@ -1141,12 +1142,12 @@ void CtdlRegisterServiceHook(int tcp_port, return; } else { - newfcn->msock = ctdl_tcp_server(config.c_ip_addr, + newfcn->msock = ctdl_tcp_server(CtdlGetConfigStr("c_ip_addr"), tcp_port, - config.c_maxsessions, + CtdlGetConfigInt("c_maxsessions"), error); snprintf(message, SIZ, "TCP port %s:%d: (%s) ", - config.c_ip_addr, tcp_port, ServiceName); + CtdlGetConfigStr("c_ip_addr"), tcp_port, ServiceName); } if (newfcn->msock > 0) { diff --git a/citadel/server.h b/citadel/server.h index 6aedb5463..4a6dbc1d2 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -1,3 +1,17 @@ +/* + * Main declarations file for the Citadel server + * + * Copyright (c) 1987-2015 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #ifndef SERVER_H #define SERVER_H @@ -66,6 +80,7 @@ typedef struct __recptypes { #define CTDLEXIT_DB 105 /* Unable to initialize database */ #define CTDLEXIT_LIBCITADEL 106 /* Incorrect version of libcitadel */ #define CTDL_EXIT_UNSUP_AUTH 107 /* Unsupported auth mode configured */ +#define CTDLEXIT_UNUSER 108 /* Could not determine uid to run as */ /* * Reasons why a session would be terminated (set CC->kill_me to these values) @@ -101,22 +116,8 @@ enum { #define CS_POSTING 4 /* Posting */ -/* - * This is the control record for the message base... - */ -struct CitControl { - long MMhighest; /* highest message number in file */ - unsigned MMflags; /* Global system flags */ - long MMnextuser; /* highest user number on system */ - long MMnextroom; /* highest room number on system */ - int version; /* Server-hosted upgrade level */ - int fulltext_wordbreaker; /* ID of wordbreaker in use */ - long MMfulltext; /* highest message number indexed */ - int MMdbversion; /* Version of Berkeley DB used on previous server run */ -}; - extern int ScheduledShutdown; -extern struct CitControl CitControl; +extern uid_t ctdluid; struct ExpressMessage { struct ExpressMessage *next; @@ -210,6 +211,7 @@ enum { CDB_EUIDINDEX, /* locate msgs by EUID */ CDB_USERSBYNUMBER, /* index of users by number */ CDB_OPENID, /* associates OpenIDs with users */ + CDB_CONFIG, /* system configuration database */ MAXCDB /* total number of CDB's defined */ }; diff --git a/citadel/server_main.c b/citadel/server_main.c index 6a7d293fb..a015876e5 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -26,6 +26,7 @@ #include "user_ops.h" #include "ecrash.h" +uid_t ctdluid = 0; const char *CitadelServiceUDS="citadel-UDS"; const char *CitadelServiceTCP="citadel-TCP"; @@ -51,6 +52,8 @@ int main(int argc, char **argv) char ctdldir[PATH_MAX]=CTDLDIR; int syslog_facility = LOG_DAEMON; const char *eDebuglist[] = {NULL, NULL}; + uid_t u = 0; + struct passwd *p = NULL; #ifdef HAVE_RUN_DIR struct stat filestats; #endif @@ -64,7 +67,7 @@ int main(int argc, char **argv) InitializeMasterTSD(); /* parse command-line arguments */ - while ((a=getopt(argc, argv, "l:dh:x:t:B:Dr")) != EOF) switch(a) { + while ((a=getopt(argc, argv, "l:dh:x:t:B:Dru:")) != EOF) switch(a) { case 'l': safestrncpy(facility, optarg, sizeof(facility)); @@ -108,16 +111,57 @@ int main(int argc, char **argv) drop_root_perms = 0; break; + /* -u tells the server what uid to run under... */ + case 'u': + u = atoi(optarg); + if (u > 0) { + ctdluid = u; + } + else { + p = getpwnam(optarg); + if (p) { + u = p->pw_uid; + } + } + if (u > 0) { + ctdluid = u; + } + break; + default: /* any other parameter makes it crash and burn */ fprintf(stderr, "citserver: usage: " "citserver " "[-l LogFacility] " "[-d] [-D] [-r] " + "[-u user] " "[-h HomeDir]\n" ); exit(1); } + + /* Last ditch effort to determine the user name ... if there's a user called "citadel" then use that */ + if (ctdluid == 0) { + p = getpwnam("citadel"); + if (!p) { + p = getpwnam("bbs"); + } + if (!p) { + p = getpwnam("guest"); + } + if (p) { + u = p->pw_uid; + } + if (u > 0) { + ctdluid = u; + } + } + + if ((ctdluid == 0) && (drop_root_perms == 0)) { + fprintf(stderr, "citserver: cannot determine user to run as; please specify -r or -u options\n"); + exit(CTDLEXIT_UNUSER); + } + StartLibCitadel(basesize); openlog("citserver", ( running_as_daemon ? (LOG_PID) : (LOG_PID | LOG_PERROR) ), @@ -161,25 +205,15 @@ int main(int argc, char **argv) syslog(LOG_DEBUG, "Called as: %s", argv[0]); syslog(LOG_INFO, "%s", libcitadel_version_string()); - /* Load site-specific configuration */ - syslog(LOG_INFO, "Loading citadel.config"); - get_config(); - - /* get_control() MUST MUST MUST be called BEFORE the databases are opened!! */ - syslog(LOG_INFO, "Acquiring control record"); - get_control(); - - put_config(); - #ifdef HAVE_RUN_DIR /* on some dists rundir gets purged on startup. so we need to recreate it. */ if (stat(ctdl_run_dir, &filestats)==-1){ #ifdef HAVE_GETPWUID_R #ifdef SOLARIS_GETPWUID - pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); + pwp = getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf)); #else // SOLARIS_GETPWUID - getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); + getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); #endif // SOLARIS_GETPWUID #else // HAVE_GETPWUID_R pwp = NULL; @@ -190,7 +224,7 @@ int main(int argc, char **argv) "unable to create run directory [%s]: %s", ctdl_run_dir, strerror(errno)); - if (chown(ctdl_run_dir, config.c_ctdluid, (pwp==NULL)?-1:pw.pw_gid) != 0) + if (chown(ctdl_run_dir, ctdluid, (pwp==NULL)?-1:pw.pw_gid) != 0) syslog(LOG_EMERG, "unable to set the access rights for [%s]: %s", ctdl_run_dir, strerror(errno)); @@ -253,7 +287,7 @@ int main(int argc, char **argv) /* * Bind the server to our favorite TCP port (usually 504). */ - CtdlRegisterServiceHook(config.c_port_number, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_port_number"), NULL, citproto_begin_session, do_command_loop, @@ -276,7 +310,7 @@ int main(int argc, char **argv) /* * If we need host auth, start our chkpwd daemon. */ - if (config.c_auth_mode == AUTHMODE_HOST) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { start_chkpwd_daemon(); } @@ -297,9 +331,9 @@ int main(int argc, char **argv) #ifdef HAVE_GETPWUID_R #ifdef SOLARIS_GETPWUID - pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); + pwp = getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf)); #else // SOLARIS_GETPWUID - getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); + getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); #endif // SOLARIS_GETPWUID #else // HAVE_GETPWUID_R pwp = NULL; diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 787a93a3d..0dda5bd55 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -7,7 +7,7 @@ * If we ever port to a different platform and either have multiple * variants of this file or simply load it up with #ifdefs. * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -39,6 +39,7 @@ #include #include "citserver.h" +#include "config.h" #include "ctdl_module.h" #include "sysdep_decls.h" @@ -731,7 +732,7 @@ int HaveMoreLinesWaiting(CitContext *CCC) */ INLINE int client_read(char *buf, int bytes) { - return(client_read_to(buf, bytes, config.c_sleeping)); + return(client_read_to(buf, bytes, CtdlGetConfigInt("c_sleeping"))); } int CtdlClientGetLine(StrBuf *Target) @@ -1475,8 +1476,8 @@ SKIP_SELECT: pthread_mutex_lock(&ThreadCountMutex); --active_workers; - if ((active_workers + config.c_min_workers < num_workers) && - (num_workers > config.c_min_workers)) + if ((active_workers + CtdlGetConfigInt("c_min_workers") < num_workers) && + (num_workers > CtdlGetConfigInt("c_min_workers"))) { num_workers--; pthread_mutex_unlock(&ThreadCountMutex); diff --git a/citadel/techdoc/hack.txt b/citadel/techdoc/hack.txt index f88432690..1af927555 100644 --- a/citadel/techdoc/hack.txt +++ b/citadel/techdoc/hack.txt @@ -229,97 +229,97 @@ all software should be written to IGNORE fields not currently defined. The type bytes currently defined are: -BYTE Mnemonic Enum / Comments - -A Author eAuthor - Name of originator of message. -B Big message eBig_message - This is a flag which indicates that the message is - big, and Citadel is storing the body in a separate - record. You will never see this field because the - internal API handles it. -C RemoteRoom eRemoteRoom - when sent via Citadel Networking, this is the room - its going to be put on the remote site. -D Destination eDestination - Contains name of the system this message should - be sent to, for mail routing (private mail only). -E Exclusive ID eExclusiveID - A persistent alphanumeric Message ID used for - network replication. When a message arrives that - contains an Exclusive ID, any existing messages which - contain the same Exclusive ID and are *older* than this - message should be deleted. If there exist any messages - with the same Exclusive ID that are *newer*, then this - message should be dropped. -F rFc822 address erFc822Addr - For Internet mail, this is the delivery address of the - message author. -H Human node name eHumanNode - Human-readable name of system message originated on. -I Message ID emessageId - An RFC822-compatible message ID for this message. -J Journal eJournal - The presence of this field indicates that the message - is disqualified from being journaled, perhaps because - it is itself a journalized message and we wish to - avoid double journaling. -K Reply-To eReplyTo - the Reply-To header for mailinglist outbound messages -L List-ID eListID - Mailing list identification, as per RFC 2919 -M Message Text eMesageText - Normal ASCII, newlines seperated by CR's or LF's, - null terminated as always. -N Nodename eNodeName - Contains node name of system message originated on. -O Room eOriginalRoom - Room of origin. -P Path eMessagePath - Complete path of message, as in the UseNet news - standard. A user should be able to send Internet mail - to this path. (Note that your system name will not be - tacked onto this until you're sending the message to - someone else) -R Recipient eRecipient - Only present in Mail messages. -S Special field eSpecialField - Only meaningful for messages being spooled over a - network. Usually means that the message isn't really - a message, but rather some other network function: - -> "S" followed by "FILE" (followed by a null, of - course) means that the message text is actually an - IGnet/Open file transfer. (OBSOLETE) - -> "S" followed by "CANCEL" means that this message - should be deleted from the local message base once - it has been replicated to all network systems. -T date/Time eTimestamp - Unix timestamp containing the creation date/time of - the message. -U sUbject eMsgSubject - Optional. - Developers may choose whether they wish to - generate or display subject fields. -V enVelope-to eenVelopeTo - The recipient specified in incoming SMTP messages. -W Wefewences eWeferences - Previous message ID's for conversation threading. When - converting from RFC822 we use References: if present, or - In-Reply-To: otherwise. - (Who in extnotify spool messages which don't need to know - other message ids) -Y carbon copY eCarbonCopY - Optional, and only in Mail messages. -0 Error eErrorMsg - This field is typically never found in a message on - disk or in transit. Message scanning modules are - expected to fill in this field when rejecting a message - with an explanation as to what happened (virus found, - message looks like spam, etc.) -1 suppress index eSuppressIdx - The presence of this field indicates that the message is - disqualified from being added to the full text index. -2 extnotify eExtnotify - Used internally by the serv_extnotify module. -3 msgnum eVltMsgNum - Used internally to pass the local message number in the - database to after-save hooks. Discarded afterwards. +BYTE Enum Mnemonic Enum / Comments + +A eAuthor Author eAuthor + Name of originator of message. +B eBig_message Big message eBig_message + This is a flag which indicates that the message is + big, and Citadel is storing the body in a separate + record. You will never see this field because the + internal API handles it. +C eRemoteRoom RemoteRoom eRemoteRoom + when sent via Citadel Networking, this is the room + its going to be put on the remote site. +D eDestination Destination eDestination + Contains name of the system this message should + be sent to, for mail routing (private mail only). +E eExclusiveID Exclusive ID eExclusiveID + A persistent alphanumeric Message ID used for + network replication. When a message arrives that + contains an Exclusive ID, any existing messages which + contain the same Exclusive ID and are *older* than this + message should be deleted. If there exist any messages + with the same Exclusive ID that are *newer*, then this + message should be dropped. +F erFc822Addr rFc822 address erFc822Addr + For Internet mail, this is the delivery address of the + message author. +H eHumanNode Human node name eHumanNode + Human-readable name of system message originated on. +I emessageId Message ID emessageId + An RFC822-compatible message ID for this message. +J eJournal Journal eJournal + The presence of this field indicates that the message + is disqualified from being journaled, perhaps because + it is itself a journalized message and we wish to + avoid double journaling. +K eReplyTo Reply-To eReplyTo + the Reply-To header for mailinglist outbound messages +L eListID List-ID eListID + Mailing list identification, as per RFC 2919 +M eMesageText Message Text eMesageText + Normal ASCII, newlines seperated by CR's or LF's, + null terminated as always. +N eNodeName Nodename eNodeName + Contains node name of system message originated on. +O eOriginalRoom Room eOriginalRoom - Room of origin. +P eMessagePath Path eMessagePath + Complete path of message, as in the UseNet news + standard. A user should be able to send Internet mail + to this path. (Note that your system name will not be + tacked onto this until you're sending the message to + someone else) +R eRecipient Recipient eRecipient - Only present in Mail messages. +S eSpecialField Special field eSpecialField + Only meaningful for messages being spooled over a + network. Usually means that the message isn't really + a message, but rather some other network function: + -> "S" followed by "FILE" (followed by a null, of + course) means that the message text is actually an + IGnet/Open file transfer. (OBSOLETE) + -> "S" followed by "CANCEL" means that this message + should be deleted from the local message base once + it has been replicated to all network systems. +T eTimestamp date/Time eTimestamp + Unix timestamp containing the creation date/time of + the message. +U eMsgSubject sUbject eMsgSubject - Optional. + Developers may choose whether they wish to + generate or display subject fields. +V eenVelopeTo enVelope-to eenVelopeTo + The recipient specified in incoming SMTP messages. +W eWeferences Wefewences eWeferences + Previous message ID's for conversation threading. When + converting from RFC822 we use References: if present, or + In-Reply-To: otherwise. + (Who in extnotify spool messages which don't need to know + other message ids) +Y eCarbonCopY carbon copY eCarbonCopY + Optional, and only in Mail messages. +0 eErrorMsg Error eErrorMsg + This field is typically never found in a message on + disk or in transit. Message scanning modules are + expected to fill in this field when rejecting a message + with an explanation as to what happened (virus found, + message looks like spam, etc.) +1 eSuppressIdx suppress index eSuppressIdx + The presence of this field indicates that the message is + disqualified from being added to the full text index. +2 eExtnotify extnotify eExtnotify - Used internally by the serv_extnotify module. +3 eVltMsgNum msgnum eVltMsgNum + Used internally to pass the local message number in the + database to after-save hooks. Discarded afterwards. EXAMPLE diff --git a/citadel/threads.c b/citadel/threads.c index 228a5b0aa..5cb70334c 100644 --- a/citadel/threads.c +++ b/citadel/threads.c @@ -1,7 +1,7 @@ /* * Thread handling stuff for Citadel server * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -19,6 +19,7 @@ #include "modules_init.h" #include "serv_extensions.h" #include "ctdl_module.h" +#include "config.h" #include "context.h" #include "threads.h" @@ -171,7 +172,7 @@ void go_threading(void) * they are all in use. */ while (!server_shutting_down) { - if ((active_workers == num_workers) && (num_workers < config.c_max_workers)) { + if ((active_workers == num_workers) && (num_workers < CtdlGetConfigInt("c_max_workers"))) { CtdlThreadCreate(worker_thread); } usleep(1000000); diff --git a/citadel/user_ops.c b/citadel/user_ops.c index 6cce2a15b..1e8792d71 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -19,6 +19,7 @@ #include "control.h" #include "support.h" #include "citserver.h" +#include "config.h" #include "citadel_ldap.h" #include "ctdl_module.h" #include "user_ops.h" @@ -314,7 +315,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) { if (who->axlevel <= AxProbU) return(0); /* Globally enabled? */ - if (config.c_restrict == 0) return(1); + if (CtdlGetConfigInt("c_restrict") == 0) return(1); /* User flagged ok? */ if (who->flags & US_INTERNET) return(2); @@ -338,7 +339,7 @@ int CtdlAccessCheck(int required_level) return(-1); } - if ((required_level >= ac_logged_in_or_guest) && (CC->logged_in == 0) && (!config.c_guest_logins)) { + if ((required_level >= ac_logged_in_or_guest) && (CC->logged_in == 0) && (CtdlGetConfigInt("c_guest_logins") == 0)) { cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return(-1); } @@ -528,10 +529,10 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname) /* If a "master user" is defined, handle its authentication if specified */ CC->is_master = 0; - if ((configlen.c_master_user > 0) && - (configlen.c_master_pass > 0) && - (authname != NULL) && - (!strcasecmp(authname, config.c_master_user))) + if ( (!IsEmptyStr(CtdlGetConfigStr("c_master_user"))) && + (!IsEmptyStr(CtdlGetConfigStr("c_master_pass"))) && + (authname != NULL) && + (!strcasecmp(authname, CtdlGetConfigStr("c_master_user"))) ) { CC->is_master = 1; } @@ -545,7 +546,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname) return login_not_found; } - if (config.c_auth_mode == AUTHMODE_HOST) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { /* host auth mode */ @@ -586,7 +587,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname) } #ifdef HAVE_LDAP - else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + else if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { /* LDAP auth mode */ @@ -670,14 +671,14 @@ void do_login(void) /* If this user's name is the name of the system administrator * (as specified in setup), automatically assign access level 6. */ - if (!strcasecmp(CCC->user.fullname, config.c_sysadm)) { + if (!strcasecmp(CCC->user.fullname, CtdlGetConfigStr("c_sysadm"))) { CCC->user.axlevel = AxAideU; } /* If we're authenticating off the host system, automatically give * root the highest level of access. */ - if (config.c_auth_mode == AUTHMODE_HOST) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { if (CCC->user.uid == 0) { CCC->user.axlevel = AxAideU; } @@ -691,7 +692,7 @@ void do_login(void) * the vCard module's login hook runs. */ snprintf(CCC->cs_inet_email, sizeof CCC->cs_inet_email, "%s@%s", - CCC->user.fullname, config.c_fqdn); + CCC->user.fullname, CtdlGetConfigStr("c_fqdn")); convert_spaces_to_underscores(CCC->cs_inet_email); /* Create any personal rooms required by the system. @@ -706,7 +707,7 @@ void do_login(void) PerformSessionHooks(EVT_LOGIN); /* Enter the lobby */ - CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL); + CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL); } @@ -877,10 +878,10 @@ int CtdlTryPassword(const char *password, long len) } if (CCC->is_master) { - code = strcmp(password, config.c_master_pass); + code = strcmp(password, CtdlGetConfigStr("c_master_pass")); } - else if (config.c_auth_mode == AUTHMODE_HOST) { + else if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { /* host auth mode */ @@ -910,7 +911,7 @@ int CtdlTryPassword(const char *password, long len) } #ifdef HAVE_LDAP - else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + else if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { /* LDAP auth mode */ @@ -1052,7 +1053,7 @@ int internal_create_user (const char *username, long len, struct ctdluser *usbuf usbuf->timescalled = 0; usbuf->posted = 0; - usbuf->axlevel = config.c_initax; + usbuf->axlevel = CtdlGetConfigInt("c_initax"); usbuf->lastcall = time(NULL); /* fetch a new user number */ @@ -1089,7 +1090,7 @@ int create_user(const char *newusername, long len, int become_user) strproc(username); - if (config.c_auth_mode == AUTHMODE_HOST) { + if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) { /* host auth mode */ @@ -1121,7 +1122,7 @@ int create_user(const char *newusername, long len, int become_user) } #ifdef HAVE_LDAP - if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { + if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) { if (CtdlTryUserLDAP(username, NULL, 0, username, sizeof username, &uid, 0) != 0) { return(ERROR + NO_SUCH_USER); } @@ -1239,7 +1240,7 @@ int CtdlForgetThisRoom(void) { visit vbuf; /* On some systems, Admins are not allowed to forget rooms */ - if (is_aide() && (config.c_aide_zap == 0) + if (is_aide() && (CtdlGetConfigInt("c_aide_zap") == 0) && ((CC->room.QRflags & QR_MAILBOX) == 0) ) { return(1); } @@ -1254,7 +1255,7 @@ int CtdlForgetThisRoom(void) { CtdlPutUserLock(&CC->user); /* Return to the Lobby, so we don't end up in an undefined room */ - CtdlUserGoto(config.c_baseroom, 0, 0, NULL, NULL, NULL, NULL); + CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL); return(0); } diff --git a/citadel/utils/ctdlmigrate.c b/citadel/utils/ctdlmigrate.c index 5a5d0c474..baa5f6de7 100644 --- a/citadel/utils/ctdlmigrate.c +++ b/citadel/utils/ctdlmigrate.c @@ -137,10 +137,14 @@ int main(int argc, char *argv[]) "(example: ctdl.foo.org)\n" "--> "); getz(remote_host); + +get_remote_user: printf("\nEnter the name of a user on %s who has full access to Citadel files\n" "(usually root)\n--> ", remote_host); getz(remote_user); + if (IsEmptyStr(remote_user)) + goto get_remote_user; printf("\nEstablishing an SSH connection to the source system...\n\n"); unlink(socket_path); @@ -194,6 +198,8 @@ int main(int argc, char *argv[]) } printf("ctdlmigrate will now begin a database migration...\n"); + printf(" if the system doesn't start working, \n"); + printf(" have a look at the syslog for pending jobs needing to be terminated.\n"); snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s -w3600 MIGR export", socket_path, remote_user, remote_host, remote_sendcommand); diff --git a/citadel/utils/setup.c b/citadel/utils/setup.c index ff65b2338..eec27947f 100644 --- a/citadel/utils/setup.c +++ b/citadel/utils/setup.c @@ -1066,95 +1066,6 @@ void GetDefaultValStr(char *WhereTo, size_t nMax, const char *VarName, const cha } -void set_default_values(void) -{ -#if 0 - struct passwd *pw; - struct utsname my_utsname; - struct hostent *he; - - /* Determine our host name, in case we need to use it as a default */ - uname(&my_utsname); - - /* set some sample/default values in place of blanks... */ - GetDefaultVALSTR(c_nodename, my_utsname.nodename); - strtok(config.c_nodename, "."); - if (IsEmptyStr(config.c_fqdn) ) { - if ((he = gethostbyname(my_utsname.nodename)) != NULL) { - safestrncpy(config.c_fqdn, he->h_name, sizeof config.c_fqdn); - } else { - safestrncpy(config.c_fqdn, my_utsname.nodename, sizeof config.c_fqdn); - } - } - GetDefaultVALSTR(c_humannode, _("My System")); - GetDefaultVALSTR(c_phonenum, _("US 800 555 1212")); - - GetDefaultVALCHAR(c_initax, 4); - - GetDefaultVALSTR(c_moreprompt, ""); - GetDefaultVALSTR(c_twitroom, "Trashcan"); - GetDefaultVALSTR(c_baseroom, BASEROOM); - GetDefaultVALSTR(c_aideroom, "Aide"); - GetDefaultVALINT(c_port_number, 504); - - GetDefaultVALINT(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 (config.c_ctdluid == 0) { - pw = getpwnam("guest"); - if (pw != NULL) { - config.c_ctdluid = pw->pw_uid; - } - } - if (config.c_createax == 0) { - config.c_createax = 3; - } - /* - * Negative values for maxsessions are not allowed. - */ - if (config.c_maxsessions < 0) { - config.c_maxsessions = 0; - } - /* We need a system default message expiry policy, because this is - * the top level and there's no 'higher' policy to fall back on. - * By default, do not expire messages at all. - */ - if (config.c_ep.expire_mode == 0) { - config.c_ep.expire_mode = EXPIRE_MANUAL; - config.c_ep.expire_value = 0; - } - - /* - * Default port numbers for various services - */ - GetDefaultVALINT(c_smtp_port, 25); - GetDefaultVALINT(c_pop3_port, 110); - GetDefaultVALINT(c_imap_port, 143); - GetDefaultVALINT(c_msa_port, 587); - GetDefaultVALINT(c_smtps_port, 465); - GetDefaultVALINT(c_pop3s_port, 995); - GetDefaultVALINT(c_imaps_port, 993); - GetDefaultVALINT(c_pftcpdict_port, -1); - GetDefaultVALINT(c_managesieve_port, 2020); - GetDefaultVALINT(c_xmpp_c2s_port, 5222); - GetDefaultVALINT(c_xmpp_s2s_port, 5269); - GetDefaultVALINT(c_nntp_port, 119); - GetDefaultVALINT(c_nntps_port, 563); -#endif -} - - int main(int argc, char *argv[]) { @@ -1313,8 +1224,6 @@ int main(int argc, char *argv[]) system("clear 2>/dev/null"); } - set_default_values(); - /* Go through a series of dialogs prompting for config info */ for (curr = 1; curr < eMaxQuestions; ++curr) { edit_value(curr); diff --git a/libcitadel/configure.in b/libcitadel/configure.in index 5e332a220..595f0b6ed 100755 --- a/libcitadel/configure.in +++ b/libcitadel/configure.in @@ -5,7 +5,7 @@ dnl dnl Ensure that libcitadel is configured with autoconf 2.52 or newer AC_PREREQ(2.52) -AC_INIT(libcitadel, 4.8.29, http://uncensored.citadel.org) +AC_INIT(libcitadel, 4.9.01, http://uncensored.citadel.org) AC_CONFIG_SRCDIR(Makefile.in) AC_CONFIG_AUX_DIR(conftools) @@ -23,7 +23,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0 dnl LIBCURRENT=4 -LIBREVISION=829 +LIBREVISION=901 LIBAGE=0 sinclude(conftools/libtool.m4) diff --git a/libcitadel/debian/changelog b/libcitadel/debian/changelog index d2f0708a2..b26175f6a 100644 --- a/libcitadel/debian/changelog +++ b/libcitadel/debian/changelog @@ -1,3 +1,9 @@ +libcitadel (9.01-1) stable; urgency=low + + * new release + + -- Wilfried Goesgens Wed, 01 Apr 2015 12:56:30 -0400 + libcitadel (8.29-1) stable; urgency=low * development prerelease diff --git a/libcitadel/lib/b64/cencode.c b/libcitadel/lib/b64/cencode.c index e440f3784..64720f6cf 100644 --- a/libcitadel/lib/b64/cencode.c +++ b/libcitadel/lib/b64/cencode.c @@ -92,6 +92,7 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in) case step_A: break; } + *codechar++ = '\r'; *codechar++ = '\n'; return codechar - code_out; diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 3e48a35f3..31c8394a5 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -28,7 +28,7 @@ #include #include -#define LIBCITADEL_VERSION_NUMBER 829 +#define LIBCITADEL_VERSION_NUMBER 901 /* * Here's a bunch of stupid magic to make the MIME parser portable. @@ -108,7 +108,7 @@ typedef enum _room_views { #define BLOG_EUIDBUF_SIZE 40 #ifndef IsEmptyStr -#define IsEmptyStr(a) ((a)[0] == '\0') +#define IsEmptyStr(a) ( ( (a) == NULL ) || ((a)[0] == '\0') ) #endif @@ -445,7 +445,6 @@ char *memreadline(char *start, char *buf, int maxlen); char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen); const char *cmemreadline(const char *start, char *buf, int maxlen); const char *cmemreadlinelen(const char *start, char *buf, int maxlen, int *retlen); -#define IsEmptyStr(a) ((a)[0] == '\0') #define num_parms(source) num_tokens(source,(char)'|') int stripout(char *str, char leftboundary, char rightboundary); long stripallbut(char *str, char leftboundary, char rightboundary); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index 134ff4779..0340ce4d4 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -2827,7 +2827,7 @@ int StrBufDecodeBase64To(const StrBuf *BufIn, StrBuf *BufOut) return -1; if (BufOut->BufSize < BufIn->BufUsed) - IncreaseBuf(BufOut, BufIn->BufUsed, 0); + IncreaseBuf(BufOut, 0, BufIn->BufUsed); BufOut->BufUsed = CtdlDecodeBase64(BufOut->buf, BufIn->buf, diff --git a/libcitadel/lib/tools.c b/libcitadel/lib/tools.c index bc0cb767b..14e43071a 100644 --- a/libcitadel/lib/tools.c +++ b/libcitadel/lib/tools.c @@ -292,7 +292,6 @@ size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int li int breaklength = 68; int readlength = 3 * breaklength / 4; - int t; int destoffset; int sourceoffset; int sourceremaining; @@ -318,12 +317,7 @@ size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int li dest[destoffset++] = '\n'; } - t = destoffset; destoffset += base64_encode_blockend(&(dest[destoffset]), &_state); - if (t < destoffset) { - dest[destoffset++] = '\r'; - dest[destoffset++] = '\n'; - } } else { destoffset = base64_encode_block(source, sourcelen, dest, &_state); diff --git a/textclient/configure.ac b/textclient/configure.ac index c967b6308..daee0dc2c 100644 --- a/textclient/configure.ac +++ b/textclient/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.52) -AC_INIT([Citadel], [8.29], [http://www.citadel.org/]) +AC_INIT([Citadel], [9.01], [http://www.citadel.org/]) AC_REVISION([$Revision: 5108 $]) AC_CONFIG_HEADER(sysdep.h) diff --git a/textclient/debian/changelog b/textclient/debian/changelog index 76a46ee86..dc8c6726b 100644 --- a/textclient/debian/changelog +++ b/textclient/debian/changelog @@ -1,3 +1,9 @@ +textclient (9.01-1) stable; urgency=low + + * new release + + -- Wilfried Goesgens Wed, 01 Apr 2015 12:56:30 -0400 + textclient (8.29-1) stable; urgency=low * development prerelease diff --git a/textclient/src/citadel.c b/textclient/src/citadel.c index d5f187c3d..c06f9ff05 100644 --- a/textclient/src/citadel.c +++ b/textclient/src/citadel.c @@ -1,15 +1,15 @@ /* * Main source module for the client program. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -1007,11 +1007,10 @@ void system_info(CtdlIPC *ipc) scr_printf("You are connected to %s (%s) @%s\n", ipc->ServInfo.nodename, ipc->ServInfo.humannode, ipc->ServInfo.fqdn); scr_printf("running %s with text client v%.2f,\n", ipc->ServInfo.software, (float)CLIENT_VERSION/100); scr_printf("server build %s,\n", ipc->ServInfo.svn_revision, (float)CLIENT_VERSION/100); - scr_printf("and located in %s.\n", ipc->ServInfo.site_location); - scr_printf("Connected users %d / Active users %d / Highest message #%ld\n", mrtg_users, mrtg_active_users, mrtg_himessage); - scr_printf("Server uptime: %s\n", mrtg_server_uptime); - scr_printf("Your system administrator is %s.\n", ipc->ServInfo.sysadm); - scr_printf("Copyright (C)1987-2009 by the Citadel development team\n"); + scr_printf("and located in %s.\n", ipc->ServInfo.site_location); + scr_printf("Connected users %d / Active users %d / Highest message #%ld\n", mrtg_users, mrtg_active_users, mrtg_himessage); + scr_printf("Server uptime: %s\n", mrtg_server_uptime); + scr_printf("Your system administrator is %s.\n", ipc->ServInfo.sysadm); } /* diff --git a/webcit/configure.ac b/webcit/configure.ac index f17cc5819..6f74bdcba 100644 --- a/webcit/configure.ac +++ b/webcit/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. dnl $Id$ -AC_INIT([WebCit], [8.29], [http://www.citadel.org/]) +AC_INIT([WebCit], [9.01], [http://www.citadel.org/]) AC_SUBST(PROG_SUBDIRS) @@ -88,6 +88,7 @@ dnl Checks for header files. AC_HEADER_STDC dnl AC_HEADER_SYS_WAIT +AC_CHECK_FUNCS(crypt gethostbyname connect flock getpwnam_r getpwuid_r getloadavg) AC_CACHE_CHECK( [for call semantics from getpwuid_r], ac_cv_call_getpwuid_r, @@ -238,7 +239,7 @@ dnl Checks for the discount markdown library. AC_CHECK_LIB(markdown, markdown, [ - LDFLAGS="$LDFLAGS -lmarkdown" + LIBS="$LIBS -lmarkdown" AC_DEFINE(HAVE_MARKDOWN,[],[whether we have markdown message rendering]) ]) diff --git a/webcit/debian/changelog b/webcit/debian/changelog index 325696725..d48253326 100644 --- a/webcit/debian/changelog +++ b/webcit/debian/changelog @@ -1,3 +1,9 @@ +webcit (9.01-1) stable; urgency=low + + * new release + + -- Wilfried Goesgens Wed, 01 Apr 2015 12:56:30 -0400 + webcit (8.29-1) stable; urgency=low * development prerelease diff --git a/webcit/debian/webcit.init b/webcit/debian/webcit.init index b99e24ca3..2375ac712 100644 --- a/webcit/debian/webcit.init +++ b/webcit/debian/webcit.init @@ -25,7 +25,6 @@ PIDFILE=$RUNDIR/$NAME.pid SCRIPTNAME=/etc/init.d/webcit SENDCOMMAND=/usr/sbin/sendcommand DEFAULT=/etc/default/webcit -LOGDIR=/var/log/webcit/ DROP_TO_UID=`id -u nobody` # Exit if the package is not installed @@ -79,10 +78,6 @@ do_start() mkdir -p $RUNDIR fi - if test ! -d $LOGDIR; then - mkdir -p $LOGDIR - fi - # are we disabled? if test "$1" -lt "0"; then return 0 @@ -93,7 +88,7 @@ do_start() # 1 if daemon was already running # 2 if daemon could not be started if $DAEMON -u $DROP_TO_UID -D$PIDFILE.$1 \ - -p$@ -t$LOGDIR/access.${1}.log $4; then + -p$@ $4; then return 0 else return 2 diff --git a/webcit/paramhandling.c b/webcit/paramhandling.c index f7d1a325d..bfc8ac7ff 100644 --- a/webcit/paramhandling.c +++ b/webcit/paramhandling.c @@ -23,9 +23,83 @@ void free_url(void *U) { urlcontent *u = (urlcontent*) U; FreeStrBuf(&u->url_data); + if (u->sub != NULL) { + DeleteHash(&u->sub); + } free(u); } +void PutSubstructUrlKey(HashList *list, urlcontent *u, char **keys, long *lengths, int max, int which){ + void *vUrl; + urlcontent *subu; + HashList *thisList = list; + if (GetHash(list, keys[which], lengths[which], &vUrl) && + (vUrl != NULL)) + { + subu = (urlcontent*) vUrl; + if (subu->sub == NULL) { + subu->sub = NewHash(1, NULL); + } + thisList = subu->sub; + } + else if (which < max) { + subu = (urlcontent *) malloc(sizeof(urlcontent)); + + memcpy(subu->url_key, keys[which], lengths[which]); + subu->klen = lengths[which]; + subu->url_data = NULL; + subu->sub = NewHash(1, NULL); + + Put(list, subu->url_key, subu->klen, subu, free_url); + thisList = subu->sub; + } + if (which >= max) { + Put(thisList, keys[which], lengths[which], u, free_url); + } + else { + PutSubstructUrlKey(subu->sub, u, keys, lengths, max, which + 1); + } +} + +void PutUrlKey(HashList *urlstrings, urlcontent *u, int have_colons) { + if (!have_colons) { + Put(urlstrings, u->url_key, u->klen, u, free_url); + } + else { + char *keys[10]; + long lengths[10]; + int i = 0; + char *pch; + char *pchs; + char *pche; + + memset(&keys, 0, sizeof(keys)); + memset(&lengths, 0, sizeof(lengths)); + pchs = pch = u->url_key; + pche = u->url_key + u->klen; + while ((i < 10) && (pch <= pche)) { + if ((*pch != ':') && (pch != pche)){ + pch ++; + continue; + } + *pch = '\0'; + if (i == 0) { + /* Separate the toplevel key : */ + u->klen = pch - pchs; + } + /* sub-section: */ + keys[i] = pchs; + lengths[i] = pch - pchs; + + pch++; + pchs = pch; + i++; + } + + PutSubstructUrlKey(urlstrings, u, keys, lengths, i - 1, 0); + } +} + /* * Extract variables from the URL. */ @@ -42,8 +116,12 @@ void ParseURLParams(StrBuf *url) eptr = ChrPtr(url) + StrLength(url); up = ChrPtr(url); while ((up < eptr) && (!IsEmptyStr(up))) { + int have_colon = 0; aptr = up; while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '=')) { + if (*aptr == ':') { + have_colon = 1; + } aptr++; } if (*aptr != '=') { @@ -57,23 +135,25 @@ void ParseURLParams(StrBuf *url) } keylen = aptr - up - 1; /* -1 -> '=' */ if (keylen > sizeof(u->url_key)) { - syslog(LOG_WARNING, "%s:%d: invalid url_key of size %d in string size %d", + syslog(LOG_WARNING, "%s:%d: invalid url_key of size %d in string size %ld", __FILE__, __LINE__, keylen, sizeof(u->url_key) ); } - u = (urlcontent *) malloc(sizeof(urlcontent)); - memcpy(u->url_key, up, keylen); - u->url_key[keylen] = '\0'; if (keylen < 0) { syslog(LOG_WARNING, "%s:%d: invalid url_key of size %d", __FILE__, __LINE__, keylen); free(u); return; } + u = (urlcontent *) malloc(sizeof(urlcontent)); + memcpy(u->url_key, up, keylen); + u->url_key[keylen] = '\0'; + u->klen = keylen; + u->sub = NULL; + if (strncmp(u->url_key, "__", 2) != 0) { - Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url); len = bptr - aptr; u->url_data = NewStrBufPlain(aptr, len); StrBufUnescape(u->url_data, 1); @@ -83,6 +163,7 @@ void ParseURLParams(StrBuf *url) StrLength(u->url_data), ChrPtr(u->url_data)); #endif + PutUrlKey(WCC->Hdr->urlstrings, u, have_colon); } else { len = bptr - aptr; @@ -336,10 +417,12 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, keylen = safestrncpy(u->url_key, name, sizeof(u->url_key)); u->url_data = NewStrBufPlain(content, length); + u->klen = keylen; + u->sub = NULL; if (strncmp(u->url_key, "__", 2) != 0) { - Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url); + PutUrlKey(WCC->Hdr->urlstrings, u, (strchr(u->url_key, ':') != NULL)); } else { syslog(LOG_INFO, "REJECTED because of __ is internal only: %s = [%d] %s\n", @@ -382,7 +465,9 @@ void PutBstr(const char *key, long keylen, StrBuf *Value) } u = (urlcontent*)malloc(sizeof(urlcontent)); memcpy(u->url_key, key, keylen + 1); + u->klen = keylen; u->url_data = Value; + u->sub = NULL; Put(WC->Hdr->urlstrings, u->url_key, keylen, u, free_url); } void PutlBstr(const char *key, long keylen, long Value) diff --git a/webcit/roomlist.c b/webcit/roomlist.c index 42cd9db10..b9f967ce6 100644 --- a/webcit/roomlist.c +++ b/webcit/roomlist.c @@ -441,7 +441,7 @@ HashList *GetThisRoomPossibleMAlias(StrBuf *Target, WCTemplputParams *TP) if (Domains == NULL) return NULL; if (GetCount(Domains) == 0) { - DeleteHash(Domains); + DeleteHash(&Domains); return NULL; } PossibleAliases = NewHash(1, NULL); diff --git a/webcit/serv_func.c b/webcit/serv_func.c index dd1cc4dee..f6642325f 100644 --- a/webcit/serv_func.c +++ b/webcit/serv_func.c @@ -187,7 +187,7 @@ int GetConnected (void) /* Server isn't ready for us? */ if (short_status != 2) { - if (Status == 571) { + if (Status == 551) { hprintf("HTTP/1.1 503 Service Unavailable\r\n"); hprintf("Content-type: text/plain; charset=utf-8\r\n"); wc_printf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator.")); diff --git a/webcit/subst.c b/webcit/subst.c index 586f4f8c6..ab4edce38 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -679,6 +679,7 @@ void StrBufAppendTemplate(StrBuf *Target, char EscapeAs = ' '; if ((FormatTypeIndex < TP->Tokens->nParameters) && + (TP->Tokens->Params[FormatTypeIndex] != NULL) && (TP->Tokens->Params[FormatTypeIndex]->Type == TYPE_STR) && (TP->Tokens->Params[FormatTypeIndex]->len >= 1)) { pFmt = TP->Tokens->Params[FormatTypeIndex]->Start; @@ -1983,6 +1984,7 @@ typedef struct _HashIterator { RetrieveHashlistFunc GetHash; HashDestructorFunc Destructor; SubTemplFunc DoSubTemplate; + FilterByParamFunc Filter; } HashIterator; void RegisterITERATOR(const char *Name, long len, @@ -1991,6 +1993,7 @@ void RegisterITERATOR(const char *Name, long len, RetrieveHashlistFunc GetHash, SubTemplFunc DoSubTempl, HashDestructorFunc Destructor, + FilterByParamFunc Filter, CtxType ContextType, CtxType XPectContextType, int Flags) @@ -2004,6 +2007,7 @@ void RegisterITERATOR(const char *Name, long len, It->GetHash = GetHash; It->DoSubTemplate = DoSubTempl; It->Destructor = Destructor; + It->Filter = Filter; It->ContextType = ContextType; It->XPectContextType = XPectContextType; It->Flags = Flags; @@ -2157,6 +2161,13 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) } while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) { if ((Status.n >= StartAt) && (Status.n <= StopAt)) { + + if ((It->Filter != NULL) && + It->Filter(Status.Key, Status.KeyLen, vContext, Target, TP)) + { + continue; + } + if (DetectGroupChange && Status.n > 0) { Status.GroupChange = SortBy->GroupChange(vContext, vLastContext); } diff --git a/webcit/subst.h b/webcit/subst.h index bd6f8318d..d80c97f52 100644 --- a/webcit/subst.h +++ b/webcit/subst.h @@ -180,7 +180,7 @@ typedef struct _ConditionalStruct { typedef void (*SubTemplFunc)(StrBuf *TemplBuffer, WCTemplputParams *TP); typedef HashList *(*RetrieveHashlistFunc)(StrBuf *Target, WCTemplputParams *TP); typedef void (*HashDestructorFunc) (HashList **KillMe); - +typedef int (*FilterByParamFunc)(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP); extern WCTemplputParams NoCtx; @@ -362,13 +362,15 @@ long GetTokenDefine(const char *Name, #define IT_NOFLAG 0 #define IT_FLAG_DETECT_GROUPCHANGE (1<<0) -#define RegisterIterator(a, b, c, d, e, f, g, h, i) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f, g, h, i) +#define RegisterIterator(a, b, c, d, e, f, g, h, i) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f, NULL, g, h, i) +#define RegisterFilteredIterator(a, b, c, d, e, f, g, h, i, j) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f, g, h, i, j) void RegisterITERATOR(const char *Name, long len, /* Our identifier */ - int AdditionalParams, /* doe we use more parameters? */ + int AdditionalParams, /* do we use more parameters? */ HashList *StaticList, /* pointer to webcit lifetime hashlists */ RetrieveHashlistFunc GetHash, /* else retrieve the hashlist by calling this function */ SubTemplFunc DoSubTempl, /* call this function on each iteration for svput & friends */ HashDestructorFunc Destructor, /* use this function to shut down the hash; NULL if its a reference */ + FilterByParamFunc Filter, /* use this function if you want to skip items */ CtxType ContextType, /* which context do we provide to the subtemplate? */ CtxType XPectContextType, /* which context do we expct to be called in? */ int Flags); diff --git a/webcit/sysdep.c b/webcit/sysdep.c index 94314a25c..4b8f4c6a6 100644 --- a/webcit/sysdep.c +++ b/webcit/sysdep.c @@ -557,6 +557,9 @@ webcit_calc_dirs_n_files(int relh, const char *basedir, int home, char *webcitdi void drop_root(uid_t UID) { struct passwd pw, *pwp = NULL; +#ifdef HAVE_GETPWUID_R + char pwbuf[SIZ]; +#endif /* * Now that we've bound the sockets, change to the Citadel user id and its diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index 1a9f11a67..47c04c724 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -15,44 +15,257 @@ #include "calendar.h" CtxType CTX_VCARD = CTX_NONE; +long VCEnumCounter = 0; + +typedef enum _VCStrEnum { + FlatString, + StringCluster, + PhoneNumber, + EmailAddr, + Street, + Number, + AliasFor, + Base64BinaryAttachment, + TerminateList +}VCStrEnum; +typedef struct vcField vcField; +struct vcField { + ConstStr STR; + VCStrEnum Type; + vcField *Sub; + long cval; + const char *Str; +}; + +vcField VCStr_Ns [] = { + {{HKEY("last")}, FlatString, NULL, 0, "Last Name"}, + {{HKEY("first")}, FlatString, NULL, 0, "First Name"}, + {{HKEY("middle")}, FlatString, NULL, 0, "Middle Name"}, + {{HKEY("prefix")}, FlatString, NULL, 0, "Prefix"}, + {{HKEY("suffix")}, FlatString, NULL, 0, "Suffix"}, + {{HKEY("")}, TerminateList, NULL, 0, ""} +}; + +vcField VCStr_Addrs [] = { + {{HKEY("POBox")}, FlatString, NULL, 0, "PO box"}, + {{HKEY("address")}, FlatString, NULL, 0, "Address"}, + {{HKEY("address2")}, FlatString, NULL, 0, ""}, + {{HKEY("city")}, FlatString, NULL, 0, "City"}, + {{HKEY("state")}, FlatString, NULL, 0, "State"}, + {{HKEY("zip")}, FlatString, NULL, 0, "ZIP code"}, + {{HKEY("country")}, FlatString, NULL, 0, "Country"}, + {{HKEY("")}, TerminateList, NULL, 0, ""} +}; + +vcField VCStrE [] = { + {{HKEY("version")}, Number, NULL, 0, ""}, + {{HKEY("rev")}, Number, NULL, 0, ""}, + {{HKEY("label")}, FlatString, NULL, 0, ""}, + {{HKEY("uid")}, FlatString, NULL, 0, ""}, + {{HKEY("n")}, StringCluster, VCStr_Ns, 0, ""}, /* N is name, but only if there's no FN already there */ + {{HKEY("fn")}, FlatString, NULL, 0, ""}, /* FN (full name) is a true 'display name' field */ + {{HKEY("title")}, FlatString, NULL, 0, "Title:"}, + {{HKEY("org")}, FlatString, NULL, 0, "Organization:"},/* organization */ + {{HKEY("email")}, EmailAddr, NULL, 0, "E-mail:"}, + {{HKEY("tel")}, PhoneNumber, NULL, 0, "Telephone:"}, + {{HKEY("adr")}, StringCluster, VCStr_Addrs, 0, "Address:"}, + {{HKEY("photo")}, Base64BinaryAttachment, NULL, 0, "Photo:"}, + {{HKEY("tel;home")}, PhoneNumber, NULL, 0, " (home)"}, + {{HKEY("tel;work")}, PhoneNumber, NULL, 0, " (work)"}, + {{HKEY("tel;fax")}, PhoneNumber, NULL, 0, " (fax)"}, + {{HKEY("tel;cell")}, PhoneNumber, NULL, 0, " (cell)"}, + {{HKEY("email;internet")}, EmailAddr, NULL, 0, "E-mail:"}, + {{HKEY("")}, TerminateList, NULL, 0, ""} +}; ConstStr VCStr [] = { + {HKEY("")}, {HKEY("n")}, /* N is name, but only if there's no FN already there */ {HKEY("fn")}, /* FN (full name) is a true 'display name' field */ {HKEY("title")}, /* title */ {HKEY("org")}, /* organization */ {HKEY("email")}, {HKEY("tel")}, - {HKEY("tel_tel")}, - {HKEY("tel_work")}, - {HKEY("tel_home")}, - {HKEY("tel_cell")}, + {HKEY("work")}, + {HKEY("home")}, + {HKEY("cell")}, {HKEY("adr")}, {HKEY("photo")}, {HKEY("version")}, {HKEY("rev")}, - {HKEY("label")} + {HKEY("label")}, + {HKEY("uid")} }; -typedef enum _eVC{ - VC_n, - VC_fn, - VC_title, - VC_org, - VC_email, - VC_tel, - VC_tel_tel, - VC_tel_work, - VC_tel_home, - VC_tel_cell, - VC_adr, - VC_photo, - VC_version, - VC_rev, - VC_label -} eVC; - -HashList *VCToEnum = NULL; + +HashList *DefineToToken = NULL; +HashList *VCTokenToDefine = NULL; +HashList *vcNames = NULL; /* todo: fill with the name strings */ + + +void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount) +{ + RegisterTokenParamDefine(SKEY(name), vf->cval); + Put(DefineToToken, LKEY(vf->cval), vf, reference_free_handler); + + syslog(LOG_DEBUG, "Token: %s -> %ld, %d", + ChrPtr(name), + vf->cval, + inTokenCount); + +} + +void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int layer) +{ + int i = 0; + while (vf[i].STR.len > 0) { + StrBuf *subStr = NewStrBuf(); + vf[i].cval = (*enumCounter) ++; + StrBufAppendBuf(subStr, BaseStr, 0); + if (StrLength(subStr) > 0) { + StrBufAppendBufPlain(subStr, HKEY("."), 0); + } + StrBufAppendBufPlain(subStr, CKEY(vf[i].STR), 0); + if (layer == 0) { + Put(VCTokenToDefine, CKEY(vf[i].STR), &vf[i], reference_free_handler); + } + switch (vf[i].Type) { + case FlatString: + break; + case StringCluster: + { + autoRegisterTokens(enumCounter, vf[i].Sub, subStr, 1); + i++; + continue; + } + break; + case PhoneNumber: + break; + case EmailAddr: + break; + case Street: + break; + case Number: + break; + case AliasFor: + break; + case Base64BinaryAttachment: + break; + case TerminateList: + break; + } + RegisterVCardToken(&vf[i], subStr, i); + i++; + } +} + +int preeval_vcard_item(WCTemplateToken *Token) +{ + WCTemplputParams TPP; + WCTemplputParams *TP; + int searchFieldNo; + StrBuf *Target = NULL; + + memset(&TPP, 0, sizeof(WCTemplputParams)); + TP = &TPP; + TP->Tokens = Token; + searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); + if (searchFieldNo >= VCEnumCounter) { + LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP, + "Invalid define"); + return 0; + } + return 1; +} + +void tmpl_vcard_item(StrBuf *Target, WCTemplputParams *TP) +{ + void *vItem; + long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); + HashList *vc = (HashList*) CTX(CTX_VCARD); + if (GetHash(vc, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { + StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); + } +} + +int preeval_vcard_name_str(WCTemplateToken *Token) +{ + WCTemplputParams TPP; + WCTemplputParams *TP; + int searchFieldNo; + StrBuf *Target = NULL; + + memset(&TPP, 0, sizeof(WCTemplputParams)); + TP = &TPP; + TP->Tokens = Token; + searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); + if (searchFieldNo >= VCEnumCounter) { + LogTemplateError(NULL, "VCardName", ERR_PARM1, TP, + "Invalid define"); + return 0; + } + return 1; +} + +void tmpl_vcard_name_str(StrBuf *Target, WCTemplputParams *TP) +{ + void *vItem; + long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); + /* todo: get descriptive string for this vcard type */ + if (GetHash(vcNames, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { + StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); + } +} + +int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) +{ + long searchType; + long type = 0; + void *vvcField; + int rc = 0; + + memcpy(type, key, sizeof(long)); + searchType = GetTemplateTokenNumber(Target, TP, 3, 0);/// todo: which? + + if (GetHash(DefineToToken, LKEY(type), &vvcField) && + (vvcField != NULL)) + { + vcField *t = (vcField*) vvcField; + if (t && t->Type == searchType) { + rc = 1; + } + } + return rc; +} + +int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) +{ + HashList *vc = (HashList*) CTX(CTX_VCARD); + long HaveFieldType = GetTemplateTokenNumber(Target, TP, 2, 0); + int rc = 0; + void *vVCitem; + const char *Key; + long len; + HashPos *it = GetNewHashPos(vc, 0); + while (GetNextHashPos(vc, it, &len, &Key, &vVCitem) && + (vVCitem != NULL)) + { + void *vvcField; + long type = 0; + memcpy(&type, Key, sizeof(long)); + if (GetHash(DefineToToken, LKEY(type), &vvcField) && + (vvcField != NULL)) + { + vcField *t = (vcField*) vvcField; + if (t && t->Type == HaveFieldType) { + rc = 1; + break; + } + } + } + DeleteHashPos(&it); + return rc; +} /* * Record compare function for sorting address book indices @@ -361,7 +574,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att utf8ify_rfc822_string(&v->prop[i].value); if (is_qp) { - // %ff can become 6 bytes in utf8 + /* %ff can become 6 bytes in utf8 */ thisvalue = malloc(len * 2 + 3); j = CtdlDecodeQuotedPrintable( thisvalue, v->prop[i].value, @@ -369,7 +582,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att thisvalue[j] = 0; } else if (is_b64) { - // ff will become one byte.. + /* ff will become one byte.. */ thisvalue = malloc(len + 50); CtdlDecodeBase64( thisvalue, v->prop[i].value, @@ -533,6 +746,20 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att StrBufAppendPrintf(Target, "\n"); } + +void PutVcardItem(vcField *thisField, HashList *thisVC, StrBuf *ThisFieldStr, int is_qp, StrBuf *Swap) +{ + /* if we have some untagged QP, detect it here. */ + if (is_qp || (strstr(ChrPtr(ThisFieldStr), "=?")!=NULL)){ + StrBuf *b; + StrBuf_RFC822_to_Utf8(Swap, ThisFieldStr, NULL, NULL); /* default charset, current charset */ + b = ThisFieldStr; + ThisFieldStr = Swap; + Swap = b; + FlushStrBuf(Swap); + } + Put(thisVC, LKEY(thisField->cval), ThisFieldStr, HFreeStrBuf); +} /* * html print a vcard * display_vcard() calls this after parsing the textual vCard into @@ -554,36 +781,103 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim { StrBuf *Val = NULL; StrBuf *Swap = NULL; - int i, j; - char buf[SIZ]; + int i, j, k; + char buf[20]; //SIZ]; int is_qp = 0; int is_b64 = 0; + int ntokens, len; StrBuf *thisname = NULL; - char firsttoken[SIZ]; + char firsttoken[20]; ///SIZ]; void *V; + HashList *thisVC; + StrBuf *thisVCToken; + void *vField = NULL; + thisVC = NewHash(1, lFlathash); Swap = NewStrBuf (); thisname = NewStrBuf(); + thisVCToken = NewStrBufPlain(NULL, 63); for (i=0; i<(v->numprops); ++i) { + FlushStrBuf(thisVCToken); is_qp = 0; is_b64 = 0; + syslog(LOG_DEBUG, "i: %d oneprop: %s - value: %s", i, v->prop[i].name, v->prop[i].value); StrBufPlain(thisname, v->prop[i].name, -1); StrBufLowerCase(thisname); /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); - - for (j=0; j 0) { + StrBufAppendBufPlain(thisVCToken, HKEY(";"), 0); + } + StrBufAppendBufPlain(thisVCToken, buf, len, 0); + /* + if (GetHash(VCToEnum, buf, len, &V)) + { + evc[k] = (int) V; + + Put(VC, IKEY(evc), Val, HFreeStrBuf); + + syslog(LOG_DEBUG, "[%ul] -> k: %d %s - %s", evc, k, buf, VCStr[evc[k]].Key); + k++; + } +*/ + + } + } + + vField = NULL; + if ((StrLength(thisVCToken) > 0) && + GetHash(VCTokenToDefine, SKEY(thisVCToken), &vField) && + (vField != NULL)) { + vcField *thisField = (vcField *)vField; + StrBuf *ThisFieldStr = NULL; + syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key); + switch (thisField->Type) { + case StringCluster: { + int j = 0; + const char *Pos = NULL; + StrBuf *thisArray = NewStrBufPlain(v->prop[i].value, -1); + StrBuf *Buf = NewStrBufPlain(NULL, StrLength(thisArray)); + while (thisField->Sub[j].STR.len > 0) { + StrBufExtract_NextToken(Buf, thisArray, &Pos, ';'); + ThisFieldStr = NewStrBufDup(Buf); + + PutVcardItem(&thisField->Sub[j], thisVC, ThisFieldStr, is_qp, Swap); + j++; + } + } + break; + case FlatString: + case PhoneNumber: + case EmailAddr: + case Street: + case Number: + case AliasFor: + /* copy over the payload into a StrBuf */ + ThisFieldStr = NewStrBufPlain(v->prop[i].value, -1); + PutVcardItem(thisField, thisVC, ThisFieldStr, is_qp, Swap); + + break; + case Base64BinaryAttachment: + case TerminateList: + break; + } + } - /* copy over the payload into a StrBuf */ Val = NewStrBufPlain(v->prop[i].value, -1); @@ -600,8 +894,10 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim StrBufDecodeBase64(Val); } - syslog(LOG_DEBUG, "%s [%s][%s]", +#if 0 + syslog(LOG_DEBUG, "-> firsttoken: %s thisname: %s Value: [%s][%s]", firsttoken, + ChrPtr(thisname), ChrPtr(Val), v->prop[i].value); if (GetHash(VCToEnum, firsttoken, strlen(firsttoken), &V)) @@ -642,18 +938,32 @@ TODO: check for layer II } */ - +#endif FreeStrBuf(&Val); - free(thisname); - thisname = NULL; + ////free(thisname); + /// thisname = NULL; } + + { + WCTemplputParams *TP = NULL; + WCTemplputParams SubTP; + FlushStrBuf(Target); + StackContext(TP, &SubTP, thisVC, CTX_VCARD, 0, NULL); + { + DoTemplate(HKEY("test_vcard"), Target, &SubTP); + } + UnStackContext(&SubTP); + } + printf("%s\n", ChrPtr(Target)); + FreeStrBuf(&thisVCToken); + DeleteHash(&thisVC);/// todo } void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) { HashList *VC = CTX(CTX_VCARD); - eVC evc; + int evc; void *vStr; evc = GetTemplateTokenNumber(Target, TP, 0, -1); @@ -737,6 +1047,7 @@ void display_vcard(StrBuf *Target, ((!isalpha(alpha)) && (!isalpha(this_alpha))) ) { +#define XXX_XXX 1 #ifdef XXX_XXX new_vcard (Target, v, full, Mime); #else @@ -1497,7 +1808,7 @@ void ServerStartModule_VCARD (void) { - VCToEnum = NewHash(0, NULL); + ///VCToEnum = NewHash(0, NULL); } @@ -1505,7 +1816,7 @@ void ServerShutdownModule_VCARD (void) { - DeleteHash(&VCToEnum); + /// DeleteHash(&VCToEnum); } void @@ -1525,24 +1836,23 @@ InitModule_VCARD WebcitAddUrlHandler(HKEY("edit_vcard"), "", 0, edit_vcard, 0); WebcitAddUrlHandler(HKEY("submit_vcard"), "", 0, submit_vcard, 0); WebcitAddUrlHandler(HKEY("vcardphoto"), "", 0, display_vcard_photo_img, NEED_URL); - +/* Put(VCToEnum, HKEY("n"), (void*)VC_n, reference_free_handler); Put(VCToEnum, HKEY("fn"), (void*)VC_fn, reference_free_handler); Put(VCToEnum, HKEY("title"), (void*)VC_title, reference_free_handler); Put(VCToEnum, HKEY("org"), (void*)VC_org, reference_free_handler); Put(VCToEnum, HKEY("email"), (void*)VC_email, reference_free_handler); Put(VCToEnum, HKEY("tel"), (void*)VC_tel, reference_free_handler); - Put(VCToEnum, HKEY("tel_tel"), (void*)VC_tel_tel, reference_free_handler); - Put(VCToEnum, HKEY("tel_work"), (void*)VC_tel_work, reference_free_handler); - Put(VCToEnum, HKEY("tel_home"), (void*)VC_tel_home, reference_free_handler); - Put(VCToEnum, HKEY("tel_cell"), (void*)VC_tel_cell, reference_free_handler); + Put(VCToEnum, HKEY("work"), (void*)VC_work, reference_free_handler); + Put(VCToEnum, HKEY("home"), (void*)VC_home, reference_free_handler); + Put(VCToEnum, HKEY("cell"), (void*)VC_cell, reference_free_handler); Put(VCToEnum, HKEY("adr"), (void*)VC_adr, reference_free_handler); Put(VCToEnum, HKEY("photo"), (void*)VC_photo, reference_free_handler); Put(VCToEnum, HKEY("version"), (void*)VC_version, reference_free_handler); Put(VCToEnum, HKEY("rev"), (void*)VC_rev, reference_free_handler); Put(VCToEnum, HKEY("label"), (void*)VC_label, reference_free_handler); - - +*/ +/* RegisterNamespace("VC", 1, 2, tmplput_VCARD_ITEM, NULL, CTX_VCARD); REGISTERTokenParamDefine(VC_n); @@ -1551,15 +1861,37 @@ InitModule_VCARD REGISTERTokenParamDefine(VC_org); REGISTERTokenParamDefine(VC_email); REGISTERTokenParamDefine(VC_tel); - REGISTERTokenParamDefine(VC_tel_tel); - REGISTERTokenParamDefine(VC_tel_work); - REGISTERTokenParamDefine(VC_tel_home); - REGISTERTokenParamDefine(VC_tel_cell); + REGISTERTokenParamDefine(VC_work); + REGISTERTokenParamDefine(VC_home); + REGISTERTokenParamDefine(VC_cell); REGISTERTokenParamDefine(VC_adr); REGISTERTokenParamDefine(VC_photo); REGISTERTokenParamDefine(VC_version); REGISTERTokenParamDefine(VC_rev); REGISTERTokenParamDefine(VC_label); +*/ + { + StrBuf *Prefix = NewStrBufPlain(HKEY("VC:")); + DefineToToken = NewHash(1, lFlathash); + VCTokenToDefine = NewHash(1, NULL); + autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0); + FreeStrBuf(&Prefix); + } + RegisterCTX(CTX_VCARD); + RegisterNamespace("VC:ITEM", 2, 2, tmpl_vcard_item, preeval_vcard_item, CTX_VCARD); + RegisterNamespace("VC:NAME", 1, 1, tmpl_vcard_name_str, preeval_vcard_name_str, CTX_VCARD); + REGISTERTokenParamDefine(FlatString); + REGISTERTokenParamDefine(StringCluster); + REGISTERTokenParamDefine(PhoneNumber); + REGISTERTokenParamDefine(EmailAddr); + REGISTERTokenParamDefine(Street); + REGISTERTokenParamDefine(Number); + REGISTERTokenParamDefine(AliasFor); + REGISTERTokenParamDefine(Base64BinaryAttachment); + REGISTERTokenParamDefine(TerminateList); + + RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD); + RegisterFilteredIterator("VC:TYPE", 1, NULL, NULL, NULL, NULL, filter_VC_ByType, CTX_STRBUF, CTX_VCARD, IT_NOFLAG); } diff --git a/webcit/webcit.h b/webcit/webcit.h index 64034c777..a087d5f37 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -1,5 +1,5 @@ /* - * 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. @@ -61,8 +61,6 @@ #define _(string) (string) #endif -#define IsEmptyStr(a) ((a)[0] == '\0') - #define DO_DBG_QR 0 #define DBG_QR(x) if(DO_DBG_QR) _DBG_QR(x) #define DBG_QR2(x) if(DO_DBG_QR) _DBG_QR2(x) @@ -129,9 +127,9 @@ extern char *ssl_cipher_list; #define PORT_NUM 2000 /* port number to listen on */ #define DEVELOPER_ID 0 #define CLIENT_ID 4 -#define CLIENT_VERSION 829 /* This version of WebCit */ -#define MINIMUM_CIT_VERSION 829 /* Minimum required version of Citadel server */ -#define LIBCITADEL_MIN 821 /* Minimum required version of libcitadel */ +#define CLIENT_VERSION 901 /* This version of WebCit */ +#define MINIMUM_CIT_VERSION 901 /* Minimum required version of Citadel server */ +#define LIBCITADEL_MIN 901 /* Minimum required version of libcitadel */ #define DEFAULT_HOST "localhost" /* Default Citadel server */ #define DEFAULT_PORT "504" #define TARGET "webcit01" /* Window target for inline URL's */ @@ -216,7 +214,9 @@ void SaveExpirePolicyFromHTTP(GPEXWhichPolicy which); typedef struct urlcontent urlcontent; struct urlcontent { char url_key[32]; /* key */ + long klen; StrBuf *url_data; /* value */ + HashList *sub; }; /* diff --git a/webcit/webserver.c b/webcit/webserver.c index 0261d696a..116c6475d 100644 --- a/webcit/webserver.c +++ b/webcit/webserver.c @@ -194,11 +194,14 @@ int main(int argc, char **argv) verbose=1; break; default: - fprintf(stderr, "usage: webcit " + fprintf(stderr, "usage:\nwebcit " "[-i ip_addr] [-p http_port] " "[-c] [-f] " "[-T Templatedebuglevel] " "[-d] [-Z] [-G i18ndumpfile] " + "[-u uid] [-h homedirectory] " + "[-D daemonizepid] [-v] " + "[-g defaultlandingpage] [-B basesize] " #ifdef HAVE_OPENSSL "[-s] [-S cipher_suites]" #endif