]> code.citadel.org Git - citadel.git/blobdiff - citadel/utils/setup.c
* move config file loading into its own function
[citadel.git] / citadel / utils / setup.c
index e83dd2aa3a0c0d40aa990cf94d0c2c83c7ab212f..cf66e3cad958379aff87e32555e0c428f9522dd4 100644 (file)
@@ -5,6 +5,8 @@
  *
  */
 
+#define SHOW_ME_VAPPEND_PRINTF
+
 #include "ctdl_module.h"
 
 
@@ -58,6 +60,7 @@
 
 
 typedef enum _SetupStep {
+       eCitadelHomeDir = 0,
        eSysAdminName = 1,
        eSysAdminPW = 2,
        eUID = 3,
@@ -67,10 +70,26 @@ typedef enum _SetupStep {
        eLDAP_Host = 7,
        eLDAP_Port = 8,
        eLDAP_Base_DN = 9,
-       eLDAP_Bind_DN =10,
-       eLDAP_Bind_PW =11
+       eLDAP_Bind_DN = 10,
+       eLDAP_Bind_PW = 11,
+       eMaxQuestions = 12
 } eSteupStep;
 
+///"CREATE_XINETD_ENTRY";
+const char *EnvNames [eMaxQuestions] = {
+       "SYSADMIN_NAME",
+       "SYSADMIN_PW",
+       "CITADEL_UID",
+       "IP_ADDR",
+       "CITADEL_PORT",
+       "ENABLE_UNIX_AUTH",
+       "LDAP_HOST",
+       "LDAP_PORT",
+       "LDAP_BASE_DN",
+       "LDAP_BIND_DN",
+       "LDAP_BIND_PW"
+""
+};
 
 int setup_type;
 char setup_directory[PATH_MAX];
@@ -79,21 +98,23 @@ int enable_home = 1;
 char admin_pass[SIZ];
 char admin_cmd[SIZ];
 
-char *setup_titles[] =
+const char *setup_titles[eMaxQuestions];
+
+void SetTitles(void)
 {
-       "Citadel Home Directory",
-       "System Administrator",
-       "Administrator Password",
-       "Citadel User ID",
-       "Server IP address",
-       "Server port number",
-       "Authentication mode",
-       "LDAP host",
-       "LDAP port number",
-       "LDAP base DN",
-       "LDAP bind DN",
-       "LDAP bind password"
-};
+       setup_titles[eCitadelHomeDir] = _("Citadel Home Directory");
+       setup_titles[eSysAdminName] = _("Citadel administrator username:");////
+       setup_titles[eSysAdminPW] = _("Administrator password:");//
+       setup_titles[eUID] = _("Citadel User ID:");
+       setup_titles[eIP_ADDR] = _("Listening address for the Citadel server:");///
+       setup_titles[eCTDL_Port] = _("Server port number:");
+       setup_titles[eAuthType] = _("Authentication method to use:");////
+       setup_titles[eLDAP_Host] = _("LDAP host:");///
+       setup_titles[eLDAP_Port] = _("LDAP port number:");////
+       setup_titles[eLDAP_Base_DN] = _("LDAP base DN:");///
+       setup_titles[eLDAP_Bind_DN] = _("LDAP bind DN:");//
+       setup_titles[eLDAP_Bind_PW] = _("LDAP bind password:");//
+}
 
 /**
  * \brief print the actual stack frame.
@@ -209,7 +230,7 @@ void cleanup(int exitcode)
 
 
 
-void title(char *text)
+void title(const char *text)
 {
        if (setup_type == UI_TEXT) {
                printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<%s>\n", text);
@@ -642,7 +663,7 @@ void check_xinetd_entry(void) {
 /*
  * Offer to disable other MTA's
  */
