]> code.citadel.org Git - citadel.git/blobdiff - citadel/utils/setup.c
Slowly working through the years of cruft that have built up in setup.c
[citadel.git] / citadel / utils / setup.c
index da770f7d15d9a53130d4275d8d54687b49d13d47..326564bcd3e5d516f93fc23ab7ee03b77ea7ea10 100644 (file)
@@ -1,5 +1,15 @@
 /*
  * Citadel setup utility
+ *
+ * Copyright (c) 1987-2012 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #define SHOW_ME_VAPPEND_PRINTF
@@ -95,14 +105,9 @@ char admin_cmd[SIZ];
 const char *setup_titles[eMaxQuestions];
 const char *setup_text[eMaxQuestions];
 
-/* calculate all our path on a central place */
-/* where to keep our config */
-       
-
 
 void SetTitles(void)
 {
-       char *locale;
        int have_run_dir;
 #ifndef HAVE_RUN_DIR
        have_run_dir = 1;
@@ -110,11 +115,13 @@ void SetTitles(void)
        have_run_dir = 0;
 #endif
 
-       locale = setlocale(LC_MESSAGES, getenv("LANG"));
+#ifdef ENABLE_NLS
+       setlocale(LC_MESSAGES, getenv("LANG"));
 
        bindtextdomain("citadel-setup", LOCALEDIR"/locale");
        textdomain("citadel-setup");
        bind_textdomain_codeset("citadel-setup","UTF8");
+#endif
 
        setup_titles[eCitadelHomeDir] = _("Citadel Home Directory");
        if (have_run_dir)
@@ -150,7 +157,7 @@ void SetTitles(void)
        setup_text[eUID] = _(
 "Citadel needs to run under its own user ID.  This would\n"
 "typically be called \"citadel\", but if you are running Citadel\n"
-"as a public BBS, you might also call it \"bbs\" or \"guest\".\n"
+"as a public site, you might also call it \"bbs\" or \"guest\".\n"
 "The server will run under this user ID.  Please specify that\n"
 "user ID here.  You may specify either a user name or a numeric\n"
 "UID.\n");
@@ -159,8 +166,8 @@ void SetTitles(void)
        setup_text[eIP_ADDR] = _(
 "Please specify the IP address which the server should be listening to. "
 "You can name a specific IPv4 or IPv6 address, or you can specify\n"
-"'*' for 'any address', '::' for 'any IPv6 address', or '0.0.0.0'\n"
-"for 'any IPv4 address'. If you leave this blank, Citadel will\n"
+"\"*\" for \"any address\", \"::\" for \"any IPv6 address\", or \"0.0.0.0\"\n"
+"for \"any IPv4 address\". If you leave this blank, Citadel will\n"
 "listen on all addresses. "
 "This can usually be left to the default unless multiple instances of Citadel "
 "are running on the same computer.");
@@ -238,7 +245,7 @@ void SetTitles(void)
 }
 
 /*
- * print the actual stack frame.
+ * Print the stack frame for a backtrace
  */
 void cit_backtrace(void)
 {
@@ -259,9 +266,6 @@ void cit_backtrace(void)
 #endif
 }
 
-struct config config;
-
-
 struct config config;
 int direction;
 
@@ -352,6 +356,8 @@ void important_message(const char *title, const char *msgtext)
                        getenv("CTDL_DIALOG"),
                        msgtext);
                rv = system(buf);
+               if (rv != 0)
+                       fprintf(stderr, _("failed to run the dialog command\n"));
                break;
        case UI_SILENT:
                fprintf(stderr, "%s\n", msgtext);
@@ -371,9 +377,7 @@ void display_error(char *error_message_format, ...)
 
        Msg = NewStrBuf();
        va_start(arg_ptr, error_message_format);
-       StrBufVAppendPrintf(Msg, 
-                           error_message_format, 
-                           arg_ptr);
+       StrBufVAppendPrintf(Msg, error_message_format, arg_ptr);
        va_end(arg_ptr);
 
        important_message(_("Error"), ChrPtr(Msg));
@@ -488,11 +492,7 @@ void delete_inittab_entry(void)
        int rv;
 
        /* Determine the fully qualified path name of citserver */
-       snprintf(looking_for, 
-                sizeof looking_for,
-                "%s/citserver", 
-                ctdl_sbin_dir
-               );
+       snprintf(looking_for, sizeof looking_for, "%s/citserver", ctdl_sbin_dir);
 
        /* Now tweak /etc/inittab */
        infp = fopen("/etc/inittab", "r");
