freebsd-nq/usr.sbin/bsdconfig/share/media/tcpip.subr

1686 lines
47 KiB
Plaintext
Raw Normal View History

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.
2013-02-25 19:55:32 +00:00
if [ ! "$_MEDIA_TCPIP_SUBR" ]; then _MEDIA_TCPIP_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..." media/tcpip.subr
f_include $BSDCFG_SHARE/struct.subr
f_include $BSDCFG_SHARE/device.subr
f_include $BSDCFG_SHARE/dialog.subr
f_include $BSDCFG_SHARE/variable.subr
BSDCFG_LIBE="/usr/libexec/bsdconfig"
f_include_lang $BSDCFG_LIBE/include/messages.subr
TCP_HELPFILE=$BSDCFG_LIBE/include/tcp.hlp
NETWORK_DEVICE_HELPFILE=$BSDCFG_LIBE/include/network_device.hlp
############################################################ GLOBALS
#
# Path to resolv.conf(5).
#
: ${RESOLV_CONF:="/etc/resolv.conf"}
#
# Path to nsswitch.conf(5).
#
: ${NSSWITCH_CONF:="/etc/nsswitch.conf"}
#
# Path to hosts(5)
#
: ${ETC_HOSTS:="/etc/hosts"}
#
# Structure of dhclient.leases(5) lease { ... } entry
#
f_struct_define DHCP_LEASE \
interface \
fixed_address \
filename \
server_name \
script \
medium \
host_name \
subnet_mask \
routers \
domain_name_servers \
domain_name \
broadcast_address \
dhcp_lease_time \
dhcp_message_type \
dhcp_server_identifier \
dhcp_renewal_time \
dhcp_rebinding_time \
renew \
rebind \
expire
############################################################ FUNCTIONS
# f_validate_hostname $hostname
#
# Returns zero if the given argument (a fully-qualified hostname) is compliant
# with standards set-forth in RFC's 952 and 1123 of the Network Working Group:
#
# RFC 952 - DoD Internet host table specification
# http://tools.ietf.org/html/rfc952
#
# RFC 1123 - Requirements for Internet Hosts - Application and Support
# http://tools.ietf.org/html/rfc1123
#
# See http://en.wikipedia.org/wiki/Hostname for a brief overview.
#
# The return status for invalid hostnames is one of:
# 255 Entire hostname exceeds the maximum length of 255 characters.
# 63 One or more individual labels within the hostname (separated by
# dots) exceeds the maximum of 63 characters.
# 1 One or more individual labels within the hostname contains one
# or more invalid characters.
# 2 One or more individual labels within the hostname starts or
# ends with a hyphen (hyphens are allowed, but a label cannot
# begin or end with a hyphen).
# 3 One or more individual labels within the hostname are null.
#
# f_dialog_validate_hostname $hostname
#
# If the hostname is determined to be invalid, the appropriate error will be
# displayed using the f_show_msg function.
#
f_validate_hostname()
{
local fqhn="$1"
# Return error if the hostname exceeds 255 characters
[ ${#fqhn} -gt 255 ] && return 255
local IFS="." # Split on `dot'
for label in $fqhn; do
# Return error if the label exceeds 63 characters
[ ${#label} -gt 63 ] && return 63
# Return error if the label is null
[ "$label" ] || return 3
# Return error if label begins/ends with dash
case "$label" in -*|*-) return 2; esac
# Return error if the label contains any invalid chars
case "$label" in *[!0-9a-zA-Z-]*) return 1; esac
done
return $SUCCESS
}
# f_inet_atoi $ipv4_address [$var_to_set]
#
# Convert an IPv4 address or mask from dotted-quad notation (e.g., `127.0.0.1'
# or `255.255.255.0') to a 32-bit unsigned integer for the purpose of network
# and broadcast calculations. For example, one can validate that two addresses
# are on the same network:
#
# f_inet_atoi 1.2.3.4 ip1num
# f_inet_atoi 1.2.4.5 ip2num
# f_inet_atoi 255.255.0.0 masknum
# if [ $(( $ip1num & $masknum )) -eq \
# $(( $ip2num & $masknum )) ]
# then
# : IP addresses are on same network
# fi
#
# See f_validate_ipaddr() below for an additional example usage, on calculating
# network and broadcast addresses.
#
# If $var_to_set is missing or NULL, the converted IP address is printed to
# standard output for capturing in a sub-shell (which is less-recommended
# because of performance degredation; for example, when called in a loop).
#
f_inet_atoi()
{
local __addr="$1" __var_to_set="$2" __num=0
if f_validate_ipaddr "$__addr"; then
__num=$( IFS=.; set -- $__addr; \
echo $(( ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 )) )
fi
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" $__num
else
echo $__num
fi
}
# f_validate_ipaddr $ipaddr [$netmask]
#
# Returns zero if the given argument (an IP address) is of the proper format.
#
# The return status for invalid IP address is one of:
# 1 One or more individual octets within the IP address (separated
# by dots) contains one or more invalid characters.
# 2 One or more individual octets within the IP address are null
# and/or missing.
# 3 One or more individual octets within the IP address exceeds the
# maximum of 255 (or 2^8, being an octet comprised of 8 bits).
# 4 The IP address has either too few or too many octets.
#
# If a netmask is provided, the IP address is checked further:
#
# 5 The IP address must not be the network or broadcast address.
#
f_validate_ipaddr()
{
local ip="$1" mask="$2"
# Track number of octets for error checking
local noctets=0
local oldIFS="$IFS"
local IFS="." # Split on `dot'
for octet in $ip; do
# Return error if the octet is null
[ "$octet" ] || return 2
# Return error if not a whole integer
f_isinteger "$octet" || return 1
# Return error if not a positive integer
[ $octet -ge 0 ] || return 1
# Return error if the octet exceeds 255
[ $octet -gt 255 ] && return 3
noctets=$(( $noctets + 1 ))
done
IFS="$oldIFS"
[ $noctets -eq 4 ] || return 4
#
# The IP address must not be network or broadcast address.
#
if [ "$mask" ]; then
local ipnum masknum netnum bcastnum
local max_addr=4294967295 # 255.255.255.255
f_inet_atoi $ip ipnum
f_inet_atoi $mask masknum
netnum=$(( $ipnum & $masknum ))
bcastnum=$(( ($ipnum & $masknum)+$max_addr-$masknum ))
if [ "$masknum" ] &&
[ $ipnum -eq $netnum -o $ipnum -eq $bcastnum ]
then
return 5
fi
fi
return $SUCCESS
}
# f_validate_ipaddr6 $ipv6_addr
#
# Returns zero if the given argument (an IPv6 address) is of the proper format.
#
# The return status for invalid IP address is one of:
# 1 One or more individual segments within the IP address
# (separated by colons) contains one or more invalid characters.
# Segments must contain only combinations of the characters 0-9,
# A-F, or a-f.
# 2 Too many/incorrect null segments. A single null segment is
# allowed within the IP address (separated by colons) but not
# allowed at the beginning or end (unless a double-null segment;
# i.e., "::*" or "*::").
# 3 One or more individual segments within the IP address
# (separated by colons) exceeds the length of 4 hex-digits.
# 4 The IP address entered has either too few (less than 3), too
# many (more than 8), or not enough segments, separated by
# colons.
# 5* The IPv4 address at the end of the IPv6 address is invalid.
# * When there is an error with the dotted-quad IPv4 address at the
# end of the IPv6 address, the return value of 5 is OR'd with a
# bit-shifted (<< 4) return of f_validate_ipaddr.
#
f_validate_ipaddr6()
{
local ip="${1%\%*}" # removing the interface specification if-present
local IFS=":" # Split on `colon'
set -- $ip:
# Return error if too many or too few segments
# Using 9 as max in case of leading or trailing null spanner
[ $# -gt 9 -o $# -lt 3 ] && return 4
local h="[0-9A-Fa-f]"
local nulls=0 nsegments=$# contains_ipv4_segment=
while [ $# -gt 0 ]; do
segment="${1%:}"
shift
#
# Return error if this segment makes one null too-many. A
# single null segment is allowed anywhere in the middle as well
# as double null segments are allowed at the beginning or end
# (but not both).
#
if [ ! "$segment" ]; then
nulls=$(( $nulls + 1 ))
if [ $nulls -eq 3 ]; then
# Only valid syntax for 3 nulls is `::'
[ "$ip" = "::" ] || return 2
elif [ $nulls -eq 2 ]; then
# Only valid if begins/ends with `::'
case "$ip" in
::*|*::) : fall thru ;;
*) return 2
esac
fi
continue
fi
#
# Return error if not a valid hexadecimal short
#
case "$segment" in
$h|$h$h|$h$h$h|$h$h$h$h)
: valid segment of 1-4 hexadecimal digits
;;
*[!0-9A-Fa-f]*)
# Segment contains at least one invalid char
# Return error immediately if not last segment
[ $# -eq 0 ] || return 1
# Otherwise, check for legacy IPv4 notation
case "$segment" in
*[!0-9.]*)
# Segment contains at least one invalid
# character even for an IPv4 address
return 1
esac
# Return error if not enough segments
if [ $nulls -eq 0 ]; then
[ $nsegments -eq 7 ] || return 4
fi
contains_ipv4_segment=1
# Validate the IPv4 address
f_validate_ipaddr "$segment" ||
return $(( 5 | $? << 4 ))
;;
*)
# Segment characters are all valid but too many
return 3
esac
done
if [ $nulls -eq 1 ]; then
# Single null segment cannot be at beginning/end
case "$ip" in
:*|*:) return 2
esac
fi
#
# A legacy IPv4 address can span the last two 16-bit segments,
# reducing the amount of maximum allowable segments by-one.
#
maxsegments=8
if [ "$contains_ipv4_segment" ]; then
maxsegments=7
fi
case $nulls in
# Return error if missing segments with no null spanner
0) [ $nsegments -eq $maxsegments ] || return 4 ;;
# Return error if null spanner with too many segments
1) [ $nsegments -le $maxsegments ] || return 4 ;;
# Return error if leading/trailing `::' with too many segments
2) [ $nsegments -le $(( $maxsegments + 1 )) ] || return 4 ;;
esac
return $SUCCESS
}
# f_validate_netmask $netmask
#
# Returns zero if the given argument (a subnet mask) is of the proper format.
#
# The return status for invalid netmask is one of:
# 1 One or more individual fields within the subnet mask (separated
# by dots) contains one or more invalid characters.
# 2 One or more individual fields within the subnet mask are null
# and/or missing.
# 3 One or more individual fields within the subnet mask exceeds
# the maximum of 255 (a full 8-bit register).
# 4 The subnet mask has either too few or too many fields.
# 5 One or more individual fields within the subnet mask is an
# invalid integer (only 0,128,192,224,240,248,252,254,255 are
# valid integers).
#
f_validate_netmask()
{
local mask="$1"
# Track number of fields for error checking
local nfields=0
local IFS="." # Split on `dot'
for field in $mask; do
# Return error if the field is null
[ "$field" ] || return 2
# Return error if not a whole positive integer
f_isinteger "$field" || return 1
# Return error if the field exceeds 255
[ $field -gt 255 ] && return 3
# Return error if the field is an invalid integer
case "$field" in
0|128|192|224|240|248|252|254|255) :;;
*) return 5;;
esac
nfields=$(( $nfields + 1 ))
done
[ $nfields -eq 4 ] || return 4
}
# f_validate_gateway $gateway $ipaddr $netmask
#
# Validate an IPv4 default gateway (aka router) address for a given IP address
# making sure the two are in the same network (able to ``talk'' to each other).
# Returns success if $ipaddr and $gateway are in the same network given subnet
# mask $netmask.
#
f_validate_gateway()
{
local gateway="$1" ipaddr="$2" netmask="$3"
local gwnum ipnum masknum
f_validate_ipaddr "$gateway" "$netmask" || return $FAILURE
f_inet_atoi "$netmask" masknum
f_inet_atoi "$ipaddr" ipnum
f_inet_atoi "$gateway" gwnum
# Gateway must be within set of IPs reachable through interface
[ $(( $ipnum & $masknum )) -eq \
$(( $gwnum & $masknum )) ] # Return status
}
# f_dialog_validate_tcpip $hostname $gateway $nameserver $ipaddr $netmask
#
# Returns success if the arguments provided are valid for accessing a TCP/IP
# network, otherwise returns failure.
#
f_dialog_validate_tcpip()
{
local hostname="$1" gateway="$2" nameserver="$3"
local ipaddr="$4" netmask="$5"
local ipnum masknum
if [ ! "$hostname" ]; then
f_dialog_msgbox "$msg_must_specify_a_host_name_of_some_sort"
elif ! f_validate_hostname "$hostname"; then
f_dialog_msgbox "$msg_invalid_hostname_value"
elif [ "$netmask" ] && ! f_validate_netmask "$netmask"; then
f_dialog_msgbox "$msg_invalid_netmask_value"
elif [ "$nameserver" ] &&
! f_validate_ipaddr "$nameserver" &&
! f_validate_ipaddr6 "$nameserver"; then
f_dialog_msgbox "$msg_invalid_name_server_ip_address_specified"
elif [ "$ipaddr" ] && ! f_validate_ipaddr "$ipaddr" "$netmask"; then
f_dialog_msgbox "$msg_invalid_ipv4_address"
elif [ "$gateway" -a "$gateway" != "NO" ] &&
! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then
f_dialog_msgbox "$msg_invalid_gateway_ipv4_address_specified"
else
return $SUCCESS
fi
return $FAILURE
}
# f_ifconfig_inet $interface [$var_to_set]
#
# Returns the IPv4 address associated with $interface. If $var_to_set is
# missing or NULL, the IP address is printed to standard output for capturing
# in a sub-shell (which is less-recommended because of performance degredation;
# for example, when called in a loop).
#
# This function is a two-parter. Below is the awk(1) portion of the function,
# afterward is the sh(1) function which utilizes the below awk script.
#
f_ifconfig_inet_awk='
BEGIN { found = 0 }
( $1 == "inet" ) \
{
print $2
found = 1
exit
}
END { exit ! found }
'
f_ifconfig_inet()
{
local __interface="$1" __var_to_set="$2"
if [ "$__var_to_set" ]; then
local __ip
__ip=$( ifconfig "$__interface" 2> /dev/null |
awk "$f_ifconfig_inet_awk" )
setvar "$__var_to_set" "$__ip"
else
ifconfig "$__interface" 2> /dev/null |
awk "$f_ifconfig_inet_awk"
fi
}
# f_ifconfig_inet6 $interface [$var_to_set]
#
# Returns the IPv6 address associated with $interface. If $var_to_set is
# missing or NULL, the IP address is printed to standard output for capturing
# in a sub-shell (which is less-recommended because of performance degredation;
# for example, when called in a loop).
#
# This function is a two-parter. Below is the awk(1) portion of the function,
# afterward is the sh(1) function which utilizes the below awk script.
#
f_ifconfig_inet6_awk='
BEGIN { found = 0 }
( $1 == "inet6" ) \
{
print $2
found = 1
exit
}
END { exit ! found }
'
f_ifconfig_inet6()
{
local __interface="$1" __var_to_set="$2"
if [ "$__var_to_set" ]; then
local __ip6
__ip6=$( ifconfig "$__interface" 2> /dev/null |
awk "$f_ifconfig_inet6_awk" )
setvar "$__var_to_set" "$__ip6"
else
ifconfig "$__interface" 2> /dev/null |
awk "$f_ifconfig_inet6_awk"
fi
}
# f_ifconfig_netmask $interface [$var_to_set]
#
# Returns the IPv4 subnet mask associated with $interface. If $var_to_set is
# missing or NULL, the netmask is printed to standard output for capturing in a
# sub-shell (which is less-recommended because of performance degredation; for
# example, when called in a loop).
#
f_ifconfig_netmask()
{
local __interface="$1" __var_to_set="$2" __octets
__octets=$( ifconfig "$__interface" 2> /dev/null | awk \
'
BEGIN { found = 0 }
( $1 == "inet" ) \
{
printf "%s %s %s %s\n",
substr($4,3,2),
substr($4,5,2),
substr($4,7,2),
substr($4,9,2)
found = 1
exit
}
END { exit ! found }
' ) || return $FAILURE
local __octet __netmask=
for __octet in $__octets; do
__netmask="$__netmask.$( printf "%u" "0x$__octet" )"
done
__netmask="${__netmask#.}"
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" "$__netmask"
else
echo $__netmask
fi
}
# f_route_get_default [$var_to_set]
#
# Returns the IP address of the currently active default router. If $var_to_set
# is missing or NULL, the IP address is printed to standard output for
# capturing in a sub-shell (which is less-recommended because of performance
# degredation; for example, when called in a loop).
#
# This function is a two-parter. Below is the awk(1) portion of the function,
# afterward is the sh(1) function which utilizes the below awk script.
#
f_route_get_default='
BEGIN { found = 0 }
( $1 == "gateway:" ) \
{
print $2
found = 1
exit
}
END { exit ! found }
'
f_route_get_default()
{
local __var_to_set="$1"
if [ "$__var_to_set" ]; then
local __ip
__ip=$( route -n get default 2> /dev/null |
awk "$f_route_get_default_awk" )
setvar "$__var_to_set" "$__ip"
else
route -n get default 2> /dev/null |
awk "$f_route_get_default_awk"
fi
}
# f_resolv_conf_nameservers [$var_to_set]
#
# Returns nameserver(s) configured in resolv.conf(5). If $var_to_set is missing
# or NULL, the list of nameservers is printed to standard output for capturing
# in a sub-shell (which is less-recommended because of performance degredation;
# for example, when called in a loop).
#
# This function is a two-parter. Below is the awk(1) portion of the function,
# afterward is the sh(1) function which utilizes the below awk script.
#
f_resolv_conf_nameservers_awk='
BEGIN { found = 0 }
( $1 == "nameserver" ) \
{
print $2
found = 1
}
END { exit ! found }
'
f_resolv_conf_nameservers()
{
local __var_to_set="$1"
if [ "$__var_to_set" ]; then
local __ns
__ns=$( awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
2> /dev/null )
setvar "$__var_to_set" "$__ns"
else
awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
2> /dev/null
fi
}
# f_config_resolv
#
# Attempts to configure resolv.conf(5) and ilk. Returns success if able to
# write the file(s), otherwise returns error status.
#
# Variables from variable.subr that are used in configuring resolv.conf(5) are
# as follows (all of which can be configured automatically through functions
# like f_dhcp_get_info() or manually):
#
# VAR_NAMESERVER
# The nameserver to add in resolv.conf(5).
# VAR_DOMAINNAME
# The domain to configure in resolv.conf(5). Also used in the
# configuration of hosts(5).
# VAR_IPADDR
# The IPv4 address to configure in hosts(5).
# VAR_IPV6ADDR
# The IPv6 address to configure in hosts(5).
# VAR_HOSTNAME
# The hostname to associate with the IPv4 and/or IPv6 address in
# hosts(5).
#
f_config_resolv()
{
local cp c6p dp hp
f_getvar $VAR_NAMESERVER cp
if [ "$cp" ]; then
case "$RESOLV_CONF" in
*/*) f_quietly mkdir -p "${RESOLV_CONF%/*}" ;;
esac
# Attempt to create/truncate the file
( :> "$RESOLV_CONF" ) 2> /dev/null || return $FAILURE
f_getvar $VAR_DOMAINNAME dp &&
printf "domain\t%s\n" "$dp" >> "$RESOLV_CONF"
printf "nameserver\t%s\n" "$cp" >> "$RESOLV_CONF"
f_dprintf "Wrote out %s" "$RESOLV_CONF"
fi
f_getvar $VAR_DOMAINNAME dp
f_getvar $VAR_IPADDR cp
f_getvar $VAR_IPV6ADDR c6p
f_getvar $VAR_HOSTNAME hp
# Attempt to create the file if it doesn't already exist
if [ ! -e "$ETC_HOSTS" ]; then
case "$ETC_HOSTS" in
*/*) f_quietly mkdir -p "${ETC_HOSTS%/*}" ;;
esac
( :> "$ETC_HOSTS" ) 2> /dev/null || return $FAILURE
fi
# Scan the file and add ourselves if not already configured
awk -v dn="$dp" -v ip4="$cp" -v ip6="$c6p" -v hn="$hp" '
BEGIN {
local4found = local6found = 0
hn4found = hn6found = h4found = h6found = 0
h = ( match(hn, /\./) ? substr(hn, 0, RSTART-1) : "" )
}
($1 == "127.0.0.1") { local4found = 1 }
($1 == "::1") { local6found = 1 }
{
for (n = 2; n <= NF; n++)
{
if ( $1 == ip4 ) {
if ( $n == h ) h4found = 1
if ( $n == hn ) hn4found = 1
if ( $n == hn "." ) hn4found = 1
}
if ( $1 == ip6 ) {
if ( $n == h ) h6found = 1
if ( $n == hn ) hn6found = 1
if ( $n == hn "." ) hn6found = 1
}
}
}
END {
hosts = FILENAME
if ( ! local6found )
printf "::1\t\t\tlocalhost%s\n",
( dn ? " localhost." dn : "" ) >> hosts
if ( ! local4found )
printf "127.0.0.1\t\tlocalhost%s\n",
( dn ? " localhost." dn : "" ) >> hosts
if ( ip6 && ! (h6found && hn6found))
{
printf "%s\t%s %s\n", ip6, hn, h >> hosts
printf "%s\t%s.\n", ip6, hn >> hosts
}
else if ( ip6 )
{
if ( ! h6found )
printf "%s\t%s.\n", ip6, h >> hosts
if ( ! hn6found )
printf "%s\t%s\n", ip6, hn >> hosts
}
if ( ip4 && ! (h4found && hn4found))
{
printf "%s\t\t%s %s\n", ip4, hn, h >> hosts
printf "%s\t\t%s.\n", ip4, hn >> hosts
}
else if ( ip4 )
{
if ( ! h4found )
printf "%s\t\t%s.\n", ip4, h >> hosts
if ( ! hn4found )
printf "%s\t\t%s\n", ip4, hn >> hosts
}
}
' "$ETC_HOSTS" 2> /dev/null || return $FAILURE
f_dprintf "Wrote out %s" "$ETC_HOSTS"
return $SUCCESS
}
# f_dhcp_parse_leases $leasefile struct_name
#
# Parse $leasefile and store the information for the most recent lease in a
# struct (see struct.subr for additional details) named `struct_name'. See
# DHCP_LEASE struct definition in the GLOBALS section above.
#
f_dhcp_parse_leases()
{
local leasefile="$1" struct_name="$2"
[ "$struct_name" ] || return $FAILURE
if [ ! -e "$leasefile" ]; then
f_dprintf "%s: No such file or directory" "$leasefile"
return $FAILURE
fi
f_struct "$struct_name" && f_struct_free "$struct_name"
f_struct_new DHCP_LEASE "$struct_name"
eval "$( awk -v struct="$struct_name" '
BEGIN {
lease_found = 0
keyword_list = " \
interface \
fixed-address \
filename \
server-name \
script \
medium \
"
split(keyword_list, keywords, FS)
time_list = "renew rebind expire"
split(time_list, times, FS)
option_list = " \
host-name \
subnet-mask \
routers \
domain-name-servers \
domain-name \
broadcast-address \
dhcp-lease-time \
dhcp-message-type \
dhcp-server-identifier \
dhcp-renewal-time \
dhcp-rebinding-time \
"
split(option_list, options, FS)
}
function set_value(prop,value)
{
lease_found = 1
gsub(/[^[:alnum:]_]/, "_", prop)
sub(/;$/, "", value)
sub(/^"/, "", value)
sub(/"$/, "", value)
sub(/,.*/, "", value)
printf "%s set %s \"%s\"\n", struct, prop, value
}
/^lease {$/, /^}$/ \
{
if ( $0 ~ /^lease {$/ ) next
if ( $0 ~ /^}$/ ) exit
for (k in keywords)
{
keyword = keywords[k]
if ( $1 == keyword )
{
set_value(keyword, $2)
next
}
}
for (t in times)
{
time = times[t]
if ( $1 == time )
{
set_value(time, $2 " " $3 " " $4)
next
}
}
if ( $1 != "option" ) next
for (o in options)
{
option = options[o]
if ( $2 == option )
{
set_value(option, $3)
next
}
}
}
EXIT {
if ( ! lease_found )
{
printf "f_struct_free \"%s\"\n", struct
print "return $FAILURE"
}
}
' "$leasefile" )"
}
# f_dhcp_get_info $interface
#
# Parse the dhclient(8) lease database for $interface to obtain all the
# necessary IPv4 details necessary to communicate on the network. The retrieved
# information is stored in VAR_IPADDR, VAR_NETMASK, VAR_GATEWAY, and
# VAR_NAMESERVER.
#
# If reading the lease database fails, values are obtained from ifconfig(8) and
# route(8). If the DHCP lease did not provide a nameserver (or likewise, we
# were unable to parse the lease database), fall-back to resolv.conf(5) for
# obtaining the nameserver. Always returns success.
#
f_dhcp_get_info()
{
local interface="$1" cp
local leasefile="/var/db/dhclient.leases.$interface"
# If it fails, do it the old-fashioned way
if f_dhcp_parse_leases "$leasefile" lease; then
lease get fixed_address $VAR_IPADDR
lease get subnet_mask $VAR_NETMASK
lease get routers cp
setvar $VAR_GATEWAY "${cp%%,*}"
lease get domain_name_servers cp
setvar $VAR_NAMESERVER "${cp%%,*}"
lease get host_name cp &&
setvar $VAR_HOSTNAME "$cp"
f_struct_free lease
else
# Bah, now we have to get the information from ifconfig
if f_debugging; then
f_dprintf "DHCP configured interface returns %s" \
"$( ifconfig "$interface" )"
fi
f_ifconfig_inet "$interface" $VAR_IPADDR
f_ifconfig_netmask "$interface" $VAR_NETMASK
f_route_get_default $VAR_GATEWAY
fi
# If we didn't get a name server value, hunt for it in resolv.conf
local ns
if [ -r "$RESOLV_CONF" ] && ! {
f_getvar $VAR_NAMESERVER ns || [ "$ns" ]
}; then
f_resolv_conf_nameservers cp &&
setvar $VAR_NAMESERVER ${cp%%[$IFS]*}
fi
return $SUCCESS
}
# f_rtsol_get_info $interface
#
# Returns the rtsol-provided IPv6 address associated with $interface. The
# retrieved IP address is stored in VAR_IPV6ADDR. Always returns success.
#
f_rtsol_get_info()
{
local interface="$1" cp
cp=$( ifconfig "$interface" 2> /dev/null | awk \
'
BEGIN { found = 0 }
( $1 == "inet6" ) && ( $2 ~ /^fe80:/ ) \
{
print $2
found = 1
exit
}
END { exit ! found }
' ) && setvar $VAR_IPV6ADDR "$cp"
}
# f_host_lookup $host [$var_to_set]
#
# Use host(1) to lookup (or reverse) an Internet number from (or to) a name.
# Multiple answers are returned separated by a single space. If host(1) does
# not exit cleanly, its full output is provided and the return status is 1.
#
# If nsswitch.conf(5) has been configured to query local access first for the
# `hosts' database, we'll manually check hosts(5) first (preventing host(1)
# from hanging in the event that DNS goes awry).
#
# If $var_to_set is missing or NULL, the list of IP addresses is printed to
# standard output for capturing in a sub-shell (which is less-recommended
# because of performance degredation; for example, when called in a loop).
#
# The variables from variable.subr used in looking up the host are as follows
# (which are set manually):
#
# VAR_IPV6_ENABLE [Optional]
# If set to "YES", enables the lookup of IPv6 addresses and IPv4
# address. IPv6 addresses, if any, will come before IPv4. Note
# that if nsswitch.conf(5) shows an affinity for "files" for the
# "host" database and there is a valid entry in hosts(5) for
# $host, this setting currently has no effect (an IPv4 address
# can supersede an IPv6 address). By design, hosts(5) overrides
# any preferential treatment. Otherwise, if this variable is not
# set, IPv6 addresses will not be used (IPv4 addresses will
# specifically be requested from DNS).
#
# This function is a two-parter. Below is the awk(1) portion of the function,
# afterward is the sh(1) function which utilizes the below awk script.
#
f_host_lookup_awk='
BEGIN{ addrs = "" }
!/^[[:space:]]*(#|$)/ \
{
for (n=1; n++ < NF;) if ($n == name)
addrs = addrs (addrs ? " " : "") $1
}
END {
if (addrs) print addrs
exit !addrs
}
'
f_host_lookup()
{
local __host="$1" __var_to_set="$2"
f_dprintf "f_host_lookup: host=[%s]" "$__host"
# If we're configured to look at local files first, do that
if awk '/^hosts:/{exit !($2=="files")}' "$NSSWITCH_CONF"; then
if [ "$__var_to_set" ]; then
local __cp
if __cp=$( awk -v name="$__host" \
"$f_host_lookup_awk" "$ETC_HOSTS" )
then
setvar "$__var_to_set" "$__cp"
return $SUCCESS
fi
else
awk -v name="$__host" \
"$f_host_lookup_awk" "$ETC_HOSTS" &&
return $SUCCESS
fi
fi
#
# Fall back to host(1) -- which is further governed by nsswitch.conf(5)
#
local __output __ip6 __addrs="" __wait=""
f_getvar $VAR_MEDIA_TIMEOUT __wait
[ "$__wait" ] && __wait="-W $(( $__wait / 2 ))"
f_getvar $VAR_IPV6_ENABLE __ip6
if [ "$__ip6" = "YES" ]; then
if ! __output=$( host -t AAAA $__wait -- "$__host" 2>&1 ); then
# An error occurred, display in-full and return error
[ "$__var_to_set" ] &&
setvar "$__var_to_set" "$__output"
return $FAILURE
fi
__addrs=$( echo "$__output" | awk '/ address /{print $NF}' )
fi
if ! __output=$( host -t A $__wait -- "$__host" 2>&1 ); then
# An error occurred, display it in-full and return error
[ "$__var_to_set" ] && setvar "$__var_to_set" "$__output"
return $FAILURE
fi
__addrs="$__addrs${__addrs:+ }$(
echo "$__output" | awk '/ address /{print $NF}' )"
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" "$__addrs"
else
echo $__addrs
fi
}
# f_device_dialog_tcp $device
#
# This is it - how to get TCP setup values. Prompt the user to edit/confirm the
# interface, gateway, nameserver, and hostname settings -- all required for
# general TCP/IP access.
#
# Variables from variable.subr that can be used to sript user input:
#
# VAR_NO_INET6
# If set, prevents asking the user if they would like to use
# rtsol(8) to check for an IPv6 router.
# VAR_TRY_RTSOL
# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
# user if they would like to try the IPv6 RouTer SOLicitation
# utility (rtsol(8)) to get IPv6 information. Ignored if
# VAR_NO_INET6 is set.
# VAR_TRY_DHCP
# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
# user if they would like to try to acquire IPv4 connection
# settings from a DHCP server using dhclient(8).
#
# VAR_GATEWAY Default gateway to use.
# VAR_IPADDR Interface address to assign.
# VAR_NETMASK Interface subnet mask.
# VAR_EXTRAS Extra interface options to ifconfig(8).
# VAR_HOSTNAME Hostname to set.
# VAR_DOMAINNAME Domain name to use.
# VAR_NAMESERVER DNS nameserver to use when making lookups.
# VAR_IPV6ADDR IPv6 interface address.
#
# In addition, the following variables are used in acquiring network settings
# from the user:
#
# VAR_NONINTERACTIVE
# If set (such as when running in a script), prevents asking the
# user questions or displaying the usual prompts, etc.
# VAR_NETINTERACTIVE
# The one exception to VAR_NONINTERACTIVE is VAR_NETINTERACTIVE,
# which if set will prompt the user to try RTSOL (unless
# VAR_TRY_RTSOL has been set), try DHCP (unless VAR_TRY_DHCP has
# been set), and display the network verification dialog. This
# allows you to have a mostly non-interactive script that still
# prompts for network setup/confirmation.
#
# After successfull execution, the following variables are set:
#
# VAR_IFCONFIG + $device (e.g., `ifconfig_em0')
# Defines the ifconfig(8) properties specific to $device.
#
f_device_dialog_tcp()
{
local dev="$1" cp n
local use_dhcp="" use_rtsol=""
local _ipaddr _netmask _extras
[ "$dev" ] || return $FAILURE
# Initialize vars from previous device values
local private
device_$dev get private private
if [ "$private" ] && f_struct "$private"; then
$private get ipaddr _ipaddr
$private get netmask _netmask
$private get extras _extras
$private get use_dhcp use_dhcp
$private get use_rtsol use_rtsol
else # See if there are any defaults
#
# This is a hack so that the dialogs below are interactive in a
# script if we have requested interactive behavior.
#
local old_interactive=
if ! f_interactive && f_netinteractive; then
f_getvar $VAR_NONINTERACTIVE old_interactive
unset $VAR_NONINTERACTIVE
fi
#
# Try a RTSOL scan if such behavior is desired.
# If the variable was configured and is YES, do it.
# If it was configured to anything else, treat it as NO.
# Otherwise, ask the question interactively.
#
local try6
if ! f_isset $VAR_NO_INET6 && {
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.
2013-02-25 19:55:32 +00:00
{ f_getvar $VAR_TRY_RTSOL try6 && [ "$try6" = "YES" ]; } ||
{
# Only prompt the user when VAR_TRY_RTSOL is unset
! f_isset $VAR_TRY_RTSOL &&
f_dialog_noyes "$msg_try_ipv6_configuration"
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.
2013-02-25 19:55:32 +00:00
}
}; then
local i
f_quietly sysctl net.inet6.ip6.forwarding=0
f_quietly sysctl net.inet6.ip6.accept_rtadv=1
f_quietly ifconfig $dev up
i=$( sysctl -n net.inet6.ip6.dad_count )
sleep $(( $i + 1 ))
f_quietly mkdir -p /var/run
f_dialog_info "$msg_scanning_for_ra_servers"
if f_quietly rtsol $dev; then
i=$( sysctl -n net.inet6.ip6.dad_count )
sleep $(( $i + 1 ))
f_rtsol_get_info $dev
use_rtsol=1
else
use_rtsol=
fi
fi
#
# Try a DHCP scan if such behavior is desired.
# If the variable was configured and is YES, do it.
# If it was configured to anything else, treat it as NO.
# Otherwise, ask the question interactively.
#
local try4
if { f_getvar $VAR_TRY_DHCP try4 && [ "$try4" = "YES" ]; } || {
# Only prompt the user when VAR_TRY_DHCP is unset
! f_isset $VAR_TRY_DHCP &&
f_dialog_noyes "$msg_try_dhcp_configuration"
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.
2013-02-25 19:55:32 +00:00
}; then
f_quietly ifconfig $dev delete
f_quietly mkdir -p /var/db
f_quietly mkdir -p /var/run
f_quietly mkdir -p /tmp
local msg="$msg_scanning_for_dhcp_servers"
trap - SIGINT
( # Execute in sub-shell to allow/catch Ctrl-C
trap 'exit $FAILURE' SIGINT
if [ "$USE_XDIALOG" ]; then
f_quietly dhclient $dev |
f_xdialog_info "$msg"
else
f_dialog_info "$msg"
f_quietly dhclient $dev
fi
)
local retval=$?
trap 'f_interrupt' SIGINT
if [ $retval -eq $SUCCESS ]; then
f_dhcp_get_info $dev
use_dhcp=1
else
use_dhcp=
fi
fi
# Restore old VAR_NONINTERACTIVE if needed.
[ "$old_interactive" ] &&
setvar $VAR_NONINTERACTIVE "$old_interactive"
# Special hack so it doesn't show up oddly in the menu
local gw
if f_getvar $VAR_GATEWAY gw && [ "$gw" = "NO" ]; then
setvar $VAR_GATEWAY ""
fi
# Get old IP address from variable space, if available
if [ ! "$_ipaddr" ]; then
if f_getvar $VAR_IPADDR cp; then
_ipaddr="$cp"
elif f_getvar ${dev}_$VAR_IPADDR cp; then
_ipaddr="$cp"
fi
fi
# Get old netmask from variable space, if available
if [ ! "$_netmask" ]; then
if f_getvar $VAR_NETMASK cp; then
_netmask="$cp"
elif f_getvar ${dev}_$VAR_NETMASK cp; then
_netmask="$cp"
fi
fi
# Get old extras string from variable space, if available
if [ ! "$_extras" ]; then
if f_getvar $VAR_EXTRAS cp; then
_extras="$cp"
elif f_getvar ${dev}_$VAR_EXTRAS cp; then
_extras="$cp"
fi
fi
fi
# Look up values already recorded with the system, or blank the string
# variables ready to accept some new data
local _hostname _gateway _nameserver
f_getvar $VAR_HOSTNAME _hostname
case "$_hostname" in
*.*) : do nothing ;; # Already fully-qualified
*)
f_getvar $VAR_DOMAINNAME cp
[ "$cp" ] && _hostname="$_hostname.$cp"
esac
f_getvar $VAR_GATEWAY _gateway
f_getvar $VAR_NAMESERVER _nameserver
# Re-check variables for initial inheritance before heading into dialog
[ "$_hostname" ] || _hostname="${HOSTNAME:-$( hostname )}"
[ "$_gateway" ] || f_route_get_default _gateway
[ ! "$_nameserver" ] &&
f_resolv_conf_nameservers cp && _nameserver=${cp%%[$IFS]*}
[ "$_ipaddr" ] || f_ifconfig_inet $dev _ipaddr
[ "$_netmask" ] || f_ifconfig_netmask $dev _netmask
# If non-interactive, jump over dialog section and into config section
if f_netinteractive || f_interactive || [ ! "$_hostname" ]
then
[ ! "$_hostname" ] && f_interactive &&
f_dialog_msgbox "$msg_hostname_variable_not_set"
local title=" $msg_network_configuration "
local hline="$hline_alnum_arrows_punc_tab_enter"
local extras_help="$tcplayout_extras_help"
# Modify the help line for PLIP config
[ "${dev#plip}" != "$dev" ] &&
extras_help="$tcplayout_extras_help_for_plip"
f_getvar $VAR_IPV6ADDR cp && [ "$cp" ] &&
title="$title($msg_ipv6_ready) "
if [ ! "$USE_XDIALOG" ]; then
local prompt="$msg_dialog_mixedform_navigation_help"
# Calculate center position for displaying device label
local devlabel="$msg_configuration_for_interface $dev"
local width=54
local n=$(( $width/2 - (${#devlabel} + 4)/2 - 2 ))
while :; do
cp=$( $DIALOG \
--title "$title" \
--backtitle "$DIALOG_BACKTITLE" \
--hline "$hline" \
--item-help \
--ok-label "$msg_ok" \
--cancel-label "$msg_cancel" \
--help-button \
--help-label "$msg_help" \
--mixedform "$prompt" 16 $width 9 \
"$msg_host_name_including_domain:" 1 2 \
"$_hostname" 2 3 45 255 0 \
"$tcplayout_hostname_help" \
"$msg_ipv4_gateway:" 3 2 \
"$_gateway" 4 3 16 15 0 \
"$tcplayout_gateway_help" \
"$msg_name_server:" 3 31 \
"$_nameserver" 4 32 16 15 0 \
"$tcplayout_nameserver_help" \
"- $devlabel -" 5 $n "" 0 0 0 0 3 "" \
"$msg_ipv4_address:" 6 6 \
"$_ipaddr" 7 7 16 15 0 \
"$tcplayout_ipaddr_help" \
"$msg_netmask:" 6 31 \
"$_netmask" 7 32 16 15 0 \
"$tcplayout_netmask_help" \
"$msg_extra_options_to_ifconfig" 8 6 \
"$_extras" 9 7 41 2048 0 \
"$extras_help" \
2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
# --mixed-form always returns 0, we have to
# use the returned data to determine button
if [ ! "$cp" ]; then
# User either chose "Cancel", pressed
# ESC, or blanked every form field
return $FAILURE
else
n=$( echo "$cp" | f_number_of_lines )
[ $n -eq 1 ] && case "$cp" in HELP*)
# User chose "Help"
f_show_help "$TCP_HELPFILE"
continue
esac
fi
# Turn mixed-form results into env variables
eval "$( echo "$cp" | awk '
BEGIN {
n = 0
field[++n] = "_hostname"
field[++n] = "_gateway"
field[++n] = "_nameserver"
field[++n] = "_ipaddr"
field[++n] = "_netmask"
field[++n] = "_extras"
nfields = n
n = 0
}
{
gsub(/'\''/, "'\'\\\\\'\''")
sub(/[[:space:]]*$/, "")
value[field[++n]] = $0
}
END {
for ( n = 1; n <= nfields; n++ )
{
printf "%s='\''%s'\'';\n",
field[n],
value[field[n]]
}
}' )"
f_dialog_validate_tcpip \
"$_hostname" \
"$_gateway" \
"$_nameserver" \
"$_ipaddr" \
"$_netmask" \
&& break
done
else
# Xdialog(1) does not support --mixed-form
# Create a persistent menu instead
f_dialog_title "$msg_network_configuration"
local prompt=
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.
2013-02-25 19:55:32 +00:00
while :; do
cp=$( $DIALOG \
--title "$DIALOG_TITLE" \
--backtitle "$DIALOG_BACKTITLE" \
--hline "$hline" \
--item-help \
--ok-label "$msg_ok" \
--cancel-label "$msg_cancel" \
--help "" \
--menu "$prompt" 21 60 8 \
"$msg_accept_continue" "" \
"$tcplayout_accept_cont_help" \
"$msg_host_name_including_domain:" \
"$_hostname" \
"$tcplayout_hostname_help" \
"$msg_ipv4_gateway:" "$_gateway" \
"$tcplayout_gateway_help" \
"$msg_name_server:" "$_nameserver" \
"$tcplayout_nameserver_help" \
"$msg_ipv4_address:" "$_ipaddr" \
"$tcplayout_ipaddr_help" \
"$msg_netmask:" "$_netmask" \
"$tcplayout_netmask_help" \
"$msg_extra_options_to_ifconfig" \
"$_extras" "$extras_help" \
2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
)
local retval=$?
Improve portion of the dialog(1) API in dialog.subr responsible for retrieving stored data (for the --menu, --calendar, --timebox, --checklist, and --radiolist widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for some very long time, so the need to always store the return status of dialog(1) and then call some function to clean-up is long-deprecated. The function that used to do the clean-up was f_dialog_menutag(). We really don't need f_dialog_menutag() for its originally designed purpose, as all dialog invocations (even when in a sub-shell) do not use temporary files anymore. However, we do need to keep f_dialog_menutag() around because it still fills the need of being able to abstract the procedure for fetching stored data provided by functions that display the aforementioned widgets. In re-designing f_dialog_menutag(), four important changes are made: 1. Rename f_dialog_menutag() to f_dialog_menutag_fetch() 2. Introduce the new first-argument of $var_to_set to reduce number of forks 3. Create a corresponding f_dialog_menutag_store() to abstract the storage 4. Offload the sanitization to a new function, f_dialog_data_sanitize() NOTE: That last one is important. Not all functions need to store their data for later fetching, meanwhile every invocation of dialog should be sanitized (as we learned early-on in the i18n-effort -- underlying libraries will spit warnings to stderr for bad values of $LANG and since dialog outputs its responses to stderr, we need to sanitize every response of these warnings). These changes greatly improve readbaility and also improve performance by reducing unnecessary forking.
2013-06-01 23:58:44 +00:00
f_dialog_data_sanitize cp
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.
2013-02-25 19:55:32 +00:00
f_dprintf "retval=%u mtag=[%s]" $retval "$cp"
if [ $retval -eq 2 ]; then
# The Help button was pressed
f_show_help "$TCP_HELPFILE"
continue
elif [ $retval -ne 0 ]; then
# User chose "Cancel" or pressed ESC
f_dialog_title_restore
return $FAILURE
fi
case "$cp" in
"$msg_accept_continue")
f_dialog_validate_tcpip \
"$_hostname" \
"$_gateway" \
"$_nameserver" \
"$_ipaddr" \
"$_netmask" \
&& break ;;
"$msg_host_name_including_domain:")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_hostname" \
&& _hostname="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
"$msg_ipv4_gateway:")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_gateway" \
&& _gateway="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
"$msg_name_server:")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_nameserver" \
&& _nameserver="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
"$msg_ipv4_address:")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_ipaddr" \
&& _ipaddr="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
"$msg_netmask:")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_netmask" \
&& _netmask="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
"$msg_extra_options_to_ifconfig")
Similar to r251236, improve the portion of dialog(1) API in dialog.subr responsible for retrieving stored input (for the --inputbox and --password widgets). When we (Ron McDowell and I) developed the first version of bsdconfig, it used temporary files to store responses from dialog(1). That hasn't been true for a very long time, so the need to always execute some clean-up function is long-deprecated. The function that used to perform these clean- up routines for these widgets was f_dialog_inputstr(). We really don't need f_dialog_inputstr() for its originally designed purpose as all dialog invocations no longer require temporary files. Just as in r251236, redesign f_dialog_inputstr() in the following four ways: 1. Rename f_dialog_inputstr() to f_dialog_inputstr_fetch() 2. Introduce the new first-argument of $var_to_set to reduce forking 3. Create a corresponding f_dialog_inputstr_store() to abstract storage 4. Offload the sanitization to a new function, f_dialog_line_sanitize() It should be noted that f_dialog_line_sanitize() -- unlike its cousin from SVN r251236, f_dialog_data_sanitize() -- trims leading/trailing whitespace from the user's input. This helps prevent errors and common mistakes caused by the fact that the new cdialog implementation allows the right-arrow cursor key to go beyond the last byte of realtime input (adding whitespace at the end of the typed value). While we're centralizing the sanitization, let's rewrite f_dialog_input() while we're here to likewise reduce forking. The f_dialog_input() function now expects the first argument of $var_to_set instead of producing results on standard-out. These changes greatly improve readability and also improve performance.
2013-06-02 05:45:25 +00:00
f_dialog_input cp "$cp" "$_extras" \
&& _extras="$cp" ;;
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.
2013-02-25 19:55:32 +00:00
esac
done
f_dialog_title_restore
fi # XDIALOG
fi # interactive
# We actually need to inform the rest of bsdconfig about this
# data now if the user hasn't selected cancel.
if [ "$_hostname" ]; then
setvar $VAR_HOSTNAME "$_hostname"
f_quietly hostname "$_hostname"
case "$_hostname" in
*.*) setvar $VAR_DOMAINNAME "${_hostname#*.}" ;;
esac
fi
[ "$_gateway" ] && setvar $VAR_GATEWAY "$_gateway"
[ "$_nameserver" ] && setvar $VAR_NAMESERVER "$_nameserver"
[ "$_ipaddr" ] && setvar $VAR_IPADDR "$_ipaddr"
[ "$_netmask" ] && setvar $VAR_NETMASK "$_netmask"
[ "$_extras" ] && setvar $VAR_EXTRAS "$_extras"
f_dprintf "Creating struct DEVICE_INFO devinfo_%s" "$dev"
f_struct_new DEVICE_INFO devinfo_$dev
device_$dev set private devinfo_$dev
devinfo_$dev set ipaddr $_ipaddr
devinfo_$dev set netmask $_netmask
devinfo_$dev set extras $_extras
devinfo_$dev set use_rtsol $use_rtsol
devinfo_$dev set use_dhcp $use_dhcp
if [ "$use_dhcp" -o "$_ipaddr" ]; then
if [ "$use_dhcp" ]; then
cp="DHCP${extras:+ $extras}"
else
cp="inet $_ipaddr netmask $_netmask${extras:+ $extras}"
fi
setvar $VAR_IFCONFIG$dev "$cp"
fi
[ "$use_rtsol" ] &&
setvar $VAR_IPV6_ENABLE "YES"
[ "$use_dhcp" ] ||
f_config_resolv # XXX this will do it on the MFS copy
return $SUCCESS
}
# f_device_scan_tcp [$var_to_set]
#
# Scan for the first active/configured TCP/IP device. The name of the interface
# is printed to stderr like other dialog(1)-based functions (stdout is reserved
# for dialog(1) interaction) if $var_to_set is missing or NULL. Returns failure
# if no active/configured interface
#
f_device_scan_tcp()
{
local __var_to_set="$1" __iface
for __iface in $( ifconfig -l ); do
if ifconfig $__iface | awk '
BEGIN {
has_inet = has_inet6 = is_ethernet = 0
is_usable = 1
}
( $1 == "status:" && $2 != "active" ) { is_usable = 0; exit }
( $1 == "inet" ) {
if ($2 == "0.0.0.0") { is_usable = 0; exit }
has_inet++
}
( $1 == "inet6") { has_inet6++ }
( $1 == "media:" ) {
if ($2 != "Ethernet") { is_usable = 0; exit }
is_ethernet = 1
}
END {
if (!(is_ethernet && (has_inet || has_inet6)))
is_usable = 0
exit ! is_usable
}'; then
f_interactive &&
f_show_msg "$msg_using_interface" "$__iface"
f_dprintf "f_device_scan_tcp found %s" "$__iface"
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" "$__iface"
else
echo "$__iface" >&2
fi
return $SUCCESS
fi
done
return $FAILURE
}
# f_device_select_tcp
#
# Prompt the user to select network interface to use for TCP/IP access.
# Variables from variable.subr that can be used to script user input:
#
# VAR_NETWORK_DEVICE [Optional]
# Either a comma-separated list of network interfaces to try when
# setting up network access (e.g., "fxp0,em0") or "ANY" (case-
# sensitive) to indicate that the first active and configured
# interface is acceptable. If unset, the user is presented with a
# menu of all available network interfaces.
#
# Returns success if a valid network interface has been selected.
#
f_device_select_tcp()
{
local devs dev cnt network_dev
f_getvar $VAR_NETWORK_DEVICE network_dev
f_dprintf "f_device_select_tcp: %s=[%s]" \
VAR_NETWORK_DEVICE "$network_dev"
if [ "$network_dev" ]; then
#
# This can be set to several types of values. If set to ANY,
# scan all network devices looking for a valid link, and go
# with the first device found. Can also be specified as a
# comma delimited list, with each network device tried in
# order. Can also be set to a single network device.
#
[ "$network_dev" = "ANY" ] && f_device_scan_tcp network_dev
while [ "$network_dev" ]; do
case "$network_dev" in
*,*) dev="${network_dev%%,*}"
network_dev="${network_dev#*,}"
;;
*) dev="$network_dev"
network_dev=
esac
f_device_find "$dev" $DEVICE_TYPE_NETWORK devs
cnt=$( set -- $devs; echo $# )
if [ ${cnt:=0} -gt 0 ]; then
dev="${devs%%[$IFS]*}"
f_device_dialog_tcp $dev
if [ $? -eq $SUCCESS ]; then
setvar $VAR_NETWORK_DEVICE $dev
return $SUCCESS
fi
fi
done
f_interactive && f_dialog_msgbox "$msg_no_network_devices"
return $FAILURE
fi # $network_dev
f_device_find "" $DEVICE_TYPE_NETWORK devs
cnt=$( set -- $devs; echo $# )
dev="${devs%%[$IFS]*}"
f_quietly f_getvar NETWORK_CONFIGURED # for debugging info
if ! f_running_as_init &&
! [ "${NETWORK_CONFIGURED+set}" -a "$NETWORK_CONFIGURED" = "NO" ]
then
trap 'f_interrupt' SIGINT
if f_dialog_yesno "$msg_assume_network_is_already_configured"
then
setvar $VAR_NETWORK_DEVICE $dev
return $SUCCESS
fi
fi
local retval=$SUCCESS
if [ ${cnt:=0} -eq 0 ]; then
f_dialog_msgbox "$msg_no_network_devices"
retval=$FAILURE
elif [ $cnt -eq 1 ]; then
f_device_dialog_tcp $dev
retval=$?
[ $retval -eq $SUCCESS ] && setvar $VAR_NETWORK_DEVICE $dev
else
local title="$msg_network_interface_information_required"
local prompt="$msg_please_select_ethernet_device_to_configure"
local hline="$hline_arrows_tab_enter"
dev=$( f_device_menu \
"$title" "$prompt" "$hline" $DEVICE_TYPE_NETWORK \
"$NETWORK_DEVICE_HELPFILE" \
2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
retval=$?
[ "$dev" ] || return $FAILURE
f_device_find "$dev" $DEVICE_TYPE_NETWORK devs
[ "$devs" ] || return $FAILURE
dev="${devs%%[$IFS]*}"
f_device_dialog_tcp $dev
retval=$?
if [ $retval -eq $SUCCESS ]; then
f_struct_copy device_$dev device_network
setvar $VAR_NETWORK_DEVICE network
else
f_struct_free device_network
fi
fi
return $retval
}
# f_dialog_menu_select_tcp
#
# Like f_dialog_select_tcp() above, but do it from a menu that doesn't care
# about status. In other words, where f_dialog_select_tcp() will not display a
# menu if scripted, this function will always display the menu of available
# network interfaces.
#
f_dialog_menu_select_tcp()
{
local private use_dhcp name
NETWORK_CONFIGURED=NO f_device_select_tcp
if f_struct device_network &&
device_network get private private &&
f_struct_copy "$private" di &&
di get use_dhcp use_dhcp &&
[ ! "$use_dhcp" ] &&
device_network get name name &&
f_yesno "$msg_would_you_like_to_bring_interface_up" "$name"
then
if ! f_device_init network; then
f_show_msg "$msg_initialization_of_device_failed" \
"$name"
fi
fi
return $SUCCESS
}
############################################################ MAIN
f_dprintf "%s: Successfully loaded." media/tcpip.subr
fi # ! $_MEDIA_TCPIP_SUBR