-void disable_other_mta(char *mta) {
+void disable_other_mta(const char *mta) {
        char buf[SIZ];
        FILE *fp;
        int lines = 0;
@@ -684,8 +705,44 @@ void disable_other_mta(char *mta) {
        rv = system(buf);
 }
 
+const char *other_mtas[] = {
+       "courier-authdaemon",
+       "courier-imap",
+       "courier-imap-ssl",
+       "courier-pop",
+       "courier-pop3",
+       "courier-pop3d",
+       "cyrmaster",
+       "cyrus",
+       "dovecot",
+       "exim",
+       "exim4",
+       "imapd",
+       "mta",
+       "pop3d",
+       "popd",
+       "postfix",
+       "qmail",
+       "saslauthd",
+       "sendmail",
+       "vmailmgrd",
+       ""
+};
 
-
+void disable_other_mtas(void)
+{
+       int i = 0;
+       if ((getenv("ACT_AS_MTA") == NULL) || 
+           (getenv("ACT_AS_MTA") &&
+            strcasecmp(getenv("ACT_AS_MTA"), "yes") == 0)) {
+               /* Offer to disable other MTA's on the system. */
+               while (!IsEmptyStr(other_mtas[i]))
+               {
+                       disable_other_mta(other_mtas[i]);
+                       i++;
+               }
+       }
+}
 
 /* 
  * Check to see if our server really works.  Returns 0 on success.
@@ -730,7 +787,7 @@ int test_server(char *setup_directory, char *relhomestr, int relhome) {
        return(-1);
 }
 
-void strprompt(char *prompt_title, char *prompt_text, char *str)
+void strprompt(const char *prompt_title, char *prompt_text, char *Target, char *DefValue)
 {
        char buf[SIZ] = "";
        char setupmsg[SIZ];
@@ -744,13 +801,13 @@ void strprompt(char *prompt_title, char *prompt_text, char *str)
        case UI_TEXT:
                title(prompt_title);
                printf("\n%s\n", prompt_text);
-               printf("This is currently set to:\n%s\n", str);
+               printf("This is currently set to:\n%s\n", Target);
                printf("Enter new value or press return to leave unchanged:\n");
                if (fgets(buf, sizeof buf, stdin)){
                        buf[strlen(buf) - 1] = 0;
                }
                if (!IsEmptyStr(buf))
-                       strcpy(str, buf);
+                       strcpy(Target, buf);
                break;
 
        case UI_DIALOG:
@@ -758,14 +815,14 @@ void strprompt(char *prompt_title, char *prompt_text, char *str)
                sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
                        getenv("CTDL_DIALOG"),
                        prompt_text,
-                       str,
+                       Target,
                        dialog_result);
                rv = system(buf);
                fp = fopen(dialog_result, "r");
                if (fp != NULL) {
-                       if (fgets(str, sizeof buf, fp)) {
-                               if (str[strlen(str)-1] == 10) {
-                                       str[strlen(str)-1] = 0;
+                       if (fgets(Target, sizeof buf, fp)) {
+                               if (Target[strlen(Target)-1] == 10) {
+                                       Target[strlen(Target)-1] = 0;
                                }
                        }
                        fclose(fp);
@@ -773,42 +830,46 @@ void strprompt(char *prompt_title, char *prompt_text, char *str)
                }
                break;
        case UI_SILENT:
+               strcpy(Target, DefValue);
                break;
        }
 }
 
-void set_bool_val(int msgpos, int *ip) {
+void set_bool_val(int msgpos, int *ip, char *DefValue) {
        title(setup_titles[msgpos]);
        *ip = yesno(setup_text[msgpos], *ip);
 }
 
-void set_str_val(int msgpos, char *str) {
-       strprompt(setup_titles[msgpos], setup_text[msgpos], str);
+void set_str_val(int msgpos, char *Target, char *DefValue) {
+       strprompt(setup_titles[msgpos], 
+                 setup_text[msgpos], 
+                 Target, 
+                 DefValue);
 }
 
-void set_int_val(int msgpos, int *ip)
+void set_int_val(int msgpos, int *ip, char *DefValue)
 {
        char buf[16];
        snprintf(buf, sizeof buf, "%d", (int) *ip);
-       set_str_val(msgpos, buf);
+       set_str_val(msgpos, buf, DefValue);
        *ip = atoi(buf);
 }
 
 
-void set_char_val(int msgpos, char *ip)
+void set_char_val(int msgpos, char *ip, char *DefValue)
 {
        char buf[16];
        snprintf(buf, sizeof buf, "%d", (int) *ip);
-       set_str_val(msgpos, buf);
+       set_str_val(msgpos, buf, DefValue);
        *ip = (char) atoi(buf);
 }
 
 
-void set_long_val(int msgpos, long int *ip)
+void set_long_val(int msgpos, long int *ip, char *DefValue)
 {
        char buf[16];
        snprintf(buf, sizeof buf, "%ld", *ip);
-       set_str_val(msgpos, buf);
+       set_str_val(msgpos, buf, DefValue);
        *ip = atol(buf);
 }
 
@@ -818,38 +879,29 @@ void edit_value(int curr)
        int i;
        struct passwd *pw;
        char ctdluidname[256];
+       char *Value = NULL;
+
+       if (setup_type == UI_SILENT)
+       {
+               Value = getenv(EnvNames[curr]);
+       }
+
 
        switch (curr) {
 
        case eSysAdminName:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("SYSADMIN_NAME")) {
-                               strcpy(config.c_sysadm, getenv("SYSADMIN_NAME"));
-                       }
-               }
-               else {
-                       set_str_val(curr, config.c_sysadm);
-               }
+               set_str_val(curr, config.c_sysadm, Value);
                break;
 
        case eSysAdminPW:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("SYSADMIN_PW")) {
-                               strcpy(admin_pass, getenv("SYSADMIN_PW"));
-                       }
-               }
-               else {
-                       set_str_val(curr, admin_pass);
-               }
+               set_str_val(curr, admin_pass, Value);
                break;
        
        case eUID:
                if (setup_type == UI_SILENT)
                {               
-                       if (getenv("CITADEL_UID")) {
-                               config.c_ctdluid = atoi(getenv("CITADEL_UID"));
+                       if (Value) {
+                               config.c_ctdluid = atoi(Value);
                        }                                       
                }
                else
@@ -860,12 +912,12 @@ void edit_value(int curr)
                        i = config.c_ctdluid;
                        pw = getpwuid(i);
                        if (pw == NULL) {
-                               set_int_val(curr, &i);
+                               set_int_val(curr, &i, Value);
                                config.c_ctdluid = i;
                        }
                        else {
                                strcpy(ctdluidname, pw->pw_name);
-                               set_str_val(curr, ctdluidname);
+                               set_str_val(curr, ctdluidname, Value);
                                pw = getpwnam(ctdluidname);
                                if (pw != NULL) {
                                        config.c_ctdluid = pw->pw_uid;
@@ -879,28 +931,11 @@ void edit_value(int curr)
                break;
 
        case eIP_ADDR:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("IP_ADDR")) {
-                               strcpy(config.c_ip_addr, getenv("IP_ADDR"));
-                       }
-               }
-               else {
-                       set_str_val(curr, config.c_ip_addr);
-               }
+               set_str_val(curr, config.c_ip_addr, Value);
                break;
 
        case eCTDL_Port:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("CITADEL_PORT")) {
-                               config.c_port_number = atoi(getenv("CITADEL_PORT"));
-                       }
-               }
-               else
-               {
-                       set_int_val(curr, &config.c_port_number);
-               }
+               set_int_val(curr, &config.c_port_number, Value);
                break;
 
        case eAuthType:
@@ -908,7 +943,7 @@ void edit_value(int curr)
                {
                        const char *auth;
                        config.c_auth_mode = AUTHMODE_NATIVE;
-                       auth = getenv("ENABLE_UNIX_AUTH");
+                       auth = Value;
                        if (auth != NULL)
                        {
                                if ((strcasecmp(auth, "yes") == 0) ||
@@ -926,80 +961,34 @@ void edit_value(int curr)
                        }
                }
                else {
-                       set_int_val(curr, &config.c_auth_mode);
+                       set_int_val(curr, &config.c_auth_mode, Value);
                }
                break;
 
        case eLDAP_Host:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("LDAP_HOST")) {
-                               strcpy(config.c_ldap_host, getenv("LDAP_HOST"));
-                       }
-               }
-               else
-               {
-                       set_str_val(curr, config.c_ldap_host);
-               }
+               set_str_val(curr, config.c_ldap_host, Value);
                break;
 
        case eLDAP_Port:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("LDAP_PORT")) {
-                               config.c_ldap_port = atoi(getenv("LDAP_PORT"));
-                       }
-               }
-               else
-               {
-                       if (config.c_ldap_port == 0) {
-                               config.c_ldap_port = 389;
-                       }
-                       set_int_val(curr, &config.c_ldap_port);
+               if (config.c_ldap_port == 0) {
+                       config.c_ldap_port = 389;
                }
+               set_int_val(curr, &config.c_ldap_port, Value);
                break;
 
        case eLDAP_Base_DN:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("LDAP_BASE_DN")) {
-                               strcpy(config.c_ldap_base_dn, getenv("LDAP_BASE_DN"));
-                       }
-               }
-               else
-               {
-                       set_str_val(curr, config.c_ldap_base_dn);
-               }
+               set_str_val(curr, config.c_ldap_base_dn, Value);
                break;
 
        case eLDAP_Bind_DN:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("LDAP_BIND_DN")) {
-                               strcpy(config.c_ldap_bind_dn, getenv("LDAP_BIND_DN"));
-                       }
-               }
-               else
-               {
-                       set_str_val(curr, config.c_ldap_bind_dn);
-               }
+               set_str_val(curr, config.c_ldap_bind_dn, Value);
                break;
 
        case eLDAP_Bind_PW:
-               if (setup_type == UI_SILENT)
-               {
-                       if (getenv("LDAP_BIND_PW")) {
-                               strcpy(config.c_ldap_bind_pw, getenv("LDAP_BIND_PW"));
-                       }
-               }
-               else
-               {
-                       set_str_val(curr, config.c_ldap_bind_pw);
-               }
+               set_str_val(curr, config.c_ldap_bind_pw, Value);
                break;
 
        }
-
 }
 
 /*
@@ -1043,6 +1032,13 @@ int discover_ui(void)
 
 
 
+void migrate_old_installs(void)
+{
+       int rv;
+       rv = system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
+       unlink("citadel.log");
+       unlink("weekly");
+}
 
 
 /*
@@ -1130,30 +1126,219 @@ void fixnss(void) {
        unlink(new_filename);
 }
 
+void check_init_script (char *relhome)
+{
+       int rv;
+       FILE *fp;
 
+       /* 
+        * If we're running on SysV, install init scripts.
+        */
+       if (!access("/var/run", W_OK)) {
+
+               if (getenv("NO_INIT_SCRIPTS") == NULL) {
+                       install_init_scripts();
+               }
 
+               if (!access("/etc/init.d/citadel", X_OK)) {
+                       rv = system("/etc/init.d/citadel start");
+                       sleep(3);
+               }
+
+               if (test_server(setup_directory, relhome, enable_home) == 0) {
+                       char buf[SIZ];
+                       int found_it = 0;
 
+                       if (config.c_auth_mode == AUTHMODE_NATIVE) {
+                               snprintf (admin_cmd, sizeof(admin_cmd), "%s/sendcommand \"CREU %s|%s\" 2>&1", 
+                                       ctdl_sbin_dir, config.c_sysadm, admin_pass);
+                               fp = popen(admin_cmd, "r");
+                               if (fp != NULL) {
+                                       while (fgets(buf, sizeof buf, fp) != NULL) 
+                                       {
+                                               if ((atol(buf) == 574) || (atol(buf) == 200))
+                                                       ++found_it;
+                                       }
+                                       pclose(fp);
+                               }
+                       
+                               if (found_it == 0) {
+                                       important_message("Error","Setup failed to create your admin user");
+                               }
+                       }
+
+                       if (setup_type != UI_SILENT)
+                               important_message("Setup finished",
+                                                 "Setup of the Citadel server is complete.\n"
+                                                 "If you will be using WebCit, please run its\n"
+                                                 "setup program now; otherwise, run './citadel'\n"
+                                                 "to log in.\n");
+               }
+               else {
+                       important_message("Setup failed",
+                               "Setup is finished, but the Citadel server failed to start.\n"
+                               "Go back and check your configuration.\n"
+                       );
+               }
+
+       }
+
+       else {
+               important_message("Setup finished",
+                       "Setup is finished.  You may now start the server.");
+       }
+}
+
+void set_default_values(void)
+{
+       struct passwd *pw;
+       struct utsname my_utsname;
+       struct hostent *he;
+
+       /* Determine our host name, in case we need to use it as a default */
+       uname(&my_utsname);
+
+       /* set some sample/default values in place of blanks... */
+       if (IsEmptyStr(config.c_nodename))
+               safestrncpy(config.c_nodename, my_utsname.nodename,
+                           sizeof config.c_nodename);
+       strtok(config.c_nodename, ".");
+       if (IsEmptyStr(config.c_fqdn) ) {
+               if ((he = gethostbyname(my_utsname.nodename)) != NULL) {
+                       safestrncpy(config.c_fqdn, he->h_name, sizeof config.c_fqdn);
+               } else {
+                       safestrncpy(config.c_fqdn, my_utsname.nodename, sizeof config.c_fqdn);
+               }
+       }
+       if (IsEmptyStr(config.c_humannode)) {
+               strcpy(config.c_humannode, "My System");
+       }
+       if (IsEmptyStr(config.c_phonenum)) {
+               strcpy(config.c_phonenum, "US 800 555 1212");
+       }
+       if (config.c_initax == 0) {
+               config.c_initax = 4;
+       }
+       if (IsEmptyStr(config.c_moreprompt)) strcpy(config.c_moreprompt, "<more>");
+       if (IsEmptyStr(config.c_twitroom)) strcpy(config.c_twitroom, "Trashcan");
+       if (IsEmptyStr(config.c_baseroom)) strcpy(config.c_baseroom, BASEROOM);
+       if (IsEmptyStr(config.c_aideroom)) strcpy(config.c_aideroom, "Aide");
+       if (config.c_port_number == 0) {
+               config.c_port_number = 504;
+       }
+       if (config.c_sleeping == 0) {
+               config.c_sleeping = 900;
+       }
+       if (config.c_ctdluid == 0) {
+               pw = getpwnam("citadel");
+               if (pw != NULL) {
+                       config.c_ctdluid = pw->pw_uid;
+               }
+       }
+       if (config.c_ctdluid == 0) {
+               pw = getpwnam("bbs");
+               if (pw != NULL) {
+                       config.c_ctdluid = pw->pw_uid;
+               }
+       }
+       if (config.c_ctdluid == 0) {
+               pw = getpwnam("guest");
+               if (pw != NULL) {
+                       config.c_ctdluid = pw->pw_uid;
+               }
+       }
+       if (config.c_createax == 0) {
+               config.c_createax = 3;
+       }
+       /*
+        * Negative values for maxsessions are not allowed.
+        */
+       if (config.c_maxsessions < 0) {
+               config.c_maxsessions = 0;
+       }
+       /* We need a system default message expiry policy, because this is
+        * the top level and there's no 'higher' policy to fall back on.
+        * By default, do not expire messages at all.
+        */
+       if (config.c_ep.expire_mode == 0) {
+               config.c_ep.expire_mode = EXPIRE_MANUAL;
+               config.c_ep.expire_value = 0;
+       }
+
+       /*
+        * Default port numbers for various services
+        */
+       if (config.c_smtp_port == 0) config.c_smtp_port = 25;
+       if (config.c_pop3_port == 0) config.c_pop3_port = 110;
+       if (config.c_imap_port == 0) config.c_imap_port = 143;
+       if (config.c_msa_port == 0) config.c_msa_port = 587;
+       if (config.c_smtps_port == 0) config.c_smtps_port = 465;
+       if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
+       if (config.c_imaps_port == 0) config.c_imaps_port = 993;
+       if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
+       if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
+       if (config.c_xmpp_c2s_port == 0) config.c_xmpp_c2s_port = 5222;
+       if (config.c_xmpp_s2s_port == 0) config.c_xmpp_s2s_port = 5269;
+}
+
+
+void get_config (void)
+{
+       int a;
+       int rv;
+       FILE *fp;
 
+       /*
+        * What we're going to try to do here is append a whole bunch of
+        * nulls to the citadel.config file, so we can keep the old config
+        * values if they exist, but if the file is missing or from an
+        * earlier version with a shorter config structure, when setup tries
+        * to read the old config parameters, they'll all come up zero.
+        * The length of the config file will be set to what it's supposed
+        * to be when we rewrite it, because we replace the old file with a
+        * completely new copy.
+        */
+       if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
+                     S_IRUSR | S_IWUSR)) == -1) {
+               display_error("setup: cannot append citadel.config");
+               cleanup(errno);
+       }
+       fp = fdopen(a, "ab");
+       if (fp == NULL) {
+               display_error("setup: cannot append citadel.config");
+               cleanup(errno);
+       }
+       for (a = 0; a < sizeof(struct config); ++a) {
+               putc(0, fp);
+       }
+       fclose(fp);
 
