Module Name: src Committed By: sborrill Date: Fri May 18 02:28:52 UTC 2012
Added Files: src/distrib/utils/sysinst [netbsd-6]: checkrc.c configmenu.c Log Message: Add new files from ticket #247: Pull up the following revisions(s) (requested by riz in ticket #247): distrib/utils/sysinst/Makefile.inc: revision 1.59 via patch distrib/utils/sysinst/checkrc.c: revision 1.1-1.2 via patch distrib/utils/sysinst/configmenu.c: revision 1.1-1.5 via patch distrib/utils/sysinst/defs.h: revision 1.162 via patch distrib/utils/sysinst/install.c: revision 1.46 via patch distrib/utils/sysinst/main.c: revision 1.64 via patch distrib/utils/sysinst/mbr.c: revision 1.90 via patch distrib/utils/sysinst/menus.mi: revision 1.45-1.46 via patch distrib/utils/sysinst/msg.mbr.de: revision 1.12 via patch distrib/utils/sysinst/msg.mbr.en: revision 1.16-1.17 via patch distrib/utils/sysinst/msg.mbr.es: revision 1.7 via patch distrib/utils/sysinst/msg.mbr.fr: revision 1.18-1.19 via patch distrib/utils/sysinst/msg.mbr.pl: revision 1.15-1.16 via patch distrib/utils/sysinst/msg.mi.de: revision 1.62-1.67 via patch distrib/utils/sysinst/msg.mi.en: revision 1.170-1.172 via patch distrib/utils/sysinst/msg.mi.es: revision 1.40-1.43 via patch distrib/utils/sysinst/msg.mi.fr: revision 1.120-1.126 via patch distrib/utils/sysinst/msg.mi.pl: revision 1.79-1.83 via patch distrib/utils/sysinst/net.c: revision 1.131-1.132 via patch distrib/utils/sysinst/run.c: revision 1.70 via patch distrib/utils/sysinst/target.c: revision 1.55 via patch distrib/utils/sysinst/util.c: revision 1.174-1.178 via patch distrib/utils/sysinst/arch/evbarm/msg.md.de: revision 1.10-1.11 via patch distrib/utils/sysinst/arch/evbmips/md.c: revision 1.10 via patch distrib/utils/sysinst/arch/hp300/msg.md.de: revision 1.6-1.7 via patch distrib/utils/sysinst/arch/hp300/msg.md.en: revision 1.9 via patch distrib/utils/sysinst/arch/hp300/msg.md.es: revision 1.5 via patch distrib/utils/sysinst/arch/hp300/msg.md.fr: revision 1.8 via patch distrib/utils/sysinst/arch/hp300/msg.md.pl: revision 1.8 via patch distrib/utils/sysinst/arch/i386/msg.md.en: revision 1.62-1.63 via patch distrib/utils/sysinst/arch/i386/msg.md.es: revision 1.14 via patch distrib/utils/sysinst/arch/i386/msg.md.de: revision 1.23 Sync sysinst with -current as of 2011-05-17 Add new post-install configuration menu for sysinst, and apply numerous bug fixes. To generate a diff of this commit: cvs rdiff -u -r0 -r1.2.2.2 src/distrib/utils/sysinst/checkrc.c cvs rdiff -u -r0 -r1.5.2.2 src/distrib/utils/sysinst/configmenu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/distrib/utils/sysinst/checkrc.c diff -u /dev/null src/distrib/utils/sysinst/checkrc.c:1.2.2.2 --- /dev/null Fri May 18 02:28:52 2012 +++ src/distrib/utils/sysinst/checkrc.c Fri May 18 02:28:52 2012 @@ -0,0 +1,117 @@ +/* $NetBSD: checkrc.c,v 1.2.2.2 2012/05/18 02:28:52 sborrill Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jeffrey C. Rizzo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* checkrc.c -- Create a script on the target to check the state of + * its rc.conf variables. */ + +#include <curses.h> +#include <err.h> +#include <stdio.h> +#include "defs.h" +#include "msg_defs.h" +#include "menu_defs.h" + +#define RC_CHECK_SCRIPT "/tmp/checkrc.sh" + +static int create_script(const char *, int); +static int check(const char *, int); + +char *rcconf = NULL; + +enum { + CHECK_CONF, + CHECK_DEFAULT +}; + +static int +create_script(const char *varname, int filetocheck) +{ + FILE *fp; + + if ((fp = fopen(target_expand(RC_CHECK_SCRIPT), "w")) == NULL) { + if (logfp) + fprintf(logfp,"Could not open %s for writing", + target_expand(RC_CHECK_SCRIPT)); + warn("Could not open %s for writing", + target_expand(RC_CHECK_SCRIPT)); + return 1; + } + + if (filetocheck == CHECK_DEFAULT) + fprintf(fp, "#!/bin/sh\n. /etc/defaults/rc.conf\n" + ". /etc/rc.subr\n"); + else + fprintf(fp, "#!/bin/sh\n. /etc/rc.conf\n. /etc/rc.subr\n"); + fprintf(fp, "if checkyesno %s\nthen\necho YES\nelse\necho NO\nfi\n", + varname); + + fclose(fp); + return 0; +} + +static int +check(const char *varname, int filetocheck) +{ + char *buf; + + create_script(varname, filetocheck); + + if (target_already_root()) + collect(T_OUTPUT, &buf, "/bin/sh %s 2>&1", RC_CHECK_SCRIPT); + else + collect(T_OUTPUT, &buf, "chroot %s /bin/sh %s 2>&1", + target_prefix(), RC_CHECK_SCRIPT); + + + unlink(target_expand(RC_CHECK_SCRIPT)); + + if (logfp) { + fprintf(logfp,"var %s is %s\n", varname, buf); + fflush(logfp); + } + + if (strncmp(buf, "YES", strlen("YES")) == 0) + return 1; + else + return 0; +} + +int +check_rcvar(const char *varname) +{ + return check(varname, CHECK_CONF); +} + +int +check_rcdefault(const char *varname) +{ + return check(varname, CHECK_DEFAULT); +} Index: src/distrib/utils/sysinst/configmenu.c diff -u /dev/null src/distrib/utils/sysinst/configmenu.c:1.5.2.2 --- /dev/null Fri May 18 02:28:52 2012 +++ src/distrib/utils/sysinst/configmenu.c Fri May 18 02:28:52 2012 @@ -0,0 +1,433 @@ +/* $NetBSD: configmenu.c,v 1.5.2.2 2012/05/18 02:28:52 sborrill Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jeffrey C. Rizzo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* configmenu.c -- post-installation system configuration menu. */ + +#include <stdio.h> +#include <curses.h> +#include <unistd.h> +#include "defs.h" +#include "msg_defs.h" +#include "menu_defs.h" + + +static int set_network(struct menudesc*, void *); +static int set_timezone_menu(struct menudesc *, void *); +static int set_root_shell(struct menudesc *, void *); +static int change_root_password(struct menudesc *, void *); +static int set_binpkg(struct menudesc *, void *); +static int set_pkgsrc(struct menudesc *, void *); +static void config_list_init(void); +static void get_rootsh(void); +static int toggle_rcvar(struct menudesc *, void *); +static void configmenu_hdr(struct menudesc *, void *); +static int check_root_password(void); + +char pkgpath[STRSIZE]; +char pkgsrcpath[STRSIZE]; + +extern const char *tz_default; + +enum { + CONFIGOPT_NETCONF, + CONFIGOPT_TZ, + CONFIGOPT_ROOTSH, + CONFIGOPT_ROOTPW, + CONFIGOPT_BINPKG, + CONFIGOPT_PKGSRC, + CONFIGOPT_SSHD, + CONFIGOPT_NTPD, + CONFIGOPT_NTPDATE, + CONFIGOPT_MDNSD, + CONFIGOPT_LAST +}; + +typedef struct configinfo { + const char *optname; + uint opt; + const char *rcvar; + int (*action)(struct menudesc *, void *); + const char *setting; +} configinfo; + + +configinfo config_list[] = { + {MSG_Configure_network, CONFIGOPT_NETCONF, NULL, set_network, MSG_configure}, + {MSG_timezone, CONFIGOPT_TZ, NULL, set_timezone_menu, NULL}, + {MSG_Root_shell, CONFIGOPT_ROOTSH, NULL, set_root_shell, NULL}, + {MSG_change_rootpw, CONFIGOPT_ROOTPW, NULL, change_root_password, MSG_change}, + {MSG_enable_binpkg, CONFIGOPT_BINPKG, NULL, set_binpkg, MSG_configure}, + {MSG_get_pkgsrc, CONFIGOPT_PKGSRC, NULL, set_pkgsrc, MSG_install}, + {MSG_enable_sshd, CONFIGOPT_SSHD, "sshd", toggle_rcvar, NULL}, + {MSG_enable_ntpd, CONFIGOPT_NTPD, "ntpd", toggle_rcvar, NULL}, + {MSG_run_ntpdate, CONFIGOPT_NTPDATE, "ntpdate", toggle_rcvar, NULL}, + {MSG_enable_mdnsd, CONFIGOPT_MDNSD, "mdnsd", toggle_rcvar, NULL}, + {NULL, CONFIGOPT_LAST, NULL, NULL, NULL} +}; + +static void +config_list_init(void) +{ + int i; + + for (i=0; i < CONFIGOPT_LAST; i++) { + switch (i) { + case CONFIGOPT_TZ: + get_tz_default(); + config_list[CONFIGOPT_TZ].setting = tz_default; + break; + case CONFIGOPT_ROOTSH: + get_rootsh(); + break; + case CONFIGOPT_ROOTPW: + if (check_root_password()) + config_list[i].setting = MSG_password_set; + else + config_list[i].setting = MSG_empty; + break; + default: + if (config_list[i].rcvar != NULL) { + if (check_rcvar(config_list[i].rcvar)) + config_list[i].setting = MSG_YES; + else + config_list[i].setting = MSG_NO; + } + break; + } + } +} + +static void +get_rootsh(void) +{ + static char *buf = NULL; + + if (buf != NULL) + free(buf); + + if (target_already_root()) + collect(T_OUTPUT, &buf, + "/usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'" + " /etc/passwd"); + else + collect(T_OUTPUT, &buf, + "chroot %s /usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'" + " /etc/passwd",target_prefix()); + + config_list[CONFIGOPT_ROOTSH].setting = (const char *)buf; +} + +static void +set_config(menudesc *menu, int opt, void *arg) +{ + configinfo **configp = arg; + configinfo *config = configp[opt]; + const char *optname, *setting; + + optname = config->optname; + setting = msg_string(config->setting); + + wprintw(menu->mw, "%-50s %-10s", msg_string(optname), setting); +} + +static int +init_config_menu(configinfo *conf, menu_ent *me, configinfo **ce) +{ + int opt; + int configopts; + + for (configopts = 0; ; conf++) { + opt = conf->opt; + if (opt == CONFIGOPT_LAST) + break; + *ce = conf; + me->opt_menu = OPT_NOMENU; + me->opt_flags = 0; + me->opt_name = NULL; /* NULL so set_config will draw */ + me->opt_action = conf->action; + configopts++; + ce++; + me++; + } + + return configopts; +} + +static int +/*ARGSUSED*/ +set_timezone_menu(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + set_timezone(); + get_tz_default(); + confp[menu->cursel]->setting = tz_default; + return 0; +} + +static int +set_root_shell(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + + process_menu(MENU_rootsh, &confp[menu->cursel]->setting); + run_program(RUN_PROGRESS | RUN_CHROOT, + "chpass -s %s root", confp[menu->cursel]->setting); + return 0; +} + +static int +set_network(struct menudesc *menu, void *arg) +{ + network_up = 0; + if (config_network()) + mnt_net_config(); + return 0; +} + +static int +check_root_password(void) +{ + char *buf; + int rval; + + if (target_already_root()) + collect(T_OUTPUT, &buf, "getent passwd root | cut -d: -f2"); + else + collect(T_OUTPUT, &buf, "chroot %s getent passwd root | " + "chroot %s cut -d: -f2", + target_prefix(), target_prefix()); + + if (logfp) + fprintf(logfp,"buf %s strlen(buf) %zu\n", buf, strlen(buf)); + + if (strlen(buf) <= 1) /* newline */ + rval = 0; + else + rval = 1; + free(buf); + return rval; +} + +static int +change_root_password(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + + msg_display(MSG_rootpw); + process_menu(MENU_yesno, NULL); + if (yesno) + run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT, + "passwd -l root"); + confp[menu->cursel]->setting = MSG_password_set; + return 0; +} + +static int +set_binpkg(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + + char pattern[STRSIZE]; + + /* binary pkg config requires network at this point, so if + it's not already configured, do it. */ + if (network_up == 0) { + if (config_network()) + mnt_net_config(); + } + + process_menu(MENU_binpkg, NULL); + make_url(pkgpath, &pkg, pkg_dir); + if ( run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT, + "pkg_add %s/pkgin", pkgpath) != 0) { + msg_display(MSG_pkgin_failed); + process_menu(MENU_ok, NULL); + confp[menu->cursel]->setting = MSG_failed; + return 0; + } + + /* configure pkgin to use $pkgpath as a repository */ + snprintf(pattern, STRSIZE, "s,^[^#].*$,%s,", pkgpath); + replace("/usr/pkg/etc/pkgin/repositories.conf", pattern); + + run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT, + "/usr/pkg/bin/pkgin -y update"); + + msg_display(MSG_binpkg_installed); + process_menu(MENU_ok, NULL); + + confp[menu->cursel]->setting = MSG_DONE; + return 0; +} + +static int +set_pkgsrc(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + distinfo dist; + + dist.name = "pkgsrc"; + dist.set = SET_PKGSRC; + dist.desc = "source for 3rd-party packages"; + dist.marker_file = NULL; + + int status = SET_RETRY; + + do { + status = get_pkgsrc(); + if (status == SET_OK) { + status = extract_file(&dist, 0); + continue; + } else if (status == SET_SKIP) { + confp[menu->cursel]->setting = MSG_abandoned; + return 0; + } + process_menu(MENU_yesno, deconst(MSG_retry_pkgsrc_network)); + if (!yesno) { + confp[menu->cursel]->setting = MSG_abandoned; + return 1; + } + } + while (status == SET_RETRY); + + + confp[menu->cursel]->setting = MSG_DONE; + return 0; +} + +static int +toggle_rcvar(struct menudesc *menu, void *arg) +{ + configinfo **confp = arg; + int s; + const char *setting, *varname; + char pattern[STRSIZE]; + char buf[STRSIZE]; + char *cp; + int found = 0; + FILE *fp; + + varname = confp[menu->cursel]->rcvar; + + s = check_rcvar(varname); + + /* we're toggling, so invert the sense */ + if (s) { + confp[menu->cursel]->setting = MSG_NO; + setting = "NO"; + } else { + confp[menu->cursel]->setting = MSG_YES; + setting = "YES"; + } + + if (!(fp = fopen(target_expand("/etc/rc.conf"), "r"))) { + msg_display(MSG_rcconf_delete_failed, varname); + process_menu(MENU_ok, NULL); + return -1; + } + + while (fgets(buf, sizeof buf, fp) != NULL) { + cp = buf + strspn(buf, " \t"); /* Skip initial spaces */ + if (strncmp(cp, varname, strlen(varname)) == 0) { + cp += strlen(varname); + if (*cp != '=') + continue; + buf[strlen(buf) - 1] = 0; + snprintf(pattern, sizeof pattern, + "s,^%s$,%s=%s,", + buf, varname, setting); + found = 1; + break; + } + } + + fclose(fp); + + if (!found) { + add_rc_conf("%s=%s\n", varname, setting); + if (logfp) { + fprintf(logfp, "adding %s=%s\n", varname, setting); + fflush(logfp); + } + } else { + if (logfp) { + fprintf(logfp, "replacement pattern is %s\n", pattern); + fflush(logfp); + } + replace("/etc/rc.conf", pattern); + } + + return 0; +} + +static void +configmenu_hdr(struct menudesc *menu, void *arg) +{ + msg_display(MSG_configmenu); +} + +void +do_configmenu() +{ + int menu_no; + int opts; + menu_ent me[CONFIGOPT_LAST]; + configinfo *ce[CONFIGOPT_LAST]; + + wrefresh(curscr); + wmove(stdscr, 0, 0); + wclear(stdscr); + wrefresh(stdscr); + + /* if the target isn't mounted already, figure it out. */ + if (target_mounted() == 0) { + if (find_disks(msg_string(MSG_configure_prior)) < 0) + return; + + if (mount_disks() != 0) + return; + } + + config_list_init(); + make_url(pkgpath, &pkg, pkg_dir); + opts = init_config_menu(config_list, me, ce); + + menu_no = new_menu(NULL, me, opts, 0, -4, 0, 70, + MC_SCROLL | MC_NOBOX | MC_DFLTEXIT, + configmenu_hdr, set_config, NULL, "XXX Help String", + MSG_doneconfig); + + process_menu(menu_no, ce); + free_menu(menu_no); + + sanity_check(); + +}