citadel
About: Citadel is an advanced messaging and collaboration system for groupware and BBS applications (preferred OS: Linux).
  Fossies Dox: citadel.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

control.c
Go to the documentation of this file.
1//
2// This module handles states which are global to the entire server.
3//
4// Copyright (c) 1987-2021 by the citadel.org team
5//
6// This program is open source software. Use, duplication, or disclosure
7// is subject to the terms of the GNU General Public License, version 3.
8// The program is distributed without any warranty, expressed or implied.
9
10#include <stdio.h>
11#include <sys/file.h>
12#include <libcitadel.h>
13
14#include "ctdl_module.h"
15#include "config.h"
16#include "citserver.h"
17#include "user_ops.h"
18
20
21/*
22 * This is the legacy "control record" format for the message base. If found
23 * on disk, its contents will be migrated into the system configuration. Never
24 * change this.
25 */
27 long MMhighest; /* highest message number in file */
28 unsigned MMflags; /* Global system flags */
29 long MMnextuser; /* highest user number on system */
30 long MMnextroom; /* highest room number on system */
31 int MM_hosted_upgrade_level; /* Server-hosted upgrade level */
32 int MM_fulltext_wordbreaker; /* ID of wordbreaker in use */
33 long MMfulltext; /* highest message number indexed */
34 int MMdbversion; /* Version of Berkeley DB used on previous server run */
35};
36
37
38/*
39 * data that gets passed back and forth between control_find_highest() and its caller
40 */
41struct cfh {
44};
45
46
47/*
48 * Callback to get highest room number when rebuilding message base metadata
49 *
50 * sanity_diag_mode (can be set by -s flag at startup) may be:
51 * 0 = attempt to fix inconsistencies
52 * 1 = show inconsistencies but don't repair them, exit after complete
53 * 2 = show inconsistencies but don't repair them, continue execution
54 */
55void control_find_highest(struct ctdlroom *qrbuf, void *data) {
56 struct cfh *cfh = (struct cfh *)data;
57 struct cdbdata *cdbfr;
58 long *msglist;
59 int num_msgs=0;
60 int c;
61
64 }
65
66 /* Load the message list */
67 cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long));
68 if (cdbfr != NULL) {
69 msglist = (long *) cdbfr->ptr;
70 num_msgs = cdbfr->len / sizeof(long);
71 }
72 else {
73 return; /* No messages at all? No further action. */
74 }
75
76 if (num_msgs > 0) {
77 for (c=0; c<num_msgs; c++) {
78 if (msglist[c] > cfh->highest_msgnum_found) {
79 cfh->highest_msgnum_found = msglist[c];
80 }
81 }
82 }
83
84 cdb_free(cdbfr);
85}
86
87
88/*
89 * Callback to get highest user number.
90 */
91void control_find_user(char *username, void *out_data) {
92 struct ctdluser EachUser;
93
94 if (CtdlGetUser(&EachUser, username) != 0) {
95 return;
96 }
97
98 if (EachUser.usernum > CtdlGetConfigLong("MMnextuser")) {
99 syslog(LOG_DEBUG, "control: fixing MMnextuser %ld > %ld , found in %s",
100 EachUser.usernum, CtdlGetConfigLong("MMnextuser"), EachUser.fullname
101 );
102 if (!sanity_diag_mode) {
103 CtdlSetConfigLong("MMnextuser", EachUser.usernum);
104 }
105 }
106}
107
108
109/*
110 * If we have a legacy format control record on disk, import it.
111 */
113 FILE *fp = NULL;
114 struct legacy_ctrl_format c;
115 memset(&c, 0, sizeof(c));
116
117 fp = fopen("citadel.control", "rb+");
118 if (fp != NULL) {
119 syslog(LOG_INFO, "control: legacy format record found -- importing to db");
120 fread(&c, sizeof(struct legacy_ctrl_format), 1, fp);
121
122 CtdlSetConfigLong( "MMhighest", c.MMhighest);
123 CtdlSetConfigInt( "MMflags", c.MMflags);
124 CtdlSetConfigLong( "MMnextuser", c.MMnextuser);
125 CtdlSetConfigLong( "MMnextroom", c.MMnextroom);
126 CtdlSetConfigInt( "MM_hosted_upgrade_level", c.MM_hosted_upgrade_level);
127 CtdlSetConfigInt( "MM_fulltext_wordbreaker", c.MM_fulltext_wordbreaker);
128 CtdlSetConfigLong( "MMfulltext", c.MMfulltext);
129
130 fclose(fp);
131 if (unlink("citadel.control") != 0) {
132 fprintf(stderr, "Unable to remove legacy control record after migrating it.\n");
133 fprintf(stderr, "Exiting to prevent data corruption.\n");
134 exit(CTDLEXIT_CONFIG);
135 }
136 }
137}
138
139
140/*
141 * check_control - check the control record has sensible values for message, user and room numbers
142 */
143void check_control(void) {
144
145 syslog(LOG_INFO, "control: sanity checking the recorded highest message and room numbers");
146 struct cfh cfh;
147 memset(&cfh, 0, sizeof(struct cfh));
149
150 if (cfh.highest_roomnum_found > CtdlGetConfigLong("MMnextroom")) {
151 syslog(LOG_DEBUG, "control: fixing MMnextroom %ld > %ld", cfh.highest_roomnum_found, CtdlGetConfigLong("MMnextroom"));
152 if (!sanity_diag_mode) {
154 }
155 }
156
157 if (cfh.highest_msgnum_found > CtdlGetConfigLong("MMhighest")) {
158 syslog(LOG_DEBUG, "control: fixing MMhighest %ld > %ld", cfh.highest_msgnum_found, CtdlGetConfigLong("MMhighest"));
159 if (!sanity_diag_mode) {
161 }
162 }
163
164 syslog(LOG_INFO, "control: sanity checking the recorded highest user number");
166
167 syslog(LOG_INFO, "control: sanity checks complete");
168
169 if (sanity_diag_mode == 1) {
170 syslog(LOG_INFO, "control: sanity check diagnostic mode is active - exiting now");
171 abort();
172 }
173}
174
175
176/*
177 * get_new_message_number() - Obtain a new, unique ID to be used for a message.
178 */
180{
181 long retval = 0L;
183 retval = CtdlGetConfigLong("MMhighest");
184 ++retval;
185 CtdlSetConfigLong("MMhighest", retval);
187 return(retval);
188}
189
190
191/*
192 * CtdlGetCurrentMessageNumber() - Obtain the current highest message number in the system
193 * This provides a quick way to initialise a variable that might be used to indicate
194 * messages that should not be processed. For example, an inbox rules script will use this
195 * to record determine that messages older than this should not be processed.
196 *
197 * (Why is this function here? Can't we just go straight to the config variable it fetches?)
198 */
200{
201 return CtdlGetConfigLong("MMhighest");
202}
203
204
205/*
206 * get_new_user_number() - Obtain a new, unique ID to be used for a user.
207 */
209{
210 long retval = 0L;
212 retval = CtdlGetConfigLong("MMnextuser");
213 ++retval;
214 CtdlSetConfigLong("MMnextuser", retval);
216 return(retval);
217}
218
219
220/*
221 * get_new_room_number() - Obtain a new, unique ID to be used for a room.
222 */
224{
225 long retval = 0L;
227 retval = CtdlGetConfigLong("MMnextroom");
228 ++retval;
229 CtdlSetConfigLong("MMnextroom", retval);
231 return(retval);
232}
233
234
235/*
236 * Helper function for cmd_conf() to handle boolean values
237 */
238int confbool(char *v)
239{
240 if (IsEmptyStr(v)) return(0);
241 if (atoi(v) != 0) return(1);
242 return(0);
243}
244
245
246/*
247 * Get or set global configuration options
248 */
249void cmd_conf(char *argbuf)
250{
251 char cmd[16];
252 char buf[1024];
253 int a, i;
254 long ii;
255 char *confptr;
256 char confname[128];
257
258 if (CtdlAccessCheck(ac_aide)) return;
259
260 extract_token(cmd, argbuf, 0, '|', sizeof cmd);
261
262 // CONF GET - retrieve system configuration in legacy format
263 // This is deprecated; please do not add fields or change their order.
264 if (!strcasecmp(cmd, "GET")) {
265 cprintf("%d Configuration...\n", LISTING_FOLLOWS);
266 cprintf("%s\n", CtdlGetConfigStr("c_nodename"));
267 cprintf("%s\n", CtdlGetConfigStr("c_fqdn"));
268 cprintf("%s\n", CtdlGetConfigStr("c_humannode"));
269 cprintf("xxx\n"); /* placeholder -- field no longer in use */
270 cprintf("%d\n", CtdlGetConfigInt("c_creataide"));
271 cprintf("%d\n", CtdlGetConfigInt("c_sleeping"));
272 cprintf("%d\n", CtdlGetConfigInt("c_initax"));
273 cprintf("%d\n", CtdlGetConfigInt("c_regiscall"));
274 cprintf("%d\n", CtdlGetConfigInt("c_twitdetect"));
275 cprintf("%s\n", CtdlGetConfigStr("c_twitroom"));
276 cprintf("%s\n", CtdlGetConfigStr("c_moreprompt"));
277 cprintf("%d\n", CtdlGetConfigInt("c_restrict"));
278 cprintf("%s\n", CtdlGetConfigStr("c_site_location"));
279 cprintf("%s\n", CtdlGetConfigStr("c_sysadm"));
280 cprintf("%d\n", CtdlGetConfigInt("c_maxsessions"));
281 cprintf("xxx\n"); /* placeholder -- field no longer in use */
282 cprintf("%d\n", CtdlGetConfigInt("c_userpurge"));
283 cprintf("%d\n", CtdlGetConfigInt("c_roompurge"));
284 cprintf("%s\n", CtdlGetConfigStr("c_logpages"));
285 cprintf("%d\n", CtdlGetConfigInt("c_createax"));
286 cprintf("%ld\n", CtdlGetConfigLong("c_maxmsglen"));
287 cprintf("%d\n", CtdlGetConfigInt("c_min_workers"));
288 cprintf("%d\n", CtdlGetConfigInt("c_max_workers"));
289 cprintf("%d\n", CtdlGetConfigInt("c_pop3_port"));
290 cprintf("%d\n", CtdlGetConfigInt("c_smtp_port"));
291 cprintf("%d\n", CtdlGetConfigInt("c_rfc822_strict_from"));
292 cprintf("%d\n", CtdlGetConfigInt("c_aide_zap"));
293 cprintf("%d\n", CtdlGetConfigInt("c_imap_port"));
294 cprintf("%ld\n", CtdlGetConfigLong("c_net_freq"));
295 cprintf("%d\n", CtdlGetConfigInt("c_disable_newu"));
296 cprintf("1\n"); /* niu */
297 cprintf("%d\n", CtdlGetConfigInt("c_purge_hour"));
298#ifdef HAVE_LDAP
299 cprintf("%s\n", CtdlGetConfigStr("c_ldap_host"));
300 cprintf("%d\n", CtdlGetConfigInt("c_ldap_port"));
301 cprintf("%s\n", CtdlGetConfigStr("c_ldap_base_dn"));
302 cprintf("%s\n", CtdlGetConfigStr("c_ldap_bind_dn"));
303 cprintf("%s\n", CtdlGetConfigStr("c_ldap_bind_pw"));
304#else
305 cprintf("\n");
306 cprintf("0\n");
307 cprintf("\n");
308 cprintf("\n");
309 cprintf("\n");
310#endif
311 cprintf("%s\n", CtdlGetConfigStr("c_ip_addr"));
312 cprintf("%d\n", CtdlGetConfigInt("c_msa_port"));
313 cprintf("%d\n", CtdlGetConfigInt("c_imaps_port"));
314 cprintf("%d\n", CtdlGetConfigInt("c_pop3s_port"));
315 cprintf("%d\n", CtdlGetConfigInt("c_smtps_port"));
316 cprintf("%d\n", CtdlGetConfigInt("c_enable_fulltext"));
317 cprintf("%d\n", CtdlGetConfigInt("c_auto_cull"));
318 cprintf("1\n");
319 cprintf("%d\n", CtdlGetConfigInt("c_allow_spoofing"));
320 cprintf("%d\n", CtdlGetConfigInt("c_journal_email"));
321 cprintf("%d\n", CtdlGetConfigInt("c_journal_pubmsgs"));
322 cprintf("%s\n", CtdlGetConfigStr("c_journal_dest"));
323 cprintf("%s\n", CtdlGetConfigStr("c_default_cal_zone"));
324 cprintf("%d\n", CtdlGetConfigInt("c_pftcpdict_port"));
325 cprintf("0\n");
326 cprintf("%d\n", CtdlGetConfigInt("c_auth_mode"));
327 cprintf("\n");
328 cprintf("\n");
329 cprintf("\n");
330 cprintf("\n");
331 cprintf("%d\n", CtdlGetConfigInt("c_rbl_at_greeting"));
332 cprintf("\n");
333 cprintf("\n");
334 cprintf("%s\n", CtdlGetConfigStr("c_pager_program"));
335 cprintf("%d\n", CtdlGetConfigInt("c_imap_keep_from"));
336 cprintf("%d\n", CtdlGetConfigInt("c_xmpp_c2s_port"));
337 cprintf("%d\n", CtdlGetConfigInt("c_xmpp_s2s_port"));
338 cprintf("%ld\n", CtdlGetConfigLong("c_pop3_fetch"));
339 cprintf("%ld\n", CtdlGetConfigLong("c_pop3_fastest"));
340 cprintf("%d\n", CtdlGetConfigInt("c_spam_flag_only"));
341 cprintf("%d\n", CtdlGetConfigInt("c_guest_logins"));
342 cprintf("%d\n", CtdlGetConfigInt("c_port_number"));
343 cprintf("%d\n", ctdluid);
344 cprintf("%d\n", CtdlGetConfigInt("c_nntp_port"));
345 cprintf("%d\n", CtdlGetConfigInt("c_nntps_port"));
346 cprintf("000\n");
347 }
348
349 // CONF SET - set system configuration in legacy format
350 // This is deprecated; please do not add fields or change their order.
351 else if (!strcasecmp(cmd, "SET")) {
353 cprintf("%d Send configuration...\n", SEND_LISTING);
354 a = 0;
355 while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) {
356 switch (a) {
357 case 0:
358 CtdlSetConfigStr("c_nodename", buf);
359 break;
360 case 1:
361 CtdlSetConfigStr("c_fqdn", buf);
362 break;
363 case 2:
364 CtdlSetConfigStr("c_humannode", buf);
365 break;
366 case 3:
367 /* placeholder -- field no longer in use */
368 break;
369 case 4:
370 CtdlSetConfigInt("c_creataide", confbool(buf));
371 break;
372 case 5:
373 CtdlSetConfigInt("c_sleeping", atoi(buf));
374 break;
375 case 6:
376 i = atoi(buf);
377 if (i < 1) i = 1;
378 if (i > 6) i = 6;
379 CtdlSetConfigInt("c_initax", i);
380 break;
381 case 7:
382 CtdlSetConfigInt("c_regiscall", confbool(buf));
383 break;
384 case 8:
385 CtdlSetConfigInt("c_twitdetect", confbool(buf));
386 break;
387 case 9:
388 CtdlSetConfigStr("c_twitroom", buf);
389 break;
390 case 10:
391 CtdlSetConfigStr("c_moreprompt", buf);
392 break;
393 case 11:
394 CtdlSetConfigInt("c_restrict", confbool(buf));
395 break;
396 case 12:
397 CtdlSetConfigStr("c_site_location", buf);
398 break;
399 case 13:
400 CtdlSetConfigStr("c_sysadm", buf);
401 break;
402 case 14:
403 i = atoi(buf);
404 if (i < 0) i = 0;
405 CtdlSetConfigInt("c_maxsessions", i);
406 break;
407 case 15:
408 /* placeholder -- field no longer in use */
409 break;
410 case 16:
411 CtdlSetConfigInt("c_userpurge", atoi(buf));
412 break;
413 case 17:
414 CtdlSetConfigInt("c_roompurge", atoi(buf));
415 break;
416 case 18:
417 CtdlSetConfigStr("c_logpages", buf);
418 break;
419 case 19:
420 i = atoi(buf);
421 if (i < 1) i = 1;
422 if (i > 6) i = 6;
423 CtdlSetConfigInt("c_createax", i);
424 break;
425 case 20:
426 ii = atol(buf);
427 if (ii >= 8192) {
428 CtdlSetConfigLong("c_maxmsglen", ii);
429 }
430 break;
431 case 21:
432 i = atoi(buf);
433 if (i >= 3) { // minimum value
434 CtdlSetConfigInt("c_min_workers", i);
435 }
436 break;
437 case 22:
438 i = atoi(buf);
439 if (i >= CtdlGetConfigInt("c_min_workers")) { // max must be >= min
440 CtdlSetConfigInt("c_max_workers", i);
441 }
442 break;
443 case 23:
444 CtdlSetConfigInt("c_pop3_port", atoi(buf));
445 break;
446 case 24:
447 CtdlSetConfigInt("c_smtp_port", atoi(buf));
448 break;
449 case 25:
450 CtdlSetConfigInt("c_rfc822_strict_from", atoi(buf));
451 break;
452 case 26:
453 CtdlSetConfigInt("c_aide_zap", confbool(buf));
454 break;
455 case 27:
456 CtdlSetConfigInt("c_imap_port", atoi(buf));
457 break;
458 case 28:
459 CtdlSetConfigLong("c_net_freq", atol(buf));
460 break;
461 case 29:
462 CtdlSetConfigInt("c_disable_newu", confbool(buf));
463 break;
464 case 30:
465 /* niu */
466 break;
467 case 31:
468 i = atoi(buf);
469 if ((i >= 0) && (i <= 23)) {
470 CtdlSetConfigInt("c_purge_hour", i);
471 }
472 break;
473 case 32:
474 CtdlSetConfigStr("c_ldap_host", buf);
475 break;
476 case 33:
477 CtdlSetConfigInt("c_ldap_port", atoi(buf));
478 break;
479 case 34:
480 CtdlSetConfigStr("c_ldap_base_dn", buf);
481 break;
482 case 35:
483 CtdlSetConfigStr("c_ldap_bind_dn", buf);
484 break;
485 case 36:
486 CtdlSetConfigStr("c_ldap_bind_pw", buf);
487 break;
488 case 37:
489 CtdlSetConfigStr("c_ip_addr", buf);
490 break;
491 case 38:
492 CtdlSetConfigInt("c_msa_port", atoi(buf));
493 break;
494 case 39:
495 CtdlSetConfigInt("c_imaps_port", atoi(buf));
496 break;
497 case 40:
498 CtdlSetConfigInt("c_pop3s_port", atoi(buf));
499 break;
500 case 41:
501 CtdlSetConfigInt("c_smtps_port", atoi(buf));
502 break;
503 case 42:
504 CtdlSetConfigInt("c_enable_fulltext", confbool(buf));
505 break;
506 case 43:
507 CtdlSetConfigInt("c_auto_cull", confbool(buf));
508 break;
509 case 44:
510 /* niu */
511 break;
512 case 45:
513 CtdlSetConfigInt("c_allow_spoofing", confbool(buf));
514 break;
515 case 46:
516 CtdlSetConfigInt("c_journal_email", confbool(buf));
517 break;
518 case 47:
519 CtdlSetConfigInt("c_journal_pubmsgs", confbool(buf));
520 break;
521 case 48:
522 CtdlSetConfigStr("c_journal_dest", buf);
523 break;
524 case 49:
525 CtdlSetConfigStr("c_default_cal_zone", buf);
526 break;
527 case 50:
528 CtdlSetConfigInt("c_pftcpdict_port", atoi(buf));
529 break;
530 case 51:
531 /* niu */
532 break;
533 case 52:
534 CtdlSetConfigInt("c_auth_mode", atoi(buf));
535 break;
536 case 53:
537 /* niu */
538 break;
539 case 54:
540 /* niu */
541 break;
542 case 55:
543 /* niu */
544 break;
545 case 56:
546 /* niu */
547 break;
548 case 57:
549 CtdlSetConfigInt("c_rbl_at_greeting", confbool(buf));
550 break;
551 case 58:
552 /* niu */
553 break;
554 case 59:
555 /* niu */
556 break;
557 case 60:
558 CtdlSetConfigStr("c_pager_program", buf);
559 break;
560 case 61:
561 CtdlSetConfigInt("c_imap_keep_from", confbool(buf));
562 break;
563 case 62:
564 CtdlSetConfigInt("c_xmpp_c2s_port", atoi(buf));
565 break;
566 case 63:
567 CtdlSetConfigInt("c_xmpp_s2s_port", atoi(buf));
568 break;
569 case 64:
570 CtdlSetConfigLong("c_pop3_fetch", atol(buf));
571 break;
572 case 65:
573 CtdlSetConfigLong("c_pop3_fastest", atol(buf));
574 break;
575 case 66:
576 CtdlSetConfigInt("c_spam_flag_only", confbool(buf));
577 break;
578 case 67:
579 CtdlSetConfigInt("c_guest_logins", confbool(buf));
580 break;
581 case 68:
582 CtdlSetConfigInt("c_port_number", atoi(buf));
583 break;
584 case 69:
585 /* niu */
586 break;
587 case 70:
588 CtdlSetConfigInt("c_nntp_port", atoi(buf));
589 break;
590 case 71:
591 CtdlSetConfigInt("c_nntps_port", atoi(buf));
592 break;
593 }
594 ++a;
595 }
596 snprintf(buf, sizeof buf,
597 "The global system configuration has been edited by %s.\n",
598 (CC->logged_in ? CC->curr_user : "an administrator")
599 );
600 CtdlAideMessage(buf, "Citadel Configuration Manager Message");
601
602 if (!IsEmptyStr(CtdlGetConfigStr("c_logpages")))
603 CtdlCreateRoom(CtdlGetConfigStr("c_logpages"), 3, "", 0, 1, 1, VIEW_BBS);
604
605 /* If full text indexing has been disabled, invalidate the
606 * index so it doesn't try to use it later.
607 */
608 if (CtdlGetConfigInt("c_enable_fulltext") == 0) {
609 CtdlSetConfigInt("MM_fulltext_wordbreaker", 0);
610 }
611 }
612
613 // CONF GETSYS - retrieve arbitrary system configuration stanzas stored in the message base
614 else if (!strcasecmp(cmd, "GETSYS")) {
615 extract_token(confname, argbuf, 1, '|', sizeof confname);
616 confptr = CtdlGetSysConfig(confname);
617 if (confptr != NULL) {
618 long len;
619
620 len = strlen(confptr);
621 cprintf("%d %s\n", LISTING_FOLLOWS, confname);
622 client_write(confptr, len);
623 if ((len > 0) && (confptr[len - 1] != 10))
624 client_write("\n", 1);
625 cprintf("000\n");
626 free(confptr);
627 } else {
628 cprintf("%d No such configuration.\n",
630 }
631 }
632
633 // CONF PUTSYS - store arbitrary system configuration stanzas in the message base
634 else if (!strcasecmp(cmd, "PUTSYS")) {
635 extract_token(confname, argbuf, 1, '|', sizeof confname);
637 cprintf("%d %s\n", SEND_LISTING, confname);
638 confptr = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0);
639 CtdlPutSysConfig(confname, confptr);
640 free(confptr);
641 }
642
643 // CONF GETVAL - retrieve configuration variables from the database
644 // CONF LOADVAL - same thing but can handle variables bigger than 1 KB (deprecated and probably safe to remove)
645 else if ( (!strcasecmp(cmd, "GETVAL")) || (!strcasecmp(cmd, "LOADVAL")) ) {
646 extract_token(confname, argbuf, 1, '|', sizeof confname);
647 char *v = CtdlGetConfigStr(confname);
648 if ( (v) && (!strcasecmp(cmd, "GETVAL")) ) {
649 cprintf("%d %s|\n", CIT_OK, v);
650 }
651 else if ( (v) && (!strcasecmp(cmd, "LOADVAL")) ) {
652 cprintf("%d %d\n", BINARY_FOLLOWS, (int)strlen(v));
653 client_write(v, strlen(v));
654 }
655 else {
656 cprintf("%d |\n", ERROR);
657 }
658 }
659
660 // CONF PUTVAL - store configuration variables in the database
661 else if (!strcasecmp(cmd, "PUTVAL")) {
662 if (num_tokens(argbuf, '|') < 3) {
663 cprintf("%d name and value required\n", ERROR);
664 }
665 else {
666 extract_token(confname, argbuf, 1, '|', sizeof confname);
667 extract_token(buf, argbuf, 2, '|', sizeof buf);
668 CtdlSetConfigStr(confname, buf);
669 cprintf("%d setting '%s' to '%s'\n", CIT_OK, confname, buf);
670 }
671 }
672
673 // CONF STOREVAL - store configuration variables in the database bigger than 1 KB (deprecated and probably safe to remove)
674 else if (!strcasecmp(cmd, "STOREVAL")) {
675 if (num_tokens(argbuf, '|') < 3) {
676 cprintf("%d name and length required\n", ERROR);
677 }
678 else {
679 extract_token(confname, argbuf, 1, '|', sizeof confname);
680 int bytes = extract_int(argbuf, 2);
681 char *valbuf = malloc(bytes + 1);
682 cprintf("%d %d\n", SEND_BINARY, bytes);
683 client_read(valbuf, bytes);
684 valbuf[bytes+1] = 0;
685 CtdlSetConfigStr(confname, valbuf);
686 free(valbuf);
687 }
688 }
689
690 // CONF LISTVAL - list configuration variables in the database and their values
691 else if (!strcasecmp(cmd, "LISTVAL")) {
692 struct cdbdata *cdbcfg;
693 int keylen = 0;
694 char *key = NULL;
695 char *value = NULL;
696
697 cprintf("%d all configuration variables\n", LISTING_FOLLOWS);
699 while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg != NULL) {
700 if (cdbcfg->len < 1020) {
701 keylen = strlen(cdbcfg->ptr);
702 key = cdbcfg->ptr;
703 value = cdbcfg->ptr + keylen + 1;
704 cprintf("%s|%s\n", key, value);
705 }
706 cdb_free(cdbcfg);
707 }
708 cprintf("000\n");
709 }
710
711 else {
712 cprintf("%d Illegal option(s) specified.\n", ERROR + ILLEGAL_VALUE);
713 }
714}
715
716
717typedef struct __ConfType {
718 ConstStr Name;
719 long Type;
721
723 { {HKEY("localhost") }, 0},
724 { {HKEY("directory") }, 0},
725 { {HKEY("smarthost") }, 2},
726 { {HKEY("fallbackhost") }, 2},
727 { {HKEY("rbl") }, 3},
728 { {HKEY("spamassassin") }, 3},
729 { {HKEY("masqdomain") }, 1},
730 { {HKEY("clamav") }, 3},
731 { {HKEY("notify") }, 3},
732 { {NULL, 0}, 0}
733};
734
735HashList *CfgNameHash = NULL;
736void cmd_gvdn(char *argbuf)
737{
738 const ConfType *pCfg;
739 char *confptr;
740 long min = atol(argbuf);
741 const char *Pos = NULL;
742 const char *PPos = NULL;
743 const char *HKey;
744 long HKLen;
745 StrBuf *Line;
746 StrBuf *Config;
747 StrBuf *Cfg;
748 StrBuf *CfgToken;
749 HashList *List;
750 HashPos *It;
751 void *vptr;
752
753 List = NewHash(1, NULL);
754 Cfg = NewStrBufPlain(CtdlGetConfigStr("c_fqdn"), -1);
755 Put(List, SKEY(Cfg), Cfg, HFreeStrBuf);
756 Cfg = NULL;
757
758 confptr = CtdlGetSysConfig(INTERNETCFG);
759 Config = NewStrBufPlain(confptr, -1);
760 free(confptr);
761
762 Line = NewStrBufPlain(NULL, StrLength(Config));
763 CfgToken = NewStrBufPlain(NULL, StrLength(Config));
764 while (StrBufSipLine(Line, Config, &Pos))
765 {
766 if (Cfg == NULL)
767 Cfg = NewStrBufPlain(NULL, StrLength(Line));
768 PPos = NULL;
769 StrBufExtract_NextToken(Cfg, Line, &PPos, '|');
770 StrBufExtract_NextToken(CfgToken, Line, &PPos, '|');
771 if (GetHash(CfgNameHash, SKEY(CfgToken), &vptr) &&
772 (vptr != NULL))
773 {
774 pCfg = (ConfType *) vptr;
775 if (pCfg->Type <= min)
776 {
777 Put(List, SKEY(Cfg), Cfg, HFreeStrBuf);
778 Cfg = NULL;
779 }
780 }
781 }
782
783 cprintf("%d Valid Domains\n", LISTING_FOLLOWS);
784 It = GetNewHashPos(List, 1);
785 while (GetNextHashPos(List, It, &HKLen, &HKey, &vptr))
786 {
787 cputbuf(vptr);
788 cprintf("\n");
789 }
790 cprintf("000\n");
791
792 DeleteHashPos(&It);
793 DeleteHash(&List);
794 FreeStrBuf(&Cfg);
795 FreeStrBuf(&Line);
796 FreeStrBuf(&CfgToken);
797 FreeStrBuf(&Config);
798}
799
800/*****************************************************************************/
801/* MODULE INITIALIZATION STUFF */
802/*****************************************************************************/
803
805{
806 if (!threading) {
807 int i;
808
809 CfgNameHash = NewHash(1, NULL);
810 for (i = 0; CfgNames[i].Name.Key != NULL; i++)
811 Put(CfgNameHash, CKEY(CfgNames[i].Name), &CfgNames[i], reference_free_handler);
812
813 CtdlRegisterProtoHook(cmd_gvdn, "GVDN", "get valid domain names");
814 CtdlRegisterProtoHook(cmd_conf, "CONF", "get/set system configuration");
815 }
816 /* return our id for the Log */
817 return "control";
818}
char * CtdlGetConfigStr(char *key)
Definition: config.c:393
void CtdlSetConfigLong(char *key, long value)
Definition: config.c:348
int CtdlGetConfigInt(char *key)
Definition: config.c:426
long CtdlGetConfigLong(char *key)
Definition: config.c:437
void CtdlPutSysConfig(char *sysconfname, char *sysconfdata)
Definition: config.c:510
void CtdlSetConfigStr(char *key, char *value)
Definition: config.c:326
void CtdlSetConfigInt(char *key, int value)
Definition: config.c:359
char * CtdlGetSysConfig(char *sysconfname)
Definition: config.c:452
#define CC
Definition: context.h:140
void cmd_gvdn(char *argbuf)
Definition: control.c:736
long get_new_room_number(void)
Definition: control.c:223
int confbool(char *v)
Definition: control.c:238
long CtdlGetCurrentMessageNumber(void)
Definition: control.c:199
void cmd_conf(char *argbuf)
Definition: control.c:249
struct __ConfType ConfType
long get_new_user_number(void)
Definition: control.c:208
void control_find_user(char *username, void *out_data)
Definition: control.c:91
long control_highest_user
Definition: control.c:19
ConfType CfgNames[]
Definition: control.c:722
long get_new_message_number(void)
Definition: control.c:179
HashList * CfgNameHash
Definition: control.c:735
void check_control(void)
Definition: control.c:143
void migrate_legacy_control_record(void)
Definition: control.c:112
void control_find_highest(struct ctdlroom *qrbuf, void *data)
Definition: control.c:55
int CtdlAccessCheck(int)
Definition: user_ops.c:389
#define CtdlAideMessage(TEXT, SUBJECT)
Definition: ctdl_module.h:58
void CtdlForEachRoom(ForEachRoomCallBack CB, void *in_data)
Definition: room_ops.c:606
@ ac_aide
Definition: ctdl_module.h:246
unsigned CtdlCreateRoom(char *new_room_name, int new_room_type, char *new_room_pass, int new_room_floor, int really_create, int avoid_access, int new_room_view)
Definition: room_ops.c:1136
int CtdlGetUser(struct ctdluser *usbuf, char *name)
Definition: user_ops.c:77
void CtdlRegisterProtoHook(void(*handler)(char *), char *cmd, char *desc)
#define CTDL_MODULE_INIT(module_name)
Definition: ctdl_module.h:50
void cdb_free(struct cdbdata *cdb)
Definition: database.c:609
struct cdbdata * cdb_next_item(int cdb)
Definition: database.c:655
struct cdbdata * cdb_fetch(int cdb, const void *key, int keylen)
Definition: database.c:546
void cdb_rewind(int cdb)
Definition: database.c:631
#define CIT_OK
Definition: ipcdef.h:6
#define ILLEGAL_VALUE
Definition: ipcdef.h:16
#define LISTING_FOLLOWS
Definition: ipcdef.h:5
#define SEND_BINARY
Definition: ipcdef.h:11
#define BINARY_FOLLOWS
Definition: ipcdef.h:10
#define ERROR
Definition: ipcdef.h:9
#define SEND_LISTING
Definition: ipcdef.h:8
char * CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, StrBuf *exist, int crlf)
Definition: msgbase.c:3037
void * malloc(size_t)
void free(void *)
struct ctdlroom qrbuf
Definition: serv_migrate.c:497
#define CTDLEXIT_CONFIG
Definition: server.h:74
uid_t ctdluid
Definition: server_main.c:30
@ CDB_MSGLISTS
Definition: server.h:189
@ CDB_CONFIG
Definition: server.h:198
int sanity_diag_mode
Definition: server_main.c:33
@ S_CONTROL
Definition: server.h:140
int snprintf(char *buf, size_t max, const char *fmt,...)
Definition: snprintf.c:69
ConstStr Name
Definition: control.c:718
long Type
Definition: control.c:719
size_t len
Definition: server.h:203
char * ptr
Definition: server.h:204
Definition: control.c:41
long highest_msgnum_found
Definition: control.c:43
long highest_roomnum_found
Definition: control.c:42
long QRnumber
Definition: citadel.h:119
char fullname[64]
Definition: citadel.h:90
long usernum
Definition: citadel.h:87
int MM_fulltext_wordbreaker
Definition: control.c:32
int MM_hosted_upgrade_level
Definition: control.c:31
unsigned MMflags
Definition: control.c:28
void cprintf(const char *format,...)
Definition: sysdep.c:381
int client_getln(char *buf, int bufsize)
Definition: sysdep.c:548
int client_write(const char *buf, int nbytes)
Definition: sysdep.c:307
int client_read(char *buf, int bytes)
Definition: sysdep.c:514
void unbuffer_output(void)
Definition: sysdep.c:276
void cputbuf(const StrBuf *Buf)
Definition: sysdep.c:374
void begin_critical_section(int which_one)
Definition: threads.c:67
void end_critical_section(int which_one)
Definition: threads.c:85
void ForEachUser(void(*CallBack)(char *, void *out_data), void *in_data)
Definition: user_ops.c:1206