@@ -524,9 +524,19 @@ void delete_inittab_entry(void)
        while (fgets(buf, sizeof buf, infp) != NULL) {
                if (strstr(buf, looking_for) != NULL) {
                        rv = fwrite("#", 1, 1, outfp);
+                       if (rv == -1)
+                       {
+                               display_error("%s %s\n",
+                                             _("failed to modify inittab"), 
+                                             strerror(errno));
+                       }
                        ++changes_made;
                }
                rv = fwrite(buf, strlen(buf), 1, outfp);
+               if (rv == -1)
+               {
+                       display_error("%s %s\n", _("failed to modify inittab"), strerror(errno));
+               }
        }
 
        fclose(infp);
@@ -554,14 +564,17 @@ void install_init_scripts(void)
        char command[SIZ];
        int rv;
 
-       if ((stat("/etc/init.d/", &etcinitd) == -1) && 
-           (errno == ENOENT))
-       {
-               if ((stat("/etc/rc.d/init.d/", &etcinitd) == -1) &&
-                   (errno == ENOENT))
+       if (    (stat("/etc/init.d/", &etcinitd) == -1)
+               && (errno == ENOENT)
+       ) {
+               if (    (stat("/etc/rc.d/init.d/", &etcinitd) == -1)
+                       && (errno == ENOENT)
+               ) {
                        initfile = CTDLDIR"/citadel.init";
-               else
+               }
+               else {
                        initfile = "/etc/rc.d/init.d/citadel";
+               }
        }
 
        fp = fopen(initfile, "r");
@@ -642,11 +655,21 @@ void install_init_scripts(void)
 
        /* Set up the run levels. */
        rv = system("/bin/rm -f /etc/rc?.d/[SK]??citadel 2>/dev/null");
+       if (rv != 0) {
+               display_error(_("failed to remove system V init links\n"));
+       }
+
        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);
        rv = system(command);
+       if (rv != 0) {
+               display_error(_("failed to set system V init links\n"));
+       }
+
        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);
        rv = system(command);
-
+       if (rv != 0) {
+               display_error(_("failed to set system V init links\n"));
+       }
 }
 
 
@@ -682,7 +705,8 @@ void check_xinetd_entry(void) {
                         _("Setup can configure the \"xinetd\" service to automatically\n"
                           "connect incoming telnet sessions to Citadel, bypassing the\n"
                           "host system login: prompt.  Would you like to do this?\n"
-                                ));
+                        )
+               );
                if (yesno(buf, 1) == 0) {
                        return;
                }
@@ -707,6 +731,8 @@ void check_xinetd_entry(void) {
 
        /* Now try to restart the service */
        rv = system("/etc/init.d/xinetd restart >/dev/null 2>&1");
+       if (rv != 0)
+               display_error(_("failed to restart xinetd.\n"));
 }
 
 
@@ -760,8 +786,13 @@ void disable_other_mta(const char *mta) {
 
        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);
        rv = system(buf);
+       if (rv != 0)
+               display_error("%s %s.\n", _("failed to disable other mta"), mta);
+
        sprintf(buf, "/etc/init.d/%s stop >/dev/null 2>&1", mta);
        rv = system(buf);
+       if (rv != 0)
+               display_error(" %s.\n", _("failed to disable other mta"), mta);
 }
 
 const char *other_mtas[] = {
@@ -817,17 +848,21 @@ int test_server(char *relhomestr, int relhome) {
         * to the server and try to get it back.  The cookie does not
         * have to be secret ... just unique.
         */
-       sprintf(cookie, "--test--%d--", getpid());
+       generate_uuid(cookie);
 
-       if (relhome)
+       if (relhome) {
                sprintf(cmd, "%s/sendcommand -h%s ECHO %s 2>&1",
                        ctdl_sbin_dir,
                        relhomestr,
-                       cookie);
-       else
+                       cookie
+               );
+       }
+       else {
                sprintf(cmd, "%s/sendcommand ECHO %s 2>&1",
                        ctdl_sbin_dir,
-                       cookie);
+                       cookie
+               );
+       }
 
        fp = popen(cmd, "r");
        if (fp == NULL) return(errno);
@@ -877,6 +912,10 @@ void strprompt(const char *prompt_title, const char *prompt_text, char *Target,
                        Target,
                        dialog_result);
                rv = system(buf);
+               if (rv != 0) {
+                       fprintf(stderr, "failed to run whiptail or dialog\n");
+               }
+               
                fp = fopen(dialog_result, "r");
                if (fp != NULL) {
                        if (fgets(Target, sizeof buf, fp)) {
@@ -889,7 +928,8 @@ void strprompt(const char *prompt_title, const char *prompt_text, char *Target,
                }
                break;
        case UI_SILENT:
-               strcpy(Target, DefValue);
+               if (*DefValue != '\0')
+                       strcpy(Target, DefValue);
                break;
        }
 }
