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 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# $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# 87# Minimum width(s) for various dialog(1) implementations (sensible global 88# default(s) for all widgets of a given variant) 89# 90: ${DIALOG_MIN_WIDTH:=24} 91: ${XDIALOG_MIN_WIDTH:=35} 92 93# 94# When manually sizing Xdialog(1) widgets such as calendar and timebox, you'll 95# need to know the size of the embedded GUI objects because the height passed 96# to Xdialog(1) for these widgets has to be tall enough to accomodate them. 97# 98# These values are helpful when manually sizing with dialog(1) too, but in a 99# different way. dialog(1) does not make you accomodate the custom items in the 100# height (but does for width) -- a height of 3 will display three lines and a 101# full calendar, for example (whereas Xdialog will truncate the calendar if 102# given a height of 3). For dialog(1), use these values for making sure that 103# the height does not exceed max_height (obtained by f_dialog_max_size()). 104# 105DIALOG_CALENDAR_HEIGHT=15 106DIALOG_TIMEBOX_HEIGHT=6 107 108############################################################ GENERIC FUNCTIONS 109 110# f_dialog_data_sanitize $var_to_edit ... 111# 112# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors 113# are generated from underlying libraries. For example, if $LANG is set to an 114# invalid or unknown locale, the warnings from the Xdialog(1) libraries will 115# clutter the output. This function helps by providing a centralied function 116# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response. 117# 118# Simply pass the name of one or more variables that need to be sanitized. 119# After execution, the variables will hold their newly-sanitized data. 120# 121f_dialog_data_sanitize() 122{ 123 if [ "$#" -eq 0 ]; then 124 f_dprintf "%s: called with zero arguments" \ 125 f_dialog_response_sanitize 126 return $FAILURE 127 fi 128 129 local __var_to_edit 130 for __var_to_edit in $*; do 131 # Skip warnings and trim leading/trailing whitespace 132 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk ' 133 BEGIN { data = 0 } 134 { 135 if ( ! data ) 136 { 137 if ( $0 ~ /^$/ ) next 138 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next 139 data = 1 140 } 141 print 142 } 143 ' )" 144 done 145} 146 147# f_dialog_line_sanitize $var_to_edit ... 148# 149# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors 150# are generated from underlying libraries. For example, if $LANG is set to an 151# invalid or unknown locale, the warnings from the Xdialog(1) libraries will 152# clutter the output. This function helps by providing a centralied function 153# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response. 154# 155# Simply pass the name of one or more variables that need to be sanitized. 156# After execution, the variables will hold their newly-sanitized data. 157# 158# This function, unlike f_dialog_data_sanitize(), also removes leading/trailing 159# whitespace from each line. 160# 161f_dialog_line_sanitize() 162{ 163 if [ "$#" -eq 0 ]; then 164 f_dprintf "%s: called with zero arguments" \ 165 f_dialog_response_sanitize 166 return $FAILURE 167 fi 168 169 local __var_to_edit 170 for __var_to_edit in $*; do 171 # Skip warnings and trim leading/trailing whitespace 172 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk ' 173 BEGIN { data = 0 } 174 { 175 if ( ! data ) 176 { 177 if ( $0 ~ /^$/ ) next 178 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next 179 data = 1 180 } 181 sub(/^[[:space:]]*/, "") 182 sub(/[[:space:]]*$/, "") 183 print 184 } 185 ' )" 186 done 187} 188 189############################################################ TITLE FUNCTIONS 190 191# f_dialog_title [$new_title] 192# 193# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1) 194# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first 195# argument is NULL, the current title is returned. 196# 197# Each time this function is called, a backup of the current values is made 198# allowing a one-time (single-level) restoration of the previous title using 199# the f_dialog_title_restore() function (below). 200# 201f_dialog_title() 202{ 203 local new_title="$1" 204 205 if [ "${1+set}" ]; then 206 if [ "$USE_XDIALOG" ]; then 207 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" 208 DIALOG_BACKTITLE="$new_title" 209 else 210 _DIALOG_TITLE="$DIALOG_TITLE" 211 DIALOG_TITLE="$new_title" 212 fi 213 else 214 if [ "$USE_XDIALOG" ]; then 215 echo "$DIALOG_BACKTITLE" 216 else 217 echo "$DIALOG_TITLE" 218 fi 219 fi 220} 221 222# f_dialog_title_restore 223# 224# Restore the previous title set by the last call to f_dialog_title(). 225# Restoration is non-recursive and only works to restore the most-recent title. 226# 227f_dialog_title_restore() 228{ 229 if [ "$USE_XDIALOG" ]; then 230 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" 231 else 232 DIALOG_TITLE="$_DIALOG_TITLE" 233 fi 234} 235 236# f_dialog_backtitle [$new_backtitle] 237# 238# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of 239# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the 240# first argument is NULL, the current backtitle is returned. 241# 242f_dialog_backtitle() 243{ 244 local new_backtitle="$1" 245 246 if [ "${1+set}" ]; then 247 if [ "$USE_XDIALOG" ]; then 248 _DIALOG_TITLE="$DIALOG_TITLE" 249 DIALOG_TITLE="$new_backtitle" 250 else 251 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" 252 DIALOG_BACKTITLE="$new_backtitle" 253 fi 254 else 255 if [ "$USE_XDIALOG" ]; then 256 echo "$DIALOG_TITLE" 257 else 258 echo "$DIALOG_BACKTITLE" 259 fi 260 fi 261} 262 263# f_dialog_backtitle_restore 264# 265# Restore the previous backtitle set by the last call to f_dialog_backtitle(). 266# Restoration is non-recursive and only works to restore the most-recent 267# backtitle. 268# 269f_dialog_backtitle_restore() 270{ 271 if [ "$USE_XDIALOG" ]; then 272 DIALOG_TITLE="$_DIALOG_TITLE" 273 else 274 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" 275 fi 276} 277 278############################################################ SIZE FUNCTIONS 279 280# f_dialog_max_size $var_height $var_width 281# 282# Get the maximum height and width for a dialog widget and store the values in 283# $var_height and $var_width (respectively). 284# 285f_dialog_max_size() 286{ 287 local __var_height="$1" __var_width="$2" __max_size 288 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 289 if [ "$USE_XDIALOG" ]; then 290 __max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION 291 else 292 __max_size=$( stty size 2> /dev/null ) # usually "24 80" 293 : ${__max_size:=$DEFAULT_TERMINAL_SIZE} 294 fi 295 if [ "$__var_height" ]; then 296 local __height="${__max_size%%[$IFS]*}" 297 # 298 # If we're not using Xdialog(1), we should assume that $DIALOG 299 # will render --backtitle behind the widget. In such a case, we 300 # should prevent a widget from obscuring the backtitle (unless 301 # $NO_BACKTITLE is set and non-NULL, allowing a trap-door). 302 # 303 if [ ! "$USE_XDIALOG" ] && [ ! "$NO_BACKTITLE" ]; then 304 # 305 # If use_shadow (in ~/.dialogrc) is OFF, we need to 306 # subtract 4, otherwise 5. However, don't check this 307 # every time, rely on an initialization variable set 308 # by f_dialog_init(). 309 # 310 local __adjust=5 311 [ "$NO_SHADOW" ] && __adjust=4 312 313 # Don't adjust height if already too small (allowing 314 # obscured backtitle for small values of __height). 315 [ ${__height:-0} -gt 11 ] && 316 __height=$(( $__height - $__adjust )) 317 fi 318 setvar "$__var_height" "$__height" 319 fi 320 [ "$__var_width" ] && setvar "$__var_width" "${__max_size##*[$IFS]}" 321} 322 323# f_dialog_size_constrain $var_height $var_width [$min_height [$min_width]] 324# 325# Modify $var_height to be no-less-than $min_height (if given; zero otherwise) 326# and no-greater-than terminal height (or screen height if $USE_XDIALOG is 327# set). 328# 329# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or 330# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal 331# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by 332# passing $min_width. 333# 334# Return status is success unless one of the passed arguments is invalid 335# or all of the $var_* arguments are either NULL or missing. 336# 337f_dialog_size_constrain() 338{ 339 local __var_height="$1" __var_width="$2" 340 local __min_height="$3" __min_width="$4" 341 local __retval=$SUCCESS 342 343 # Return failure unless at least one var_* argument is passed 344 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 345 346 # 347 # Print debug warnings if any given (non-NULL) argument are invalid 348 # NOTE: Don't change the name of $__{var,min,}{height,width} 349 # 350 local __height __width 351 local __arg __cp __fname=f_dialog_size_constrain 352 for __arg in height width; do 353 debug= f_getvar __var_$__arg __cp 354 [ "$__cp" ] || continue 355 if ! debug= f_getvar "$__cp" __$__arg; then 356 f_dprintf "%s: var_%s variable \`%s' not set" \ 357 $__fname $__arg "$__cp" 358 __retval=$FAILURE 359 elif ! eval f_isinteger \$__$__arg; then 360 f_dprintf "%s: var_%s variable value not a number" \ 361 $__fname $__arg 362 __retval=$FAILURE 363 fi 364 done 365 for __arg in height width; do 366 debug= f_getvar __min_$__arg __cp 367 [ "$__cp" ] || continue 368 f_isinteger "$__cp" && continue 369 f_dprintf "%s: min_%s value not a number" $__fname $__arg 370 __retval=$FAILURE 371 setvar __min_$__arg "" 372 done 373 374 # Obtain maximum height and width values 375 # NOTE: Function name appended to prevent __var_{height,width} values 376 # from becoming local (and thus preventing setvar from working). 377 local __max_height_size_constain __max_width_size_constrain 378 f_dialog_max_size \ 379 __max_height_size_constrain __max_width_size_constrain 380 381 # Adjust height if desired 382 if [ "$__var_height" ]; then 383 if [ $__height -lt ${__min_height:-0} ]; then 384 setvar "$__var_height" $__min_height 385 elif [ $__height -gt $__max_height_size_constrain ]; then 386 setvar "$__var_height" $__max_height_size_constrain 387 fi 388 fi 389 390 # Adjust width if desired 391 if [ "$__var_width" ]; then 392 if [ "$USE_XDIALOG" ]; then 393 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}} 394 else 395 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}} 396 fi 397 if [ $__width -lt $__min_width ]; then 398 setvar "$__var_width" $__min_width 399 elif [ $__width -gt $__max_width_size_constrain ]; then 400 setvar "$__var_width" $__max_width_size_constrain 401 fi 402 fi 403 404 if [ "$debug" ]; then 405 # Print final constrained values to debugging 406 f_quietly f_getvar "$__var_height" 407 f_quietly f_getvar "$__var_width" 408 fi 409 410 return $__retval # success if no debug warnings were printed 411} 412 413# f_dialog_menu_constrain $var_height $var_width $var_rows "$prompt" \ 414# [$min_height [$min_width [$min_rows]]] 415# 416# Modify $var_height to be no-less-than $min_height (if given; zero otherwise) 417# and no-greater-than terminal height (or screen height if $USE_XDIALOG is 418# set). 419# 420# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or 421# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal 422# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by 423# passing $min_width. 424# 425# Last, modify $var_rows to be no-less-than $min_rows (if specified; zero 426# otherwise) and no-greater-than (max_height - 8) where max_height is the 427# terminal height (or screen height if $USE_XDIALOG is set). If $prompt is NULL 428# or missing, dialog(1) allows $var_rows to be (max_height - 7), maximizing the 429# number of visible rows. 430# 431# Return status is success unless one of the passed arguments is invalid 432# or all of the $var_* arguments are either NULL or missing. 433# 434f_dialog_menu_constrain() 435{ 436 local __var_height="$1" __var_width="$2" __var_rows="$3" __prompt="$4" 437 local __min_height="$5" __min_width="$6" __min_rows="$7" 438 439 # Return failure unless at least one var_* argument is passed 440 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] || 441 return $FAILURE 442 443 # 444 # Print debug warnings if any given (non-NULL) argument are invalid 445 # NOTE: Don't change the name of $__{var,min,}{height,width,rows} 446 # 447 local __height __width __rows 448 local __arg __cp __fname=f_dialog_menu_constrain 449 for __arg in height width rows; do 450 debug= f_getvar __var_$__arg __cp 451 [ "$__cp" ] || continue 452 if ! debug= f_getvar "$__cp" __$__arg; then 453 f_dprintf "%s: var_%s variable \`%s' not set" \ 454 $__fname $__arg "$__cp" 455 __retval=$FAILURE 456 elif ! eval f_isinteger \$__$__arg; then 457 f_dprintf "%s: var_%s variable value not a number" \ 458 $__fname $__arg 459 __retval=$FAILURE 460 fi 461 done 462 for __arg in height width rows; do 463 debug= f_getvar __min_$__arg __cp 464 [ "$__cp" ] || continue 465 f_isinteger "$__cp" && continue 466 f_dprintf "%s: min_%s value not a number" $__fname $__arg 467 __retval=$FAILURE 468 setvar __min_$__arg "" 469 done 470 471 # Obtain maximum height and width values 472 # NOTE: Function name appended to prevent __var_{height,width} values 473 # from becoming local (and thus preventing setvar from working). 474 local __max_height_menu_constrain __max_width_menu_constrain 475 f_dialog_max_size \ 476 __max_height_menu_constrain __max_width_menu_constrain 477 478 # Adjust height if desired 479 if [ "$__var_height" ]; then 480 if [ $__height -lt ${__min_height:-0} ]; then 481 setvar "$__var_height" $__min_height 482 elif [ $__height -gt $__max_height_menu_constrain ]; then 483 setvar "$__var_height" $__max_height_menu_constrain 484 fi 485 fi 486 487 # Adjust width if desired 488 if [ "$__var_width" ]; then 489 if [ "$USE_XDIALOG" ]; then 490 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}} 491 else 492 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}} 493 fi 494 if [ $__width -lt $__min_width ]; then 495 setvar "$__var_width" $__min_width 496 elif [ $__width -gt $__max_width_menu_constrain ]; then 497 setvar "$__var_width" $__max_width_menu_constrain 498 fi 499 fi 500 501 # Adjust rows if desired 502 if [ "$__var_rows" ]; then 503 if [ "$USE_XDIALOG" ]; then 504 : ${__min_rows:=1} 505 else 506 : ${__min_rows:=0} 507 fi 508 509 local __max_rows=$(( $__max_height_menu_constrain - 8 )) 510 # If prompt_len is zero (no prompt), bump the max-rows by 1 511 # Default assumption is (if no argument) that there's no prompt 512 [ ${__prompt_len:-0} -gt 0 ] || 513 __max_rows=$(( $__max_rows + 1 )) 514 515 if [ $__rows -lt $__min_rows ]; then 516 setvar "$__var_rows" $__min_rows 517 elif [ $__rows -gt $__max_rows ]; then 518 setvar "$__var_rows" $__max_rows 519 fi 520 fi 521 522 if [ "$debug" ]; then 523 # Print final constrained values to debuggin 524 f_quietly f_getvar "$__var_height" 525 f_quietly f_getvar "$__var_width" 526 f_quietly f_getvar "$__var_rows" 527 fi 528 529 return $__retval # success if no debug warnings were printed 530} 531 532# f_dialog_infobox_size [-n] $var_height $var_width \ 533# $title $backtitle $prompt [$hline] 534# 535# Not all versions of dialog(1) perform auto-sizing of the width and height of 536# `--infobox' boxes sensibly. 537# 538# This function helps solve this issue by taking two sets of sequential 539# arguments. The first set of arguments are the variable names to use when 540# storing the calculated height and width. The second set of arguments are the 541# title, backtitle, prompt, and [optionally] hline. The optimal height and 542# width for the described widget (not exceeding the actual terminal height or 543# width) is stored in $var_height and $var_width (respectively). 544# 545# If the first argument is `-n', the calculated sizes ($var_height and 546# $var_width) are not constrained to minimum/maximum values. 547# 548# Newline character sequences (``\n'') in $prompt are expanded as-is done by 549# dialog(1). 550# 551f_dialog_infobox_size() 552{ 553 local __constrain=1 554 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 555 local __var_height="$1" __var_width="$2" 556 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6" 557 558 # Return unless at least one size aspect has been requested 559 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 560 561 # Default height/width of zero for auto-sizing 562 local __height=0 __width=0 __n 563 564 # Adjust height if desired 565 if [ "$__var_height" ]; then 566 # 567 # Set height based on number of rows in prompt 568 # 569 __n=$( echo -n "$__prompt" | f_number_of_lines ) 570 __n=$(( $__n + 2 )) 571 [ $__n -gt $__height ] && __height=$__n 572 573 # 574 # For Xdialog(1) bump height if backtitle is enabled (displayed 575 # in the X11 window with a separator line between the backtitle 576 # and msg text). 577 # 578 if [ "$USE_XDIALOG" -a "$__btitle" ]; then 579 __n=$( echo "$__btitle" | f_number_of_lines ) 580 __height=$(( $__height + $__n + 2 )) 581 fi 582 583 setvar "$__var_height" $__height 584 fi 585 586 # Adjust width if desired 587 if [ "$__var_width" ]; then 588 # 589 # Bump width for long titles 590 # 591 __n=$(( ${#__title} + 4 )) 592 [ $__n -gt $__width ] && __width=$__n 593 594 # 595 # If using Xdialog(1), bump width for long backtitles (which 596 # appear within the window). 597 # 598 if [ "$USE_XDIALOG" ]; then 599 __n=$(( ${#__btitle} + 4 )) 600 [ $__n -gt $__width ] && __width=$__n 601 fi 602 603 # 604 # Bump width for long prompts 605 # 606 __n=$( echo "$__prompt" | f_longest_line_length ) 607 __n=$(( $__n + 4 )) # add width for border 608 [ $__n -gt $__width ] && __width=$__n 609 610 # 611 # Bump width for long hlines. Xdialog(1) supports `--hline' but 612 # it's currently not used (so don't do anything here if using 613 # Xdialog(1)). 614 # 615 if [ ! "$USE_XDIALOG" ]; then 616 __n=$(( ${#__hline} + 10 )) 617 [ $__n -gt $__width ] && __width=$__n 618 fi 619 620 # Bump width by 16.6% if using Xdialog(1) 621 [ "$USE_XDIALOG" ] && __width=$(( $__width + $__width / 6 )) 622 623 setvar "$__var_width" $__width 624 fi 625 626 # Constrain values to sensible minimums/maximums unless `-n' was passed 627 # Return success if no-constrain, else return status from constrain 628 [ ! "$__constrain" ] || 629 f_dialog_size_constrain "$__var_height" "$__var_width" 630} 631 632# f_dialog_buttonbox_size [-n] $var_height $var_width \ 633# $title $backtitle $prompt [$hline] 634# 635# Not all versions of dialog(1) perform auto-sizing of the width and height of 636# `--msgbox' and `--yesno' boxes sensibly. 637# 638# This function helps solve this issue by taking two sets of sequential 639# arguments. The first set of arguments are the variable names to use when 640# storing the calculated height and width. The second set of arguments are the 641# title, backtitle, prompt, and [optionally] hline. The optimal height and 642# width for the described widget (not exceeding the actual terminal height or 643# width) is stored in $var_height and $var_width (respectively). 644# 645# If the first argument is `-n', the calculated sizes ($var_height and 646# $var_width) are not constrained to minimum/maximum values. 647# 648# Newline character sequences (``\n'') in $prompt are expanded as-is done by 649# dialog(1). 650# 651f_dialog_buttonbox_size() 652{ 653 local __constrain=1 654 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 655 local __var_height="$1" __var_width="$2" 656 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6" 657 658 # Return unless at least one size aspect has been requested 659 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 660 661 # Calculate height/width of infobox (adjusted/constrained below) 662 # NOTE: Function name appended to prevent __var_{height,width} values 663 # from becoming local (and thus preventing setvar from working). 664 local __height_bbox_size __width_bbox_size 665 f_dialog_infobox_size -n \ 666 "${__var_height:+__height_bbox_size}" \ 667 "${__var_width:+__width_bbox_size}" \ 668 "$__title" "$__btitle" "$__prompt" "$__hline" 669 670 # Adjust height if desired 671 if [ "$__var_height" ]; then 672 # Add height to accomodate the buttons 673 __height_bbox_size=$(( $__height_bbox_size + 2 )) 674 675 # Adjust for clipping with Xdialog(1) on Linux/GTK2 676 [ "$USE_XDIALOG" ] && 677 __height_bbox_size=$(( $__height_bbox_size + 3 )) 678 679 setvar "$__var_height" $__height_bbox_size 680 fi 681 682 # No adjustemnts to width, just pass-thru the infobox width 683 if [ "$__var_width" ]; then 684 setvar "$__var_width" $__width_bbox_size 685 fi 686 687 # Constrain values to sensible minimums/maximums unless `-n' was passed 688 # Return success if no-constrain, else return status from constrain 689 [ ! "$__constrain" ] || 690 f_dialog_size_constrain "$__var_height" "$__var_width" 691} 692 693# f_dialog_inputbox_size [-n] $var_height $var_width \ 694# $title $backtitle $prompt $init [$hline] 695# 696# Not all versions of dialog(1) perform auto-sizing of the width and height of 697# `--inputbox' boxes sensibly. 698# 699# This function helps solve this issue by taking two sets of sequential 700# arguments. The first set of arguments are the variable names to use when 701# storing the calculated height and width. The second set of arguments are the 702# title, backtitle, prompt, and [optionally] hline. The optimal height and 703# width for the described widget (not exceeding the actual terminal height or 704# width) is stored in $var_height and $var_width (respectively). 705# 706# If the first argument is `-n', the calculated sizes ($var_height and 707# $var_width) are not constrained to minimum/maximum values. 708# 709# Newline character sequences (``\n'') in $prompt are expanded as-is done by 710# dialog(1). 711# 712f_dialog_inputbox_size() 713{ 714 local __constrain=1 715 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 716 local __var_height="$1" __var_width="$2" 717 local __title="$3" __btitle="$4" __prompt="$5" __init="$6" __hline="$7" 718 719 # Return unless at least one size aspect has been requested 720 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 721 722 # Calculate height/width of buttonbox (adjusted/constrained below) 723 # NOTE: Function name appended to prevent __var_{height,width} values 724 # from becoming local (and thus preventing setvar from working). 725 local __height_ibox_size __width_ibox_size 726 f_dialog_buttonbox_size -n \ 727 "${__var_height:+__height_ibox_size}" \ 728 "${__var_width:+__width_ibox_size}" \ 729 "$__title" "$__btitle" "$__prompt" "$__hline" 730 731 # Adjust height if desired 732 if [ "$__var_height" ]; then 733 # Add height for input box (not needed for Xdialog(1)) 734 [ ! "$USE_XDIALOG" ] && 735 __height_ibox_size=$(( $__height_ibox_size + 3 )) 736 737 setvar "$__var_height" $__height_ibox_size 738 fi 739 740 # Adjust width if desired 741 if [ "$__var_width" ]; then 742 # Bump width for initial text (something neither dialog(1) nor 743 # Xdialog(1) do, but worth it!; add 16.6% if using Xdialog(1)) 744 local __n=$(( ${#__init} + 7 )) 745 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) 746 [ $__n -gt $__width_ibox_size ] && __width_ibox_size=$__n 747 748 setvar "$__var_width" $__width_ibox_size 749 fi 750 751 # Constrain values to sensible minimums/maximums unless `-n' was passed 752 # Return success if no-constrain, else return status from constrain 753 [ ! "$__constrain" ] || 754 f_dialog_size_constrain "$__var_height" "$__var_width" 755} 756 757# f_xdialog_2inputsbox_size [-n] $var_height $var_width \ 758# $title $backtitle $prompt \ 759# $label1 $init1 $label2 $init2 760# 761# Xdialog(1) does not perform auto-sizing of the width and height of 762# `--2inputsbox' boxes sensibly. 763# 764# This function helps solve this issue by taking two sets of sequential 765# arguments. The first set of arguments are the variable names to use when 766# storing the calculated height and width. The second set of arguments are the 767# title, backtitle, prompt, label for the first field, initial text for said 768# field, label for the second field, and initial text for said field. The 769# optimal height and width for the described widget (not exceeding the actual 770# terminal height or width) is stored in $var_height and $var_width 771# (respectively). 772# 773# If the first argument is `-n', the calculated sizes ($var_height and 774# $var_width) are not constrained to minimum/maximum values. 775# 776# Newline character sequences (``\n'') in $prompt are expanded as-is done by 777# Xdialog(1). 778# 779f_xdialog_2inputsbox_size() 780{ 781 local __constrain=1 782 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 783 local __var_height="$1" __var_width="$2" 784 local __title="$3" __btitle="$4" __prompt="$5" 785 local __label1="$6" __init1="$7" __label2="$8" __init2="$9" 786 787 # Return unless at least one size aspect has been requested 788 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 789 790 # Calculate height/width of inputbox (adjusted/constrained below) 791 # NOTE: Function name appended to prevent __var_{height,width} values 792 # from becoming local (and thus preventing setvar from working). 793 local __height_2ibox_size __width_2ibox_size 794 f_dialog_inputbox_size -n \ 795 "${__var_height:+__height_2ibox_size}" \ 796 "${__var_width:+__width_2ibox_size}" \ 797 "$__title" "$__btitle" "$__prompt" "$__hline" "$__init1" 798 799 # Adjust height if desired 800 if [ "$__var_height" ]; then 801 # Add height for 1st label, 2nd label, and 2nd input box 802 __height_2ibox_size=$(( $__height_2ibox_size + 2 + 2 + 2 )) 803 setvar "$__var_height" $__height_2ibox_size 804 fi 805 806 # Adjust width if desired 807 if [ "$__var_width" ]; then 808 local __n 809 810 # Bump width for first label text (+16.6% since Xdialog(1)) 811 __n=$(( ${#__label1} + 7 )) 812 __n=$(( $__n + $__n / 6 )) 813 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n 814 815 # Bump width for second label text (+16.6% since Xdialog(1)) 816 __n=$(( ${#__label2} + 7 )) 817 __n=$(( $__n + $__n / 6 )) 818 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n 819 820 # Bump width for 2nd initial text (something neither dialog(1) 821 # nor Xdialog(1) do, but worth it!; +16.6% since Xdialog(1)) 822 __n=$(( ${#__init2} + 7 )) 823 __n=$(( $__n + $__n / 6 )) 824 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n 825 826 setvar "$__var_width" $__width_2ibox_size 827 fi 828 829 # Constrain values to sensible minimums/maximums unless `-n' was passed 830 # Return success if no-constrain, else return status from constrain 831 [ ! "$__constrain" ] || 832 f_dialog_size_constrain "$__var_height" "$__var_width" 833} 834 835# f_dialog_menu_size [-n] $var_height $var_width $var_rows \ 836# $title $backtitle $prompt $hline \ 837# $tag1 $item1 $tag2 $item2 ... 838# 839# Not all versions of dialog(1) perform auto-sizing of the width and height of 840# `--menu' boxes sensibly. 841# 842# This function helps solve this issue by taking three sets of sequential 843# arguments. The first set of arguments are the variable names to use when 844# storing the calculated height, width, and rows. The second set of arguments 845# are the title, backtitle, prompt, and hline. The [optional] third set of 846# arguments are the menu list itself (comprised of tag/item couplets). The 847# optimal height, width, and rows for the described widget (not exceeding the 848# actual terminal height or width) is stored in $var_height, $var_width, and 849# $var_rows (respectively). 850# 851# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 852# and $var_rows) are not constrained to minimum/maximum values. 853# 854f_dialog_menu_size() 855{ 856 local __constrain=1 857 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 858 local __var_height="$1" __var_width="$2" __var_rows="$3" 859 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7" 860 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline 861 862 # Return unless at least one size aspect has been requested 863 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] || 864 return $FAILURE 865 866 # Calculate height/width of infobox (adjusted/constrained below) 867 # NOTE: Function name appended to prevent __var_{height,width} values 868 # from becoming local (and thus preventing setvar from working). 869 local __height_menu_size __width_menu_size 870 f_dialog_infobox_size -n \ 871 "${__var_height:+__height_menu_size}" \ 872 "${__var_width:+__width_menu_size}" \ 873 "$__title" "$__btitle" "$__prompt" "$__hline" 874 875 # 876 # Always process the menu-item arguments to get the longest tag-length, 877 # longest item-length (both used to bump the width), and the number of 878 # rows (used to bump the height). 879 # 880 local __longest_tag=0 __longest_item=0 __rows=0 881 while [ $# -ge 2 ]; do 882 local __tag="$1" __item="$2" 883 shift 2 # tag/item 884 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag} 885 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item} 886 __rows=$(( $__rows + 1 )) 887 done 888 889 # Adjust rows early (for up-comning height calculation) 890 if [ "$__var_height" -o "$__var_rows" ]; then 891 # Add a row for visual aid if using Xdialog(1) 892 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 )) 893 fi 894 895 # Adjust height if desired 896 if [ "$__var_height" ]; then 897 # Add rows to height 898 if [ "$USE_XDIALOG" ]; then 899 __height_menu_size=$(( 900 $__height_menu_size + $__rows + 7 )) 901 else 902 __height_menu_size=$(( 903 $__height_menu_size + $__rows + 4 )) 904 fi 905 setvar "$__var_height" $__height_menu_size 906 fi 907 908 # Adjust width if desired 909 if [ "$__var_width" ]; then 910 # The sum total between the longest tag-length and the 911 # longest item-length should be used to bump menu width 912 local __n=$(( $__longest_tag + $__longest_item + 10 )) 913 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6% 914 [ $__n -gt $__width_menu_size ] && __width_menu_size=$__n 915 916 setvar "$__var_width" $__width_menu_size 917 fi 918 919 # Store adjusted rows if desired 920 [ "$__var_rows" ] && setvar "$__var_rows" $__rows 921 922 # Constrain height, width, and rows to sensible minimum/maximum values 923 # Return success if no-constrain, else return status from constrain 924 [ ! "$__constrain" ] || f_dialog_menu_constrain \ 925 "$__var_height" "$__var_width" "$__var_rows" "$__prompt" 926} 927 928# f_dialog_menu_with_help_size [-n] $var_height $var_width $var_rows \ 929# $title $backtitle $prompt $hline \ 930# $tag1 $item1 $help1 $tag2 $item2 $help2 ... 931# 932# Not all versions of dialog(1) perform auto-sizing of the width and height of 933# `--menu' boxes sensibly. 934# 935# This function helps solve this issue by taking three sets of sequential 936# arguments. The first set of arguments are the variable names to use when 937# storing the calculated height, width, and rows. The second set of arguments 938# are the title, backtitle, prompt, and hline. The [optional] third set of 939# arguments are the menu list itself (comprised of tag/item/help triplets). The 940# optimal height, width, and rows for the described widget (not exceeding the 941# actual terminal height or width) is stored in $var_height, $var_width, and 942# $var_rows (respectively). 943# 944# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 945# and $var_rows) are not constrained to minimum/maximum values. 946# 947f_dialog_menu_with_help_size() 948{ 949 local __constrain=1 950 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 951 local __var_height="$1" __var_width="$2" __var_rows="$3" 952 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7" 953 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline 954 955 # Return unless at least one size aspect has been requested 956 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] || 957 return $FAILURE 958 959 # Calculate height/width of infobox (adjusted/constrained below) 960 # NOTE: Function name appended to prevent __var_{height,width} values 961 # from becoming local (and thus preventing setvar from working). 962 local __height_menu_with_help_size __width_menu_with_help_size 963 f_dialog_infobox_size -n \ 964 "${__var_height:+__height_menu_with_help_size}" \ 965 "${__var_width:+__width_menu_with_help_size}" \ 966 "$__title" "$__btitle" "$__prompt" "$__hline" 967 968 # 969 # Always process the menu-item arguments to get the longest tag-length, 970 # longest item-length, longest help-length (help-length only considered 971 # if using Xdialog(1), as it places the help string in the widget) -- 972 # all used to bump the width -- and the number of rows (used to bump 973 # the height). 974 # 975 local __longest_tag=0 __longest_item=0 __longest_help=0 __rows=0 976 while [ $# -ge 3 ]; do 977 local __tag="$1" __item="$2" __help="$3" 978 shift 3 # tag/item/help 979 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag} 980 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item} 981 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help} 982 __rows=$(( $__rows + 1 )) 983 done 984 985 # Adjust rows early (for up-coming height calculation) 986 if [ "$__var_height" -o "$__var_rows" ]; then 987 # Add a row for visual aid if using Xdialog(1) 988 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 )) 989 fi 990 991 # Adjust height if desired 992 if [ "$__var_height" ]; then 993 # Add rows to height 994 if [ "$USE_XDIALOG" ]; then 995 __height_menu_with_help_size=$(( 996 $__height_menu_with_help_size + $__rows + 8 )) 997 else 998 __height_menu_with_help_size=$(( 999 $__height_menu_with_help_size + $__rows + 4 )) 1000 fi 1001 setvar "$__var_height" $__height_menu_with_help_size 1002 fi 1003 1004 # Adjust width if desired 1005 if [ "$__var_width" ]; then 1006 # The sum total between the longest tag-length and the 1007 # longest item-length should be used to bump menu width 1008 local __n=$(( $__longest_tag + $__longest_item + 10 )) 1009 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6% 1010 [ $__n -gt $__width_menu_with_help_size ] && 1011 __width_menu_with_help_size=$__n 1012 1013 # Update width for help text if using Xdialog(1) 1014 if [ "$USE_XDIALOG" ]; then 1015 __n=$(( $__longest_help + 10 )) 1016 __n=$(( $__n + $__n / 6 )) # plus 16.6% 1017 [ $__n -gt $__width_menu_with_help_size ] && 1018 __width_menu_with_help_size=$__n 1019 fi 1020 1021 setvar "$__var_width" $__width_menu_with_help_size 1022 fi 1023 1024 # Store adjusted rows if desired 1025 [ "$__var_rows" ] && setvar "$__var_rows" $__rows 1026 1027 # Constrain height, width, and rows to sensible minimum/maximum values 1028 # Return success if no-constrain, else return status from constrain 1029 [ ! "$__constrain" ] || f_dialog_menu_constrain \ 1030 "$__var_height" "$__var_width" "$__var_rows" "$__prompt" 1031} 1032 1033# f_dialog_radiolist_size [-n] $var_height $var_width $var_rows \ 1034# $title $backtitle $prompt $hline \ 1035# $tag1 $item1 $status1 $tag2 $item2 $status2 ... 1036# 1037# Not all versions of dialog(1) perform auto-sizing of the width and height of 1038# `--radiolist' boxes sensibly. 1039# 1040# This function helps solve this issue by taking three sets of sequential 1041# arguments. The first set of arguments are the variable names to use when 1042# storing the calculated height, width, and rows. The second set of arguments 1043# are the title, backtitle, prompt, and hline. The [optional] third set of 1044# arguments are the radio list itself (comprised of tag/item/status triplets). 1045# The optimal height, width, and rows for the described widget (not exceeding 1046# the actual terminal height or width) is stored in $var_height, $var_width, 1047# and $var_rows (respectively). 1048# 1049# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 1050# and $var_rows) are not constrained to minimum/maximum values. 1051# 1052f_dialog_radiolist_size() 1053{ 1054 local __constrain=1 1055 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 1056 local __var_height="$1" __var_width="$2" __var_rows="$3" 1057 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7" 1058 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline 1059 1060 # Return unless at least one size aspect has been requested 1061 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] || 1062 return $FAILURE 1063 1064 # Calculate height/width of infobox (adjusted/constrained below) 1065 # NOTE: Function name appended to prevent __var_{height,width} values 1066 # from becoming local (and thus preventing setvar from working). 1067 local __height_rlist_size __width_rlist_size 1068 f_dialog_infobox_size -n \ 1069 "${__var_height:+__height_rlist_size}" \ 1070 "${__var_width:+__width_rlist_size}" \ 1071 "$__title" "$__btitle" "$__prompt" "$__hline" 1072 1073 # 1074 # Always process the menu-item arguments to get the longest tag-length, 1075 # longest item-length (both used to bump the width), and the number of 1076 # rows (used to bump the height). 1077 # 1078 local __longest_tag=0 __longest_item=0 __rows=0 1079 while [ $# -ge 3 ]; do 1080 local __tag="$1" __item="$2" 1081 shift 3 # tag/item/status 1082 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag} 1083 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item} 1084 __rows=$(( $__rows + 1 )) 1085 done 1086 1087 # Adjust rows early (for up-coming height calculation) 1088 if [ "$__var_height" -o "$__var_rows" ]; then 1089 # Add a row for visual aid if using Xdialog(1) 1090 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 )) 1091 fi 1092 1093 # Adjust height if desired 1094 if [ "$__var_height" ]; then 1095 # Add rows to height 1096 if [ "$USE_XDIALOG" ]; then 1097 __height_rlist_size=$(( 1098 $__height_rlist_size + $__rows + 7 )) 1099 else 1100 __height_rlist_size=$(( 1101 $__height_rlist_size + $__rows + 4 )) 1102 fi 1103 setvar "$__var_height" $__height_rlist_size 1104 fi 1105 1106 # Adjust width if desired 1107 if [ "$__var_width" ]; then 1108 # Sum total between longest tag-length, longest item-length, 1109 # and radio-button width should be used to bump menu width 1110 local __n=$(( $__longest_tag + $__longest_item + 13 )) 1111 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6% 1112 [ $__n -gt $__width_rlist_size ] && __width_rlist_size=$__n 1113 1114 setvar "$__var_width" $__width_rlist_size 1115 fi 1116 1117 # Store adjusted rows if desired 1118 [ "$__var_rows" ] && setvar "$__var_rows" $__rows 1119 1120 # Constrain height, width, and rows to sensible minimum/maximum values 1121 # Return success if no-constrain, else return status from constrain 1122 [ ! "$__constrain" ] || f_dialog_menu_constrain \ 1123 "$__var_height" "$__var_width" "$__var_rows" "$__prompt" 1124} 1125 1126# f_dialog_checklist_size [-n] $var_height $var_width $var_rows \ 1127# $title $backtitle $prompt $hline \ 1128# $tag1 $item1 $status1 $tag2 $item2 $status2 ... 1129# 1130# Not all versions of dialog(1) perform auto-sizing of the width and height of 1131# `--checklist' boxes sensibly. 1132# 1133# This function helps solve this issue by taking three sets of sequential 1134# arguments. The first set of arguments are the variable names to use when 1135# storing the calculated height, width, and rows. The second set of arguments 1136# are the title, backtitle, prompt, and hline. The [optional] third set of 1137# arguments are the check list itself (comprised of tag/item/status triplets). 1138# The optimal height, width, and rows for the described widget (not exceeding 1139# the actual terminal height or width) is stored in $var_height, $var_width, 1140# and $var_rows (respectively). 1141# 1142# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 1143# and $var_rows) are not constrained to minimum/maximum values. 1144# 1145f_dialog_checklist_size() 1146{ 1147 f_dialog_radiolist_size "$@" 1148} 1149 1150# f_dialog_radiolist_with_help_size [-n] $var_height $var_width $var_rows \ 1151# $title $backtitle $prompt $hline \ 1152# $tag1 $item1 $status1 $help1 \ 1153# $tag2 $item2 $status2 $help2 ... 1154# 1155# Not all versions of dialog(1) perform auto-sizing of the width and height of 1156# `--radiolist' boxes sensibly. 1157# 1158# This function helps solve this issue by taking three sets of sequential 1159# arguments. The first set of arguments are the variable names to use when 1160# storing the calculated height, width, and rows. The second set of arguments 1161# are the title, backtitle, prompt, and hline. The [optional] third set of 1162# arguments are the radio list itself (comprised of tag/item/status/help 1163# quadruplets). The optimal height, width, and rows for the described widget 1164# (not exceeding the actual terminal height or width) is stored in $var_height, 1165# $var_width, and $var_rows (respectively). 1166# 1167# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 1168# and $var_rows) are not constrained to minimum/maximum values. 1169# 1170f_dialog_radiolist_with_help_size() 1171{ 1172 local __constrain=1 1173 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 1174 local __var_height="$1" __var_width="$2" __var_rows="$3" 1175 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7" 1176 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline 1177 1178 # Return unless at least one size aspect has been requested 1179 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] || 1180 return $FAILURE 1181 1182 # Calculate height/width of infobox (adjusted/constrained below) 1183 # NOTE: Function name appended to prevent __var_{height,width} values 1184 # from becoming local (and thus preventing setvar from working). 1185 local __height_rlist_with_help_size __width_rlist_with_help_size 1186 f_dialog_infobox_size -n \ 1187 "${__var_height:+__height_rlist_with_help_size}" \ 1188 "${__var_width:+__width_rlist_with_help_size}" \ 1189 "$__title" "$__btitle" "$__prompt" "$__hline" 1190 1191 # 1192 # Always process the menu-item arguments to get the longest tag-length, 1193 # longest item-length, longest help-length (help-length only considered 1194 # if using Xdialog(1), as it places the help string in the widget) -- 1195 # all used to bump the width -- and the number of rows (used to bump 1196 # the height). 1197 # 1198 local __longest_tag=0 __longest_item=0 __longest_help=0 __rows=0 1199 while [ $# -ge 4 ]; do 1200 local __tag="$1" __item="$2" __status="$3" __help="$4" 1201 shift 4 # tag/item/status/help 1202 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag} 1203 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item} 1204 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help} 1205 __rows=$(( $__rows + 1 )) 1206 done 1207 1208 # Adjust rows early (for up-coming height calculation) 1209 if [ "$__var_height" -o "$__var_rows" ]; then 1210 # Add a row for visual aid if using Xdialog(1) 1211 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 )) 1212 fi 1213 1214 # Adjust height if desired 1215 if [ "$__var_height" ]; then 1216 # Add rows to height 1217 if [ "$USE_XDIALOG" ]; then 1218 __height_rlist_with_help_size=$(( 1219 $__height_rlist_with_help_size + $__rows + 7 )) 1220 else 1221 __height_rlist_with_help_size=$(( 1222 $__height_rlist_with_help_size + $__rows + 4 )) 1223 fi 1224 setvar "$__var_height" $__height 1225 fi 1226 1227 # Adjust width if desired 1228 if [ "$__var_width" ]; then 1229 # Sum total between longest tag-length, longest item-length, 1230 # and radio-button width should be used to bump menu width 1231 local __n=$(( $__longest_tag + $__longest_item + 13 )) 1232 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6% 1233 [ $__n -gt $__width_rlist_with_help_size ] && 1234 __width_rlist_with_help_size=$__n 1235 1236 # Update width for help text if using Xdialog(1) 1237 if [ "$USE_XDIALOG" ]; then 1238 __n=$(( $__longest_help + 10 )) 1239 __n=$(( $__n + $__n / 6 )) # plus 16.6% 1240 [ $__n -gt $__width_rlist_with_help_size ] && 1241 __width_rlist_with_help_size=$__n 1242 fi 1243 1244 setvar "$__var_width" $__width_rlist_with_help_size 1245 fi 1246 1247 # Store adjusted rows if desired 1248 [ "$__var_rows" ] && setvar "$__var_rows" $__rows 1249 1250 # Constrain height, width, and rows to sensible minimum/maximum values 1251 # Return success if no-constrain, else return status from constrain 1252 [ ! "$__constrain" ] || f_dialog_menu_constrain \ 1253 "$__var_height" "$__var_width" "$__var_rows" "$__prompt" 1254} 1255 1256# f_dialog_checklist_with_help_size [-n] $var_height $var_width $var_rows \ 1257# $title $backtitle $prompt $hline \ 1258# $tag1 $item1 $status1 $help1 \ 1259# $tag2 $item2 $status2 $help2 ... 1260# 1261# Not all versions of dialog(1) perform auto-sizing of the width and height of 1262# `--checklist' boxes sensibly. 1263# 1264# This function helps solve this issue by taking three sets of sequential 1265# arguments. The first set of arguments are the variable names to use when 1266# storing the calculated height, width, and rows. The second set of arguments 1267# are the title, backtitle, prompt, and hline. The [optional] third set of 1268# arguments are the check list itself (comprised of tag/item/status/help 1269# quadruplets). The optimal height, width, and rows for the described widget 1270# (not exceeding the actual terminal height or width) is stored in $var_height, 1271# $var_width, and $var_rows (respectively). 1272# 1273# If the first argument is `-n', the calculated sizes ($var_height, $var_width, 1274# and $var_rows) are not constrained to minimum/maximum values. 1275# 1276f_dialog_checklist_with_help_size() 1277{ 1278 f_dialog_radiolist_with_help_size "$@" 1279} 1280 1281# f_dialog_calendar_size [-n] $var_height $var_width \ 1282# $title $backtitle $prompt [$hline] 1283# 1284# Not all versions of dialog(1) perform auto-sizing of the width and height of 1285# `--calendar' boxes sensibly. 1286# 1287# This function helps solve this issue by taking two sets of sequential 1288# arguments. The first set of arguments are the variable names to use when 1289# storing the calculated height and width. The second set of arguments are the 1290# title, backtitle, prompt, and [optionally] hline. The optimal height and 1291# width for the described widget (not exceeding the actual terminal height or 1292# width) is stored in $var_height and $var_width (respectively). 1293# 1294# If the first argument is `-n', the calculated sizes ($var_height and 1295# $var_width) are not constrained to minimum/maximum values. 1296# 1297# Newline character sequences (``\n'') in $prompt are expanded as-is done by 1298# dialog(1). 1299# 1300f_dialog_calendar_size() 1301{ 1302 local __constrain=1 1303 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 1304 local __var_height="$1" __var_width="$2" 1305 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6" 1306 1307 # Return unless at least one size aspect has been requested 1308 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 1309 1310 # 1311 # Obtain/Adjust minimum and maximum thresholds 1312 # NOTE: Function name appended to prevent __var_{height,width} values 1313 # from becoming local (and thus preventing setvar from working). 1314 # 1315 local __max_height_cal_size __max_width_cal_size 1316 f_dialog_max_size __max_height_cal_size __max_width_cal_size 1317 __max_width_cal_size=$(( $__max_width_cal_size - 2 )) 1318 # the calendar box will refuse to display if too wide 1319 local __min_width 1320 if [ "$USE_XDIALOG" ]; then 1321 __min_width=55 1322 else 1323 __min_width=40 1324 __max_height_cal_size=$(( 1325 $__max_height_cal_size - $DIALOG_CALENDAR_HEIGHT )) 1326 # When using dialog(1), we can't predict whether the user has 1327 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll 1328 # subtract one for the potential shadow around the widget 1329 __max_height_cal_size=$(( $__max_height_cal_size - 1 )) 1330 fi 1331 1332 # Calculate height if desired 1333 if [ "$__var_height" ]; then 1334 local __height 1335 __height=$( echo "$__prompt" | f_number_of_lines ) 1336 1337 if [ "$USE_XDIALOG" ]; then 1338 # Add height to accomodate for embedded calendar widget 1339 __height=$(( $__height + $DIALOG_CALENDAR_HEIGHT - 1 )) 1340 1341 # Also, bump height if backtitle is enabled 1342 if [ "$__btitle" ]; then 1343 local __n 1344 __n=$( echo "$__btitle" | f_number_of_lines ) 1345 __height=$(( $__height + $__n + 2 )) 1346 fi 1347 else 1348 [ "$__prompt" ] && __height=$(( $__height + 1 )) 1349 fi 1350 1351 # Enforce maximum height, unless `-n' was passed 1352 [ "$__constrain" -a $__height -gt $__max_height_cal_size ] && 1353 __height=$__max_height_cal_size 1354 1355 setvar "$__var_height" $__height 1356 fi 1357 1358 # Calculate width if desired 1359 if [ "$__var_width" ]; then 1360 # NOTE: Function name appended to prevent __var_{height,width} 1361 # values from becoming local (and thus preventing setvar 1362 # from working). 1363 local __width_cal_size 1364 f_dialog_infobox_size -n "" __width_cal_size \ 1365 "$__title" "$__btitle" "$__prompt" "$__hline" 1366 1367 # Enforce minimum/maximum width, unless `-n' was passed 1368 if [ "$__constrain" ]; then 1369 if [ $__width_cal_size -lt $__min_width ]; then 1370 __width_cal_size=$__min_width 1371 elif [ $__width_cal_size -gt $__max_width_cal_size ] 1372 then 1373 __width_cal_size=$__max_width_size 1374 fi 1375 fi 1376 1377 setvar "$__var_width" $__width_cal_size 1378 fi 1379 1380 return $SUCCESS 1381} 1382 1383# f_dialog_timebox_size [-n] $var_height $var_width \ 1384# $title $backtitle $prompt [$hline] 1385# 1386# Not all versions of dialog(1) perform auto-sizing of the width and height of 1387# `--timebox' boxes sensibly. 1388# 1389# This function helps solve this issue by taking two sets of sequential 1390# arguments. The first set of arguments are the variable names to use when 1391# storing the calculated height and width. The second set of arguments are the 1392# title, backtitle, prompt, and [optionally] hline. The optional height and 1393# width for the described widget (not exceeding the actual terminal height or 1394# width) is stored in $var_height and $var_width (respectively). 1395# 1396# If the first argument is `-n', the calculated sizes ($var_height and 1397# $var_width) are not constrained to minimum/maximum values. 1398# 1399# Newline character sequences (``\n'') in $prompt are expanded as-is done by 1400# dialog(1). 1401# 1402f_dialog_timebox_size() 1403{ 1404 local __constrain=1 1405 [ "$1" = "-n" ] && __constrain= && shift 1 # -n 1406 local __var_height="$1" __var_width="$2" 1407 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6" 1408 1409 # Return unless at least one size aspect has been requested 1410 [ "$__var_height" -o "$__var_width" ] || return $FAILURE 1411 1412 # 1413 # Obtain/Adjust minimum and maximum thresholds 1414 # NOTE: Function name appended to prevent __var_{height,width} values 1415 # from becoming local (and thus preventing setvar from working). 1416 # 1417 local __max_height_tbox_size __max_width_tbox_size 1418 f_dialog_max_size __max_height_tbox_size __max_width_tbox_size 1419 __max_width_tbox_size=$(( $__max_width_tbox_size - 2 )) 1420 # the timebox widget refuses to display if too wide 1421 local __min_width 1422 if [ "$USE_XDIALOG" ]; then 1423 __min_width=40 1424 else 1425 __min_width=20 1426 __max_height_tbox_size=$(( \ 1427 $__max_height_tbox_size - $DIALOG_TIMEBOX_HEIGHT )) 1428 # When using dialog(1), we can't predict whether the user has 1429 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll 1430 # subtract one for the potential shadow around the widget 1431 __max_height_tbox_size=$(( $__max_height_tbox_size - 1 )) 1432 fi 1433 1434 # Calculate height if desired 1435 if [ "$__var_height" -a "$USE_XDIALOG" ]; then 1436 # When using Xdialog(1), the height seems to have 1437 # no effect. All values provide the same results. 1438 setvar "$__var_height" 0 # autosize 1439 elif [ "$__var_height" ]; then 1440 local __height 1441 __height=$( echo "$__prompt" | f_number_of_lines ) 1442 __height=$(( $__height ${__prompt:++1} + 1 )) 1443 1444 # Enforce maximum height, unless `-n' was passed 1445 [ "$__constrain" -a $__height -gt $__max_height_tbox_size ] && 1446 __height=$__max_height_tbox_size 1447 1448 setvar "$__var_height" $__height 1449 fi 1450 1451 # Calculate width if desired 1452 if [ "$__var_width" ]; then 1453 # NOTE: Function name appended to prevent __var_{height,width} 1454 # values from becoming local (and thus preventing setvar 1455 # from working). 1456 local __width_tbox_size 1457 f_dialog_infobox_size -n "" __width_tbox_size \ 1458 "$__title" "$__btitle" "$__prompt" "$__hline" 1459 1460 # Enforce the minimum width for displaying the timebox 1461 if [ "$__constrain" ]; then 1462 if [ $__width_tbox_size -lt $__min_width ]; then 1463 __width_tbox_size=$__min_width 1464 elif [ $__width_tbox_size -ge $__max_width_tbox_size ] 1465 then 1466 __width_tbox_size=$__max_width_tbox_size 1467 fi 1468 fi 1469 1470 setvar "$__var_width" $__width_tbox_size 1471 fi 1472 1473 return $SUCCESS 1474} 1475 1476############################################################ CLEAR FUNCTIONS 1477 1478# f_dialog_clear 1479# 1480# Clears any/all previous dialog(1) displays. 1481# 1482f_dialog_clear() 1483{ 1484 $DIALOG --clear 1485} 1486 1487############################################################ INFO FUNCTIONS 1488 1489# f_dialog_info $info_text ... 1490# 1491# Throw up a dialog(1) infobox. The infobox remains until another dialog is 1492# displayed or `dialog --clear' (or f_dialog_clear) is called. 1493# 1494f_dialog_info() 1495{ 1496 local info_text="$*" height width 1497 f_dialog_infobox_size height width \ 1498 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text" 1499 $DIALOG \ 1500 --title "$DIALOG_TITLE" \ 1501 --backtitle "$DIALOG_BACKTITLE" \ 1502 ${USE_XDIALOG:+--ignore-eof} \ 1503 ${USE_XDIALOG:+--no-buttons} \ 1504 --infobox "$info_text" $height $width 1505} 1506 1507# f_xdialog_info $info_text ... 1508# 1509# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces 1510# EOF. This implies that you must execute this either as an rvalue to a pipe, 1511# lvalue to indirection or in a sub-shell that provides data on stdin. 1512# 1513f_xdialog_info() 1514{ 1515 local info_text="$*" height width 1516 f_dialog_infobox_size height width \ 1517 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text" 1518 $DIALOG \ 1519 --title "$DIALOG_TITLE" \ 1520 --backtitle "$DIALOG_BACKTITLE" \ 1521 --no-close --no-buttons \ 1522 --infobox "$info_text" $height $width \ 1523 -1 # timeout of -1 means abort when EOF on stdin 1524} 1525 1526############################################################ MSGBOX FUNCTIONS 1527 1528# f_dialog_msgbox $msg_text [$hline] 1529# 1530# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER 1531# or ESC, acknowledging the modal dialog. 1532# 1533# If the user presses ENTER, the exit status is zero (success), otherwise if 1534# the user presses ESC the exit status is 255. 1535# 1536f_dialog_msgbox() 1537{ 1538 local msg_text="$1" hline="$2" height width 1539 f_dialog_buttonbox_size height width \ 1540 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline" 1541 $DIALOG \ 1542 --title "$DIALOG_TITLE" \ 1543 --backtitle "$DIALOG_BACKTITLE" \ 1544 --hline "$hline" \ 1545 --ok-label "$msg_ok" \ 1546 --msgbox "$msg_text" $height $width 1547} 1548 1549############################################################ TEXTBOX FUNCTIONS 1550 1551# f_dialog_textbox $file 1552# 1553# Display the contents of $file (or an error if $file does not exist, etc.) in 1554# a dialog(1) textbox (which has a scrollable region for the text). The textbox 1555# remains until the user presses ENTER or ESC, acknowledging the modal dialog. 1556# 1557# If the user presses ENTER, the exit status is zero (success), otherwise if 1558# the user presses ESC the exit status is 255. 1559# 1560f_dialog_textbox() 1561{ 1562 local file="$1" 1563 local contents height width retval 1564 1565 contents=$( cat "$file" 2>&1 ) 1566 retval=$? 1567 1568 f_dialog_buttonbox_size height width \ 1569 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$contents" 1570 1571 if [ $retval -eq $SUCCESS ]; then 1572 $DIALOG \ 1573 --title "$DIALOG_TITLE" \ 1574 --backtitle "$DIALOG_BACKTITLE" \ 1575 --exit-label "$msg_ok" \ 1576 --no-cancel \ 1577 --textbox "$file" $height $width 1578 else 1579 $DIALOG \ 1580 --title "$DIALOG_TITLE" \ 1581 --backtitle "$DIALOG_BACKTITLE" \ 1582 --ok-label "$msg_ok" \ 1583 --msgbox "$contents" $height $width 1584 fi 1585} 1586 1587############################################################ YESNO FUNCTIONS 1588 1589# f_dialog_yesno $msg_text [$hline] 1590# 1591# Display a dialog(1) Yes/No prompt to allow the user to make some decision. 1592# The yesno prompt remains until the user presses ENTER or ESC, acknowledging 1593# the modal dialog. 1594# 1595# If the user chooses YES the exit status is zero, or chooses NO the exit 1596# status is one, or presses ESC the exit status is 255. 1597# 1598f_dialog_yesno() 1599{ 1600 local msg_text="$1" height width 1601 local hline="${2-$hline_arrows_tab_enter}" 1602 1603 f_interactive || return 0 # If non-interactive, return YES all the time 1604 1605 f_dialog_buttonbox_size height width \ 1606 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline" 1607 1608 if [ "$USE_XDIALOG" ]; then 1609 $DIALOG \ 1610 --title "$DIALOG_TITLE" \ 1611 --backtitle "$DIALOG_BACKTITLE" \ 1612 --hline "$hline" \ 1613 --ok-label "$msg_yes" \ 1614 --cancel-label "$msg_no" \ 1615 --yesno "$msg_text" $height $width 1616 else 1617 $DIALOG \ 1618 --title "$DIALOG_TITLE" \ 1619 --backtitle "$DIALOG_BACKTITLE" \ 1620 --hline "$hline" \ 1621 --yes-label "$msg_yes" \ 1622 --no-label "$msg_no" \ 1623 --yesno "$msg_text" $height $width 1624 fi 1625} 1626 1627# f_dialog_noyes $msg_text [$hline] 1628# 1629# Display a dialog(1) No/Yes prompt to allow the user to make some decision. 1630# The noyes prompt remains until the user presses ENTER or ESC, acknowledging 1631# the modal dialog. 1632# 1633# If the user chooses YES the exit status is zero, or chooses NO the exit 1634# status is one, or presses ESC the exit status is 255. 1635# 1636# NOTE: This is just like the f_dialog_yesno function except "No" is default. 1637# 1638f_dialog_noyes() 1639{ 1640 local msg_text="$1" height width 1641 local hline="${2-$hline_arrows_tab_enter}" 1642 1643 f_interactive || return 1 # If non-interactive, return NO all the time 1644 1645 f_dialog_buttonbox_size height width \ 1646 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline" 1647 1648 if [ "$USE_XDIALOG" ]; then 1649 $DIALOG \ 1650 --title "$DIALOG_TITLE" \ 1651 --backtitle "$DIALOG_BACKTITLE" \ 1652 --hline "$hline" \ 1653 --default-no \ 1654 --ok-label "$msg_yes" \ 1655 --cancel-label "$msg_no" \ 1656 --yesno "$msg_text" $height $width 1657 else 1658 $DIALOG \ 1659 --title "$DIALOG_TITLE" \ 1660 --backtitle "$DIALOG_BACKTITLE" \ 1661 --hline "$hline" \ 1662 --defaultno \ 1663 --yes-label "$msg_yes" \ 1664 --no-label "$msg_no" \ 1665 --yesno "$msg_text" $height $width 1666 fi 1667} 1668 1669############################################################ INPUT FUNCTIONS 1670 1671# f_dialog_inputstr_store [-s] $text 1672# 1673# Store some text from a dialog(1) inputbox to be retrieved later by 1674# f_dialog_inputstr_fetch(). If the first argument is `-s', the text is 1675# sanitized before being stored. 1676# 1677f_dialog_inputstr_store() 1678{ 1679 local sanitize= 1680 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s 1681 local text="$1" 1682 1683 # Sanitize the line before storing it if desired 1684 [ "$sanitize" ] && f_dialog_line_sanitize text 1685 1686 setvar DIALOG_INPUTBOX_$$ "$text" 1687} 1688 1689# f_dialog_inputstr_fetch [$var_to_set] 1690# 1691# Obtain the inputstr entered by the user from the most recently displayed 1692# dialog(1) inputbox (previously stored with f_dialog_inputstr_store() above). 1693# If $var_to_set is NULL or missing, output is printed to stdout (which is less 1694# recommended due to performance degradation; in a loop for example). 1695# 1696f_dialog_inputstr_fetch() 1697{ 1698 local __var_to_set="$1" __cp 1699 1700 debug= f_getvar DIALOG_INPUTBOX_$$ "${__var_to_set:-__cp}" # get data 1701 setvar DIALOG_INPUTBOX_$$ "" # scrub memory in case data was sensitive 1702 1703 # Return the line on standard-out if desired 1704 [ "$__var_to_set" ] || echo "$__cp" 1705 1706 return $SUCCESS 1707} 1708 1709# f_dialog_input $var_to_set $prompt [$init [$hline]] 1710# 1711# Prompt the user with a dialog(1) inputbox to enter some value. The inputbox 1712# remains until the the user presses ENTER or ESC, or otherwise ends the 1713# editing session (by selecting `Cancel' for example). 1714# 1715# If the user presses ENTER, the exit status is zero (success), otherwise if 1716# the user presses ESC the exit status is 255, or if the user chose Cancel, the 1717# exit status is instead 1. 1718# 1719# NOTE: The hline should correspond to the type of data you want from the user. 1720# NOTE: Should not be used to edit multiline values. 1721# 1722f_dialog_input() 1723{ 1724 local __var_to_set="$1" __prompt="$2" __init="$3" __hline="$4" 1725 1726 # NOTE: Function name appended to prevent __var_{height,width} values 1727 # from becoming local (and thus preventing setvar from working). 1728 local __height_input __width_input 1729 f_dialog_inputbox_size __height_input __width_input \ 1730 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" \ 1731 "$__prompt" "$__init" "$__hline" 1732 1733 local __opterm="--" 1734 [ "$USE_XDIALOG" ] && __opterm= 1735 1736 local __dialog_input 1737 __dialog_input=$( 1738 $DIALOG \ 1739 --title "$DIALOG_TITLE" \ 1740 --backtitle "$DIALOG_BACKTITLE" \ 1741 --hline "$__hline" \ 1742 --ok-label "$msg_ok" \ 1743 --cancel-label "$msg_cancel" \ 1744 --inputbox "$__prompt" \ 1745 $__height_input $__width_input \ 1746 $__opterm "$__init" \ 1747 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1748 ) 1749 local __retval=$? 1750 1751 # Remove warnings and leading/trailing whitespace from user input 1752 f_dialog_line_sanitize __dialog_input 1753 1754 setvar "$__var_to_set" "$__dialog_input" 1755 return $__retval 1756} 1757 1758############################################################ MENU FUNCTIONS 1759 1760# f_dialog_menutag_store [-s] $text 1761# 1762# Store some text from a dialog(1) menu to be retrieved later by 1763# f_dialog_menutag_fetch(). If the first argument is `-s', the text is 1764# sanitized before being stored. 1765# 1766f_dialog_menutag_store() 1767{ 1768 local sanitize= 1769 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s 1770 local text="$1" 1771 1772 # Sanitize the menutag before storing it if desired 1773 [ "$sanitize" ] && f_dialog_data_sanitize text 1774 1775 setvar DIALOG_MENU_$$ "$text" 1776} 1777 1778# f_dialog_menutag_fetch [$var_to_set] 1779# 1780# Obtain the menutag chosen by the user from the most recently displayed 1781# dialog(1) menu (previously stored with f_dialog_menutag_store() above). If 1782# $var_to_set is NULL or missing, output is printed to stdout (which is less 1783# recommended due to performance degradation; in a loop for example). 1784# 1785f_dialog_menutag_fetch() 1786{ 1787 local __var_to_set="$1" __cp 1788 1789 debug= f_getvar DIALOG_MENU_$$ "${__var_to_set:-__cp}" # get the data 1790 setvar DIALOG_MENU_$$ "" # scrub memory in case data was sensitive 1791 1792 # Return the data on standard-out if desired 1793 [ "$__var_to_set" ] || echo "$__cp" 1794 1795 return $SUCCESS 1796} 1797 1798# f_dialog_menuitem_store [-s] $text 1799# 1800# Store the item from a dialog(1) menu (see f_dialog_menutag2item()) to be 1801# retrieved later by f_dialog_menuitem_fetch(). If the first argument is `-s', 1802# the text is sanitized before being stored. 1803# 1804f_dialog_menuitem_store() 1805{ 1806 local sanitize= 1807 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s 1808 local text="$1" 1809 1810 # Sanitize the menuitem before storing it if desired 1811 [ "$sanitize" ] && f_dialog_data_sanitize text 1812 1813 setvar DIALOG_MENUITEM_$$ "$text" 1814} 1815 1816# f_dialog_menuitem_fetch [$var_to_set] 1817# 1818# Obtain the menuitem chosen by the user from the most recently displayed 1819# dialog(1) menu (previously stored with f_dialog_menuitem_store() above). If 1820# $var_to_set is NULL or missing, output is printed to stdout (which is less 1821# recommended due to performance degradation; in a loop for example). 1822# 1823f_dialog_menuitem_fetch() 1824{ 1825 local __var_to_set="$1" __cp 1826 1827 debug= f_getvar DIALOG_MENUITEM_$$ "${__var_to_set:-__cp}" # get data 1828 setvar DIALOG_MENUITEM_$$ "" # scrub memory in case data was sensitive 1829 1830 # Return the data on standard-out if desired 1831 [ "$__var_to_set" ] || echo "$__cp" 1832 1833 return $SUCCESS 1834} 1835 1836# f_dialog_default_store [-s] $text 1837# 1838# Store some text to be used later as the --default-item argument to dialog(1) 1839# (or Xdialog(1)) for --menu, --checklist, and --radiolist widgets. Retrieve 1840# the text later with f_dialog_menutag_fetch(). If the first argument is `-s', 1841# the text is sanitized before being stored. 1842# 1843f_dialog_default_store() 1844{ 1845 local sanitize= 1846 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s 1847 local text="$1" 1848 1849 # Sanitize the defaulitem before storing it if desired 1850 [ "$sanitize" ] && f_dialog_data_sanitize text 1851 1852 setvar DEFAULTITEM_$$ "$text" 1853} 1854 1855# f_dialog_default_fetch [$var_to_set] 1856# 1857# Obtain text to be used with the --default-item argument of dialog(1) (or 1858# Xdialog(1)) (previously stored with f_dialog_default_store() above). If 1859# $var_to_set is NULL or missing, output is printed to stdout (which is less 1860# recommended due to performance degradation; in a loop for example). 1861# 1862f_dialog_default_fetch() 1863{ 1864 local __var_to_set="$1" __cp 1865 1866 debug= f_getvar DEFAULTITEM_$$ "${__var_to_set:-__cp}" # get the data 1867 setvar DEFAULTITEM_$$ "" # scrub memory in case data was sensitive 1868 1869 # Return the data on standard-out if desired 1870 [ "$__var_to_set" ] || echo "$__cp" 1871 1872 return $SUCCESS 1873} 1874 1875# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ... 1876# 1877# To use the `--menu' option of dialog(1) you must pass an ordered list of 1878# tag/item pairs on the command-line. When the user selects a menu option the 1879# tag for that item is printed to stderr. 1880# 1881# This function allows you to dereference the tag chosen by the user back into 1882# the item associated with said tag. 1883# 1884# Pass the tag chosen by the user as the first argument, followed by the 1885# ordered list of tag/item pairs (HINT: use the same tag/item list as was 1886# passed to dialog(1) for consistency). 1887# 1888# If the tag cannot be found, NULL is returned. 1889# 1890f_dialog_menutag2item() 1891{ 1892 local tag="$1" tagn item 1893 shift 1 # tag 1894 1895 while [ $# -gt 0 ]; do 1896 tagn="$1" 1897 item="$2" 1898 shift 2 # tagn/item 1899 1900 if [ "$tag" = "$tagn" ]; then 1901 echo "$item" 1902 return $SUCCESS 1903 fi 1904 done 1905 return $FAILURE 1906} 1907 1908# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \ 1909# $tag2 $item2 $help2 ... 1910# 1911# To use the `--menu' option of dialog(1) with the `--item-help' option, you 1912# must pass an ordered list of tag/item/help triplets on the command-line. When 1913# the user selects a menu option the tag for that item is printed to stderr. 1914# 1915# This function allows you to dereference the tag chosen by the user back into 1916# the item associated with said tag (help is discarded/ignored). 1917# 1918# Pass the tag chosen by the user as the first argument, followed by the 1919# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list 1920# as was passed to dialog(1) for consistency). 1921# 1922# If the tag cannot be found, NULL is returned. 1923# 1924f_dialog_menutag2item_with_help() 1925{ 1926 local tag="$1" tagn item 1927 shift 1 # tag 1928 1929 while [ $# -gt 0 ]; do 1930 tagn="$1" 1931 item="$2" 1932 shift 3 # tagn/item/help 1933 1934 if [ "$tag" = "$tagn" ]; then 1935 echo "$item" 1936 return $SUCCESS 1937 fi 1938 done 1939 return $FAILURE 1940} 1941 1942# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ... 1943# 1944# To use the `--menu' option of dialog(1) you must pass an ordered list of 1945# tag/item pairs on the command-line. When the user selects a menu option the 1946# tag for that item is printed to stderr. 1947# 1948# This function allows you to dereference the tag chosen by the user back into 1949# the index associated with said tag. The index is the one-based tag/item pair 1950# array position within the ordered list of tag/item pairs passed to dialog(1). 1951# 1952# Pass the tag chosen by the user as the first argument, followed by the 1953# ordered list of tag/item pairs (HINT: use the same tag/item list as was 1954# passed to dialog(1) for consistency). 1955# 1956# If the tag cannot be found, NULL is returned. 1957# 1958f_dialog_menutag2index() 1959{ 1960 local tag="$1" tagn n=1 1961 shift 1 # tag 1962 1963 while [ $# -gt 0 ]; do 1964 tagn="$1" 1965 shift 2 # tagn/item 1966 1967 if [ "$tag" = "$tagn" ]; then 1968 echo $n 1969 return $SUCCESS 1970 fi 1971 n=$(( $n + 1 )) 1972 done 1973 return $FAILURE 1974} 1975 1976# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \ 1977# $tag2 $item2 $help2 ... 1978# 1979# To use the `--menu' option of dialog(1) with the `--item-help' option, you 1980# must pass an ordered list of tag/item/help triplets on the command-line. When 1981# the user selects a menu option the tag for that item is printed to stderr. 1982# 1983# This function allows you to dereference the tag chosen by the user back into 1984# the index associated with said tag. The index is the one-based tag/item/help 1985# triplet array position within the ordered list of tag/item/help triplets 1986# passed to dialog(1). 1987# 1988# Pass the tag chosen by the user as the first argument, followed by the 1989# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list 1990# as was passed to dialog(1) for consistency). 1991# 1992# If the tag cannot be found, NULL is returned. 1993# 1994f_dialog_menutag2index_with_help() 1995{ 1996 local tag="$1" tagn n=1 1997 shift 1 # tag 1998 1999 while [ $# -gt 0 ]; do 2000 tagn="$1" 2001 shift 3 # tagn/item/help 2002 2003 if [ "$tag" = "$tagn" ]; then 2004 echo $n 2005 return $SUCCESS 2006 fi 2007 n=$(( $n + 1 )) 2008 done 2009 return $FAILURE 2010} 2011 2012############################################################ INIT FUNCTIONS 2013 2014# f_dialog_init 2015# 2016# Initialize (or re-initialize) the dialog module after setting/changing any 2017# of the following environment variables: 2018# 2019# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 2020# that Xdialog(1) should be used instead of dialog(1). 2021# 2022# SECURE Either NULL or Non-NULL. If given a value will indicate 2023# that (while running as root) sudo(8) authentication is 2024# required to proceed. 2025# 2026# Also reads ~/.dialogrc for the following information: 2027# 2028# NO_SHADOW Either NULL or Non-NULL. If use_shadow is OFF (case- 2029# insensitive) in ~/.dialogrc this is set to "1" (otherwise 2030# unset). 2031# 2032f_dialog_init() 2033{ 2034 DIALOG_SELF_INITIALIZE= 2035 2036 # 2037 # Clone terminal stdout so we can redirect to it from within sub-shells 2038 # 2039 eval exec $DIALOG_TERMINAL_PASSTHRU_FD\>\&1 2040 2041 # 2042 # Add `-S' and `-X' to the list of standard arguments supported by all 2043 # 2044 case "$GETOPTS_STDARGS" in 2045 *SX*) : good ;; # already present 2046 *) GETOPTS_STDARGS="${GETOPTS_STDARGS}SX" 2047 esac 2048 2049 # 2050 # Process stored command-line arguments 2051 # 2052 f_dprintf "f_dialog_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \ 2053 "$ARGV" "$GETOPTS_STDARGS" 2054 SECURE=$( set -- $ARGV 2055 while getopts \ 2056 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \ 2057 flag > /dev/null; do 2058 case "$flag" in 2059 S) echo 1 ;; 2060 esac 2061 done 2062 ) 2063 USE_XDIALOG=$( set -- $ARGV 2064 while getopts \ 2065 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \ 2066 flag > /dev/null; do 2067 case "$flag" in 2068 S|X) echo 1 ;; 2069 esac 2070 done 2071 ) 2072 f_dprintf "f_dialog_init: SECURE=[%s] USE_XDIALOG=[%s]" \ 2073 "$SECURE" "$USE_XDIALOG" 2074 2075 # 2076 # Process `-X' command-line option 2077 # 2078 [ "$USE_XDIALOG" ] && DIALOG=Xdialog 2079 2080 # 2081 # Sanity check, or die gracefully 2082 # 2083 if ! f_have $DIALOG; then 2084 unset USE_XDIALOG 2085 local failed_dialog="$DIALOG" 2086 DIALOG=dialog 2087 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog" 2088 fi 2089 2090 # 2091 # Read ~/.dialogrc (unless using Xdialog(1)) for properties 2092 # 2093 if [ -f ~/.dialogrc -a ! "$USE_XDIALOG" ]; then 2094 eval "$( 2095 awk -v param=use_shadow -v expect=OFF \ 2096 -v set="NO_SHADOW=1" ' 2097 !/^[[:space:]]*(#|$)/ && \ 2098 tolower($1) ~ "^"param"(=|$)" && \ 2099 /[^#]*=/ { 2100 sub(/^[^=]*=[[:space:]]*/, "") 2101 if ( toupper($1) == expect ) print set";" 2102 }' ~/.dialogrc 2103 )" 2104 fi 2105 2106 # 2107 # If we're already running as root but we got there by way of sudo(8) 2108 # and we have X11, we should merge the xauth(1) credentials from our 2109 # original user. 2110 # 2111 if [ "$USE_XDIALOG" ] && 2112 [ "$( id -u )" = "0" ] && 2113 [ "$SUDO_USER" -a "$DISPLAY" ] 2114 then 2115 if ! f_have xauth; then 2116 # Die gracefully, as we [likely] can't use Xdialog(1) 2117 unset USE_XDIALOG 2118 DIALOG=dialog 2119 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth" 2120 fi 2121 HOSTNAME=$(hostname) 2122 local displaynum="${DISPLAY#*:}" 2123 eval xauth -if \~$SUDO_USER/.Xauthority extract - \ 2124 \"\$HOSTNAME/unix:\$displaynum\" \ 2125 \"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \ 2126 ~root/.Xauthority merge - > /dev/null 2>&1' 2127 fi 2128 2129 # 2130 # Probe Xdialog(1) for maximum height/width constraints, or die 2131 # gracefully 2132 # 2133 if [ "$USE_XDIALOG" ]; then 2134 local maxsize 2135 if ! maxsize=$( LANG= LC_ALL= $DIALOG --print-maxsize 2>&1 ) 2136 then 2137 # Xdialog(1) failed, fall back to dialog(1) 2138 unset USE_XDIALOG 2139 2140 # Display the error message produced by Xdialog(1) 2141 local height width 2142 f_dialog_buttonbox_size height width \ 2143 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$maxsize" 2144 dialog \ 2145 --title "$DIALOG_TITLE" \ 2146 --backtitle "$DIALOG_BACKTITLE" \ 2147 --ok-label "$msg_ok" \ 2148 --msgbox "$maxsize" $height $width 2149 exit $FAILURE 2150 fi 2151 2152 XDIALOG_MAXSIZE=$( 2153 set -- ${maxsize##*:} 2154 2155 height=${1%,} 2156 width=$2 2157 2158 echo $height $width 2159 ) 2160 fi 2161 2162 # 2163 # If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE. 2164 # The reason for this is because many dialog(1) applications use 2165 # --backtitle for the program name (which is better suited as 2166 # --title with Xdialog(1)). 2167 # 2168 if [ "$USE_XDIALOG" ]; then 2169 local _DIALOG_TITLE="$DIALOG_TITLE" 2170 DIALOG_TITLE="$DIALOG_BACKTITLE" 2171 DIALOG_BACKTITLE="$_DIALOG_TITLE" 2172 fi 2173 2174 f_dprintf "f_dialog_init: dialog(1) API initialized." 2175} 2176 2177############################################################ MAIN 2178 2179# 2180# Self-initialize unless requested otherwise 2181# 2182f_dprintf "%s: DIALOG_SELF_INITIALIZE=[%s]" \ 2183 dialog.subr "$DIALOG_SELF_INITIALIZE" 2184case "$DIALOG_SELF_INITIALIZE" in 2185""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;; 2186*) f_dialog_init 2187esac 2188 2189f_dprintf "%s: Successfully loaded." dialog.subr 2190 2191fi # ! $_DIALOG_SUBR 2192