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(char *setup_directory) {
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 -h%s ECHO %s 2>&1",
618 fp = popen(cmd, "r");
619 if (fp == NULL) return(errno);
621 while (fgets(buf, sizeof buf, fp) != NULL) {
623 && (strstr(buf, cookie) != NULL) ) {
635 void strprompt(char *prompt_title, char *prompt_text, char *str)
639 char dialog_result[PATH_MAX];
642 strcpy(setupmsg, "");
644 switch (setup_type) {
647 printf("\n%s\n", prompt_text);
648 printf("This is currently set to:\n%s\n", str);
649 printf("Enter new value or press return to leave unchanged:\n");
650 fgets(buf, sizeof buf, stdin);
651 buf[strlen(buf) - 1] = 0;
652 if (!IsEmptyStr(buf))
657 CtdlMakeTempFileName(dialog_result, sizeof dialog_result);
658 sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
659 getenv("CTDL_DIALOG"),
664 fp = fopen(dialog_result, "r");
666 fgets(str, sizeof buf, fp);
667 if (str[strlen(str)-1] == 10) {
668 str[strlen(str)-1] = 0;
671 unlink(dialog_result);
678 void set_bool_val(int msgpos, int *ip) {
679 title(setup_titles[msgpos]);
680 *ip = yesno(setup_text[msgpos], *ip);
683 void set_str_val(int msgpos, char *str) {
684 strprompt(setup_titles[msgpos], setup_text[msgpos], str);
687 void set_int_val(int msgpos, int *ip)
690 snprintf(buf, sizeof buf, "%d", (int) *ip);
691 set_str_val(msgpos, buf);
696 void set_char_val(int msgpos, char *ip)
699 snprintf(buf, sizeof buf, "%d", (int) *ip);
700 set_str_val(msgpos, buf);
701 *ip = (char) atoi(buf);
705 void set_long_val(int msgpos, long int *ip)
708 snprintf(buf, sizeof buf, "%ld", *ip);
709 set_str_val(msgpos, buf);
714 void edit_value(int curr)
718 char ctdluidname[256];
723 if (setup_type == UI_SILENT)
725 if (getenv("SYSADMIN_NAME")) {
726 strcpy(config.c_sysadm, getenv("SYSADMIN_NAME"));
730 set_str_val(curr, config.c_sysadm);
735 if (setup_type == UI_SILENT)
737 if (getenv("SYSADMIN_PW")) {
738 strcpy(admin_pass, getenv("SYSADMIN_PW"));
742 set_str_val(curr, admin_pass);
747 if (setup_type == UI_SILENT)
749 if (getenv("CITADEL_UID")) {
750 config.c_ctdluid = atoi(getenv("CITADEL_UID"));
756 config.c_ctdluid = 0; /* XXX Windows hack, prob. insecure */
758 i = config.c_ctdluid;
761 set_int_val(curr, &i);
762 config.c_ctdluid = i;
765 strcpy(ctdluidname, pw->pw_name);
766 set_str_val(curr, ctdluidname);
767 pw = getpwnam(ctdluidname);
769 config.c_ctdluid = pw->pw_uid;
771 else if (atoi(ctdluidname) > 0) {
772 config.c_ctdluid = atoi(ctdluidname);
780 if (setup_type == UI_SILENT)
782 if (getenv("IP_ADDR")) {
783 strcpy(config.c_ip_addr, getenv("IP_ADDR"));
787 set_str_val(curr, config.c_ip_addr);
792 if (setup_type == UI_SILENT)
794 if (getenv("CITADEL_PORT")) {
795 config.c_port_number = atoi(getenv("CITADEL_PORT"));
800 set_int_val(curr, &config.c_port_number);
805 if (setup_type == UI_SILENT)
807 if (getenv("ENABLE_UNIX_AUTH")) {
808 if (!strcasecmp(getenv("ENABLE_UNIX_AUTH"), "yes")) {
809 config.c_auth_mode = AUTHMODE_HOST;
812 config.c_auth_mode = AUTHMODE_NATIVE;
817 set_bool_val(curr, &config.c_auth_mode);
825 * (re-)write the config data to disk
827 void write_config_to_disk(void)
832 if ((fd = creat(file_citadel_config, S_IRUSR | S_IWUSR)) == -1) {
833 display_error("setup: cannot open citadel.config");
836 fp = fdopen(fd, "wb");
838 display_error("setup: cannot open citadel.config");
841 fwrite((char *) &config, sizeof(struct config), 1, fp);
849 * Figure out what type of user interface we're going to use
851 int discover_ui(void)
854 /* Use "dialog" if we have it */
855 if (getenv("CTDL_DIALOG") != NULL) {
867 * Strip "db" entries out of /etc/nsswitch.conf
877 int file_changed = 0;
878 char new_filename[64];
880 fp_read = fopen(NSSCONF, "r");
881 if (fp_read == NULL) {
885 strcpy(new_filename, "/tmp/ctdl_fixnss_XXXXXX");
886 fd_write = mkstemp(new_filename);
892 while (fgets(buf, sizeof buf, fp_read) != NULL) {
895 for (i=0; i<strlen(buf_nc); ++i) {
896 if (buf_nc[i] == '#') {
900 for (i=0; i<strlen(buf_nc); ++i) {
901 if (!strncasecmp(&buf_nc[i], "db", 2)) {
903 if ((isspace(buf_nc[i+2])) || (buf_nc[i+2]==0)) {
906 strcpy(&buf_nc[i], &buf_nc[i+2]);
907 strcpy(&buf[i], &buf[i+2]);
909 strcpy(&buf_nc[i], &buf_nc[i+1]);
910 strcpy(&buf[i], &buf[i+1]);
916 if (write(fd_write, buf, strlen(buf)) != strlen(buf)) {
919 unlink(new_filename);
927 unlink(new_filename);
931 snprintf(question, sizeof question,
933 "/etc/nsswitch.conf is configured to use the 'db' module for\n"
934 "one or more services. This is not necessary on most systems,\n"
935 "and it is known to crash the Citadel server when delivering\n"
936 "mail to the Internet.\n"
938 "Do you want this module to be automatically disabled?\n"
942 if (yesno(question, 1)) {
943 sprintf(buf, "/bin/mv -f %s %s", new_filename, NSSCONF);
946 unlink(new_filename);
956 int main(int argc, char *argv[])
962 int old_setup_level = 0;
964 struct utsname my_utsname;
970 char relhome[PATH_MAX]="";
971 char ctdldir[PATH_MAX]=CTDLDIR;
973 /* set an invalid setup type */
976 /* Check to see if we're running the web installer */
977 if (getenv("CITADEL_INSTALLER") != NULL) {
978 using_web_installer = 1;
981 /* parse command line args */
982 for (a = 0; a < argc; ++a) {
983 if (!strncmp(argv[a], "-u", 2)) {
984 strcpy(aaa, argv[a]);
985 strcpy(aaa, &aaa[2]);
986 setup_type = atoi(aaa);
988 else if (!strcmp(argv[a], "-i")) {
991 else if (!strcmp(argv[a], "-q")) {
992 setup_type = UI_SILENT;
994 else if (!strncmp(argv[a], "-h", 2)) {
995 relh=argv[a][2]!='/';
996 if (!relh) safestrncpy(ctdl_home_directory, &argv[a][2],
997 sizeof ctdl_home_directory);
999 safestrncpy(relhome, &argv[a][2],
1006 calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
1008 /* If a setup type was not specified, try to determine automatically
1009 * the best one to use out of all available types.
1011 if (setup_type < 0) {
1012 setup_type = discover_ui();
1014 if (info_only == 1) {
1015 important_message("Citadel Setup", CITADEL);
1019 /* Get started in a valid setup directory. */
1020 strcpy(setup_directory, ctdl_run_dir);
1021 if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
1022 strcpy(setup_directory, getenv("CITADEL"));
1025 set_str_val(0, setup_directory);
1028 enable_home=(relh|home);
1030 if (chdir(setup_directory) == 0) {
1031 strcpy(file_citadel_config, "./citadel.config");
1034 important_message("Citadel Setup",
1035 "The directory you specified does not exist.");
1039 /* Determine our host name, in case we need to use it as a default */
1042 /* Try to stop Citadel if we can */
1043 if (!access("/etc/init.d/citadel", X_OK)) {
1044 system("/etc/init.d/citadel stop");
1047 /* Make sure Citadel is not running. */
1048 if (test_server(setup_directory) == 0) {
1049 important_message("Citadel Setup",
1050 "The Citadel service is still running.\n"
1051 "Please stop the service manually and run "
1057 switch (setup_type) {
1061 " *** Citadel setup program ***\n\n");
1067 * What we're going to try to do here is append a whole bunch of
1068 * nulls to the citadel.config file, so we can keep the old config
1069 * values if they exist, but if the file is missing or from an
1070 * earlier version with a shorter config structure, when setup tries
1071 * to read the old config parameters, they'll all come up zero.
1072 * The length of the config file will be set to what it's supposed
1073 * to be when we rewrite it, because we replace the old file with a
1074 * completely new copy.
1076 if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
1077 S_IRUSR | S_IWUSR)) == -1) {
1078 display_error("setup: cannot append citadel.config");
1081 fp = fdopen(a, "ab");
1083 display_error("setup: cannot append citadel.config");
1086 for (a = 0; a < sizeof(struct config); ++a)
1090 /* now we re-open it, and read the old or blank configuration */
1091 fp = fopen(file_citadel_config, "rb");
1093 display_error("setup: cannot open citadel.config");
1096 fread((char *) &config, sizeof(struct config), 1, fp);
1099 /* set some sample/default values in place of blanks... */
1100 if (IsEmptyStr(config.c_nodename))
1101 safestrncpy(config.c_nodename, my_utsname.nodename,
1102 sizeof config.c_nodename);
1103 strtok(config.c_nodename, ".");
1104 if (IsEmptyStr(config.c_fqdn) ) {
1105 if ((he = gethostbyname(my_utsname.nodename)) != NULL)
1106 safestrncpy(config.c_fqdn, he->h_name,
1107 sizeof config.c_fqdn);
1109 safestrncpy(config.c_fqdn, my_utsname.nodename,
1110 sizeof config.c_fqdn);
1112 if (IsEmptyStr(config.c_humannode))
1113 strcpy(config.c_humannode, "My System");
1114 if (IsEmptyStr(config.c_phonenum))
1115 strcpy(config.c_phonenum, "US 800 555 1212");
1116 if (config.c_initax == 0) {
1117 config.c_initax = 4;
1119 if (IsEmptyStr(config.c_moreprompt))
1120 strcpy(config.c_moreprompt, "<more>");
1121 if (IsEmptyStr(config.c_twitroom))
1122 strcpy(config.c_twitroom, "Trashcan");
1123 if (IsEmptyStr(config.c_baseroom))
1124 strcpy(config.c_baseroom, BASEROOM);
1125 if (IsEmptyStr(config.c_aideroom))
1126 strcpy(config.c_aideroom, "Aide");
1127 if (config.c_port_number == 0) {
1128 config.c_port_number = 504;
1130 if (config.c_sleeping == 0) {
1131 config.c_sleeping = 900;
1133 if (config.c_ctdluid == 0) {
1134 pw = getpwnam("citadel");
1136 config.c_ctdluid = pw->pw_uid;
1138 if (config.c_ctdluid == 0) {
1139 pw = getpwnam("bbs");
1141 config.c_ctdluid = pw->pw_uid;
1143 if (config.c_ctdluid == 0) {
1144 pw = getpwnam("guest");
1146 config.c_ctdluid = pw->pw_uid;
1148 if (config.c_createax == 0) {
1149 config.c_createax = 3;
1152 * Negative values for maxsessions are not allowed.
1154 if (config.c_maxsessions < 0) {
1155 config.c_maxsessions = 0;
1157 /* We need a system default message expiry policy, because this is
1158 * the top level and there's no 'higher' policy to fall back on.
1159 * By default, do not expire messages at all.
1161 if (config.c_ep.expire_mode == 0) {
1162 config.c_ep.expire_mode = EXPIRE_MANUAL;
1163 config.c_ep.expire_value = 0;
1167 * Default port numbers for various services
1169 if (config.c_smtp_port == 0) config.c_smtp_port = 25;
1170 if (config.c_pop3_port == 0) config.c_pop3_port = 110;
1171 if (config.c_imap_port == 0) config.c_imap_port = 143;
1172 if (config.c_msa_port == 0) config.c_msa_port = 587;
1173 if (config.c_smtps_port == 0) config.c_smtps_port = 465;
1174 if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
1175 if (config.c_imaps_port == 0) config.c_imaps_port = 993;
1176 if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
1177 if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
1178 if (config.c_xmpp_c2s_port == 0) config.c_xmpp_c2s_port = 5222;
1179 if (config.c_xmpp_s2s_port == 0) config.c_xmpp_s2s_port = 5269;
1181 /* Go through a series of dialogs prompting for config info */
1182 for (curr = 1; curr <= MAXSETUP; ++curr) {
1186 /***** begin version update section ***** */
1187 /* take care of any updating that is necessary */
1189 old_setup_level = config.c_setup_level;
1191 if (old_setup_level == 0) {
1195 if (old_setup_level < 555) {
1196 important_message("Citadel Setup",
1197 "This Citadel installation is too old "
1201 write_config_to_disk();
1203 old_setup_level = config.c_setup_level;
1205 /* end of version update section */
1208 config.c_setup_level = REV_LEVEL;
1210 /******************************************/
1212 write_config_to_disk();
1214 mkdir(ctdl_info_dir, 0700);
1215 chmod(ctdl_info_dir, 0700);
1216 chown(ctdl_info_dir, config.c_ctdluid, -1);
1218 mkdir(ctdl_bio_dir, 0700);
1219 chmod(ctdl_bio_dir, 0700);
1220 chown(ctdl_bio_dir, config.c_ctdluid, -1);
1222 mkdir(ctdl_usrpic_dir, 0700);
1223 chmod(ctdl_usrpic_dir, 0700);
1224 chown(ctdl_usrpic_dir, config.c_ctdluid, -1);
1226 mkdir(ctdl_message_dir, 0700);
1227 chmod(ctdl_message_dir, 0700);
1228 chown(ctdl_message_dir, config.c_ctdluid, -1);
1230 mkdir(ctdl_hlp_dir, 0700);
1231 chmod(ctdl_hlp_dir, 0700);
1232 chown(ctdl_hlp_dir, config.c_ctdluid, -1);
1234 mkdir(ctdl_image_dir, 0700);
1235 chmod(ctdl_image_dir, 0700);
1236 chown(ctdl_image_dir, config.c_ctdluid, -1);
1238 mkdir(ctdl_bb_dir, 0700);
1239 chmod(ctdl_bb_dir, 0700);
1240 chown(ctdl_bb_dir, config.c_ctdluid, -1);
1242 mkdir(ctdl_file_dir, 0700);
1243 chmod(ctdl_file_dir, 0700);
1244 chown(ctdl_file_dir, config.c_ctdluid, -1);
1246 mkdir(ctdl_netcfg_dir, 0700);
1247 chmod(ctdl_netcfg_dir, 0700);
1248 chown(ctdl_netcfg_dir, config.c_ctdluid, -1);
1250 /* Delete files and directories used by older Citadel versions */
1251 system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
1252 unlink("citadel.log");
1255 if (((setup_type == UI_SILENT) && (getenv("ALTER_ETC_SERVICES")!=NULL)) ||
1256 (setup_type != UI_SILENT))
1257 check_services_entry(); /* Check /etc/services */
1259 delete_inittab_entry(); /* Remove obsolete /etc/inittab entry */
1260 check_xinetd_entry(); /* Check /etc/xinetd.d/telnet */
1262 /* Offer to disable other MTA's on the system. */
1263 disable_other_mta("courier-authdaemon");
1264 disable_other_mta("courier-imap");
1265 disable_other_mta("courier-imap-ssl");
1266 disable_other_mta("courier-pop");
1267 disable_other_mta("courier-pop3");
1268 disable_other_mta("courier-pop3d");
1269 disable_other_mta("cyrmaster");
1270 disable_other_mta("cyrus");
1271 disable_other_mta("dovecot");
1272 disable_other_mta("exim");
1273 disable_other_mta("exim4");
1274 disable_other_mta("imapd");
1275 disable_other_mta("mta");
1276 disable_other_mta("pop3d");
1277 disable_other_mta("popd");
1278 disable_other_mta("postfix");
1279 disable_other_mta("qmail");
1280 disable_other_mta("saslauthd");
1281 disable_other_mta("sendmail");
1282 disable_other_mta("vmailmgrd");
1285 /* Check for the 'db' nss and offer to disable it */
1288 if ((pw = getpwuid(config.c_ctdluid)) == NULL)
1293 progress("Setting file permissions", 0, 3);
1294 chown(ctdl_run_dir, config.c_ctdluid, gid);
1295 progress("Setting file permissions", 1, 3);
1296 chown(file_citadel_config, config.c_ctdluid, gid);
1297 progress("Setting file permissions", 2, 3);
1298 chmod(file_citadel_config, S_IRUSR | S_IWUSR);
1299 progress("Setting file permissions", 3, 3);
1302 * If we're running on SysV, install init scripts.
1304 if (!access("/var/run", W_OK)) {
1306 if (getenv("NO_INIT_SCRIPTS") == NULL) {
1307 install_init_scripts();
1310 if (!access("/etc/init.d/citadel", X_OK)) {
1311 system("/etc/init.d/citadel start");
1315 if (test_server(setup_directory) == 0) {
1316 snprintf (admin_cmd, sizeof(admin_cmd), "%s/sendcommand \"CREU %s|%s\"", ctdl_utilbin_dir, config.c_sysadm, admin_pass);
1318 important_message("Setup finished",
1319 "Setup of the Citadel server is complete.\n"
1320 "If you will be using WebCit, please run its\n"
1321 "setup program now; otherwise, run './citadel'\n"
1325 important_message("Setup failed",
1326 "Setup is finished, but the Citadel server failed to start.\n"
1327 "Go back and check your configuration.\n"
1334 important_message("Setup finished",
1335 "Setup is finished. You may now start the server.");