@@ -905,7 +945,8 @@ void set_str_val(int msgpos, char *Target, char *DefValue)
        strprompt(setup_titles[msgpos], 
                  setup_text[msgpos], 
                  Target, 
-                 DefValue);
+                 DefValue
+       );
 }
 
 void set_int_val(int msgpos, int *ip, char *DefValue)
@@ -946,9 +987,9 @@ void edit_value(int curr)
        {
                Value = getenv(EnvNames[curr]);
        }
-       if (Value == NULL)
+       if (Value == NULL) {
                Value = "";
-
+       }
 
        switch (curr) {
 
@@ -970,7 +1011,7 @@ void edit_value(int curr)
                else
                {
 #ifdef __CYGWIN__
-                       config.c_ctdluid = 0;   /* XXX Windows hack, prob. insecure */
+                       config.c_ctdluid = 0;   /* work-around for Windows */
 #else
                        i = config.c_ctdluid;
                        pw = getpwuid(i);
@@ -1071,8 +1112,13 @@ void write_config_to_disk(void)
        if (fp == NULL) {
                display_error("%s citadel.config [%s][%s]\n", _("setup: cannot open"), file_citadel_config, strerror(errno));
                cleanup(1);
+               return;
        }
        rv = fwrite((char *) &config, sizeof(struct config), 1, fp);
+
+       if (rv == -1)
+               display_error("%s citadel.config [%s][%s]\n", _("setup: cannot write"), file_citadel_config, strerror(errno));
+
        fclose(fp);
 }
 
@@ -1085,7 +1131,7 @@ void write_config_to_disk(void)
 int discover_ui(void)
 {
 
-       /* Use "dialog" if we have it */
+       /* Use "whiptail" or "dialog" if we have it */
        if (getenv("CTDL_DIALOG") != NULL) {
                return UI_DIALOG;
        }
@@ -1095,15 +1141,6 @@ 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");
-}
-
-
 /*
  * Strip "db" entries out of /etc/nsswitch.conf
  */
@@ -1114,7 +1151,6 @@ void fixnss(void) {
        char buf_nc[256];
        char question[512];
        int i;
-       int changed = 0;
        int file_changed = 0;
        char new_filename[64];
        int rv;
@@ -1132,7 +1168,6 @@ void fixnss(void) {
        }
 
        while (fgets(buf, sizeof buf, fp_read) != NULL) {
-               changed = 0;
                strcpy(buf_nc, buf);
                for (i=0; i<strlen(buf_nc); ++i) {
                        if (buf_nc[i] == '#') {
@@ -1143,7 +1178,6 @@ void fixnss(void) {
                        if (!strncasecmp(&buf_nc[i], "db", 2)) {
                                if (i > 0) {
                                        if ((isspace(buf_nc[i+2])) || (buf_nc[i+2]==0)) {
-                                               changed = 1;
                                                file_changed = 1;
                                                strcpy(&buf_nc[i], &buf_nc[i+2]);
                                                strcpy(&buf[i], &buf[i+2]);
@@ -1186,6 +1220,9 @@ void fixnss(void) {
        if (yesno(question, 1)) {
                sprintf(buf, "/bin/mv -f %s %s", new_filename, NSSCONF);
                rv = system(buf);
+               if (rv != 0)
+                       fprintf(stderr, "failed to edit %s.\n", NSSCONF);
+
                chmod(NSSCONF, 0644);
        }
        unlink(new_filename);
@@ -1207,6 +1244,8 @@ void check_init_script (char *relhome)
 
                if (!access("/etc/init.d/citadel", X_OK)) {
                        rv = system("/etc/init.d/citadel start");
+                       if (rv != 0)
+                               fprintf(stderr, "failed to call our initscript.");
                        sleep(3);
                }
 
@@ -1254,6 +1293,47 @@ void check_init_script (char *relhome)
        }
 }
 
+
+
+#define GetDefaultVALINT(CFGNAME, DEFL) GetDefaultValInt(&config.CFGNAME, "CITADEL_"#CFGNAME, DEFL)
+void GetDefaultValInt(int *WhereTo, const char *VarName, int DefVal)
+{
+       const char *ch;
+       if (*WhereTo == 0) *WhereTo = DefVal;
+
+       if ((setup_type == UI_SILENT) &&
+           (ch = getenv(VarName), ch != NULL))
+       {
+               *WhereTo = atoi(ch);
+       }
+}
+#define GetDefaultVALCHAR(CFGNAME, DEFL) GetDefaultValChar(&config.CFGNAME, "CITADEL_"#CFGNAME, DEFL)
+void GetDefaultValChar(char *WhereTo, const char *VarName, char DefVal)
+{
+       const char *ch;
+       if (*WhereTo == 0) *WhereTo = DefVal;
+
+       if ((setup_type == UI_SILENT) &&
+           (ch = getenv(VarName), ch != NULL))
+       {
+               *WhereTo = atoi(ch);
+       }
+}
+#define GetDefaultVALSTR(CFGNAME, DEFL) GetDefaultValStr(&config.CFGNAME[0], sizeof(config.CFGNAME), "CITADEL_"#CFGNAME, DEFL)
+void GetDefaultValStr(char *WhereTo, size_t nMax, const char *VarName, const char *DefVal)
+{
+       const char *ch;
+       if (*WhereTo == '\0') 
+               safestrncpy(WhereTo, DefVal, nMax);
+
+       if ((setup_type == UI_SILENT) &&
+           (ch = getenv(VarName), ch != NULL))
+       {
+               safestrncpy(WhereTo, ch, nMax);
+       }
+}
+
+
 void set_default_values(void)
 {
        struct passwd *pw;
@@ -1264,9 +1344,7 @@ void set_default_values(void)
        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);
+       GetDefaultVALSTR(c_nodename, my_utsname.nodename);
        strtok(config.c_nodename, ".");
        if (IsEmptyStr(config.c_fqdn) ) {
                if ((he = gethostbyname(my_utsname.nodename)) != NULL) {
@@ -1275,25 +1353,19 @@ void set_default_values(void)
                        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;
-       }
+       GetDefaultVALSTR(c_humannode, _("My System"));
+       GetDefaultVALSTR(c_phonenum, _("US 800 555 1212"));
+
+       GetDefaultVALCHAR(c_initax, 4);
+
+       GetDefaultVALSTR(c_moreprompt, "<more>");
+       GetDefaultVALSTR(c_twitroom, "Trashcan");
+       GetDefaultVALSTR(c_baseroom, BASEROOM);
+       GetDefaultVALSTR(c_aideroom, "Aide");
+       GetDefaultVALINT(c_port_number, 504);
+       
+       GetDefaultVALINT(c_sleeping, 900);
+
        if (config.c_ctdluid == 0) {
                pw = getpwnam("citadel");
                if (pw != NULL) {
@@ -1333,17 +1405,17 @@ void set_default_values(void)
        /*
         * 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;
+       GetDefaultVALINT(c_smtp_port, 25);
+       GetDefaultVALINT(c_pop3_port, 110);
+       GetDefaultVALINT(c_imap_port, 143);
+       GetDefaultVALINT(c_msa_port, 587);
+       GetDefaultVALINT(c_smtps_port, 465);
+       GetDefaultVALINT(c_pop3s_port, 995);
+       GetDefaultVALINT(c_imaps_port, 993);
+       GetDefaultVALINT(c_pftcpdict_port, -1);
+       GetDefaultVALINT(c_managesieve_port, 2020);
+       GetDefaultVALINT(c_xmpp_c2s_port, 5222);
+       GetDefaultVALINT(c_xmpp_s2s_port, 5269);
 }
 
 
@@ -1383,8 +1455,11 @@ void get_config (void)
        if (fp == NULL) {
                display_error("%s citadel.config [%s][%s]\n", _("setup: cannot open"), file_citadel_config, strerror(errno));
                cleanup(errno);
+               return;
        }
        rv = fread((char *) &config, sizeof(struct config), 1, fp);
+       if (rv == -1)
+               display_error("%s citadel.config [%s][%s]\n", _("setup: cannot write"), file_citadel_config, strerror(errno));
        fclose(fp);
 
 }
@@ -1465,6 +1540,8 @@ int main(int argc, char *argv[])
        /* Try to stop Citadel if we can */
        if (!access("/etc/init.d/citadel", X_OK)) {
                rv = system("/etc/init.d/citadel stop");
+               if (rv != 0)
+                       fprintf(stderr, _("failed to stop us using the initscript.\n"));
        }
 
        /* Make sure Citadel is not running. */
@@ -1487,8 +1564,7 @@ int main(int argc, char *argv[])
 
        }
 
-       get_config ();
-
+       get_config();
        set_default_values();
 
        /* Go through a series of dialogs prompting for config info */
@@ -1533,8 +1609,6 @@ NEW_INST:
 
        write_config_to_disk();
 
-        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)
@@ -1559,5 +1633,3 @@ NEW_INST:
        cleanup(0);
        return 0;
 }
-
-