Home | History | Annotate | Line # | Download | only in sysinst
menus.mi revision 1.17
      1 /*	$NetBSD: menus.mi,v 1.17 2019/06/12 06:20:17 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_gpt_options()
    199 {
    200 	/*
    201 	 * No GPT available, remove the following menu entries:
    202 	 */
    203 	remove_menu_option(MENU_pmdiskentry, MSG_switchgpt);
    204 	remove_menu_option(MENU_pmpartentry, MSG_switchgpt);
    205 }
    206 
    207 void
    208 remove_cgd_options()
    209 {
    210 	/*
    211 	 * No CGD available, remove the following menu entries:
    212 	 */
    213 	remove_menu_option(MENU_pmdiskentry, MSG_encrypt);
    214 	remove_menu_option(MENU_pmpartentry, MSG_encrypt);
    215 }
    216 #endif
    217 
    218 }
    219 
    220 default y=12, no exit, scrollable;
    221 
    222 allow dynamic menus;
    223 allow dynamic messages;
    224 allow expand;
    225 
    226 error action {
    227 	fprintf (stderr, "Could not initialize menu system, please check "
    228 	    "your terminal type.\n");
    229 	exit(4);
    230 };
    231 
    232 /*
    233  * Called with arg = struct single_part_fs_edit*
    234  */
    235 menu mountoptions, title MSG_toggle, y=5, x=30, exitstring MSG_unchanged;
    236 	/*
    237 	 *  XXX - enable / disable options depending on FS type in
    238 	 *  display action
    239 	*/
    240 	option "log", exit, action
    241 		{ struct single_part_fs_edit *edit = arg;
    242 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_LOG; };
    243 	option "async", exit, action
    244 		{ struct single_part_fs_edit *edit = arg;
    245 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_ASYNC; };
    246 	option "noatime", exit, action
    247 		{ struct single_part_fs_edit *edit = arg;
    248 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOATIME; };
    249 	option "nodev", exit, action
    250 		{ struct single_part_fs_edit *edit = arg;
    251 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NODEV; };
    252 	option "nodevmtime", exit, action
    253 		{ struct single_part_fs_edit *edit = arg;
    254 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NODEVMTIME; };
    255 	option "noexec", exit, action
    256 		{ struct single_part_fs_edit *edit = arg;
    257 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOEXEC; };
    258 	option "nosuid", exit, action
    259 		{ struct single_part_fs_edit *edit = arg;
    260 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOSUID; };
    261 	option "noauto", exit, action
    262 		{ struct single_part_fs_edit *edit = arg;
    263 		  edit->pset->infos[edit->index].mountflags ^= PUIMNT_NOAUTO; };
    264 
    265 menu netbsd, title MSG_NetBSD_VERSION_Install_System, y=-1,
    266     exit, exitstring MSG_Exit_Install_System;
    267 	display action  { toplevel(); };
    268 	option MSG_Install_NetBSD_to_hard_disk,
    269 		action { do_install(); };
    270 	option MSG_Upgrade_NetBSD_on_a_hard_disk,
    271 		action { do_upgrade(); };
    272 	option MSG_Re_install_sets_or_install_additional_sets,
    273 		action { do_reinstall_sets(NULL); };
    274 	option MSG_Reboot_the_computer, exit,
    275 		action (endwin) { system("/sbin/reboot -q"); };
    276 	option MSG_Utility_menu, sub menu utility;
    277 	option MSG_Config_menu, action { do_configmenu(NULL); };
    278 
    279 menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
    280 		exitstring MSG_exit_menu_generic;
    281 	display action  { toplevel(); };
    282 	option MSG_Run_bin_sh,
    283 		action (endwin) { system("/bin/sh"); };
    284 	option MSG_Set_timezone,
    285 		action { set_timezone(); };
    286 	option MSG_Configure_network,
    287 		action {
    288 			extern int network_up;
    289 			network_up = 0;
    290 			config_network();
    291 		};
    292 	option MSG_Partition_a_disk,
    293 		action {
    294 #ifndef NO_PARTMAN
    295 			partman_go = 1;
    296 			partman();
    297 #endif
    298 		};
    299 	option MSG_Logging_functions, action { do_logging(); };
    300 	option MSG_Color_scheme, sub menu colors;
    301 	option MSG_Halt_the_system, exit,
    302 		action (endwin) { system("/sbin/halt -q"); };
    303 
    304 menu colors, title MSG_Color_scheme, exit,
    305 		exitstring MSG_exit_menu_generic;
    306 	option MSG_White_on_black, action { do_coloring(COLOR_WHITE,COLOR_BLACK); };
    307 	option MSG_Black_on_white, action { do_coloring(COLOR_BLACK,COLOR_WHITE); };
    308 	option MSG_White_on_blue,  action { do_coloring(COLOR_WHITE,COLOR_BLUE); };
    309 	option MSG_Green_on_black, action { do_coloring(COLOR_GREEN,COLOR_BLACK); };
    310 
    311 
    312 menu yesno, y=-10;
    313 	display action { arg_rv *p = arg;
    314 		menu->title = p->arg ? p->arg : MSG_yes_or_no; };
    315 	option MSG_Yes, exit, action  { ((arg_rv*)arg)->rv = 1; };
    316 	option MSG_No,  exit, action  { ((arg_rv*)arg)->rv = 0; };
    317 
    318 menu noyes, y=-10;
    319 	display action { arg_rv *p = arg;
    320 		menu->title = p->arg ? p->arg : MSG_yes_or_no; };
    321 	option MSG_No,  exit, action  { ((arg_rv*)arg)->rv = 0; };
    322 	option MSG_Yes, exit, action  { ((arg_rv*)arg)->rv = 1; };
    323 
    324 menu ok, no shortcut, y=-10;
    325 	display action { menu->title = arg; };
    326 	option MSG_Hit_enter_to_continue, exit;
    327 
    328 menu sizechoice, sub menu, y=0, title MSG_Choose_your_size_specifier;
    329 	display action {
    330 		if (sizemult == pm->current_cylsize)
    331 			menu->cursel = 2;
    332 		else if (sizemult == 1)
    333 			menu->cursel = 3;
    334 		else if (sizemult == (GIG/512))
    335 			menu->cursel = 0;
    336 		else
    337 			menu->cursel = 1; };
    338 	option MSG_Gigabytes, exit, action { set_sizemult(GIG/512); };
    339 	option MSG_Megabytes, exit, action { set_sizemult(MEG/512); };
    340 	option MSG_Cylinders, exit, action { set_sizemult(pm->current_cylsize); };
    341 	option MSG_Sectors, exit, action { set_sizemult(1); };
    342 
    343 menu ptnsize_replace_existing_partition, sub menu, y=0,
    344 	title MSG_ptnsize_replace_existing;
    345 	display action { menu->cursel = 1; };
    346 	option MSG_Yes, exit, action { *((int*)arg) = 1; };
    347 	option MSG_cancel, exit, action { *((int*)arg) = 0; };
    348 
    349 menu distmedium, title MSG_Select_medium, y=-5;
    350 	option MSG_cdrom,     exit, action { *(int *)arg = get_via_cdrom(); };
    351 	option MSG_http,      exit, action { *(int *)arg = get_via_ftp(XFER_HTTP); };
    352 	option MSG_ftp,	      exit, action { *(int *)arg = get_via_ftp(XFER_FTP); };
    353 	option MSG_nfs,	      exit, action { *(int *)arg = get_via_nfs(); };
    354 	option MSG_floppy,    exit, action { *(int *)arg = get_via_floppy(); };
    355 	option MSG_local_fs,  exit, action { *(int *)arg = get_via_localfs(); };
    356 	option MSG_local_dir, exit, action { *(int *)arg = get_via_localdir();};
    357 	option MSG_Skip_set,  exit, action { *(int *)arg = SET_SKIP; };
    358 	option MSG_Skip_group,exit, action { *(int *)arg = SET_SKIP_GROUP; };
    359 	option MSG_Abandon,   exit, action { *(int *)arg = SET_ABANDON; };
    360 
    361 menu distset, title MSG_Select_your_distribution, exit,
    362 	    no default exit, exitstring MSG_Abandon;
    363 	display action { msg_display (MSG_distset); };
    364 	option MSG_Full_installation, exit, action { *(int *)arg = 1; init_set_status(0);  };
    365 	option MSG_Full_installation_nox, exit, action { *(int *)arg = 1; init_set_status(SFLAG_NOX); };
    366 	option MSG_Minimal_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); };
    367 	option MSG_Custom_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); customise_sets(); };
    368 
    369 menu ftpsource, y=-4, x=0, w=70, no box, no clear,
    370 	    exitstring MSG_Get_Distribution;
    371 	display action { msg_display(MSG_ftpsource, url_proto((uintptr_t)((arg_rv*)arg)->arg)); };
    372 	option {src_legend(menu, MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]);},
    373 		action { src_prompt(MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg], sizeof ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]); };
    374 	option {src_legend(menu, MSG_Base_dir, ftp.dir);},
    375 		action { src_prompt(MSG_Base_dir, ftp.dir, sizeof ftp.dir); };
    376 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    377 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    378 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    379 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    380 	option {src_legend(menu, MSG_User, ftp.user);},
    381 		action { src_prompt(MSG_User, ftp.user, sizeof ftp.user);
    382 			ftp.pass[0] = 0;
    383 		};
    384 	option {src_legend(menu, MSG_Password,
    385 		    strcmp(ftp.user, "ftp") == 0 || ftp.pass[0] == 0
    386 			? ftp.pass : msg_string(MSG_hidden));},
    387 		action { if (strcmp(ftp.user, "ftp") == 0)
    388 			src_prompt(MSG_email, ftp.pass, sizeof ftp.pass);
    389 		  else {
    390 			msg_prompt_noecho(MSG_Password, "",
    391 					ftp.pass, sizeof ftp.pass);
    392 		  }
    393 		};
    394 	option {src_legend(menu, MSG_Proxy, ftp.proxy);},
    395 		action { src_prompt(MSG_Proxy, ftp.proxy, sizeof ftp.proxy);
    396 		  if (strcmp(ftp.proxy, "") == 0) {
    397 			unsetenv("ftp_proxy");
    398 			unsetenv("http_proxy");
    399 		  } else {
    400 			setenv("ftp_proxy", ftp.proxy, 1);
    401 			setenv("http_proxy", ftp.proxy, 1);
    402 		  }
    403 		};
    404 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    405 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    406 	option {src_legend(menu, MSG_delete_xfer_file,
    407 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    408 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    409 	option MSG_Configure_network,
    410 		action {
    411 			extern int network_up;
    412 			network_up = 0;
    413 			config_network();
    414 		};
    415 	option MSG_exit_menu_generic, exit, action { ((arg_rv*)arg)->rv = SET_RETRY; };
    416 
    417 
    418 menu nfssource, y=-4, x=0, w=70, no box, no clear,
    419 	    exitstring MSG_Get_Distribution;
    420 	display action { msg_display(MSG_nfssource); };
    421 	option {src_legend(menu, MSG_Host, nfs_host);},
    422 		action { src_prompt(MSG_Host, nfs_host, sizeof nfs_host); };
    423 	option {src_legend(menu, MSG_Base_dir, nfs_dir);},
    424 		action { src_prompt(MSG_Base_dir, nfs_dir, sizeof nfs_dir); };
    425 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    426 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    427 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    428 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    429 	option MSG_Configure_network,
    430 		action {
    431 			extern int network_up;
    432 			network_up = 0;
    433 			config_network();
    434 		};
    435 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    436 
    437 menu fdremount, title MSG_What_do_you_want_to_do;
    438 	option MSG_Try_again, 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 fdok, title MSG_What_do_you_want_to_do;
    443 	option MSG_OK, exit, action { *(int *)arg = SET_CONTINUE; };
    444 	option MSG_Set_finished, exit, action { *(int *)arg = SET_OK; };
    445 	option MSG_Abort_fetch, exit, action { *(int *)arg = SET_RETRY; };
    446 
    447 menu fd_type, title MSG_fd_type, y=16;
    448 	option "msdos", exit, action { fd_type = "msdos"; };
    449 	option "ffs",   exit, action { fd_type = "ffs"; };
    450 .if ADOS_FLOPPY
    451 	option "ados",  exit, action { fd_type = "ados"; };
    452 .endif
    453 
    454 menu floppysource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    455 	display action { msg_display(MSG_floppysource); };
    456 	option {src_legend(menu, MSG_Device, fd_dev);},
    457 		action { src_prompt(MSG_dev, fd_dev, sizeof fd_dev); };
    458 	option {src_legend(menu, MSG_fd_type, fd_type);}, sub menu fd_type;
    459 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    460 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    461 	option {src_legend(menu, MSG_delete_xfer_file,
    462 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    463 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    464 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    465 
    466 menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    467 	display action { msg_display(MSG_cdromsource); };
    468 	option {src_legend(menu, MSG_Device, cdrom_dev);},
    469 		action { src_prompt(MSG_dev, cdrom_dev, sizeof cdrom_dev); };
    470 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    471 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    472 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    473 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    474 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    475 
    476 menu localfssource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    477 	display action { msg_display(MSG_localfssource); };
    478 	option {src_legend(menu, MSG_Device, localfs_dev);},
    479 		action { src_prompt(MSG_dev, localfs_dev, sizeof localfs_dev);};
    480 	option {src_legend(menu, MSG_File_system, localfs_fs);},
    481 		action { src_prompt(MSG_filesys, localfs_fs, sizeof localfs_fs); };
    482 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    483 		action { src_prompt(MSG_Base_dir, localfs_dir, sizeof localfs_dir);};
    484 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    485 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    486 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    487 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    488 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    489 
    490 menu localdirsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    491 	display action { msg_display(MSG_localdir); };
    492 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    493 		action { src_prompt(MSG_Base_dir, localfs_dir, 60); };
    494 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    495 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, 60); };
    496 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    497 		action { src_prompt(MSG_Set_dir_src, set_dir_src, 60); };
    498 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    499 
    500 menu namesrv6, title MSG_Select_DNS_server;
    501 	option "google-public-dns-a.google.com (IPv4)", exit, action
    502 		{
    503 #ifdef INET6
    504 		  strlcpy(net_namesvr, "8.8.8.8",
    505 		      sizeof(net_namesvr));
    506 		  *((int*)arg) = 1;
    507 #else
    508 		  *((int*)arg) = 0;
    509 #endif
    510 		};
    511 	option "google-public-dns-b.google.com (IPv4)", exit, action
    512 		{
    513 #ifdef INET6
    514 		  strlcpy(net_namesvr, "8.8.4.4",
    515 		      sizeof(net_namesvr));
    516 		  *((int*)arg) = 1;
    517 #else
    518 		  *((int*)arg) = 0;
    519 #endif
    520 		};
    521 	option "google-public-dns-a.google.com (IPv6)", exit, action
    522 		{
    523 #ifdef INET6
    524 		  strlcpy(net_namesvr, "2001:4860:4860::8888",
    525 		      sizeof(net_namesvr));
    526 		  *((int*)arg) = 1;
    527 #else
    528 		  *((int*)arg) = 0;
    529 #endif
    530 		};
    531 	option "google-public-dns-b.google.com (IPv6)", exit, action
    532 		{
    533 #ifdef INET6
    534 		  strlcpy(net_namesvr, "2001:4860:4860::8844",
    535 		      sizeof(net_namesvr));
    536 		  *((int*)arg) = 1;
    537 #else
    538 		  *((int*)arg) = 0;
    539 #endif
    540 		};
    541 	option MSG_other, exit, action
    542 		{ *((int*)arg) = 0; };
    543 
    544 menu rootsh, title MSG_Root_shell, no clear;
    545 	option "/bin/sh",  exit, action {*(const char **)arg = "/bin/sh";};
    546 	option "/bin/ksh", exit, action {*(const char **)arg = "/bin/ksh";};
    547 	option "/bin/csh", exit, action {*(const char **)arg = "/bin/csh";};
    548 
    549 menu zeroconf, title "Zeroconf", no clear;
    550 	option "run mdnsd only", exit, action {*(const char **)arg = "mdnsd";};
    551 	option "run mdnsd and resolve local names", exit, action {*(const char **) arg = "mdnsd+nsswitch";};
    552 	option "do not run mdnsd", exit, action {*(const char **)arg = "No";};
    553 
    554 menu binpkg, y=-4, x=0, w=70, no box, no clear,
    555 	    exitstring MSG_Install_pkgin;
    556 	display action { msg_display(MSG_pkgpath); };
    557 	option {src_legend(menu, MSG_Host, pkg.xfer_host[pkg.xfer]);},
    558 		action { src_prompt(MSG_Host, pkg.xfer_host[pkg.xfer], sizeof pkg.xfer_host[pkg.xfer]); };
    559 	option {src_legend(menu, MSG_Base_dir, pkg.dir);},
    560 		action { src_prompt(MSG_Base_dir, pkg.dir, sizeof pkg.dir); };
    561 	option {src_legend(menu, MSG_Pkg_dir, pkg_dir);},
    562 		action { src_prompt(MSG_Pkg_dir, pkg_dir, sizeof pkg_dir); };
    563 	option {src_legend(menu, MSG_User, pkg.user);},
    564 		action { src_prompt(MSG_User, pkg.user, sizeof pkg.user);
    565 			pkg.pass[0] = 0;
    566 		};
    567 	option {src_legend(menu, MSG_Password,
    568 		    strcmp(pkg.user, "ftp") == 0 || pkg.pass[0] == 0
    569 			? pkg.pass : msg_string(MSG_hidden));},
    570 		action { if (strcmp(pkg.user, "ftp") == 0)
    571 			src_prompt(MSG_email, pkg.pass, sizeof pkg.pass);
    572 		  else {
    573 			msg_prompt_noecho(MSG_Password, "",
    574 					pkg.pass, sizeof pkg.pass);
    575 		  }
    576 		};
    577 	option {src_legend(menu, MSG_Proxy, pkg.proxy);},
    578 		action { src_prompt(MSG_Proxy, pkg.proxy, sizeof pkg.proxy);
    579 		  if (strcmp(pkg.proxy, "") == 0) {
    580 			unsetenv("ftp_proxy");
    581 			unsetenv("http_proxy");
    582 		  } else {
    583 			setenv("ftp_proxy", pkg.proxy, 1);
    584 			setenv("http_proxy", pkg.proxy, 1);
    585 		  }
    586 		};
    587 	option {src_legend(menu, "Additional packages", (char*)(((arg_rv*)arg)->arg)); }, /*TODO*/
    588 		action { src_prompt("Additional packages", (char*)(((arg_rv*)arg)->arg),
    589 			 sizeof(char) * STRSIZE); };
    590 	option MSG_Configure_network,
    591 		action {
    592 			extern int network_up;
    593 			network_up = 0;
    594 			config_network();
    595 			mnt_net_config();
    596 		};
    597 	option {src_legend(menu, MSG_transfer_method, url_proto(pkg.xfer));},
    598 		action { pkg.xfer = (pkg.xfer+1) % (XFER_MAX+1); };
    599 	option MSG_quit_pkgs_install, exit, action { ((arg_rv*)arg)->rv = SET_SKIP; };
    600 
    601 menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
    602 	    exit, exitstring MSG_Install_pkgsrc;
    603 	display action { msg_display(MSG_pkgsrc); };
    604 	option {src_legend(menu, MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer]);},
    605 		action { src_prompt(MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer],
    606 			sizeof pkgsrc.xfer_host[pkgsrc.xfer]); };
    607 	option {src_legend(menu, MSG_Pkgsrc_dir, pkgsrc_dir);},
    608 		action { src_prompt(MSG_Pkgsrc_dir, pkgsrc_dir, sizeof pkgsrc_dir); };
    609 	option {src_legend(menu, MSG_User, pkgsrc.user);},
    610 		action { src_prompt(MSG_User, pkgsrc.user, sizeof pkgsrc.user);
    611 			pkgsrc.pass[0] = 0;
    612 		};
    613 	option {src_legend(menu, MSG_Password,
    614 		    strcmp(pkgsrc.user, "ftp") == 0 || pkgsrc.pass[0] == 0
    615 			? pkgsrc.pass : msg_string(MSG_hidden));},
    616 		action { if (strcmp(pkgsrc.user, "ftp") == 0)
    617 			src_prompt(MSG_email, pkgsrc.pass, sizeof pkgsrc.pass);
    618 		  else {
    619 			msg_prompt_noecho(MSG_Password, "",
    620 					pkgsrc.pass, sizeof pkgsrc.pass);
    621 		  }
    622 		};
    623 	option {src_legend(menu, MSG_Proxy, pkgsrc.proxy);},
    624 		action { src_prompt(MSG_Proxy, pkgsrc.proxy, sizeof pkgsrc.proxy);
    625 		  if (strcmp(pkgsrc.proxy, "") == 0) {
    626 			unsetenv("ftp_proxy");
    627 			unsetenv("http_proxy");
    628 		  } else {
    629 			setenv("ftp_proxy", pkgsrc.proxy, 1);
    630 			setenv("http_proxy", pkgsrc.proxy, 1);
    631 		  }
    632 		};
    633 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    634 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    635 	option {src_legend(menu, MSG_delete_xfer_file,
    636 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    637 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    638 	option {src_legend(menu, MSG_transfer_method, url_proto(pkgsrc.xfer));},
    639 		action { pkgsrc.xfer = (pkgsrc.xfer+1) % (XFER_MAX+1); };
    640 	option MSG_quit_pkgsrc, exit, action { *((int*)arg) = SET_SKIP;};
    641 
    642 menu usersh, title MSG_User_shell, no clear;
    643 	option "/bin/sh",  exit, action { ushell = "/bin/sh";};
    644 	option "/bin/ksh", exit, action { ushell = "/bin/ksh";};
    645 	option "/bin/csh", exit, action { ushell = "/bin/csh";};
    646 
    647 menu convertscheme, title MSG_cvtscheme_hdr;
    648 	option MSG_cvtscheme_keep,		exit, action { *(int*)arg = 0; };
    649 	option MSG_cvtscheme_delete,		exit, action { *(int*)arg = 1; };
    650 	option MSG_cvtscheme_convert,		exit, action { *(int*)arg = 2; };
    651 	option MSG_cvtscheme_abort,		exit, action { *(int*)arg = 3; };
    652 
    653 
    654 menu reedit, title MSG_reeditpart, y=-10;
    655 	expand action { expand_all_option_texts(menu, arg); };
    656 	option MSG_reedit_partitions, exit,
    657 	    action  {((arg_rep_int*)arg)->rv = 1;};
    658 	option MSG_use_partitions_anyway, exit,
    659 	    action  {((arg_rep_int*)arg)->rv = 2;};
    660 	option MSG_abort_installation,       exit,
    661 	    action  {((arg_rep_int*)arg)->rv = 0;};
    662 
    663 
    664