+       /* now we re-open it, and read the old or blank configuration */
+       fp = fopen(file_citadel_config, "rb");
+       if (fp == NULL) {
+               display_error("setup: cannot open citadel.config");
+               cleanup(errno);
+       }
+       rv = fread((char *) &config, sizeof(struct config), 1, fp);
+       fclose(fp);
 
+}
 
 int main(int argc, char *argv[])
 {
        int a;
        int curr; 
        char aaa[128];
-       FILE *fp;
        int old_setup_level = 0;
        int info_only = 0;
-       struct utsname my_utsname;
-       struct passwd *pw;
-       struct hostent *he;
-       gid_t gid;
        int relh=0;
        int home=0;
        char relhome[PATH_MAX]="";
        char ctdldir[PATH_MAX]=CTDLDIR;
+       char DefValue[PATH_MAX];
        int rv;
+       struct passwd *pw;
+       gid_t gid;
        
        /* set an invalid setup type */
        setup_type = (-1);
@@ -1203,11 +1388,12 @@ int main(int argc, char *argv[])
 
        /* Get started in a valid setup directory. */
        strcpy(setup_directory, ctdl_run_dir);
+       strcpy(DefValue, ctdl_run_dir);
        if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
                strcpy(setup_directory, getenv("CITADEL"));
        }
        else {
-               set_str_val(0, setup_directory);
+               set_str_val(0, setup_directory, DefValue);
        }
 
        enable_home = ( relh | home );
