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