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