Implement a post-install configuration menu, as proposed on tech-install. trunk
authorriz <riz@NetBSD.org>
Fri, 06 Apr 2012 23:48:53 +0000
branchtrunk
changeset 210449 ee828567e269
parent 210448 d638ebdab18b
child 210450 a7bcd147e25e
Implement a post-install configuration menu, as proposed on tech-install. Enables the user to configure a few additional items, including using pkgin to manage binary packages, in a post-install menu which replaces the series of questions (Do you want to set a root password? etc). This is by no means a perfect solution, nor should it discourage anyone from working on more sweeping changes to sysinst. Some bug fixes, and .de translation provided by Julian Fagir. XXX .es, .fr and .pl translations still needed. Please help!
distrib/utils/sysinst/Makefile.inc
distrib/utils/sysinst/checkrc.c
distrib/utils/sysinst/configmenu.c
distrib/utils/sysinst/defs.h
distrib/utils/sysinst/install.c
distrib/utils/sysinst/main.c
distrib/utils/sysinst/menus.mi
distrib/utils/sysinst/msg.mi.de
distrib/utils/sysinst/msg.mi.en
distrib/utils/sysinst/msg.mi.es
distrib/utils/sysinst/msg.mi.fr
distrib/utils/sysinst/msg.mi.pl
distrib/utils/sysinst/net.c
distrib/utils/sysinst/target.c
distrib/utils/sysinst/util.c
--- a/distrib/utils/sysinst/Makefile.inc	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/Makefile.inc	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.58 2012/01/08 21:20:40 riz Exp $
+#	$NetBSD: Makefile.inc,v 1.59 2012/04/06 23:48:53 riz Exp $
 #
 # Makefile for sysinst
 
@@ -13,7 +13,7 @@
 
 SRCS+=	menu_defs.c msg_defs.c main.c install.c upgrade.c \
 	txtwalk.c run.c factor.c net.c disks.c disks_lfs.c util.c geom.c \
-	label.c target.c md.c sizemultname.c
+	label.c target.c md.c sizemultname.c configmenu.c checkrc.c
 
 SRCS+=	${MD_OPTIONS:MAOUT2ELF:S/AOUT2ELF/aout2elf.c/}
 SRCS+=	${MENUS_MD:Mmenus.mbr:S/menus.mbr/mbr.c/}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/utils/sysinst/checkrc.c	Fri Apr 06 23:48:53 2012 +0000
@@ -0,0 +1,113 @@
+/* $NetBSD: checkrc.c,v 1.1 2012/04/06 23:48:53 riz 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);
+
+	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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/utils/sysinst/configmenu.c	Fri Apr 06 23:48:53 2012 +0000
@@ -0,0 +1,416 @@
+/* $NetBSD: configmenu.c,v 1.1 2012/04/06 23:48:53 riz 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);
+
+	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;
+
+	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];
+
+	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;
+	}
+
+	run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
+		"/usr/pkg/bin/pkgin update");
+
+	/* configure pkgin to use $pkgpath as a repository */
+	snprintf(pattern, STRSIZE, "s,^[^#].*$,%s,", pkgpath);
+	replace("/usr/pkg/etc/pkgin/repositories.conf", pattern);
+	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();
+
+}
--- a/distrib/utils/sysinst/defs.h	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/defs.h	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: defs.h,v 1.161 2012/01/10 21:02:47 gson Exp $	*/
+/*	$NetBSD: defs.h,v 1.162 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -133,6 +133,7 @@
     SET_LAST,
     SET_GROUP,		/* Start of submenu */
     SET_GROUP_END,	/* End of submenu */
+    SET_PKGSRC,		/* pkgsrc, not counted as regular set */
 };
 
 /* Initialisers to select sets */
@@ -288,26 +289,50 @@
 #define SYSINST_FTP_DIR		"pub/NetBSD/NetBSD-" REL
 #endif
 
+#if !defined(SYSINST_PKG_HOST)
+#define SYSINST_PKG_HOST	SYSINST_FTP_HOST
+#endif
+
+#if !defined(SYSINST_PKG_DIR)
+#define SYSINST_PKG_DIR		"pub/pkgsrc/packages/NetBSD"
+#endif
+
+#if !defined(SYSINST_PKGSRC_HOST)
+#define SYSINST_PKGSRC_HOST	SYSINST_PKG_HOST
+#endif
+
 /* Abs. path we extract binary sets from */
 char ext_dir_bin[STRSIZE];
 
 /* Abs. path we extract source sets from */
 char ext_dir_src[STRSIZE];
 
+/* Abs. path we extract pkgsrc from */
+char ext_dir_pkgsrc[STRSIZE];
+
 /* Place we look for binary sets in all fs types */
 char set_dir_bin[STRSIZE];
 
 /* Place we look for source sets in all fs types */
 char set_dir_src[STRSIZE];
 
-struct {
+/* Place we look for pkgs in all fs types */
+char pkg_dir[STRSIZE];
+
+/* Place we look for pkgsrc in all fs types */
+char pkgsrc_dir[STRSIZE];
+
+struct ftpinfo {
     char host[STRSIZE];
     char dir[STRSIZE] ;
     char user[SSTRSIZE];
     char pass[STRSIZE];
     char proxy[STRSIZE];
     const char *xfer_type;		/* "ftp" or "http" */
-} ftp;
+};
+
+/* use the same struct for sets ftp and to build pkgpath */
+struct ftpinfo ftp, pkg, pkgsrc;
 
 int (*fetch_fn)(const char *);
 char nfs_host[STRSIZE];
@@ -393,11 +418,14 @@
 int	get_real_geom(const char *, struct disklabel *);
 
 /* from net.c */
+extern int network_up;
 extern char net_namesvr6[STRSIZE];
 int	get_via_ftp(const char *);
 int	get_via_nfs(void);
 int	config_network(void);
 void	mnt_net_config(void);
