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