svn commit: r252112 - in head/usr.sbin/bsdconfig: include share share/media

Devin Teske dteske at FreeBSD.org
Sun Jun 23 10:48:28 UTC 2013


Author: dteske
Date: Sun Jun 23 10:48:26 2013
New Revision: 252112
URL: http://svnweb.freebsd.org/changeset/base/252112

Log:
  Merge r248313 from stable/9 sysinstall(8) to head bsdconfig(8):
  Add support for installation directly via HTTP.
  
  While we're here, remove the menu-item for Passive FTP (since moving to
  ftp(1) and switching FTPMODE to `auto' by default -- see r251613 -- the
  single remaining FTP menu-item works for both ftp.f.o and ftp-archive.f.o;
  previously each requiring separately active versus passive both work with
  the `auto' setting). In scripting you still have mediaSetFTPActive and
  mediaSetFTPPassive but the remaining FTP menu-item uses mediaSetFTP which
  defaults to `auto' (aforementioned SVN r251613).

Added:
  head/usr.sbin/bsdconfig/share/media/http.subr   (contents, props changed)
Modified:
  head/usr.sbin/bsdconfig/include/media.hlp
  head/usr.sbin/bsdconfig/include/messages.subr
  head/usr.sbin/bsdconfig/share/device.subr
  head/usr.sbin/bsdconfig/share/media/Makefile
  head/usr.sbin/bsdconfig/share/media/any.subr
  head/usr.sbin/bsdconfig/share/media/options.subr
  head/usr.sbin/bsdconfig/share/script.subr
  head/usr.sbin/bsdconfig/share/variable.subr

Modified: head/usr.sbin/bsdconfig/include/media.hlp
==============================================================================
--- head/usr.sbin/bsdconfig/include/media.hlp	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/include/media.hlp	Sun Jun 23 10:48:26 2013	(r252112)
@@ -25,13 +25,11 @@ You can install from the following types
 
    FTP      Get the distribution files from an anonymous ftp server
             (you will be presented with a list).  Please note that
-            you may invoke FTP in "Active" mode, "Passive" mode, or
+            you may invoke FTP in "Active"/"Passive" auto-mode, or
             via an HTTP proxy.
 
-            Active mode is the standard way of fetching files and
-            Passive mode is for use when you're behind a firewall or
-            some other security mechanism that blocks active FTP
-            connections.  Using an HTTP proxy is sometimes necessary
+            By default, ftp(1) will automatically use the best mode
+            for the server.  Using an HTTP proxy is sometimes necessary
             for firewalls which block all FTP connections.
 
             If you chose to enter your own URL in the FTP menu, please
@@ -41,6 +39,14 @@ You can install from the following types
             Options screen.
 
 
+   HTTP Direct
+            Get the distribution files directly from an HTTP server.
+
+            If you chose to enter your own URL in the HTTP Direct menu,
+            please note that all paths are *relative* to the root
+            directory of the web server.
+
+
    NFS      Get the distribution files from an NFS server somewhere
             (make sure that permissions on the server allow this!).
             If this install method hangs on you or refuses to work

Modified: head/usr.sbin/bsdconfig/include/messages.subr
==============================================================================
--- head/usr.sbin/bsdconfig/include/messages.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/include/messages.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -87,6 +87,7 @@ msg_could_not_unmount_the_nfs_partition=
 msg_could_not_unmount_the_ufs_partition="Could not unmount the UFS partition from %s: %s"
 msg_couldnt_connect_to_ftp_server="Couldn't connect to FTP server"
 msg_couldnt_connect_to_proxy="Couldn't connect to proxy"
+msg_couldnt_connect_to_server="Couldn't connect to server"
 msg_couldnt_open_ftp_connection="Couldn't open FTP connection to %s:\n  %s."
 msg_created_path="Created %s"
 msg_croatia="Croatia"
@@ -148,7 +149,7 @@ msg_hebrew_desc="Ported software for Heb
 msg_help="Help"
 msg_host_name_including_domain="Host name (including domain)"
 msg_hostname_variable_not_set="WARNING: hostname variable not set and is a non-optional\nparameter.  Please add this to your installation script\nor set the netInteractive variable (see bsdconfig man page)"
-msg_http="HTTP"
+msg_http_direct="HTTP Direct"
 msg_http_proxy="HTTP Proxy"
 msg_hungarian_desc="Ported software for the Hungarian market."
 msg_hungary="Hungary"
@@ -161,6 +162,7 @@ msg_install_from_a_usb_drive="Install fr
 msg_install_from_an_ftp_server="Install from an FTP server"
 msg_install_from_an_ftp_server_thru_firewall="Install from an FTP server through a firewall"
 msg_install_from_an_ftp_server_thru_proxy="Install from an FTP server through an HTTP proxy"
+msg_install_from_an_http_server="Install from an HTTP server"
 msg_install_from_the_existing_filesystem="Install from the existing filesystem"
 msg_install_over_nfs="Install over NFS"
 msg_installed="Installed"
@@ -270,6 +272,7 @@ msg_please_select_a_category_to_display=
 msg_please_select_a_cd_dvd_drive="FreeBSD can be installed directly from a CD/DVD containing a valid\nFreeBSD distribution.  If you are seeing this menu it is because\nmore than one CD/DVD drive was found on your system.  Please select\none of the following CD/DVD drives as your installation drive."
 msg_please_select_a_floppy_drive="You have more than one floppy drive.  Please choose which drive\nyou would like to use."
 msg_please_select_a_freebsd_ftp_distribution_site="Please select a FreeBSD FTP distribution site"
+msg_please_select_a_freebsd_http_distribution_site="Please select a FreeBSD HTTP distribution site"
 msg_please_select_a_usb_drive="You have more than one USB drive. Please choose which drive\nyou would like to use."
 msg_please_select_dos_partition="FreeBSD can be installed directly from a DOS partition assuming,\nof course, that you have copied the relevant distributions into\nyour DOS partition before starting this installation.  If this is\nnot the case then you should reboot DOS at this time and copy the\ndistributions you wish to install into a \"FREEBSD\" subdirectory\non one of your DOS partitions.  Otherwise, please select the DOS\npartition containing the FreeBSD distribution files."
 msg_please_select_ethernet_device_to_configure="Please select the ethernet or PLIP device to configure."
@@ -280,6 +283,7 @@ msg_please_specify_the_name_of_the_text_
 msg_please_specify_the_number_of_seconds_to_wait="Please specify the number of seconds to wait for slow media:"
 msg_please_specify_the_release_you_wish_to_load="Please specify the release you wish to load or\n\"any\" for a generic release install:"
 msg_please_specify_url_of_a_freebsd_distribution="Please specify the URL of a FreeBSD distribution on a\nremote ftp site.  This site must accept either anonymous\nftp or you should have set an ftp username and password\nin the Options screen.\n\nA URL looks like this:  ftp://<hostname>/<path>\nWhere <path> is relative to the anonymous ftp directory or the\nhome directory of the user being logged in as."
+msg_please_specify_url_of_freebsd_http_distribution="Please specify the URL of a FreeBSD distribution on a\nremote http site.\nA URL looks like this:  http://<hostname>/<path>"
 msg_poland="Poland"
 msg_polish_desc="Ported software for the Polish market."
 msg_ports_mgmt_desc="Utilities for managing ports and packages."
@@ -302,6 +306,7 @@ msg_rescan_devices="Re-scan Devices"
 msg_reset="RESET!"
 msg_reset_all_values_to_startup_defaults="Reset all values to startup defaults"
 msg_reuse_old_ftp_site_selection_values="Re-use old FTP site selection values?"
+msg_reuse_old_http_site_settings="Re-use old HTTP site settings?"
 msg_review="Review"
 msg_review_desc="Review/perform pending actions"
 msg_review_help="Install, Re-Install, or Un-install selected packages and dependencies"
@@ -334,6 +339,7 @@ msg_south_africa="South Africa"
 msg_spain="Spain"
 msg_spanish_desc="Ported software for the Spanish market."
 msg_specify_some_other_ftp_site="Specify some other ftp site by URL"
+msg_specify_some_other_http_site="Specify some other http site by URL"
 msg_sweden="Sweden"
 msg_switzerland="Switzerland"
 msg_sysutils_desc="Various system utilities."

Modified: head/usr.sbin/bsdconfig/share/device.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/device.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/device.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -73,6 +73,7 @@ setvar DEVICE_TYPE_UFS		9
 setvar DEVICE_TYPE_NFS		10
 setvar DEVICE_TYPE_ANY		11
 setvar DEVICE_TYPE_HTTP_PROXY	12
+setvar DEVICE_TYPE_HTTP		13
 
 #
 # Default behavior is to call f_device_get_all() automatically when loaded.

Modified: head/usr.sbin/bsdconfig/share/media/Makefile
==============================================================================
--- head/usr.sbin/bsdconfig/share/media/Makefile	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/media/Makefile	Sun Jun 23 10:48:26 2013	(r252112)
@@ -4,8 +4,8 @@ NO_OBJ=
 
 FILESDIR=	${SHAREDIR}/bsdconfig/media
 FILES=		any.subr cdrom.subr common.subr directory.subr dos.subr \
-		floppy.subr ftp.subr httpproxy.subr network.subr nfs.subr \
-		options.subr tcpip.subr ufs.subr usb.subr
+		floppy.subr ftp.subr http.subr httpproxy.subr network.subr \
+		nfs.subr options.subr tcpip.subr ufs.subr usb.subr
 
 beforeinstall:
 	mkdir -p ${DESTDIR}${FILESDIR}

Modified: head/usr.sbin/bsdconfig/share/media/any.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/media/any.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/media/any.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -37,6 +37,7 @@ f_include $BSDCFG_SHARE/media/directory.
 f_include $BSDCFG_SHARE/media/dos.subr
 f_include $BSDCFG_SHARE/media/floppy.subr
 f_include $BSDCFG_SHARE/media/ftp.subr
+f_include $BSDCFG_SHARE/media/http.subr
 f_include $BSDCFG_SHARE/media/httpproxy.subr
 f_include $BSDCFG_SHARE/media/nfs.subr
 f_include $BSDCFG_SHARE/media/options.subr
@@ -71,9 +72,9 @@ f_media_get_type()
 	local menu_list="
 		'1 $msg_cd_dvd'    '$msg_install_from_a_freebsd_cd_dvd'
 		'2 $msg_ftp'       '$msg_install_from_an_ftp_server'
-		'3 $msg_ftp_passive'
-		                '$msg_install_from_an_ftp_server_thru_firewall'
-		'4 $msg_http'      '$msg_install_from_an_ftp_server_thru_proxy'
+		'3 $msg_http_proxy'
+		                '$msg_install_from_an_ftp_server_thru_proxy'
+		'4 $msg_http_direct' '$msg_install_from_an_http_server'
 		'5 $msg_directory' '$msg_install_from_the_existing_filesystem'
 		'6 $msg_nfs'       '$msg_install_over_nfs'
 		'7 $msg_dos'       '$msg_install_from_a_dos_partition'
@@ -123,8 +124,8 @@ f_media_get_type()
 		case "$mtag" in
 		?" $msg_cd_dvd")      f_media_set_cdrom ;;
 		?" $msg_ftp")         f_media_set_ftp ;;
-		?" $msg_ftp_passive") f_media_set_ftp_passive ;;
-		?" $msg_http")        f_media_set_http_proxy ;;
+		?" $msg_http_proxy")  f_media_set_http_proxy ;;
+		?" $msg_http_direct") f_media_set_http ;;
 		?" $msg_directory")   f_media_set_directory ;;
 		?" $msg_dos")         f_media_set_dos ;;
 		?" $msg_nfs")         f_media_set_nfs ;;

Added: head/usr.sbin/bsdconfig/share/media/http.subr
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsdconfig/share/media/http.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -0,0 +1,635 @@
+if [ ! "$_MEDIA_HTTP_SUBR" ]; then _MEDIA_HTTP_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/http.subr
+f_include $BSDCFG_SHARE/device.subr
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/media/common.subr
+f_include $BSDCFG_SHARE/media/tcpip.subr
+f_include $BSDCFG_SHARE/strings.subr
+f_include $BSDCFG_SHARE/struct.subr
+f_include $BSDCFG_SHARE/variable.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig"
+f_include_lang $BSDCFG_LIBE/include/messages.subr
+
+############################################################ GLOBALS
+
+HTTP_SKIP_RESOLV=
+
+URL_MAX=261261
+	# NOTE: This is according to actual fetch(1) test-results. We actually
+	# use nc(1) to retrieve files, but it's still a good idea to keep the
+	# URLs short enough that fetch(1) won't complain.
+
+HTTP_DIRS="
+	.
+	releases/$UNAME_P
+	snapshots/$UNAME_P
+	pub/FreeBSD
+	pub/FreeBSD/releases/$UNAME_P
+	pub/FreeBSD/snapshots/$UNAME_P
+	pub/FreeBSD-Archive/old-releases/$UNAME_P
+" # END-QUOTE
+
+############################################################ FUNCTIONS
+
+# f_dialog_menu_media_http
+#
+# Prompt the user to select from a range of ``built-in'' HTTP servers or
+# specify their own. If the user makes a choice and doesn't cancel or press
+# Esc, stores the user's choice in VAR_FTP_PATH (see variable.subr) and returns
+# success.
+#
+f_dialog_menu_media_http()
+{
+	f_dialog_title "$msg_please_select_a_freebsd_http_distribution_site"
+	local title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
+	f_dialog_title_restore
+	local prompt="$msg_please_select_the_site_closest_to_you_or_other"
+	local menu_list="
+		'URL' '$msg_specify_some_other_http_site'
+	" # END-QUOTE
+	local hline="$msg_select_a_site_thats_close"
+
+	local height width rows
+	eval f_dialog_menu_size height width rows \
+	                        \"\$title\"  \
+	                        \"\$btitle\" \
+	                        \"\$prompt\" \
+	                        \"\$hline\"  \
+	                        $menu_list
+
+	local mtag
+	mtag=$( eval $DIALOG \
+		--title \"\$title\"             \
+		--backtitle \"\$btitle\"        \
+		--hline \"\$hline\"             \
+		--ok-label \"\$msg_ok\"         \
+		--cancel-label \"\$msg_cancel\" \
+		--menu \"\$prompt\"             \
+		$height $width $rows            \
+		$menu_list                      \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	) || return $FAILURE
+	f_dialog_data_sanitize mtag
+
+	case "$mtag" in
+	URL) setvar $VAR_HTTP_PATH "other" ;;
+	*)
+		local value
+		value=$( eval f_dialog_menutag2item \"\$mtag\" $menu_list )
+		setvar $VAR_HTTP_PATH "http://$value"
+	esac
+	
+	return $SUCCESS
+}
+
+# f_media_set_http
+#
+# Return success if we both found and set the media type to be an HTTP server.
+#
+# Variables from variable.subr that can be used to script user input:
+#
+# 	VAR_HTTP_PATH
+# 		URL containing host and optionally a target path to the release
+# 		repository on the HTTP server. Valid examples include:
+# 			http://myhost
+# 			http://somename:80/pub/
+# 			http://192.168.2.3/pub/
+# 			http://[::1]:8000/
+# 		The default port if not specified is 80.
+# 	VAR_NAMESERVER [Optional]
+# 		If set, overrides resolv.conf(5) and sets the nameserver that
+# 		is used to convert names into addresses (when a name converts
+# 		into multiple addresses, the first address to successfully
+# 		connect is used).
+#
+# Meanwhile, the following variables from variable.subr are set after
+# successful execution:
+#
+# 	VAR_HTTP_HOST
+# 		The HTTP host to connect to, parsed from VAR_HTTP_PATH. In the
+# 		example case of IPv6 where VAR_HTTP_PATH is "http://[::1]" this
+# 		variable will be set to "::1" (the outer brackets are removed).
+# 	VAR_HTTP_PORT
+# 		The TCP port to connect to, parsed from VAR_HTTP_PATH. Usually
+# 		80 unless VAR_HTTP_PATH was one of the following forms:
+# 			http://hostname:OTHER_PORT
+# 			http://hostname:OTHER_PORT/*
+# 			http://ip:OTHER_PORT
+# 			http://ip:OTHER_PORT/*
+# 			http://[ip6]:OTHER_PORT
+# 			http://[ip6]:OTHER_PORT/*
+# 	VAR_HTTP_DIR
+# 		If VAR_HTTP_PATH contained a directory element (e.g.,
+# 		"http://localhost/pub") this variable contains only the
+# 		directory element (e.g., "/pub").
+#
+f_media_set_http()
+{
+	f_media_close
+
+	local url
+	f_getvar $VAR_HTTP_PATH url
+
+	# If we've been through here before ...
+	if f_struct device_network && [ "${url#$msg_other}" ]; then
+		f_dialog_yesno "$msg_reuse_old_http_site_settings" || url=
+	fi
+
+	if [ ! "$url" ]; then
+		f_dialog_menu_media_http || return $FAILURE
+		f_getvar $VAR_HTTP_PATH url
+	fi
+	[ "$url" ] || return $FAILURE
+
+	case "$url" in
+	other)
+		setvar $VAR_HTTP_PATH "http://"
+		f_variable_get_value $VAR_HTTP_PATH \
+			"$msg_please_specify_url_of_freebsd_http_distribution"
+		f_getvar $VAR_HTTP_PATH url
+		if [ ! "${url#http://}" ]; then
+			unset $VAR_HTTP_PATH
+			return $FAILURE
+		fi
+		if [ ${#url} -gt ${URL_MAX:-261261} ]; then
+			f_show_msg "$msg_length_of_specified_url_is_too_long" \
+			           ${#url} ${URL_MAX:-261261}
+			unset $VAR_HTTP_PATH
+			return $FAILURE
+		fi
+		case "$url" in
+		http://*) : valid URL ;;
+		*)
+			f_show_msg "$msg_sorry_invalid_url" "$url"
+			unset $VAR_HTTP_PATH
+			return $FAILURE
+		esac
+	esac
+	case "$url" in
+	http://*) : valid URL ;;
+	*)
+		f_show_msg "$msg_sorry_invalid_url" "$url"
+		unset $VAR_HTTP_PATH
+		return $FAILURE
+	esac
+
+	# Set the name of the HTTP device to the URL
+	f_struct_new DEVICE device_http
+	device_http set name "$url"
+
+	if ! f_struct device_network ||
+	   ! f_dialog_yesno "$msg_youve_already_done_the_network_configuration"
+	then
+		f_struct device_network &&
+			f_device_shutdown network
+		if ! f_device_select_tcp; then
+			unset $VAR_HTTP_PATH
+			return $FAILURE
+		fi
+		local dev
+		f_getvar $VAR_NETWORK_DEVICE dev
+		f_struct_copy "device_$dev" device_network
+	fi
+	if ! f_device_init network; then
+		f_dprintf "f_media_set_http: %s" "$msg_net_device_init_failed"
+		unset $VAR_HTTP_PATH
+		return $FAILURE
+	fi
+
+	local hostname="${url#*://}" port=80 dir=/
+	case "$hostname" in
+	#
+	# The order in-which the below individual cases appear is important!
+	#
+	"["*"]":*/*) # IPv6 address with port and directory
+		f_dprintf "Looks like an IPv6 addr with port/dir: %s" \
+		          "$hostname"
+		hostname="${hostname#\[}"
+		port="${hostname#*\]:}"
+		port="${port%%[!0-9]*}"
+		dir="/${hostname#*/}"
+		hostname="${hostname%%\]:*}"
+		;;
+	"["*"]":*) # IPv6 address with port
+		f_dprintf "Looks like an IPv6 addr with port: %s" "$hostname"
+		hostname="${hostname#\[}"
+		port="${hostname#*\]:}"
+		port="${port%%[!0-9]*}"
+		hostname="${hostname%%\]:*}"
+		;;
+	"["*"]"/*) # IPv6 address with directory
+		f_dprintf "Looks like an IPv6 addr with dir: %s" "$hostname"
+		hostname="${hostname#\[}"
+		dir="/${hostname#*/}"
+		hostname="${hostname%%\]*}"
+		;;
+	"["*"]") # IPv6 address
+		f_dprintf "Looks like an IPv6 addr: %s" "$hostname"
+		hostname="${hostname#\[}"
+		hostname="${hostname%\]}"
+		;;
+	#
+	# ^^^ IPv6 above / DNS Name or IPv4 below vvv
+	#
+	*:*/*) # DNS name or IPv4 address with port and directory
+		f_dprintf "Looks like a %s with port/dir: %s" \
+		          "DNS name or IPv4 addr" "$hostname"
+		port="${hostname#*:}"
+		port="${port%%[!0-9]*}"
+		dir="/${hostname#*/}"
+		hostname="${hostname%%:*}"
+		;;
+	*:*) # DNS name or IPv4 address with port
+		f_dprintf "Looks like a DNS name or IPv4 addr with port: %s" \
+		          "$hostname"
+		port="${hostname#*:}"
+		hostname="${hostname%%:*}"
+		;;
+	*/*) # DNS name or IPv4 address with directory
+		f_dprintf "Looks like a DNS name or IPv4 addr with dir: %s" \
+		          "$hostname"
+		dir="/${hostname#*/}"
+		hostname="${hostname%%/*}"
+		;;
+	*) # DNS name or IPv4 address
+		f_dprintf "Looks like a DNS name or IPv4 addr: %s" "$hostname"
+		: leave hostname as-is
+	esac
+
+	f_dprintf "hostname = \`%s'" "$hostname"
+	f_dprintf "dir = \`%s'" "$dir"
+	f_dprintf "port \# = \`%d'" "$port"
+
+	local ns
+	f_getvar $VAR_NAMESERVER ns
+	[ "$ns" ] || f_resolv_conf_nameservers ns
+	if [ "$ns" -a ! "$HTTP_SKIP_RESOLV" ] && ! {
+		f_validate_ipaddr "$hostname" ||
+		f_validate_ipaddr6 "$hostname"
+	}; then
+		f_show_info "$msg_looking_up_host" "$hostname"
+		f_dprintf "%s: Looking up hostname, %s, using host(1)" \
+		          "f_media_set_http" "$hostname"
+		if ! f_quietly f_host_lookup "$hostname"; then
+			f_show_msg "$msg_cannot_resolve_hostname" "$hostname"
+			f_struct device_network &&
+				f_device_shutdown network
+			f_struct_free device_network
+			unset $VAR_HTTP_PATH
+			return $FAILURE
+		fi
+		f_dprintf "Found DNS entry for %s successfully." "$hostname"
+	fi
+
+	setvar $VAR_HTTP_HOST "$hostname"
+	setvar $VAR_HTTP_PORT "$port"
+	setvar $VAR_HTTP_DIR  "$dir"
+
+	device_http set type     $DEVICE_TYPE_HTTP
+	device_http set init     f_media_init_http
+	device_http set get      f_media_get_http
+	device_http set shutdown f_media_shutdown_http
+	device_http set private  network
+	f_struct_copy device_http device_media
+	f_struct_free device_http
+
+	return $SUCCESS
+}
+
+# f_http_check_access [$connect_only]
+#
+# Return success if able list a remote HTTP directory. If $connect_only is
+# present and non-null, then returns success if a connection can be made.
+# Variables from variable.subr that can be used to script user input:
+#
+# 	VAR_HTTP_HOST
+# 		The HTTP server host name, IPv4 address or IPv6 address.
+# 		Valid examples include:
+# 			myhost
+# 			192.168.2.3
+# 			::1
+# 	VAR_HTTP_PORT
+# 		The TCP port to connect to when communicating with the server.
+# 	VAR_HTTP_PATH
+# 		The HTTP path sent to the server. Unused if $connect_only is
+# 		present and non-NULL.
+#
+f_http_check_access()
+{
+	local connect_only="$1" hosts=
+
+	local http_host http_port
+	f_getvar $VAR_HTTP_HOST http_host
+	f_getvar $VAR_HTTP_PORT http_port
+
+	if ! {
+		f_validate_ipaddr "$http_host" ||
+		f_validate_ipaddr6 "$http_host" ||
+		{
+		  f_dprintf "%s: Looking up hostname, %s, using host(1)" \
+		            "f_http_check_access" "$http_host"
+		  f_host_lookup "$http_host" hosts
+		}
+	}; then
+		# All the above validations failed
+		[ "$hosts" ] && f_dialog_msgbox "$hosts"
+		unset $VAR_HTTP_HOST
+		return $FAILURE
+	elif [ ! "$hosts" ]; then
+		# One of the first two validations passed
+		hosts="$http_host"
+	fi
+
+	local host connected=
+	for host in $hosts; do
+		f_quietly nc -nz "$host" "$http_port" || continue
+		connected=1; break
+	done
+	if [ ! "$connected" ]; then
+		f_show_msg "$msg_couldnt_connect_to_server http://%s:%s/" \
+		           "$http_host" "$http_port"
+		unset $VAR_HTTP_HOST
+		return $FAILURE
+	fi
+	[ "$connect_only" ] && return $SUCCESS
+
+	local http_path
+	f_getvar $VAR_HTTP_PATH http_path
+	f_show_info "$msg_checking_access_to" "$http_path"
+
+	local rx
+	if ! rx=$(
+		printf "GET /%s/ HTTP/1.0\r\n\r\n" "${http_path%/}" |
+			nc -n "$host" "$http_port"
+	); then
+		f_show_msg "$msg_couldnt_connect_to_server http://%s:%s/" \
+		           "$http_host" "$http_port"
+		unset $VAR_HTTP_HOST
+		return $FAILURE
+	fi
+
+	local hdr
+	hdr=$( echo "$rx" | awk '/^\r$/{exit}{print}' )
+
+	local http_found=$FAILURE
+	if echo "$hdr" | awk '
+		BEGIN { found = 0 }
+		/^HTTP.... 200 / {
+			found = 1
+			exit
+		}
+		END { exit ! found }
+	'; then
+		http_found=$SUCCESS
+	fi
+
+	return $http_found
+}
+
+# f_media_init_http $device
+#
+# Initializes the HTTP media device. Returns success if able to confirm the
+# existence of at least one known HTTP server release path directly via HTTP
+# using f_http_check_access(), above.
+#
+# Variables from variable.subr that can be used to script user input:
+#
+# 	VAR_HTTP_HOST
+#		The HTTP server to connect to. Must be set. Also see
+# 		f_http_check_access() for additional variables.
+# 	VAR_RELNAME
+# 		Usually set to `uname -r' but can be overridden.
+# 	VAR_HTTP_PATH
+# 		The HTTP path sent to the server. Usually set by calling
+# 		f_media_set_http().
+#
+# Meanwhile, after successful execution, the following variables (also from
+# variable.subr) are set:
+#
+# 	VAR_HTTP_PATH
+# 		The [possibly] adjusted VAR_HTTP_PATH that was found to contain
+# 		a valid FreeBSD repository.
+#
+f_media_init_http()
+{
+	local dev="$1"
+	f_dprintf "Init routine called for HTTP device. dev=[%s]" "$dev"
+
+	#
+	# First verify access
+	#
+	local connect_only=1
+	f_http_check_access $connect_only
+
+	local http_host
+	f_getvar $VAR_HTTP_HOST http_host
+	while [ ! "$http_host" ]; do
+		f_media_set_http || return $FAILURE
+		f_http_check_access $connect_only
+		f_getvar $VAR_HTTP_HOST http_host
+	done
+
+	local http_path http_found=$FAILURE
+	while :; do
+		#
+		# Now that we've verified that the path we're given is ok,
+		# let's try to be a bit intelligent in locating the release we
+		# are looking for.  First off, if the release is specified as
+		# "__RELEASE" or "any", then just assume that the current
+		# directory is the one we want and give up.
+		#
+		local rel
+		f_getvar $VAR_RELNAME rel
+		f_dprintf "f_media_init_http: rel=[%s]" "$rel"
+
+		case "$rel" in
+		__RELEASE|any)
+			setvar $VAR_HTTP_PATH "$VAR_HTTP_DIR"
+			f_http_check_access
+			http_found=$?
+			;;
+		*)
+			#
+			# Ok, since we have a release variable, let's walk
+			# through the list of directories looking for a release
+			# directory. First successful path wins.
+			#
+			local fdir hp
+			f_getvar $VAR_HTTP_PATH%/ hp
+			for fdir in $HTTP_DIRS; do
+				setvar $VAR_HTTP_PATH "$hp/$fdir/$rel"
+				if f_http_check_access; then
+					http_found=$SUCCESS
+					break
+				fi
+			done
+		esac
+
+		[ $http_found -eq $SUCCESS ] && break
+
+		f_getvar $VAR_HTTP_PATH http_path
+		f_show_msg "$msg_please_check_the_url_and_try_again" \
+		           "$http_path"
+
+		unset $VAR_HTTP_PATH
+		f_media_set_http || break
+	done
+
+	return $http_found
+}
+
+# f_media_get_http $device $file [$probe_only]
+#
+# Returns data from $file on an HTTP server using nc(1). Please note that
+# $device is unused but must be present (even if null). Information is instead
+# gathered from the environment. If $probe_only is both present and non-NULL,
+# this function exits after receiving the HTTP header response from the server
+# (if the HTTP response code is 200, success is returned; otherwise failure).
+#
+# The variables used to configure the connection are as follows (all of which
+# are configured by f_media_set_http above):
+#
+# 	VAR_HTTP_HOST
+# 		HTTP server which to connect. Can be an IPv4 address, IPv6
+# 		address, or DNS hostname of your choice.
+# 	VAR_HTTP_PORT
+# 		TCP port to connect on; see f_media_set_http above.
+# 	VAR_HTTP_PATH
+# 		Directory prefix to use when requesting $file. Default is `/'
+# 		unless f_media_init_http was able to use f_http_check_access
+# 		to validate one of the defaults in $HTTP_DIRS (see GLOBALS at
+# 		the top of this file); assuming VAR_RELNAME was not set to
+# 		either `__RELEASE' or `any' (indicating that the global set of
+# 		$HTTP_DIRS should be ignored).
+#
+# See variable.subr for additional information.
+#
+# Example usage:
+# 	f_media_set_http
+# 	f_media_get_http media $file
+#
+f_media_get_http()
+{
+	local dev="$1" file="$2" probe_only="$3" hosts=
+
+	f_dprintf "f_media_get_http: dev=[%s] file=[%s] probe_only=%s" \
+	          "$dev" "$file" "$probe_only"
+
+	local http_host http_port
+	f_getvar $VAR_HTTP_HOST http_host
+	f_getvar $VAR_HTTP_PORT http_port
+
+	if ! {
+		f_validate_ipaddr "$http_host" ||
+		f_validate_ipaddr6 "$http_host" ||
+		{
+		  f_dprintf "%s: Looking up hostname, %s, using host(1)" \
+		            "f_media_get_http" "$http_host"
+		  f_host_lookup "$http_host" hosts
+		}
+	}; then
+		# All the above validations failed
+		[ "$hosts" ] && f_dialog_msgbox "$hosts"
+		return $FAILURE
+	elif [ ! "$hosts" ]; then
+		# One of the first two validations passed
+		hosts="$http_host"
+	fi
+
+	local host connected=
+	for host in $hosts; do
+		f_quietly nc -nz "$host" "$http_port" || continue
+		connected=1; break
+	done
+	if [ ! "$connected" ]; then
+		f_show_msg "$msg_couldnt_connect_to_server http://%s:%s/" \
+		           "$http_host" "$http_port"
+		return $FAILURE
+	fi
+
+	local http_path
+	f_getvar $VAR_HTTP_PATH%/ http_path
+	local url="/$http_path/$file" rx
+
+	f_dprintf "sending http request for: %s" "$url"
+	printf "GET %s HTTP/1.0\r\n\r\n" "$url" | nc -n "$host" "$http_port" |
+	(
+		#
+		# scan the headers of the response
+		# this is extremely quick'n dirty
+		#
+
+		rv=0
+		while read LINE; do
+			case "$LINE" in
+			HTTP*)
+				f_dprintf "received response: %s" "$LINE"
+				set -- $LINE; rv=$2
+				f_isinteger "$rv" || rv=0
+				;;
+			*)
+				[ "${LINE%
}" ] || break # End of headers
+			esac
+		done
+
+		[ $rv -ge 500 ] && exit 5
+		[ $rv -eq 404 ] && exit 44
+		[ $rv -ge 400 ] && exit 4
+		[ $rv -ge 300 ] && exit 3
+		[ $rv -eq 200 ] || exit $FAILURE
+
+		if [ ! "$probe_only" ]; then
+			cat # output the rest ``as-is''
+		fi
+		exit 200
+	)
+	local retval=$?
+	[ $retval -eq 200 ] && return $SUCCESS
+	[ "$probe_only" ] && return $FAILURE
+
+	case "$retval" in
+	  5) f_show_msg "$msg_server_error_when_requesting_url" "$url" ;;
+	 44) f_show_msg "$msg_url_was_not_found" "$url" ;;
+	  4) f_show_msg "$msg_client_error" ;;
+	  *) f_show_msg "$msg_error_when_requesting_url" "$url" ;;
+	esac
+	return $FAILURE
+}
+
+############################################################ MAIN
+
+f_dprintf "%s: Successfully loaded." media/http.subr
+
+fi # ! $_MEDIA_HTTP_SUBR

