X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontrol.c;h=e71055c880492596fd8e5f404e1dc4169e8681f5;hb=7d7e0178bdc7159658ac8deb23ea2f502e7ac3be;hp=8da8192fa07ae82089d9a7d6ec8c65783d29f69e;hpb=e005b5e8fb186efccfdbac57f3ac278f05b131d6;p=citadel.git diff --git a/citadel/control.c b/citadel/control.c index 8da8192fa..e71055c88 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -1,8 +1,21 @@ /* - * $Id$ - * * This module handles states which are global to the entire server. * + * Copyright (c) 1987-2010 by the citadel.org team + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -29,6 +42,7 @@ #include #include #include +#include #include #include "citadel.h" #include "server.h" @@ -47,6 +61,8 @@ #include "snprintf.h" #endif +#include "ctdl_module.h" + struct CitControl CitControl; extern struct config config; FILE *control_fp = NULL; @@ -59,15 +75,10 @@ long control_highest_user = 0; */ void lock_control(void) { -#ifdef HAVE_FLOCK -/* - * TODO: solaris manpages describe this function, but the headers - * don't show it! - */ - +#if defined(LOCK_EX) && defined(LOCK_NB) if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) { - CtdlLogPrintf(CTDL_EMERG, "citserver: unable to lock %s.\n", file_citadel_control); - CtdlLogPrintf(CTDL_EMERG, "Is another citserver already running?\n"); + 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 @@ -83,12 +94,16 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) long *msglist; int num_msgs=0; int c; - + int room_fixed = 0; + int message_fixed = 0; if (qrbuf->QRnumber > CitControl.MMnextroom) + { CitControl.MMnextroom = qrbuf->QRnumber; + room_fixed = 1; + } - getroom (&room, qrbuf->QRname); + CtdlGetRoom (&room, qrbuf->QRname); /* Load the message list */ cdbfr = cdb_fetch(CDB_MSGLISTS, &room.QRnumber, sizeof(long)); @@ -104,10 +119,17 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) for (c=0; c CitControl.MMhighest) + { CitControl.MMhighest = msglist[c]; + message_fixed = 1; + } } } cdb_free(cdbfr); + if (room_fixed) + syslog(LOG_INFO, "Control record checking....Fixed room counter\n"); + if (message_fixed) + syslog(LOG_INFO, "Control record checking....Fixed message count\n"); return; } @@ -118,8 +140,15 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) void control_find_user (struct ctdluser *EachUser, void *out_data) { + int user_fixed = 0; + if (EachUser->usernum > CitControl.MMnextuser) + { CitControl.MMnextuser = EachUser->usernum; + user_fixed = 1; + } + if(user_fixed) + syslog(LOG_INFO, "Control record checking....Fixed user count\n"); } @@ -129,6 +158,7 @@ void control_find_user (struct ctdluser *EachUser, void *out_data) void get_control(void) { static int already_have_control = 0; + int rv = 0; /* * If we already have the control record in memory, there's no point @@ -145,34 +175,53 @@ void get_control(void) control_fp = fopen(file_citadel_control, "rb+"); if (control_fp != NULL) { lock_control(); - fchown(fileno(control_fp), config.c_ctdluid, -1); + 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(); - fchown(fileno(control_fp), config.c_ctdluid, -1); memset(&CitControl, 0, sizeof(struct CitControl)); - // Find highest room number and message number. - ForEachRoom(control_find_highest, NULL); - ForEachUser(control_find_user, NULL); - fwrite(&CitControl, sizeof(struct CitControl), - 1, control_fp); + + 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); } } if (control_fp == NULL) { - CtdlLogPrintf(CTDL_ALERT, "ERROR opening %s: %s\n", - file_citadel_control, - strerror(errno)); + syslog(LOG_ALERT, "ERROR opening %s: %s\n", file_citadel_control, strerror(errno)); return; } rewind(control_fp); - fread(&CitControl, sizeof(struct CitControl), 1, 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; - chown(file_citadel_control, config.c_ctdluid, (-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)); } /* @@ -180,22 +229,41 @@ void get_control(void) */ void put_control(void) { + int rv = 0; if (control_fp != NULL) { rewind(control_fp); - fwrite(&CitControl, sizeof(struct CitControl), 1, - 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); } } -/** + +/* + * check_control - check the control record has sensible values for message, user and room numbers + */ +void check_control(void) +{ + syslog(LOG_INFO, "Checking/re-building control record\n"); + get_control(); + // Find highest room number and message number. + 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) + if (control_fp != NULL) { fclose(control_fp); + } control_fp = NULL; } @@ -265,6 +333,10 @@ long get_new_room_number(void) /* * 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/documentation:appproto:system_config + * */ void cmd_conf(char *argbuf) { @@ -353,6 +425,8 @@ void cmd_conf(char *argbuf) 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("000\n"); } @@ -606,6 +680,12 @@ void cmd_conf(char *argbuf) case 65: config.c_pop3_fastest = atol(buf); break; + case 66: + config.c_spam_flag_only = atoi(buf); + break; + case 67: + config.c_guest_logins = atoi(buf); + break; } ++a; } @@ -613,10 +693,10 @@ void cmd_conf(char *argbuf) snprintf(buf, sizeof buf, "The global system configuration has been edited by %s.\n", CC->curr_user); - aide_message(buf,"Citadel Configuration Manager Message"); + CtdlAideMessage(buf,"Citadel Configuration Manager Message"); if (!IsEmptyStr(config.c_logpages)) - create_room(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS); + CtdlCreateRoom(config.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. @@ -631,9 +711,12 @@ void cmd_conf(char *argbuf) 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, strlen(confptr)); - if (confptr[strlen(confptr) - 1] != 10) + client_write(confptr, len); + if ((len > 0) && (confptr[len - 1] != 10)) client_write("\n", 1); cprintf("000\n"); free(confptr); @@ -647,7 +730,7 @@ void cmd_conf(char *argbuf) extract_token(confname, argbuf, 1, '|', sizeof confname); unbuffer_output(); cprintf("%d %s\n", SEND_LISTING, confname); - confptr = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0); + confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); CtdlPutSysConfig(confname, confptr); free(confptr); } @@ -657,3 +740,18 @@ void cmd_conf(char *argbuf) ERROR + ILLEGAL_VALUE); } } + + +/*****************************************************************************/ +/* MODULE INITIALIZATION STUFF */ +/*****************************************************************************/ + + +CTDL_MODULE_INIT(control) +{ + if (!threading) { + CtdlRegisterProtoHook(cmd_conf, "CONF", "get/set system configuration"); + } + /* return our id for the Log */ + return "control"; +}