X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontrol.c;h=22f6625582926adf20264dac06bfc6e3754b6e06;hb=100b6a90d5ea460fc62e648311ebf3fad965c139;hp=cabf6df1314a3cc439230345db9f0f2798f0b8c9;hpb=554b4865ddb1cd09b9311b13307b61abf4f1b22d;p=citadel.git diff --git a/citadel/control.c b/citadel/control.c index cabf6df13..22f662558 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -1,16 +1,11 @@ -/* - * This module handles states which are global to the entire server. - * - * Copyright (c) 1987-2019 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 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 @@ -40,6 +35,15 @@ struct legacy_ctrl_format { }; +/* + * 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 * @@ -48,48 +52,36 @@ struct legacy_ctrl_format { * 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 ctdlroom room; +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 > CtdlGetConfigLong("MMnextroom")) { - syslog(LOG_DEBUG, "control: fixing MMnextroom %ld > %ld , found in %s", - qrbuf->QRnumber, CtdlGetConfigLong("MMnextroom"), qrbuf->QRname - ); - if (!sanity_diag_mode) { - CtdlSetConfigLong("MMnextroom", qrbuf->QRnumber); - } + + if (qrbuf->QRnumber > cfh->highest_roomnum_found) { + cfh->highest_roomnum_found = qrbuf->QRnumber; } - - CtdlGetRoom(&room, qrbuf->QRname); - + /* Load the message list */ - cdbfr = cdb_fetch(CDB_MSGLISTS, &room.QRnumber, sizeof(long)); + cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long)); if (cdbfr != NULL) { msglist = (long *) cdbfr->ptr; num_msgs = cdbfr->len / sizeof(long); - } else { + } + else { return; /* No messages at all? No further action. */ } if (num_msgs > 0) { for (c=0; c CtdlGetConfigLong("MMhighest")) { - syslog(LOG_DEBUG, "control: fixing MMhighest %ld > %ld , found in %s", - msglist[c], CtdlGetConfigLong("MMhighest"), qrbuf->QRname - ); - if (!sanity_diag_mode) { - CtdlSetConfigLong("MMhighest", msglist[c]); - } + if (msglist[c] > cfh->highest_msgnum_found) { + cfh->highest_msgnum_found = msglist[c]; } } } + cdb_free(cdbfr); - return; } @@ -117,13 +109,12 @@ void control_find_user(char *username, void *out_data) { /* * If we have a legacy format control record on disk, import it. */ -void migrate_legacy_control_record(void) -{ +void migrate_legacy_control_record(void) { FILE *fp = NULL; struct legacy_ctrl_format c; memset(&c, 0, sizeof(c)); - fp = fopen(file_citadel_control, "rb+"); + 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); @@ -137,8 +128,8 @@ void migrate_legacy_control_record(void) 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); + 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); } @@ -149,13 +140,32 @@ void migrate_legacy_control_record(void) /* * check_control - check the control record has sensible values for message, user and room numbers */ -void check_control(void) -{ +void check_control(void) { + syslog(LOG_INFO, "control: sanity checking the recorded highest message and room numbers"); - CtdlForEachRoom(control_find_highest, NULL); + 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(); @@ -181,7 +191,7 @@ long get_new_message_number(void) /* * 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. EG. a new Sieve script will use this + * 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?) @@ -791,10 +801,6 @@ void cmd_gvdn(char *argbuf) /* MODULE INITIALIZATION STUFF */ /*****************************************************************************/ -void control_cleanup(void) -{ - DeleteHash(&CfgNameHash); -} CTDL_MODULE_INIT(control) { if (!threading) { @@ -806,8 +812,6 @@ CTDL_MODULE_INIT(control) CtdlRegisterProtoHook(cmd_gvdn, "GVDN", "get valid domain names"); CtdlRegisterProtoHook(cmd_conf, "CONF", "get/set system configuration"); - CtdlRegisterCleanupHook(control_cleanup); - } /* return our id for the Log */ return "control";