@@ -1220,8 +1406,6 @@ int main(int argc, char *argv[])
                cleanup(errno);
        }
 
-       /* Determine our host name, in case we need to use it as a default */
-       uname(&my_utsname);
 
        /* Try to stop Citadel if we can */
        if (!access("/etc/init.d/citadel", X_OK)) {
@@ -1247,121 +1431,9 @@ int main(int argc, char *argv[])
 
        }
 
-       /*
-        * What we're going to try to do here is append a whole bunch of
-        * nulls to the citadel.config file, so we can keep the old config
-        * values if they exist, but if the file is missing or from an
-        * earlier version with a shorter config structure, when setup tries
-        * to read the old config parameters, they'll all come up zero.
-        * The length of the config file will be set to what it's supposed
-        * to be when we rewrite it, because we replace the old file with a
-        * completely new copy.
-        */
-       if ((a = open(file_citadel_config, O_WRONLY | O_CREAT | O_APPEND,
-                     S_IRUSR | S_IWUSR)) == -1) {
-               display_error("setup: cannot append citadel.config");
-               cleanup(errno);
-       }
-       fp = fdopen(a, "ab");
-       if (fp == NULL) {
-               display_error("setup: cannot append citadel.config");
-               cleanup(errno);
-       }
-       for (a = 0; a < sizeof(struct config); ++a) {
-               putc(0, fp);
-       }
-       fclose(fp);
+       get_config ();
 
