X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontrol.c;h=e14d4f29b4568c5079a310c2cde77562b61ee260;hb=cc6ff1d17f37d670330001a9d4dd91eef7044c9b;hp=230b8d3df9d787cff61a6cfff4dbbb08a8caa9ee;hpb=d7fd95a3ec0da47dbbdeabc3bee0dfb01a8dde61;p=citadel.git diff --git a/citadel/control.c b/citadel/control.c index 230b8d3df..e14d4f29b 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -21,10 +21,22 @@ #include "citserver.h" #include "user_ops.h" -struct CitControl CitControl; -FILE *control_fp = NULL; long control_highest_user = 0; +/* + * This is the control record for the message base... + */ +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 */ +}; + /* @@ -40,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; } @@ -61,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; } @@ -85,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) @@ -96,90 +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) { - rv = fchown(fileno(control_fp), 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) { - memset(&CitControl, 0, sizeof(struct CitControl)); - - rv = fchown(fileno(control_fp), 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, 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); - } } @@ -188,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. @@ -215,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); } @@ -228,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"); } @@ -247,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); } @@ -263,9 +205,9 @@ 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); } @@ -287,13 +229,13 @@ int confbool(char *v) * 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]; + char buf[1024]; int a, i; long ii; char *confptr; @@ -302,6 +244,8 @@ void cmd_conf(char *argbuf) 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", CtdlGetConfigStr("c_nodename")); @@ -387,6 +331,7 @@ void cmd_conf(char *argbuf) 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); @@ -645,11 +590,11 @@ void cmd_conf(char *argbuf) * index so it doesn't try to use it later. */ if (CtdlGetConfigInt("c_enable_fulltext") == 0) { - CitControl.MM_fulltext_wordbreaker = 0; - put_control(); + 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); @@ -669,6 +614,7 @@ 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(); @@ -678,9 +624,31 @@ void cmd_conf(char *argbuf) 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); } }