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[SIZ];
50 char citserver_init_entry[SIZ];
51 int using_web_installer = 0;
54 char *setup_titles[] =
56 "Citadel Home Directory",
57 "System Administrator",
66 /* calculate all our path on a central place */
67 /* where to keep our config */
70 char *setup_text[] = {
72 "Enter the full pathname of the directory in which the Citadel\n"
73 "installation you are creating or updating resides. If you\n"
74 "specify a directory other than the default, you will need to\n"
75 "specify the -h flag to the server when you start it up.\n",
77 "Enter the subdirectory name for an alternate installation of "
78 "Citadel. To do a default installation just leave it blank."
79 "If you specify a directory other than the default, you will need to\n"
80 "specify the -h flag to the server when you start it up.\n"
81 "note that it may not have a leading /",
84 "Enter the name of the system administrator (which is probably\n"
85 "you). When an account is created with this name, it will\n"
86 "automatically be given administrator-level access.\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",
109 struct config config;
113 void cleanup(int exitcode)
125 void title(char *text)
127 if (setup_type == UI_TEXT) {
128 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<%s>\n", text);
134 int yesno(char *question)
137 newtComponent form = NULL;
138 newtComponent yesbutton = NULL;
139 newtComponent nobutton = NULL;
140 int prompt_window_height = 0;
146 switch (setup_type) {
150 printf("%s\nYes/No --> ", question);
151 fgets(buf, sizeof buf, stdin);
152 answer = tolower(buf[0]);
155 else if (answer == 'n')
157 } while ((answer < 0) || (answer > 1));
161 sprintf(buf, "exec %s --yesno '%s' 10 72",
162 getenv("CTDL_DIALOG"),
175 prompt_window_height = num_tokens(question, '\n') + 5;
176 newtCenteredWindow(76, prompt_window_height, "Question");
177 form = newtForm(NULL, NULL, 0);
178 for (i=0; i<num_tokens(question, '\n'); ++i) {
179 extract_token(buf, question, i, '\n', sizeof buf);
180 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
182 yesbutton = newtButton(10, (prompt_window_height - 4), "Yes");
183 nobutton = newtButton(60, (prompt_window_height - 4), "No");
184 newtFormAddComponent(form, yesbutton);
185 newtFormAddComponent(form, nobutton);
186 if (newtRunForm(form) == yesbutton) {
193 newtFormDestroy(form);
203 void important_message(char *title, char *msgtext)
206 newtComponent form = NULL;
211 switch (setup_type) {
214 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");
215 printf(" %s \n\n%s\n\n", title, msgtext);
216 printf("Press return to continue...");
217 fgets(buf, sizeof buf, stdin);
221 sprintf(buf, "exec %s --msgbox '%s' 19 72",
222 getenv("CTDL_DIALOG"),
229 newtCenteredWindow(76, 10, title);
230 form = newtForm(NULL, NULL, 0);
231 for (i=0; i<num_tokens(msgtext, '\n'); ++i) {
232 extract_token(buf, msgtext, i, '\n', sizeof buf);
233 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
235 newtFormAddComponent(form, newtButton(35, 5, "OK"));
238 newtFormDestroy(form);
245 void important_msgnum(int msgnum)
247 important_message("Important Message", setup_text[msgnum]);
250 void display_error(char *error_message)
252 important_message("Error", error_message);
255 void progress(char *text, long int curr, long int cmax)
259 /* These variables are static because progress() gets called
260 * multiple times during the course of whatever operation is
261 * being performed. This makes setup non-threadsafe, but who
264 static newtComponent form = NULL;
265 static newtComponent scale = NULL;
267 static long dots_printed = 0L;
269 static FILE *fp = NULL;
272 switch (setup_type) {
276 printf("%s\n", text);
277 printf("..........................");
278 printf("..........................");
279 printf("..........................\r");
282 } else if (curr == cmax) {
283 printf("\r%79s\n", "");
285 a = (curr * 100) / cmax;
288 while (dots_printed < a) {
298 sprintf(buf, "exec %s --gauge '%s' 7 72 0",
299 getenv("CTDL_DIALOG"),
301 fp = popen(buf, "w");
307 else if (curr == cmax) {
309 fprintf(fp, "100\n");
315 a = (curr * 100) / cmax;
317 fprintf(fp, "%ld\n", a);
326 newtCenteredWindow(76, 8, text);
327 form = newtForm(NULL, NULL, 0);
328 scale = newtScale(1, 3, 74, cmax);
329 newtFormAddComponent(form, scale);
333 if ((curr > 0) && (curr <= cmax)) {
334 newtScaleSet(scale, curr);
338 newtFormDestroy(form);
351 * check_services_entry() -- Make sure "citadel" is in /etc/services
354 void check_services_entry(void)
359 if (getservbyname(SERVICE_NAME, PROTO_NAME) == NULL) {
360 for (i=0; i<=3; ++i) {
361 progress("Adding service entry...", i, 3);
363 sfp = fopen("/etc/services", "a");
365 display_error(strerror(errno));
367 fprintf(sfp, "%s 504/tcp\n",
381 * delete_inittab_entry() -- Remove obsolete /etc/inittab entry for Citadel
384 void delete_inittab_entry(void)
388 char looking_for[256];
390 char outfilename[32];
391 int changes_made = 0;
393 /* Determine the fully qualified path name of citserver */
394 snprintf(looking_for,
404 /* Now tweak /etc/inittab */
405 infp = fopen("/etc/inittab", "r");
407 display_error(strerror(errno));
411 strcpy(outfilename, "/tmp/ctdlsetup.XXXXXX");
412 outfp = fdopen(mkstemp(outfilename), "w+");
414 display_error(strerror(errno));
419 while (fgets(buf, sizeof buf, infp) != NULL) {
420 if (strstr(buf, looking_for) == NULL) {
421 fwrite(buf, strlen(buf), 1, outfp);
432 sprintf(buf, "/bin/mv -f %s /etc/inittab 2>/dev/null", outfilename);
434 system("/sbin/init q 2>/dev/null");
443 * On systems which use xinetd, see if we can offer to install Citadel as
444 * the default telnet target.
446 void check_xinetd_entry(void) {
447 char *filename = "/etc/xinetd.d/telnet";
450 int already_citadel = 0;
452 fp = fopen(filename, "r+");
453 if (fp == NULL) return; /* Not there. Oh well... */
455 while (fgets(buf, sizeof buf, fp) != NULL) {
456 if (strstr(buf, setup_directory) != NULL) already_citadel = 1;
459 if (already_citadel) return; /* Already set up this way. */
461 /* Otherwise, prompt the user to create an entry. */
462 if (getenv("CREATE_XINETD_ENTRY") != NULL) {
463 if (strcasecmp(getenv("CREATE_XINETD_ENTRY"), "yes")) {
468 snprintf(buf, sizeof buf,
469 "Setup can configure the \"xinetd\" service to automatically\n"
470 "connect incoming telnet sessions to Citadel, bypassing the\n"
471 "host system login: prompt. Would you like to do this?\n"
473 if (yesno(buf) == 0) {
478 fp = fopen(filename, "w");
480 "# description: telnet service for Citadel users\n"
485 " socket_type = stream\n"
488 " server = /usr/sbin/in.telnetd\n"
489 " server_args = -h -L %s/citadel\n"
490 " log_on_failure += USERID\n"
500 /* Now try to restart the service */
501 system("/etc/init.d/xinetd restart >/dev/null 2>&1");
507 * Offer to disable other MTA's
509 void disable_other_mta(char *mta) {
514 sprintf(buf, "/bin/ls -l /etc/rc*.d/S*%s 2>/dev/null; "
515 "/bin/ls -l /etc/rc.d/rc*.d/S*%s 2>/dev/null",
517 fp = popen(buf, "r");
518 if (fp == NULL) return;
520 while (fgets(buf, sizeof buf, fp) != NULL) {
524 if (lines == 0) return; /* Nothing to do. */
527 /* Offer to replace other MTA with the vastly superior Citadel :) */
529 if (getenv("ACT_AS_MTA")) {
530 if (strcasecmp(getenv("ACT_AS_MTA"), "yes")) {
535 snprintf(buf, sizeof buf,
536 "You appear to have the \"%s\" email program\n"
537 "running on your system. If you want Citadel mail\n"
538 "connected with %s, you will have to manually integrate\n"
539 "them. It is preferable to disable %s, and use Citadel's\n"
540 "SMTP, POP3, and IMAP services.\n\n"
541 "May we disable %s so that Citadel has access to ports\n"
542 "25, 110, and 143?\n",
545 if (yesno(buf) == 0) {
550 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);
552 sprintf(buf, "/etc/init.d/%s stop >/dev/null 2>&1", mta);
560 * Check to see if our server really works. Returns 0 on success.
562 int test_server(void) {
569 /* Generate a silly little cookie. We're going to write it out
570 * to the server and try to get it back. The cookie does not
571 * have to be secret ... just unique.
573 sprintf(cookie, "--test--%d--", getpid());
575 sprintf(cmd, "%s/sendcommand %s%s ECHO %s 2>&1",
581 (enable_home)?"-h":"",
582 (enable_home)?setup_directory:"",
585 fp = popen(cmd, "r");
586 if (fp == NULL) return(errno);
588 while (fgets(buf, sizeof buf, fp) != NULL) {
590 && (strstr(buf, cookie) != NULL) ) {
602 void strprompt(char *prompt_title, char *prompt_text, char *str)
608 int prompt_window_height = 0;
612 char dialog_result[PATH_MAX];
615 strcpy(setupmsg, "");
617 switch (setup_type) {
620 printf("\n%s\n", prompt_text);
621 printf("This is currently set to:\n%s\n", str);
622 printf("Enter new value or press return to leave unchanged:\n");
623 fgets(buf, sizeof buf, stdin);
624 buf[strlen(buf) - 1] = 0;
625 if (strlen(buf) != 0)
630 CtdlMakeTempFileName(dialog_result, sizeof dialog_result);
631 sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
632 getenv("CTDL_DIALOG"),
637 fp = fopen(dialog_result, "r");
639 fgets(str, sizeof buf, fp);
640 if (str[strlen(str)-1] == 10) {
641 str[strlen(str)-1] = 0;
644 unlink(dialog_result);
651 prompt_window_height = num_tokens(prompt_text, '\n') + 5 ;
652 newtCenteredWindow(76,
653 prompt_window_height,
655 form = newtForm(NULL, NULL, 0);
656 for (i=0; i<num_tokens(prompt_text, '\n'); ++i) {
657 extract_token(buf, prompt_text, i, '\n', sizeof buf);
658 newtFormAddComponent(form, newtLabel(1, 1+i, buf));
660 newtFormAddComponent(form,
662 (prompt_window_height - 2),
665 (const char **) &result,
666 NEWT_FLAG_RETURNEXIT)
672 newtFormDestroy(form);
678 void set_str_val(int msgpos, char *str) {
679 strprompt(setup_titles[msgpos], setup_text[msgpos], str);
684 void set_int_val(int msgpos, int *ip)
687 snprintf(buf, sizeof buf, "%d", (int) *ip);
688 set_str_val(msgpos, buf);
693 void set_char_val(int msgpos, char *ip)
696 snprintf(buf, sizeof buf, "%d", (int) *ip);
697 set_str_val(msgpos, buf);
698 *ip = (char) atoi(buf);
702 void set_long_val(int msgpos, long int *ip)
705 snprintf(buf, sizeof buf, "%ld", *ip);
706 set_str_val(msgpos, buf);
711 void edit_value(int curr)
715 char ctdluidname[SIZ];
720 if (getenv("SYSADMIN_NAME")) {
721 strcpy(config.c_sysadm, getenv("SYSADMIN_NAME"));
724 set_str_val(curr, config.c_sysadm);
730 config.c_ctdluid = 0; /* XXX Windows hack, prob. insecure */
732 i = config.c_ctdluid;
735 set_int_val(curr, &i);
736 config.c_ctdluid = i;
739 strcpy(ctdluidname, pw->pw_name);
740 set_str_val(curr, ctdluidname);
741 pw = getpwnam(ctdluidname);
743 config.c_ctdluid = pw->pw_uid;
745 else if (atoi(ctdluidname) > 0) {
746 config.c_ctdluid = atoi(ctdluidname);
753 set_str_val(curr, config.c_ip_addr);
757 set_int_val(curr, &config.c_port_number);
765 * (re-)write the config data to disk
767 void write_config_to_disk(void)
772 if ((fd = creat(file_citadel_config, S_IRUSR | S_IWUSR)) == -1) {
773 display_error("setup: cannot open citadel.config");
776 fp = fdopen(fd, "wb");
778 display_error("setup: cannot open citadel.config");
781 fwrite((char *) &config, sizeof(struct config), 1, fp);
789 * Figure out what type of user interface we're going to use
791 int discover_ui(void)
794 /* Use "dialog" if we have it */
795 if (getenv("CTDL_DIALOG") != NULL) {
803 newtDrawRootText(0, 0, "Citadel Setup");
814 * Strip "db" entries out of /etc/nsswitch.conf
824 int file_changed = 0;
825 char new_filename[64];
827 fp_read = fopen(NSSCONF, "r");
828 if (fp_read == NULL) {
832 strcpy(new_filename, "/tmp/ctdl_fixnss_XXXXXX");
833 fd_write = mkstemp(new_filename);
839 while (fgets(buf, sizeof buf, fp_read) != NULL) {
842 for (i=0; i<strlen(buf_nc); ++i) {
843 if (buf_nc[i] == '#') {
847 for (i=0; i<strlen(buf_nc); ++i) {
848 if (!strncasecmp(&buf_nc[i], "db", 2)) {
850 if ((isspace(buf_nc[i+2])) || (buf_nc[i+2]==0)) {
853 strcpy(&buf_nc[i], &buf_nc[i+2]);
854 strcpy(&buf[i], &buf[i+2]);
856 strcpy(&buf_nc[i], &buf_nc[i+1]);
857 strcpy(&buf[i], &buf[i+1]);
863 if (write(fd_write, buf, strlen(buf)) != strlen(buf)) {
866 unlink(new_filename);
874 unlink(new_filename);
878 snprintf(question, sizeof question,
880 "/etc/nsswitch.conf is configured to use the 'db' module for\n"
881 "one or more services. This is not necessary on most systems,\n"
882 "and it is known to crash the Citadel server when delivering\n"
883 "mail to the Internet.\n"
885 "Do you want this module to be automatically disabled?\n"
889 if (yesno(question)) {
890 sprintf(buf, "/bin/mv -f %s %s", new_filename, NSSCONF);
893 unlink(new_filename);
903 int main(int argc, char *argv[])
909 int old_setup_level = 0;
911 struct utsname my_utsname;
917 char relhome[PATH_MAX]="";
918 char ctdldir[PATH_MAX]=CTDLDIR;
920 /* set an invalid setup type */
923 /* Check to see if we're running the web installer */
924 if (getenv("CITADEL_INSTALLER") != NULL) {
925 using_web_installer = 1;
928 /* parse command line args */
929 for (a = 0; a < argc; ++a) {
930 if (!strncmp(argv[a], "-u", 2)) {
931 strcpy(aaa, argv[a]);
932 strcpy(aaa, &aaa[2]);
933 setup_type = atoi(aaa);
935 if (!strcmp(argv[a], "-i")) {
938 if (!strcmp(argv[a], "-q")) {
939 setup_type = UI_SILENT;
944 /* If a setup type was not specified, try to determine automatically
945 * the best one to use out of all available types.
947 if (setup_type < 0) {
948 setup_type = discover_ui();
950 if (info_only == 1) {
951 important_message("Citadel Setup", CITADEL);
955 /* Get started in a valid setup directory. */
956 strcpy(setup_directory,
963 if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
964 strcpy(setup_directory, getenv("CITADEL"));
967 set_str_val(0, setup_directory);
970 home=(setup_directory[1]!='\0');
971 relh=home&(setup_directory[1]!='/');
973 safestrncpy(ctdl_home_directory, setup_directory, sizeof ctdl_home_directory);
976 safestrncpy(relhome, ctdl_home_directory, sizeof relhome);
979 calc_dirs_n_files(relh, home, relhome, ctdldir);
981 enable_home=(relh|home);
984 if (chdir(setup_directory) == 0) {
985 strcpy(file_citadel_config, "./citadel.config");
988 important_message("Citadel Setup",
989 "The directory you specified does not exist.");
994 /* Determine our host name, in case we need to use it as a default */
997 /* Make sure Citadel is not running. */
998 if (test_server() == 0) {
999 important_message("Citadel Setup",
1000 "The Citadel service is still running.\n"
1001 "Please stop the service manually and run "
1007 switch (setup_type) {
1011 " *** Citadel setup program ***\n\n");
1017 * What we're going to try to do here is append a whole bunch of
1018 * nulls to the citadel.config file, so we can keep the old config
1019 * values if they exist, but if the file is missing or from an
1020 * earlier version with a shorter config structure, when setup tries
1021 * to read the old config parameters, they'll all come up zero.
1022 * The length of the config file will be set to what it's supposed
1023 * to be when we rewrite it, because we replace the old file with a
1024 * completely new copy.
1026 if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
1027 S_IRUSR | S_IWUSR)) == -1) {
1028 display_error("setup: cannot append citadel.config");
1031 fp = fdopen(a, "ab");
1033 display_error("setup: cannot append citadel.config");
1036 for (a = 0; a < sizeof(struct config); ++a)
1040 /* now we re-open it, and read the old or blank configuration */
1041 fp = fopen(file_citadel_config, "rb");
1043 display_error("setup: cannot open citadel.config");
1046 fread((char *) &config, sizeof(struct config), 1, fp);
1049 /* set some sample/default values in place of blanks... */
1050 if (strlen(config.c_nodename) == 0)
1051 safestrncpy(config.c_nodename, my_utsname.nodename,
1052 sizeof config.c_nodename);
1053 strtok(config.c_nodename, ".");
1054 if (strlen(config.c_fqdn) == 0) {
1055 if ((he = gethostbyname(my_utsname.nodename)) != NULL)
1056 safestrncpy(config.c_fqdn, he->h_name,
1057 sizeof config.c_fqdn);
1059 safestrncpy(config.c_fqdn, my_utsname.nodename,
1060 sizeof config.c_fqdn);
1062 if (strlen(config.c_humannode) == 0)
1063 strcpy(config.c_humannode, "My System");
1064 if (strlen(config.c_phonenum) == 0)
1065 strcpy(config.c_phonenum, "US 800 555 1212");
1066 if (config.c_initax == 0) {
1067 config.c_initax = 4;
1069 if (strlen(config.c_moreprompt) == 0)
1070 strcpy(config.c_moreprompt, "<more>");
1071 if (strlen(config.c_twitroom) == 0)
1072 strcpy(config.c_twitroom, "Trashcan");
1073 if (strlen(config.c_baseroom) == 0)
1074 strcpy(config.c_baseroom, BASEROOM);
1075 if (strlen(config.c_aideroom) == 0)
1076 strcpy(config.c_aideroom, "Aide");
1077 if (config.c_port_number == 0) {
1078 config.c_port_number = 504;
1080 if (config.c_sleeping == 0) {
1081 config.c_sleeping = 900;
1083 if (config.c_ctdluid == 0) {
1084 pw = getpwnam("citadel");
1086 config.c_ctdluid = pw->pw_uid;
1088 if (config.c_ctdluid == 0) {
1089 pw = getpwnam("bbs");
1091 config.c_ctdluid = pw->pw_uid;
1093 if (config.c_ctdluid == 0) {
1094 pw = getpwnam("guest");
1096 config.c_ctdluid = pw->pw_uid;
1098 if (config.c_createax == 0) {
1099 config.c_createax = 3;
1102 * Negative values for maxsessions are not allowed.
1104 if (config.c_maxsessions < 0) {
1105 config.c_maxsessions = 0;
1107 /* We need a system default message expiry policy, because this is
1108 * the top level and there's no 'higher' policy to fall back on.
1109 * By default, do not expire messages at all.
1111 if (config.c_ep.expire_mode == 0) {
1112 config.c_ep.expire_mode = EXPIRE_MANUAL;
1113 config.c_ep.expire_value = 0;
1117 * Default port numbers for various services
1119 if (config.c_smtp_port == 0) config.c_smtp_port = 25;
1120 if (config.c_pop3_port == 0) config.c_pop3_port = 110;
1121 if (config.c_imap_port == 0) config.c_imap_port = 143;
1122 if (config.c_msa_port == 0) config.c_msa_port = 587;
1123 if (config.c_smtps_port == 0) config.c_smtps_port = 465;
1124 if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
1125 if (config.c_imaps_port == 0) config.c_imaps_port = 993;
1126 if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
1127 if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
1129 /* Go through a series of dialogs prompting for config info */
1130 if (setup_type != UI_SILENT) {
1131 for (curr = 1; curr <= MAXSETUP; ++curr) {
1136 /***** begin version update section ***** */
1137 /* take care of any updating that is necessary */
1139 old_setup_level = config.c_setup_level;
1141 if (old_setup_level == 0) {
1145 if (old_setup_level < 555) {
1146 important_message("Citadel Setup",
1147 "This Citadel installation is too old "
1151 write_config_to_disk();
1153 old_setup_level = config.c_setup_level;
1155 /* end of version update section */
1158 config.c_setup_level = REV_LEVEL;
1160 /******************************************/
1162 write_config_to_disk();
1164 mkdir(ctdl_info_dir, 0700);
1165 chmod(ctdl_info_dir, 0700);
1166 chown(ctdl_info_dir, config.c_ctdluid, -1);
1168 mkdir(ctdl_bio_dir, 0700);
1169 chmod(ctdl_bio_dir, 0700);
1170 chown(ctdl_bio_dir, config.c_ctdluid, -1);
1172 mkdir(ctdl_usrpic_dir, 0700);
1173 chmod(ctdl_usrpic_dir, 0700);
1174 chown(ctdl_usrpic_dir, config.c_ctdluid, -1);
1176 mkdir(ctdl_message_dir, 0700);
1177 chmod(ctdl_message_dir, 0700);
1178 chown(ctdl_message_dir, config.c_ctdluid, -1);
1180 mkdir(ctdl_hlp_dir, 0700);
1181 chmod(ctdl_hlp_dir, 0700);
1182 chown(ctdl_hlp_dir, config.c_ctdluid, -1);
1184 mkdir(ctdl_image_dir, 0700);
1185 chmod(ctdl_image_dir, 0700);
1186 chown(ctdl_image_dir, config.c_ctdluid, -1);
1188 mkdir(ctdl_bb_dir, 0700);
1189 chmod(ctdl_bb_dir, 0700);
1190 chown(ctdl_bb_dir, config.c_ctdluid, -1);
1192 mkdir(ctdl_file_dir, 0700);
1193 chmod(ctdl_file_dir, 0700);
1194 chown(ctdl_file_dir, config.c_ctdluid, -1);
1196 mkdir(ctdl_netcfg_dir, 0700);
1197 chmod(ctdl_netcfg_dir, 0700);
1198 chown(ctdl_netcfg_dir, config.c_ctdluid, -1);
1200 /* TODO: where to put this? */
1201 mkdir("netconfigs", 0700);
1202 chmod("netconfigs", 0700);
1203 chown("netconfigs", config.c_ctdluid, -1);
1205 /* Delete files and directories used by older Citadel versions */
1206 system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
1207 unlink("citadel.log");
1210 check_services_entry(); /* Check /etc/services */
1212 delete_inittab_entry(); /* Remove obsolete /etc/inittab entry */
1213 check_xinetd_entry(); /* Check /etc/xinetd.d/telnet */
1215 /* Offer to disable other MTA's on the system. */
1216 disable_other_mta("courier-authdaemon");
1217 disable_other_mta("courier-imap");
1218 disable_other_mta("courier-imap-ssl");
1219 disable_other_mta("courier-pop");
1220 disable_other_mta("courier-pop3");
1221 disable_other_mta("courier-pop3d");
1222 disable_other_mta("cyrmaster");
1223 disable_other_mta("cyrus");
1224 disable_other_mta("dovecot");
1225 disable_other_mta("exim");
1226 disable_other_mta("exim4");
1227 disable_other_mta("hula");
1228 disable_other_mta("imapd");
1229 disable_other_mta("mta");
1230 disable_other_mta("pop3d");
1231 disable_other_mta("popd");
1232 disable_other_mta("postfix");
1233 disable_other_mta("qmail");
1234 disable_other_mta("saslauthd");
1235 disable_other_mta("sendmail");
1236 disable_other_mta("vmailmgrd");
1237 disable_other_mta("zimbra");
1240 /* Check for the 'db' nss and offer to disable it */
1243 if ((pw = getpwuid(config.c_ctdluid)) == NULL)
1248 progress("Setting file permissions", 0, 4);
1249 chown(".", config.c_ctdluid, gid);
1251 progress("Setting file permissions", 1, 4);
1252 chown(file_citadel_config, config.c_ctdluid, gid);
1254 progress("Setting file permissions", 2, 4);
1256 snprintf(aaa, sizeof aaa,
1259 chown(aaa,0,0); /* config.c_ctdluid, gid); chkpwd needs to be root owned*/
1261 progress("Setting file permissions", 3, 4);
1265 progress("Setting file permissions", 3, 4);
1266 chmod(file_citadel_config, S_IRUSR | S_IWUSR);
1268 progress("Setting file permissions", 4, 4);
1270 /* See if we can start the Citadel service. */
1273 if (test_server() == 0) {
1274 important_message("Setup finished",
1275 "Setup of the Citadel server is complete.\n"
1276 "If you will be using WebCit, please run its\n"
1277 "setup program now; otherwise, run './citadel'\n"
1281 important_message("Setup finished",
1282 "Setup is finished. You may now start the server.");