4 * Citadel setup utility
14 #include <sys/types.h>
16 #include <sys/utsname.h>
24 #include <libcitadel.h>
29 #include "citadel_dirs.h"
31 #define MAXSETUP 6 /* How many setup questions to ask */
33 #define UI_TEXT 0 /* Default setup type -- text only */
34 #define UI_DIALOG 2 /* Use the 'dialog' program */
35 #define UI_SILENT 3 /* Silent running, for use in scripts */
37 #define SERVICE_NAME "citadel"
38 #define PROTO_NAME "tcp"
39 #define NSSCONF "/etc/nsswitch.conf"
42 char setup_directory[PATH_MAX];
43 int using_web_installer = 0;
48 char *setup_titles[] =
50 "Citadel Home Directory",
51 "System Administrator",
52 "Administrator Password",
62 /* calculate all our path on a central place */
63 /* where to keep our config */
66 char *setup_text[] = {
68 "Enter the full pathname of the directory in which the Citadel\n"
69 "installation you are creating or updating resides. If you\n"
70 "specify a directory other than the default, you will need to\n"
71 "specify the -h flag to the server when you start it up.\n",
73 "Enter the subdirectory name for an alternate installation of "
74 "Citadel. To do a default installation just leave it blank."
75 "If you specify a directory other than the default, you will need to\n"
76 "specify the -h flag to the server when you start it up.\n"
77 "note that it may not have a leading /",
80 "Enter the name of the system administrator (which is probably\n"
81 "you). When an account is created with this name, it will\n"
82 "automatically be given administrator-level access.\n",
84 "Enter a password for the system administrator. When setup\n"
85 "completes it will attempt to create the administrator user\n"
86 "and set the password specified here.\n",
88 "Citadel needs to run under its own user ID. This would\n"
89 "typically be called \"citadel\", but if you are running Citadel\n"
90 "as a public BBS, you might also call it \"bbs\" or \"guest\".\n"
91 "The server will run under this user ID. Please specify that\n"
92 "user ID here. You may specify either a user name or a numeric\n"
95 "Specify the IP address on which your server will run. If you\n"
96 "leave this blank, or if you specify 0.0.0.0, Citadel will listen\n"
97 "on all addresses. You can usually skip this unless you are\n"
98 "running multiple instances of Citadel on the same computer.\n",
100 "Specify the TCP port number on which your server will run.\n"
101 "Normally, this will be port 504, which is the official port\n"
102 "assigned by the IANA for Citadel servers. You will only need\n"
103 "to specify a different port number if you run multiple instances\n"
104 "of Citadel on the same computer and there is something else\n"
105 "already using port 504.\n",
107 "Normally, a Citadel system uses a \"black box\" authentication mode.\n"
108 "This means that users do not have accounts or home directories on\n"
109 "the underlying host system -- Citadel manages its own user database.\n"
110 "However, if you wish to override this behavior, you can enable the\n"
111 "host based authentication mode which is traditional for Unix systems.\n"
112 "WARNING: do *not* change this setting once your system is installed.\n"
114 "(Answer \"no\" unless you completely understand this option)\n"
115 "Do you want to enable host based authentication mode?\n"
119 struct config config;
123 void cleanup(int exitcode)
130 void title(char *text)
132 if (setup_type == UI_TEXT) {
133 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<%s>\n", text);
139 int yesno(char *question, int default_value)
145 switch (setup_type) {
149 printf("%s\nYes/No [%s] --> ",
151 ( default_value ? "Yes" : "No" )
153 fgets(buf, sizeof buf, stdin);
154 answer = tolower(buf[0]);
155 if ((buf[0]==0) || (buf[0]==13) || (buf[0]==10))
156 answer = default_value;
157 else if (answer == 'y')
159 else if (answer == 'n')
161 } while ((answer < 0) || (answer > 1));
165 sprintf(buf, "exec %s %s --yesno '%s' 15 75",
166 getenv("CTDL_DIALOG"),
167 ( default_value ? "" : "--defaultno" ),
183 void important_message(char *title, char *msgtext)
187 switch (setup_type) {
190 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
191 printf(" %s \n\n%s\n\n", title, msgtext);
192 printf("Press return to continue...");
193 fgets(buf, sizeof buf, stdin);
197 sprintf(buf, "exec %s --msgbox '%s' 19 72",
198 getenv("CTDL_DIALOG"),
205 void important_msgnum(int msgnum)
207 important_message("Important Message", setup_text[msgnum]);
210 void display_error(char *error_message)
212 important_message("Error", error_message);
215 void progress(char *text, long int curr, long int cmax)
217 static long dots_printed = 0L;
219 static FILE *fp = NULL;
222 switch (setup_type) {
226 printf("%s\n", text);
227 printf("..........................");
228 printf("..........................");
229 printf("..........................\r");
232 } else if (curr == cmax) {
233 printf("\r%79s\n", "");
235 a = (curr * 100) / cmax;
238 while (dots_printed < a) {
248 sprintf(buf, "exec %s --gauge '%s' 7 72 0",
249 getenv("CTDL_DIALOG"),
251 fp = popen(buf, "w");
257 else if (curr == cmax) {
259 fprintf(fp, "100\n");
265 a = (curr * 100) / cmax;
267 fprintf(fp, "%ld\n", a);
279 * check_services_entry() -- Make sure "citadel" is in /etc/services
282 void check_services_entry(void)
288 if (getservbyname(SERVICE_NAME, PROTO_NAME) == NULL) {
289 for (i=0; i<=2; ++i) {
290 progress("Adding service entry...", i, 2);
292 sfp = fopen("/etc/services", "a");
294 sprintf(errmsg, "Cannot open /etc/services: %s", strerror(errno));
295 display_error(errmsg);
297 fprintf(sfp, "%s 504/tcp\n", SERVICE_NAME);
309 * delete_inittab_entry() -- Remove obsolete /etc/inittab entry for Citadel
312 void delete_inittab_entry(void)
316 char looking_for[256];
318 char outfilename[32];
319 int changes_made = 0;
321 /* Determine the fully qualified path name of citserver */
322 snprintf(looking_for,
328 /* Now tweak /etc/inittab */
329 infp = fopen("/etc/inittab", "r");
332 /* If /etc/inittab does not exist, return quietly.
333 * Not all host platforms have it.
335 if (errno == ENOENT) {
339 /* Other errors might mean something really did go wrong.
341 sprintf(buf, "Cannot open /etc/inittab: %s", strerror(errno));
346 strcpy(outfilename, "/tmp/ctdlsetup.XXXXXX");
347 outfp = fdopen(mkstemp(outfilename), "w+");
349 sprintf(buf, "Cannot open %s: %s", outfilename, strerror(errno));
355 while (fgets(buf, sizeof buf, infp) != NULL) {
356 if (strstr(buf, looking_for) != NULL) {
357 fwrite("#", 1, 1, outfp);
360 fwrite(buf, strlen(buf), 1, outfp);
367 sprintf(buf, "/bin/mv -f %s /etc/inittab 2>/dev/null", outfilename);
369 system("/sbin/init q 2>/dev/null");
378 * install_init_scripts() -- Try to configure to start Citadel at boot
381 void install_init_scripts(void)
383 struct stat etcinitd;
385 char *initfile = "/etc/init.d/citadel";
388 if ((stat("/etc/init.d/", &etcinitd) == -1) &&
391 if ((stat("/etc/rc.d/init.d/", &etcinitd) == -1) &&
393 initfile = CTDLDIR"/citadel.init";
395 initfile = "/etc/rc.d/init.d/citadel";
398 fp = fopen(initfile, "r");
400 if (yesno("Citadel already appears to be configured to start at boot.\n"
401 "Would you like to keep your boot configuration as is?\n", 1) == 1) {
408 if (yesno("Would you like to automatically start Citadel at boot?\n", 1) == 0) {
412 fp = fopen(initfile, "w");
414 display_error("Cannot create /etc/init.d/citadel");
418 fprintf(fp, "#!/bin/sh\n"
420 "# Init file for Citadel\n"
422 "# chkconfig: - 79 30\n"
423 "# description: Citadel service\n"
424 "# processname: citserver\n"
425 "# pidfile: %s/citadel.pid\n"
433 "test -d /var/run || exit 0\n"
437 "start) echo -n \"Starting Citadel... \"\n"
438 " if $CITADEL_DIR/citserver -d -h$CITADEL_DIR\n"
445 "stop) echo -n \"Stopping Citadel... \"\n"
446 " if $CITADEL_DIR/sendcommand DOWN >/dev/null 2>&1 ; then\n"
451 " rm -f %s/citadel.pid 2>/dev/null\n"
456 "restart) if $CITADEL_DIR/sendcommand DOWN 1 >/dev/null 2>&1 ; then\n"
462 "*) echo \"Usage: $0 {start|stop|restart}\"\n"
469 chmod(initfile, 0755);
471 /* Set up the run levels. */
472 system("/bin/rm -f /etc/rc?.d/[SK]??citadel 2>/dev/null");
473 snprintf(command, sizeof(command), "for x in 2 3 4 5 ; do [ -d /etc/rc$x.d ] && ln -s %s /etc/rc$x.d/S79citadel ; done 2>/dev/null", initfile);
475 snprintf(command, sizeof(command),"for x in 0 6 S; do [ -d /etc/rc$x.d ] && ln -s %s /etc/rc$x.d/K30citadel ; done 2>/dev/null", initfile);
486 * On systems which use xinetd, see if we can offer to install Citadel as
487 * the default telnet target.
489 void check_xinetd_entry(void) {
490 char *filename = "/etc/xinetd.d/telnet";
493 int already_citadel = 0;
495 fp = fopen(filename, "r+");
496 if (fp == NULL) return; /* Not there. Oh well... */
498 while (fgets(buf, sizeof buf, fp) != NULL) {
499 if (strstr(buf, setup_directory) != NULL) already_citadel = 1;
502 if (already_citadel) return; /* Already set up this way. */
504 /* Otherwise, prompt the user to create an entry. */
505 if (getenv("CREATE_XINETD_ENTRY") != NULL) {
506 if (strcasecmp(getenv("CREATE_XINETD_ENTRY"), "yes")) {
511 snprintf(buf, sizeof buf,
512 "Setup can configure the \"xinetd\" service to automatically\n"
513 "connect incoming telnet sessions to Citadel, bypassing the\n"
514 "host system login: prompt. Would you like to do this?\n"
516 if (yesno(buf, 1) == 0) {
521 fp = fopen(filename, "w");
523 "# description: telnet service for Citadel users\n"
528 " socket_type = stream\n"
531 " server = /usr/sbin/in.telnetd\n"
532 " server_args = -h -L %s/citadel\n"
533 " log_on_failure += USERID\n"
538 /* Now try to restart the service */
539 system("/etc/init.d/xinetd restart >/dev/null 2>&1");
545 * Offer to disable other MTA's
547 void disable_other_mta(char *mta) {
552 sprintf(buf, "/bin/ls -l /etc/rc*.d/S*%s 2>/dev/null; "
553 "/bin/ls -l /etc/rc.d/rc*.d/S*%s 2>/dev/null",
555 fp = popen(buf, "r");
556 if (fp == NULL) return;
558 while (fgets(buf, sizeof buf, fp) != NULL) {
562 if (lines == 0) return; /* Nothing to do. */
565 /* Offer to replace other MTA with the vastly superior Citadel :) */
567 if (getenv("ACT_AS_MTA")) {
568 if (strcasecmp(getenv("ACT_AS_MTA"), "yes")) {
573 snprintf(buf, sizeof buf,
574 "You appear to have the \"%s\" email program\n"
575 "running on your system. If you want Citadel mail\n"
576 "connected with %s, you will have to manually integrate\n"
577 "them. It is preferable to disable %s, and use Citadel's\n"
578 "SMTP, POP3, and IMAP services.\n\n"
579 "May we disable %s so that Citadel has access to ports\n"
580 "25, 110, and 143?\n",
583 if (yesno(buf, 1) == 0) {
588 sprintf(buf, "for x in /etc/rc*.d/S*%s; do mv $x `echo $x |sed s/S/K/g`; done >/dev/null 2>&1", mta);
590 sprintf(buf, "/etc/init.d/%s stop >/dev/null 2>&1", mta);
598 * Check to see if our server really works. Returns 0 on success.
600 int test_server(void) {
607 /* Generate a silly little cookie. We're going to write it out
608 * to the server and try to get it back. The cookie does not
609 * have to be secret ... just unique.
611 sprintf(cookie, "--test--%d--", getpid());
613 sprintf(cmd, "%s/sendcommand %s%s ECHO %s 2>&1",
615 (enable_home)?"-h":"",
616 (enable_home)?ctdl_run_dir:"",
619 fp = popen(cmd, "r");
620 if (fp == NULL) return(errno);
622 while (fgets(buf, sizeof buf, fp) != NULL) {
624 && (strstr(buf, cookie) != NULL) ) {
636 void strprompt(char *prompt_title, char *prompt_text, char *str)
640 char dialog_result[PATH_MAX];
643 strcpy(setupmsg, "");
645 switch (setup_type) {
648 printf("\n%s\n", prompt_text);
649 printf("This is currently set to:\n%s\n", str);
650 printf("Enter new value or press return to leave unchanged:\n");
651 fgets(buf, sizeof buf, stdin);
652 buf[strlen(buf) - 1] = 0;
653 if (!IsEmptyStr(buf))
658 CtdlMakeTempFileName(dialog_result, sizeof dialog_result);
659 sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
660 getenv("CTDL_DIALOG"),
665 fp = fopen(dialog_result, "r");
667 fgets(str, sizeof buf, fp);
668 if (str[strlen(str)-1] == 10) {
669 str[strlen(str)-1] = 0;
672 unlink(dialog_result);
679 void set_bool_val(int msgpos, int *ip) {
680 title(setup_titles[msgpos]);
681 *ip = yesno(setup_text[msgpos], *ip);
684 void set_str_val(int msgpos, char *str) {
685 strprompt(setup_titles[msgpos], setup_text[msgpos], str);
688 void set_int_val(int msgpos, int *ip)
691 snprintf(buf, sizeof buf, "%d", (int) *ip);
692 set_str_val(msgpos, buf);
697 void set_char_val(int msgpos, char *ip)
700 snprintf(buf, sizeof buf, "%d", (int) *ip);
701 set_str_val(msgpos, buf);
702 *ip = (char) atoi(buf);
706 void set_long_val(int msgpos, long int *ip)
709 snprintf(buf, sizeof buf, "%ld", *ip);
710 set_str_val(msgpos, buf);
715 void edit_value(int curr)
719 char ctdluidname[256];
724 if (setup_type == UI_SILENT)
726 if (getenv("SYSADMIN_NAME")) {
727 strcpy(config.c_sysadm, getenv("SYSADMIN_NAME"));
731 set_str_val(curr, config.c_sysadm);
736 if (setup_type == UI_SILENT)
738 if (getenv("SYSADMIN_PW")) {
739 strcpy(admin_pass, getenv("SYSADMIN_PW"));
743 set_str_val(curr, admin_pass);
748 if (setup_type == UI_SILENT)
750 if (getenv("CITADEL_UID")) {
751 config.c_ctdluid = atoi(getenv("CITADEL_UID"));
757 config.c_ctdluid = 0; /* XXX Windows hack, prob. insecure */
759 i = config.c_ctdluid;
762 set_int_val(curr, &i);
763 config.c_ctdluid = i;
766 strcpy(ctdluidname, pw->pw_name);
767 set_str_val(curr, ctdluidname);
768 pw = getpwnam(ctdluidname);
770 config.c_ctdluid = pw->pw_uid;
772 else if (atoi(ctdluidname) > 0) {
773 config.c_ctdluid = atoi(ctdluidname);
781 if (setup_type == UI_SILENT)
783 if (getenv("IP_ADDR")) {
784 strcpy(config.c_ip_addr, getenv("IP_ADDR"));
788 set_str_val(curr, config.c_ip_addr);
793 if (setup_type == UI_SILENT)
795 if (getenv("CITADEL_PORT")) {
796 config.c_port_number = atoi(getenv("CITADEL_PORT"));
801 set_int_val(curr, &config.c_port_number);
806 if (setup_type == UI_SILENT)
808 if (getenv("ENABLE_UNIX_AUTH")) {
809 if (!strcasecmp(getenv("ENABLE_UNIX_AUTH"), "yes")) {
810 config.c_auth_mode = AUTHMODE_HOST;
813 config.c_auth_mode = AUTHMODE_NATIVE;
818 set_bool_val(curr, &config.c_auth_mode);
826 * (re-)write the config data to disk
828 void write_config_to_disk(void)
833 if ((fd = creat(file_citadel_config, S_IRUSR | S_IWUSR)) == -1) {
834 display_error("setup: cannot open citadel.config");
837 fp = fdopen(fd, "wb");
839 display_error("setup: cannot open citadel.config");
842 fwrite((char *) &config, sizeof(struct config), 1, fp);
850 * Figure out what type of user interface we're going to use
852 int discover_ui(void)
855 /* Use "dialog" if we have it */
856 if (getenv("CTDL_DIALOG") != NULL) {
868 * Strip "db" entries out of /etc/nsswitch.conf
878 int file_changed = 0;
879 char new_filename[64];
881 fp_read = fopen(NSSCONF, "r");
882 if (fp_read == NULL) {
886 strcpy(new_filename, "/tmp/ctdl_fixnss_XXXXXX");
887 fd_write = mkstemp(new_filename);
893 while (fgets(buf, sizeof buf, fp_read) != NULL) {
896 for (i=0; i<strlen(buf_nc); ++i) {
897 if (buf_nc[i] == '#') {
901 for (i=0; i<strlen(buf_nc); ++i) {
902 if (!strncasecmp(&buf_nc[i], "db", 2)) {
904 if ((isspace(buf_nc[i+2])) || (buf_nc[i+2]==0)) {
907 strcpy(&buf_nc[i], &buf_nc[i+2]);
908 strcpy(&buf[i], &buf[i+2]);
910 strcpy(&buf_nc[i], &buf_nc[i+1]);
911 strcpy(&buf[i], &buf[i+1]);
917 if (write(fd_write, buf, strlen(buf)) != strlen(buf)) {
920 unlink(new_filename);
928 unlink(new_filename);
932 snprintf(question, sizeof question,
934 "/etc/nsswitch.conf is configured to use the 'db' module for\n"
935 "one or more services. This is not necessary on most systems,\n"
936 "and it is known to crash the Citadel server when delivering\n"
937 "mail to the Internet.\n"
939 "Do you want this module to be automatically disabled?\n"
943 if (yesno(question, 1)) {
944 sprintf(buf, "/bin/mv -f %s %s", new_filename, NSSCONF);
947 unlink(new_filename);
957 int main(int argc, char *argv[])
963 int old_setup_level = 0;
965 struct utsname my_utsname;
971 char relhome[PATH_MAX]="";
972 char ctdldir[PATH_MAX]=CTDLDIR;
974 /* set an invalid setup type */
977 /* Check to see if we're running the web installer */
978 if (getenv("CITADEL_INSTALLER") != NULL) {
979 using_web_installer = 1;
982 /* parse command line args */
983 for (a = 0; a < argc; ++a) {
984 if (!strncmp(argv[a], "-u", 2)) {
985 strcpy(aaa, argv[a]);
986 strcpy(aaa, &aaa[2]);
987 setup_type = atoi(aaa);
989 else if (!strcmp(argv[a], "-i")) {
992 else if (!strcmp(argv[a], "-q")) {
993 setup_type = UI_SILENT;
995 else if (!strncmp(argv[a], "-h", 2)) {
996 relh=argv[a][2]!='/';
997 if (!relh) safestrncpy(ctdl_home_directory, &argv[a][2],
998 sizeof ctdl_home_directory);
1000 safestrncpy(relhome, &argv[a][2],
1008 calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
1010 /* If a setup type was not specified, try to determine automatically
1011 * the best one to use out of all available types.
1013 if (setup_type < 0) {
1014 setup_type = discover_ui();
1016 if (info_only == 1) {
1017 important_message("Citadel Setup", CITADEL);
1021 /* Get started in a valid setup directory. */
1022 strcpy(setup_directory, ctdl_run_dir);
1023 if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
1024 strcpy(setup_directory, getenv("CITADEL"));
1027 set_str_val(0, setup_directory);
1030 enable_home=(relh|home);
1033 if (chdir(setup_directory) == 0) {
1034 strcpy(file_citadel_config, "./citadel.config");
1037 important_message("Citadel Setup",
1038 "The directory you specified does not exist.");
1043 /* Determine our host name, in case we need to use it as a default */
1046 /* Try to stop Citadel if we can */
1047 if (!access("/etc/init.d/citadel", X_OK)) {
1048 system("/etc/init.d/citadel stop");
1051 /* Make sure Citadel is not running. */
1052 if (test_server() == 0) {
1053 important_message("Citadel Setup",
1054 "The Citadel service is still running.\n"
1055 "Please stop the service manually and run "
1061 switch (setup_type) {
1065 " *** Citadel setup program ***\n\n");
1071 * What we're going to try to do here is append a whole bunch of
1072 * nulls to the citadel.config file, so we can keep the old config
1073 * values if they exist, but if the file is missing or from an
1074 * earlier version with a shorter config structure, when setup tries
1075 * to read the old config parameters, they'll all come up zero.
1076 * The length of the config file will be set to what it's supposed
1077 * to be when we rewrite it, because we replace the old file with a
1078 * completely new copy.
1080 if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
1081 S_IRUSR | S_IWUSR)) == -1) {
1082 display_error("setup: cannot append citadel.config");
1085 fp = fdopen(a, "ab");
1087 display_error("setup: cannot append citadel.config");
1090 for (a = 0; a < sizeof(struct config); ++a)
1094 /* now we re-open it, and read the old or blank configuration */
1095 fp = fopen(file_citadel_config, "rb");
1097 display_error("setup: cannot open citadel.config");
1100 fread((char *) &config, sizeof(struct config), 1, fp);
1103 /* set some sample/default values in place of blanks... */
1104 if (IsEmptyStr(config.c_nodename))
1105 safestrncpy(config.c_nodename, my_utsname.nodename,
1106 sizeof config.c_nodename);
1107 strtok(config.c_nodename, ".");
1108 if (IsEmptyStr(config.c_fqdn) ) {
1109 if ((he = gethostbyname(my_utsname.nodename)) != NULL)
1110 safestrncpy(config.c_fqdn, he->h_name,
1111 sizeof config.c_fqdn);
1113 safestrncpy(config.c_fqdn, my_utsname.nodename,
1114 sizeof config.c_fqdn);
1116 if (IsEmptyStr(config.c_humannode))
1117 strcpy(config.c_humannode, "My System");
1118 if (IsEmptyStr(config.c_phonenum))
1119 strcpy(config.c_phonenum, "US 800 555 1212");
1120 if (config.c_initax == 0) {
1121 config.c_initax = 4;
1123 if (IsEmptyStr(config.c_moreprompt))
1124 strcpy(config.c_moreprompt, "<more>");
1125 if (IsEmptyStr(config.c_twitroom))
1126 strcpy(config.c_twitroom, "Trashcan");
1127 if (IsEmptyStr(config.c_baseroom))
1128 strcpy(config.c_baseroom, BASEROOM);
1129 if (IsEmptyStr(config.c_aideroom))
1130 strcpy(config.c_aideroom, "Aide");
1131 if (config.c_port_number == 0) {
1132 config.c_port_number = 504;
1134 if (config.c_sleeping == 0) {
1135 config.c_sleeping = 900;
1137 if (config.c_ctdluid == 0) {
1138 pw = getpwnam("citadel");
1140 config.c_ctdluid = pw->pw_uid;
1142 if (config.c_ctdluid == 0) {
1143 pw = getpwnam("bbs");
1145 config.c_ctdluid = pw->pw_uid;
1147 if (config.c_ctdluid == 0) {
1148 pw = getpwnam("guest");
1150 config.c_ctdluid = pw->pw_uid;
1152 if (config.c_createax == 0) {
1153 config.c_createax = 3;
1156 * Negative values for maxsessions are not allowed.
1158 if (config.c_maxsessions < 0) {
1159 config.c_maxsessions = 0;
1161 /* We need a system default message expiry policy, because this is
1162 * the top level and there's no 'higher' policy to fall back on.
1163 * By default, do not expire messages at all.
1165 if (config.c_ep.expire_mode == 0) {
1166 config.c_ep.expire_mode = EXPIRE_MANUAL;
1167 config.c_ep.expire_value = 0;
1171 * Default port numbers for various services
1173 if (config.c_smtp_port == 0) config.c_smtp_port = 25;
1174 if (config.c_pop3_port == 0) config.c_pop3_port = 110;
1175 if (config.c_imap_port == 0) config.c_imap_port = 143;
1176 if (config.c_msa_port == 0) config.c_msa_port = 587;
1177 if (config.c_smtps_port == 0) config.c_smtps_port = 465;
1178 if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
1179 if (config.c_imaps_port == 0) config.c_imaps_port = 993;
1180 if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
1181 if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
1182 if (config.c_xmpp_c2s_port == 0) config.c_xmpp_c2s_port = 5222;
1183 if (config.c_xmpp_s2s_port == 0) config.c_xmpp_s2s_port = 5269;
1185 /* Go through a series of dialogs prompting for config info */
1186 for (curr = 1; curr <= MAXSETUP; ++curr) {
1190 /***** begin version update section ***** */
1191 /* take care of any updating that is necessary */
1193 old_setup_level = config.c_setup_level;
1195 if (old_setup_level == 0) {
1199 if (old_setup_level < 555) {
1200 important_message("Citadel Setup",
1201 "This Citadel installation is too old "
1205 write_config_to_disk();
1207 old_setup_level = config.c_setup_level;
1209 /* end of version update section */
1212 config.c_setup_level = REV_LEVEL;
1214 /******************************************/
1216 write_config_to_disk();
1218 mkdir(ctdl_info_dir, 0700);
1219 chmod(ctdl_info_dir, 0700);
1220 chown(ctdl_info_dir, config.c_ctdluid, -1);
1222 mkdir(ctdl_bio_dir, 0700);
1223 chmod(ctdl_bio_dir, 0700);
1224 chown(ctdl_bio_dir, config.c_ctdluid, -1);
1226 mkdir(ctdl_usrpic_dir, 0700);
1227 chmod(ctdl_usrpic_dir, 0700);
1228 chown(ctdl_usrpic_dir, config.c_ctdluid, -1);
1230 mkdir(ctdl_message_dir, 0700);
1231 chmod(ctdl_message_dir, 0700);
1232 chown(ctdl_message_dir, config.c_ctdluid, -1);
1234 mkdir(ctdl_hlp_dir, 0700);
1235 chmod(ctdl_hlp_dir, 0700);
1236 chown(ctdl_hlp_dir, config.c_ctdluid, -1);
1238 mkdir(ctdl_image_dir, 0700);
1239 chmod(ctdl_image_dir, 0700);
1240 chown(ctdl_image_dir, config.c_ctdluid, -1);
1242 mkdir(ctdl_bb_dir, 0700);
1243 chmod(ctdl_bb_dir, 0700);
1244 chown(ctdl_bb_dir, config.c_ctdluid, -1);
1246 mkdir(ctdl_file_dir, 0700);
1247 chmod(ctdl_file_dir, 0700);
1248 chown(ctdl_file_dir, config.c_ctdluid, -1);
1250 mkdir(ctdl_netcfg_dir, 0700);
1251 chmod(ctdl_netcfg_dir, 0700);
1252 chown(ctdl_netcfg_dir, config.c_ctdluid, -1);
1254 /* Delete files and directories used by older Citadel versions */
1255 system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
1256 unlink("citadel.log");
1259 if (((setup_type == UI_SILENT) && (getenv("ALTER_ETC_SERVICES")!=NULL)) ||
1260 (setup_type != UI_SILENT))
1261 check_services_entry(); /* Check /etc/services */
1263 delete_inittab_entry(); /* Remove obsolete /etc/inittab entry */
1264 check_xinetd_entry(); /* Check /etc/xinetd.d/telnet */
1266 /* Offer to disable other MTA's on the system. */
1267 disable_other_mta("courier-authdaemon");
1268 disable_other_mta("courier-imap");
1269 disable_other_mta("courier-imap-ssl");
1270 disable_other_mta("courier-pop");
1271 disable_other_mta("courier-pop3");
1272 disable_other_mta("courier-pop3d");
1273 disable_other_mta("cyrmaster");
1274 disable_other_mta("cyrus");
1275 disable_other_mta("dovecot");
1276 disable_other_mta("exim");
1277 disable_other_mta("exim4");
1278 disable_other_mta("imapd");
1279 disable_other_mta("mta");
1280 disable_other_mta("pop3d");
1281 disable_other_mta("popd");
1282 disable_other_mta("postfix");
1283 disable_other_mta("qmail");
1284 disable_other_mta("saslauthd");
1285 disable_other_mta("sendmail");
1286 disable_other_mta("vmailmgrd");
1289 /* Check for the 'db' nss and offer to disable it */
1292 if ((pw = getpwuid(config.c_ctdluid)) == NULL)
1297 progress("Setting file permissions", 0, 3);
1298 chown(ctdl_run_dir, config.c_ctdluid, gid);
1299 progress("Setting file permissions", 1, 3);
1300 chown(file_citadel_config, config.c_ctdluid, gid);
1301 progress("Setting file permissions", 2, 3);
1302 chmod(file_citadel_config, S_IRUSR | S_IWUSR);
1303 progress("Setting file permissions", 3, 3);
1306 * If we're running on SysV, install init scripts.
1308 if (!access("/var/run", W_OK)) {
1310 if (getenv("NO_INIT_SCRIPTS") == NULL) {
1311 install_init_scripts();
1314 if (!access("/etc/init.d/citadel", X_OK)) {
1315 system("/etc/init.d/citadel start");
1319 if (test_server() == 0) {
1320 snprintf (admin_cmd, sizeof(admin_cmd), "%s/sendcommand \"CREU %s|%s\"", ctdl_utilbin_dir, config.c_sysadm, admin_pass);
1322 important_message("Setup finished",
1323 "Setup of the Citadel server is complete.\n"
1324 "If you will be using WebCit, please run its\n"
1325 "setup program now; otherwise, run './citadel'\n"
1329 important_message("Setup failed",
1330 "Setup is finished, but the Citadel server failed to start.\n"
1331 "Go back and check your configuration.\n"
1338 important_message("Setup finished",
1339 "Setup is finished. You may now start the server.");