X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=citadel%2Fcontrol.c;fp=citadel%2Fcontrol.c;h=0000000000000000000000000000000000000000;hp=645904267539e6a166b9e0d70c0ac6ba39581790;hb=f6fcf350671e3661f8f22696eb35133014ab6a14;hpb=2e4e67a1f7f65568abace99d13a71024ad06ebde diff --git a/citadel/control.c b/citadel/control.c deleted file mode 100644 index 645904267..000000000 --- a/citadel/control.c +++ /dev/null @@ -1,810 +0,0 @@ -// -// This module handles states which are global to the entire server. -// -// Copyright (c) 1987-2021 by the citadel.org team -// -// This program is open source software. Use, duplication, or disclosure -// is subject to the terms of the GNU General Public License, version 3. -// The program is distributed without any warranty, expressed or implied. - -#include -#include -#include - -#include "ctdl_module.h" -#include "config.h" -#include "citserver.h" -#include "user_ops.h" - -long control_highest_user = 0; - -/* - * This is the legacy "control record" format for the message base. If found - * on disk, its contents will be migrated into the system configuration. Never - * change this. - */ -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 */ -}; - - -/* - * data that gets passed back and forth between control_find_highest() and its caller - */ -struct cfh { - long highest_roomnum_found; - long highest_msgnum_found; -}; - - -/* - * Callback to get highest room number when rebuilding message base metadata - * - * sanity_diag_mode (can be set by -s flag at startup) may be: - * 0 = attempt to fix inconsistencies - * 1 = show inconsistencies but don't repair them, exit after complete - * 2 = show inconsistencies but don't repair them, continue execution - */ -void control_find_highest(struct ctdlroom *qrbuf, void *data) { - struct cfh *cfh = (struct cfh *)data; - struct cdbdata *cdbfr; - long *msglist; - int num_msgs=0; - int c; - - if (qrbuf->QRnumber > cfh->highest_roomnum_found) { - cfh->highest_roomnum_found = qrbuf->QRnumber; - } - - /* Load the message list */ - cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long)); - if (cdbfr != NULL) { - msglist = (long *) cdbfr->ptr; - num_msgs = cdbfr->len / sizeof(long); - } - else { - return; /* No messages at all? No further action. */ - } - - if (num_msgs > 0) { - for (c=0; c cfh->highest_msgnum_found) { - cfh->highest_msgnum_found = msglist[c]; - } - } - } - - cdb_free(cdbfr); -} - - -/* - * Callback to get highest user number. - */ -void control_find_user(char *username, void *out_data) { - struct ctdluser EachUser; - - if (CtdlGetUser(&EachUser, username) != 0) { - return; - } - - if (EachUser.usernum > CtdlGetConfigLong("MMnextuser")) { - syslog(LOG_DEBUG, "control: fixing MMnextuser %ld > %ld , found in %s", - EachUser.usernum, CtdlGetConfigLong("MMnextuser"), EachUser.fullname - ); - if (!sanity_diag_mode) { - CtdlSetConfigLong("MMnextuser", EachUser.usernum); - } - } -} - - -/* - * If we have a legacy format control record on disk, import it. - */ -void migrate_legacy_control_record(void) { - FILE *fp = NULL; - struct legacy_ctrl_format c; - memset(&c, 0, sizeof(c)); - - fp = fopen("citadel.control", "rb+"); - if (fp != NULL) { - syslog(LOG_INFO, "control: legacy format 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("citadel.control") != 0) { - fprintf(stderr, "Unable to remove legacy control record after migrating it.\n"); - fprintf(stderr, "Exiting to prevent data corruption.\n"); - exit(CTDLEXIT_CONFIG); - } - } -} - - -/* - * check_control - check the control record has sensible values for message, user and room numbers - */ -void check_control(void) { - - syslog(LOG_INFO, "control: sanity checking the recorded highest message and room numbers"); - struct cfh cfh; - memset(&cfh, 0, sizeof(struct cfh)); - CtdlForEachRoom(control_find_highest, &cfh); - - if (cfh.highest_roomnum_found > CtdlGetConfigLong("MMnextroom")) { - syslog(LOG_DEBUG, "control: fixing MMnextroom %ld > %ld", cfh.highest_roomnum_found, CtdlGetConfigLong("MMnextroom")); - if (!sanity_diag_mode) { - CtdlSetConfigLong("MMnextroom", cfh.highest_roomnum_found); - } - } - - if (cfh.highest_msgnum_found > CtdlGetConfigLong("MMhighest")) { - syslog(LOG_DEBUG, "control: fixing MMhighest %ld > %ld", cfh.highest_msgnum_found, CtdlGetConfigLong("MMhighest")); - if (!sanity_diag_mode) { - CtdlSetConfigLong("MMhighest", cfh.highest_msgnum_found); - } - } - - syslog(LOG_INFO, "control: sanity checking the recorded highest user number"); - ForEachUser(control_find_user, NULL); - - syslog(LOG_INFO, "control: sanity checks complete"); - - if (sanity_diag_mode == 1) { - syslog(LOG_INFO, "control: sanity check diagnostic mode is active - exiting now"); - abort(); - } -} - - -/* - * get_new_message_number() - Obtain a new, unique ID to be used for a message. - */ -long get_new_message_number(void) -{ - long retval = 0L; - begin_critical_section(S_CONTROL); - retval = CtdlGetConfigLong("MMhighest"); - ++retval; - CtdlSetConfigLong("MMhighest", retval); - end_critical_section(S_CONTROL); - return(retval); -} - - -/* - * CtdlGetCurrentMessageNumber() - Obtain the current highest message number in the system - * This provides a quick way to initialise a variable that might be used to indicate - * messages that should not be processed. For example, an inbox rules 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) -{ - return CtdlGetConfigLong("MMhighest"); -} - - -/* - * get_new_user_number() - Obtain a new, unique ID to be used for a user. - */ -long get_new_user_number(void) -{ - long retval = 0L; - begin_critical_section(S_CONTROL); - retval = CtdlGetConfigLong("MMnextuser"); - ++retval; - CtdlSetConfigLong("MMnextuser", retval); - end_critical_section(S_CONTROL); - return(retval); -} - - -/* - * get_new_room_number() - Obtain a new, unique ID to be used for a room. - */ -long get_new_room_number(void) -{ - long retval = 0L; - begin_critical_section(S_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 - */ -void cmd_conf(char *argbuf) -{ - char cmd[16]; - 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 - // This is deprecated; please do not add fields or change their order. - if (!strcasecmp(cmd, "GET")) { - cprintf("%d Configuration...\n", LISTING_FOLLOWS); - cprintf("%s\n", CtdlGetConfigStr("c_nodename")); - cprintf("%s\n", CtdlGetConfigStr("c_fqdn")); - cprintf("%s\n", CtdlGetConfigStr("c_humannode")); - cprintf("xxx\n"); /* placeholder -- field no longer in use */ - cprintf("%d\n", CtdlGetConfigInt("c_creataide")); - cprintf("%d\n", CtdlGetConfigInt("c_sleeping")); - cprintf("%d\n", CtdlGetConfigInt("c_initax")); - cprintf("%d\n", CtdlGetConfigInt("c_regiscall")); - cprintf("%d\n", CtdlGetConfigInt("c_twitdetect")); - cprintf("%s\n", CtdlGetConfigStr("c_twitroom")); - cprintf("%s\n", CtdlGetConfigStr("c_moreprompt")); - cprintf("%d\n", CtdlGetConfigInt("c_restrict")); - cprintf("%s\n", CtdlGetConfigStr("c_site_location")); - cprintf("%s\n", CtdlGetConfigStr("c_sysadm")); - cprintf("%d\n", CtdlGetConfigInt("c_maxsessions")); - cprintf("xxx\n"); /* placeholder -- field no longer in use */ - cprintf("%d\n", 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", CtdlGetConfigInt("c_purge_hour")); - 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")); - 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", 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("0\n"); - cprintf("%d\n", CtdlGetConfigInt("c_auth_mode")); - cprintf("\n"); - cprintf("\n"); - cprintf("\n"); - cprintf("\n"); - cprintf("%d\n", CtdlGetConfigInt("c_rbl_at_greeting")); - cprintf("\n"); - cprintf("\n"); - 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 - // This is deprecated; please do not add fields or change their order. - else if (!strcasecmp(cmd, "SET")) { - unbuffer_output(); - cprintf("%d Send configuration...\n", SEND_LISTING); - a = 0; - while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) { - switch (a) { - case 0: - CtdlSetConfigStr("c_nodename", buf); - break; - case 1: - CtdlSetConfigStr("c_fqdn", buf); - break; - case 2: - CtdlSetConfigStr("c_humannode", buf); - break; - case 3: - /* placeholder -- field no longer in use */ - break; - case 4: - CtdlSetConfigInt("c_creataide", confbool(buf)); - break; - case 5: - CtdlSetConfigInt("c_sleeping", atoi(buf)); - break; - case 6: - i = atoi(buf); - if (i < 1) i = 1; - if (i > 6) i = 6; - CtdlSetConfigInt("c_initax", i); - break; - case 7: - CtdlSetConfigInt("c_regiscall", confbool(buf)); - break; - case 8: - CtdlSetConfigInt("c_twitdetect", confbool(buf)); - break; - case 9: - CtdlSetConfigStr("c_twitroom", buf); - break; - case 10: - CtdlSetConfigStr("c_moreprompt", buf); - break; - case 11: - CtdlSetConfigInt("c_restrict", confbool(buf)); - break; - case 12: - CtdlSetConfigStr("c_site_location", buf); - break; - case 13: - CtdlSetConfigStr("c_sysadm", buf); - break; - case 14: - i = atoi(buf); - if (i < 0) i = 0; - CtdlSetConfigInt("c_maxsessions", i); - break; - case 15: - /* placeholder -- field no longer in use */ - break; - case 16: - CtdlSetConfigInt("c_userpurge", atoi(buf)); - break; - case 17: - CtdlSetConfigInt("c_roompurge", atoi(buf)); - break; - case 18: - CtdlSetConfigStr("c_logpages", buf); - break; - case 19: - i = atoi(buf); - if (i < 1) i = 1; - if (i > 6) i = 6; - CtdlSetConfigInt("c_createax", i); - break; - case 20: - ii = atol(buf); - if (ii >= 8192) { - CtdlSetConfigLong("c_maxmsglen", ii); - } - break; - case 21: - i = atoi(buf); - if (i >= 3) { // minimum value - CtdlSetConfigInt("c_min_workers", i); - } - break; - case 22: - i = atoi(buf); - if (i >= CtdlGetConfigInt("c_min_workers")) { // max must be >= min - CtdlSetConfigInt("c_max_workers", i); - } - break; - case 23: - CtdlSetConfigInt("c_pop3_port", atoi(buf)); - break; - case 24: - CtdlSetConfigInt("c_smtp_port", atoi(buf)); - break; - case 25: - CtdlSetConfigInt("c_rfc822_strict_from", atoi(buf)); - break; - case 26: - CtdlSetConfigInt("c_aide_zap", confbool(buf)); - break; - case 27: - CtdlSetConfigInt("c_imap_port", atoi(buf)); - break; - case 28: - CtdlSetConfigLong("c_net_freq", atol(buf)); - break; - case 29: - CtdlSetConfigInt("c_disable_newu", confbool(buf)); - break; - case 30: - /* niu */ - break; - case 31: - i = atoi(buf); - if ((i >= 0) && (i <= 23)) { - CtdlSetConfigInt("c_purge_hour", i); - } - break; - case 32: - CtdlSetConfigStr("c_ldap_host", buf); - break; - case 33: - CtdlSetConfigInt("c_ldap_port", atoi(buf)); - break; - case 34: - CtdlSetConfigStr("c_ldap_base_dn", buf); - break; - case 35: - CtdlSetConfigStr("c_ldap_bind_dn", buf); - break; - case 36: - CtdlSetConfigStr("c_ldap_bind_pw", buf); - break; - case 37: - CtdlSetConfigStr("c_ip_addr", buf); - break; - case 38: - CtdlSetConfigInt("c_msa_port", atoi(buf)); - break; - case 39: - CtdlSetConfigInt("c_imaps_port", atoi(buf)); - break; - case 40: - CtdlSetConfigInt("c_pop3s_port", atoi(buf)); - break; - case 41: - CtdlSetConfigInt("c_smtps_port", atoi(buf)); - break; - case 42: - CtdlSetConfigInt("c_enable_fulltext", confbool(buf)); - break; - case 43: - CtdlSetConfigInt("c_auto_cull", confbool(buf)); - break; - case 44: - /* niu */ - break; - case 45: - CtdlSetConfigInt("c_allow_spoofing", confbool(buf)); - break; - case 46: - CtdlSetConfigInt("c_journal_email", confbool(buf)); - break; - case 47: - CtdlSetConfigInt("c_journal_pubmsgs", confbool(buf)); - break; - case 48: - CtdlSetConfigStr("c_journal_dest", buf); - break; - case 49: - CtdlSetConfigStr("c_default_cal_zone", buf); - break; - case 50: - CtdlSetConfigInt("c_pftcpdict_port", atoi(buf)); - break; - case 51: - /* niu */ - break; - case 52: - CtdlSetConfigInt("c_auth_mode", atoi(buf)); - break; - case 53: - /* niu */ - break; - case 54: - /* niu */ - break; - case 55: - /* niu */ - break; - case 56: - /* niu */ - break; - case 57: - CtdlSetConfigInt("c_rbl_at_greeting", confbool(buf)); - break; - case 58: - /* niu */ - break; - case 59: - /* niu */ - break; - case 60: - CtdlSetConfigStr("c_pager_program", buf); - break; - case 61: - CtdlSetConfigInt("c_imap_keep_from", confbool(buf)); - break; - case 62: - CtdlSetConfigInt("c_xmpp_c2s_port", atoi(buf)); - break; - case 63: - CtdlSetConfigInt("c_xmpp_s2s_port", atoi(buf)); - break; - case 64: - CtdlSetConfigLong("c_pop3_fetch", atol(buf)); - break; - case 65: - CtdlSetConfigLong("c_pop3_fastest", atol(buf)); - break; - case 66: - CtdlSetConfigInt("c_spam_flag_only", confbool(buf)); - break; - case 67: - CtdlSetConfigInt("c_guest_logins", confbool(buf)); - break; - case 68: - CtdlSetConfigInt("c_port_number", atoi(buf)); - break; - case 69: - /* niu */ - break; - case 70: - CtdlSetConfigInt("c_nntp_port", atoi(buf)); - break; - case 71: - CtdlSetConfigInt("c_nntps_port", atoi(buf)); - break; - } - ++a; - } - 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(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 (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); - if (confptr != NULL) { - long len; - - len = strlen(confptr); - cprintf("%d %s\n", LISTING_FOLLOWS, confname); - client_write(confptr, len); - if ((len > 0) && (confptr[len - 1] != 10)) - client_write("\n", 1); - cprintf("000\n"); - free(confptr); - } else { - cprintf("%d No such configuration.\n", - ERROR + ILLEGAL_VALUE); - } - } - - // 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"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0); - CtdlPutSysConfig(confname, confptr); - free(confptr); - } - - // CONF GETVAL - retrieve configuration variables from the database - // CONF LOADVAL - same thing but can handle variables bigger than 1 KB (deprecated and probably safe to remove) - else if ( (!strcasecmp(cmd, "GETVAL")) || (!strcasecmp(cmd, "LOADVAL")) ) { - extract_token(confname, argbuf, 1, '|', sizeof confname); - char *v = CtdlGetConfigStr(confname); - if ( (v) && (!strcasecmp(cmd, "GETVAL")) ) { - cprintf("%d %s|\n", CIT_OK, v); - } - else if ( (v) && (!strcasecmp(cmd, "LOADVAL")) ) { - cprintf("%d %d\n", BINARY_FOLLOWS, (int)strlen(v)); - client_write(v, strlen(v)); - } - else { - cprintf("%d |\n", ERROR); - } - } - - // CONF PUTVAL - store configuration variables in the database - 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); - } - } - - // CONF STOREVAL - store configuration variables in the database bigger than 1 KB (deprecated and probably safe to remove) - else if (!strcasecmp(cmd, "STOREVAL")) { - if (num_tokens(argbuf, '|') < 3) { - cprintf("%d name and length required\n", ERROR); - } - else { - extract_token(confname, argbuf, 1, '|', sizeof confname); - int bytes = extract_int(argbuf, 2); - char *valbuf = malloc(bytes + 1); - cprintf("%d %d\n", SEND_BINARY, bytes); - client_read(valbuf, bytes); - valbuf[bytes+1] = 0; - CtdlSetConfigStr(confname, valbuf); - free(valbuf); - } - } - - // CONF LISTVAL - list configuration variables in the database and their values - else if (!strcasecmp(cmd, "LISTVAL")) { - struct cdbdata *cdbcfg; - int keylen = 0; - char *key = NULL; - char *value = NULL; - - cprintf("%d all configuration variables\n", LISTING_FOLLOWS); - cdb_rewind(CDB_CONFIG); - while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg != NULL) { - if (cdbcfg->len < 1020) { - keylen = strlen(cdbcfg->ptr); - key = cdbcfg->ptr; - value = cdbcfg->ptr + keylen + 1; - cprintf("%s|%s\n", key, value); - } - cdb_free(cdbcfg); - } - cprintf("000\n"); - } - - else { - cprintf("%d Illegal option(s) specified.\n", ERROR + ILLEGAL_VALUE); - } -} - - -typedef struct __ConfType { - ConstStr Name; - long Type; -}ConfType; - -ConfType CfgNames[] = { - { {HKEY("localhost") }, 0}, - { {HKEY("directory") }, 0}, - { {HKEY("smarthost") }, 2}, - { {HKEY("fallbackhost") }, 2}, - { {HKEY("rbl") }, 3}, - { {HKEY("spamassassin") }, 3}, - { {HKEY("masqdomain") }, 1}, - { {HKEY("clamav") }, 3}, - { {HKEY("notify") }, 3}, - { {NULL, 0}, 0} -}; - -HashList *CfgNameHash = NULL; -void cmd_gvdn(char *argbuf) -{ - const ConfType *pCfg; - char *confptr; - long min = atol(argbuf); - const char *Pos = NULL; - const char *PPos = NULL; - const char *HKey; - long HKLen; - StrBuf *Line; - StrBuf *Config; - StrBuf *Cfg; - StrBuf *CfgToken; - HashList *List; - HashPos *It; - void *vptr; - - List = NewHash(1, NULL); - Cfg = NewStrBufPlain(CtdlGetConfigStr("c_fqdn"), -1); - Put(List, SKEY(Cfg), Cfg, HFreeStrBuf); - Cfg = NULL; - - confptr = CtdlGetSysConfig(INTERNETCFG); - Config = NewStrBufPlain(confptr, -1); - free(confptr); - - Line = NewStrBufPlain(NULL, StrLength(Config)); - CfgToken = NewStrBufPlain(NULL, StrLength(Config)); - while (StrBufSipLine(Line, Config, &Pos)) - { - if (Cfg == NULL) - Cfg = NewStrBufPlain(NULL, StrLength(Line)); - PPos = NULL; - StrBufExtract_NextToken(Cfg, Line, &PPos, '|'); - StrBufExtract_NextToken(CfgToken, Line, &PPos, '|'); - if (GetHash(CfgNameHash, SKEY(CfgToken), &vptr) && - (vptr != NULL)) - { - pCfg = (ConfType *) vptr; - if (pCfg->Type <= min) - { - Put(List, SKEY(Cfg), Cfg, HFreeStrBuf); - Cfg = NULL; - } - } - } - - cprintf("%d Valid Domains\n", LISTING_FOLLOWS); - It = GetNewHashPos(List, 1); - while (GetNextHashPos(List, It, &HKLen, &HKey, &vptr)) - { - cputbuf(vptr); - cprintf("\n"); - } - cprintf("000\n"); - - DeleteHashPos(&It); - DeleteHash(&List); - FreeStrBuf(&Cfg); - FreeStrBuf(&Line); - FreeStrBuf(&CfgToken); - FreeStrBuf(&Config); -} - -/*****************************************************************************/ -/* MODULE INITIALIZATION STUFF */ -/*****************************************************************************/ - -CTDL_MODULE_INIT(control) -{ - if (!threading) { - int i; - - CfgNameHash = NewHash(1, NULL); - for (i = 0; CfgNames[i].Name.Key != NULL; i++) - Put(CfgNameHash, CKEY(CfgNames[i].Name), &CfgNames[i], reference_free_handler); - - CtdlRegisterProtoHook(cmd_gvdn, "GVDN", "get valid domain names"); - CtdlRegisterProtoHook(cmd_conf, "CONF", "get/set system configuration"); - } - /* return our id for the Log */ - return "control"; -}