summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsdconfig/share/device.subr
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2013-02-25 19:55:32 +0000
committerdteske <dteske@FreeBSD.org>2013-02-25 19:55:32 +0000
commit1f658c88bed0f72839a6caee6fdc9731cfd3a516 (patch)
treecd0ba840ab0526258652c2740f9e0c046edb8374 /usr.sbin/bsdconfig/share/device.subr
parent66bd226a8bcd9c32e76c9a7c414af10c393e50d8 (diff)
downloadFreeBSD-src-1f658c88bed0f72839a6caee6fdc9731cfd3a516.zip
FreeBSD-src-1f658c88bed0f72839a6caee6fdc9731cfd3a516.tar.gz
Import media selection/preparation framework (sysinstall inspired). Makes
accessing files from various types of media nice and abstracted away from the wet-work involved in preparing, validating, and initializing those types of media. This will be used for the package management system module and other modules that need access to files and want to allow the user to decide where those files come from (either in a scripted fashion, prompted fashion, or any combination thereof). Heavily inspired by sysinstall and even uses the same reserved words so that scripts are portable. Coded over months, tested continuously through- out, and reviewed several times. Some notes about the changes: - Move network-setting acquisition/validation routines to media/tcpip.subr - The options screen from sysinstall has been converted to a dialog menu - The "UFS" media choice is renamed to "Directory" to reflect how sysinstall treats the choice and a new [true] "UFS" media choice has been added that acts on real UFS partitions (such as external disks with disklabels). - Many more help files have been resurrected from sysinstall (I noticed that some of the content seems a bit dated; I gave them a once-over but they could really use an update). - A total of 10 media choices are presented (via mediaGetType) including: CD/DVD, FTP, FTP Passive, HTTP Proxy, Directory, NFS, DOS, UFS, Floppy, USB - Novel struct/device management layer for managing the issue of passing more information than can comfortably fit in an argument list.
Diffstat (limited to 'usr.sbin/bsdconfig/share/device.subr')
-rw-r--r--usr.sbin/bsdconfig/share/device.subr799
1 files changed, 799 insertions, 0 deletions
diff --git a/usr.sbin/bsdconfig/share/device.subr b/usr.sbin/bsdconfig/share/device.subr
new file mode 100644
index 0000000..473838b
--- /dev/null
+++ b/usr.sbin/bsdconfig/share/device.subr
@@ -0,0 +1,799 @@
+if [ ! "$_DEVICE_SUBR" ]; then _DEVICE_SUBR=1
+#
+# Copyright (c) 2012-2013 Devin Teske
+# All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." device.subr
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/strings.subr
+f_include $BSDCFG_SHARE/struct.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig"
+f_include_lang $BSDCFG_LIBE/include/messages.subr
+
+############################################################ GLOBALS
+
+DEVICES=
+DEVICE_NAMES=
+
+# A "device" from sysinstall's point of view
+f_struct_define DEVICE \
+ name \
+ desc \
+ devname \
+ type \
+ enabled \
+ init \
+ get \
+ shutdown \
+ flags \
+ private \
+ volume
+
+# Network devices have their `private' property set to this
+f_struct_define DEVICE_INFO \
+ use_rtsol use_dhcp ipaddr ipv6addr netmask extras
+
+setvar DEVICE_TYPE_NONE 1
+setvar DEVICE_TYPE_DISK 2
+setvar DEVICE_TYPE_FLOPPY 3
+setvar DEVICE_TYPE_FTP 4
+setvar DEVICE_TYPE_NETWORK 5
+setvar DEVICE_TYPE_CDROM 6
+setvar DEVICE_TYPE_USB 7
+setvar DEVICE_TYPE_DOS 8
+setvar DEVICE_TYPE_UFS 9
+setvar DEVICE_TYPE_NFS 10
+setvar DEVICE_TYPE_ANY 11
+setvar DEVICE_TYPE_HTTP_PROXY 12
+
+#
+# Default behavior is to call f_device_get_all() automatically when loaded.
+#
+: ${DEVICE_SELF_SCAN_ALL=1}
+
+############################################################ FUNCTIONS
+
+# f_device_try $name [$i [$var_path]]
+#
+# Test a particular device. If $i is given, then $name is expected to contain a
+# single "%d" where $i will be inserted using printf. If $var_path is given,
+# it is used as a variable name to provide the caller the device pathname.
+#
+# Returns success if the device path exists and is a cdev.
+#
+f_device_try()
+{
+ local name="$1" i="$2" var_path="$3" unit
+ if [ "$i" ]; then
+ unit=$( printf "$name" "$i" )
+ else
+ unit="$name"
+ fi
+ case "$unit" in
+ /dev/*) : good ;; # already qualified
+ *) unit="/dev/$unit" ;;
+ esac
+ [ "$var_path" ] && setvar "$var_path" "$unit"
+ f_dprintf "f_device_try: making sure %s is a device node" "$unit"
+ if [ -c "$unit" ]; then
+ f_dprintf "f_device_try: %s is a cdev [good]" "$unit"
+ return $SUCCESS
+ else
+ f_dprintf "f_device_try: %s is not a cdev [skip]" "$unit"
+ return $FAILURE
+ fi
+}
+
+# f_device_register $name $desc $devname $type $enabled $init_function \
+# $get_function $shutdown_function $private
+#
+# Register a device. A `structure' (see struct.subr) is created with the name
+# device_$name (so make sure $name contains only alpha-numeric characters or
+# the underscore, `_'). The remaining arguments after $name correspond to the
+# properties of the `DEVICE' structure-type (defined above).
+#
+# If not already registered, the device is then appended to the DEVICES
+# environment variable, a space-separated list of all registered devices.
+#
+f_device_register()
+{
+ local name="$1" desc="$2" devname="$3" type="$4" enabled="$5"
+ local init_func="$6" get_func="$7" shutdown_func="$8" private="$9"
+
+ f_struct_new DEVICE "device_$name" || return $FAILURE
+ device_$name set name "$name"
+ device_$name set desc "$desc"
+ device_$name set devname "$devname"
+ device_$name set type "$type"
+ device_$name set enabled "$enabled"
+ device_$name set init "$init_func"
+ device_$name set get "$get_func"
+ device_$name set shutdown "$shutdown_func"
+ device_$name set private "$private"
+
+ # Scan our global register to see if it needs ammending
+ local dev found=
+ for dev in $DEVICES; do
+ [ "$dev" = "$name" ] || continue
+ found=1 && break
+ done
+ [ "$found" ] || DEVICES="$DEVICES $name"
+
+ return $SUCCESS
+}
+
+# f_device_reset
+#
+# Reset the registered device chain.
+#
+f_device_reset()
+{
+ local dev
+ for dev in $DEVICES; do
+ f_device_shutdown $dev
+
+ #
+ # XXX this potentially leaks $dev->private if it's being
+ # used to point to something dynamic, but you're not supposed
+ # to call this routine at such times that some open instance
+ # has its private member pointing somewhere anyway. XXX
+ #
+ f_struct_free device_$dev
+ done
+ DEVICES=
+}
+
+# f_device_get_all
+#
+# Get all device information for devices we have attached.
+#
+f_device_get_all()
+{
+ local devname desc
+
+ f_dprintf "f_device_get_all: Probing devices..."
+ f_dialog_info "$msg_probing_devices_please_wait_this_can_take_a_while"
+
+ # First go for the network interfaces
+ for devname in $( ifconfig -l ); do
+ # Eliminate network devices that don't make sense
+ case "$devname" in
+ lo*) continue ;;
+ esac
+
+ # Try and find its description
+ f_device_desc "$devname" $DEVICE_TYPE_NETWORK desc
+
+ f_dprintf "Found a network device named %s" "$devname"
+ f_device_register $devname \
+ "$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
+ f_media_init_network "" f_media_shutdown_network ""
+ done
+
+ # Next, try to find all the types of devices one might use
+ # as a media source for content
+ #
+
+ local dev desc type max n=0
+ for dev in $DEVICE_NAMES; do
+ n=$(( $n + 1 ))
+ # Get the desc, type, and max (with debugging disabled)
+ # NOTE: Bypassing f_device_name_get() for efficiency
+ debug= f_getvar _device_desc$n desc
+ debug= f_getvar _device_type$n type
+ debug= f_getvar _device_max$n max
+
+ local k=0
+ while [ $k -lt ${max:-0} ]; do
+ i=$k k=$(( $k + 1 ))
+ devname=""
+ case "$type" in
+ $DEVICE_TYPE_CDROM)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" \
+ "$devname"
+ ;;
+ $DEVICE_TYPE_FLOPPY)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_FLOPPY 1 \
+ f_media_init_floppy \
+ f_media_get_floppy \
+ f_media_shutdown_floppy ""
+ f_dprintf "Found a floppy device for %s" \
+ "$devname"
+ ;;
+ $DEVICE_TYPE_USB)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_USB 1 \
+ f_media_init_usb f_media_get_usb \
+ f_media_shutdown_usb ""
+ f_dprintf "Found a USB disk for %s" "$devname"
+ ;;
+ esac
+ done
+ done
+
+ # Register ISO9660 providers as CDROM devices
+ for devname in /dev/iso9660/*; do
+ f_device_try "$devname" || continue
+ f_device_register "${devname##*/}" "ISO9660 file system" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" "$devname"
+ done
+
+ # Scan for mdconfig(8)-created md(4) devices
+ local filename
+ for devname in /dev/md[0-9] /dev/md[0-9][0-9]; do
+ f_device_try "$devname" || continue
+
+ # See if the md(4) device is a vnode type backed by a file
+ filename=$( sysctl kern.geom.conftxt |
+ awk -v devname="${devname##*/}" \
+ '
+ ( $2 == "MD" ) && \
+ ( $3 == devname ) && \
+ ( $(NF-2) == "vnode" ) && \
+ ( $(NF-1) == "file" ) \
+ {
+ print $NF
+ }
+ ' )
+ case "$filename" in
+ *.iso) # Register the device as an ISO9660 provider
+ f_device_register "${devname##*/}" \
+ "md(4) vnode file system" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" "$devname"
+ ;;
+ esac
+ done
+
+ # Finally go get the disks and look for partitions to register
+ local diskname slices index type rest slice part
+ for diskname in $( sysctl -n kern.disks ); do
+
+ case "$diskname" in
+ cd*)
+ # XXX
+ # Due to unknown reasons, kern.disks returns SCSI
+ # CDROM as a valid disk. This will prevent bsdconfig
+ # from presenting SCSI CDROMs as available disks in
+ # various menus. Why GEOM treats SCSI CDROM as a disk
+ # is beyond me and that should be investigated.
+ # For temporary workaround, ignore SCSI CDROM device.
+ #
+ continue ;;
+ esac
+
+ # Try to create a list of partitions and their types,
+ # consisting of "N,typeN ..." (e.g., "1,0xa5 2,0x06").
+ if ! slices=$( fdisk -p "$diskname" 2> /dev/null |
+ awk '( $1 == "p" ) { print $2","$3 }' )
+ then
+ f_dprintf "Unable to open disk %s" "$diskname"
+ continue
+ fi
+
+ f_device_register "$diskname" "" \
+ "/dev/$diskname" $DEVICE_TYPE_DISK 0
+ f_dprintf "Found a disk device named %s" "$diskname"
+
+ # Look for existing partitions to register
+ for slice in $slices; do
+ index="${slice%%,*}" type="${slice#*,}"
+ slice=${diskname}s$index
+ case "$type" in
+ 0x01|0x04|0x06|0x0b|0x0c|0x0e|0xef)
+ # DOS partitions to add as "DOS media devices"
+ f_device_register "$slice" "" \
+ "/dev/$slice" $DEVICE_TYPE_DOS 1 \
+ f_media_init_dos f_media_get_dos \
+ f_media_shutdown_dos ""
+ f_dprintf "Found a DOS partition %s" "$slice"
+ ;;
+ 0xa5) # FreeBSD partition
+ for part in $(
+ bsdlabel -r $slice 2> /dev/null |
+ awk -v slice="$slice" '
+ ( $1 ~ /[abdefgh]:/ ) {
+ printf "%s%s\n",
+ slice,
+ substr($1,1,1)
+ }'
+ ); do
+ f_quietly dumpfs -m /dev/$part ||
+ continue
+ f_device_register \
+ "$part" "" "/dev/$part" \
+ $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs \
+ f_media_get_ufs \
+ f_media_shutdown_ufs ""
+ f_dprintf "Found a UFS partition %s" \
+ "$part"
+ done # parts
+ ;;
+ esac
+ done # slices
+
+ done # disks
+}
+
+# f_device_name_get $type $name type|desc|max [$var_to_set]
+#
+# Fetch the device type (type), description (desc), or maximum number of
+# devices to scan for (max) associated with device $name and $type. If $type is
+# either NULL, missing, or set to $DEVICE_TYPE_ANY then only $name is used.
+# Returns success if a match was found, otherwise failure.
+#
+# If $var_to_set is missing or NULL, the device name is printed to standard out
+# for capturing in a sub-shell (which is less-recommended because of
+# performance degredation; for example, when called in a loop).
+#
+f_device_name_get()
+{
+ local __type="$1" __name="$2" __prop="$3" __var_to_set="$4"
+ local __dev __devtype __n=0
+
+ # Return failure if no $name or $prop is an unknown property
+ [ "$__name" ] || return $FAILURE
+ case "$__prop" in type|desc|max) : good ;;
+ *) return $FAILURE; esac
+
+ [ "$__type" = "$DEVICE_TYPE_ANY" ] && __type=
+ for __dev in $DEVICE_NAMES; do
+ __n=$(( $__n + 1 ))
+ [ "$__dev" = "$__name" ] || continue
+ f_getvar _device_type$__n __devtype
+ [ "${__type:-$__devtype}" = "$__devtype" ] || continue
+ f_getvar _device_$__prop$__n $__var_to_set
+ return $?
+ done
+ return $FAILURE
+}
+
+# f_device_name_set $type $name $desc [$max]
+#
+# Store a description (desc) and [optionally] maximum number of devices to scan
+# for (max) in-association with device $type and $name. Returns success. Use
+# the f_device_name_get() routine with the same $name and [optionally] $type to
+# retrieve one of type, desc, or max properties.
+#
+f_device_name_set()
+{
+ local type="$1" name="$2" desc="$3" max="$4"
+ local dev devtype n=0 found=
+ [ "$name" ] || return $FAILURE
+ for dev in $DEVICE_NAMES; do
+ n=$(( $n + 1 ))
+ [ "$dev" = "$name" ] || continue
+ if f_getvar _device_type$n devtype; then
+ # Allow multiple entries with same name but diff type
+ [ "$devtype" = "$type" ] || continue
+ fi
+ found=1 && break
+ done
+ if [ ! "$found" ]; then
+ DEVICE_NAMES="$DEVICE_NAMES $name"
+ n=$(( $n + 1 ))
+ fi
+ setvar _device_type$n "$type"
+ setvar _device_desc$n "$desc"
+ [ "${4+set}" ] && setvar _device_max$n "$max"
+ return $SUCCESS
+}
+
+# f_device_desc $device_name $device_type [$var_to_set]
+#
+# Print a description for a device name (eg., `fxp0') given a specific device
+# type/class.
+#
+# If $var_to_set is missing or NULL, the device description is printed to
+# standard out for capturing in a sub-shell (which is less-recommended because
+# of performance degredation; for example, when called in a loop).
+#
+f_device_desc()
+{
+ local __name="$1" __type="$2" __var_to_set="$3"
+ local __devname __devunit __cp
+
+ # Check variables
+ [ "$__name" ] || return $SUCCESS
+ [ "$__type" = "$DEVICE_TYPE_ANY" ] && type=
+ [ "$__var_to_set" ] && { setvar "$__var_to_set" "" || return; }
+
+ #
+ # Return sysctl MIB dev.NAME.UNIT.%desc if it exists,
+ # otherwise fall through to below static list.
+ #
+ if f_have sysctl; then
+ __devname="${__name%%[0-9]*}"
+ __devunit="${__name#$__devname}"
+ __devunit="${__devunit%%[!0-9]*}"
+ if [ "$__var_to_set" ]; then
+ if __cp=$(
+ sysctl -n "dev.$__devname.$__devunit.%desc" \
+ 2> /dev/null
+ ); then
+ setvar "$__var_to_set" "$__cp" &&
+ return $SUCCESS
+ fi
+ else
+ sysctl -n "dev.$__devname.$__devunit.%desc" \
+ 2> /dev/null && return $SUCCESS
+ fi
+ fi
+
+ local __dev __devtype __n=0
+ for __dev in $DEVICE_NAMES; do
+ __n=$(( $__n + 1 ))
+ debug= f_getvar _device_type$__n __devtype
+ [ "${__type:-$__devtype}" = "$__devtype" ] || continue
+ if [ "$__devtype" = "$DEVICE_TYPE_NETWORK" ]; then
+ __devname=$( f_substr "$__name" 0 ${#__dev} )
+ [ "$__devname" = "$__dev" ] || continue
+ else
+ __devname="${__name%%[0-9]*}"
+ __devunit="${__name#$__devname}"
+ __devunit="${__devunit%%[!0-9]*}"
+ __devname=$( printf "$__dev" $__devunit )
+ [ "$__devname" = "$__name" ] || continue
+ fi
+ debug= f_getvar _device_desc$__n $__var_to_set
+ return $?
+ done
+
+ #
+ # Sensible fall-backs for specific types
+ #
+ case "$__type" in
+ $DEVICE_TYPE_CDROM) __cp="<unknown cdrom device type>";;
+ $DEVICE_TYPE_DISK) __cp="<unknown disk device type>";;
+ $DEVICE_TYPE_FLOPPY) __cp="<unknown floppy device type>";;
+ $DEVICE_TYPE_USB) __cp="<unknown usb storage device type>";;
+ $DEVICE_TYPE_NETWORK) __cp="<unknown network interface type>";;
+ *)
+ __cp="<unknown device type>"
+ esac
+
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "$__cp"
+ else
+ echo "$__cp"
+ fi
+
+ return $FAILURE
+}
+
+# f_device_rescan
+#
+# Rescan all devices, after closing previous set - convenience function.
+#
+f_device_rescan()
+{
+ f_device_reset
+ f_device_get_all
+}
+
+# f_device_find $name [$type [$var_to_set]]
+#
+# Find one or more registered devices by name, type, or both. Returns a space-
+# separated list of devices matching the search criterion.
+#
+# If $var_to_set is missing or NULL, the device name(s) are printed to standard
+# out for capturing in a sub-shell (which is less-recommended because of
+# performance degredation; for example, when called in a loop).
+#
+f_device_find()
+{
+ local __name="$1" __type="${2:-$DEVICE_TYPE_ANY}" __var_to_set="$3"
+ local __dev __devname __devtype __found=
+ for __dev in $DEVICES; do
+ device_$__dev get name __devname
+ device_$__dev get type __devtype
+ if [ "$__name" = "$__devname" -o ! "$__name" ] &&
+ [ "$__type" = "$DEVICE_TYPE_ANY" -o \
+ "$__type" = "$__devtype" ]
+ then
+ __found="$__found $__dev"
+ fi
+ done
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "${__found# }"
+ else
+ echo $__found
+ fi
+ [ "$__found" ] # Return status
+}
+
+# f_device_init $name
+#
+# Initialize a device by evaluating its `init' function.
+#
+f_device_init()
+{
+ local name="$1" init_func
+ device_$name get init init_func || return
+ ${init_func:-:} $name
+}
+
+# f_device_get $name $file [$probe]
+#
+# Read $file by evaluating the device's `get' function. The file is commonly
+# produced on standard output (but it truly depends on the function called).
+#
+f_device_get()
+{
+ local name="$1" file="$2" probe="$3" get_func
+ device_$name get get get_func || return
+ ${get_func:-:} $name "$file" ${3+"$probe"}
+}
+
+# f_device_shutdown $name
+#
+# Shutdown a device by evaluating its `shutdown' function.
+#
+f_device_shutdown()
+{
+ local name="$1" shutdown_func
+ device_$name get shutdown shutdown_func || return
+ ${shutdown_func:-:} $name
+}
+
+# f_device_menu $title $prompt $hline $device_type [$helpfile]
+#
+# Display a menu listing all the devices of a certain type in the system.
+#
+f_device_menu()
+{
+ f_dialog_title "$1"
+ local title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
+ f_dialog_title_restore
+
+ local prompt="$2" hline="$3" type="$4" helpfile="$5"
+
+ local dev devtype devs=
+ for dev in $DEVICES; do
+ device_$dev get type devtype || continue
+ [ "$devtype" = "$type" ] || continue
+ devs="$devs $dev"
+ done
+ [ "$devs" ] || return $FAILURE
+
+ local sanitize_awk="{ gsub(/'/, \"'\\\\''\"); print }"
+
+ local desc menu_list=
+ for dev in $devs; do
+ device_$dev get desc desc
+ desc=$( echo "$desc" | awk "$sanitize_awk" )
+ menu_list="$menu_list '$dev' '$desc'"
+ done
+
+ local size mtag
+ size=$( eval f_dialog_menu_size \
+ \"\$title\" \
+ \"\$btitle\" \
+ \"\$prompt\" \
+ \"\$hline\" \
+ $menu_list )
+
+ local errexit=
+ case $- in *e*) errexit=1; esac
+ set +e
+
+ while :; do
+ mtag=$( eval $DIALOG \
+ --title \"\$title\" \
+ --backtitle \"\$btitle\" \
+ --ok-label \"\$msg_ok\" \
+ --cancel-label \"\$msg_cancel\" \
+ ${helpfile:+ \
+ --help-button \
+ --help-label \"\$msg_help\" \
+ ${USE_XDIALOG:+--help \"\"} \
+ } \
+ --menu \"\$prompt\" $size \
+ $menu_list \
+ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+ )
+ local retval=$?
+
+ [ $retval -ne 2 ] && break
+ # Otherwise, the Help button was pressed
+ f_show_help "$helpfile"
+ # Loop back to menu
+ done
+ f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
+
+ [ "$errexit" ] && set -e
+
+ [ $retval -eq 0 ] && echo "$mtag" >&2
+
+ return $retval
+}
+
+#
+# Short-hand
+#
+f_cdrom() { f_device_name_set $DEVICE_TYPE_CDROM "$1" "$2" "$3"; }
+f_disk() { f_device_name_set $DEVICE_TYPE_DISK "$1" "$2" "$3"; }
+f_floppy() { f_device_name_set $DEVICE_TYPE_FLOPPY "$1" "$2" "$3"; }
+f_serial() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2" "$3"; }
+f_usb() { f_device_name_set $DEVICE_TYPE_USB "$1" "$2" "$3"; }
+f_network() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2"; }
+
+############################################################ MAIN
+
+# CDROM, Disk, Floppy, Serial, and USB devices/names
+f_cdrom "acd%d" "ATAPI/IDE CDROM" 4
+f_cdrom "cd%d" "SCSI CDROM drive" 4
+f_cdrom "mcd%d" "Mitsumi (old model) CDROM drive" 4
+f_cdrom "scd%d" "Sony CDROM drive - CDU31/33A type" 4
+f_disk "aacd%d" "Adaptec FSA RAID array" 4
+f_disk "ad%d" "ATA/IDE disk device" 16
+f_disk "ada%d" "SATA disk device" 16
+f_disk "afd%d" "ATAPI/IDE floppy device" 4
+f_disk "amrd%d" "AMI MegaRAID drive" 4
+f_disk "ar%d" "ATA/IDE RAID device" 16
+f_disk "da%d" "SCSI disk device" 16
+f_disk "idad%d" "Compaq RAID array" 4
+f_disk "ipsd%d" "IBM ServeRAID RAID array" 4
+f_disk "mfid%d" "LSI MegaRAID SAS array" 4
+f_disk "mlxd%d" "Mylex RAID disk" 4
+f_disk "twed%d" "3ware ATA RAID array" 4
+f_floppy "fd%d" "Floppy Drive unit A" 4
+f_serial "cuau%d" "%s on device %s (COM%d)" 16
+f_usb "da%da" "USB Mass Storage Device" 16
+
+# Network interfaces/names
+f_network "ae" "Attansic/Atheros L2 Fast Ethernet"
+f_network "age" "Attansic/Atheros L1 Gigabit Ethernet"
+f_network "alc" "Atheros AR8131/AR8132 PCIe Ethernet"
+f_network "ale" "Atheros AR8121/AR8113/AR8114 PCIe Ethernet"
+f_network "an" "Aironet 4500/4800 802.11 wireless adapter"
+f_network "ath" "Atheros IEEE 802.11 wireless adapter"
+f_network "aue" "ADMtek USB Ethernet adapter"
+f_network "axe" "ASIX Electronics USB Ethernet adapter"
+f_network "bce" "Broadcom NetXtreme II Gigabit Ethernet card"
+f_network "bfe" "Broadcom BCM440x PCI Ethernet card"
+f_network "bge" "Broadcom BCM570x PCI Gigabit Ethernet card"
+f_network "bm" "Apple BMAC Built-in Ethernet"
+f_network "bwn" "Broadcom BCM43xx IEEE 802.11 wireless adapter"
+f_network "cas" "Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"
+f_network "cc3i" "SDL HSSI sync serial PCI card"
+f_network "cue" "CATC USB Ethernet adapter"
+f_network "cxgb" "Chelsio T3 10Gb Ethernet card"
+f_network "dc" "DEC/Intel 21143 (and clones) PCI Fast Ethernet card"
+f_network "de" "DEC DE435 PCI NIC or other DC21040-AA based card"
+f_network "disc" "Software discard network interface"
+f_network "ed" "Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA"
+f_network "el" "3Com 3C501 Ethernet card"
+f_network "em" "Intel(R) PRO/1000 Ethernet card"
+f_network "en" "Efficient Networks ATM PCI card"
+f_network "ep" "3Com 3C509 Ethernet card/3C589 PCMCIA"
+f_network "et" "Agere ET1310 based PCI Express Gigabit Ethernet card"
+f_network "ex" "Intel EtherExpress Pro/10 Ethernet card"
+f_network "fe" "Fujitsu MB86960A/MB86965A Ethernet card"
+f_network "fpa" "DEC DEFPA PCI FDDI card"
+f_network "fwe" "FireWire Ethernet emulation"
+f_network "fwip" "IP over FireWire"
+f_network "fxp" "Intel EtherExpress Pro/100B PCI Fast Ethernet card"
+f_network "gem" "Apple GMAC or Sun ERI/GEM Ethernet adapter"
+f_network "hme" "Sun HME (Happy Meal Ethernet) Ethernet adapter"
+f_network "ie" "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210"
+f_network "igb" "Intel(R) PRO/1000 PCI Express Gigabit Ethernet card"
+f_network "ipw" "Intel PRO/Wireless 2100 IEEE 802.11 adapter"
+f_network "iwi" "Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter"
+f_network "iwn" "Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter"
+f_network "ixgbe" "Intel(R) PRO/10Gb Ethernet card"
+f_network "ixgb" "Intel(R) PRO/10Gb Ethernet card"
+f_network "ix" "Intel Etherexpress Ethernet card"
+ # Maintain sequential order of above(3): ixgbe ixgb ix
+f_network "jme" "JMicron JMC250 Gigabit/JMC260 Fast Ethernet"
+f_network "kue" "Kawasaki LSI USB Ethernet adapter"
+f_network "le" "AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter"
+f_network "lge" "Level 1 LXT1001 Gigabit Ethernet card"
+f_network "lnc" "Lance/PCnet (Isolan/Novell NE2100/NE32-VL) Ethernet"
+f_network "lo" "Loop-back (local) network interface"
+f_network "lp" "Parallel Port IP (PLIP) peer connection"
+f_network "malo" "Marvell Libertas 88W8335 802.11 wireless adapter"
+f_network "msk" "Marvell/SysKonnect Yukon II Gigabit Ethernet"
+f_network "mxge" "Myricom Myri10GE 10Gb Ethernet card"
+f_network "nfe" "NVIDIA nForce MCP Ethernet"
+f_network "nge" "NatSemi PCI Gigabit Ethernet card"
+f_network "ng" "Vimage netgraph(4) bridged Ethernet device"
+ # Maintain sequential order of above(2): nge ng
+f_network "nve" "NVIDIA nForce MCP Ethernet"
+f_network "nxge" "Neterion Xframe 10GbE Server/Storage adapter"
+f_network "pcn" "AMD Am79c79x PCI Ethernet card"
+f_network "plip" "Parallel Port IP (PLIP) peer connection"
+f_network "ral" "Ralink Technology IEEE 802.11 wireless adapter"
+f_network "ray" "Raytheon Raylink 802.11 wireless adapter"
+f_network "re" "RealTek 8139C+/8169/8169S/8110S PCI Ethernet adapter"
+f_network "rl" "RealTek 8129/8139 PCI Ethernet card"
+f_network "rue" "RealTek USB Ethernet card"
+f_network "rum" "Ralink Technology USB IEEE 802.11 wireless adapter"
+f_network "sf" "Adaptec AIC-6915 PCI Ethernet card"
+f_network "sge" "Silicon Integrated Systems SiS190/191 Ethernet"
+f_network "sis" "SiS 900/SiS 7016 PCI Ethernet card"
+f_network "sk" "SysKonnect PCI Gigabit Ethernet card"
+f_network "snc" "SONIC Ethernet card"
+f_network "sn" "SMC/Megahertz Ethernet card"
+ # Maintain sequential order of above(2): snc sn
+f_network "sr" "SDL T1/E1 sync serial PCI card"
+f_network "ste" "Sundance ST201 PCI Ethernet card"
+f_network "stge" "Sundance/Tamarack TC9021 Gigabit Ethernet"
+f_network "ti" "Alteon Networks PCI Gigabit Ethernet card"
+f_network "tl" "Texas Instruments ThunderLAN PCI Ethernet card"
+f_network "txp" "3Com 3cR990 Ethernet card"
+f_network "tx" "SMC 9432TX Ethernet card"
+ # Maintain sequential order of above(2): txp tx
+f_network "uath" "Atheros AR5005UG and AR5005UX USB wireless adapter"
+f_network "upgt" "Conexant/Intersil PrismGT USB wireless adapter"
+f_network "ural" "Ralink Technology RT2500USB 802.11 wireless adapter"
+f_network "urtw" "Realtek 8187L USB wireless adapter"
+f_network "vge" "VIA VT612x PCI Gigabit Ethernet card"
+f_network "vlan" "IEEE 802.1Q VLAN network interface"
+f_network "vr" "VIA VT3043/VT86C100A Rhine PCI Ethernet card"
+f_network "vx" "3COM 3c590 / 3c595 Ethernet card"
+f_network "wb" "Winbond W89C840F PCI Ethernet card"
+f_network "wi" "Lucent WaveLAN/IEEE 802.11 wireless adapter"
+f_network "wpi" "Intel 3945ABG IEEE 802.11 wireless adapter"
+f_network "wx" "Intel Gigabit Ethernet (82452) card"
+f_network "xe" "Xircom/Intel EtherExpress Pro100/16 Ethernet card"
+f_network "xl" "3COM 3c90x / 3c90xB PCI Ethernet card"
+f_network "zyd" "ZyDAS ZD1211/ZD1211B USB 802.11 wireless adapter"
+
+f_dprintf "%s: Initialized %u known device names/descriptions." device.subr \
+ "$( set -- $DEVICE_NAMES; echo $# )"
+
+#
+# Scan for the above devices unless requeted otherwise
+#
+f_dprintf "%s: DEVICE_SELF_SCAN_ALL=[%s]" device.subr "$DEVICE_SELF_SCAN_ALL"
+case "$DEVICE_SELF_SCAN_ALL" in
+""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
+*) f_device_get_all
+esac
+
+f_dprintf "%s: Successfully loaded." device.subr
+
+fi # ! $_DEVICE_SUBR
OpenPOWER on IntegriCloud