xref: /freebsd/contrib/bsddialog/utility/util_cli.c (revision f2d966f6c13d93cccceb8e594a69d1a50471d314)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/ioctl.h>
29 
30 #include <getopt.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 
36 #include <bsddialog.h>
37 #include <bsddialog_theme.h>
38 
39 #include "util.h"
40 
41 enum OPTS {
42 	/* Options */
43 	ALTERNATE_SCREEN = '?' + 1,
44 	AND_DIALOG,
45 	ASCII_LINES,
46 	BACKTITLE,
47 	BEGIN_X,
48 	BEGIN_Y,
49 	BIKESHED,
50 	CANCEL_EXIT_CODE,
51 	CANCEL_LABEL,
52 	CLEAR_DIALOG,
53 	CLEAR_SCREEN,
54 	COLUMNS_PER_ROW,
55 	CR_WRAP,
56 	DATEBOX_FORMAT,
57 	DATE_FORMAT,
58 	DEFAULT_BUTTON,
59 	DEFAULT_ITEM,
60 	DEFAULT_NO,
61 	DISABLE_ESC,
62 	ERROR_EXIT_CODE,
63 	ESC_EXIT_CODE,
64 	EXIT_LABEL,
65 	EXTRA_BUTTON,
66 	EXTRA_EXIT_CODE,
67 	EXTRA_LABEL,
68 	HELP_BUTTON,
69 	HELP_EXIT_CODE,
70 	HELP_LABEL,
71 	HELP_PRINT_ITEMS,
72 	HELP_PRINT_NAME,
73 	HFILE,
74 	HLINE,
75 	HMSG,
76 	IGNORE,
77 	INSECURE,
78 	ITEM_BOTTOM_DESC,
79 	ITEM_DEPTH,
80 	ITEM_PREFIX,
81 	LEFT1_BUTTON,
82 	LEFT1_EXIT_CODE,
83 	LEFT2_BUTTON,
84 	LEFT2_EXIT_CODE,
85 	LEFT3_BUTTON,
86 	LEFT3_EXIT_CODE,
87 	LOAD_THEME,
88 	MAX_INPUT_FORM,
89 	NO_CANCEL,
90 	NO_DESCRIPTIONS,
91 	NO_LINES,
92 	NO_NAMES,
93 	NO_OK,
94 	NO_SHADOW,
95 	NORMAL_SCREEN,
96 	OK_EXIT_CODE,
97 	OK_LABEL,
98 	OUTPUT_FD,
99 	OUTPUT_SEPARATOR,
100 	PRINT_MAXSIZE,
101 	PRINT_SIZE,
102 	PRINT_VERSION,
103 	QUOTED,
104 	RIGHT1_BUTTON,
105 	RIGHT1_EXIT_CODE,
106 	RIGHT2_BUTTON,
107 	RIGHT2_EXIT_CODE,
108 	RIGHT3_BUTTON,
109 	RIGHT3_EXIT_CODE,
110 	SAVE_THEME,
111 	SEPARATE_OUTPUT,
112 	SHADOW,
113 	SINGLE_QUOTED,
114 	SLEEP,
115 	STDERR,
116 	STDOUT,
117 	SWITCH_BUTTONS,
118 	TAB_ESCAPE,
119 	TAB_LEN,
120 	TEXT_ESCAPE,
121 	TEXT_UNCHANGED,
122 	THEME,
123 	TIMEOUT_EXIT_CODE,
124 	TIME_FORMAT,
125 	TITLE,
126 	/* Dialogs */
127 	CALENDAR,
128 	CHECKLIST,
129 	DATEBOX,
130 	FORM,
131 	GAUGE,
132 	INFOBOX,
133 	INPUTBOX,
134 	MENU,
135 	MIXEDFORM,
136 	MIXEDGAUGE,
137 	MSGBOX,
138 	PASSWORDBOX,
139 	PASSWORDFORM,
140 	PAUSE,
141 	RADIOLIST,
142 	RANGEBOX,
143 	TEXTBOX,
144 	TIMEBOX,
145 	TREEVIEW,
146 	YESNO,
147 	SLIDER,
148 };
149 
150 /* options descriptor */
151 static struct option longopts[] = {
152 	/* Options */
153 	{"alternate-screen",  no_argument,       NULL, ALTERNATE_SCREEN},
154 	{"and-dialog",        no_argument,       NULL, AND_DIALOG},
155 	{"and-widget",        no_argument,       NULL, AND_DIALOG},
156 	{"ascii-lines",       no_argument,       NULL, ASCII_LINES},
157 	{"backtitle",         required_argument, NULL, BACKTITLE},
158 	{"begin-x",           required_argument, NULL, BEGIN_X},
159 	{"begin-y",           required_argument, NULL, BEGIN_Y},
160 	{"bikeshed",          no_argument,       NULL, BIKESHED},
161 	{"cancel-exit-code",  required_argument, NULL, CANCEL_EXIT_CODE},
162 	{"cancel-label",      required_argument, NULL, CANCEL_LABEL},
163 	{"clear",             no_argument,       NULL, CLEAR_SCREEN},
164 	{"clear-dialog",      no_argument,       NULL, CLEAR_DIALOG},
165 	{"clear-screen",      no_argument,       NULL, CLEAR_SCREEN},
166 	{"colors",            no_argument,       NULL, TEXT_ESCAPE},
167 	{"columns-per-row",   required_argument, NULL, COLUMNS_PER_ROW},
168 	{"cr-wrap",           no_argument,       NULL, CR_WRAP},
169 	{"datebox-format",    required_argument, NULL, DATEBOX_FORMAT},
170 	{"date-format",       required_argument, NULL, DATE_FORMAT},
171 	{"defaultno",         no_argument,       NULL, DEFAULT_NO},
172 	{"default-button",    required_argument, NULL, DEFAULT_BUTTON},
173 	{"default-item",      required_argument, NULL, DEFAULT_ITEM},
174 	{"default-no",        no_argument,       NULL, DEFAULT_NO},
175 	{"disable-esc",       no_argument,       NULL, DISABLE_ESC},
176 	{"error-exit-code",   required_argument, NULL, ERROR_EXIT_CODE},
177 	{"esc-exit-code",     required_argument, NULL, ESC_EXIT_CODE},
178 	{"exit-label",        required_argument, NULL, EXIT_LABEL},
179 	{"extra-button",      no_argument,       NULL, EXTRA_BUTTON},
180 	{"extra-exit-code",   required_argument, NULL, EXTRA_EXIT_CODE},
181 	{"extra-label",       required_argument, NULL, EXTRA_LABEL},
182 	{"help-button",       no_argument,       NULL, HELP_BUTTON},
183 	{"help-exit-code",    required_argument, NULL, HELP_EXIT_CODE},
184 	{"help-label",        required_argument, NULL, HELP_LABEL},
185 	{"help-print-items",  no_argument,       NULL, HELP_PRINT_ITEMS},
186 	{"help-print-name",   no_argument,       NULL, HELP_PRINT_NAME},
187 	{"help-status",       no_argument,       NULL, HELP_PRINT_ITEMS},
188 	{"help-tags",         no_argument,       NULL, HELP_PRINT_NAME},
189 	{"hfile",             required_argument, NULL, HFILE},
190 	{"hline",             required_argument, NULL, HLINE},
191 	{"hmsg",              required_argument, NULL, HMSG},
192 	{"ignore",            no_argument,       NULL, IGNORE},
193 	{"insecure",          no_argument,       NULL, INSECURE},
194 	{"item-bottom-desc",  no_argument,       NULL, ITEM_BOTTOM_DESC},
195 	{"item-depth",        no_argument,       NULL, ITEM_DEPTH},
196 	{"item-help",         no_argument,       NULL, ITEM_BOTTOM_DESC},
197 	{"item-prefix",       no_argument,       NULL, ITEM_PREFIX},
198 	{"keep-tite",         no_argument,       NULL, ALTERNATE_SCREEN},
199 	{"left1-button",      required_argument, NULL, LEFT1_BUTTON},
200 	{"left1-exit-code",   required_argument, NULL, LEFT1_EXIT_CODE},
201 	{"left2-button",      required_argument, NULL, LEFT2_BUTTON},
202 	{"left2-exit-code",   required_argument, NULL, LEFT2_EXIT_CODE},
203 	{"left3-button",      required_argument, NULL, LEFT3_BUTTON},
204 	{"left3-exit-code",   required_argument, NULL, LEFT3_EXIT_CODE},
205 	{"load-theme",        required_argument, NULL, LOAD_THEME},
206 	{"max-input",         required_argument, NULL, MAX_INPUT_FORM},
207 	{"no-cancel",         no_argument,       NULL, NO_CANCEL},
208 	{"nocancel",          no_argument,       NULL, NO_CANCEL},
209 	{"no-descriptions",   no_argument,       NULL, NO_DESCRIPTIONS},
210 	{"no-items",          no_argument,       NULL, NO_DESCRIPTIONS},
211 	{"no-label",          required_argument, NULL, CANCEL_LABEL},
212 	{"no-lines",          no_argument,       NULL, NO_LINES},
213 	{"no-names",          no_argument,       NULL, NO_NAMES},
214 	{"no-ok",             no_argument,       NULL, NO_OK},
215 	{"nook",              no_argument,       NULL, NO_OK},
216 	{"no-shadow",         no_argument,       NULL, NO_SHADOW},
217 	{"no-tags",           no_argument,       NULL, NO_NAMES},
218 	{"normal-screen",     no_argument,       NULL, NORMAL_SCREEN},
219 	{"ok-exit-code",      required_argument, NULL, OK_EXIT_CODE},
220 	{"ok-label",          required_argument, NULL, OK_LABEL},
221 	{"output-fd",         required_argument, NULL, OUTPUT_FD},
222 	{"output-separator",  required_argument, NULL, OUTPUT_SEPARATOR},
223 	{"print-maxsize",     no_argument,       NULL, PRINT_MAXSIZE},
224 	{"print-size",        no_argument,       NULL, PRINT_SIZE},
225 	{"print-version",     no_argument,       NULL, PRINT_VERSION},
226 	{"quoted",            no_argument,       NULL, QUOTED},
227 	{"right1-button",     required_argument, NULL, RIGHT1_BUTTON},
228 	{"right1-exit-code",  required_argument, NULL, RIGHT1_EXIT_CODE},
229 	{"right2-button",     required_argument, NULL, RIGHT2_BUTTON},
230 	{"right2-exit-code",  required_argument, NULL, RIGHT2_EXIT_CODE},
231 	{"right3-button",     required_argument, NULL, RIGHT3_BUTTON},
232 	{"right3-exit-code",  required_argument, NULL, RIGHT3_EXIT_CODE},
233 	{"save-theme",        required_argument, NULL, SAVE_THEME},
234 	{"separate-output",   no_argument,       NULL, SEPARATE_OUTPUT},
235 	{"separator",         required_argument, NULL, OUTPUT_SEPARATOR},
236 	{"shadow",            no_argument,       NULL, SHADOW},
237 	{"single-quoted",     no_argument,       NULL, SINGLE_QUOTED},
238 	{"sleep",             required_argument, NULL, SLEEP},
239 	{"stderr",            no_argument,       NULL, STDERR},
240 	{"stdout",            no_argument,       NULL, STDOUT},
241 	{"switch-buttons",    no_argument,       NULL, SWITCH_BUTTONS},
242 	{"tab-escape",        no_argument,       NULL, TAB_ESCAPE},
243 	{"tab-len",           required_argument, NULL, TAB_LEN},
244 	{"text-escape",       no_argument,       NULL, TEXT_ESCAPE},
245 	{"text-unchanged",    no_argument,       NULL, TEXT_UNCHANGED},
246 	{"theme",             required_argument, NULL, THEME},
247 	{"timeout-exit-code", required_argument, NULL, TIMEOUT_EXIT_CODE},
248 	{"time-format",       required_argument, NULL, TIME_FORMAT},
249 	{"title",             required_argument, NULL, TITLE},
250 	{"yes-label",         required_argument, NULL, OK_LABEL},
251 	/* Dialogs */
252 	{"calendar",     no_argument, NULL, CALENDAR},
253 	{"checklist",    no_argument, NULL, CHECKLIST},
254 	{"datebox",      no_argument, NULL, DATEBOX},
255 	{"form",         no_argument, NULL, FORM},
256 	{"gauge",        no_argument, NULL, GAUGE},
257 	{"infobox",      no_argument, NULL, INFOBOX},
258 	{"inputbox",     no_argument, NULL, INPUTBOX},
259 	{"menu",         no_argument, NULL, MENU},
260 	{"mixedform",    no_argument, NULL, MIXEDFORM},
261 	{"mixedgauge",   no_argument, NULL, MIXEDGAUGE},
262 	{"msgbox",       no_argument, NULL, MSGBOX},
263 	{"passwordbox",  no_argument, NULL, PASSWORDBOX},
264 	{"passwordform", no_argument, NULL, PASSWORDFORM},
265 	{"pause",        no_argument, NULL, PAUSE},
266 	{"radiolist",    no_argument, NULL, RADIOLIST},
267 	{"rangebox",     no_argument, NULL, RANGEBOX},
268 	{"slider",       no_argument, NULL, SLIDER},
269 	{"textbox",      no_argument, NULL, TEXTBOX},
270 	{"timebox",      no_argument, NULL, TIMEBOX},
271 	{"treeview",     no_argument, NULL, TREEVIEW},
272 	{"yesno",        no_argument, NULL, YESNO},
273 	/* END */
274 	{ NULL, 0, NULL, 0}
275 };
276 
usage(void)277 void usage(void)
278 {
279 	printf("usage: bsddialog --help | --version\n");
280 	printf("       bsddialog [--<opt>] --<dialog> <text> <rows> <cols> "
281 	    "[<arg>] [--<opt>]\n");
282 	printf("       bsddialog ... --<dialog1> ... [--and-dialog --<dialog2> "
283 	    "...] ...\n");
284 	printf("\n");
285 
286 	printf("Options:\n");
287 	printf(" --alternate-screen, --ascii-lines, --backtitle <backtitle>,"
288 	    " --begin-x <x>,\n --begin-y <y>, --bikeshed,"
289 	    " --cancel-exit-code <retval>, --cancel-label <label>,\n"
290 	    " --clear-dialog, --clear-screen, --columns-per-row <columns>,"
291 	    " --cr-wrap,\n --datebox-format d/m/y|m/d/y|y/m/d,"
292 	    " --date-format <format>,\n --default-button <label>,"
293 	    " --default-item <name>, --default-no, --disable-esc,\n"
294 	    " --error-exit-code <retval>, --esc-exit-code <retval>,"
295 	    " --exit-label <label>,\n --extra-button,"
296 	    " --extra-exit-code <retval>, --extra-label <label>,\n"
297 	    " --left1-button <label>, --left1-exit-code <retval>,"
298 	    " --left2-button <label>,\n --left2-exit-code <retval>,"
299 	    " --left3-button <label>, --left3-exit-code <retval>,\n"
300 	    " --help-button, --help-exit-code <retval>, --help-label <label>,\n"
301 	    " --help-print-items, --help-print-name, --hfile <file>,"
302 	    " --hline <string>,\n --hmsg <string>, --ignore, --insecure,"
303 	    " --item-bottom-desc, --item-depth,\n --item-prefix,"
304 	    " --load-theme <file>, --max-input <size>, --no-cancel,\n"
305 	    " --no-descriptions, --no-label <label>, --no-lines, --no-names,"
306 	    " --no-ok,\n --no-shadow, --normal-screen, --ok-exit-code <retval>,"
307 	    " --ok-label <label>,\n --output-fd <fd>, --output-separator <sep>,"
308 	    " --print-maxsize, --print-size,\n --print-version, --quoted,"
309 	    " --right1-button <label>,\n --right1-exit-code <retval>,"
310 	    " --right2-button <label>,\n --right2-exit-code <retval>,"
311 	    " --right3-button <label>,\n --right3-exit-code <retval>,"
312 	    " --save-theme <file>, --separate-output,\n --separator <sep>,"
313 	    " --shadow, --single-quoted, --sleep <secs>, --stderr,\n --stdout,"
314 	    " --switch-buttons, --tab-escape, --tab-len <spaces>,"
315 	    " --text-escape,\n --text-unchanged, --theme 3d|blackwhite|flat,"
316 	    " --timeout-exit-code <retval>,\n --time-format <format>,"
317 	    " --title <title>, --yes-label <label>.");
318 	printf("\n\n");
319 
320 	printf("Dialogs:\n");
321 	printf(" --calendar <text> <rows> <cols> [<dd> <mm> <yy>]\n");
322 	printf(" --checklist <text> <rows> <cols> <menurows> [<name> <desc> "
323 	    "on|off] ...\n");
324 	printf(" --datebox <text> <rows> <cols> [<dd> <mm> <yy>]\n");
325 	printf(" --form <text> <rows> <cols> <formrows> [<label> <ylabel> "
326 	    "<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters>] "
327 	    "...\n");
328 	printf(" --gauge <text> <rows> <cols> [<perc>]\n");
329 	printf(" --infobox <text> <rows> <cols>\n");
330 	printf(" --inputbox <text> <rows> <cols> [<init>]\n");
331 	printf(" --menu <text> <rows> <cols> <menurows> [<name> <desc>] ...\n");
332 	printf(" --mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
333 	    "<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters> "
334 	    "0|1|2] ...\n");
335 	printf(" --mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
336 	    "<miniperc>] ...\n");
337 	printf(" --msgbox <text> <rows> <cols>\n");
338 	printf(" --passwordbox <text> <rows> <cols> [<init>]\n");
339 	printf(" --passwordform <text> <rows> <cols> <formrows> [<label> "
340 	    "<ylabel> <xlabel> <init> <yfield> <xfield> <fieldlen> "
341 	    "<maxletters>] ...\n");
342 	printf(" --pause <text> <rows> <cols> <secs>\n");
343 	printf(" --radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
344 	    "on|off] ...\n");
345 	printf(" --rangebox <text> <rows> <cols> <min> <max> [<init>]\n");
346 	printf(" --textbox <file> <rows> <cols>\n");
347 	printf(" --timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n");
348 	printf(" --treeview <text> <rows> <cols> <menurows> [<depth> <name> "
349 	    "<desc> on|off] ...\n");
350 	printf(" --yesno <text> <rows> <cols>\n");
351 	printf("\n");
352 
353 	printf("See 'man 1 bsddialog' for more information.\n");
354 }
355 
356 int
parseargs(int argc,char ** argv,struct bsddialog_conf * conf,struct options * opt)357 parseargs(int argc, char **argv, struct bsddialog_conf *conf,
358     struct options *opt)
359 {
360 	int arg, parsed, i;
361 	struct winsize ws;
362 
363 	bsddialog_initconf(conf);
364 	conf->key.enable_esc = true;
365 	conf->button.always_active = true;
366 
367 	memset(opt, 0, sizeof(struct options));
368 	opt->theme = -1;
369 	opt->output_fd = STDERR_FILENO;
370 	opt->max_input_form = 2048;
371 	opt->mandatory_dialog = true;
372 
373 	for (i = 0; i < argc; i++) {
374 		if (strcmp(argv[i], "--and-dialog") == 0 ||
375 		    strcmp(argv[i], "--and-widget") == 0) {
376 			argc = i + 1;
377 			break;
378 		}
379 	}
380 	parsed = argc;
381 	while ((arg = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
382 		switch (arg) {
383 		/* Options */
384 		case ALTERNATE_SCREEN:
385 			opt->screen_mode = "smcup";
386 			break;
387 		case AND_DIALOG:
388 			if (opt->dialogbuilder == NULL)
389 				exit_error(true,"--and-dialog without "
390 				    "previous --<dialog>");
391 			break;
392 		case ASCII_LINES:
393 			conf->ascii_lines = true;
394 			break;
395 		case BACKTITLE:
396 			opt->backtitle = optarg;
397 			if (conf->y == BSDDIALOG_CENTER)
398 				conf->auto_topmargin = 2;
399 			break;
400 		case BEGIN_X:
401 			conf->x = (int)strtol(optarg, NULL, 10);
402 			if (conf->x < BSDDIALOG_CENTER)
403 				exit_error(false, "--begin-x %d is < %d",
404 				    conf->x, BSDDIALOG_CENTER);
405 			break;
406 		case BEGIN_Y:
407 			conf->y = (int)strtol(optarg, NULL, 10);
408 			if (conf->y < BSDDIALOG_CENTER)
409 				exit_error(false, "--begin-y %d is < %d",
410 				    conf->y, BSDDIALOG_CENTER);
411 			conf->auto_topmargin = 0;
412 			break;
413 		case BIKESHED:
414 			opt->bikeshed = true;
415 			break;
416 		case CANCEL_EXIT_CODE:
417 			set_exit_code(BSDDIALOG_CANCEL,
418 			    (int)strtol(optarg, NULL, 10));
419 			break;
420 		case CANCEL_LABEL:
421 			conf->button.cancel_label = optarg;
422 			break;
423 		case CLEAR_DIALOG:
424 			conf->clear = true;
425 			break;
426 		case CLEAR_SCREEN:
427 			opt->mandatory_dialog = false;
428 			opt->clearscreen = true;
429 			break;
430 		case COLUMNS_PER_ROW:
431 			conf->text.cols_per_row =
432 			    (u_int)strtoul(optarg, NULL, 10);
433 			break;
434 		case CR_WRAP:
435 			opt->cr_wrap = true;
436 			break;
437 		case DATEBOX_FORMAT:
438 			if (strcasecmp(optarg, "d/m/y") == 0)
439 				conf->date.format = "d/m/y";
440 			else if (strcasecmp(optarg, "m/d/y") == 0)
441 				conf->date.format = "m/d/y";
442 			else if (strcasecmp(optarg, "y/m/d") == 0)
443 				conf->date.format = "y/m/d";
444 			else
445 				exit_error(true,
446 				    "date format \"%s\" is invalid", optarg);
447 			break;
448 		case DATE_FORMAT:
449 			opt->date_fmt = optarg;
450 			break;
451 		case DEFAULT_BUTTON:
452 			conf->button.default_label = optarg;
453 			break;
454 		case DEFAULT_ITEM:
455 			opt->item_default = optarg;
456 			break;
457 		case DEFAULT_NO:
458 			conf->button.default_cancel = true;
459 			break;
460 		case DISABLE_ESC:
461 			conf->key.enable_esc = false;
462 			break;
463 		case ERROR_EXIT_CODE:
464 			set_exit_code(BSDDIALOG_ERROR,
465 			    (int)strtol(optarg, NULL, 10));
466 			break;
467 		case ESC_EXIT_CODE:
468 			set_exit_code(BSDDIALOG_ESC,
469 			    (int)strtol(optarg, NULL, 10));
470 			break;
471 		case EXIT_LABEL:
472 			conf->button.ok_label = optarg;
473 			break;
474 		case EXTRA_BUTTON:
475 			conf->button.with_extra = true;
476 			break;
477 		case EXTRA_EXIT_CODE:
478 			set_exit_code(BSDDIALOG_EXTRA,
479 			    (int)strtol(optarg, NULL, 10));
480 			break;
481 		case EXTRA_LABEL:
482 			conf->button.extra_label = optarg;
483 			break;
484 		case HELP_BUTTON:
485 			conf->button.with_help = true;
486 			break;
487 		case HELP_EXIT_CODE:
488 			i = (int)strtol(optarg, NULL, 10);
489 			set_exit_code(BSDDIALOG_HELP, i);
490 			/* _TEM_HELP follows _HELP */
491 			set_exit_code(BSDDIALOG_ITEM_HELP, i);
492 			break;
493 		case HELP_LABEL:
494 			conf->button.help_label = optarg;
495 			break;
496 		case HELP_PRINT_ITEMS:
497 			opt->help_print_items = true;
498 			break;
499 		case HELP_PRINT_NAME:
500 			opt->help_print_item_name = true;
501 			break;
502 		case HFILE:
503 			conf->key.f1_file = optarg;
504 			break;
505 		case HLINE:
506 			if (optarg[0] != '\0')
507 				conf->bottomtitle = optarg;
508 			break;
509 		case HMSG:
510 			conf->key.f1_message = optarg;
511 			break;
512 		case IGNORE:
513 			opt->ignore = true;
514 			break;
515 		case INSECURE:
516 			conf->form.securech = '*';
517 			break;
518 		case ITEM_BOTTOM_DESC:
519 			opt->item_bottomdesc = true;
520 			break;
521 		case ITEM_DEPTH:
522 			opt->item_depth = true;
523 			break;
524 		case ITEM_PREFIX:
525 			opt->item_prefix = true;
526 			break;
527 		case LEFT1_BUTTON:
528 			conf->button.left1_label = optarg;
529 			break;
530 		case LEFT1_EXIT_CODE:
531 			set_exit_code(BSDDIALOG_LEFT1,
532 			    (int)strtol(optarg, NULL, 10));
533 			break;
534 		case LEFT2_BUTTON:
535 			conf->button.left2_label = optarg;
536 			break;
537 		case LEFT2_EXIT_CODE:
538 			set_exit_code(BSDDIALOG_LEFT2,
539 			    (int)strtol(optarg, NULL, 10));
540 			break;
541 		case LEFT3_BUTTON:
542 			conf->button.left3_label = optarg;
543 			break;
544 		case LEFT3_EXIT_CODE:
545 			set_exit_code(BSDDIALOG_LEFT3,
546 			    (int)strtol(optarg, NULL, 10));
547 			break;
548 		case LOAD_THEME:
549 			opt->loadthemefile = optarg;
550 			break;
551 		case MAX_INPUT_FORM:
552 			opt->max_input_form = (u_int)strtoul(optarg, NULL, 10);
553 			break;
554 		case NO_CANCEL:
555 			conf->button.without_cancel = true;
556 			break;
557 		case NO_DESCRIPTIONS:
558 			conf->menu.no_desc = true;
559 			break;
560 		case NO_LINES:
561 			conf->no_lines = true;
562 			break;
563 		case NO_NAMES:
564 			conf->menu.no_name = true;
565 			break;
566 		case NO_OK:
567 			conf->button.without_ok = true;
568 			break;
569 		case NO_SHADOW:
570 			conf->shadow = false;
571 			break;
572 		case NORMAL_SCREEN:
573 			opt->screen_mode = "rmcup";
574 			break;
575 		case OK_EXIT_CODE:
576 			set_exit_code(BSDDIALOG_OK,
577 			    (int)strtol(optarg, NULL, 10));
578 			break;
579 		case OK_LABEL:
580 			conf->button.ok_label = optarg;
581 			break;
582 		case OUTPUT_FD:
583 			opt->output_fd = (int)strtol(optarg, NULL, 10);
584 			break;
585 		case OUTPUT_SEPARATOR:
586 			opt->item_output_sep = optarg;
587 			break;
588 		case QUOTED:
589 			opt->item_always_quote = true;
590 			break;
591 		case PRINT_MAXSIZE:
592 			opt->mandatory_dialog = false;
593 			ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
594 			dprintf(opt->output_fd, "MaxSize: %d, %d\n",
595 			    ws.ws_row, ws.ws_col);
596 			break;
597 		case PRINT_SIZE:
598 			conf->get_height = &opt->getH;
599 			conf->get_width = &opt->getW;
600 			break;
601 		case PRINT_VERSION:
602 			opt->mandatory_dialog = false;
603 			dprintf(opt->output_fd, "Version: %s\n",
604 			    LIBBSDDIALOG_VERSION);
605 			break;
606 		case RIGHT1_BUTTON:
607 			conf->button.right1_label = optarg;
608 			break;
609 		case RIGHT1_EXIT_CODE:
610 			set_exit_code(BSDDIALOG_RIGHT1,
611 			    (int)strtol(optarg, NULL, 10));
612 			break;
613 		case RIGHT2_BUTTON:
614 			conf->button.right2_label = optarg;
615 			break;
616 		case RIGHT2_EXIT_CODE:
617 			set_exit_code(BSDDIALOG_RIGHT2,
618 			    (int)strtol(optarg, NULL, 10));
619 			break;
620 		case RIGHT3_BUTTON:
621 			conf->button.right3_label = optarg;
622 			break;
623 		case RIGHT3_EXIT_CODE:
624 			set_exit_code(BSDDIALOG_RIGHT3,
625 			    (int)strtol(optarg, NULL, 10));
626 			break;
627 		case SAVE_THEME:
628 			opt->mandatory_dialog = false;
629 			opt->savethemefile = optarg;
630 			break;
631 		case SEPARATE_OUTPUT:
632 			opt->item_output_sepnl = true;
633 			break;
634 		case SHADOW:
635 			conf->shadow = true;
636 			break;
637 		case SINGLE_QUOTED:
638 			opt->item_singlequote = true;
639 			break;
640 		case SLEEP:
641 			conf->sleep = (u_int)strtoul(optarg, NULL, 10);
642 			break;
643 		case STDERR:
644 			opt->output_fd = STDERR_FILENO;
645 			break;
646 		case STDOUT:
647 			opt->output_fd = STDOUT_FILENO;
648 			break;
649 		case SWITCH_BUTTONS:
650 			conf->button.always_active = false;
651 			break;
652 		case TAB_ESCAPE:
653 			opt->tab_escape = true;
654 			break;
655 		case TAB_LEN:
656 			conf->text.tablen = (u_int)strtoul(optarg, NULL, 10);
657 			break;
658 		case TEXT_ESCAPE:
659 			conf->text.escape = true;
660 			break;
661 		case TEXT_UNCHANGED:
662 			opt->text_unchanged = true;
663 			break;
664 		case THEME:
665 			if (strcasecmp(optarg, "blackwhite") == 0)
666 				opt->theme = BSDDIALOG_THEME_BLACKWHITE;
667 			else if (strcasecmp(optarg, "flat") == 0)
668 				opt->theme = BSDDIALOG_THEME_FLAT;
669 			else if (strcasecmp(optarg, "3d") == 0)
670 				opt->theme = BSDDIALOG_THEME_3D;
671 			else
672 				exit_error(true,
673 				    "--theme: \"%s\" is unknown", optarg);
674 			break;
675 		case TIMEOUT_EXIT_CODE:
676 			set_exit_code(BSDDIALOG_TIMEOUT,
677 			    (int)strtol(optarg, NULL, 10));
678 			break;
679 		case TIME_FORMAT:
680 			opt->time_fmt = optarg;
681 			break;
682 		case TITLE:
683 			conf->title = optarg;
684 			break;
685 		/* Dialogs */
686 		case CALENDAR:
687 			if (opt->dialogbuilder != NULL)
688 				exit_error(true, "%s and --calendar without "
689 				    "--and-dialog", opt->name);
690 			opt->name = "--calendar";
691 			opt->dialogbuilder = calendar_builder;
692 			break;
693 		case CHECKLIST:
694 			if (opt->dialogbuilder != NULL)
695 				exit_error(true, "%s and --checklist without "
696 				    "--and-dialog", opt->name);
697 			opt->name = "--checklist";
698 			opt->dialogbuilder = checklist_builder;
699 			conf->auto_downmargin = 1;
700 			break;
701 		case DATEBOX:
702 			if (opt->dialogbuilder != NULL)
703 				exit_error(true, "%s and --datebox without "
704 				    "--and-dialog", opt->name);
705 			opt->name = "--datebox";
706 			opt->dialogbuilder = datebox_builder;
707 			break;
708 		case FORM:
709 			if (opt->dialogbuilder != NULL)
710 				exit_error(true, "%s and --form without "
711 				    "--and-dialog", opt->name);
712 			opt->name = "--form";
713 			opt->dialogbuilder = form_builder;
714 			conf->auto_downmargin = 1;
715 			break;
716 		case GAUGE:
717 			if (opt->dialogbuilder != NULL)
718 				exit_error(true, "%s and --gauge without "
719 				    "--and-dialog", opt->name);
720 			opt->name = "--gauge";
721 			opt->dialogbuilder = gauge_builder;
722 			break;
723 		case INFOBOX:
724 			if (opt->dialogbuilder != NULL)
725 				exit_error(true, "%s and --infobox without "
726 				    "--and-dialog", opt->name);
727 			opt->name = "--infobox";
728 			opt->dialogbuilder = infobox_builder;
729 			break;
730 		case INPUTBOX:
731 			if (opt->dialogbuilder != NULL)
732 				exit_error(true, "%s and --inputbox without "
733 				    "--and-dialog", opt->name);
734 			opt->name = "--inputbox";
735 			opt->dialogbuilder = inputbox_builder;
736 			conf->auto_downmargin = 1;
737 			break;
738 		case MENU:
739 			if (opt->dialogbuilder != NULL)
740 				exit_error(true, "%s and --menu without "
741 				    "--and-dialog", opt->name);
742 			opt->name = "--menu";
743 			opt->dialogbuilder = menu_builder;
744 			conf->auto_downmargin = 1;
745 			break;
746 		case MIXEDFORM:
747 			if (opt->dialogbuilder != NULL)
748 				exit_error(true, "%s and --mixedform without "
749 				    "--and-dialog", opt->name);
750 			opt->name = "--mixedform";
751 			opt->dialogbuilder = mixedform_builder;
752 			conf->auto_downmargin = 1;
753 			break;
754 		case MIXEDGAUGE:
755 			if (opt->dialogbuilder != NULL)
756 				exit_error(true, "%s and --mixedgauge without "
757 				    "--and-dialog", opt->name);
758 			opt->name = "--mixedgauge";
759 			opt->dialogbuilder = mixedgauge_builder;
760 			break;
761 		case MSGBOX:
762 			if (opt->dialogbuilder != NULL)
763 				exit_error(true, "%s and --msgbox without "
764 				    "--and-dialog", opt->name);
765 			opt->name = "--";
766 			opt->dialogbuilder = msgbox_builder;
767 			break;
768 		case PAUSE:
769 			if (opt->dialogbuilder != NULL)
770 				exit_error(true, "%s and --pause without "
771 				    "--and-dialog", opt->name);
772 			opt->name = "--pause";
773 			opt->dialogbuilder = pause_builder;
774 			break;
775 		case PASSWORDBOX:
776 			if (opt->dialogbuilder != NULL)
777 				exit_error(true, "%s and --passwordbox without "
778 				    "--and-dialog", opt->name);
779 			opt->name = "--passwordbox";
780 			opt->dialogbuilder = passwordbox_builder;
781 			conf->auto_downmargin = 1;
782 			break;
783 		case PASSWORDFORM:
784 			if (opt->dialogbuilder != NULL)
785 				exit_error(true, "%s and --passwordform "
786 				    "without --and-dialog", opt->name);
787 			opt->name = "--passwordform";
788 			opt->dialogbuilder = passwordform_builder;
789 			conf->auto_downmargin = 1;
790 			break;
791 		case RADIOLIST:
792 			if (opt->dialogbuilder != NULL)
793 				exit_error(true, "%s and --radiolist without "
794 				    "--and-dialog", opt->name);
795 			opt->name = "--radiolist";
796 			opt->dialogbuilder = radiolist_builder;
797 			conf->auto_downmargin = 1;
798 			break;
799 		case RANGEBOX:
800 			if (opt->dialogbuilder != NULL)
801 				exit_error(true, "%s and --rangebox without "
802 				    "--and-dialog", opt->name);
803 			opt->name = "--rangebox";
804 			opt->dialogbuilder = rangebox_builder;
805 			break;
806 		case SLIDER:
807 			if (opt->dialogbuilder != NULL)
808 				exit_error(true, "%s and --slider without "
809 				    "--and-dialog", opt->name);
810 			opt->name = "--slider";
811 			opt->dialogbuilder = slider_builder;
812 			break;
813 		case TEXTBOX:
814 			if (opt->dialogbuilder != NULL)
815 				exit_error(true, "%s and --textbox without "
816 				    "--and-dialog", opt->name);
817 			opt->name = "--textbox";
818 			opt->dialogbuilder = textbox_builder;
819 			break;
820 		case TIMEBOX:
821 			if (opt->dialogbuilder != NULL)
822 				exit_error(true, "%s and --timebox without "
823 				    "--and-dialog", opt->name);
824 			opt->name = "--timebox";
825 			opt->dialogbuilder = timebox_builder;
826 			break;
827 		case TREEVIEW:
828 			if (opt->dialogbuilder != NULL)
829 				exit_error(true, "%s and --treeview without "
830 				    "--and-dialog", opt->name);
831 			opt->name = "--treeview";
832 			opt->dialogbuilder = treeview_builder;
833 			conf->auto_downmargin = 1;
834 			break;
835 		case YESNO:
836 			if (opt->dialogbuilder != NULL)
837 				exit_error(true, "%s and --yesno without "
838 				    "--and-dialog", opt->name);
839 			opt->name = "--yesno";
840 			opt->dialogbuilder = yesno_builder;
841 			break;
842 		default: /* Error */
843 			if (opt->ignore == true)
844 				break;
845 			exit_error(true, "--ignore to continue");
846 		}
847 	}
848 
849 	return (parsed);
850 }
851