xref: /netbsd/usr.sbin/sysinst/configmenu.c (revision 889f657f)
1*889f657fSsnj /* $NetBSD: configmenu.c,v 1.3 2015/01/20 21:51:05 snj Exp $ */
226165e63Sdholland 
326165e63Sdholland /*-
426165e63Sdholland  * Copyright (c) 2012 The NetBSD Foundation, Inc.
526165e63Sdholland  * All rights reserved.
626165e63Sdholland  *
726165e63Sdholland  * This code is derived from software contributed to The NetBSD Foundation
826165e63Sdholland  * by Jeffrey C. Rizzo
926165e63Sdholland  *
1026165e63Sdholland  * Redistribution and use in source and binary forms, with or without
1126165e63Sdholland  * modification, are permitted provided that the following conditions
1226165e63Sdholland  * are met:
1326165e63Sdholland  * 1. Redistributions of source code must retain the above copyright
1426165e63Sdholland  *    notice, this list of conditions and the following disclaimer.
1526165e63Sdholland  * 2. Redistributions in binary form must reproduce the above copyright
1626165e63Sdholland  *    notice, this list of conditions and the following disclaimer in the
1726165e63Sdholland  *    documentation and/or other materials provided with the distribution.
1826165e63Sdholland  *
1926165e63Sdholland  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2026165e63Sdholland  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2126165e63Sdholland  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2226165e63Sdholland  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2326165e63Sdholland  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2426165e63Sdholland  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2526165e63Sdholland  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2626165e63Sdholland  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2726165e63Sdholland  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2826165e63Sdholland  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2926165e63Sdholland  * POSSIBILITY OF SUCH DAMAGE.
3026165e63Sdholland  */
3126165e63Sdholland 
3226165e63Sdholland /* configmenu.c -- post-installation system configuration menu. */
3326165e63Sdholland 
3426165e63Sdholland #include <stdio.h>
3526165e63Sdholland #include <curses.h>
3626165e63Sdholland #include <unistd.h>
37da5a563bSmartin #include <errno.h>
3826165e63Sdholland #include "defs.h"
3926165e63Sdholland #include "msg_defs.h"
4026165e63Sdholland #include "menu_defs.h"
4126165e63Sdholland 
4226165e63Sdholland 
4326165e63Sdholland static int set_network(struct menudesc*, void *);
4426165e63Sdholland static int set_timezone_menu(struct menudesc *, void *);
4526165e63Sdholland static int set_root_shell(struct menudesc *, void *);
4626165e63Sdholland static int change_root_password(struct menudesc *, void *);
4726165e63Sdholland static int add_new_user(struct menudesc *, void *);
4826165e63Sdholland static int set_binpkg(struct menudesc *, void *);
4926165e63Sdholland static int set_pkgsrc(struct menudesc *, void *);
5026165e63Sdholland static void config_list_init(void);
5126165e63Sdholland static void get_rootsh(void);
5226165e63Sdholland static int toggle_rcvar(struct menudesc *, void *);
5326165e63Sdholland static void configmenu_hdr(struct menudesc *, void *);
5426165e63Sdholland static int check_root_password(void);
5526165e63Sdholland 
5626165e63Sdholland char pkgpath[STRSIZE];
5726165e63Sdholland char pkgsrcpath[STRSIZE];
5826165e63Sdholland 
5926165e63Sdholland extern const char *tz_default;
6026165e63Sdholland 
6126165e63Sdholland enum {
6226165e63Sdholland 	CONFIGOPT_NETCONF,
6326165e63Sdholland 	CONFIGOPT_TZ,
6426165e63Sdholland 	CONFIGOPT_ROOTSH,
6526165e63Sdholland 	CONFIGOPT_ROOTPW,
6626165e63Sdholland 	CONFIGOPT_BINPKG,
6726165e63Sdholland 	CONFIGOPT_PKGSRC,
6826165e63Sdholland 	CONFIGOPT_SSHD,
6926165e63Sdholland 	CONFIGOPT_NTPD,
7026165e63Sdholland 	CONFIGOPT_NTPDATE,
7126165e63Sdholland 	CONFIGOPT_MDNSD,
72da5a563bSmartin 	CONFIGOPT_XDM,
73da5a563bSmartin 	CONFIGOPT_CGD,
74da5a563bSmartin 	CONFIGOPT_LVM,
75da5a563bSmartin 	CONFIGOPT_RAIDFRAME,
7626165e63Sdholland 	CONFIGOPT_ADDUSER,
7726165e63Sdholland 	CONFIGOPT_LAST
7826165e63Sdholland };
7926165e63Sdholland 
8026165e63Sdholland typedef struct configinfo {
8126165e63Sdholland 	const char	*optname;
8226165e63Sdholland 	uint		opt;
8326165e63Sdholland 	const char	*rcvar;
8426165e63Sdholland 	int		(*action)(struct menudesc *, void *);
8526165e63Sdholland 	const char	*setting;
8626165e63Sdholland } configinfo;
8726165e63Sdholland 
8826165e63Sdholland 
8926165e63Sdholland configinfo config_list[] = {
9026165e63Sdholland 	{MSG_Configure_network, CONFIGOPT_NETCONF, NULL, set_network, MSG_configure},
9126165e63Sdholland 	{MSG_timezone, CONFIGOPT_TZ, NULL, set_timezone_menu, NULL},
9226165e63Sdholland 	{MSG_Root_shell, CONFIGOPT_ROOTSH, NULL, set_root_shell, NULL},
9326165e63Sdholland 	{MSG_change_rootpw, CONFIGOPT_ROOTPW, NULL, change_root_password, MSG_change},
94da5a563bSmartin 	{MSG_enable_binpkg, CONFIGOPT_BINPKG, NULL, set_binpkg, MSG_install},
9526165e63Sdholland 	{MSG_get_pkgsrc, CONFIGOPT_PKGSRC, NULL, set_pkgsrc, MSG_install},
9626165e63Sdholland 	{MSG_enable_sshd, CONFIGOPT_SSHD, "sshd", toggle_rcvar, NULL},
9726165e63Sdholland 	{MSG_enable_ntpd, CONFIGOPT_NTPD, "ntpd", toggle_rcvar, NULL},
9826165e63Sdholland 	{MSG_run_ntpdate, CONFIGOPT_NTPDATE, "ntpdate", toggle_rcvar, NULL},
9926165e63Sdholland 	{MSG_enable_mdnsd, CONFIGOPT_MDNSD, "mdnsd", toggle_rcvar, NULL},
100da5a563bSmartin 	{MSG_enable_xdm, CONFIGOPT_XDM, "xdm", toggle_rcvar, NULL},
101da5a563bSmartin 	{MSG_enable_cgd, CONFIGOPT_CGD, "cgd", toggle_rcvar, NULL},
102da5a563bSmartin 	{MSG_enable_lvm, CONFIGOPT_LVM, "lvm", toggle_rcvar, NULL},
103da5a563bSmartin 	{MSG_enable_raid, CONFIGOPT_RAIDFRAME, "raidframe", toggle_rcvar, NULL},
10426165e63Sdholland 	{MSG_add_a_user, CONFIGOPT_ADDUSER, NULL, add_new_user, ""},
10526165e63Sdholland 	{NULL,		CONFIGOPT_LAST,	NULL, NULL, NULL}
10626165e63Sdholland };
10726165e63Sdholland 
10826165e63Sdholland static void
10926165e63Sdholland config_list_init(void)
11026165e63Sdholland {
11126165e63Sdholland 	int i;
11226165e63Sdholland 
11326165e63Sdholland 	for (i=0; i < CONFIGOPT_LAST; i++) {
11426165e63Sdholland 		switch (i) {
11526165e63Sdholland 		case CONFIGOPT_TZ:
11626165e63Sdholland 			get_tz_default();
11726165e63Sdholland 			config_list[CONFIGOPT_TZ].setting = tz_default;
11826165e63Sdholland 			break;
11926165e63Sdholland 		case CONFIGOPT_ROOTSH:
12026165e63Sdholland 			get_rootsh();
12126165e63Sdholland 			break;
12226165e63Sdholland 		case CONFIGOPT_ROOTPW:
12326165e63Sdholland 			if (check_root_password())
12426165e63Sdholland 				config_list[i].setting = MSG_password_set;
12526165e63Sdholland 			else
12626165e63Sdholland 				config_list[i].setting = MSG_empty;
12726165e63Sdholland 			break;
12826165e63Sdholland 		default:
12926165e63Sdholland 			if (config_list[i].rcvar != NULL) {
13026165e63Sdholland 				if (check_rcvar(config_list[i].rcvar))
13126165e63Sdholland 					config_list[i].setting = MSG_YES;
13226165e63Sdholland 				else
13326165e63Sdholland 					config_list[i].setting = MSG_NO;
13426165e63Sdholland 			}
13526165e63Sdholland 			break;
13626165e63Sdholland 		}
13726165e63Sdholland 	}
13826165e63Sdholland }
13926165e63Sdholland 
14026165e63Sdholland static void
14126165e63Sdholland get_rootsh(void)
14226165e63Sdholland {
14326165e63Sdholland 	static char *buf = NULL;
14426165e63Sdholland 
14526165e63Sdholland 	if (buf != NULL)
14626165e63Sdholland 		free(buf);
14726165e63Sdholland 
14826165e63Sdholland 	if (target_already_root())
14926165e63Sdholland 		collect(T_OUTPUT, &buf,
15026165e63Sdholland 		    "/usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'"
15126165e63Sdholland 		    " /etc/passwd");
15226165e63Sdholland 	else
15326165e63Sdholland 		collect(T_OUTPUT, &buf,
15426165e63Sdholland 		    "chroot %s /usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'"
15526165e63Sdholland 		    " /etc/passwd",target_prefix());
15626165e63Sdholland 
15726165e63Sdholland 	config_list[CONFIGOPT_ROOTSH].setting = (const char *)buf;
15826165e63Sdholland }
15926165e63Sdholland 
16026165e63Sdholland static void
16126165e63Sdholland set_config(menudesc *menu, int opt, void *arg)
16226165e63Sdholland {
16326165e63Sdholland 	configinfo	**configp = arg;
16426165e63Sdholland 	configinfo	*config = configp[opt];
16526165e63Sdholland 	const char	*optname, *setting;
16626165e63Sdholland 
16726165e63Sdholland 	optname = config->optname;
16826165e63Sdholland 	setting = msg_string(config->setting);
16926165e63Sdholland 
17026165e63Sdholland 	wprintw(menu->mw, "%-50s %-10s", msg_string(optname), setting);
17126165e63Sdholland }
17226165e63Sdholland 
17326165e63Sdholland static int
17426165e63Sdholland init_config_menu(configinfo *conf, menu_ent *me, configinfo **ce)
17526165e63Sdholland {
17626165e63Sdholland 	int	opt;
17726165e63Sdholland 	int	configopts;
17826165e63Sdholland 
17926165e63Sdholland 	for (configopts = 0; ; conf++) {
18026165e63Sdholland 		opt = conf->opt;
18126165e63Sdholland 		if (opt == CONFIGOPT_LAST)
18226165e63Sdholland 			break;
18326165e63Sdholland 		*ce = conf;
18426165e63Sdholland 		me->opt_menu = OPT_NOMENU;
18526165e63Sdholland 		me->opt_flags = 0;
18626165e63Sdholland 		me->opt_name = NULL;  /* NULL so set_config will draw */
18726165e63Sdholland 		me->opt_action = conf->action;
18826165e63Sdholland 		configopts++;
18926165e63Sdholland 		ce++;
19026165e63Sdholland 		me++;
19126165e63Sdholland 	}
19226165e63Sdholland 
19326165e63Sdholland 	return configopts;
19426165e63Sdholland }
19526165e63Sdholland 
19626165e63Sdholland static int
19726165e63Sdholland /*ARGSUSED*/
19826165e63Sdholland set_timezone_menu(struct menudesc *menu, void *arg)
19926165e63Sdholland {
20026165e63Sdholland 	configinfo **confp = arg;
20126165e63Sdholland 	set_timezone();
20226165e63Sdholland 	get_tz_default();
20326165e63Sdholland 	confp[menu->cursel]->setting = tz_default;
20426165e63Sdholland 	return 0;
20526165e63Sdholland }
20626165e63Sdholland 
20726165e63Sdholland static int
20826165e63Sdholland set_root_shell(struct menudesc *menu, void *arg)
20926165e63Sdholland {
21026165e63Sdholland 	configinfo **confp = arg;
21126165e63Sdholland 
21226165e63Sdholland 	process_menu(MENU_rootsh, &confp[menu->cursel]->setting);
213da5a563bSmartin 	if (run_program(RUN_PROGRESS | RUN_CHROOT,
214da5a563bSmartin 		"chpass -s %s root", confp[menu->cursel]->setting) != 0)
215da5a563bSmartin 		confp[menu->cursel]->setting = MSG_failed;
21626165e63Sdholland 	return 0;
21726165e63Sdholland }
21826165e63Sdholland 
21926165e63Sdholland static int
22026165e63Sdholland set_network(struct menudesc *menu, void *arg)
22126165e63Sdholland {
22226165e63Sdholland 	network_up = 0;
22326165e63Sdholland 	if (config_network())
22426165e63Sdholland 		mnt_net_config();
22526165e63Sdholland 	return 0;
22626165e63Sdholland }
22726165e63Sdholland 
22826165e63Sdholland static int
22926165e63Sdholland check_root_password(void)
23026165e63Sdholland {
23126165e63Sdholland 	char *buf;
23226165e63Sdholland 	int rval;
23326165e63Sdholland 
23426165e63Sdholland 	if (target_already_root())
23526165e63Sdholland 		collect(T_OUTPUT, &buf, "getent passwd root | cut -d: -f2");
23626165e63Sdholland 	else
23726165e63Sdholland 		collect(T_OUTPUT, &buf, "chroot %s getent passwd root | "
23826165e63Sdholland 		    "chroot %s cut -d: -f2",
23926165e63Sdholland 		    target_prefix(), target_prefix());
24026165e63Sdholland 
24126165e63Sdholland 	if (logfp)
24226165e63Sdholland 		fprintf(logfp,"buf %s strlen(buf) %zu\n", buf, strlen(buf));
24326165e63Sdholland 
24426165e63Sdholland 	if (strlen(buf) <= 1)  /* newline */
24526165e63Sdholland 		rval = 0;
24626165e63Sdholland 	else
24726165e63Sdholland 		rval = 1;
24826165e63Sdholland 	free(buf);
24926165e63Sdholland 	return rval;
25026165e63Sdholland }
25126165e63Sdholland 
25226165e63Sdholland static int
25326165e63Sdholland add_new_user(struct menudesc *menu, void *arg)
25426165e63Sdholland {
255*889f657fSsnj 	char username[STRSIZE] = "";
25626165e63Sdholland 	int inwheel=0;
25726165e63Sdholland 
25826165e63Sdholland 	msg_prompt(MSG_addusername, NULL, username, sizeof username -1);
259*889f657fSsnj 	if (strlen(username) == 0)
260*889f657fSsnj 		return 0;
26126165e63Sdholland 	process_menu(MENU_yesno, deconst(MSG_addusertowheel));
26226165e63Sdholland 	inwheel = yesno;
26326165e63Sdholland 	ushell = "/bin/csh";
26426165e63Sdholland 	process_menu(MENU_usersh, NULL);
26526165e63Sdholland 	if (inwheel)
26626165e63Sdholland 		run_program(RUN_PROGRESS | RUN_CHROOT,
26726165e63Sdholland 		    "/usr/sbin/useradd -m -s %s -G wheel %s",
26826165e63Sdholland 		    ushell, username);
26926165e63Sdholland 	else
27026165e63Sdholland 		run_program(RUN_PROGRESS | RUN_CHROOT,
27126165e63Sdholland 		    "/usr/sbin/useradd -m -s %s %s", ushell, username);
27226165e63Sdholland 	run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
27326165e63Sdholland 	    "passwd -l %s", username);
27426165e63Sdholland 	return 0;
27526165e63Sdholland }
27626165e63Sdholland 
27726165e63Sdholland static int
27826165e63Sdholland change_root_password(struct menudesc *menu, void *arg)
27926165e63Sdholland {
28026165e63Sdholland 	configinfo **confp = arg;
28126165e63Sdholland 
28226165e63Sdholland 	msg_display(MSG_rootpw);
28326165e63Sdholland 	process_menu(MENU_yesno, NULL);
284da5a563bSmartin 	if (yesno) {
285da5a563bSmartin 		if (run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
286da5a563bSmartin 			"passwd -l root") == 0)
28726165e63Sdholland 			confp[menu->cursel]->setting = MSG_password_set;
288da5a563bSmartin 		else
289da5a563bSmartin 			confp[menu->cursel]->setting = MSG_failed;
290da5a563bSmartin 	}
29126165e63Sdholland 	return 0;
29226165e63Sdholland }
29326165e63Sdholland 
29426165e63Sdholland static int
29526165e63Sdholland set_binpkg(struct menudesc *menu, void *arg)
29626165e63Sdholland {
29726165e63Sdholland 	configinfo **confp = arg;
298da5a563bSmartin 	char additional_pkgs[STRSIZE] = {0};
29926165e63Sdholland 	char pattern[STRSIZE];
300da5a563bSmartin 	int allok = 0;
30126165e63Sdholland 
302da5a563bSmartin 	do {
303da5a563bSmartin 		yesno = -1;
304da5a563bSmartin 		process_menu(MENU_binpkg, additional_pkgs);
305da5a563bSmartin 		if (yesno == SET_SKIP) {
306da5a563bSmartin 			confp[menu->cursel]->setting = MSG_abandoned;
30726165e63Sdholland 			return 0;
30826165e63Sdholland 		}
30926165e63Sdholland 
310da5a563bSmartin 		make_url(pkgpath, &pkg, pkg_dir);
311da5a563bSmartin 		if (run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
312da5a563bSmartin 			"pkg_add %s/pkgin", pkgpath) == 0) {
313da5a563bSmartin 			allok = 1;
314da5a563bSmartin 		}
315da5a563bSmartin 	} while (allok == 0);
316da5a563bSmartin 
31726165e63Sdholland 	/* configure pkgin to use $pkgpath as a repository */
31826165e63Sdholland 	snprintf(pattern, STRSIZE, "s,^[^#].*$,%s,", pkgpath);
31926165e63Sdholland 	replace("/usr/pkg/etc/pkgin/repositories.conf", pattern);
32026165e63Sdholland 
32126165e63Sdholland 	run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
32226165e63Sdholland 		"/usr/pkg/bin/pkgin -y update");
32326165e63Sdholland 
324da5a563bSmartin 	if (strlen(additional_pkgs) > 0)
325da5a563bSmartin 		run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
326da5a563bSmartin 		"/usr/pkg/bin/pkgin -y install %s", additional_pkgs);
327da5a563bSmartin 
32826165e63Sdholland 	msg_display(MSG_binpkg_installed);
32926165e63Sdholland 	process_menu(MENU_ok, NULL);
33026165e63Sdholland 
33126165e63Sdholland 	confp[menu->cursel]->setting = MSG_DONE;
33226165e63Sdholland 	return 0;
33326165e63Sdholland }
33426165e63Sdholland 
33526165e63Sdholland static int
33626165e63Sdholland set_pkgsrc(struct menudesc *menu, void *arg)
33726165e63Sdholland {
33826165e63Sdholland 	configinfo **confp = arg;
33926165e63Sdholland 	distinfo dist;
34026165e63Sdholland 
34126165e63Sdholland 	dist.name = "pkgsrc";
34226165e63Sdholland 	dist.set = SET_PKGSRC;
34326165e63Sdholland 	dist.desc = "source for 3rd-party packages";
34426165e63Sdholland 	dist.marker_file = NULL;
34526165e63Sdholland 
34626165e63Sdholland 	int status = SET_RETRY;
34726165e63Sdholland 
34826165e63Sdholland 	do {
34926165e63Sdholland 		status = get_pkgsrc();
35026165e63Sdholland 		if (status == SET_OK) {
35126165e63Sdholland 			status = extract_file(&dist, 0);
35226165e63Sdholland 			continue;
35326165e63Sdholland 		} else if (status == SET_SKIP) {
35426165e63Sdholland 			confp[menu->cursel]->setting = MSG_abandoned;
35526165e63Sdholland 			return 0;
35626165e63Sdholland 		}
35726165e63Sdholland 		process_menu(MENU_yesno, deconst(MSG_retry_pkgsrc_network));
35826165e63Sdholland 		if (!yesno) {
35926165e63Sdholland 			confp[menu->cursel]->setting = MSG_abandoned;
36026165e63Sdholland 			return 1;
36126165e63Sdholland 		}
36226165e63Sdholland 	}
36326165e63Sdholland 	while (status == SET_RETRY);
36426165e63Sdholland 
36526165e63Sdholland 	confp[menu->cursel]->setting = MSG_DONE;
36626165e63Sdholland 	return 0;
36726165e63Sdholland }
36826165e63Sdholland 
36926165e63Sdholland static int
37026165e63Sdholland toggle_rcvar(struct menudesc *menu, void *arg)
37126165e63Sdholland {
37226165e63Sdholland 	configinfo **confp = arg;
37326165e63Sdholland 	int s;
37426165e63Sdholland 	const char *setting, *varname;
37526165e63Sdholland 	char pattern[STRSIZE];
37626165e63Sdholland 	char buf[STRSIZE];
37726165e63Sdholland 	char *cp;
37826165e63Sdholland 	int found = 0;
37926165e63Sdholland 	FILE *fp;
38026165e63Sdholland 
38126165e63Sdholland 	varname = confp[menu->cursel]->rcvar;
38226165e63Sdholland 
38326165e63Sdholland 	s = check_rcvar(varname);
38426165e63Sdholland 
38526165e63Sdholland 	/* we're toggling, so invert the sense */
38626165e63Sdholland 	if (s) {
38726165e63Sdholland 		confp[menu->cursel]->setting = MSG_NO;
38826165e63Sdholland 		setting = "NO";
38926165e63Sdholland 	} else {
39026165e63Sdholland 		confp[menu->cursel]->setting = MSG_YES;
39126165e63Sdholland 		setting = "YES";
39226165e63Sdholland 	}
39326165e63Sdholland 
39426165e63Sdholland 	if (!(fp = fopen(target_expand("/etc/rc.conf"), "r"))) {
395da5a563bSmartin 		msg_display(MSG_openfail, target_expand("/etc/rc.conf"), strerror(errno));
39626165e63Sdholland 		process_menu(MENU_ok, NULL);
397da5a563bSmartin 		return 0;
39826165e63Sdholland 	}
39926165e63Sdholland 
40026165e63Sdholland 	while (fgets(buf, sizeof buf, fp) != NULL) {
40126165e63Sdholland 		cp = buf + strspn(buf, " \t"); /* Skip initial spaces */
40226165e63Sdholland 		if (strncmp(cp, varname, strlen(varname)) == 0) {
40326165e63Sdholland 			cp += strlen(varname);
40426165e63Sdholland 			if (*cp != '=')
40526165e63Sdholland 				continue;
40626165e63Sdholland 			buf[strlen(buf) - 1] = 0;
40726165e63Sdholland 			snprintf(pattern, sizeof pattern,
40826165e63Sdholland 					"s,^%s$,%s=%s,",
40926165e63Sdholland 					buf, varname, setting);
41026165e63Sdholland 			found = 1;
41126165e63Sdholland 			break;
41226165e63Sdholland 		}
41326165e63Sdholland 	}
41426165e63Sdholland 
41526165e63Sdholland 	fclose(fp);
41626165e63Sdholland 
41726165e63Sdholland 	if (!found) {
41826165e63Sdholland 		add_rc_conf("%s=%s\n", varname, setting);
41926165e63Sdholland 		if (logfp) {
42026165e63Sdholland 			fprintf(logfp, "adding %s=%s\n", varname, setting);
42126165e63Sdholland 			fflush(logfp);
42226165e63Sdholland 		}
42326165e63Sdholland 	} else {
42426165e63Sdholland 		if (logfp) {
42526165e63Sdholland 			fprintf(logfp, "replacement pattern is %s\n", pattern);
42626165e63Sdholland 			fflush(logfp);
42726165e63Sdholland 		}
42826165e63Sdholland 		replace("/etc/rc.conf", pattern);
42926165e63Sdholland 	}
43026165e63Sdholland 
43126165e63Sdholland 	return 0;
43226165e63Sdholland }
43326165e63Sdholland 
43426165e63Sdholland static void
43526165e63Sdholland configmenu_hdr(struct menudesc *menu, void *arg)
43626165e63Sdholland {
43726165e63Sdholland 	msg_display(MSG_configmenu);
43826165e63Sdholland }
43926165e63Sdholland 
44026165e63Sdholland void
44126165e63Sdholland do_configmenu()
44226165e63Sdholland {
44326165e63Sdholland 	int		menu_no;
44426165e63Sdholland 	int		opts;
44526165e63Sdholland 	menu_ent	me[CONFIGOPT_LAST];
44626165e63Sdholland 	configinfo	*ce[CONFIGOPT_LAST];
44726165e63Sdholland 
44826165e63Sdholland 	/* if the target isn't mounted already, figure it out. */
44926165e63Sdholland 	if (target_mounted() == 0) {
450da5a563bSmartin 		partman_go = 0;
45126165e63Sdholland 		if (find_disks(msg_string(MSG_configure_prior)) < 0)
45226165e63Sdholland 			return;
45326165e63Sdholland 
45426165e63Sdholland 		if (mount_disks() != 0)
45526165e63Sdholland 			return;
45626165e63Sdholland 	}
45726165e63Sdholland 
45826165e63Sdholland 	config_list_init();
45926165e63Sdholland 	make_url(pkgpath, &pkg, pkg_dir);
46026165e63Sdholland 	opts = init_config_menu(config_list, me, ce);
46126165e63Sdholland 
462da5a563bSmartin 	wrefresh(curscr);
463da5a563bSmartin 	wmove(stdscr, 0, 0);
464da5a563bSmartin 	wclear(stdscr);
465da5a563bSmartin 	wrefresh(stdscr);
466da5a563bSmartin 
46726165e63Sdholland 	menu_no = new_menu(NULL, me, opts, 0, -4, 0, 70,
46826165e63Sdholland 		MC_SCROLL | MC_NOBOX | MC_DFLTEXIT,
46926165e63Sdholland 		configmenu_hdr, set_config, NULL, "XXX Help String",
47026165e63Sdholland 		MSG_doneconfig);
47126165e63Sdholland 
47226165e63Sdholland 	process_menu(menu_no, ce);
47326165e63Sdholland 	free_menu(menu_no);
47426165e63Sdholland }
475