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 */ 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 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 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 */ 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 */ 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 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 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 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 */ 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 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 239 int datebox_builder(BUILDER_ARGS) 240 { 241 return (date(conf, text, rows, cols, argc, argv, opt)); 242 } 243 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 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 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 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 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 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 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 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 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 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 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 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 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