+void	make_url(char *, struct ftpinfo *, const char *);
+int	get_pkgsrc(void);
 
 /* From run.c */
 int	collect(int, char **, const char *, ...) __printflike(3, 4);
@@ -430,11 +458,10 @@
 int 	get_and_unpack_sets(int, msg, msg, msg);
 int	sanity_check(void);
 int	set_timezone(void);
-int	set_root_password(void);
-int	set_root_shell(void);
 void	scripting_fprintf(FILE *, const char *, ...) __printflike(2, 3);
 void	scripting_vfprintf(FILE *, const char *, va_list) __printflike(2, 0);
 void	add_rc_conf(const char *, ...);
+int	del_rc_conf(const char *);
 void	add_sysctl_conf(const char *, ...) __printflike(1, 2);
 void	enable_rc_conf(void);
 void	set_sizemultname_cyl(void);
@@ -446,6 +473,9 @@
 int 	set_is_source(const char *);
 const char *set_dir_for_set(const char *);
 const char *ext_dir_for_set(const char *);
+void	replace(const char *, const char *, ...);
+void	get_tz_default(void);
+int	extract_file(distinfo *, int);
 
 /* from target.c */
 #if defined(DEBUG)  ||	defined(DEBUG_ROOT)
@@ -476,6 +506,7 @@
 int	target_file_exists_p(const char *);
 int	target_symlink_exists_p(const char *);
 void	unwind_mounts(void);
+int	target_mounted(void);
 
 /* from bsddisklabel.c */
 int	make_bsd_partitions(void);
@@ -495,4 +526,11 @@
 #define	get_kb_encoding()
 #define	save_kb_encoding()
 #endif
+
+/* from configmenu.c */
+void	do_configmenu(void);
+
+/* from checkrc.c */
+int	check_rcvar(const char *);
+int	check_rcdefault(const char *);
 #endif	/* _DEFS_H_ */