Modified: head/usr.sbin/bsdconfig/share/media/options.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/media/options.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/media/options.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -158,14 +158,15 @@ f_media_options_menu()
 			case "$cp" in
 			$DEVICE_TYPE_UFS|$DEVICE_TYPE_DISK)
 				cp="$msg_file_system" ;;
-			$DEVICE_TYPE_DIRECTORY)  cp="$msg_directory"  ;;
-			$DEVICE_TYPE_FLOPPY)     cp="$msg_floppy"     ;;
-			$DEVICE_TYPE_FTP)        cp="$msg_ftp"        ;;
-			$DEVICE_TYPE_HTTP_PROXY) cp="$msg_http_proxy" ;;
-			$DEVICE_TYPE_CDROM)      cp="$msg_cdrom"      ;;
-			$DEVICE_TYPE_USB)        cp="$msg_usb"        ;;
-			$DEVICE_TYPE_DOS)        cp="$msg_dos"        ;;
-			$DEVICE_TYPE_NFS)        cp="$msg_nfs"        ;;
+			$DEVICE_TYPE_DIRECTORY)  cp="$msg_directory"   ;;
+			$DEVICE_TYPE_FLOPPY)     cp="$msg_floppy"      ;;
+			$DEVICE_TYPE_FTP)        cp="$msg_ftp"         ;;
+			$DEVICE_TYPE_HTTP_PROXY) cp="$msg_http_proxy"  ;;
+			$DEVICE_TYPE_HTTP)       cp="$msg_http_direct" ;;
+			$DEVICE_TYPE_CDROM)      cp="$msg_cdrom"       ;;
+			$DEVICE_TYPE_USB)        cp="$msg_usb"         ;;
+			$DEVICE_TYPE_DOS)        cp="$msg_dos"         ;;
+			$DEVICE_TYPE_NFS)        cp="$msg_nfs"         ;;
 			*)
 				cp="<$msg_unknown>"
 			esac

