4 * Citadel setup utility
14 #include <sys/types.h>
16 #include <sys/utsname.h>
30 #include "citadel_dirs.h"
37 #define MAXSETUP 4 /* How many setup questions to ask */
39 #define UI_TEXT 0 /* Default setup type -- text only */
40 #define UI_DIALOG 2 /* Use the 'dialog' program */
41 #define UI_SILENT 3 /* Silent running, for use in scripts */
42 #define UI_NEWT 4 /* Use the "newt" window library */
44 #define SERVICE_NAME "citadel"
45 #define PROTO_NAME "tcp"
46 #define NSSCONF "/etc/nsswitch.conf"
49 char setup_directory[PATH_MAX];
50 int using_web_installer = 0;
53 char *setup_titles[] =
55 "Citadel Home Directory",
56 "System Administrator",
65 /* calculate all our path on a central place */
66 /* where to keep our config */
69 char *setup_text[] = {
71 "Enter the full pathname of the directory in which the Citadel\n"
72 "installation you are creating or updating resides. If you\n"
73 "specify a directory other than the default, you will need to\n"
74 "specify the -h flag to the server when you start it up.\n",
76 "Enter the subdirectory name for an alternate installation of "
77 "Citadel. To do a default installation just leave it blank."
78 "If you specify a directory other than the default, you will need to\n"
79 "specify the -h flag to the server when you start it up.\n"
80 "note that it may not have a leading /",
83 "Enter the name of the system administrator (which is probably\n"
84 "you). When an account is created with this name, it will\n"
85 "automatically be given administrator-level access.\n",
87 "Citadel needs to run under its own user ID. This would\n"
88 "typically be called \"citadel\", but if you are running Citadel\n"
89 "as a public BBS, you might also call it \"bbs\" or \"guest\".\n"
90 "The server will run under this user ID. Please specify that\n"
91 "user ID here. You may specify either a user name or a numeric\n"
94 "Specify the IP address on which your server will run. If you\n"
95 "leave this blank, or if you specify 0.0.0.0, Citadel will listen\n"
96 "on all addresses. You can usually skip this unless you are\n"
97 "running multiple instances of Citadel on the same computer.\n",
99 "Specify the TCP port number on which your server will run.\n"
100 "Normally, this will be port 504, which is the official port\n"
101 "assigned by the IANA for Citadel servers. You will only need\n"
102 "to specify a different port number if you run multiple instances\n"
103 "of Citadel on the same computer and there is something else\n"
104 "already using port 504.\n",
108 struct config config;
112 void cleanup(int exitcode)
124 void title(char *text)
126 if (setup_type == UI_TEXT) {
127 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<%s>\n", text);
133 int yesno(char *question)
136 newtComponent form = NULL;
137 newtComponent yesbutton = NULL;
138 newtComponent nobutton = NULL;
139 int prompt_window_height = 0;
145 switch (setup_type) {
149 printf("%s\nYes/No --> ", question);
150 fgets(buf, sizeof buf, stdin);
151 answer = tolower(buf[0]);
154 else if (answer == 'n')
156 } while ((answer < 0) || (answer > 1));
160 sprintf(buf, "exec %s --yesno '%s' 10 72",
161 getenv("CTDL_DIALOG"),
174 prompt_window_height = num_tokens(question, '\n') + 5;
175 newtCenteredWindow(76, prompt_window_height, "Question");
176 form = newtForm(NULL, NULL, 0);
177 for (i=0; i<num_tokens(question, '\n'); ++i) {
178 extract_token(buf, question, i, '\n', sizeof buf);
179 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
181 yesbutton = newtButton(10, (prompt_window_height - 4), "Yes");
182 nobutton = newtButton(60, (prompt_window_height - 4), "No");
183 newtFormAddComponent(form, yesbutton);
184 newtFormAddComponent(form, nobutton);
185 if (newtRunForm(form) == yesbutton) {
192 newtFormDestroy(form);
202 void important_message(char *title, char *msgtext)
205 newtComponent form = NULL;
210 switch (setup_type) {
213 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");
214 printf(" %s \n\n%s\n\n", title, msgtext);
215 printf("Press return to continue...");
216 fgets(buf, sizeof buf, stdin);
220 sprintf(buf, "exec %s --msgbox '%s' 19 72",
221 getenv("CTDL_DIALOG"),
228 newtCenteredWindow(76, 10, title);
229 form = newtForm(NULL, NULL, 0);
230 for (i=0; i<num_tokens(msgtext, '\n'); ++i) {
231 extract_token(buf, msgtext, i, '\n', sizeof buf);
232 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
234 newtFormAddComponent(form, newtButton(35, 5, "OK"));
237 newtFormDestroy(form);
244 void important_msgnum(int msgnum)
246 important_message("Important Message", setup_text[msgnum]);
249 void display_error(char *error_message)
251 important_message("Error", error_message);
254 void progress(char *text, long int curr, long int cmax)
258 /* These variables are static because progress() gets called
259 * multiple times during the course of whatever operation is
260 * being performed. This makes setup non-threadsafe, but who
263 static newtComponent form = NULL;
264 static newtComponent scale = NULL;
266 static long dots_printed = 0L;
268 static FILE *fp = NULL;
271 switch (setup_type) {
275 printf("%s\n", text);
276 printf("..........................");
277 printf("..........................");
278 printf("..........................\r");
281 } else if (curr == cmax) {
282 printf("\r%79s\n", "");
284 a = (curr * 100) / cmax;
287 while (dots_printed < a) {
297 sprintf(buf, "exec %s --gauge '%s' 7 72 0",
298 getenv("CTDL_DIALOG"),
300 fp = popen(buf, "w");
306 else if (curr == cmax) {
308 fprintf(fp, "100\n");
314 a = (curr * 100) / cmax;
316 fprintf(fp, "%ld\n", a);
325 newtCenteredWindow(76, 8, text);
326 form = newtForm(NULL, NULL, 0);
327 scale = newtScale(1, 3, 74, cmax);
328 newtFormAddComponent(form, scale);
332 if ((curr > 0) && (curr <= cmax)) {
333 newtScaleSet(scale, curr);
337 newtFormDestroy(form);
350 * check_services_entry() -- Make sure "citadel" is in /etc/services
353 void check_services_entry(void)
358 if (getservbyname(SERVICE_NAME, PROTO_NAME) == NULL) {
359 for (i=0; i<=2; ++i) {
360 progress("Adding service entry...", i, 2);
362 sfp = fopen("/etc/services", "a");
364 display_error(strerror(errno));
366 fprintf(sfp, "%s 504/tcp\n",
380 * delete_inittab_entry() -- Remove obsolete /etc/inittab entry for Citadel
383 void delete_inittab_entry(void)
387 char looking_for[256];
389 char outfilename[32];
390 int changes_made = 0;
392 /* Determine the fully qualified path name of citserver */
393 snprintf(looking_for,
403 /* Now tweak /etc/inittab */
404 infp = fopen("/etc/inittab", "r");
406 display_error(strerror(errno));
410 strcpy(outfilename, "/tmp/ctdlsetup.XXXXXX");
411 outfp = fdopen(mkstemp(outfilename), "w+");
413 display_error(strerror(errno));
418 while (fgets(buf, sizeof buf, infp) != NULL) {
419 if (strstr(buf, looking_for) == NULL) {
420 fwrite(buf, strlen(buf), 1, outfp);
431 sprintf(buf, "/bin/mv -f %s /etc/inittab 2>/dev/null", outfilename);
433 system("/sbin/init q 2>/dev/null");
442 * install_init_scripts() -- Try to configure to start Citadel at boot
445 void install_init_scripts(void)
449 if (yesno("Would you like to automatically start Citadel at boot?\n") == 0) {
453 fp = fopen("/etc/init.d/citadel", "w");
455 display_error("Cannot create /etc/init.d/citadel");
459 fprintf(fp, "#!/bin/sh\n"
461 "CITADEL_DIR=%s\n", setup_directory);
463 "test -x $CITADEL_DIR/ctdlsvc || exit 0\n"
464 "test -d /var/run || exit 0\n"
468 "start) echo -n \"Starting Citadel... \"\n"
469 " if $CITADEL_DIR/ctdlsvc /var/run/citadel.pid "
470 "$CITADEL_DIR/citserver "
478 "stop) echo -n \"Stopping Citadel... \"\n"
479 " if $CITADEL_DIR/sendcommand DOWN >/dev/null 2>&1 ; then\n"
484 " rm -f /var/run/citadel.pid 2>/dev/null\n");
489 "*) echo \"Usage: $0 {start|stop|restart}\"\n"
496 chmod("/etc/init.d/citadel", 0755);
498 /* Set up the run levels. */
499 system("/bin/rm -f /etc/rc?.d/[SK]??citadel 2>/dev/null");
500 system("for x in 2 3 4 5 ; do [ -d /etc/rc$x.d ] && ln -s /etc/init.d/citadel /etc/rc$x.d/S79citadel ; done 2>/dev/null");
501 system("for x in 0 6 S; do [ -d /etc/rc$x.d ] && ln -s /etc/init.d/citadel /etc/rc$x.d/K30citadel ; done 2>/dev/null");
511 * On systems which use xinetd, see if we can offer to install Citadel as
512 * the default telnet target.
514 void check_xinetd_entry(void) {
515 char *filename = "/etc/xinetd.d/telnet";
518 int already_citadel = 0;
520 fp = fopen(filename, "r+");
521 if (fp == NULL) return; /* Not there. Oh well... */
523 while (fgets(buf, sizeof buf, fp) != NULL) {
524 if (strstr(buf, setup_directory) != NULL) already_citadel = 1;
527 if (already_citadel) return; /* Already set up this way. */
529 /* Otherwise, prompt the user to create an entry. */
530 if (getenv("CREATE_XINETD_ENTRY") != NULL) {
531 if (strcasecmp(getenv("CREATE_XINETD_ENTRY"), "yes")) {
536 snprintf(buf, sizeof buf,
537 "Setup can configure the \"xinetd\" service to automatically\n"
538 "connect incoming telnet sessions to Citadel, bypassing the\n"
539 "host system login: prompt. Would you like to do this?\n"
541 if (yesno(buf) == 0) {
546 fp = fopen(filename, "w");
548 "# description: telnet service for Citadel users\n"
553 " socket_type = stream\n"
556 " server = /usr/sbin/in.telnetd\n"
557 " server_args = -h -L %s/citadel\n"
558 " log_on_failure += USERID\n"
568 /* Now try to restart the service */
569 system("/etc/init.d/xinetd restart >/dev/null 2>&1");
575 * Offer to disable other MTA's
577 void disable_other_mta(char *mta) {
582 sprintf(buf, "/bin/ls -l /etc/rc*.d/S*%s 2>/dev/null; "
583 "/bin/ls -l /etc/rc.d/rc*.d/S*%s 2>/dev/null",
585 fp = popen(buf, "r");
586 if (fp == NULL) return;
588 while (fgets(buf, sizeof buf, fp) != NULL) {
592 if (lines == 0) return; /* Nothing to do. */
595 /* Offer to replace other MTA with the vastly superior Citadel :) */
597 if (getenv("ACT_AS_MTA")) {
598 if (strcasecmp(getenv("ACT_AS_MTA"), "yes")) {
603 snprintf(buf, sizeof buf,
604 "You appear to have the \"%s\" email program\n"
605 "running on your system. If you want Citadel mail\n"
606 "connected with %s, you will have to manually integrate\n"
607 "them. It is preferable to disable %s, and use Citadel's\n"
608 "SMTP, POP3, and IMAP services.\n\n"
609 "May we disable %s so that Citadel has access to ports\n"
610 "25, 110, and 143?\n",
613 if (yesno(buf) == 0) {
618 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);
620 sprintf(buf, "/etc/init.d/%s stop >/dev/null 2>&1", mta);
628 * Check to see if our server really works. Returns 0 on success.
630 int test_server(void) {
637 /* Generate a silly little cookie. We're going to write it out
638 * to the server and try to get it back. The cookie does not
639 * have to be secret ... just unique.
641 sprintf(cookie, "--test--%d--", getpid());
643 sprintf(cmd, "%s/sendcommand %s%s ECHO %s 2>&1",
649 (enable_home)?"-h":"",
650 (enable_home)?setup_directory:"",
653 fp = popen(cmd, "r");
654 if (fp == NULL) return(errno);
656 while (fgets(buf, sizeof buf, fp) != NULL) {
658 && (strstr(buf, cookie) != NULL) ) {
670 void strprompt(char *prompt_title, char *prompt_text, char *str)
676 int prompt_window_height = 0;
680 char dialog_result[PATH_MAX];
683 strcpy(setupmsg, "");
685 switch (setup_type) {
688 printf("\n%s\n", prompt_text);
689 printf("This is currently set to:\n%s\n", str);
690 printf("Enter new value or press return to leave unchanged:\n");
691 fgets(buf, sizeof buf, stdin);
692 buf[strlen(buf) - 1] = 0;
693 if (strlen(buf) != 0)
698 CtdlMakeTempFileName(dialog_result, sizeof dialog_result);
699 sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
700 getenv("CTDL_DIALOG"),
705 fp = fopen(dialog_result, "r");
707 fgets(str, sizeof buf, fp);
708 if (str[strlen(str)-1] == 10) {
709 str[strlen(str)-1] = 0;
712 unlink(dialog_result);
719 prompt_window_height = num_tokens(prompt_text, '\n') + 5 ;
720 newtCenteredWindow(76,
721 prompt_window_height,
723 form = newtForm(NULL, NULL, 0);
724 for (i=0; i<num_tokens(prompt_text, '\n'); ++i) {
725 extract_token(buf, prompt_text, i, '\n', sizeof buf);
726 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
728 newtFormAddComponent(form,
730 (prompt_window_height - 2),
733 (const char **) &result,
734 NEWT_FLAG_RETURNEXIT)
740 newtFormDestroy(form);
746 void set_str_val(int msgpos, char *str) {
747 strprompt(setup_titles[msgpos], setup_text[msgpos], str);
752 void set_int_val(int msgpos, int *ip)
755 snprintf(buf, sizeof buf, "%d", (int) *ip);
756 set_str_val(msgpos, buf);
761 void set_char_val(int msgpos, char *ip)
764 snprintf(buf, sizeof buf, "%d", (int) *ip);
765 set_str_val(msgpos, buf);
766 *ip = (char) atoi(buf);
770 void set_long_val(int msgpos, long int *ip)
773 snprintf(buf, sizeof buf, "%ld", *ip);
774 set_str_val(msgpos, buf);
779 void edit_value(int curr)
783 char ctdluidname[SIZ];
788 if (getenv("SYSADMIN_NAME")) {
789 strcpy(config.c_sysadm, getenv("SYSADMIN_NAME"));
792 set_str_val(curr, config.c_sysadm);
798 config.c_ctdluid = 0; /* XXX Windows hack, prob. insecure */
800 i = config.c_ctdluid;
803 set_int_val(curr, &i);
804 config.c_ctdluid = i;
807 strcpy(ctdluidname, pw->pw_name);
808 set_str_val(curr, ctdluidname);
809 pw = getpwnam(ctdluidname);
811 config.c_ctdluid = pw->pw_uid;
813 else if (atoi(ctdluidname) > 0) {
814 config.c_ctdluid = atoi(ctdluidname);
821 set_str_val(curr, config.c_ip_addr);
825 set_int_val(curr, &config.c_port_number);
833 * (re-)write the config data to disk
835 void write_config_to_disk(void)
840 if ((fd = creat(file_citadel_config, S_IRUSR | S_IWUSR)) == -1) {
841 display_error("setup: cannot open citadel.config");
844 fp = fdopen(fd, "wb");
846 display_error("setup: cannot open citadel.config");
849 fwrite((char *) &config, sizeof(struct config), 1, fp);
857 * Figure out what type of user interface we're going to use
859 int discover_ui(void)
862 /* Use "dialog" if we have it */
863 if (getenv("CTDL_DIALOG") != NULL) {
871 newtDrawRootText(0, 0, "Citadel Setup");
882 * Strip "db" entries out of /etc/nsswitch.conf
892 int file_changed = 0;
893 char new_filename[64];
895 fp_read = fopen(NSSCONF, "r");
896 if (fp_read == NULL) {
900 strcpy(new_filename, "/tmp/ctdl_fixnss_XXXXXX");
901 fd_write = mkstemp(new_filename);
907 while (fgets(buf, sizeof buf, fp_read) != NULL) {
910 for (i=0; i<strlen(buf_nc); ++i) {
911 if (buf_nc[i] == '#') {
915 for (i=0; i<strlen(buf_nc); ++i) {
916 if (!strncasecmp(&buf_nc[i], "db", 2)) {
918 if ((isspace(buf_nc[i+2])) || (buf_nc[i+2]==0)) {
921 strcpy(&buf_nc[i], &buf_nc[i+2]);
922 strcpy(&buf[i], &buf[i+2]);
924 strcpy(&buf_nc[i], &buf_nc[i+1]);
925 strcpy(&buf[i], &buf[i+1]);
931 if (write(fd_write, buf, strlen(buf)) != strlen(buf)) {
934 unlink(new_filename);
942 unlink(new_filename);
946 snprintf(question, sizeof question,
948 "/etc/nsswitch.conf is configured to use the 'db' module for\n"
949 "one or more services. This is not necessary on most systems,\n"
950 "and it is known to crash the Citadel server when delivering\n"
951 "mail to the Internet.\n"
953 "Do you want this module to be automatically disabled?\n"
957 if (yesno(question)) {
958 sprintf(buf, "/bin/mv -f %s %s", new_filename, NSSCONF);
961 unlink(new_filename);
971 int main(int argc, char *argv[])
977 int old_setup_level = 0;
979 struct utsname my_utsname;
985 char relhome[PATH_MAX]="";
986 char ctdldir[PATH_MAX]=CTDLDIR;
988 /* set an invalid setup type */
991 /* Check to see if we're running the web installer */
992 if (getenv("CITADEL_INSTALLER") != NULL) {
993 using_web_installer = 1;
996 /* parse command line args */
997 for (a = 0; a < argc; ++a) {
998 if (!strncmp(argv[a], "-u", 2)) {
999 strcpy(aaa, argv[a]);
1000 strcpy(aaa, &aaa[2]);
1001 setup_type = atoi(aaa);
1003 if (!strcmp(argv[a], "-i")) {
1006 if (!strcmp(argv[a], "-q")) {
1007 setup_type = UI_SILENT;
1012 /* If a setup type was not specified, try to determine automatically
1013 * the best one to use out of all available types.
1015 if (setup_type < 0) {
1016 setup_type = discover_ui();
1018 if (info_only == 1) {
1019 important_message("Citadel Setup", CITADEL);
1023 /* Get started in a valid setup directory. */
1024 strcpy(setup_directory,
1031 if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
1032 strcpy(setup_directory, getenv("CITADEL"));
1035 set_str_val(0, setup_directory);
1038 home=(setup_directory[1]!='\0');
1039 relh=home&(setup_directory[1]!='/');
1041 safestrncpy(ctdl_home_directory, setup_directory, sizeof ctdl_home_directory);
1044 safestrncpy(relhome, ctdl_home_directory, sizeof relhome);
1047 calc_dirs_n_files(relh, home, relhome, ctdldir);
1049 enable_home=(relh|home);
1052 if (chdir(setup_directory) == 0) {
1053 strcpy(file_citadel_config, "./citadel.config");
1056 important_message("Citadel Setup",
1057 "The directory you specified does not exist.");
1062 /* Determine our host name, in case we need to use it as a default */
1065 /* Try to stop Citadel if we can */
1066 if (!access("/etc/init.d/citadel", X_OK)) {
1067 for (a=0; a<=2; ++a) {
1068 progress("Stopping the Citadel service...", a, 2);
1069 if (a == 0) system("/etc/init.d/citadel stop >/dev/null 2>&1");
1074 /* Make sure Citadel is not running. */
1075 if (test_server() == 0) {
1076 important_message("Citadel Setup",
1077 "The Citadel service is still running.\n"
1078 "Please stop the service manually and run "
1084 switch (setup_type) {
1088 " *** Citadel setup program ***\n\n");
1094 * What we're going to try to do here is append a whole bunch of
1095 * nulls to the citadel.config file, so we can keep the old config
1096 * values if they exist, but if the file is missing or from an
1097 * earlier version with a shorter config structure, when setup tries
1098 * to read the old config parameters, they'll all come up zero.
1099 * The length of the config file will be set to what it's supposed
1100 * to be when we rewrite it, because we replace the old file with a
1101 * completely new copy.
1103 if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
1104 S_IRUSR | S_IWUSR)) == -1) {
1105 display_error("setup: cannot append citadel.config");
1108 fp = fdopen(a, "ab");
1110 display_error("setup: cannot append citadel.config");
1113 for (a = 0; a < sizeof(struct config); ++a)
1117 /* now we re-open it, and read the old or blank configuration */
1118 fp = fopen(file_citadel_config, "rb");
1120 display_error("setup: cannot open citadel.config");
1123 fread((char *) &config, sizeof(struct config), 1, fp);
1126 /* set some sample/default values in place of blanks... */
1127 if (strlen(config.c_nodename) == 0)
1128 safestrncpy(config.c_nodename, my_utsname.nodename,
1129 sizeof config.c_nodename);
1130 strtok(config.c_nodename, ".");
1131 if (strlen(config.c_fqdn) == 0) {
1132 if ((he = gethostbyname(my_utsname.nodename)) != NULL)
1133 safestrncpy(config.c_fqdn, he->h_name,
1134 sizeof config.c_fqdn);
1136 safestrncpy(config.c_fqdn, my_utsname.nodename,
1137 sizeof config.c_fqdn);
1139 if (strlen(config.c_humannode) == 0)
1140 strcpy(config.c_humannode, "My System");
1141 if (strlen(config.c_phonenum) == 0)
1142 strcpy(config.c_phonenum, "US 800 555 1212");
1143 if (config.c_initax == 0) {
1144 config.c_initax = 4;
1146 if (strlen(config.c_moreprompt) == 0)
1147 strcpy(config.c_moreprompt, "<more>");
1148 if (strlen(config.c_twitroom) == 0)
1149 strcpy(config.c_twitroom, "Trashcan");
1150 if (strlen(config.c_baseroom) == 0)
1151 strcpy(config.c_baseroom, BASEROOM);
1152 if (strlen(config.c_aideroom) == 0)
1153 strcpy(config.c_aideroom, "Aide");
1154 if (config.c_port_number == 0) {
1155 config.c_port_number = 504;
1157 if (config.c_sleeping == 0) {
1158 config.c_sleeping = 900;
1160 if (config.c_ctdluid == 0) {
1161 pw = getpwnam("citadel");
1163 config.c_ctdluid = pw->pw_uid;
1165 if (config.c_ctdluid == 0) {
1166 pw = getpwnam("bbs");
1168 config.c_ctdluid = pw->pw_uid;
1170 if (config.c_ctdluid == 0) {
1171 pw = getpwnam("guest");
1173 config.c_ctdluid = pw->pw_uid;
1175 if (config.c_createax == 0) {
1176 config.c_createax = 3;
1179 * Negative values for maxsessions are not allowed.
1181 if (config.c_maxsessions < 0) {
1182 config.c_maxsessions = 0;
1184 /* We need a system default message expiry policy, because this is
1185 * the top level and there's no 'higher' policy to fall back on.
1186 * By default, do not expire messages at all.
1188 if (config.c_ep.expire_mode == 0) {
1189 config.c_ep.expire_mode = EXPIRE_MANUAL;
1190 config.c_ep.expire_value = 0;
1194 * Default port numbers for various services
1196 if (config.c_smtp_port == 0) config.c_smtp_port = 25;
1197 if (config.c_pop3_port == 0) config.c_pop3_port = 110;
1198 if (config.c_imap_port == 0) config.c_imap_port = 143;
1199 if (config.c_msa_port == 0) config.c_msa_port = 587;
1200 if (config.c_smtps_port == 0) config.c_smtps_port = 465;
1201 if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
1202 if (config.c_imaps_port == 0) config.c_imaps_port = 993;
1203 if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
1204 if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
1206 /* Go through a series of dialogs prompting for config info */
1207 if (setup_type != UI_SILENT) {
1208 for (curr = 1; curr <= MAXSETUP; ++curr) {
1213 /***** begin version update section ***** */
1214 /* take care of any updating that is necessary */
1216 old_setup_level = config.c_setup_level;
1218 if (old_setup_level == 0) {
1222 if (old_setup_level < 555) {
1223 important_message("Citadel Setup",
1224 "This Citadel installation is too old "
1228 write_config_to_disk();
1230 old_setup_level = config.c_setup_level;
1232 /* end of version update section */
1235 config.c_setup_level = REV_LEVEL;
1237 /******************************************/
1239 write_config_to_disk();
1241 mkdir(ctdl_info_dir, 0700);
1242 chmod(ctdl_info_dir, 0700);
1243 chown(ctdl_info_dir, config.c_ctdluid, -1);
1245 mkdir(ctdl_bio_dir, 0700);
1246 chmod(ctdl_bio_dir, 0700);
1247 chown(ctdl_bio_dir, config.c_ctdluid, -1);
1249 mkdir(ctdl_usrpic_dir, 0700);
1250 chmod(ctdl_usrpic_dir, 0700);
1251 chown(ctdl_usrpic_dir, config.c_ctdluid, -1);
1253 mkdir(ctdl_message_dir, 0700);
1254 chmod(ctdl_message_dir, 0700);
1255 chown(ctdl_message_dir, config.c_ctdluid, -1);
1257 mkdir(ctdl_hlp_dir, 0700);
1258 chmod(ctdl_hlp_dir, 0700);
1259 chown(ctdl_hlp_dir, config.c_ctdluid, -1);
1261 mkdir(ctdl_image_dir, 0700);
1262 chmod(ctdl_image_dir, 0700);
1263 chown(ctdl_image_dir, config.c_ctdluid, -1);
1265 mkdir(ctdl_bb_dir, 0700);
1266 chmod(ctdl_bb_dir, 0700);
1267 chown(ctdl_bb_dir, config.c_ctdluid, -1);
1269 mkdir(ctdl_file_dir, 0700);
1270 chmod(ctdl_file_dir, 0700);
1271 chown(ctdl_file_dir, config.c_ctdluid, -1);
1273 mkdir(ctdl_netcfg_dir, 0700);
1274 chmod(ctdl_netcfg_dir, 0700);
1275 chown(ctdl_netcfg_dir, config.c_ctdluid, -1);
1277 /* TODO: where to put this? */
1278 mkdir("netconfigs", 0700);
1279 chmod("netconfigs", 0700);
1280 chown("netconfigs", config.c_ctdluid, -1);
1282 /* Delete files and directories used by older Citadel versions */
1283 system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
1284 unlink("citadel.log");
1287 check_services_entry(); /* Check /etc/services */
1289 delete_inittab_entry(); /* Remove obsolete /etc/inittab entry */
1290 check_xinetd_entry(); /* Check /etc/xinetd.d/telnet */
1292 /* Offer to disable other MTA's on the system. */
1293 disable_other_mta("courier-authdaemon");
1294 disable_other_mta("courier-imap");
1295 disable_other_mta("courier-imap-ssl");
1296 disable_other_mta("courier-pop");
1297 disable_other_mta("courier-pop3");
1298 disable_other_mta("courier-pop3d");
1299 disable_other_mta("cyrmaster");
1300 disable_other_mta("cyrus");
1301 disable_other_mta("dovecot");
1302 disable_other_mta("exim");
1303 disable_other_mta("exim4");
1304 disable_other_mta("hula");
1305 disable_other_mta("imapd");
1306 disable_other_mta("mta");
1307 disable_other_mta("pop3d");
1308 disable_other_mta("popd");
1309 disable_other_mta("postfix");
1310 disable_other_mta("qmail");
1311 disable_other_mta("saslauthd");
1312 disable_other_mta("sendmail");
1313 disable_other_mta("vmailmgrd");
1314 disable_other_mta("zimbra");
1317 /* Check for the 'db' nss and offer to disable it */
1320 if ((pw = getpwuid(config.c_ctdluid)) == NULL)
1325 progress("Setting file permissions", 0, 4);
1326 chown(".", config.c_ctdluid, gid);
1328 progress("Setting file permissions", 1, 4);
1329 chown(file_citadel_config, config.c_ctdluid, gid);
1331 progress("Setting file permissions", 2, 4);
1333 snprintf(aaa, sizeof aaa,
1336 chown(aaa,0,0); /* config.c_ctdluid, gid); chkpwd needs to be root owned*/
1338 progress("Setting file permissions", 3, 4);
1342 progress("Setting file permissions", 3, 4);
1343 chmod(file_citadel_config, S_IRUSR | S_IWUSR);
1345 progress("Setting file permissions", 4, 4);
1348 * If we're running on SysV, install init scripts.
1350 if (!access("/var/run", W_OK)) {
1352 if (getenv("NO_INIT_SCRIPTS") == NULL) {
1353 install_init_scripts();
1356 if (!access("/etc/init.d/citadel", X_OK)) {
1357 for (a=0; a<=2; ++a) {
1358 progress("Starting the Citadel service...", a, 2);
1359 if (a == 0) system("/etc/init.d/citadel start >/dev/null 2>&1");
1364 if (test_server() == 0) {
1365 important_message("Setup finished",
1366 "Setup of the Citadel server is complete.\n"
1367 "If you will be using WebCit, please run its\n"
1368 "setup program now; otherwise, run './citadel'\n"
1372 important_message("Setup failed",
1373 "Setup is finished, but the Citadel server failed to start.\n"
1374 "Go back and check your configuration.\n"
1381 important_message("Setup finished",
1382 "Setup is finished. You may now start the server.");