X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontrol.c;h=dbe84067057cc98f8961932dadbc24236251c110;hb=b2e29e3d33f3eda3a3eb3f7be959cf841a393fb0;hp=f2268d8fa2f06c655e71ea313675a8992d2c5efa;hpb=11219dbc3e638e7ee47feffbbb7d63588d7dd77f;p=citadel.git diff --git a/citadel/control.c b/citadel/control.c index f2268d8fa..dbe840670 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -28,10 +28,10 @@ #include #include #include +#include #include "citadel.h" #include "server.h" #include "control.h" -#include "serv_extensions.h" #include "sysdep_decls.h" #include "support.h" #include "config.h" @@ -39,6 +39,8 @@ #include "citserver.h" #include "tools.h" #include "room_ops.h" +#include "user_ops.h" +#include "database.h" #ifndef HAVE_SNPRINTF #include "snprintf.h" @@ -47,12 +49,91 @@ struct CitControl CitControl; extern struct config config; FILE *control_fp = NULL; +long control_highest_user = 0; + + +/* + * lock_control - acquire a lock on the control record file. + * This keeps multiple citservers from running concurrently. + */ +void lock_control(void) +{ +#ifdef HAVE_FLOCK +/* + * TODO: solaris manpages describe this function, but the headers + * don't show it! + */ + + if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) { + lprintf(CTDL_EMERG, "citserver: unable to lock %s.\n", file_citadel_control); + lprintf(CTDL_EMERG, "Is another citserver already running?\n"); + exit(CTDLEXIT_CONTROL); + } +#endif +} + +/* + * callback to get highest room number when rebuilding control file + */ +void control_find_highest(struct ctdlroom *qrbuf, void *data) +{ + struct ctdlroom room; + struct cdbdata *cdbfr; + long *msglist; + int num_msgs=0; + int c; + + + if (qrbuf->QRnumber > CitControl.MMnextroom) + CitControl.MMnextroom = qrbuf->QRnumber; + + getroom (&room, qrbuf->QRname); + + /* Load the message list */ + cdbfr = cdb_fetch(CDB_MSGLISTS, &room.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. */ + } + + if (num_msgs>0) + { + for (c=0; c CitControl.MMhighest) + CitControl.MMhighest = msglist[c]; + } + } + cdb_free(cdbfr); + return; +} + + +/* + * Callback to get highest user number. + */ + +void control_find_user (struct ctdluser *EachUser, void *out_data) +{ + if (EachUser->usernum > CitControl.MMnextuser) + CitControl.MMnextuser = EachUser->usernum; +} + /* * get_control - read the control record into memory. */ void get_control(void) { + static int already_have_control = 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 @@ -62,14 +143,19 @@ void get_control(void) if (control_fp == NULL) { control_fp = fopen(file_citadel_control, "rb+"); if (control_fp != NULL) { + lock_control(); fchown(fileno(control_fp), config.c_ctdluid, -1); } } 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); rewind(control_fp); @@ -84,6 +170,7 @@ void get_control(void) rewind(control_fp); fread(&CitControl, sizeof(struct CitControl), 1, control_fp); + already_have_control = 1; } /* @@ -100,6 +187,15 @@ void put_control(void) } } +/** + * 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. @@ -224,6 +320,15 @@ void cmd_conf(char *argbuf) cprintf("%s\n", config.c_default_cal_zone); cprintf("%d\n", config.c_pftcpdict_port); cprintf("%d\n", config.c_managesieve_port); + cprintf("%d\n", config.c_auth_mode); + cprintf("%s\n", config.c_funambol_host); + cprintf("%d\n", config.c_funambol_port); + cprintf("%s\n", config.c_funambol_source); + cprintf("%s\n", config.c_funambol_auth); + cprintf("%d\n", config.c_rbl_at_greeting); + cprintf("%s\n", config.c_master_user); + cprintf("%s\n", config.c_master_pass); + cprintf("%s\n", config.c_pager_program); cprintf("000\n"); } @@ -429,6 +534,39 @@ void cmd_conf(char *argbuf) case 51: config.c_managesieve_port = atoi(buf); break; + case 52: + config.c_auth_mode = atoi(buf); + case 53: + safestrncpy(config.c_funambol_host, buf, + sizeof config.c_funambol_host); + break; + case 54: + config.c_funambol_port = atoi(buf); + break; + case 55: + safestrncpy(config.c_funambol_source, + buf, + sizeof config.c_funambol_source); + break; + case 56: + safestrncpy(config.c_funambol_auth, + buf, + sizeof config.c_funambol_auth); + break; + case 57: + config.c_rbl_at_greeting = atoi(buf); + break; + case 58: + safestrncpy(config.c_master_user, buf, sizeof config.c_master_user); + break; + case 59: + safestrncpy(config.c_master_pass, buf, sizeof config.c_master_pass); + break; + case 60: + safestrncpy(config.c_pager_program, + buf, + sizeof config.c_pager_program); + break; } ++a; } @@ -438,7 +576,7 @@ void cmd_conf(char *argbuf) CC->curr_user); aide_message(buf,"Citadel Configuration Manager Message"); - if (strlen(config.c_logpages) > 0) + if (!IsEmptyStr(config.c_logpages)) create_room(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS); /* If full text indexing has been disabled, invalidate the @@ -470,8 +608,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); + confptr = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0); CtdlPutSysConfig(confname, confptr); free(confptr); }