1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2021-2023 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 <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33
34 #include <bsddialog.h>
35 #include <bsddialog_theme.h>
36
37 #include "util.h"
38
39 #define NO_PRINT_VALUES(rv) \
40 (rv == BSDDIALOG_ERROR || rv == BSDDIALOG_CANCEL || rv == BSDDIALOG_ESC)
41
42 /* message */
infobox_builder(BUILDER_ARGS)43 int infobox_builder(BUILDER_ARGS)
44 {
45 if (argc > 0)
46 error_args(opt->name, argc, argv);
47
48 return (bsddialog_infobox(conf, text, rows, cols));
49 }
50
msgbox_builder(BUILDER_ARGS)51 int msgbox_builder(BUILDER_ARGS)
52 {
53 if (argc > 0)
54 error_args(opt->name, argc, argv);
55
56 return (bsddialog_msgbox(conf, text, rows, cols));
57 }
58
yesno_builder(BUILDER_ARGS)59 int yesno_builder(BUILDER_ARGS)
60 {
61 if (argc > 0)
62 error_args(opt->name, argc, argv);
63
64 return (bsddialog_yesno(conf, text, rows, cols));
65 }
66
67 /* textbox */
textbox_builder(BUILDER_ARGS)68 int textbox_builder(BUILDER_ARGS)
69 {
70 if (argc > 0)
71 error_args(opt->name, argc, argv);
72
73 return (bsddialog_textbox(conf, text, rows, cols));
74 }
75
76 /* bar */
gauge_builder(BUILDER_ARGS)77 int gauge_builder(BUILDER_ARGS)
78 {
79 int output;
80 unsigned int perc;
81
82 perc = 0;
83 if (argc == 1) {
84 perc = (u_int)strtoul(argv[0], NULL, 10);
85 perc = perc > 100 ? 100 : perc;
86 } else if (argc > 1) {
87 error_args(opt->name, argc - 1, argv + 1);
88 }
89
90 output = bsddialog_gauge(conf, text, rows, cols, perc, STDIN_FILENO,
91 "XXX", "EOF");
92
93 return (output);
94 }
95
mixedgauge_builder(BUILDER_ARGS)96 int mixedgauge_builder(BUILDER_ARGS)
97 {
98 int output, *minipercs;
99 unsigned int i, mainperc, nminibars;
100 const char **minilabels;
101
102 if (argc < 1)
103 exit_error(true, "%s missing <mainperc>", opt->name);
104 if (((argc-1) % 2) != 0)
105 exit_error(true,
106 "bad %s pair number [<minilabel> <miniperc>]", opt->name);
107
108 mainperc = (u_int)strtoul(argv[0], NULL, 10);
109 mainperc = mainperc > 100 ? 100 : mainperc;
110 argc--;
111 argv++;
112
113 nminibars = argc / 2;
114 if ((minilabels = calloc(nminibars, sizeof(char*))) == NULL)
115 exit_error(false, "Cannot allocate memory for minilabels");
116 if ((minipercs = calloc(nminibars, sizeof(int))) == NULL)
117 exit_error(false, "Cannot allocate memory for minipercs");
118
119 for (i = 0; i < nminibars; i++) {
120 minilabels[i] = argv[i * 2];
121 minipercs[i] = (int)strtol(argv[i * 2 + 1], NULL, 10);
122 }
123
124 output = bsddialog_mixedgauge(conf, text, rows, cols, mainperc,
125 nminibars, minilabels, minipercs);
126
127 return (output);
128 }
129
pause_builder(BUILDER_ARGS)130 int pause_builder(BUILDER_ARGS)
131 {
132 int output;
133 unsigned int secs;
134
135 if (argc == 0)
136 exit_error(true, "--pause missing <seconds>");
137 if (argc > 1)
138 error_args(opt->name, argc - 1, argv + 1);
139
140 secs = (u_int)strtoul(argv[0], NULL, 10);
141 output = bsddialog_pause(conf, text, rows, cols, &secs);
142
143 return (output);
144 }
145
rangebox_builder(BUILDER_ARGS)146 int rangebox_builder(BUILDER_ARGS)
147 {
148 int output, min, max, value;
149
150 if (argc < 2)
151 exit_error(true, "--rangebox missing <min> <max> [<init>]");
152 if (argc > 3)
153 error_args("--rangebox", argc - 3, argv + 3);
154
155 min = (int)strtol(argv[0], NULL, 10);
156 max = (int)strtol(argv[1], NULL, 10);
157
158 if (argc == 3) {
159 value = (int)strtol(argv[2], NULL, 10);
160 value = value < min ? min : value;
161 value = value > max ? max : value;
162 } else
163 value = min;
164
165 output = bsddialog_rangebox(conf, text, rows, cols, min, max, &value);
166 if (NO_PRINT_VALUES(output) == false)
167 dprintf(opt->output_fd, "%d", value);
168
169 return (output);
170 }
171
172 /* date and time */
date(BUILDER_ARGS)173 static int date(BUILDER_ARGS)
174 {
175 int rv;
176 unsigned int yy, mm, dd;
177 time_t cal;
178 struct tm *localtm;
179 char stringdate[1024];
180
181 time(&cal);
182 localtm = localtime(&cal);
183 yy = localtm->tm_year + 1900;
184 mm = localtm->tm_mon + 1;
185 dd = localtm->tm_mday;
186
187 if (argc > 3) {
188 error_args(opt->name, argc - 3, argv + 3);
189 } else if (argc == 3) {
190 /* lib checks/sets max and min */
191 dd = (u_int)strtoul(argv[0], NULL, 10);
192 mm = (u_int)strtoul(argv[1], NULL, 10);
193 yy = (u_int)strtoul(argv[2], NULL, 10);
194 }
195
196 if (strcmp(opt->name, "--datebox") == 0)
197 rv = bsddialog_datebox(conf, text, rows, cols, &yy, &mm, &dd);
198 else
199 rv = bsddialog_calendar(conf, text, rows, cols, &yy, &mm, &dd);
200 if (NO_PRINT_VALUES(rv))
201 return (rv);
202
203 if (opt->date_fmt != NULL) {
204 time(&cal);
205 localtm = localtime(&cal);
206 localtm->tm_year = yy - 1900;
207 localtm->tm_mon = mm - 1;
208 localtm->tm_mday = dd;
209 strftime(stringdate, 1024, opt->date_fmt, localtm);
210 dprintf(opt->output_fd, "%s", stringdate);
211 } else if (opt->bikeshed && ~dd & 1) {
212 dprintf(opt->output_fd, "%u/%u/%u", dd, mm, yy);
213 } else {
214 dprintf(opt->output_fd, "%02u/%02u/%u", dd, mm, yy);
215 }
216
217 return (rv);
218 }
219
calendar_builder(BUILDER_ARGS)220 int calendar_builder(BUILDER_ARGS)
221 {
222 /* Use height autosizing with rows = 2. Documented in bsddialog(1).
223 *
224 * f_dialog_calendar_size() in bsdconfig/share/dialog.subr:1352
225 * computes height 2 for `dialog --calendar', called by:
226 * 1) f_dialog_input_expire_password() in
227 * bsdconfig/usermgmt/share/user_input.subr:517 and
228 * 2) f_dialog_input_expire_account() in
229 * bsdconfig/usermgmt/share/user_input.subr:660.
230 *
231 * Then use height autosizing with 2 that is min height like dialog.
232 */
233 if (rows == 2)
234 rows = 0;
235
236 return (date(conf, text, rows, cols, argc, argv, opt));
237 }
238
datebox_builder(BUILDER_ARGS)239 int datebox_builder(BUILDER_ARGS)
240 {
241 return (date(conf, text, rows, cols, argc, argv, opt));
242 }
243
timebox_builder(BUILDER_ARGS)244 int timebox_builder(BUILDER_ARGS)
245 {
246 int output;
247 unsigned int hh, mm, ss;
248 time_t clock;
249 struct tm *localtm;
250 char stringtime[1024];
251
252 time(&clock);
253 localtm = localtime(&clock);
254 hh = localtm->tm_hour;
255 mm = localtm->tm_min;
256 ss = localtm->tm_sec;
257
258 if (argc > 3) {
259 error_args("--timebox", argc - 3, argv + 3);
260 } else if (argc == 3) {
261 hh = (u_int)strtoul(argv[0], NULL, 10);
262 mm = (u_int)strtoul(argv[1], NULL, 10);
263 ss = (u_int)strtoul(argv[2], NULL, 10);
264 }
265
266 output = bsddialog_timebox(conf, text, rows, cols, &hh, &mm, &ss);
267 if (NO_PRINT_VALUES(output))
268 return (output);
269
270 if (opt->time_fmt != NULL) {
271 time(&clock);
272 localtm = localtime(&clock);
273 localtm->tm_hour = hh;
274 localtm->tm_min = mm;
275 localtm->tm_sec = ss;
276 strftime(stringtime, 1024, opt->time_fmt, localtm);
277 dprintf(opt->output_fd, "%s", stringtime);
278 } else if (opt->bikeshed && ~ss & 1) {
279 dprintf(opt->output_fd, "%u:%u:%u", hh, mm, ss);
280 } else {
281 dprintf(opt->output_fd, "%02u:%02u:%02u", hh, mm, ss);
282 }
283
284 return (output);
285 }
286
287 /* menu */
288 static void
get_menu_items(int argc,char ** argv,bool setprefix,bool setdepth,bool setname,bool setdesc,bool setstatus,bool sethelp,unsigned int * nitems,struct bsddialog_menuitem ** items,int * focusitem,struct options * opt)289 get_menu_items(int argc, char **argv, bool setprefix, bool setdepth,
290 bool setname, bool setdesc, bool setstatus, bool sethelp,
291 unsigned int *nitems, struct bsddialog_menuitem **items, int *focusitem,
292 struct options *opt)
293 {
294 unsigned int i, j, sizeitem;
295
296 *focusitem = -1;
297
298 sizeitem = 0;
299 sizeitem += setprefix ? 1 : 0;
300 sizeitem += setdepth ? 1 : 0;
301 sizeitem += setname ? 1 : 0;
302 sizeitem += setdesc ? 1 : 0;
303 sizeitem += setstatus ? 1 : 0;
304 sizeitem += sethelp ? 1 : 0;
305 if ((argc % sizeitem) != 0)
306 exit_error(true, "%s bad arguments items number", opt->name);
307
308 *nitems = argc / sizeitem;
309 *items = calloc(*nitems, sizeof(struct bsddialog_menuitem));
310 if (items == NULL)
311 exit_error(false, "%s cannot allocate items", opt->name);
312
313 j = 0;
314 for (i = 0; i < *nitems; i++) {
315 (*items)[i].prefix = setprefix ? argv[j++] : "";
316 (*items)[i].depth = setdepth ?
317 (u_int)strtoul(argv[j++], NULL, 0) : 0;
318 (*items)[i].name = setname ? argv[j++] : "";
319 (*items)[i].desc = setdesc ? argv[j++] : "";
320 if (setstatus) {
321 if (strcasecmp(argv[j], "on") == 0)
322 (*items)[i].on = true;
323 else if (strcasecmp(argv[j], "off") == 0)
324 (*items)[i].on = false;
325 else
326 exit_error(true,
327 "\"%s\" (item %i) invalid status \"%s\"",
328 (*items)[i].name, i+1, argv[j]);
329 j++;
330 } else
331 (*items)[i].on = false;
332 (*items)[i].bottomdesc = sethelp ? argv[j++] : "";
333
334 if (opt->item_default != NULL && *focusitem == -1)
335 if (strcmp((*items)[i].name, opt->item_default) == 0)
336 *focusitem = i;
337 }
338 }
339
340 static void
print_menu_items(int output,int nitems,struct bsddialog_menuitem * items,int focusitem,struct options * opt)341 print_menu_items(int output, int nitems, struct bsddialog_menuitem *items,
342 int focusitem, struct options *opt)
343 {
344 bool sep, sepbefore, sepafter, sepsecond, toquote, ismenu, ischecklist;
345 int i;
346 char quotech;
347 const char *focusname, *sepstr;
348
349 ismenu = (strcmp(opt->name, "--menu") == 0) ? true : false;
350 ischecklist = (strcmp(opt->name, "--checklist") == 0) ? true : false;
351 sep = false;
352 quotech = opt->item_singlequote ? '\'' : '"';
353
354 if (NO_PRINT_VALUES(output))
355 return;
356
357 if (output == BSDDIALOG_HELP) {
358 dprintf(opt->output_fd, "HELP ");
359
360 if (focusitem >= 0) {
361 focusname = items[focusitem].name;
362 if (opt->item_bottomdesc &&
363 opt->help_print_item_name == false)
364 focusname = items[focusitem].bottomdesc;
365
366 toquote = false;
367 if (strchr(focusname, ' ') != NULL) {
368 toquote = opt->item_always_quote;
369 if (ismenu == false &&
370 opt->item_output_sepnl == false)
371 toquote = true;
372 }
373 if (toquote) {
374 dprintf(opt->output_fd, "%c%s%c",
375 quotech, focusname, quotech);
376 } else
377 dprintf(opt->output_fd, "%s", focusname);
378 }
379
380 if (ismenu || opt->help_print_items == false)
381 return;
382 sep = true;
383 }
384
385 sepbefore = false;
386 sepsecond = false;
387 if ((sepstr = opt->item_output_sep) == NULL) {
388 if (opt->item_output_sepnl)
389 sepstr = "\n";
390 else {
391 sepstr = " ";
392 sepsecond = true;
393 }
394 } else
395 sepbefore = true;
396
397 sepafter = false;
398 if (opt->item_output_sepnl) {
399 sepbefore = false;
400 sepafter = true;
401 }
402
403 for (i = 0; i < nitems; i++) {
404 if (items[i].on == false)
405 continue;
406
407 if (sep || sepbefore)
408 dprintf(opt->output_fd, "%s", sepstr);
409 sep = false;
410 if (sepsecond)
411 sep = true;
412
413 toquote = false;
414 if (strchr(items[i].name, ' ') != NULL) {
415 toquote = opt->item_always_quote;
416 if (ischecklist && opt->item_output_sepnl == false)
417 toquote = true;
418 }
419 if (toquote)
420 dprintf(opt->output_fd, "%c%s%c",
421 quotech, items[i].name, quotech);
422 else
423 dprintf(opt->output_fd, "%s", items[i].name);
424
425 if (sepafter)
426 dprintf(opt->output_fd, "%s", sepstr);
427 }
428 }
429
checklist_builder(BUILDER_ARGS)430 int checklist_builder(BUILDER_ARGS)
431 {
432 int output, focusitem;
433 unsigned int menurows, nitems;
434 struct bsddialog_menuitem *items;
435
436 if (argc < 1)
437 exit_error(true, "--checklist missing <menurows>");
438 menurows = (u_int)strtoul(argv[0], NULL, 10);
439
440 get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
441 true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
442
443 output = bsddialog_checklist(conf, text, rows, cols, menurows, nitems,
444 items, &focusitem);
445
446 print_menu_items(output, nitems, items, focusitem, opt);
447 free(items);
448
449 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
450 output = BSDDIALOG_ITEM_HELP;
451
452 return (output);
453 }
454
menu_builder(BUILDER_ARGS)455 int menu_builder(BUILDER_ARGS)
456 {
457 int output, focusitem;
458 unsigned int menurows, nitems;
459 struct bsddialog_menuitem *items;
460
461 if (argc < 1)
462 exit_error(true, "--menu missing <menurows>");
463 menurows = (u_int)strtoul(argv[0], NULL, 10);
464
465 get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
466 true, false, opt->item_bottomdesc, &nitems, &items, &focusitem,
467 opt);
468
469 output = bsddialog_menu(conf, text, rows, cols, menurows, nitems,
470 items, &focusitem);
471
472 print_menu_items(output, nitems, items, focusitem, opt);
473 free(items);
474
475 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
476 output = BSDDIALOG_ITEM_HELP;
477
478 return (output);
479 }
480
radiolist_builder(BUILDER_ARGS)481 int radiolist_builder(BUILDER_ARGS)
482 {
483 int output, focusitem;
484 unsigned int menurows, nitems;
485 struct bsddialog_menuitem *items;
486
487 if (argc < 1)
488 exit_error(true, "--radiolist missing <menurows>");
489 menurows = (u_int)strtoul(argv[0], NULL, 10);
490
491 get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
492 true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
493
494 output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
495 items, &focusitem);
496
497 print_menu_items(output, nitems, items, focusitem, opt);
498 free(items);
499
500 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
501 output = BSDDIALOG_ITEM_HELP;
502
503 return (output);
504 }
505
treeview_builder(BUILDER_ARGS)506 int treeview_builder(BUILDER_ARGS)
507 {
508 int output, focusitem;
509 unsigned int menurows, nitems;
510 struct bsddialog_menuitem *items;
511
512 if (argc < 1)
513 exit_error(true, "--treeview missing <menurows>");
514 menurows = (u_int)strtoul(argv[0], NULL, 10);
515
516 get_menu_items(argc-1, argv+1, opt->item_prefix, true, true, true, true,
517 opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
518
519 conf->menu.no_name = true;
520 conf->menu.align_left = true;
521
522 output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
523 items, &focusitem);
524
525 print_menu_items(output, nitems, items, focusitem, opt);
526 free(items);
527
528 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
529 output = BSDDIALOG_ITEM_HELP;
530
531 return (output);
532 }
533
534 /* form */
535 static void
print_form_items(int output,int nitems,struct bsddialog_formitem * items,int focusitem,struct options * opt)536 print_form_items(int output, int nitems, struct bsddialog_formitem *items,
537 int focusitem, struct options *opt)
538 {
539 int i;
540 const char *helpname;
541
542 if (NO_PRINT_VALUES(output))
543 return;
544
545 if (output == BSDDIALOG_HELP) {
546 dprintf(opt->output_fd, "HELP");
547 if (focusitem >= 0) {
548 helpname = items[focusitem].label;
549 if (opt->item_bottomdesc &&
550 opt->help_print_item_name == false)
551 helpname = items[focusitem].bottomdesc;
552 dprintf(opt->output_fd, " %s", helpname);
553 }
554 if(opt->help_print_items == false)
555 return;
556 dprintf(opt->output_fd, "\n");
557 }
558
559 for (i = 0; i < nitems; i++) {
560 dprintf(opt->output_fd, "%s\n", items[i].value);
561 free(items[i].value);
562 }
563 }
564
form_builder(BUILDER_ARGS)565 int form_builder(BUILDER_ARGS)
566 {
567 int output, fieldlen, valuelen, focusitem;
568 unsigned int i, j, flags, formheight, nitems, sizeitem;
569 struct bsddialog_formitem *items;
570
571 if (argc < 1)
572 exit_error(true, "--form missing <formheight>");
573 formheight = (u_int)strtoul(argv[0], NULL, 10);
574
575 argc--;
576 argv++;
577 sizeitem = opt->item_bottomdesc ? 9 : 8;
578 if (argc % sizeitem != 0)
579 exit_error(true, "--form bad number of arguments items");
580
581 nitems = argc / sizeitem;
582 if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
583 exit_error(false, "cannot allocate memory for form items");
584 j = 0;
585 for (i = 0; i < nitems; i++) {
586 items[i].label = argv[j++];
587 items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
588 items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
589 items[i].init = argv[j++];
590 items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
591 items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
592
593 fieldlen = (int)strtol(argv[j++], NULL, 10);
594 items[i].fieldlen = abs(fieldlen);
595
596 valuelen = (int)strtol(argv[j++], NULL, 10);
597 items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
598
599 flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
600 items[i].flags = flags;
601
602 items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
603 }
604
605 focusitem = -1;
606 output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
607 items, &focusitem);
608 print_form_items(output, nitems, items, focusitem, opt);
609 free(items);
610
611 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
612 output = BSDDIALOG_ITEM_HELP;
613
614 return (output);
615 }
616
inputbox_builder(BUILDER_ARGS)617 int inputbox_builder(BUILDER_ARGS)
618 {
619 int output;
620 struct bsddialog_formitem item;
621
622 if (argc > 1)
623 error_args("--inputbox", argc - 1, argv + 1);
624
625 item.label = "";
626 item.ylabel = 0;
627 item.xlabel = 0;
628 item.init = argc > 0 ? argv[0] : "";
629 item.yfield = 0;
630 item.xfield = 0;
631 item.fieldlen = 1;
632 item.maxvaluelen = opt->max_input_form;
633 item.flags = BSDDIALOG_FIELDNOCOLOR;
634 item.flags |= BSDDIALOG_FIELDCURSOREND;
635 item.flags |= BSDDIALOG_FIELDEXTEND;
636 item.bottomdesc = "";
637
638 output = bsddialog_form(conf, text, rows, cols, 1, 1, &item, NULL);
639 print_form_items(output, 1, &item, -1, opt);
640
641 return (output);
642 }
643
mixedform_builder(BUILDER_ARGS)644 int mixedform_builder(BUILDER_ARGS)
645 {
646 int output, focusitem;
647 unsigned int i, j, formheight, nitems, sizeitem;
648 struct bsddialog_formitem *items;
649
650 if (argc < 1)
651 exit_error(true, "--mixedform missing <formheight>");
652 formheight = (u_int)strtoul(argv[0], NULL, 10);
653
654 argc--;
655 argv++;
656 sizeitem = opt->item_bottomdesc ? 10 : 9;
657 if (argc % sizeitem != 0)
658 exit_error(true, "--mixedform bad number of arguments items");
659
660 nitems = argc / sizeitem;
661 if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
662 exit_error(false, "cannot allocate memory for form items");
663 j = 0;
664 for (i = 0; i < nitems; i++) {
665 items[i].label = argv[j++];
666 items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
667 items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
668 items[i].init = argv[j++];
669 items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
670 items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
671 items[i].fieldlen = (u_int)strtoul(argv[j++], NULL, 10);
672 items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
673 items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
674 items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
675 }
676
677 focusitem = -1;
678 output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
679 items, &focusitem);
680 print_form_items(output, nitems, items, focusitem, opt);
681 free(items);
682
683 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
684 output = BSDDIALOG_ITEM_HELP;
685
686 return (output);
687 }
688
passwordbox_builder(BUILDER_ARGS)689 int passwordbox_builder(BUILDER_ARGS)
690 {
691 int output;
692 struct bsddialog_formitem item;
693
694 if (argc > 1)
695 error_args("--passwordbox", argc - 1, argv + 1);
696
697 item.label = "";
698 item.ylabel = 0;
699 item.xlabel = 0;
700 item.init = argc > 0 ? argv[0] : "";
701 item.yfield = 0;
702 item.xfield = 0;
703 item.fieldlen = 1;
704 item.maxvaluelen = opt->max_input_form;
705 item.flags = BSDDIALOG_FIELDHIDDEN;
706 item.flags |= BSDDIALOG_FIELDNOCOLOR;
707 item.flags |= BSDDIALOG_FIELDCURSOREND;
708 item.flags |= BSDDIALOG_FIELDEXTEND;
709 item.bottomdesc = "";
710
711 output = bsddialog_form(conf, text, rows, cols, 1, 1, &item, NULL);
712 print_form_items(output, 1, &item, -1, opt);
713
714 return (output);
715 }
716
passwordform_builder(BUILDER_ARGS)717 int passwordform_builder(BUILDER_ARGS)
718 {
719 int output, fieldlen, valuelen, focusitem;
720 unsigned int i, j, flags, formheight, nitems, sizeitem;
721 struct bsddialog_formitem *items;
722
723 if (argc < 1)
724 exit_error(true, "--passwordform missing <formheight>");
725 formheight = (u_int)strtoul(argv[0], NULL, 10);
726
727 argc--;
728 argv++;
729 sizeitem = opt->item_bottomdesc ? 9 : 8;
730 if (argc % sizeitem != 0)
731 exit_error(true, "--passwordform bad arguments items number");
732
733 flags = BSDDIALOG_FIELDHIDDEN;
734 nitems = argc / sizeitem;
735 if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
736 exit_error(false, "cannot allocate memory for form items");
737 j = 0;
738 for (i = 0; i < nitems; i++) {
739 items[i].label = argv[j++];
740 items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
741 items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
742 items[i].init = argv[j++];
743 items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
744 items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
745
746 fieldlen = (int)strtol(argv[j++], NULL, 10);
747 items[i].fieldlen = abs(fieldlen);
748
749 valuelen = (int)strtol(argv[j++], NULL, 10);
750 items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
751
752 flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
753 items[i].flags = flags;
754
755 items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
756 }
757
758 focusitem = -1;
759 output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
760 items, &focusitem);
761 print_form_items(output, nitems, items, focusitem, opt);
762 free(items);
763
764 if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
765 output = BSDDIALOG_ITEM_HELP;
766
767 return (output);
768 }
769