//
// This module handles states which are global to the entire server.
//
-// Copyright (c) 1987-2022 by the citadel.org team
+// Copyright (c) 1987-2024 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 <stdio.h>
#include <sys/file.h>
#include "config.h"
#include "citserver.h"
#include "user_ops.h"
+#include "room_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.
- */
+// 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 */
+ 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
- */
+// 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
- */
+// 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;
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. */
- }
-
+ // Load the message list
+ num_msgs = CtdlFetchMsgList(qrbuf->QRnumber, &msglist);
if (num_msgs > 0) {
for (c=0; c<num_msgs; c++) {
if (msglist[c] > cfh->highest_msgnum_found) {
}
}
}
-
- cdb_free(cdbfr);
+ free(msglist);
}
-/*
- * Callback to get highest user number.
- */
+// Callback to get highest user number.
void control_find_user(char *username, void *out_data) {
struct ctdluser EachUser;
}
-/*
- * If we have a legacy format control record on disk, import it.
- */
+// 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;
}
-/*
- * check_control - check the control record has sensible values for message, user and room numbers
- */
+// 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");
if (sanity_diag_mode == 1) {
syslog(LOG_INFO, "control: sanity check diagnostic mode is active - exiting now");
- abort();
+ exit(CTDLEXIT_SANITY);
}
}
-/*
- * get_new_message_number() - Obtain a new, unique ID to be used for a message.
- */
-long get_new_message_number(void)
-{
+// 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");
}
-/*
- * CtdlGetCurrentMessageNumber() - Obtain the current highest message number in the system
- * This provides a quick way to initialize 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)
-{
+// CtdlGetCurrentMessageNumber() - Obtain the current highest message number in the system
+// This provides a quick way to initialize 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)
-{
+// 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");
}
-/*
- * get_new_room_number() - Obtain a new, unique ID to be used for a room.
- */
-long get_new_room_number(void)
-{
+// 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");
}
-/*
- * Helper function for cmd_conf() to handle boolean values
- */
-int confbool(char *v)
-{
+// 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)
-{
+// Get or set global configuration options
+void cmd_conf(char *argbuf) {
char cmd[16];
char buf[1024];
int a, i;
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("xxx\n");
cprintf("%d\n", CtdlGetConfigInt("c_creataide"));
cprintf("%d\n", CtdlGetConfigInt("c_sleeping"));
cprintf("%d\n", CtdlGetConfigInt("c_initax"));
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("xxx\n");
cprintf("%d\n", CtdlGetConfigInt("c_userpurge"));
cprintf("%d\n", CtdlGetConfigInt("c_roompurge"));
cprintf("%s\n", CtdlGetConfigStr("c_logpages"));
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("1\n");
cprintf("%d\n", CtdlGetConfigInt("c_purge_hour"));
cprintf("%s\n", CtdlGetConfigStr("c_ldap_host"));
cprintf("%d\n", CtdlGetConfigInt("c_ldap_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("1\n");
cprintf("%d\n", CtdlGetConfigInt("c_allow_spoofing"));
cprintf("%d\n", CtdlGetConfigInt("c_journal_email"));
CtdlSetConfigStr("c_humannode", buf);
break;
case 3:
- /* placeholder -- field no longer in use */
+ // placeholder -- field no longer in use
break;
case 4:
CtdlSetConfigInt("c_creataide", confbool(buf));
CtdlSetConfigInt("c_maxsessions", i);
break;
case 15:
- /* placeholder -- field no longer in use */
+ // placeholder -- field no longer in use
break;
case 16:
CtdlSetConfigInt("c_userpurge", atoi(buf));
CtdlSetConfigInt("c_disable_newu", confbool(buf));
break;
case 30:
- /* niu */
+ // niu
break;
case 31:
i = atoi(buf);
CtdlSetConfigInt("c_enable_fulltext", confbool(buf));
break;
case 43:
- CtdlSetConfigInt("c_auto_cull", confbool(buf));
+ // niu
break;
case 44:
- /* niu */
+ // niu
break;
case 45:
CtdlSetConfigInt("c_allow_spoofing", confbool(buf));
CtdlSetConfigInt("c_pftcpdict_port", atoi(buf));
break;
case 51:
- /* niu */
+ // niu
break;
case 52:
CtdlSetConfigInt("c_auth_mode", atoi(buf));
break;
case 53:
- /* niu */
+ // niu
break;
case 54:
- /* niu */
+ // niu
break;
case 55:
- /* niu */
+ // niu
break;
case 56:
- /* niu */
+ // niu
break;
case 57:
CtdlSetConfigInt("c_rbl_at_greeting", confbool(buf));
break;
case 58:
- /* niu */
+ // niu
break;
case 59:
- /* niu */
+ // niu
break;
case 60:
CtdlSetConfigStr("c_pager_program", buf);
CtdlSetConfigInt("c_port_number", atoi(buf));
break;
case 69:
- /* niu */
+ // niu
break;
case 70:
CtdlSetConfigInt("c_nntp_port", atoi(buf));
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 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);
}
len = strlen(confptr);
cprintf("%d %s\n", LISTING_FOLLOWS, confname);
client_write(confptr, len);
- if ((len > 0) && (confptr[len - 1] != 10))
+ 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);
+ }
+ else {
+ cprintf("%d No such configuration.\n", ERROR + ILLEGAL_VALUE);
}
}
// CONF LISTVAL - list configuration variables in the database and their values
else if (!strcasecmp(cmd, "LISTVAL")) {
- struct cdbdata *cdbcfg;
+ struct cdbkeyval 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;
+ while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg.val.ptr!=NULL) { // MUST read to the end
+ if (cdbcfg.val.len < 1020) {
+ keylen = strlen(cdbcfg.val.ptr);
+ key = cdbcfg.val.ptr;
+ value = cdbcfg.val.ptr + keylen + 1;
cprintf("%s|%s\n", key, value);
}
- cdb_free(cdbcfg);
}
cprintf("000\n");
}
typedef struct __ConfType {
ConstStr Name;
long Type;
-}ConfType;
+} ConfType;
ConfType CfgNames[] = {
{ {HKEY("localhost") }, 0},
};
HashList *CfgNameHash = NULL;
-void cmd_gvdn(char *argbuf)
-{
+void cmd_gvdn(char *argbuf) {
const ConfType *pCfg;
char *confptr;
long min = atol(argbuf);
Line = NewStrBufPlain(NULL, StrLength(Config));
CfgToken = NewStrBufPlain(NULL, StrLength(Config));
- while (StrBufSipLine(Line, Config, &Pos))
- {
+ 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))
- {
+ if (GetHash(CfgNameHash, SKEY(CfgToken), &vptr) && (vptr != NULL)) {
pCfg = (ConfType *) vptr;
- if (pCfg->Type <= min)
- {
+ 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))
- {
+ while (GetNextHashPos(List, It, &HKLen, &HKey, &vptr)) {
cputbuf(vptr);
cprintf("\n");
}
FreeStrBuf(&Config);
}
-/*****************************************************************************/
-/* MODULE INITIALIZATION STUFF */
-/*****************************************************************************/
+// MODULE INITIALIZATION STUFF
char *ctdl_module_init_control(void) {
if (!threading) {
int i;
CfgNameHash = NewHash(1, NULL);
- for (i = 0; CfgNames[i].Name.Key != NULL; i++)
+ 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 our id for the log
return "control";
}