Modified: head/usr.sbin/bsdconfig/share/script.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/script.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/script.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -181,8 +181,10 @@ f_resword_new mediaSetFTPActive		f_media
 f_resword_new mediaSetFTPPassive	f_media_set_ftp_passive
 f_resword_new mediaSetFTPUserPass	f_media_set_ftp_userpass
 
+# media/http.subr
+f_resword_new mediaSetHTTP	f_media_set_http
+
 # media/httpproxy.subr
-f_resword_new mediaSetHTTP	f_media_set_http_proxy
 f_resword_new mediaSetHTTPProxy	f_media_set_http_proxy
 
 # packages/packages.subr

Modified: head/usr.sbin/bsdconfig/share/variable.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/variable.subr	Sun Jun 23 10:16:14 2013	(r252111)
+++ head/usr.sbin/bsdconfig/share/variable.subr	Sun Jun 23 10:48:26 2013	(r252112)
@@ -204,7 +204,11 @@ f_variable_new VAR_FTP_STATE		ftpState
 f_variable_new VAR_FTP_USER		ftpUser
 f_variable_new VAR_GATEWAY		defaultrouter
 f_variable_new VAR_HOSTNAME		hostname
+f_variable_new VAR_HTTP_DIR		httpDirectory
 f_variable_new VAR_HTTP_FTP_MODE	httpFtpMode
+f_variable_new VAR_HTTP_HOST		httpHost
+f_variable_new VAR_HTTP_PATH		_httpPath
+f_variable_new VAR_HTTP_PORT		httpPort
 f_variable_new VAR_HTTP_PROXY		httpProxy
 f_variable_new VAR_HTTP_PROXY_HOST	httpProxyHost
 f_variable_new VAR_HTTP_PROXY_PATH	_httpProxyPath


More information about the svn-src-head mailing list