-       /* now we re-open it, and read the old or blank configuration */
-       fp = fopen(file_citadel_config, "rb");
-       if (fp == NULL) {
-               display_error("setup: cannot open citadel.config");
-               cleanup(errno);
-       }
-       rv = fread((char *) &config, sizeof(struct config), 1, fp);
-       fclose(fp);
-
-       /* set some sample/default values in place of blanks... */
-       if (IsEmptyStr(config.c_nodename))
-               safestrncpy(config.c_nodename, my_utsname.nodename,
-                           sizeof config.c_nodename);
-       strtok(config.c_nodename, ".");
-       if (IsEmptyStr(config.c_fqdn) ) {
-               if ((he = gethostbyname(my_utsname.nodename)) != NULL) {
-                       safestrncpy(config.c_fqdn, he->h_name, sizeof config.c_fqdn);
-               } else {
-                       safestrncpy(config.c_fqdn, my_utsname.nodename, sizeof config.c_fqdn);
-               }
-       }
-       if (IsEmptyStr(config.c_humannode)) {
-               strcpy(config.c_humannode, "My System");
-       }
-       if (IsEmptyStr(config.c_phonenum)) {
-               strcpy(config.c_phonenum, "US 800 555 1212");
-       }
-       if (config.c_initax == 0) {
-               config.c_initax = 4;
-       }
-       if (IsEmptyStr(config.c_moreprompt)) strcpy(config.c_moreprompt, "<more>");
-       if (IsEmptyStr(config.c_twitroom)) strcpy(config.c_twitroom, "Trashcan");
-       if (IsEmptyStr(config.c_baseroom)) strcpy(config.c_baseroom, BASEROOM);
-       if (IsEmptyStr(config.c_aideroom)) strcpy(config.c_aideroom, "Aide");
-       if (config.c_port_number == 0) {
-               config.c_port_number = 504;
-       }
-       if (config.c_sleeping == 0) {
-               config.c_sleeping = 900;
-       }
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("citadel");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
-       }
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("bbs");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
-       }
-       if (config.c_ctdluid == 0) {
-               pw = getpwnam("guest");
-               if (pw != NULL) {
-                       config.c_ctdluid = pw->pw_uid;
-               }
-       }
-       if (config.c_createax == 0) {
-               config.c_createax = 3;
-       }
-       /*
-        * Negative values for maxsessions are not allowed.
-        */
-       if (config.c_maxsessions < 0) {
-               config.c_maxsessions = 0;
-       }
-       /* We need a system default message expiry policy, because this is
-        * the top level and there's no 'higher' policy to fall back on.
-        * By default, do not expire messages at all.
-        */
-       if (config.c_ep.expire_mode == 0) {
-               config.c_ep.expire_mode = EXPIRE_MANUAL;
-               config.c_ep.expire_value = 0;
-       }
-
-       /*
-        * Default port numbers for various services
-        */
-       if (config.c_smtp_port == 0) config.c_smtp_port = 25;
-       if (config.c_pop3_port == 0) config.c_pop3_port = 110;
-       if (config.c_imap_port == 0) config.c_imap_port = 143;
-       if (config.c_msa_port == 0) config.c_msa_port = 587;
-       if (config.c_smtps_port == 0) config.c_smtps_port = 465;
-       if (config.c_pop3s_port == 0) config.c_pop3s_port = 995;
-       if (config.c_imaps_port == 0) config.c_imaps_port = 993;
-       if (config.c_pftcpdict_port == 0) config.c_pftcpdict_port = -1;
-       if (config.c_managesieve_port == 0) config.c_managesieve_port = 2020;
-       if (config.c_xmpp_c2s_port == 0) config.c_xmpp_c2s_port = 5222;
-       if (config.c_xmpp_s2s_port == 0) config.c_xmpp_s2s_port = 5269;
+       set_default_values();
 
        /* Go through a series of dialogs prompting for config info */
        for (curr = 1; curr <= MAXSETUP; ++curr) {
@@ -1396,49 +1468,17 @@ NEW_INST:
        config.c_setup_level = REV_LEVEL;
 
 /******************************************/
+       if ((pw = getpwuid(config.c_ctdluid)) == NULL) {
+               gid = getgid();
+       } else {
+               gid = pw->pw_gid;
+       }
 
-       write_config_to_disk();
-
-       rv = mkdir(ctdl_info_dir, 0700);
-       rv = chmod(ctdl_info_dir, 0700);
-       rv = chown(ctdl_info_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_bio_dir, 0700);
-       rv = chmod(ctdl_bio_dir, 0700);
-       rv = chown(ctdl_bio_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_usrpic_dir, 0700);
-       rv = chmod(ctdl_usrpic_dir, 0700);
-       rv = chown(ctdl_usrpic_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_message_dir, 0700);
-       rv = chmod(ctdl_message_dir, 0700);
-       rv = chown(ctdl_message_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_hlp_dir, 0700);
-       rv = chmod(ctdl_hlp_dir, 0700);
-       rv = chown(ctdl_hlp_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_image_dir, 0700);
-       rv = chmod(ctdl_image_dir, 0700);
-       rv = chown(ctdl_image_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_bb_dir, 0700);
-       rv = chmod(ctdl_bb_dir, 0700);
-       rv = chown(ctdl_bb_dir, config.c_ctdluid, -1);
-
-       rv = mkdir(ctdl_file_dir, 0700);
-       rv = chmod(ctdl_file_dir, 0700);
-       rv = chown(ctdl_file_dir, config.c_ctdluid, -1);
+       create_run_directories(config.c_ctdluid, gid);
 
-       rv = mkdir(ctdl_netcfg_dir, 0700);
-       rv = chmod(ctdl_netcfg_dir, 0700);
-       rv = chown(ctdl_netcfg_dir, config.c_ctdluid, -1);
+       write_config_to_disk();
 
-       /* Delete files and directories used by older Citadel versions */
-       rv = system("exec /bin/rm -fr ./rooms ./chatpipes ./expressmsgs ./sessions 2>/dev/null");
-       unlink("citadel.log");
-       unlink("weekly");
+        migrate_old_installs();        /* Delete files and directories used by older Citadel versions */
 
        if (((setup_type == UI_SILENT) && (getenv("ALTER_ETC_SERVICES")!=NULL)) || 
            (setup_type != UI_SILENT))
@@ -1446,108 +1486,18 @@ NEW_INST:
 #ifndef __CYGWIN__
        delete_inittab_entry(); /* Remove obsolete /etc/inittab entry */
        check_xinetd_entry();   /* Check /etc/xinetd.d/telnet */
+       disable_other_mtas();   /* Offer to disable other MTAs */
 
-       if ((getenv("ACT_AS_MTA") == NULL) || 
-           (getenv("ACT_AS_MTA") &&
-            strcasecmp(getenv("ACT_AS_MTA"), "yes") == 0)) {
-               /* Offer to disable other MTA's on the system. */
-               disable_other_mta("courier-authdaemon");
-               disable_other_mta("courier-imap");
-               disable_other_mta("courier-imap-ssl");
-               disable_other_mta("courier-pop");
-               disable_other_mta("courier-pop3");
-               disable_other_mta("courier-pop3d");
-               disable_other_mta("cyrmaster");
-               disable_other_mta("cyrus");
-               disable_other_mta("dovecot");
-               disable_other_mta("exim");
-               disable_other_mta("exim4");
-               disable_other_mta("imapd");
-               disable_other_mta("mta");
-               disable_other_mta("pop3d");
-               disable_other_mta("popd");
-               disable_other_mta("postfix");
-               disable_other_mta("qmail");
-               disable_other_mta("saslauthd");
-               disable_other_mta("sendmail");
-               disable_other_mta("vmailmgrd");
-       }
 #endif
+       fixnss();       /* Check for the 'db' nss and offer to disable it */
 
-       /* Check for the 'db' nss and offer to disable it */
-       fixnss();
-
-       if ((pw = getpwuid(config.c_ctdluid)) == NULL) {
-               gid = getgid();
-       } else {
-               gid = pw->pw_gid;
-       }
-
-       progress("Setting file permissions", 0, 3);
-       rv = chown(ctdl_run_dir, config.c_ctdluid, gid);
        progress("Setting file permissions", 1, 3);
        rv = chown(file_citadel_config, config.c_ctdluid, gid);
        progress("Setting file permissions", 2, 3);
        rv = chmod(file_citadel_config, S_IRUSR | S_IWUSR);
        progress("Setting file permissions", 3, 3);
 
-       /* 
-        * If we're running on SysV, install init scripts.
-        */
-       if (!access("/var/run", W_OK)) {
-
-               if (getenv("NO_INIT_SCRIPTS") == NULL) {
-                       install_init_scripts();
-               }
-
-               if (!access("/etc/init.d/citadel", X_OK)) {
-                       rv = system("/etc/init.d/citadel start");
-                       sleep(3);
-               }
-
-               if (test_server(setup_directory, relhome, enable_home) == 0) {
-                       char buf[SIZ];
-                       int found_it = 0;
-
-                       if (config.c_auth_mode == AUTHMODE_NATIVE) {
-                               snprintf (admin_cmd, sizeof(admin_cmd), "%s/sendcommand \"CREU %s|%s\" 2>&1", 
-                                       ctdl_sbin_dir, config.c_sysadm, admin_pass);
-                               fp = popen(admin_cmd, "r");
-                               if (fp != NULL) {
-                                       while (fgets(buf, sizeof buf, fp) != NULL) 
-                                       {
-                                               if ((atol(buf) == 574) || (atol(buf) == 200))
-                                                       ++found_it;
-                                       }
-                                       pclose(fp);
-                               }
-                       
-                               if (found_it == 0) {
-                                       important_message("Error","Setup failed to create your admin user");
-                               }
-                       }
-
-                       if (setup_type != UI_SILENT)
-                               important_message("Setup finished",
-                                                 "Setup of the Citadel server is complete.\n"
-                                                 "If you will be using WebCit, please run its\n"
-                                                 "setup program now; otherwise, run './citadel'\n"
-                                                 "to log in.\n");
-               }
-               else {
-                       important_message("Setup failed",
-                               "Setup is finished, but the Citadel server failed to start.\n"
-                               "Go back and check your configuration.\n"
-                       );
-               }
-
-       }
-
-       else {
-               important_message("Setup finished",
-                       "Setup is finished.  You may now start the server.");
-       }
-
+       check_init_script (relhome);
        cleanup(0);
        return 0;
 }