--- a/distrib/utils/sysinst/install.c	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/install.c	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: install.c,v 1.45 2011/04/04 08:30:12 mbalmer Exp $	*/
+/*	$NetBSD: install.c,v 1.46 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -117,10 +117,7 @@
 	if (md_post_extract() != 0)
 		return;
 
-	set_timezone();
-
-	set_root_password();
-	set_root_shell();
+	do_configmenu();
 
 	sanity_check();
 
--- a/distrib/utils/sysinst/main.c	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/main.c	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.63 2012/01/10 21:02:47 gson Exp $	*/
+/*	$NetBSD: main.c,v 1.64 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -99,6 +99,18 @@
 	{"targetroot mount", "/targetroot", targetroot_mnt, sizeof targetroot_mnt},
 	{"dist postfix", ".tgz", dist_postfix, sizeof dist_postfix},
 	{"diskname", "mydisk", bsddiskname, sizeof bsddiskname},
+	{"pkg host", SYSINST_PKG_HOST, pkg.host, sizeof pkg.host},
+	{"pkg dir", SYSINST_PKG_DIR, pkg.dir, sizeof pkg.dir},
+	{"pkg prefix", "/" MACH "/" REL "/All", pkg_dir, sizeof pkg_dir},
+	{"pkg user", "ftp", pkg.user, sizeof pkg.user},
+	{"pkg pass", "", pkg.pass, sizeof pkg.pass},
+	{"pkg proxy", "", pkg.proxy, sizeof pkg.proxy},
+	{"pkgsrc host", SYSINST_PKGSRC_HOST, pkgsrc.host, sizeof pkgsrc.host},
+	{"pkgsrc dir", "", pkgsrc.dir, sizeof pkgsrc.dir},
+	{"pkgsrc prefix", "pub/pkgsrc/stable", pkgsrc_dir, sizeof pkgsrc_dir},
+	{"pkgsrc user", "ftp", pkgsrc.user, sizeof pkgsrc.user},
+	{"pkgsrc pass", "", pkgsrc.pass, sizeof pkgsrc.pass},
+	{"pkgsrc proxy", "", pkgsrc.proxy, sizeof pkgsrc.proxy},
 
 	{NULL, NULL, NULL, 0}
 };
@@ -118,6 +130,7 @@
 
 	for (arg = fflagopts; arg->name != NULL; arg++)
 		strlcpy(arg->var, arg->dflt, arg->size);
+	pkg.xfer_type = pkgsrc.xfer_type = "http";
 }
 
 int
--- a/distrib/utils/sysinst/menus.mi	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/menus.mi	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: menus.mi,v 1.44 2012/01/10 21:02:47 gson Exp $	*/
+/*	$NetBSD: menus.mi,v 1.45 2012/04/06 23:48:53 riz Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -162,6 +162,7 @@
 	option MSG_Reboot_the_computer, exit,
 		action (endwin) { system("/sbin/reboot -q"); };
 	option MSG_Utility_menu, sub menu utility;
+	option "Config menu", action { do_configmenu(); };
 
 menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
 		exitstring MSG_exit_utility_menu;
@@ -281,6 +282,7 @@
 		action {process_menu(MENU_yesno, deconst(MSG_delete_xfer_file));
 			clean_xfer_dir = yesno; };
 
+
 menu nfssource, y=-4, x=0, w=70, no box, no clear,
 	    exitstring MSG_Continue;
 	display action { msg_display(MSG_nfssource); };
@@ -377,7 +379,86 @@
 	option MSG_other, exit, action
 		{ yesno = 0; };
 
-menu rootsh, title MSG_Root_shell;
+menu rootsh, title MSG_Root_shell, no clear;
 	option "/bin/sh",  exit, action {*(const char **)arg = "/bin/sh";}; 
 	option "/bin/ksh", exit, action {*(const char **)arg = "/bin/ksh";};
 	option "/bin/csh", exit, action {*(const char **)arg = "/bin/csh";};
+
+menu zeroconf, title "Zeroconf", no clear;
+	option "run mdnsd only", exit, action {*(const char **)arg = "mdnsd";};
+	option "run mdnsd and resolve local names", exit, action {*(const char **) arg = "mdnsd+nsswitch";};
+	option "do not run mdnsd", exit, action {*(const char **)arg = "No";};
+
+menu binpkg, y=-4, x=0, w=70, no box, no clear,
+	    exitstring MSG_Install_pkgin;
+	display action { msg_display(MSG_pkgpath); };
+	option {src_legend(menu, MSG_Host, pkg.host);},
+		action { src_prompt(MSG_Host, pkg.host, sizeof pkg.host); };
+	option {src_legend(menu, MSG_Base_dir, pkg.dir);},
+		action { src_prompt(MSG_Base_dir, pkg.dir, sizeof pkg.dir); };
+	option {src_legend(menu, MSG_Pkg_dir, pkg_dir);},
+		action { src_prompt(MSG_Pkg_dir, pkg_dir, sizeof pkg_dir); };
+	option {src_legend(menu, MSG_User, pkg.user);},
+		action { src_prompt(MSG_User, pkg.user, sizeof pkg.user);
+			pkg.pass[0] = 0;
+		};
+	option {src_legend(menu, MSG_Password,
+		    strcmp(pkg.user, "ftp") == 0 || pkg.pass[0] == 0
+			? pkg.pass : msg_string(MSG_hidden));},
+		action { if (strcmp(pkg.user, "ftp") == 0)
+			src_prompt(MSG_email, pkg.pass, sizeof pkg.pass);
+		  else {
+			msg_prompt_noecho(MSG_Password, "",
+					pkg.pass, sizeof pkg.pass);
+		  }
+		};
+	option {src_legend(menu, MSG_Proxy, pkg.proxy);},
+		action { src_prompt(MSG_Proxy, pkg.proxy, sizeof pkg.proxy);
+		  if (strcmp(pkg.proxy, "") == 0) {
+			unsetenv("ftp_proxy");
+			unsetenv("http_proxy");
+		  } else {
+			setenv("ftp_proxy", pkg.proxy, 1);
+			setenv("http_proxy", pkg.proxy, 1);
+		  }
+		};
+
+menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
+	    exit, exitstring MSG_Install_pkgsrc;
+	display action { msg_display(MSG_pkgsrc); };
+	option {src_legend(menu, MSG_Host, pkgsrc.host);},
+		action { src_prompt(MSG_Host, pkgsrc.host,
+			sizeof pkgsrc.host); };
+	option {src_legend(menu, MSG_Pkgsrc_dir, pkgsrc_dir);},
+		action { src_prompt(MSG_Pkgsrc_dir, pkgsrc_dir, sizeof pkgsrc_dir); };
+	option {src_legend(menu, MSG_User, pkgsrc.user);},
+		action { src_prompt(MSG_User, pkgsrc.user, sizeof pkgsrc.user);
+			pkgsrc.pass[0] = 0;
+		};
+	option {src_legend(menu, MSG_Password,
+		    strcmp(pkgsrc.user, "ftp") == 0 || pkgsrc.pass[0] == 0
+			? pkgsrc.pass : msg_string(MSG_hidden));},
+		action { if (strcmp(pkgsrc.user, "ftp") == 0)
+			src_prompt(MSG_email, pkgsrc.pass, sizeof pkgsrc.pass);
+		  else {
+			msg_prompt_noecho(MSG_Password, "",
+					pkgsrc.pass, sizeof pkgsrc.pass);
+		  }
+		};
+	option {src_legend(menu, MSG_Proxy, pkgsrc.proxy);},
+		action { src_prompt(MSG_Proxy, pkgsrc.proxy, sizeof pkgsrc.proxy);
+		  if (strcmp(pkgsrc.proxy, "") == 0) {
+			unsetenv("ftp_proxy");
+			unsetenv("http_proxy");
+		  } else {
+			setenv("ftp_proxy", pkgsrc.proxy, 1);
+			setenv("http_proxy", pkgsrc.proxy, 1);
+		  }
+		};
+	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
+		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
+	option {src_legend(menu, MSG_delete_xfer_file,
+			clean_xfer_dir ? MSG_Yes : MSG_No);},
+		action {process_menu(MENU_yesno, deconst(MSG_delete_xfer_file));
+			clean_xfer_dir = yesno; };
+	option MSG_quit_pkgsrc, exit, action { yesno = 0;};
--- a/distrib/utils/sysinst/msg.mi.de	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/msg.mi.de	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.de,v 1.64 2012/03/03 02:34:13 tsutsui Exp $	*/
+/*	$NetBSD: msg.mi.de,v 1.65 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -1039,3 +1039,64 @@
 Um den Lizenztext zu lesen, geben Sie ^Z ein, schauen den Inhalt
 der Datei an und kehren mit dem Befehl "fg" zu sysinst zurück.}
 
+message binpkg
+{Um Binärpakete zu installieren, muss erst eine Netzwerkverbindung konfiguriert 
+werden, über die die Pakete heruntergeladen werden. Nach einem ersten Start in
+das installierte System können mit dem Kommando 'pkgin' zusätzliche Pakete 
+installiert oder entfernt werden.}
+
+message pkgpath
+{Zur Konfiguration von pkgin muss zuerst das Repository konfiguriert werden. 
+Welches Protokoll, welcher Host, welches Verzeichnis und welcher User/Passwort 
+sollen zum Herunterladen verwendet werden? Wenn der User auf "ftp" gesetzt wird, 
+dann wird kein Passwort benötigt. 
+
+}
+message rcconf_backup_failed {rc.conf-Backup fehlgeschlagen. Trotzdem fortfahren?}
+message rcconf_backup_succeeded {rc.conf-Backup nach %s gespeichert.}
+message rcconf_restore_failed {rc.conf-Restore ist fehlgeschlagen.}
+message rcconf_delete_failed {Löschen des alten %s-Eintrages ist fehlgeschlagen.}
+message Pkg_dir {Paketverzeichnis}
+message configure_prior {Existierende Installation konfigurieren}
+message configure {Konfigurieren}
+message change {Ändern}
+message password_set {Passwort gesetzt}
+message YES {JA}
+message NO {NEIN}
+message DONE {ERLEDIGT}
+message abandoned {Abgebrochen}
+message empty {***LEER***}
+message timezone {Zeitzone}
+message change_rootpw {root-Passwort setzen}
+message enable_binpkg {Enable installation of binary packages}
+message enable_sshd {sshd aktivieren}
+message enable_ntpd {ntpd aktivieren}
+message run_ntpdate {ntpdate beim Starten ausführen}
+message enable_mdnsd {mdnsd aktivieren}
+message configmenu {Zusätzliche Einstellungen konfigurieren.}
+message doneconfig {Konfiguration abgeschlossen.}
+message Install_pkgin {pkgin installieren und Datenbank initialisieren}
+message binpkg_installed 
+{Das System kann nun Binärpakete mittels pkgin installieren. Um ein Paket zu 
+installieren, muss man folenden Befehl von einer root-Shell ausführen:
+
+pkgin install <packagename>
+
+Weitere Informationen finden sich in der pkgin(1)-Manpage.}
+message Install_pkgsrc {pkgsrc herunterladen und entpacken}
+message pkgsrc
+{Welches Protokoll, welcher Host, welches Verzeichnis und welcher User/Passwort 
+sollen zum Herunterladen von pkgsrc verwendet werden? Wenn der User auf "ftp" 
+gesetzt wird, dann wird kein Passwort benötigt. 
+
+}
+message Pkgsrc_dir {pkgsrc-Verzeichnis}
+message get_pkgsrc {pkgsrc zur Installation von Quellpaketen herunterladen und 
+installieren}
+message retry_pkgsrc_network {Netzwerkkonfiguration fehlgeschlagen. Noch einmal 
+versuchen?}
+message quit_pkgsrc {Ohne Installation von pkgsrc beenden.}
+message pkgin_failed 
+{Die Installation von pkgin ist fehlgeschlagen, evtl. weil keine Binärpakete 
+vorhanden sind. Bitte den Pfad der Pakete überprüfen und noch einmal versuchen.}
+message failed {Fehlgeschlagen}
--- a/distrib/utils/sysinst/msg.mi.en	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/msg.mi.en	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.en,v 1.171 2012/03/03 03:06:30 tsutsui Exp $	*/
+/*	$NetBSD: msg.mi.en,v 1.172 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -972,3 +972,61 @@
 {To use the network interface %s, you must agree to the license in
 file %s. To view this file now, you can type ^Z, look at the contents of
 the file and then type "fg" to resume.}
+
+message binpkg
+{To configure the binary package system, please choose the network location
+to fetch packages from.  Once your system comes up, you can use 'pkgin'
+to install additional packages, or remove packages.}
+
+message pkgpath
+{Enabling binary packages with pkgin requires setting up the repository.
+The following are the host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message rcconf_backup_failed {Making backup of rc.conf failed. Continue?}
+message rcconf_backup_succeeded {rc.conf backup saved to %s.}
+message rcconf_restore_failed {Restoring backup rc.conf failed.}
+message rcconf_delete_failed {Deleting old %s entry failed.}
+message Pkg_dir {Package directory}
+message configure_prior {configure a prior installation of}
+message configure {configure}
+message change {change}
+message password_set {password set}
+message YES {YES}
+message NO {NO}
+message DONE {DONE}
+message abandoned {Abandoned}
+message empty {***EMPTY***}
+message timezone {Timezone}
+message change_rootpw {Change root password}
+message enable_binpkg {Enable installation of binary packages}
+message enable_sshd {Enable sshd}
+message enable_ntpd {Enable ntpd}
+message run_ntpdate {Run ntpdate at boot}
+message enable_mdnsd {Enable mdnsd}
+message configmenu {Configure the additional items as needed.}
+message doneconfig {Finished configuring}
+message Install_pkgin {Install pkgin and update package summary}
+message binpkg_installed
+{Your system is now configured to use pkgin to install binary packages.  To
+install a package, run:
+
+pkgin install <packagename>
+
+from a root shell.  Read the pkgin(1) manual page for further information.}
+message Install_pkgsrc {Fetch and unpack pkgsrc}
+message pkgsrc
+{Installing pkgsrc requires unpacking an archive retrieved over the network.
+The following are the host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message Pkgsrc_dir {pkgsrc directory}
+message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
+message retry_pkgsrc_network {Network configuration failed.  Retry?}
+message quit_pkgsrc {Quit without installing pkgsrc}
+message pkgin_failed
+{Installation of pkgin failed, possibly because no binary packages
+exist.  Please check the package path and try again.}
+message failed {Failed}
--- a/distrib/utils/sysinst/msg.mi.es	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/msg.mi.es	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.es,v 1.42 2012/03/03 03:06:30 tsutsui Exp $	*/
+/*	$NetBSD: msg.mi.es,v 1.43 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -1012,3 +1012,59 @@
 file %s.
 To view this file now, you can type ^Z, look at the contents of
 the file and then type "fg" to resume.}
+
+message binpkg
+{To configure the binary package system, please choose the network location
+to fetch packages from.  Once your system comes up, you can use 'pkgin'
+to install additional packages, or remove packages.}
+
+message pkgpath
+{The following are the protocol, host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message rcconf_backup_failed {Making backup of rc.conf failed. Continue?}
+message rcconf_backup_succeeded {rc.conf backup saved to %s.}
+message rcconf_restore_failed {Restoring backup rc.conf failed.}
+message rcconf_delete_failed {Deleting old %s entry failed.}
+message Pkg_dir {Package directory}
+message configure_prior {configure a prior installation of}
+message configure {configure}
+message change {change}
+message password_set {password set}
+message YES {YES}
+message NO {NO}
+message DONE {DONE}
+message abandoned {Abandoned}
+message empty {***EMPTY***}
+message timezone {Timezone}
+message change_rootpw {Change root password}
+message enable_binpkg {Enable installation of binary packages}
+message enable_sshd {Enable sshd}
+message enable_ntpd {Enable ntpd}
+message run_ntpdate {Run ntpdate at boot}
+message enable_mdnsd {Enable mdnsd}
+message configmenu {Configure the additional items as needed.}
+message doneconfig {Finished configuring}
+message Install_pkgin {Install pkgin and update package summary}
+message binpkg_installed 
+{You are now configured to use pkgin to install binary packages.  To
+install a package, run:
+
+pkgin install <packagename>
+
+from a root shell.  Read the pkgin(1) manual page for further information.}
+message Install_pkgsrc {Fetch and unpack pkgsrc}
+message pkgsrc
+{Installing pkgsrc requires unpacking an archive retrieved over the network.
+The following are the host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message Pkgsrc_dir {pkgsrc directory}
+message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
+message retry_pkgsrc_network {Network configuration failed.  Retry?}
+message quit_pkgsrc {Quit without installing pkgsrc}
+message pkgin_failed 
+{Installation of pkgin failed, possibly because no binary packages  exist.  Please check the package path and try again.}
+message failed {Failed}
--- a/distrib/utils/sysinst/msg.mi.fr	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/msg.mi.fr	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.fr,v 1.123 2012/03/03 02:34:13 tsutsui Exp $	*/
+/*	$NetBSD: msg.mi.fr,v 1.124 2012/04/06 23:48:53 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -1071,3 +1071,59 @@
 {Afin d'utiliser l'interface réseau : %s, vous devez accepter la licence
 contenue dans le fichier %s.
 Pour afficher ce fichier, tapez ^Z, lisez le puis tapez "fg" pour reprendre.}
+
+message binpkg
+{To configure the binary package system, please choose the network location
+to fetch packages from.  Once your system comes up, you can use 'pkgin'
+to install additional packages, or remove packages.}
+
+message pkgpath
+{The following are the protocol, host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message rcconf_backup_failed {Making backup of rc.conf failed. Continue?}
+message rcconf_backup_succeeded {rc.conf backup saved to %s.}
+message rcconf_restore_failed {Restoring backup rc.conf failed.}
+message rcconf_delete_failed {Deleting old %s entry failed.}
+message Pkg_dir {Package directory}
+message configure_prior {configure a prior installation of}
+message configure {configure}
+message change {change}
+message password_set {password set}
+message YES {YES}
+message NO {NO}
+message DONE {DONE}
+message abandoned {Abandoned}
+message empty {***EMPTY***}
+message timezone {Timezone}
+message change_rootpw {Change root password}
+message enable_binpkg {Enable installation of binary packages}
+message enable_sshd {Enable sshd}
+message enable_ntpd {Enable ntpd}
+message run_ntpdate {Run ntpdate at boot}
+message enable_mdnsd {Enable mdnsd}
+message configmenu {Configure the additional items as needed.}
+message doneconfig {Finished configuring}
+message Install_pkgin {Install pkgin and update package summary}
+message binpkg_installed 
+{You are now configured to use pkgin to install binary packages.  To
+install a package, run:
+
+pkgin install <packagename>
+
+from a root shell.  Read the pkgin(1) manual page for further information.}
+message Install_pkgsrc {Fetch and unpack pkgsrc}
+message pkgsrc
+{Installing pkgsrc requires unpacking an archive retrieved over the network.
+The following are the host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message Pkgsrc_dir {pkgsrc directory}
+message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
+message retry_pkgsrc_network {Network configuration failed.  Retry?}
+message quit_pkgsrc {Quit without installing pkgsrc}
+message pkgin_failed 
+{Installation of pkgin failed, possibly because no binary packages  exist.  Please check the package path and try again.}
+message failed {Failed}
--- a/distrib/utils/sysinst/msg.mi.pl	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/msg.mi.pl	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.pl,v 1.82 2012/03/03 03:06:30 tsutsui Exp $	*/
+/*	$NetBSD: msg.mi.pl,v 1.83 2012/04/06 23:48:53 riz Exp $	*/
 /*	Based on english version: */
 /*	NetBSD: msg.mi.pl,v 1.36 2004/04/17 18:55:35 atatat Exp       */
 
