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