Home | History | Annotate | Line # | Download | only in sysinst
menus.mi revision 1.21
      1 /*	$NetBSD: menus.mi,v 1.21 2020/01/27 21:21:22 martin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by David Laight.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Menu system definitions -- machine and language independent
     34  *
     35  * Some menus may be called directly in the code rather than via the
     36  * menu system.
     37  *
     38  *  This file must be first in the sed command line.
     39  *
     40  */
     41 
     42 {
     43 #include <stdio.h>
     44 #include <time.h>
     45 #include <curses.h>
     46 #include "defs.h"
     47 #include "md.h"
     48 #include "msg_defs.h"
     49 #include "menu_defs.h"
     50 
     51 static menudesc menu_def[];
     52 
     53 static void
     54 expand_option_text(menudesc *menu, void *arg, int sel)
     55 {
     56 	arg_replace *ar = arg;
     57 	struct menu_ent *opt = &menu->opts[sel];
     58 
     59 	if (menu->opts[sel].opt_exp_name)
     60 		return;	/* has already been expanded */
     61 
     62 	opt->opt_exp_name =
     63 	    str_arg_subst(MSG_XLAT(opt->opt_name), ar->argc, ar->argv);
     64 }
     65 
     66 void
     67 expand_all_option_texts(menudesc *menu, void *arg)
     68 {
     69 	arg_replace *ar = arg;
     70 	const char *title;
     71 	int i;
     72 
     73 	if (menu->title != NULL && menu->exp_title == NULL) {
     74 		title = MSG_XLAT(menu->title);
     75 		if (needs_expanding(title, ar->argc)) {
     76 			menu->exp_title = str_arg_subst(title,
     77 			    ar->argc, ar->argv);
     78 		}
     79 	}
     80 	for (i = 0; i < menu->numopts; i++) {
     81 		const char *t = MSG_XLAT(menu->opts[i].opt_name);
     82 
     83 		if (t == NULL) continue;
     84 
     85 		if (needs_expanding(t, ar->argc))
     86 			expand_option_text(menu, arg, i);
     87 	}
     88 }
     89 
     90 /*
     91  * Re-create the menu window with heigh/width updated to current state.
     92  */
     93 void
     94 resize_menu_height(menudesc *m)
     95 {
     96 
     97 	if (m->mw == NULL)
     98 		return;
     99 
    100 	wclear(m->mw);
    101 	if (m->sv_mw) {
    102 		overwrite(m->sv_mw, m->mw);
    103 		delwin(m->sv_mw);
    104 		m->sv_mw = NULL;
    105 	}
    106 	wnoutrefresh(m->mw);
    107 	delwin(m->mw);
    108 	m->mw = NULL;
    109 }
    110 
    111 static void
    112 src_legend(menudesc *menu, const char *legend, const char *text)
    113 {
    114         wprintw(menu->mw, "%-35s %.50s", MSG_XLAT(legend), MSG_XLAT(text));
    115 }
    116 
    117 static void
    118 src_prompt(const char *prompt, char *buf, size_t size)
    119 {
    120 	msg_prompt_win(prompt, -1, 12, 0, 0, buf, buf, size);
    121 }
    122 
    123 static void
    124 remove_sub_menu(int menuID)
    125 {
    126 
    127 	for (size_t i = 0; i < DYN_MENU_START; i++) {
    128 		for (int j = 0; j < menu_def[i].numopts; j++) {
    129 			if ((menu_def[i].opts[j].opt_flags & OPT_SUB)
    130 			    && menu_def[i].opts[j].opt_menu == menuID) {
    131 
    132 				for (int k = j + 1; k < menu_def[i].numopts;
    133 				    k++) {
    134 					menu_def[i].opts[k-1] =
    135 					    menu_def[i].opts[k];
    136 				}
    137 				menu_def[i].numopts--;
    138 				return;
    139 
    140 			}
    141 		}
    142 	}
    143 }
    144 
    145 #ifndef NO_PARTMAN
    146 static void
    147 remove_menu_option(int menuID, const char *option)
    148 {
    149 
    150 	for (int j = 0; j < menu_def[menuID].numopts; j++) {
    151 		if (menu_def[menuID].opts[j].opt_name == option) {
    152 			for (int k = j + 1; k < menu_def[menuID].numopts;
    153 			    k++) {
    154 				menu_def[menuID].opts[k-1] =
    155 				    menu_def[menuID].opts[k];
    156 			}
    157 			menu_def[menuID].numopts--;
    158 			return;
    159 
    160 		}
    161 	}
    162 }
    163 #endif
    164 
    165 void
    166 remove_color_options()
    167 {
    168 	/*
    169 	 * Current terminal type does not support colors, so remove all
    170 	 * menu entries (actually that is: Utils/Color Scheme) that do not
    171 	 * make any sense in this case.
    172 	 */
    173 	remove_sub_menu(MENU_colors);
    174 }
    175 
    176 #ifndef NO_PARTMAN
    177 void
    178 remove_raid_options()
    179 {
    180 	/*
    181 	 * No raidframe available, remove the following menu entries:
    182 	 */
    183 	remove_menu_option(MENU_pmdiskentry, MSG_fmtasraid);
    184 	remove_menu_option(MENU_pmpartentry, MSG_fmtasraid);
    185 }
    186 
    187 void
    188 remove_lvm_options()
    189 {
    190 	/*
    191 	 * No LVM available, remove the following menu entries:
    192 	 */
    193 	remove_menu_option(MENU_pmdiskentry, MSG_fmtaslvm);
    194 	remove_menu_option(MENU_pmpartentry, MSG_fmtaslvm);
    195 }
    196 
    197 void
    198 remove_cgd_options()
    199 {
    200 	/*
    201 	 * No CGD available, remove the following menu entries:
    202 	 */
    203 	remove_menu_option(MENU_pmdiskentry, MSG_encrypt);
    204 	remove_menu_option(MENU_pmpartentry, MSG_encrypt);
    205 }
    206 #endif
    207 
    208 }
    209 
    210 default y=12, no exit, scrollable;
    211 
    212 allow dynamic menus;
    213 allow dynamic messages;
    214 allow expand;
    215 
    216 error action {
    217 	fprintf (stderr, "Could not initialize menu system, please check "
    218 	    "your terminal type.\n");
    219 	exit(4);
    220 };
    221 
    222 /*
    223  * Called with arg = struct single_part_fs_edit*
    224  */
    225 menu mountoptions, title MSG_toggle, y=5, x=30, exitstring MSG_unchanged;
    226 	/*
    227 	 *  XXX - enable / disable options depending on FS type in
    228 	 *  display action
    229 	*/
    230 	option "log", exit, action
    231 		{ struct single_part_fs_edit *edit = arg;
    232 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_LOG; };
    233 	option "async", exit, action
    234 		{ struct single_part_fs_edit *edit = arg;
    235 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_ASYNC; };
    236 	option "noatime", exit, action
    237 		{ struct single_part_fs_edit *edit = arg;
    238 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOATIME; };
    239 	option "nodev", exit, action
    240 		{ struct single_part_fs_edit *edit = arg;
    241 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NODEV; };
    242 	option "nodevmtime", exit, action
    243 		{ struct single_part_fs_edit *edit = arg;
    244 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NODEVMTIME; };
    245 	option "noexec", exit, action
    246 		{ struct single_part_fs_edit *edit = arg;
    247 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOEXEC; };
    248 	option "nosuid", exit, action
    249 		{ struct single_part_fs_edit *edit = arg;
    250 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOSUID; };
    251 	option "noauto", exit, action
    252 		{ struct single_part_fs_edit *edit = arg;
    253 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOAUTO; };
    254 
    255 menu netbsd, title MSG_NetBSD_VERSION_Install_System, y=-1,
    256     exit, exitstring MSG_Exit_Install_System;
    257 	display action  { toplevel(); };
    258 	option MSG_Install_NetBSD_to_hard_disk,
    259 		action { do_install(); };
    260 	option MSG_Upgrade_NetBSD_on_a_hard_disk,
    261 		action { do_upgrade(); };
    262 	option MSG_Re_install_sets_or_install_additional_sets,
    263 		action { do_reinstall_sets(); };
    264 	option MSG_Reboot_the_computer, exit,
    265 		action (endwin) { system("/sbin/reboot -q"); };
    266 	option MSG_Utility_menu, sub menu utility;
    267 	option MSG_Config_menu, action { do_configmenu(NULL); };
    268 
    269 menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
    270 		exitstring MSG_exit_menu_generic;
    271 	display action  { toplevel(); };
    272 	option MSG_Run_bin_sh,
    273 		action (endwin) { system("/bin/sh"); };
    274 	option MSG_Set_timezone,
    275 		action { set_timezone(); };
    276 	option MSG_Configure_network,
    277 		action {
    278 			extern int network_up;
    279 			network_up = 0;
    280 			config_network();
    281 		};
    282 	option MSG_Partition_a_disk,
    283 		action {
    284 #ifndef NO_PARTMAN
    285 			partman_go = 1;
    286 			partman();
    287 #endif
    288 		};
    289 	option MSG_Logging_functions, action { do_logging(); };
    290 	option MSG_Color_scheme, sub menu colors;
    291 	option MSG_Halt_the_system, exit,
    292 		action (endwin) { system("/sbin/halt -q"); };
    293 
    294 menu colors, title MSG_Color_scheme, exit,
    295 		exitstring MSG_exit_menu_generic;
    296 	option MSG_White_on_black, action { do_coloring(COLOR_WHITE,COLOR_BLACK); };
    297 	option MSG_Black_on_white, action { do_coloring(COLOR_BLACK,COLOR_WHITE); };
    298 	option MSG_White_on_blue,  action { do_coloring(COLOR_WHITE,COLOR_BLUE); };
    299 	option MSG_Green_on_black, action { do_coloring(COLOR_GREEN,COLOR_BLACK); };
    300 
    301 
    302 menu yesno, y=-10;
    303 	display action { arg_rv *p = arg;
    304 		menu->title = p->arg ? p->arg : MSG_yes_or_no; };
    305 	option MSG_Yes, exit, action  { ((arg_rv*)arg)->rv = 1; };
    306 	option MSG_No,  exit, action  { ((arg_rv*)arg)->rv = 0; };
    307 
    308 menu noyes, y=-10;
    309 	display action { arg_rv *p = arg;
    310 		menu->title = p->arg ? p->arg : MSG_yes_or_no; };
    311 	option MSG_No,  exit, action  { ((arg_rv*)arg)->rv = 0; };
    312 	option MSG_Yes, exit, action  { ((arg_rv*)arg)->rv = 1; };
    313 
    314 menu ok, no shortcut, y=-10;
    315 	display action { menu->title = arg; };
    316 	option MSG_Hit_enter_to_continue, exit;
    317 
    318 menu sizechoice, sub menu, y=0, title MSG_Choose_your_size_specifier;
    319 	display action {
    320 		if (sizemult == pm->current_cylsize)
    321 			menu->cursel = 2;
    322 		else if (sizemult == 1)
    323 			menu->cursel = 3;
    324 		else if (sizemult == (GIG/pm->sectorsize))
    325 			menu->cursel = 0;
    326 		else
    327 			menu->cursel = 1; };
    328 	option MSG_Gigabytes, exit, action
    329 		{ set_sizemult(GIG, pm->sectorsize); };
    330 	option MSG_Megabytes, exit, action
    331 		{ set_sizemult(MEG, pm->sectorsize); };
    332 	option MSG_Cylinders, exit, action
    333 		{ set_sizemult(pm->current_cylsize*pm->sectorsize, pm->sectorsize); };
    334 	option MSG_Sectors, exit, action
    335 		{ set_sizemult(pm->sectorsize, pm->sectorsize); };
    336 
    337 menu ptnsize_replace_existing_partition, sub menu, y=0,
    338 	title MSG_ptnsize_replace_existing;
    339 	display action { menu->cursel = 1; };
    340 	option MSG_Yes, exit, action { *((int*)arg) = 1; };
    341 	option MSG_cancel, exit, action { *((int*)arg) = 0; };
    342 
    343 menu distmedium, title MSG_Select_medium, y=-5;
    344 	option MSG_cdrom,     exit, action { *(int *)arg = get_via_cdrom(); };
    345 	option MSG_http,      exit, action { *(int *)arg = get_via_ftp(XFER_HTTP); };
    346 	option MSG_ftp,	      exit, action { *(int *)arg = get_via_ftp(XFER_FTP); };
    347 	option MSG_nfs,	      exit, action { *(int *)arg = get_via_nfs(); };
    348 	option MSG_floppy,    exit, action { *(int *)arg = get_via_floppy(); };
    349 	option MSG_local_fs,  exit, action { *(int *)arg = get_via_localfs(); };
    350 	option MSG_local_dir, exit, action { *(int *)arg = get_via_localdir();};
    351 	option MSG_Skip_set,  exit, action { *(int *)arg = SET_SKIP; };
    352 	option MSG_Skip_group,exit, action { *(int *)arg = SET_SKIP_GROUP; };
    353 	option MSG_Abandon,   exit, action { *(int *)arg = SET_ABANDON; };
    354 
    355 menu distset, title MSG_Select_your_distribution, exit,
    356 	    no default exit, exitstring MSG_Abandon;
    357 	display action { msg_display (MSG_distset); };
    358 	option MSG_Full_installation, exit, action { *(int *)arg = 1; init_set_status(0);  };
    359 	option MSG_Full_installation_nox, exit, action { *(int *)arg = 1; init_set_status(SFLAG_NOX); };
    360 	option MSG_Minimal_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); };
    361 	option MSG_Custom_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); customise_sets(); };
    362 
    363 menu ftpsource, y=-4, x=0, w=70, no box, no clear,
    364 	    exitstring MSG_Get_Distribution;
    365 	display action { msg_fmt_display(MSG_ftpsource, "%s",
    366 	    url_proto((uintptr_t)((arg_rv*)arg)->arg)); };
    367 	option {src_legend(menu, MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]);},
    368 		action { src_prompt(MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg], sizeof ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]); };
    369 	option {src_legend(menu, MSG_Base_dir, ftp.dir);},
    370 		action { src_prompt(MSG_Base_dir, ftp.dir, sizeof ftp.dir); };
    371 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    372 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    373 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    374 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    375 	option {src_legend(menu, MSG_User, ftp.user);},
    376 		action { src_prompt(MSG_User, ftp.user, sizeof ftp.user);
    377 			ftp.pass[0] = 0;
    378 		};
    379 	option {src_legend(menu, MSG_Password,
    380 		    strcmp(ftp.user, "ftp") == 0 || ftp.pass[0] == 0
    381 			? ftp.pass : msg_string(MSG_hidden));},
    382 		action { if (strcmp(ftp.user, "ftp") == 0)
    383 			src_prompt(MSG_email, ftp.pass, sizeof ftp.pass);
    384 		  else {
    385 			msg_prompt_noecho(MSG_Password, "",
    386 					ftp.pass, sizeof ftp.pass);
    387 		  }
    388 		};
    389 	option {src_legend(menu, MSG_Proxy, ftp.proxy);},
    390 		action { src_prompt(MSG_Proxy, ftp.proxy, sizeof ftp.proxy);
    391 		  if (strcmp(ftp.proxy, "") == 0) {
    392 			unsetenv("ftp_proxy");
    393 			unsetenv("http_proxy");
    394 		  } else {
    395 			setenv("ftp_proxy", ftp.proxy, 1);
    396 			setenv("http_proxy", ftp.proxy, 1);
    397 		  }
    398 		};
    399 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    400 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    401 	option {src_legend(menu, MSG_delete_xfer_file,
    402 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    403 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    404 	option MSG_Configure_network,
    405 		action {
    406 			extern int network_up;
    407 			network_up = 0;
    408 			config_network();
    409 		};
    410 	option MSG_exit_menu_generic, exit, action { ((arg_rv*)arg)->rv = SET_RETRY; };
    411 
    412 
    413 menu nfssource, y=-4, x=0, w=70, no box, no clear,
    414 	    exitstring MSG_Get_Distribution;
    415 	display action { msg_display(MSG_nfssource); };
    416 	option {src_legend(menu, MSG_Host, nfs_host);},
    417 		action { src_prompt(MSG_Host, nfs_host, sizeof nfs_host); };
    418 	option {src_legend(menu, MSG_Base_dir, nfs_dir);},
    419 		action { src_prompt(MSG_Base_dir, nfs_dir, sizeof nfs_dir); };
    420 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    421 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    422 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    423 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    424 	option MSG_Configure_network,
    425 		action {
    426 			extern int network_up;
    427 			network_up = 0;
    428 			config_network();
    429 		};
    430 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    431 
    432 menu fdremount, title MSG_What_do_you_want_to_do;
    433 	option MSG_Try_again, exit, action { *(int *)arg = SET_CONTINUE; };
    434 	option MSG_Set_finished, exit, action { *(int *)arg = SET_OK; };
    435 	option MSG_Abort_fetch, exit, action { *(int *)arg = SET_RETRY; };
    436 
    437 menu fdok, title MSG_What_do_you_want_to_do;
    438 	option MSG_OK, exit, action { *(int *)arg = SET_CONTINUE; };
    439 	option MSG_Set_finished, exit, action { *(int *)arg = SET_OK; };
    440 	option MSG_Abort_fetch, exit, action { *(int *)arg = SET_RETRY; };
    441 
    442 menu fd_type, title MSG_fd_type, y=16;
    443 	option "msdos", exit, action { fd_type = "msdos"; };
    444 	option "ffs",   exit, action { fd_type = "ffs"; };
    445 .if ADOS_FLOPPY
    446 	option "ados",  exit, action { fd_type = "ados"; };
    447 .endif
    448 
    449 menu floppysource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    450 	display action { msg_display(MSG_floppysource); };
    451 	option {src_legend(menu, MSG_Device, fd_dev);},
    452 		action { src_prompt(MSG_dev, fd_dev, sizeof fd_dev); };
    453 	option {src_legend(menu, MSG_fd_type, fd_type);}, sub menu fd_type;
    454 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    455 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    456 	option {src_legend(menu, MSG_delete_xfer_file,
    457 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    458 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    459 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    460 
    461 menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    462 	display action { msg_display(MSG_cdromsource); };
    463 	option {src_legend(menu, MSG_Device, cdrom_dev);},
    464 		action { src_prompt(MSG_dev, cdrom_dev, sizeof cdrom_dev); };
    465 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    466 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    467 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    468 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    469 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    470 
    471 menu localfssource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    472 	display action { msg_display(MSG_localfssource); };
    473 	option {src_legend(menu, MSG_Device, localfs_dev);},
    474 		action { src_prompt(MSG_dev, localfs_dev, sizeof localfs_dev);};
    475 	option {src_legend(menu, MSG_File_system, localfs_fs);},
    476 		action { src_prompt(MSG_filesys, localfs_fs, sizeof localfs_fs); };
    477 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    478 		action { src_prompt(MSG_Base_dir, localfs_dir, sizeof localfs_dir);};
    479 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    480 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    481 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    482 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    483 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    484 
    485 menu localdirsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    486 	display action { msg_display(MSG_localdir); };
    487 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    488 		action { src_prompt(MSG_Base_dir, localfs_dir, 60); };
    489 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    490 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, 60); };
    491 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    492 		action { src_prompt(MSG_Set_dir_src, set_dir_src, 60); };
    493 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    494 
    495 menu namesrv6, title MSG_Select_DNS_server;
    496 	option "google-public-dns-a.google.com (IPv4)", exit, action
    497 		{
    498 #ifdef INET6
    499 		  strlcpy(net_namesvr, "8.8.8.8",
    500 		      sizeof(net_namesvr));
    501 		  *((int*)arg) = 1;
    502 #else
    503 		  *((int*)arg) = 0;
    504 #endif
    505 		};
    506 	option "google-public-dns-b.google.com (IPv4)", exit, action
    507 		{
    508 #ifdef INET6
    509 		  strlcpy(net_namesvr, "8.8.4.4",
    510 		      sizeof(net_namesvr));
    511 		  *((int*)arg) = 1;
    512 #else
    513 		  *((int*)arg) = 0;
    514 #endif
    515 		};
    516 	option "google-public-dns-a.google.com (IPv6)", exit, action
    517 		{
    518 #ifdef INET6
    519 		  strlcpy(net_namesvr, "2001:4860:4860::8888",
    520 		      sizeof(net_namesvr));
    521 		  *((int*)arg) = 1;
    522 #else
    523 		  *((int*)arg) = 0;
    524 #endif
    525 		};
    526 	option "google-public-dns-b.google.com (IPv6)", exit, action
    527 		{
    528 #ifdef INET6
    529 		  strlcpy(net_namesvr, "2001:4860:4860::8844",
    530 		      sizeof(net_namesvr));
    531 		  *((int*)arg) = 1;
    532 #else
    533 		  *((int*)arg) = 0;
    534 #endif
    535 		};
    536 	option MSG_other, exit, action
    537 		{ *((int*)arg) = 0; };
    538 
    539 menu rootsh, title MSG_Root_shell, no clear;
    540 	option "/bin/sh",  exit, action {*(const char **)arg = "/bin/sh";};
    541 	option "/bin/ksh", exit, action {*(const char **)arg = "/bin/ksh";};
    542 	option "/bin/csh", exit, action {*(const char **)arg = "/bin/csh";};
    543 
    544 menu zeroconf, title "Zeroconf", no clear;
    545 	option "run mdnsd only", exit, action {*(const char **)arg = "mdnsd";};
    546 	option "run mdnsd and resolve local names", exit, action {*(const char **) arg = "mdnsd+nsswitch";};
    547 	option "do not run mdnsd", exit, action {*(const char **)arg = "No";};
    548 
    549 menu binpkg, y=-4, x=0, w=70, no box, no clear,
    550 	    exitstring MSG_Install_pkgin;
    551 	display action { msg_display(MSG_pkgpath); };
    552 	option {src_legend(menu, MSG_Host, pkg.xfer_host[pkg.xfer]);},
    553 		action { src_prompt(MSG_Host, pkg.xfer_host[pkg.xfer], sizeof pkg.xfer_host[pkg.xfer]); };
    554 	option {src_legend(menu, MSG_Base_dir, pkg.dir);},
    555 		action { src_prompt(MSG_Base_dir, pkg.dir, sizeof pkg.dir); };
    556 	option {src_legend(menu, MSG_Pkg_dir, pkg_dir);},
    557 		action { src_prompt(MSG_Pkg_dir, pkg_dir, sizeof pkg_dir); };
    558 	option {src_legend(menu, MSG_User, pkg.user);},
    559 		action { src_prompt(MSG_User, pkg.user, sizeof pkg.user);
    560 			pkg.pass[0] = 0;
    561 		};
    562 	option {src_legend(menu, MSG_Password,
    563 		    strcmp(pkg.user, "ftp") == 0 || pkg.pass[0] == 0
    564 			? pkg.pass : msg_string(MSG_hidden));},
    565 		action { if (strcmp(pkg.user, "ftp") == 0)
    566 			src_prompt(MSG_email, pkg.pass, sizeof pkg.pass);
    567 		  else {
    568 			msg_prompt_noecho(MSG_Password, "",
    569 					pkg.pass, sizeof pkg.pass);
    570 		  }
    571 		};
    572 	option {src_legend(menu, MSG_Proxy, pkg.proxy);},
    573 		action { src_prompt(MSG_Proxy, pkg.proxy, sizeof pkg.proxy);
    574 		  if (strcmp(pkg.proxy, "") == 0) {
    575 			unsetenv("ftp_proxy");
    576 			unsetenv("http_proxy");
    577 		  } else {
    578 			setenv("ftp_proxy", pkg.proxy, 1);
    579 			setenv("http_proxy", pkg.proxy, 1);
    580 		  }
    581 		};
    582 	option {src_legend(menu, "Additional packages", (char*)(((arg_rv*)arg)->arg)); }, /*TODO*/
    583 		action { src_prompt("Additional packages", (char*)(((arg_rv*)arg)->arg),
    584 			 sizeof(char) * STRSIZE); };
    585 	option MSG_Configure_network,
    586 		action {
    587 			extern int network_up;
    588 			network_up = 0;
    589 			config_network();
    590 			mnt_net_config();
    591 		};
    592 	option {src_legend(menu, MSG_transfer_method, url_proto(pkg.xfer));},
    593 		action { pkg.xfer = (pkg.xfer+1) % (XFER_MAX+1); };
    594 	option MSG_quit_pkgs_install, exit, action { ((arg_rv*)arg)->rv = SET_SKIP; };
    595 
    596 menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
    597 	    exit, exitstring MSG_Install_pkgsrc;
    598 	display action { msg_display(MSG_pkgsrc); };
    599 	option {src_legend(menu, MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer]);},
    600 		action { src_prompt(MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer],
    601 			sizeof pkgsrc.xfer_host[pkgsrc.xfer]); };
    602 	option {src_legend(menu, MSG_Pkgsrc_dir, pkgsrc_dir);},
    603 		action { src_prompt(MSG_Pkgsrc_dir, pkgsrc_dir, sizeof pkgsrc_dir); };
    604 	option {src_legend(menu, MSG_User, pkgsrc.user);},
    605 		action { src_prompt(MSG_User, pkgsrc.user, sizeof pkgsrc.user);
    606 			pkgsrc.pass[0] = 0;
    607 		};
    608 	option {src_legend(menu, MSG_Password,
    609 		    strcmp(pkgsrc.user, "ftp") == 0 || pkgsrc.pass[0] == 0
    610 			? pkgsrc.pass : msg_string(MSG_hidden));},
    611 		action { if (strcmp(pkgsrc.user, "ftp") == 0)
    612 			src_prompt(MSG_email, pkgsrc.pass, sizeof pkgsrc.pass);
    613 		  else {
    614 			msg_prompt_noecho(MSG_Password, "",
    615 					pkgsrc.pass, sizeof pkgsrc.pass);
    616 		  }
    617 		};
    618 	option {src_legend(menu, MSG_Proxy, pkgsrc.proxy);},
    619 		action { src_prompt(MSG_Proxy, pkgsrc.proxy, sizeof pkgsrc.proxy);
    620 		  if (strcmp(pkgsrc.proxy, "") == 0) {
    621 			unsetenv("ftp_proxy");
    622 			unsetenv("http_proxy");
    623 		  } else {
    624 			setenv("ftp_proxy", pkgsrc.proxy, 1);
    625 			setenv("http_proxy", pkgsrc.proxy, 1);
    626 		  }
    627 		};
    628 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    629 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    630 	option {src_legend(menu, MSG_delete_xfer_file,
    631 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    632 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    633 	option {src_legend(menu, MSG_transfer_method, url_proto(pkgsrc.xfer));},
    634 		action { pkgsrc.xfer = (pkgsrc.xfer+1) % (XFER_MAX+1); };
    635 	option MSG_quit_pkgsrc, exit, action { *((int*)arg) = SET_SKIP;};
    636 
    637 menu usersh, title MSG_User_shell, no clear;
    638 	option "/bin/sh",  exit, action { ushell = "/bin/sh";};
    639 	option "/bin/ksh", exit, action { ushell = "/bin/ksh";};
    640 	option "/bin/csh", exit, action { ushell = "/bin/csh";};
    641 
    642 menu convertscheme, title MSG_cvtscheme_hdr;
    643 	option MSG_cvtscheme_keep,		exit, action { *(int*)arg = 0; };
    644 	option MSG_cvtscheme_delete,		exit, action { *(int*)arg = 1; };
    645 	option MSG_cvtscheme_convert,		exit, action { *(int*)arg = 2; };
    646 	option MSG_cvtscheme_abort,		exit, action { *(int*)arg = 3; };
    647 
    648 
    649 menu reedit, title MSG_reeditpart, y=-10;
    650 	expand action { expand_all_option_texts(menu, arg); };
    651 	option MSG_reedit_partitions, exit,
    652 	    action  {((arg_rep_int*)arg)->rv = 1;};
    653 	option MSG_use_partitions_anyway, exit,
    654 	    action  {((arg_rep_int*)arg)->rv = 2;};
    655 	option MSG_abort_installation,       exit,
    656 	    action  {((arg_rep_int*)arg)->rv = 0;};
    657 
    658 
    659