@@ -967,3 +967,59 @@
 zawarta w pliku %s.
 Aby obejrzec ten plik, mozesz wpisac ^Z, przejrzec jego zawartosc,
 a nastepnie wpisac "fg".}
+
+message binpkg
+{To configure the binary package system, please choose the network location
+to fetch packages from.  Once your system comes up, you can use 'pkgin'
+to install additional packages, or remove packages.}
+
+message pkgpath
+{The following are the protocol, host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message rcconf_backup_failed {Making backup of rc.conf failed. Continue?}
+message rcconf_backup_succeeded {rc.conf backup saved to %s.}
+message rcconf_restore_failed {Restoring backup rc.conf failed.}
+message rcconf_delete_failed {Deleting old %s entry failed.}
+message Pkg_dir {Package directory}
+message configure_prior {configure a prior installation of}
+message configure {configure}
+message change {change}
+message password_set {password set}
+message YES {YES}
+message NO {NO}
+message DONE {DONE}
+message abandoned {Abandoned}
+message empty {***EMPTY***}
+message timezone {Timezone}
+message change_rootpw {Change root password}
+message enable_binpkg {Enable installation of binary packages}
+message enable_sshd {Enable sshd}
+message enable_ntpd {Enable ntpd}
+message run_ntpdate {Run ntpdate at boot}
+message enable_mdnsd {Enable mdnsd}
+message configmenu {Configure the additional items as needed.}
+message doneconfig {Finished configuring}
+message Install_pkgin {Install pkgin and update package summary}
+message binpkg_installed 
+{You are now configured to use pkgin to install binary packages.  To
+install a package, run:
+
+pkgin install <packagename>
+
+from a root shell.  Read the pkgin(1) manual page for further information.}
+message Install_pkgsrc {Fetch and unpack pkgsrc}
+message pkgsrc
+{Installing pkgsrc requires unpacking an archive retrieved over the network.
+The following are the host, directory, user, and password that
+will be used.  If "user" is "ftp", then the password is not needed.
+
+}
+message Pkgsrc_dir {pkgsrc directory}
+message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
+message retry_pkgsrc_network {Network configuration failed.  Retry?}
+message quit_pkgsrc {Quit without installing pkgsrc}
+message pkgin_failed 
+{Installation of pkgin failed, possibly because no binary packages  exist.  Please check the package path and try again.}
+message failed {Failed}
--- a/distrib/utils/sysinst/net.c	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/net.c	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: net.c,v 1.130 2012/01/10 21:02:47 gson Exp $	*/
+/*	$NetBSD: net.c,v 1.131 2012/04/06 23:48:54 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -939,61 +939,91 @@
 	return network_up;
 }
 
-static int
-ftp_fetch(const char *set_name)
+void
+make_url(char *urlbuffer, struct ftpinfo *f, const char *dir)
 {
-	const char *ftp_opt;
 	char ftp_user_encoded[STRSIZE];
 	char ftp_dir_encoded[STRSIZE];
 	char *cp;
-	const char *set_dir2;
-	int rval;
+	const char *dir2;
 
 	/*
-	 * Invoke ftp to fetch the file.
-	 *
-	 * ftp.pass is quite likely to contain unsafe characters
+	 * f->pass is quite likely to contain unsafe characters
 	 * that need to be encoded in the URL (for example,
 	 * "@", ":" and "/" need quoting).  Let's be
-	 * paranoid and also encode ftp.user and ftp.dir.  (For
-	 * example, ftp.dir could easily contain '~', which is
+	 * paranoid and also encode f->user and f->dir.  (For
+	 * example, f->dir could easily contain '~', which is
 	 * unsafe by a strict reading of RFC 1738).
 	 */
-	if (strcmp("ftp", ftp.user) == 0 && ftp.pass[0] == 0) {
-		/* do anon ftp */
-		ftp_opt = "-a ";
+	if (strcmp("ftp", f->user) == 0 && f->pass[0] == 0) {
 		ftp_user_encoded[0] = 0;
 	} else {
-		ftp_opt = "";
-		cp = url_encode(ftp_user_encoded, ftp.user,
+		cp = url_encode(ftp_user_encoded, f->user,
 			ftp_user_encoded + sizeof ftp_user_encoded - 1,
 			RFC1738_SAFE_LESS_SHELL, 0);
 		*cp++ = ':';
-		cp = url_encode(cp, ftp.pass,
+		cp = url_encode(cp, f->pass,
 			ftp_user_encoded + sizeof ftp_user_encoded - 1,
 			NULL, 0);
 		*cp++ = '@';
 		*cp = 0;
 	}
-
-	cp = url_encode(ftp_dir_encoded, ftp.dir,
+	cp = url_encode(ftp_dir_encoded, f->dir,
 			ftp_dir_encoded + sizeof ftp_dir_encoded - 1,
 			RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 1);
 	if (cp != ftp_dir_encoded && cp[-1] != '/')
 		*cp++ = '/';
 
-	set_dir2 = set_dir_for_set(set_name);
-	while (*set_dir2 == '/')
-		++set_dir2;
+	dir2 = dir;
+	while (*dir2 == '/')
+		++dir2;
 
-	url_encode(cp, set_dir2,
+	url_encode(cp, dir2,
 			ftp_dir_encoded + sizeof ftp_dir_encoded,
 			RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 0);
 
+	snprintf(urlbuffer, STRSIZE, "%s://%s%s/%s", f->xfer_type,
+	    ftp_user_encoded, f->host, ftp_dir_encoded);
+}
+
+
+/* ftp_fetch() and pkgsrc_fetch() are essentially the same, with a different
+ * ftpinfo var. */
+static int do_ftp_fetch(const char *, struct ftpinfo *);
+
+static int
+ftp_fetch(const char *set_name)
+{
+	return do_ftp_fetch(set_name, &ftp);
+}
+
+static int
+pkgsrc_fetch(const char *set_name)
+{
+	return do_ftp_fetch(set_name, &pkgsrc);
+}
+
+static int
+do_ftp_fetch(const char *set_name, struct ftpinfo *f)
+{
+	const char *ftp_opt;
+	char url[STRSIZE];
+	int rval;
+
+	/*
+	 * Invoke ftp to fetch the file.
+	 */
+	if (strcmp("ftp", f->user) == 0 && f->pass[0] == 0) {
+		/* do anon ftp */
+		ftp_opt = "-a ";
+	} else {
+		ftp_opt = "";
+	}
+
+	make_url(url, f, set_dir_for_set(set_name));
 	rval = run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_XFER_DIR,
-		    "/usr/bin/ftp %s%s://%s%s/%s/%s%s",
-		    ftp_opt, ftp.xfer_type, ftp_user_encoded, ftp.host,
-		    ftp_dir_encoded, set_name, dist_postfix);
+		    "/usr/bin/ftp %s%s/%s%s",
+		    ftp_opt, url, set_name, dist_postfix);
 
 	return rval ? SET_RETRY : SET_OK;
 }
@@ -1021,6 +1051,25 @@
 }
 
 int
+get_pkgsrc(void)
+{
+	if (!network_up)
+		if (do_config_network() != 0)
+			return SET_RETRY;
+
+	yesno = 1;
+	process_menu(MENU_pkgsrc, NULL);
+	
+	if (yesno == 0)
+		return SET_SKIP;
+	fetch_fn = pkgsrc_fetch;
+	snprintf(ext_dir_pkgsrc, sizeof ext_dir_pkgsrc, "%s/%s",
+	    target_prefix(), xfer_dir + (*xfer_dir == '/'));
+
+	return SET_OK;
+}
+
+int
 get_via_ftp(const char *xfer_type)
 {
 
@@ -1102,6 +1151,7 @@
 mnt_net_config(void)
 {
 	char ifconfig_fn[STRSIZE];
+	char ifconfig_str[STRSIZE];
 	FILE *ifconf = NULL;
 
 	if (!network_up)
@@ -1112,7 +1162,8 @@
 
 	/* Write hostname to /etc/rc.conf */
 	if ((net_dhcpconf & DHCPCONF_HOST) == 0)
-		add_rc_conf("hostname=%s\n", recombine_host_domain());
+		if (del_rc_conf("hostname"))
+			add_rc_conf("hostname=%s\n", recombine_host_domain());
 
 	/* Copy resolv.conf to target.  If DHCP was used to create it,
 	 * it will be replaced on next boot anyway. */
@@ -1176,14 +1227,18 @@
 			fclose(hosts);
 		}
 
-		add_rc_conf("defaultroute=\"%s\"\n", net_defroute);
+		if (!del_rc_conf("defaultroute"))
+			add_rc_conf("defaultroute=\"%s\"\n", net_defroute);
 	} else {
-		add_rc_conf("ifconfig_%s=dhcp\n", net_dev);
+		if (snprintf(ifconfig_str, sizeof ifconfig_str, "ifconfig_%s", net_dev) > 0
+				&& del_rc_conf(ifconfig_str))
+			add_rc_conf("ifconfig_%s=dhcp\n", net_dev);
         }
 
 #ifdef INET6
 	if ((net_ip6conf & IP6CONF_AUTOHOST) != 0) {
-		add_rc_conf("ip6mode=autohost\n");
+		if (!del_rc_conf("ip6mode"))
+			add_rc_conf("ip6mode=autohost\n");
 		if (ifconf != NULL) {
 			scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
 			    target_prefix(), ifconfig_fn);
--- a/distrib/utils/sysinst/target.c	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/target.c	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: target.c,v 1.54 2012/01/05 21:29:25 christos Exp $	*/
+/*	$NetBSD: target.c,v 1.55 2012/04/06 23:48:54 riz Exp $	*/
 
 /*
  * Copyright 1997 Jonathan Stone
@@ -71,7 +71,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: target.c,v 1.54 2012/01/05 21:29:25 christos Exp $");
+__RCSID("$NetBSD: target.c,v 1.55 2012/04/06 23:48:54 riz Exp $");
 #endif
 
 /*
@@ -538,3 +538,9 @@
 
 	return (target_test_symlink(path) == 0);
 }
+
+int
+target_mounted(void)
+{
+	return (unwind_mountlist != NULL);
+}
--- a/distrib/utils/sysinst/util.c	Fri Apr 06 22:50:39 2012 +0000
+++ b/distrib/utils/sysinst/util.c	Fri Apr 06 23:48:53 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.174 2012/03/21 05:43:55 matt Exp $	*/
+/*	$NetBSD: util.c,v 1.175 2012/04/06 23:48:54 riz Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -287,7 +287,6 @@
  *
  * replace("/etc/some-file.conf", "s/prop1=NO/prop1=YES/;s/foo/bar/");
  */
-static
 void
 replace(const char *path, const char *patterns, ...)
 {
@@ -858,7 +857,7 @@
  * full path name to the directory.
  */
 
-static int
+int
 extract_file(distinfo *dist, int update)
 {
 	char path[STRSIZE];
@@ -909,7 +908,9 @@
 	if (update && (dist->set == SET_ETC || dist->set == SET_X11_ETC)) {
 		make_target_dir("/.sysinst");
 		target_chdir_or_die("/.sysinst");
-	} else
+	} else if (dist->set == SET_PKGSRC)
+		target_chdir_or_die("/usr");
+	else
 		target_chdir_or_die("/");
 
 	/*
@@ -1181,7 +1182,7 @@
 static char zoneinfo_dir[STRSIZE];
 static int zonerootlen;
 static char *tz_selected;	/* timezonename (relative to share/zoneinfo */
-static const char *tz_default;	/* UTC, or whatever /etc/localtime points to */
+const char *tz_default;		/* UTC, or whatever /etc/localtime points to */
 static char tz_env[STRSIZE];
 static int save_cursel, save_topline;
 
@@ -1332,21 +1333,13 @@
 	qsort(tz_menu, nfiles, sizeof *tz_menu, tz_sort);
 }
 
-/*
- * Choose from the files in usr/share/zoneinfo and set etc/localtime
- */
-int
-set_timezone(void)
+void
+get_tz_default(void)
 {
 	char localtime_link[STRSIZE];
-	char localtime_target[STRSIZE];
+	static char localtime_target[STRSIZE];
 	int rc;
-	time_t t;
-	int menu_no;
 
-	strlcpy(zoneinfo_dir, target_expand("/usr/share/zoneinfo/"),
-	    sizeof zoneinfo_dir - 1);
-	zonerootlen = strlen(zoneinfo_dir);
 	strlcpy(localtime_link, target_expand("/etc/localtime"),
 	    sizeof localtime_link);
 
@@ -1363,6 +1356,24 @@
 		localtime_target[rc] = '\0';
 		tz_default = strchr(strstr(localtime_target, "zoneinfo"), '/') + 1;
 	}
+}
+
+/*
+ * Choose from the files in usr/share/zoneinfo and set etc/localtime
+ */
+int
+set_timezone(void)
+{
+	char localtime_link[STRSIZE];
+	char localtime_target[STRSIZE];
+	time_t t;
+	int menu_no;
+
+	strlcpy(zoneinfo_dir, target_expand("/usr/share/zoneinfo/"),
+	    sizeof zoneinfo_dir - 1);
+	zonerootlen = strlen(zoneinfo_dir);
+
+	get_tz_default();
 
 	tz_selected = strdup(tz_default);
 	snprintf(tz_env, sizeof(tz_env), "%s%s", zoneinfo_dir, tz_selected);
@@ -1389,6 +1400,8 @@
 
 	snprintf(localtime_target, sizeof(localtime_target),
 		 "/usr/share/zoneinfo/%s", tz_selected);
+	strlcpy(localtime_link, target_expand("/etc/localtime"),
+	    sizeof localtime_link);
 	unlink(localtime_link);
 	symlink(localtime_target, localtime_link);
 
@@ -1396,29 +1409,6 @@
 	return 1;
 }
 
-int
-set_root_password(void)
-{
-
-	msg_display(MSG_rootpw);
-	process_menu(MENU_yesno, NULL);
-	if (yesno)
-		run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
-			    "passwd -l root");
-	return 0;
-}
-
-int
-set_root_shell(void)
-{
-	const char *shellpath;
-
-	msg_display(MSG_rootsh);
-	process_menu(MENU_rootsh, &shellpath);
-	run_program(RUN_DISPLAY | RUN_CHROOT, "chpass -s %s root", shellpath);
-	return 0;
-}
-
 void
 scripting_vfprintf(FILE *f, const char *fmt, va_list ap)
 {
@@ -1457,6 +1447,102 @@
 	va_end(ap);
 }
 
+int
+del_rc_conf(const char *value)
+{
+	FILE *fp, *nfp;
+	char buf[4096]; /* Ridiculously high, but should be enough in any way */
+	char *rcconf, *tempname, *bakname;
+	char *cp;
+	int done = 0;
+	int fd;
+	int retval = 0;
+
+	/* The paths might seem strange, but using /tmp would require copy instead 
+	 * of rename operations. */
+	if (asprintf(&rcconf, "%s", target_expand("/etc/rc.conf")) < 0
+			|| asprintf(&tempname, "%s", target_expand("/etc/rc.conf.tmp.XXXXXX")) < 0
+			|| asprintf(&bakname, "%s", target_expand("/etc/rc.conf.bak.XXXXXX")) < 0) {
+		if (rcconf)
+			free(rcconf);
+		if (tempname)
+			free(tempname);
+		msg_display(MSG_rcconf_delete_failed, value);
+		process_menu(MENU_ok, NULL);
+		return -1;
+	}
+
+	if ((fd = mkstemp(bakname)) < 0) {
+		msg_display(MSG_rcconf_delete_failed, value);
+		process_menu(MENU_ok, NULL);
+		return -1;
+	}
+	close(fd);
+
+	if (!(fp = fopen(rcconf, "r+")) || (fd = mkstemp(tempname)) < 0) {
+		if (fp)
+			fclose(fp);
+		msg_display(MSG_rcconf_delete_failed, value);
+		process_menu(MENU_ok, NULL);
+		return -1;
+	}
+
+	nfp = fdopen(fd, "w");
+	if (!nfp) {
+		fclose(fp);
+		close(fd);
+		msg_display(MSG_rcconf_delete_failed, value);
+		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, value, strlen(value)) == 0) {
+			cp += strlen(value);
+			if (*cp != '=')
+				scripting_fprintf(nfp, "%s", buf);
+			else
+				done = 1;
+		} else {
+			scripting_fprintf(nfp, "%s", buf);
+		}
+	}
+	fclose(fp);
+	fclose(nfp);
+	
+	if (done) {
+		if (rename(rcconf, bakname)) {
+			msg_display(MSG_rcconf_backup_failed);
+			process_menu(MENU_noyes, NULL);
+			if (!yesno) {
+				retval = -1;
+				goto done;
+			}
+		}
+
+		if (rename(tempname, rcconf)) {
+			if (rename(bakname, rcconf)) {
+				msg_display(MSG_rcconf_restore_failed);
+				process_menu(MENU_ok, NULL);
+			} else {
+				msg_display(MSG_rcconf_delete_failed, value);
+				process_menu(MENU_ok, NULL);
+			}
+		} else {
+			(void)unlink(bakname);
+		}
+	}
+
+done:
+	(void)unlink(tempname);
+	free(rcconf);
+	free(tempname);
+	free(bakname);
+	return retval;
+}
+
 void
 add_sysctl_conf(const char *fmt, ...)
 {
@@ -1503,11 +1589,15 @@
 
 const char *
 set_dir_for_set(const char *set_name) {
+	if (strcmp(set_name, "pkgsrc") == 0)
+		return pkgsrc_dir;
 	return set_is_source(set_name) ? set_dir_src : set_dir_bin;
 }
 
 const char *
 ext_dir_for_set(const char *set_name) {
+	if (strcmp(set_name, "pkgsrc") == 0)
+		return ext_dir_pkgsrc;
 	return set_is_source(set_name) ? ext_dir_src : ext_dir_bin;
 }