Home | History | Annotate | Line # | Download | only in sysinst
menus.mi revision 1.18
      1 /*	$NetBSD: menus.mi,v 1.18 2019/06/20 00:43:55 christos 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_fmt_display(MSG_ftpsource, "%s",
    372 	    url_proto((uintptr_t)((arg_rv*)arg)->arg)); };
    373 	option {src_legend(menu, MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]);},
    374 		action { src_prompt(MSG_Host, ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg], sizeof ftp.xfer_host[(uintptr_t)((arg_rv*)arg)->arg]); };
    375 	option {src_legend(menu, MSG_Base_dir, ftp.dir);},
    376 		action { src_prompt(MSG_Base_dir, ftp.dir, sizeof ftp.dir); };
    377 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    378 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    379 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    380 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    381 	option {src_legend(menu, MSG_User, ftp.user);},
    382 		action { src_prompt(MSG_User, ftp.user, sizeof ftp.user);
    383 			ftp.pass[0] = 0;
    384 		};
    385 	option {src_legend(menu, MSG_Password,
    386 		    strcmp(ftp.user, "ftp") == 0 || ftp.pass[0] == 0
    387 			? ftp.pass : msg_string(MSG_hidden));},
    388 		action { if (strcmp(ftp.user, "ftp") == 0)
    389 			src_prompt(MSG_email, ftp.pass, sizeof ftp.pass);
    390 		  else {
    391 			msg_prompt_noecho(MSG_Password, "",
    392 					ftp.pass, sizeof ftp.pass);
    393 		  }
    394 		};
    395 	option {src_legend(menu, MSG_Proxy, ftp.proxy);},
    396 		action { src_prompt(MSG_Proxy, ftp.proxy, sizeof ftp.proxy);
    397 		  if (strcmp(ftp.proxy, "") == 0) {
    398 			unsetenv("ftp_proxy");
    399 			unsetenv("http_proxy");
    400 		  } else {
    401 			setenv("ftp_proxy", ftp.proxy, 1);
    402 			setenv("http_proxy", ftp.proxy, 1);
    403 		  }
    404 		};
    405 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    406 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    407 	option {src_legend(menu, MSG_delete_xfer_file,
    408 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    409 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    410 	option MSG_Configure_network,
    411 		action {
    412 			extern int network_up;
    413 			network_up = 0;
    414 			config_network();
    415 		};
    416 	option MSG_exit_menu_generic, exit, action { ((arg_rv*)arg)->rv = SET_RETRY; };
    417 
    418 
    419 menu nfssource, y=-4, x=0, w=70, no box, no clear,
    420 	    exitstring MSG_Get_Distribution;
    421 	display action { msg_display(MSG_nfssource); };
    422 	option {src_legend(menu, MSG_Host, nfs_host);},
    423 		action { src_prompt(MSG_Host, nfs_host, sizeof nfs_host); };
    424 	option {src_legend(menu, MSG_Base_dir, nfs_dir);},
    425 		action { src_prompt(MSG_Base_dir, nfs_dir, sizeof nfs_dir); };
    426 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    427 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    428 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    429 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    430 	option MSG_Configure_network,
    431 		action {
    432 			extern int network_up;
    433 			network_up = 0;
    434 			config_network();
    435 		};
    436 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    437 
    438 menu fdremount, title MSG_What_do_you_want_to_do;
    439 	option MSG_Try_again, exit, action { *(int *)arg = SET_CONTINUE; };
    440 	option MSG_Set_finished, exit, action { *(int *)arg = SET_OK; };
    441 	option MSG_Abort_fetch, exit, action { *(int *)arg = SET_RETRY; };
    442 
    443 menu fdok, title MSG_What_do_you_want_to_do;
    444 	option MSG_OK, exit, action { *(int *)arg = SET_CONTINUE; };
    445 	option MSG_Set_finished, exit, action { *(int *)arg = SET_OK; };
    446 	option MSG_Abort_fetch, exit, action { *(int *)arg = SET_RETRY; };
    447 
    448 menu fd_type, title MSG_fd_type, y=16;
    449 	option "msdos", exit, action { fd_type = "msdos"; };
    450 	option "ffs",   exit, action { fd_type = "ffs"; };
    451 .if ADOS_FLOPPY
    452 	option "ados",  exit, action { fd_type = "ados"; };
    453 .endif
    454 
    455 menu floppysource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    456 	display action { msg_display(MSG_floppysource); };
    457 	option {src_legend(menu, MSG_Device, fd_dev);},
    458 		action { src_prompt(MSG_dev, fd_dev, sizeof fd_dev); };
    459 	option {src_legend(menu, MSG_fd_type, fd_type);}, sub menu fd_type;
    460 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    461 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    462 	option {src_legend(menu, MSG_delete_xfer_file,
    463 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    464 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    465 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    466 
    467 menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    468 	display action { msg_display(MSG_cdromsource); };
    469 	option {src_legend(menu, MSG_Device, cdrom_dev);},
    470 		action { src_prompt(MSG_dev, cdrom_dev, sizeof cdrom_dev); };
    471 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    472 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    473 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    474 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    475 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    476 
    477 menu localfssource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    478 	display action { msg_display(MSG_localfssource); };
    479 	option {src_legend(menu, MSG_Device, localfs_dev);},
    480 		action { src_prompt(MSG_dev, localfs_dev, sizeof localfs_dev);};
    481 	option {src_legend(menu, MSG_File_system, localfs_fs);},
    482 		action { src_prompt(MSG_filesys, localfs_fs, sizeof localfs_fs); };
    483 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    484 		action { src_prompt(MSG_Base_dir, localfs_dir, sizeof localfs_dir);};
    485 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    486 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
    487 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    488 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
    489 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    490 
    491 menu localdirsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
    492 	display action { msg_display(MSG_localdir); };
    493 	option {src_legend(menu, MSG_Base_dir, localfs_dir);},
    494 		action { src_prompt(MSG_Base_dir, localfs_dir, 60); };
    495 	option {src_legend(menu, MSG_Set_dir_bin, set_dir_bin);},
    496 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, 60); };
    497 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
    498 		action { src_prompt(MSG_Set_dir_src, set_dir_src, 60); };
    499 	option MSG_exit_menu_generic, exit, action { *((int*)arg) = SET_RETRY; };
    500 
    501 menu namesrv6, title MSG_Select_DNS_server;
    502 	option "google-public-dns-a.google.com (IPv4)", exit, action
    503 		{
    504 #ifdef INET6
    505 		  strlcpy(net_namesvr, "8.8.8.8",
    506 		      sizeof(net_namesvr));
    507 		  *((int*)arg) = 1;
    508 #else
    509 		  *((int*)arg) = 0;
    510 #endif
    511 		};
    512 	option "google-public-dns-b.google.com (IPv4)", exit, action
    513 		{
    514 #ifdef INET6
    515 		  strlcpy(net_namesvr, "8.8.4.4",
    516 		      sizeof(net_namesvr));
    517 		  *((int*)arg) = 1;
    518 #else
    519 		  *((int*)arg) = 0;
    520 #endif
    521 		};
    522 	option "google-public-dns-a.google.com (IPv6)", exit, action
    523 		{
    524 #ifdef INET6
    525 		  strlcpy(net_namesvr, "2001:4860:4860::8888",
    526 		      sizeof(net_namesvr));
    527 		  *((int*)arg) = 1;
    528 #else
    529 		  *((int*)arg) = 0;
    530 #endif
    531 		};
    532 	option "google-public-dns-b.google.com (IPv6)", exit, action
    533 		{
    534 #ifdef INET6
    535 		  strlcpy(net_namesvr, "2001:4860:4860::8844",
    536 		      sizeof(net_namesvr));
    537 		  *((int*)arg) = 1;
    538 #else
    539 		  *((int*)arg) = 0;
    540 #endif
    541 		};
    542 	option MSG_other, exit, action
    543 		{ *((int*)arg) = 0; };
    544 
    545 menu rootsh, title MSG_Root_shell, no clear;
    546 	option "/bin/sh",  exit, action {*(const char **)arg = "/bin/sh";};
    547 	option "/bin/ksh", exit, action {*(const char **)arg = "/bin/ksh";};
    548 	option "/bin/csh", exit, action {*(const char **)arg = "/bin/csh";};
    549 
    550 menu zeroconf, title "Zeroconf", no clear;
    551 	option "run mdnsd only", exit, action {*(const char **)arg = "mdnsd";};
    552 	option "run mdnsd and resolve local names", exit, action {*(const char **) arg = "mdnsd+nsswitch";};
    553 	option "do not run mdnsd", exit, action {*(const char **)arg = "No";};
    554 
    555 menu binpkg, y=-4, x=0, w=70, no box, no clear,
    556 	    exitstring MSG_Install_pkgin;
    557 	display action { msg_display(MSG_pkgpath); };
    558 	option {src_legend(menu, MSG_Host, pkg.xfer_host[pkg.xfer]);},
    559 		action { src_prompt(MSG_Host, pkg.xfer_host[pkg.xfer], sizeof pkg.xfer_host[pkg.xfer]); };
    560 	option {src_legend(menu, MSG_Base_dir, pkg.dir);},
    561 		action { src_prompt(MSG_Base_dir, pkg.dir, sizeof pkg.dir); };
    562 	option {src_legend(menu, MSG_Pkg_dir, pkg_dir);},
    563 		action { src_prompt(MSG_Pkg_dir, pkg_dir, sizeof pkg_dir); };
    564 	option {src_legend(menu, MSG_User, pkg.user);},
    565 		action { src_prompt(MSG_User, pkg.user, sizeof pkg.user);
    566 			pkg.pass[0] = 0;
    567 		};
    568 	option {src_legend(menu, MSG_Password,
    569 		    strcmp(pkg.user, "ftp") == 0 || pkg.pass[0] == 0
    570 			? pkg.pass : msg_string(MSG_hidden));},
    571 		action { if (strcmp(pkg.user, "ftp") == 0)
    572 			src_prompt(MSG_email, pkg.pass, sizeof pkg.pass);
    573 		  else {
    574 			msg_prompt_noecho(MSG_Password, "",
    575 					pkg.pass, sizeof pkg.pass);
    576 		  }
    577 		};
    578 	option {src_legend(menu, MSG_Proxy, pkg.proxy);},
    579 		action { src_prompt(MSG_Proxy, pkg.proxy, sizeof pkg.proxy);
    580 		  if (strcmp(pkg.proxy, "") == 0) {
    581 			unsetenv("ftp_proxy");
    582 			unsetenv("http_proxy");
    583 		  } else {
    584 			setenv("ftp_proxy", pkg.proxy, 1);
    585 			setenv("http_proxy", pkg.proxy, 1);
    586 		  }
    587 		};
    588 	option {src_legend(menu, "Additional packages", (char*)(((arg_rv*)arg)->arg)); }, /*TODO*/
    589 		action { src_prompt("Additional packages", (char*)(((arg_rv*)arg)->arg),
    590 			 sizeof(char) * STRSIZE); };
    591 	option MSG_Configure_network,
    592 		action {
    593 			extern int network_up;
    594 			network_up = 0;
    595 			config_network();
    596 			mnt_net_config();
    597 		};
    598 	option {src_legend(menu, MSG_transfer_method, url_proto(pkg.xfer));},
    599 		action { pkg.xfer = (pkg.xfer+1) % (XFER_MAX+1); };
    600 	option MSG_quit_pkgs_install, exit, action { ((arg_rv*)arg)->rv = SET_SKIP; };
    601 
    602 menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
    603 	    exit, exitstring MSG_Install_pkgsrc;
    604 	display action { msg_display(MSG_pkgsrc); };
    605 	option {src_legend(menu, MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer]);},
    606 		action { src_prompt(MSG_Host, pkgsrc.xfer_host[pkgsrc.xfer],
    607 			sizeof pkgsrc.xfer_host[pkgsrc.xfer]); };
    608 	option {src_legend(menu, MSG_Pkgsrc_dir, pkgsrc_dir);},
    609 		action { src_prompt(MSG_Pkgsrc_dir, pkgsrc_dir, sizeof pkgsrc_dir); };
    610 	option {src_legend(menu, MSG_User, pkgsrc.user);},
    611 		action { src_prompt(MSG_User, pkgsrc.user, sizeof pkgsrc.user);
    612 			pkgsrc.pass[0] = 0;
    613 		};
    614 	option {src_legend(menu, MSG_Password,
    615 		    strcmp(pkgsrc.user, "ftp") == 0 || pkgsrc.pass[0] == 0
    616 			? pkgsrc.pass : msg_string(MSG_hidden));},
    617 		action { if (strcmp(pkgsrc.user, "ftp") == 0)
    618 			src_prompt(MSG_email, pkgsrc.pass, sizeof pkgsrc.pass);
    619 		  else {
    620 			msg_prompt_noecho(MSG_Password, "",
    621 					pkgsrc.pass, sizeof pkgsrc.pass);
    622 		  }
    623 		};
    624 	option {src_legend(menu, MSG_Proxy, pkgsrc.proxy);},
    625 		action { src_prompt(MSG_Proxy, pkgsrc.proxy, sizeof pkgsrc.proxy);
    626 		  if (strcmp(pkgsrc.proxy, "") == 0) {
    627 			unsetenv("ftp_proxy");
    628 			unsetenv("http_proxy");
    629 		  } else {
    630 			setenv("ftp_proxy", pkgsrc.proxy, 1);
    631 			setenv("http_proxy", pkgsrc.proxy, 1);
    632 		  }
    633 		};
    634 	option {src_legend(menu, MSG_Xfer_dir, xfer_dir);},
    635 		action { src_prompt(MSG_Xfer_dir, xfer_dir, sizeof xfer_dir); };
    636 	option {src_legend(menu, MSG_delete_xfer_file,
    637 			clean_xfer_dir ? MSG_Yes : MSG_No);},
    638 		action {clean_xfer_dir = ask_yesno(MSG_delete_xfer_file); };
    639 	option {src_legend(menu, MSG_transfer_method, url_proto(pkgsrc.xfer));},
    640 		action { pkgsrc.xfer = (pkgsrc.xfer+1) % (XFER_MAX+1); };
    641 	option MSG_quit_pkgsrc, exit, action { *((int*)arg) = SET_SKIP;};
    642 
    643 menu usersh, title MSG_User_shell, no clear;
    644 	option "/bin/sh",  exit, action { ushell = "/bin/sh";};
    645 	option "/bin/ksh", exit, action { ushell = "/bin/ksh";};
    646 	option "/bin/csh", exit, action { ushell = "/bin/csh";};
    647 
    648 menu convertscheme, title MSG_cvtscheme_hdr;
    649 	option MSG_cvtscheme_keep,		exit, action { *(int*)arg = 0; };
    650 	option MSG_cvtscheme_delete,		exit, action { *(int*)arg = 1; };
    651 	option MSG_cvtscheme_convert,		exit, action { *(int*)arg = 2; };
    652 	option MSG_cvtscheme_abort,		exit, action { *(int*)arg = 3; };
    653 
    654 
    655 menu reedit, title MSG_reeditpart, y=-10;
    656 	expand action { expand_all_option_texts(menu, arg); };
    657 	option MSG_reedit_partitions, exit,
    658 	    action  {((arg_rep_int*)arg)->rv = 1;};
    659 	option MSG_use_partitions_anyway, exit,
    660 	    action  {((arg_rep_int*)arg)->rv = 2;};
    661 	option MSG_abort_installation,       exit,
    662 	    action  {((arg_rep_int*)arg)->rv = 0;};
    663 
    664 
    665