X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontrol.c;h=4a09a9adc3baaa11fa95b0bf9eaf02dca56d4327;hb=adccf08ddebcb920c4244cc62bc48f85575c2d88;hp=7cdf65d3bae8939a895529aab81a5564d1033f85;hpb=322953f1b1f00cd3e644e195b14c816eedbada12;p=citadel.git diff --git a/citadel/control.c b/citadel/control.c index 7cdf65d3b..4a09a9adc 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -1,8 +1,15 @@ /* - * $Id$ - * * This module handles states which are global to the entire server. * + * Copyright (c) 1987-2012 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. */ #include "sysdep.h" @@ -43,11 +50,6 @@ #include "user_ops.h" #include "database.h" #include "threads.h" - -#ifndef HAVE_SNPRINTF -#include "snprintf.h" -#endif - #include "ctdl_module.h" struct CitControl CitControl; @@ -62,15 +64,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 @@ -95,7 +92,7 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) room_fixed = 1; } - getroom (&room, qrbuf->QRname); + CtdlGetRoom (&room, qrbuf->QRname); /* Load the message list */ cdbfr = cdb_fetch(CDB_MSGLISTS, &room.QRnumber, sizeof(long)); @@ -119,9 +116,9 @@ void control_find_highest(struct ctdlroom *qrbuf, void *data) } cdb_free(cdbfr); if (room_fixed) - CtdlLogPrintf(CTDL_INFO, "Control record checking....Fixed room counter\n"); + syslog(LOG_INFO, "Control record checking....Fixed room counter\n"); if (message_fixed) - CtdlLogPrintf(CTDL_INFO, "Control record checking....Fixed message count\n"); + syslog(LOG_INFO, "Control record checking....Fixed message count\n"); return; } @@ -140,7 +137,7 @@ void control_find_user (struct ctdluser *EachUser, void *out_data) user_fixed = 1; } if(user_fixed) - CtdlLogPrintf(CTDL_INFO, "Control record checking....Fixed user count\n"); + syslog(LOG_INFO, "Control record checking....Fixed user count\n"); } @@ -168,30 +165,52 @@ void get_control(void) if (control_fp != NULL) { lock_control(); 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(); + memset(&CitControl, 0, sizeof(struct CitControl)); + 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); - memset(&CitControl, 0, sizeof(struct CitControl)); + 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); 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, config.c_ctdluid, (-1)); - + if (rv == -1) + syslog(LOG_EMERG, "Failed to adjust ownership of: %s [%s]\n", + file_citadel_control, strerror(errno)); } /* @@ -204,6 +223,9 @@ void put_control(void) 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); } } @@ -214,22 +236,23 @@ void put_control(void) */ void check_control(void) { - CtdlLogPrintf(CTDL_INFO, "Checking/re-building control record\n"); + syslog(LOG_INFO, "Checking/re-building control record\n"); get_control(); // Find highest room number and message number. - ForEachRoom(control_find_highest, NULL); + 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; } @@ -299,6 +322,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?id=documentation:applicationprotocol + * */ void cmd_conf(char *argbuf) { @@ -388,6 +415,9 @@ void cmd_conf(char *argbuf) 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("%d\n", config.c_port_number); + cprintf("%d\n", config.c_ctdluid); cprintf("000\n"); } @@ -644,17 +674,27 @@ void cmd_conf(char *argbuf) case 66: config.c_spam_flag_only = atoi(buf); break; + case 67: + config.c_guest_logins = atoi(buf); + break; + case 68: + config.c_port_number = atoi(buf); + break; + case 69: + config.c_ctdluid = atoi(buf); + break; } ++a; } put_config(); snprintf(buf, sizeof buf, - "The global system configuration has been edited by %s.\n", - CC->curr_user); - aide_message(buf,"Citadel Configuration Manager Message"); + "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(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. @@ -669,9 +709,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); @@ -685,7 +728,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); } @@ -696,15 +739,111 @@ void cmd_conf(char *argbuf) } } +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(config.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 */ /*****************************************************************************/ - +void control_cleanup(void) +{ + DeleteHash(&CfgNameHash); +} CTDL_MODULE_INIT(control) { - CtdlRegisterProtoHook(cmd_conf, "CONF", "Autoconverted. TODO: document me."); - /* return our Subversion id for the Log */ - return "$Id$"; + 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"); + CtdlRegisterCleanupHook(control_cleanup); + + } + /* return our id for the Log */ + return "control"; }