1if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1 2# 3# Copyright (c) 2006-2012 Devin Teske 4# All Rights Reserved. 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 (INLUDING, 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# $FreeBSD$ 28# 29############################################################ INCLUDES 30 31BSDCFG_SHARE="/usr/share/bsdconfig" 32. $BSDCFG_SHARE/common.subr || exit 1 33f_dprintf "%s: loading includes..." dialog.subr 34f_include $BSDCFG_SHARE/strings.subr 35 36BSDCFG_LIBE="/usr/libexec/bsdconfig" 37f_include_lang $BSDCFG_LIBE/include/messages.subr 38 39############################################################ CONFIGURATION 40 41# 42# Default file descriptor to link to stdout for dialog(1) passthru allowing 43# execution of dialog from within a sub-shell (so-long as its standard output 44# is explicitly redirected to this file descriptor). 45# 46: ${DIALOG_TERMINAL_PASSTHRU_FD:=${TERMINAL_STDOUT_PASSTHRU:-3}} 47 48############################################################ GLOBALS 49 50# 51# Default name of dialog(1) utility 52# NOTE: This is changed to "Xdialog" by the optional `-X' argument 53# 54DIALOG="dialog" 55 56# 57# Default dialog(1) title and backtitle text 58# 59DIALOG_TITLE="$pgm" 60DIALOG_BACKTITLE="bsdconfig" 61 62# 63# Settings used while interacting with dialog(1) 64# 65DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz" 66 67# 68# Declare that we are fully-compliant with Xdialog(1) by unset'ing all 69# compatibility settings. 70# 71unset XDIALOG_HIGH_DIALOG_COMPAT 72unset XDIALOG_FORCE_AUTOSIZE 73unset XDIALOG_INFOBOX_TIMEOUT 74 75# 76# Default behavior is to call f_dialog_init() automatically when loaded. 77# 78: ${DIALOG_SELF_INITIALIZE=1} 79 80# 81# Default terminal size (used if/when running without a controlling terminal) 82# 83: ${DEFAULT_TERMINAL_SIZE:=24 80} 84 85############################################################ GENERIC FUNCTIONS 86 87# f_dialog_title [$new_title] 88# 89# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1) 90# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first 91# argument is NULL, the current title is returned. 92# 93# Each time this function is called, a backup of the current values is made 94# allowing a one-time (single-level) restoration of the previous title using the 95# f_dialog_title_restore() function (below). 96# 97f_dialog_title() 98{ 99 local new_title="$1" 100 101 if [ "${1+set}" ]; then 102 if [ "$USE_XDIALOG" ]; then 103 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" 104 DIALOG_BACKTITLE="$new_title" 105 else 106 _DIALOG_TITLE="$DIALOG_TITLE" 107 DIALOG_TITLE="$new_title" 108 fi 109 else 110 if [ "$USE_XDIALOG" ]; then 111 echo "$DIALOG_BACKTITLE" 112 else 113 echo "$DIALOG_TITLE" 114 fi 115 fi 116} 117 118# f_dialog_title_restore 119# 120# Restore the previous title set by the last call to f_dialog_title(). 121# Restoration is non-recursive and only works to restore the most-recent title. 122# 123f_dialog_title_restore() 124{ 125 if [ "$USE_XDIALOG" ]; then 126 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" 127 else 128 DIALOG_TITLE="$_DIALOG_TITLE" 129 fi 130} 131 132# f_dialog_backtitle [$new_backtitle] 133# 134# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of 135# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the 136# first argument is NULL, the current backtitle is returned. 137# 138f_dialog_backtitle() 139{ 140 local new_backtitle="$1" 141 142 if [ "${1+set}" ]; then 143 if [ "$USE_XDIALOG" ]; then 144 _DIALOG_TITLE="$DIALOG_TITLE" 145 DIALOG_TITLE="$new_backtitle" 146 else 147 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" 148 DIALOG_BACKTITLE="$new_backtitle" 149 fi 150 else 151 if [ "$USE_XDIALOG" ]; then 152 echo "$DIALOG_TITLE" 153 else 154 echo "$DIALOG_BACKTITLE" 155 fi 156 fi 157} 158 159# f_dialog_backtitle_restore 160# 161# Restore the previous backtitle set by the last call to f_dialog_backtitle(). 162# Restoration is non-recursive and only works to restore the most-recent 163# backtitle. 164# 165f_dialog_backtitle_restore() 166{ 167 if [ "$USE_XDIALOG" ]; then 168 DIALOG_TITLE="$_DIALOG_TITLE" 169 else 170 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" 171 fi 172} 173 174############################################################ SIZE FUNCTIONS 175 176# f_dialog_infobox_size $title $backtitle $prompt [$hline] 177# 178# Not all versions of dialog(1) perform auto-sizing of the width and height of 179# `--infobox' boxes sensibly. 180# 181# This function helps solve this issue by taking as arguments (in order of 182# appearance) the title, backtitle, prompt, and [optionally] hline returning 183# the optimal width and height for the box (not exceeding the actual terminal 184# width or height). 185# 186# Newline character sequences (``\n'') in $prompt are expanded as-is done by 187# dialog(1). 188# 189# Output is in the format of "height width". 190# 191f_dialog_infobox_size() 192{ 193 local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 194 local min_width max_size 195 196 if [ "$USE_XDIALOG" ]; then 197 min_width=35 198 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 199 else 200 min_width=24 201 max_size=$( stty size 2> /dev/null ) # usually "24 80" 202 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 203 fi 204 205 local max_height="${max_size%%[$IFS]*}" 206 local max_width="${max_size##*[$IFS]}" 207 local height width=$min_width 208 209 # 210 # Bump width for long titles (but don't exceed terminal width). 211 # 212 n=$(( ${#title} + 4 )) 213 if [ $n -gt $width -a $n -gt $min_width ]; then 214 # Add 16.6% width for Xdialog(1) 215 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) 216 217 if [ $n -lt $max_width ]; then 218 width=$n 219 else 220 width=$max_width 221 fi 222 fi 223 224 # 225 # For Xdialog(1), bump width for long backtitles (which appear within 226 # the window; don't exceed maximum width). 227 # 228 if [ "$USE_XDIALOG" ]; then 229 n=$(( ${#btitle} + 4 )) 230 n=$(( $n + $n / 6 )) 231 if [ $n -gt $width -a $n -gt $min_width ]; then 232 if [ $n -lt $max_width ]; then 233 width=$n 234 else 235 width=$max_width 236 fi 237 fi 238 fi 239 240 # 241 # Bump width for long prompts (if not already at maximum width). 242 # 243 if [ $width -lt $max_width ]; then 244 n=$( echo "$prompt" | f_longest_line_length ) 245 n=$(( $n + 4 )) 246 247 # Add 16.6% width for Xdialog(1) 248 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) 249 250 if [ $n -gt $width -a $n -gt $min_width ]; then 251 if [ $n -lt $max_width ]; then 252 width=$n 253 else 254 width=$max_width 255 fi 256 fi 257 fi 258 259 # 260 # Bump width for long hlines (if not already at maximum width). 261 # NOTE: Though Xdialog(1) supports `--hline', it's not currently used. 262 # 263 if [ ! "$USE_XDIALOG" ]; then 264 if [ $width -lt $max_width ]; then 265 n=$(( ${#hline} + 10 )) 266 if [ $n -gt $width -a $n -gt $min_width ]; then 267 if [ $n -lt $max_width ]; then 268 width=$n 269 else 270 width=$max_width 271 fi 272 fi 273 fi 274 fi 275 276 # 277 # Set height based on number of rows in prompt 278 # 279 height=$( echo -n "$prompt" | f_number_of_lines ) 280 height=$(( $height + 2 )) 281 282 # 283 # For Xdialog(1) bump height if backtitle is enabled (displayed in the 284 # X11 window with a separator line between the backtitle and msg text) 285 # 286 if [ "$USE_XDIALOG" -a "$btitle" ]; then 287 n=$( echo "$btitle" | f_number_of_lines ) 288 height=$(( $height + $n + 2 )) 289 fi 290 291 # Make sure height is less than maximum screen size 292 [ $height -le $max_height ] || height=$max_height 293 294 # Return both 295 echo "$height $width" 296} 297 298# f_dialog_buttonbox_size $title $backtitle $prompt [$hline] 299# 300# Not all versions of dialog(1) perform auto-sizing of the width and height of 301# `--msgbox' and `--yesno' boxes sensibly. 302# 303# This function helps solve this issue by taking as arguments (in order of 304# appearance) the title, backtitle, prompt, and [optionally] hline returning 305# the optimal width and height for the box (not exceeding the actual terminal 306# width or height). 307# 308# Newline character sequences (``\n'') in $prompt are expanded as-is done by 309# dialog(1). 310# 311# Output is in the format of "height width". 312# 313f_dialog_buttonbox_size() 314{ 315 local title="$1" btitle="$2" prompt="$3" hline="$4" 316 local size="$( f_dialog_infobox_size \ 317 "$title" "$btitle" "$prompt" "$hline" )" 318 local height="${size%%[$IFS]*}" 319 local width="${size##*[$IFS]}" 320 321 # Add height to accomodate the buttons 322 height=$(( $height + 2 )) 323 324 # Adjust for clipping with Xdialog(1) on Linux/GTK2 325 [ "$USE_XDIALOG" ] && height=$(( $height + 3 )) 326 327 # 328 # Enforce maximum height regardless 329 # 330 local max_size 331 if [ "$USE_XDIALOG" ]; then 332 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 333 else 334 max_size=$( stty size 2> /dev/null ) # usually "24 80" 335 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 336 fi 337 local max_height="${max_size%%[$IFS]*}" 338 [ $height -le $max_height ] || height=$max_height 339 340 # Return both 341 echo "$height $width" 342} 343 344# f_dialog_inputbox_size $title $backtitle $prompt $init [$hline] 345# 346# Not all versions of dialog(1) perform auto-sizing of the width and height of 347# `--inputbox' boxes sensibly. 348# 349# This function helps solve this issue by taking as arguments (in order of 350# appearance) the title, backtitle, prompt, initial text, and [optionally] 351# hline returning the optimal width and height for the box (not exceeding the 352# actual terminal width and height). 353# 354# Newline character sequences (``\n'') in $prompt are expanded as-is done by 355# dialog(1). 356# 357# Output is in the format of "height width". 358# 359f_dialog_inputbox_size() 360{ 361 local title="$1" btitle="$2" prompt="$3" init="$4" hline="$5" n 362 local size="$( f_dialog_buttonbox_size \ 363 "$title" "$btitle" "$prompt" "$hline" )" 364 local height="${size%%[$IFS]*}" 365 local width="${size##*[$IFS]}" 366 367 local min_width max_size 368 if [ "$USE_XDIALOG" ]; then 369 min_width=35 370 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 371 else 372 min_width=24 373 max_size=$( stty size 2> /dev/null ) # usually "24 80" 374 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 375 fi 376 local max_height="${max_size%%[$IFS]*}" 377 local max_width="${max_size##*[$IFS]}" 378 379 # 380 # Add height to accomodate the input box 381 # 382 [ ! "$USE_XDIALOG" ] && height=$(( $height + 3 )) 383 [ $height -le $max_height ] || height=$max_height 384 385 # 386 # Bump width for initial text (if not already at maximum width). 387 # NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it! 388 # 389 if [ $width -lt $max_width ]; then 390 n=$(( ${#init} + 7 )) 391 392 # Add 16.6% width for Xdialog(1) 393 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) 394 395 if [ $n -gt $width -a $n -gt $min_width ]; then 396 if [ $n -lt $max_width ]; then 397 width=$n 398 else 399 width=$max_width 400 fi 401 fi 402 fi 403 404 # Return both 405 echo "$height $width" 406} 407 408# f_xdialog_2inputsbox_size $title $backtitle $prompt \ 409# $label1 $init1 $label2 $init2 410# 411# Xdialog(1) does not perform auto-sizing of the width and height of 412# `--2inputsbox' boxes sensibly. 413# 414# This function helps solve this issue by taking as arguments (in order of 415# appearance) the title, backtitle, prompt, label for the first field, initial 416# text for said field, label for the second field, and initial text for said 417# field returning the optimal width and height for the box (not exceeding the 418# actual terminal width and height). 419# 420# Newline character sequences (``\n'') in $prompt are expanded as-is done by 421# Xdialog(1). 422# 423# Output is in the format of "height width". 424# 425f_xdialog_2inputsbox_size() 426{ 427 local title="$1" btitle="$2" prompt="$3" 428 local label1="$4" init1="$5" label2="$6" init2="$7" n 429 local size="$( f_dialog_inputbox_size \ 430 "$title" "$btitle" "$prompt" "$init1" )" 431 local height="${size%%[$IFS]*}" 432 local width="${size##*[$IFS]}" 433 434 local min_width=35 435 local max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 436 local max_height="${max_size%%[$IFS]*}" 437 local max_width="${max_size##*[$IFS]}" 438 439 # Add height for first label 440 height=$(( $height + 2 )) 441 442 # 443 # Bump width for first label text (if not already at maximum width). 444 # 445 if [ $width -lt $max_width ]; then 446 n=$(( ${#label1} + 7 )) 447 448 # Add 16.6% width for Xdialog(1) 449 n=$(( $n + $n / 6 )) 450 451 if [ $n -gt $width -a $n -gt $min_width ]; then 452 if [ $n -lt $max_width ]; then 453 width=$n 454 else 455 width=$max_width 456 fi 457 fi 458 fi 459 460 # Add height for second label 461 height=$(( $height + 2 )) 462 463 # 464 # Bump width for second label text (if not already at maximum width). 465 # 466 if [ $width -lt $max_width ]; then 467 n=$(( ${#label2} + 7 )) 468 469 # Add 16.6% width for Xdialog(1) 470 n=$(( $n + $n / 6 )) 471 472 if [ $n -gt $width -a $n -gt $min_width ]; then 473 if [ $n -lt $max_width ]; then 474 width=$n 475 else 476 width=$max_width 477 fi 478 fi 479 fi 480 481 # Add height for a second inputbox 482 height=$(( $height + 2 )) 483 [ $height -le $max_height ] || height=$max_height 484 485 # 486 # Bump width for second initial text (if not already at maximum width). 487 # NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it! 488 # 489 if [ $width -lt $max_width ]; then 490 n=$(( ${#init2} + 7 )) 491 492 # Add 16.6% width for Xdialog(1) 493 n=$(( $n + $n / 6 )) 494 495 if [ $n -gt $width -a $n -gt $min_width ]; then 496 if [ $n -lt $max_width ]; then 497 width=$n 498 else 499 width=$max_width 500 fi 501 fi 502 fi 503 504 # Return both 505 echo "$height $width" 506} 507 508# f_dialog_menu_size $title $backtitle $prompt $hline \ 509# $tag1 $item1 $tag2 $item2 ... 510# 511# Not all versions of dialog(1) perform auto-sizing of the width and height of 512# `--menu' boxes sensibly. 513# 514# This function helps solve this issue by taking as arguments (in order of 515# appearance) the title, backtitle, prompt, hline and list of tag/item pairs, 516# returning the optimal width and height for the menu (not exceeding the actual 517# terminal width or height). 518# 519# Output is in the format of "height width rows". 520# 521f_dialog_menu_size() 522{ 523 local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 524 local min_width min_rows max_size 525 526 if [ "$USE_XDIALOG" ]; then 527 min_width=35 528 min_rows=1 529 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 530 else 531 min_width=24 532 min_rows=0 533 max_size=$( stty size 2> /dev/null ) # usually "24 80" 534 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 535 fi 536 537 local max_width="${max_size##*[$IFS]}" 538 local max_height="${max_size%%[$IFS]*}" 539 local box_size="$( f_dialog_infobox_size \ 540 "$title" "$btitle" "$prompt" "$hline" )" 541 local box_height="${box_size%%[$IFS]*}" 542 local box_width="${box_size##*[$IFS]}" 543 local max_rows=$(( $max_height - 8 )) 544 local height width=$box_width rows=$min_rows 545 546 shift 4 # title/btitle/prompt/hline 547 548 # If there's no prompt, bump the max-rows by 1 549 [ "$prompt" ] || max_rows=$(( $max_rows + 1 )) 550 551 # 552 # The sum total between the longest tag-length and longest item-length 553 # should be used for the menu width (not to exceed terminal width). 554 # 555 # Also, calculate the number of rows (not to exceed terminal height). 556 # 557 local longest_tag=0 longest_item=0 558 while [ $# -ge 2 ]; do 559 local tag="$1" item="$2" 560 shift 2 # tag/item 561 562 [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} 563 [ ${#item} -gt $longest_item ] && longest_item=${#item} 564 [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) 565 done 566 567 # Update width 568 n=$(( $longest_tag + $longest_item + 10 )) 569 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) 570 if [ $n -gt $width -a $n -gt $min_width ]; then 571 if [ $n -lt $max_width ]; then 572 width=$n 573 else 574 width=$max_width 575 fi 576 fi 577 578 # Fix rows and set height 579 [ $rows -gt 0 ] || rows=1 580 if [ "$USE_XDIALOG" ]; then 581 height=$(( $rows + $box_height + 7 )) 582 else 583 height=$(( $rows + $box_height + 4 )) 584 fi 585 [ $height -le $max_height ] || height=$max_height 586 587 # Return all three 588 echo "$height $width $rows" 589} 590 591# f_dialog_menu_with_help_size $title $backtitle $prompt $hline \ 592# $tag1 $item1 $help1 $tag2 $item2 $help2 ... 593# 594# Not all versions of dialog(1) perform auto-sizing of the width and height of 595# `--menu' boxes sensibly. 596# 597# This function helps solve this issue by taking as arguments (in order of 598# appearance) the title, backtitle, prompt, hline and list of tag/item/help 599# triplets, returning the optimal width and height for the menu (not exceeding 600# the actual terminal width or height). 601# 602# Output is in the format of "height width rows". 603# 604f_dialog_menu_with_help_size() 605{ 606 local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 607 local min_width min_rows max_size 608 609 if [ "$USE_XDIALOG" ]; then 610 min_width=35 611 min_rows=1 612 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 613 else 614 min_width=24 615 min_rows=0 616 max_size=$( stty size 2> /dev/null ) # usually "24 80" 617 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 618 fi 619 620 local max_width="${max_size##*[$IFS]}" 621 local max_height="${max_size%%[$IFS]*}" 622 local box_size="$( f_dialog_infobox_size \ 623 "$title" "$btitle" "$prompt" "$hline" )" 624 local box_height="${box_size%%[$IFS]*}" 625 local box_width="${box_size##*[$IFS]}" 626 local max_rows=$(( $max_height - 8 )) 627 local height width=$box_width rows=$min_rows 628 629 shift 4 # title/btitle/prompt/hline 630 631 # If there's no prompt, bump the max-rows by 1 632 [ "$prompt" ] || max_rows=$(( $max_rows + 1 )) 633 634 # 635 # The sum total between the longest tag-length and longest item-length 636 # should be used for the menu width (not to exceed terminal width). 637 # 638 # Also, calculate the number of rows (not to exceed terminal height). 639 # 640 # Also, calculate the longest help while we're here. This will be used 641 # to influence the width of the menu if (and only-if) using Xdialog(1). 642 # 643 local longest_tag=0 longest_item=0 longest_help=0 644 while [ $# -ge 3 ]; do 645 local tag="$1" item="$2" help="$3" 646 shift 3 # tag/item/help 647 648 [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} 649 [ ${#item} -gt $longest_item ] && longest_item=${#item} 650 [ ${#help} -gt $longest_help ] && longest_help=${#help} 651 [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) 652 done 653 654 # Update width 655 n=$(( $longest_tag + $longest_item + 10 )) 656 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) 657 if [ $n -gt $width -a $n -gt $min_width ]; then 658 if [ $n -lt $max_width ]; then 659 width=$n 660 else 661 width=$max_width 662 fi 663 fi 664 665 # Update width for help text if using Xdialog(1) 666 if [ "$USE_XDIALOG" ]; then 667 n=$(( $longest_help + 10 )) 668 n=$(( $n + $n / 6 )) # +16.6% 669 if [ $n -gt $width -a $n -gt $min_width ]; then 670 if [ $n -lt $max_width ]; then 671 width=$n 672 else 673 width=$max_width 674 fi 675 fi 676 fi 677 678 # Fix rows and set height 679 [ $rows -gt 0 ] || rows=1 680 if [ "$USE_XDIALOG" ]; then 681 height=$(( $rows + $box_height + 8 )) 682 else 683 height=$(( $rows + $box_height + 4 )) 684 fi 685 [ $height -le $max_height ] || height=$max_height 686 687 # Return all three 688 echo "$height $width $rows" 689} 690 691# f_dialog_radiolist_size $title $backtitle $prompt $hline \ 692# $tag1 $item1 $status1 $tag2 $item2 $status2 ... 693# 694# Not all versions of dialog(1) perform auto-sizing of the width and height of 695# `--radiolist' boxes sensibly. 696# 697# This function helps solve this issue by taking as arguments (in order of 698# appearance) the title, backtitle, prompt, hline and list of tag/item/status 699# triplets, returning the optimal width and height for the radiolist (not 700# exceeding the actual terminal width or height). 701# 702# Output is in the format of "height width rows". 703# 704f_dialog_radiolist_size() 705{ 706 local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 707 local min_width min_rows max_size 708 709 if [ "$USE_XDIALOG" ]; then 710 min_width=35 711 min_rows=1 712 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 713 else 714 min_width=24 715 min_rows=0 716 max_size=$( stty size 2> /dev/null ) # usually "24 80" 717 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 718 fi 719 720 local max_width="${max_size##*[$IFS]}" 721 local max_height="${max_size%%[$IFS]*}" 722 local box_size="$( f_dialog_infobox_size \ 723 "$title" "$btitle" "$prompt" "$hline" )" 724 local box_height="${box_size%%[$IFS]*}" 725 local box_width="${box_size##*[$IFS]}" 726 local max_rows=$(( $max_height - 8 )) 727 local height width=$box_width rows=$min_rows 728 729 shift 4 # title/btitle/prompt/hline 730 731 # 732 # The sum total between the longest tag-length, longest item-length, 733 # and radio-button width should be used for the menu width (not to 734 # exceed terminal width). 735 # 736 # Also, calculate the number of rows (not to exceed terminal height). 737 # 738 local longest_tag=0 longest_item=0 739 while [ $# -ge 2 ]; do 740 local tag="$1" item="$2" help="$3" 741 shift 3 # tag/item/status 742 743 [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} 744 [ ${#item} -gt $longest_item ] && longest_item=${#item} 745 [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) 746 done 747 748 # Update width 749 n=$(( $longest_tag + $longest_item + 13 )) 750 [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) 751 if [ $n -gt $width -a $n -gt $min_width ]; then 752 if [ $n -lt $max_width ]; then 753 width=$n 754 else 755 width=$max_width 756 fi 757 fi 758 759 # Fix rows and set height 760 [ $rows -gt 0 ] || rows=1 761 if [ "$USE_XDIALOG" ]; then 762 height=$(( $rows + $box_height + 7 )) 763 else 764 height=$(( $rows + $box_height + 4 )) 765 fi 766 [ $height -le $max_height ] || height=$max_height 767 768 # Return all three 769 echo "$height $width $rows" 770} 771 772# f_dialog_calendar_size $title $backtitle $prompt [$hline] 773# 774# Not all versions of dialog(1) perform auto-sizing of the width and height of 775# `--calendar' boxes sensibly. 776# 777# This function helps solve this issue by taking as arguments (in order of 778# appearance) the title, backtitle, prompt, and [optionally] hline returning 779# the optimal width and height for the box (not exceeding the actual terminal 780# width and height). 781# 782# Newline character sequences (``\n'') in $prompt are expanded as-is done by 783# dialog(1). 784# 785# Output is in the format of "height width". 786# 787f_dialog_calendar_size() 788{ 789 local title="$1" btitle="$2" prompt="$3" hline="$4" n 790 local size="$( f_dialog_infobox_size \ 791 "$title" "$btitle" "$prompt" "$hline" )" 792 local height="${size%%[$IFS]*}" 793 local width="${size##*[$IFS]}" 794 795 local min_width min_height max_size 796 if [ "$USE_XDIALOG" ]; then 797 min_height=15 798 min_width=55 799 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 800 else 801 min_height=0 802 min_width=40 803 max_size=$( stty size 2> /dev/null ) # usually "24 80" 804 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 805 fi 806 local max_height="${max_size%%[$IFS]*}" 807 local max_width="${max_size##*[$IFS]}" 808 809 # 810 # Enforce the minimum width for displaying the calendar 811 # 812 [ $width -ge $min_width ] || width=$min_width 813 814 # 815 # When using dialog(1), the calendar box is unique from other dialog(1) 816 # boxes in-that the height passed should not accomodate the 15-lines 817 # required to display the calendar. This does not apply to Xdialog(1). 818 # 819 # When using Xdialog(1), the height must accomodate the 15-lines 820 # required to display the calendar. 821 # 822 # NOTE: Also under dialog(1), because we can't predict whether the user 823 # has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract 824 # 16 rather than 15. This does not apply to Xdialog(1). 825 # 826 max_height=$(( $max_height - 16 )) 827 height=$( echo "$prompt" | f_number_of_lines ) 828 if [ "$USE_XDIALOG" ]; then 829 # Add height to accomodate for the embedded calendar widget 830 height=$(( $height + $min_height - 1 )) 831 832 # Also, bump height if backtitle is enabled 833 if [ "$btitle" ]; then 834 local n="$( echo "$btitle" | f_number_of_lines )" 835 height=$(( $height + $n + 2 )) 836 fi 837 else 838 [ "$prompt" ] && height=$(( $height + 1 )) 839 fi 840 [ $height -le $max_height ] || height=$max_height 841 842 # 843 # The calendar box refuses to display if too large. 844 # 845 max_width=$(( $max_width - 2 )) 846 [ $width -le $max_width ] || width=$max_width 847 848 # Return both 849 echo "$height $width" 850} 851 852# f_dialog_timebox_size $title $backtitle $prompt [$hline] 853# 854# Not all versions of dialog(1) perform auto-sizing of the width and height of 855# `--timebox' boxes sensibly. 856# 857# This function helps solve this issue by taking as arguments (in order of 858# appearance) the title, backtitle, prompt, and [optionally] hline returning 859# the optimal width and height for the box (not exceeding the actual terminal 860# width and height). 861# 862# Newline character sequences (``\n'') in $prompt are expanded as-is done by 863# dialog(1). 864# 865# Output is in the format of "height width". 866# 867f_dialog_timebox_size() 868{ 869 local title="$1" btitle="$2" prompt="$3" hline="$4" n 870 local size="$( f_dialog_infobox_size \ 871 "$title" "$btitle" "$prompt" "$hline" )" 872 local height="${size%%[$IFS]*}" 873 local width="${size##*[$IFS]}" 874 875 local min_width min_height max_size 876 if [ "$USE_XDIALOG" ]; then 877 min_width=40 878 max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 879 else 880 min_height=0 881 min_width=20 882 max_size=$( stty size 2> /dev/null ) # usually "24 80" 883 : ${max_size:=$DEFAULT_TERMINAL_SIZE} 884 fi 885 local max_height="${max_size%%[$IFS]*}" 886 local max_width="${max_size##*[$IFS]}" 887 888 # 889 # Enforce the minimum width for displaying the timebox 890 # 891 [ $width -ge $min_width ] || width=$min_width 892 893 # 894 # When using dialog(1), the timebox box is unique from other dialog(1) 895 # boxes in-that the height passed should not accomodate the 6-lines 896 # required to display the timebox. This does not apply to Xdialog(1). 897 # 898 # When using Xdialog(1), the height seems to have no effect. All values 899 # provide the same results. 900 # 901 # NOTE: Also under dialog(1), because we can't predict whether the user 902 # has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract 903 # 7 rather than 6. This does not apply to Xdialog(1). 904 # 905 if [ "$USE_XDIALOG" ]; then 906 height=0 # Autosize; all values produce same results 907 else 908 max_height=$(( $max_height - 7 )) 909 height=$( echo "$prompt" | f_number_of_lines ) 910 height=$(( $height + 1 )) 911 [ $height -le $max_height ] || height=$max_height 912 [ "$prompt" ] && height=$(( $height + 1 )) 913 fi 914 915 # 916 # The timebox box refuses to display if too large. 917 # 918 max_width=$(( $max_width - 2 )) 919 [ $width -le $max_width ] || width=$max_width 920 921 # Return both 922 echo "$height $width" 923} 924 925############################################################ CLEAR FUNCTIONS 926 927# f_dialog_clear 928# 929# Clears any/all previous dialog(1) displays. 930# 931f_dialog_clear() 932{ 933 $DIALOG --clear 934} 935 936############################################################ INFO FUNCTIONS 937 938# f_dialog_info $info_text ... 939# 940# Throw up a dialog(1) infobox. The infobox remains until another dialog is 941# displayed or `dialog --clear' (or f_dialog_clear) is called. 942# 943f_dialog_info() 944{ 945 local info_text="$*" 946 local size="$( f_dialog_infobox_size \ 947 "$DIALOG_TITLE" \ 948 "$DIALOG_BACKTITLE" \ 949 "$info_text" )" 950 951 eval $DIALOG \ 952 --title \"\$DIALOG_TITLE\" \ 953 --backtitle \"\$DIALOG_BACKTITLE\" \ 954 ${USE_XDIALOG:+--ignore-eof} \ 955 ${USE_XDIALOG:+--no-buttons} \ 956 --infobox \"\$info_text\" $size 957} 958 959# f_xdialog_info $info_text ... 960# 961# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces 962# EOF. This implies that you must execute this either as an rvalue to a pipe, 963# lvalue to indirection or in a sub-shell that provides data on stdin. 964# 965f_xdialog_info() 966{ 967 local info_text="$*" 968 local size="$( f_dialog_infobox_size \ 969 "$DIALOG_TITLE" \ 970 "$DIALOG_BACKTITLE" \ 971 "$info_text" )" 972 973 eval $DIALOG \ 974 --title \"\$DIALOG_TITLE\" \ 975 --backtitle \"\$DIALOG_BACKTITLE\" \ 976 --no-close --no-buttons \ 977 --infobox \"\$info_text\" $size \ 978 -1 # timeout of -1 means abort when EOF on stdin 979} 980 981############################################################ MSGBOX FUNCTIONS 982 983# f_dialog_msgbox $msg_text ... 984# 985# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER 986# or ESC, acknowledging the modal dialog. 987# 988# If the user presses ENTER, the exit status is zero (success), otherwise if 989# the user presses ESC the exit status is 255. 990# 991f_dialog_msgbox() 992{ 993 local msg_text="$*" 994 local size="$( f_dialog_buttonbox_size \ 995 "$DIALOG_TITLE" \ 996 "$DIALOG_BACKTITLE" \ 997 "$msg_text" )" 998 999 eval $DIALOG \ 1000 --title \"\$DIALOG_TITLE\" \ 1001 --backtitle \"\$DIALOG_BACKTITLE\" \ 1002 --ok-label \"\$msg_ok\" \ 1003 --msgbox \"\$msg_text\" $size 1004} 1005 1006############################################################ TEXTBOX FUNCTIONS 1007 1008# f_dialog_textbox $file 1009# 1010# Display the contents of $file (or an error if $file does not exist, etc.) in 1011# a dialog(1) textbox (which has a scrollable region for the text). The textbox 1012# remains until the user presses ENTER or ESC, acknowledging the modal dialog. 1013# 1014# If the user presses ENTER, the exit status is zero (success), otherwise if 1015# the user presses ESC the exit status is 255. 1016# 1017f_dialog_textbox() 1018{ 1019 local file="$1" 1020 local contents retval size 1021 1022 contents=$( cat "$file" 2>&1 ) 1023 retval=$? 1024 1025 size=$( f_dialog_buttonbox_size \ 1026 "$DIALOG_TITLE" \ 1027 "$DIALOG_BACKTITLE" \ 1028 "$contents" ) 1029 1030 if [ $retval -eq $SUCCESS ]; then 1031 eval $DIALOG \ 1032 --title \"\$DIALOG_TITLE\" \ 1033 --backtitle \"\$DIALOG_BACKTITLE\" \ 1034 --exit-label \"\$msg_ok\" \ 1035 --no-cancel \ 1036 --textbox \"\$file\" $size 1037 else 1038 eval $DIALOG \ 1039 --title \"\$DIALOG_TITLE\" \ 1040 --backtitle \"\$DIALOG_BACKTITLE\" \ 1041 --ok-label \"\$msg_ok\" \ 1042 --msgbox \"\$contents\" $size 1043 fi 1044} 1045 1046############################################################ YESNO FUNCTIONS 1047 1048# f_dialog_yesno $msg_text ... 1049# 1050# Display a dialog(1) Yes/No prompt to allow the user to make some decision. 1051# The yesno prompt remains until the user presses ENTER or ESC, acknowledging 1052# the modal dialog. 1053# 1054# If the user chooses YES the exit status is zero, or chooses NO the exit 1055# status is one, or presses ESC the exit status is 255. 1056# 1057f_dialog_yesno() 1058{ 1059 local msg_text="$*" 1060 local hline="$hline_arrows_tab_enter" 1061 local size="$( f_dialog_buttonbox_size \ 1062 "$DIALOG_TITLE" \ 1063 "$DIALOG_BACKTITLE" \ 1064 "$msg_text" \ 1065 "$hline" )" 1066 1067 if [ "$USE_XDIALOG" ]; then 1068 eval $DIALOG \ 1069 --title \"\$DIALOG_TITLE\" \ 1070 --backtitle \"\$DIALOG_BACKTITLE\" \ 1071 --hline \"\$hline\" \ 1072 --ok-label \"\$msg_yes\" \ 1073 --cancel-label \"\$msg_no\" \ 1074 --yesno \"\$msg_text\" $size 1075 else 1076 eval $DIALOG \ 1077 --title \"\$DIALOG_TITLE\" \ 1078 --backtitle \"\$DIALOG_BACKTITLE\" \ 1079 --hline \"\$hline\" \ 1080 --yes-label \"\$msg_yes\" \ 1081 --no-label \"\$msg_no\" \ 1082 --yesno \"\$msg_text\" $size 1083 fi 1084} 1085 1086# f_dialog_noyes $msg_text ... 1087# 1088# Display a dialog(1) No/Yes prompt to allow the user to make some decision. 1089# The noyes prompt remains until the user presses ENTER or ESC, acknowledging 1090# the modal dialog. 1091# 1092# If the user chooses YES the exit status is zero, or chooses NO the exit 1093# status is one, or presses ESC the exit status is 255. 1094# 1095# NOTE: This is just like the f_dialog_yesno function except "No" is default. 1096# 1097f_dialog_noyes() 1098{ 1099 local msg_text="$*" 1100 local hline="$hline_arrows_tab_enter" 1101 local size="$( f_dialog_buttonbox_size \ 1102 "$DIALOG_TITLE" \ 1103 "$DIALOG_BACKTITLE" \ 1104 "$msg_text" \ 1105 "$hline" )" 1106 1107 if [ "$USE_XDIALOG" ]; then 1108 eval $DIALOG \ 1109 --title \"\$DIALOG_TITLE\" \ 1110 --backtitle \"\$DIALOG_BACKTITLE\" \ 1111 --hline \"\$hline\" \ 1112 --default-no \ 1113 --ok-label \"\$msg_yes\" \ 1114 --cancel-label \"\$msg_no\" \ 1115 --yesno \"\$msg_text\" $size 1116 else 1117 eval $DIALOG \ 1118 --title \"\$DIALOG_TITLE\" \ 1119 --backtitle \"\$DIALOG_BACKTITLE\" \ 1120 --hline \"\$hline\" \ 1121 --defaultno \ 1122 --yes-label \"\$msg_yes\" \ 1123 --no-label \"\$msg_no\" \ 1124 --yesno \"\$msg_text\" $size 1125 fi 1126} 1127 1128############################################################ INPUT FUNCTIONS 1129 1130# f_dialog_inputstr 1131# 1132# Obtain the inputstr entered by the user from the most recently displayed 1133# dialog(1) inputbox and clean up any temporary files/variables. 1134# 1135f_dialog_inputstr() 1136{ 1137 # Skip warnings and trim leading/trailing whitespace from user input 1138 eval echo \"\$DIALOG_INPUTBOX_$$\" | awk ' 1139 BEGIN { found = 0 } 1140 { 1141 if ( ! found ) 1142 { 1143 if ( $0 ~ /^$/ ) next 1144 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next 1145 found = 1 1146 } 1147 sub(/^[[:space:]]*/, "") 1148 sub(/[[:space:]]*$/, "") 1149 print 1150 } 1151 ' 1152 setvar DIALOG_INPUTBOX_$$ "" # scrub memory in case data was sensitive 1153 return $SUCCESS 1154} 1155 1156# f_dialog_input $prompt [$init [$hline]] 1157# 1158# Prompt the user with a dialog(1) inputbox to enter some value. The inputbox 1159# remains until the the user presses ENTER or ESC, or otherwise ends the 1160# editing session, by selecting `Cancel' for example. 1161# 1162# If the user presses ENTER, the exit status is zero (success), otherwise if 1163# the user presses ESC the exit status is 255, or if the user chose Cancel, the 1164# exit status is instead 1. 1165# 1166# NOTE: The hline should correspond to the type of data you want from the user. 1167# NOTE: Should not be used to edit multiline values. 1168# 1169f_dialog_input() 1170{ 1171 local prompt="$1" init="$2" hline="$3" 1172 local size="$( f_dialog_inputbox_size \ 1173 "$DIALOG_TITLE" \ 1174 "$DIALOG_BACKTITLE" \ 1175 "$prompt" \ 1176 "$init" \ 1177 "$hline" )" 1178 1179 local opterm="--" 1180 [ "$USE_XDIALOG" ] && opterm= 1181 1182 local dialog_input 1183 dialog_input=$( 1184 eval $DIALOG \ 1185 --title \"\$DIALOG_TITLE\" \ 1186 --backtitle \"\$DIALOG_BACKTITLE\" \ 1187 --hline \"\$hline\" \ 1188 --ok-label \"\$msg_ok\" \ 1189 --cancel-label \"\$msg_cancel\" \ 1190 --inputbox \"\$prompt\" $size \ 1191 $opterm \"\$init\" \ 1192 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1193 ) 1194 local retval=$? 1195 1196 setvar DIALOG_INPUTBOX_$$ "$dialog_input" 1197 f_dialog_inputstr 1198 1199 return $retval 1200} 1201 1202############################################################ MENU FUNCTIONS 1203 1204# f_dialog_menutag 1205# 1206# Obtain the menutag chosen by the user from the most recently displayed 1207# dialog(1) menu and clean up any temporary files/variables. 1208# 1209f_dialog_menutag() 1210{ 1211 # Skip warnings 1212 eval echo \"\$DIALOG_MENU_$$\" | awk ' 1213 BEGIN { found = 0 } 1214 { 1215 if ( found ) # ... just spew 1216 { 1217 print 1218 next 1219 } 1220 if ( $0 ~ /^$/ ) next 1221 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next 1222 found = 1 1223 print 1224 } 1225 ' 1226 setvar DIALOG_MENU_$$ "" # scrub memory in case data was sensitive 1227 return $SUCCESS 1228} 1229 1230# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ... 1231# 1232# To use the `--menu' option of dialog(1) you must pass an ordered list of 1233# tag/item pairs on the command-line. When the user selects a menu option the 1234# tag for that item is printed to stderr. 1235# 1236# This function allows you to dereference the tag chosen by the user back into 1237# the item associated with said tag. 1238# 1239# Pass the tag chosen by the user as the first argument, followed by the 1240# ordered list of tag/item pairs (HINT: use the same tag/item list as was 1241# passed to dialog(1) for consistency). 1242# 1243# If the tag cannot be found, NULL is returned. 1244# 1245f_dialog_menutag2item() 1246{ 1247 local tag="$1" tagn item 1248 shift 1 # tag 1249 1250 while [ $# -gt 0 ]; do 1251 tagn="$1" 1252 item="$2" 1253 shift 2 # tagn/item 1254 1255 if [ "$tag" = "$tagn" ]; then 1256 echo "$item" 1257 return $SUCCESS 1258 fi 1259 done 1260 return $FAILURE 1261} 1262 1263# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \ 1264# $tag2 $item2 $help2 ... 1265# 1266# To use the `--menu' option of dialog(1) with the `--item-help' option, you 1267# must pass an ordered list of tag/item/help triplets on the command-line. When 1268# the user selects a menu option the tag for that item is printed to stderr. 1269# 1270# This function allows you to dereference the tag chosen by the user back into 1271# the item associated with said tag (help is discarded/ignored). 1272# 1273# Pass the tag chosen by the user as the first argument, followed by the 1274# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list 1275# as was passed to dialog(1) for consistency). 1276# 1277# If the tag cannot be found, NULL is returned. 1278# 1279f_dialog_menutag2item_with_help() 1280{ 1281 local tag="$1" tagn item 1282 shift 1 # tag 1283 1284 while [ $# -gt 0 ]; do 1285 tagn="$1" 1286 item="$2" 1287 shift 3 # tagn/item/help 1288 1289 if [ "$tag" = "$tagn" ]; then 1290 echo "$item" 1291 return $SUCCESS 1292 fi 1293 done 1294 return $FAILURE 1295} 1296 1297# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ... 1298# 1299# To use the `--menu' option of dialog(1) you must pass an ordered list of 1300# tag/item pairs on the command-line. When the user selects a menu option the 1301# tag for that item is printed to stderr. 1302# 1303# This function allows you to dereference the tag chosen by the user back into 1304# the index associated with said tag. The index is the one-based tag/item pair 1305# array position within the ordered list of tag/item pairs passed to dialog(1). 1306# 1307# Pass the tag chosen by the user as the first argument, followed by the 1308# ordered list of tag/item pairs (HINT: use the same tag/item list as was 1309# passed to dialog(1) for consistency). 1310# 1311# If the tag cannot be found, NULL is returned. 1312# 1313f_dialog_menutag2index() 1314{ 1315 local tag="$1" tagn n=1 1316 shift 1 # tag 1317 1318 while [ $# -gt 0 ]; do 1319 tagn="$1" 1320 shift 2 # tagn/item 1321 1322 if [ "$tag" = "$tagn" ]; then 1323 echo $n 1324 return $SUCCESS 1325 fi 1326 n=$(( $n + 1 )) 1327 done 1328 return $FAILURE 1329} 1330 1331# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \ 1332# $tag2 $item2 $help2 ... 1333# 1334# To use the `--menu' option of dialog(1) with the `--item-help' option, you 1335# must pass an ordered list of tag/item/help triplets on the command-line. When 1336# the user selects a menu option the tag for that item is printed to stderr. 1337# 1338# This function allows you to dereference the tag chosen by the user back into 1339# the index associated with said tag. The index is the one-based tag/item/help 1340# triplet array position within the ordered list of tag/item/help triplets 1341# passed to dialog(1). 1342# 1343# Pass the tag chosen by the user as the first argument, followed by the 1344# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list 1345# as was passed to dialog(1) for consistency). 1346# 1347# If the tag cannot be found, NULL is returned. 1348# 1349f_dialog_menutag2index_with_help() 1350{ 1351 local tag="$1" tagn n=1 1352 shift 1 # tag 1353 1354 while [ $# -gt 0 ]; do 1355 tagn="$1" 1356 shift 3 # tagn/item/help 1357 1358 if [ "$tag" = "$tagn" ]; then 1359 echo $n 1360 return $SUCCESS 1361 fi 1362 n=$(( $n + 1 )) 1363 done 1364 return $FAILURE 1365} 1366 1367############################################################ INIT FUNCTIONS 1368 1369# f_dialog_init 1370# 1371# Initialize (or re-initialize) the dialog module after setting/changing any 1372# of the following environment variables: 1373# 1374# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 1375# that Xdialog(1) should be used instead of dialog(1). 1376# 1377# SECURE Either NULL or Non-NULL. If given a value will indicate 1378# that (while running as root) sudo(8) authentication is 1379# required to proceed. 1380# 1381f_dialog_init() 1382{ 1383 DIALOG_SELF_INITIALIZE= 1384 1385 # 1386 # Clone terminal stdout so we can redirect to it from within sub-shells 1387 # 1388 eval exec $DIALOG_TERMINAL_PASSTHRU_FD\>\&1 1389 1390 # 1391 # Process stored command-line arguments 1392 # 1393 SECURE=$( set -- "$ARGV" 1394 while getopts S flag > /dev/null; do 1395 case "$flag" in 1396 S) echo 1;; 1397 \?) continue;; 1398 esac 1399 done 1400 ) 1401 USE_XDIALOG=$( set -- "$ARGV" 1402 while getopts SX flag > /dev/null; do 1403 case "$flag" in 1404 S|X) echo 1;; 1405 \?) continue;; 1406 esac 1407 done 1408 ) 1409 1410 # 1411 # Process `-X' command-line option 1412 # 1413 [ "$USE_XDIALOG" ] && DIALOG=Xdialog 1414 1415 # 1416 # Sanity check, or die gracefully 1417 # 1418 if ! f_have $DIALOG; then 1419 unset USE_XDIALOG 1420 failed_dialog="$DIALOG" 1421 DIALOG=dialog 1422 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog" 1423 fi 1424 1425 # 1426 # If we're already running as root but we got there by way of sudo(8) 1427 # and we have X11, we should merge the xauth(1) credentials from our 1428 # original user. 1429 # 1430 if [ "$USE_XDIALOG" ] && 1431 [ "$( id -u )" = "0" ] && 1432 [ "$SUDO_USER" -a "$DISPLAY" ] 1433 then 1434 if ! f_have xauth; then 1435 # Die gracefully, as we [likely] can't use Xdialog(1) 1436 unset USE_XDIALOG 1437 DIALOG=dialog 1438 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth" 1439 fi 1440 HOSTNAME=$(hostname) 1441 displaynum="${DISPLAY#*:}" 1442 eval xauth -if \~$SUDO_USER/.Xauthority extract - \ 1443 \"\$HOSTNAME/unix:\$displaynum\" \ 1444 \"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \ 1445 ~root/.Xauthority merge - > /dev/null 2>&1' 1446 fi 1447 1448 # 1449 # Probe Xdialog(1) for maximum height/width constraints, or die 1450 # gracefully 1451 # 1452 if [ "$USE_XDIALOG" ]; then 1453 if ! maxsize=$( LANG= LC_ALL= $DIALOG --print-maxsize 2>&1 ) 1454 then 1455 # Xdialog(1) failed, fall back to dialog(1) 1456 unset USE_XDIALOG 1457 size=$( f_dialog_buttonbox_size "$DIALOG_TITLE" \ 1458 "$DIALOG_BACKTITLE" \ 1459 "$maxsize" "" ) 1460 eval dialog \ 1461 --title \"\$DIALOG_TITLE\" \ 1462 --backtitle \"\$DIALOG_BACKTITLE\" \ 1463 --ok-label \"\$msg_ok\" \ 1464 --msgbox \"\$maxsize\" $size 1465 exit $FAILURE 1466 fi 1467 1468 XDIALOG_MAXSIZE=$( 1469 set -- ${maxsize##*:} 1470 1471 height=${1%,} 1472 width=$2 1473 1474 echo $height $width 1475 ) 1476 unset maxsize 1477 fi 1478 1479 # 1480 # If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE. 1481 # The reason for this is because many dialog(1) applications use 1482 # --backtitle for the program name (which is better suited as 1483 # --title with Xdialog(1)). 1484 # 1485 if [ "$USE_XDIALOG" ]; then 1486 _DIALOG_TITLE="$DIALOG_TITLE" 1487 DIALOG_TITLE="$DIALOG_BACKTITLE" 1488 DIALOG_BACKTITLE="$_DIALOG_TITLE" 1489 unset _DIALOG_TITLE 1490 fi 1491 1492 f_dprintf "f_dialog_init: dialog(1) API initialized." 1493} 1494 1495############################################################ MAIN 1496 1497# 1498# Self-initialize unless requested otherwise 1499# 1500f_dprintf "%s: DIALOG_SELF_INITIALIZE=[%s]" \ 1501 dialog.subr "$DIALOG_SELF_INITIALIZE" 1502case "$DIALOG_SELF_INITIALIZE" in 1503""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;; 1504*) f_dialog_init 1505esac 1506 1507f_dprintf "%s: Successfully loaded." dialog.subr 1508 1509fi # ! $_DIALOG_SUBR 1510