Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Jul 2014 23:10:12 +0000 (UTC)
From:      Devin Teske <dteske@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r268999 - in head/usr.sbin/bsdconfig: examples include share share/media share/packages
Message-ID:  <201407222310.s6MNACJM060347@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dteske
Date: Tue Jul 22 23:10:12 2014
New Revision: 268999
URL: http://svnweb.freebsd.org/changeset/base/268999

Log:
  Add example script `add_some_packages.sh', demonstrating how to install
  a list of packages using the bsdconfig(8) API, providing dialog(8) based
  user experience (versus plain console output were you to use pkg(8)
  directly to install the same list of packages).
  
  Remove example script `browse_packages_ftp.sh', made obsolete because
  the digests.txz and packagesite.txz databases for pkg(8) are not
  available via FTP (HTTP only to pkg.freebsd.org SRV hosts).
  
  Update example script `browse_packages_http.sh', made to work with new
  pkg(8) demonstrating how to generate a local package repository.
  
  Fix a bug in `bsdconfig packages' where packages were listed twice. This
  fix requires pkg(8) version 1.2.7_4 or higher.
  
  NB: It is the introduction of pkg(8) 1.2.7_4 wherein I am also able to
  drastically reduce the generation time of package dependencies prior to
  the dialog display (by utilizing the new `-I' flag to pkg-rquery(8)).
  
  While here, fix a positional argument nit for f_index_initialize() of
  `packages/index.subr' include (the one and only argument is positional
  argument 1 to state the by-ref handle, indicating the variable to set
  in the caller's namespace; the nit I'm fixing here is that we were
  querying positional argument 2 for this information incorrectly; caused
  by a missing hunk back around SVN r257795).
  
  Fix a bug in sysrc(8) described by PR bin/187458 "sysrc(8) silently and
  unexpectedly bootstraps pkg". This was caused by an explicit entry in
  `/usr/share/bsdconfig/common.subr' (used by sysrc(8)) that called pkg(8)
  to populate the $PKG_ABI global (called in a way that allows implicit
  bootstrap of pkg(8)). The solution to which was to find every place in
  bsdconfig(8) that requires the $PKG_ABI global and add a layer of
  protection by way of introducing the new API call f_musthavepkg_init()
  (provided by new include, `/usr/share/bsdconfig/packages/musthavepkg.subr'
  intented to mirror `/usr/share/bsdconfig/mustberoot.subr'). When the
  $PKG_ABI global is required, you can use `f_musthavepkg_init' to cause
  graceful premature termination in the event that pkg(8) has not yet been
  bootstrapped, and thus cannot be used to populate $PKG_ABI.
  
  NB: If running interactively ($nonInteractive is NULL or unset), the
  f_musthavepkg_init() API call will attempt to bootstrap pkg(8), but only
  if the user chooses "Yes" to a Yes/No dialog confirming it is ok to
  bootstrap.
  
  While here, simplify an if-conditional in `media/http.subr' include to
  use sh(1) inline assignment-with-break.
  
  Also, fix a bug in `media/http.subr' and `media/httpproxy.subr' wherein
  the error messages for various HTTP failures were not finding their way
  to the console (needed to pass stdout to pass-thru descriptor).
  
  While here, remove the executable bit from `packages/categories.subr',
  `packages/index.subr', and `packages/packages.subr' includes.
  
  Fix issues where pkg(8) complains about PACKAGESITE being defined.
  Previously, we would set $PACKAGESITE and export it. Now we only set
  $PACKAGESITE for invocations of "pkg update" -- getting rid of all the
  spurious warnings about PACKAGESITE being deprecated (it's still used
  in the case of "pkg update" for simplicity versus having to configure
  a config-file).
  
  Remove the leading argument from invocations of f_index_initialize() in
  `packages/packages.subr' include. The leading argument no longer means
  what it used to, pre SVN r257995).
  
  PR:		bin/187458
  Reviewed by:	nwhitehorn
  MFC after:	1 week
  X-MFC-to:	stable/10, stable/9

Added:
  head/usr.sbin/bsdconfig/examples/add_some_packages.sh   (contents, props changed)
  head/usr.sbin/bsdconfig/share/packages/musthavepkg.subr   (contents, props changed)
Deleted:
  head/usr.sbin/bsdconfig/examples/browse_packages_ftp.sh
Modified:
  head/usr.sbin/bsdconfig/examples/Makefile
  head/usr.sbin/bsdconfig/examples/browse_packages_http.sh
  head/usr.sbin/bsdconfig/include/messages.subr
  head/usr.sbin/bsdconfig/share/common.subr
  head/usr.sbin/bsdconfig/share/media/http.subr
  head/usr.sbin/bsdconfig/share/media/httpproxy.subr
  head/usr.sbin/bsdconfig/share/packages/Makefile
  head/usr.sbin/bsdconfig/share/packages/index.subr   (contents, props changed)
  head/usr.sbin/bsdconfig/share/packages/packages.subr   (contents, props changed)
Directory Properties:
  head/usr.sbin/bsdconfig/share/packages/categories.subr   (props changed)

Modified: head/usr.sbin/bsdconfig/examples/Makefile
==============================================================================
--- head/usr.sbin/bsdconfig/examples/Makefile	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/examples/Makefile	Tue Jul 22 23:10:12 2014	(r268999)
@@ -3,7 +3,7 @@
 NO_OBJ=
 
 FILESDIR=	${SHAREDIR}/examples/bsdconfig
-FILES=		browse_packages_ftp.sh browse_packages_http.sh bsdconfigrc
+FILES=		add_some_packages.sh browse_packages_http.sh bsdconfigrc
 
 beforeinstall:
 	mkdir -p ${DESTDIR}${FILESDIR}

Added: head/usr.sbin/bsdconfig/examples/add_some_packages.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsdconfig/examples/add_some_packages.sh	Tue Jul 22 23:10:12 2014	(r268999)
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# This sample installs a short list of packages from the main HTTP site.
+#
+[ "$_SCRIPT_SUBR" ] || . /usr/share/bsdconfig/script.subr || exit 1
+nonInteractive=1
+_httpPath=http://pkg.freebsd.org
+mediaSetHTTP
+mediaOpen
+for package in wget bash rsync; do
+	packageAdd
+done

Modified: head/usr.sbin/bsdconfig/examples/browse_packages_http.sh
==============================================================================
--- head/usr.sbin/bsdconfig/examples/browse_packages_http.sh	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/examples/browse_packages_http.sh	Tue Jul 22 23:10:12 2014	(r268999)
@@ -1,25 +1,32 @@
 #!/bin/sh
 # $FreeBSD$
 #
-# This sample downloads the package INDEX file from HTTP to /tmp (if it doesn't
-# already exist) and then displays the package configuration/management screen
-# using the local INDEX file (results in faster browsing of packages from-start
-# since the INDEX can be loaded from local media).
+# This sample downloads the package digests.txz and packagesite.txz files from
+# HTTP to /tmp (if they don't already exist) and then displays the package
+# configuration/management screen using the local files (resulting in faster
+# browsing of packages from-start since digests.txz/packagesite.txz can be
+# loaded from local media).
 #
-# NOTE: Packages cannot be installed unless staged to /tmp/packages/All
+# NOTE: Packages cannot be installed unless staged to
+#       /tmp/packages/$PKG_ABI/All
 #
-. /usr/share/bsdconfig/script.subr
+[ "$_SCRIPT_SUBR" ] || . /usr/share/bsdconfig/script.subr || exit 1
 nonInteractive=1
+f_musthavepkg_init # Make sure we have a usable pkg(8) with $PKG_ABI
 TMPDIR=/tmp
-if [ ! -e "$TMPDIR/packages/INDEX" ]; then
-	[ -d "$TMPDIR/packages" ] || mkdir -p "$TMPDIR/packages" || exit 1
-	_httpPath=http://ftp.freebsd.org
-	# For older releases, use http://ftp-archive.freebsd.org
-	mediaSetHTTP
-	mediaOpen
-	f_show_info "Downloading packages/INDEX from\n %s" "$_httpPath"
-	f_device_get device_media packages/INDEX > $TMPDIR/packages/INDEX
-fi
+PKGDIR=$TMPDIR/packages/$PKG_ABI
+[ -d "$PKGDIR" ] || mkdir -p "$PKGDIR" || exit 1
+for file in digests.txz packagesite.txz; do
+	[ -s "$PKGDIR/$file" ] && continue
+	if [ ! "$HTTP_INITIALIZED" ]; then
+		_httpPath=http://pkg.freebsd.org
+		mediaSetHTTP
+		mediaOpen
+	fi
+	f_show_info "Downloading %s from\n %s" "$file" "$_httpPath"
+	f_device_get device_media "/$PKG_ABI/latest/$file" > $PKGDIR/$file ||
+		exit 1
+done
 _directoryPath=$TMPDIR
 mediaSetDirectory
 configPackages

Modified: head/usr.sbin/bsdconfig/include/messages.subr
==============================================================================
--- head/usr.sbin/bsdconfig/include/messages.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/include/messages.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -57,6 +57,7 @@ msg_back="Back"
 msg_becoming_root_via_sudo="Becoming root via sudo(8)..."
 msg_benchmarks_desc="Utilities for measuring system performance."
 msg_biology_desc="Software related to biology."
+msg_bootstrapping_pkg="Bootstrapping pkg(8)..."
 msg_brazil="Brazil"
 msg_building_package_menus="Building package menu(s)..."
 msg_cad_desc="Computer Aided Design utilities."
@@ -142,8 +143,6 @@ msg_generating_index_from_pkg_database="
 msg_geography_desc="Geography-related software."
 msg_german_desc="Ported software for Germanic countries."
 msg_germany="Germany"
-msg_getting_package_categories_via_pkg_rquery="Getting package categories via pkg-rquery(8)..."
-msg_getting_package_dependencies_via_pkg_rquery="Getting package dependencies via pkg-rquery(8)\n(this can take a while)..."
 msg_gnome_desc="Components of the Gnome Desktop environment."
 msg_gnustep_desc="Software for GNUstep desktop environment."
 msg_graphics_desc="Graphics libraries and utilities."
@@ -219,6 +218,7 @@ msg_misc_desc="Miscellaneous utilities."
 msg_missing_ftp_host_or_directory="Missing FTP host or directory specification.  FTP media not initialized."
 msg_multimedia_desc="Multimedia software."
 msg_must_be_root_to_execute="%s: must be root to execute"
+msg_must_have_pkg_to_execute="%s: must have pkg(8) to execute"
 msg_must_specify_a_host_name_of_some_sort="Must specify a host name of some sort!"
 msg_name_server="Name server"
 msg_net_desc="Networking utilities."
@@ -274,6 +274,7 @@ msg_perl5_desc="Utilities/modules for th
 msg_permission_denied="%s: %s: Permission denied"
 msg_pkg_delete_failed="Warning: pkg-delete(8) of %s failed.\n  Run with debugging for details."
 msg_pkg_install_apparently_did_not_like_the_package="pkg-install(8) apparently did not like the %s package."
+msg_pkg_not_yet_installed_install_now="pkg(8) not yet installed. Install now?"
 msg_plan9_desc="Software from the Plan9 operating system."
 msg_please_check_the_url_and_try_again="No such directory: %s\nplease check the URL and try again.\n"
 msg_please_enter_password="Please enter your password for sudo(8):"
@@ -376,15 +377,13 @@ msg_unable_to_get_proper_ftp_path="Unabl
 msg_unable_to_initialize_media_type_for_package_extract="Unable to initialize media type for package extract."
 msg_unable_to_make_directory_mountpoint="Unable to make %s directory mountpoint for %s!"
 msg_unable_to_open="Unable to open %s"
-msg_unable_to_pkg_rquery_package_categories="Unable to pkg-rquery(8) package categories!"
-msg_unable_to_pkg_rquery_package_dependencies="Unable to pkg-rquery(8) package dependencies!"
 msg_unable_to_update_pkg_from_selected_media="Unable to update pkg(8) from selected media."
 msg_uninstall="Uninstall"
 msg_uninstall_desc="Mark this package for deletion"
 msg_uninstalling_package_waiting_for_pkg_delete="Uninstalling %s package - waiting for pkg-delete(8)"
 msg_unknown="unknown"
 msg_unknown_user="Unknown user: %s"
-msg_url_was_not_found="%s was not found, maybe directory or release-version are wrong?"
+msg_url_was_not_found="%s was not found,\nmaybe directory or release-version are wrong?"
 msg_usa="USA"
 msg_usage="Usage"
 msg_usb="USB"

Modified: head/usr.sbin/bsdconfig/share/common.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/common.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/common.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -62,12 +62,6 @@ export UNAME_S="$( uname -s )" # Operati
 export UNAME_P="$( uname -p )" # Processor Architecture (i.e. i386)
 export UNAME_M="$( uname -m )" # Machine platform (i.e. i386)
 export UNAME_R="$( uname -r )" # Release Level (i.e. X.Y-RELEASE)
-if [ ! "${PKG_ABI+set}" ]; then
-	export PKG_ABI="$(
-		ASSUME_ALWAYS_YES=1 pkg -vv 2> /dev/null |
-			awk '$1=="ABI"{print $3;exit}'
-	)"
-fi
 
 #
 # Default behavior is to call f_debug_init() automatically when loaded.

Modified: head/usr.sbin/bsdconfig/share/media/http.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/media/http.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/media/http.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -515,10 +515,7 @@ f_media_init_http()
 			fi
 		esac
 
-		if [ $http_found -eq $SUCCESS ]; then
-			HTTP_INITIALIZED=YES
-			break
-		fi
+		[ $http_found -eq $SUCCESS ] && HTTP_INITIALIZED=YES break
 
 		f_getvar $VAR_HTTP_PATH http_path
 		f_show_msg "$msg_please_check_the_url_and_try_again" \
@@ -668,7 +665,7 @@ f_media_get_http()
 	 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
+	esac 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
 	return $FAILURE
 }
 

Modified: head/usr.sbin/bsdconfig/share/media/httpproxy.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/media/httpproxy.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/media/httpproxy.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -452,7 +452,7 @@ f_media_get_http_proxy()
 	 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
+	esac 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
 	return $FAILURE
 }
 

Modified: head/usr.sbin/bsdconfig/share/packages/Makefile
==============================================================================
--- head/usr.sbin/bsdconfig/share/packages/Makefile	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/packages/Makefile	Tue Jul 22 23:10:12 2014	(r268999)
@@ -3,7 +3,7 @@
 NO_OBJ=
 
 FILESDIR=	${SHAREDIR}/bsdconfig/packages
-FILES=		categories.subr index.subr packages.subr
+FILES=		categories.subr index.subr musthavepkg.subr packages.subr
 
 beforeinstall:
 	mkdir -p ${DESTDIR}${FILESDIR}

Modified: head/usr.sbin/bsdconfig/share/packages/index.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/packages/index.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/packages/index.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -33,6 +33,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 f_dprintf "%s: loading includes..." packages/index.subr
 f_include $BSDCFG_SHARE/device.subr
 f_include $BSDCFG_SHARE/media/common.subr
+f_include $BSDCFG_SHARE/packages/musthavepkg.subr
 f_include $BSDCFG_SHARE/strings.subr
 
 BSDCFG_LIBE="/usr/libexec/bsdconfig"
@@ -53,27 +54,6 @@ SQLITE_REPO="/var/db/pkg/repo-packagesit
 #
 PACKAGES_INDEX_CACHEFILE="/var/run/bsdconfig/packages_INDEX.cache"
 
-#
-# INDEX format for FreeBSD-6.0 or higher:
-#
-# 	package|port-origin|install-prefix|comment|port-desc-file|maintainer|
-# 	categories|build-deps|run-deps|www-site|reserve|reserve|reserve|disc
-#
-INDEX_FORMAT="%n-%v" # package
-INDEX_FORMAT="$INDEX_FORMAT|/usr/ports/%o"	# port-origin
-INDEX_FORMAT="$INDEX_FORMAT|%p"			# install-prefix
-INDEX_FORMAT="$INDEX_FORMAT|%c"			# comment
-INDEX_FORMAT="$INDEX_FORMAT|/usr/ports/%o/pkg-descr"	# port-desc-file
-INDEX_FORMAT="$INDEX_FORMAT|%m"			# maintainer
-INDEX_FORMAT="$INDEX_FORMAT|@CATEGORIES@"	# place-holder
-INDEX_FORMAT="$INDEX_FORMAT|"			# build-deps
-INDEX_FORMAT="$INDEX_FORMAT|@RUNDEPS@"		# place-holder
-INDEX_FORMAT="$INDEX_FORMAT|%w"			# www-site
-INDEX_FORMAT="$INDEX_FORMAT|"			# reserved
-INDEX_FORMAT="$INDEX_FORMAT|"			# reserved
-INDEX_FORMAT="$INDEX_FORMAT|"			# reserved
-INDEX_FORMAT="$INDEX_FORMAT|"			# disc
-
 ############################################################ FUNCTIONS
 
 # f_index_initialize [$var_to_set]
@@ -87,13 +67,16 @@ INDEX_FORMAT="$INDEX_FORMAT|"			# disc
 f_index_initialize()
 {
 	local __funcname=f_index_initialize
-	local __var_to_set="${2:-PACKAGE_INDEX}"
+	local __var_to_set="${1:-PACKAGE_INDEX}"
 
 	[ "$_INDEX_INITTED" ] && return $SUCCESS
 
 	# Got any media?
 	f_media_verify || return $FAILURE
 
+	# Make sure we have a usable pkg(8) with $PKG_ABI
+	f_musthavepkg_init
+
 	# Does it move when you kick it?
 	f_device_init device_media || return $FAILURE
 
@@ -126,9 +109,10 @@ f_index_initialize()
 		__site="file://$MOUNTPOINT/packages/$PKG_ABI"
 	esac
 
-	export PACKAGESITE="$__site"
-	f_dprintf "PACKAGESITE=[%s]" "$PACKAGESITE"
-	if ! f_eval_catch $__funcname pkg "pkg update"; then
+	f_dprintf "PACKAGESITE=[%s]" "$__site"
+	if ! f_eval_catch $__funcname pkg \
+		'PACKAGESITE="%s" pkg update' "$__site"
+	then
 		f_show_err "$msg_unable_to_update_pkg_from_selected_media"
 		f_device_shutdown device_media
 		return $FAILURE
@@ -195,53 +179,8 @@ f_index_initialize()
 	# If we reach this point, we need to generate the data from scratch
 	#
 
-	f_show_info "$msg_getting_package_categories_via_pkg_rquery"
-	if ! eval "$( pkg rquery "%n-%v %C" | awk '
-	{ categories[$1] = categories[$1] " " $2 }
-	END {
-		for (package in categories)
-		{
-			cats = categories[package]
-			sub(/^ /, "", cats)
-			gsub(/[^[:alnum:]_]/, "_", package)
-			printf "local _%s_categories=\"%s\";\n", package, cats
-		}
-	}' )"; then
-		f_show_err "$msg_unable_to_pkg_rquery_package_dependencies"
-		f_device_shutdown device_media
-		return $FAILURE
-	fi
-
-	f_show_info "$msg_getting_package_dependencies_via_pkg_rquery"
-	if ! eval "$( pkg rquery "%n-%v %dn-%dv" | awk '
-	{ rundeps[$1] = rundeps[$1] " " $2 }
-	END {
-		for (package in rundeps)
-		{
-			deps = rundeps[package]
-			sub(/^ /, "", deps)
-			gsub(/[^[:alnum:]_]/, "_", package)
-			printf "local _%s_rundeps=\"%s\";\n", package, deps
-		}
-	}' )"; then
-		f_show_err "$msg_unable_to_pkg_rquery_package_dependencies"
-		f_device_shutdown device_media
-		return $FAILURE
-	fi
-
 	f_show_info "$msg_generating_index_from_pkg_database"
-	eval "$__var_to_set"='$( pkg rquery "$INDEX_FORMAT" |
-		while read LINE; do
-			package="${LINE%%|*}";
-			f_str2varname "$package" varpkg;
-			eval f_replaceall \"\$LINE\" \"\|@CATEGORIES@\|\" \
-				\"\|\$_${varpkg}_categories\|\" LINE
-			eval f_replaceall \"\$LINE\" \"\|@RUNDEPS@\|\" \
-				\"\|\$_${varpkg}_rundeps\|\" LINE
-			echo "$LINE"
-		done
-	)' # always returns true (status of last item in pipe-chain)
-	eval "$__var_to_set"='$( debug= f_getvar "$__var_to_set" | sort )'
+	eval "$__var_to_set"='$( pkg rquery -I | sort )'
 
 	#
 	# Attempt to create the persistant on-disk cache

Added: head/usr.sbin/bsdconfig/share/packages/musthavepkg.subr
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsdconfig/share/packages/musthavepkg.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -0,0 +1,87 @@
+if [ ! "$_PACKAGES_MUSTHAVEPKG_SUBR" ]; then _PACKAGES_MUSTHAVEPKG_SUBR=1
+#
+# Copyright (c) 2014 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 (INCLUDING, 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..." packages/musthavepkg.subr
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/mustberoot.subr
+
+############################################################ FUNCTIONS
+
+# f_musthavepkg_init
+#
+# Validate pkg(8) is installed and set $PKG_ABI global if not already set.
+# Returns success unless pkg(8) is not installed and user refuses to install
+# it (upon prompt when running interactively).
+#
+f_musthavepkg_init()
+{
+	local funcname=f_musthavepkg_init
+	local pkg_abi_awk='$1~/^ABI/{print $NF; exit}'
+
+	if [ "$PKG_ABI" ]; then # Already set
+		f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
+		export PKG_ABI
+		f_quietly pkg -N -vv # return status (pkg(8) functional?)
+		return $?
+	fi
+
+	# Attempt to get PKG_ABI without prematurely bootstrapping pkg(8)
+	if f_eval_catch -k PKG_ABI $funcname pkg \
+		"pkg -N -vv | awk '%s'" "$pkg_abi_awk"
+	then
+		f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
+		export PKG_ABI
+		return $SUCCESS
+	fi
+
+	# pkg(8) not yet bootstrapped; ask for permission unless nonInteractive
+	f_dialog_yesno "$msg_pkg_not_yet_installed_install_now" ||
+		f_die 1 "$msg_must_have_pkg_to_execute" "$pgm"
+
+	f_mustberoot_init # Have to be root to install pkg(8)
+
+	# Bootstrap pkg(8)
+	f_dialog_info "$msg_bootstrapping_pkg"
+	f_eval_catch -k PKG_ABI $funcname pkg \
+		"ASSUME_ALWAYS_YES=1 pkg -vv | awk '%s'" "$pkg_abi_awk" ||
+		f_die 1 "$msg_must_have_pkg_to_execute" "$pgm"
+
+	f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
+	export PKG_ABI
+	return $SUCCESS
+}
+
+############################################################ MAIN
+
+f_dprintf "%s: Successfully loaded." packages/musthavepkg.subr
+
+fi # ! $_PACKAGES_MUSTHAVEPKG_SUBR

Modified: head/usr.sbin/bsdconfig/share/packages/packages.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/packages/packages.subr	Tue Jul 22 22:57:26 2014	(r268998)
+++ head/usr.sbin/bsdconfig/share/packages/packages.subr	Tue Jul 22 23:10:12 2014	(r268999)
@@ -36,6 +36,7 @@ f_include $BSDCFG_SHARE/device.subr
 f_include $BSDCFG_SHARE/media/common.subr
 f_include $BSDCFG_SHARE/packages/categories.subr
 f_include $BSDCFG_SHARE/packages/index.subr
+f_include $BSDCFG_SHARE/packages/musthavepkg.subr
 f_include $BSDCFG_SHARE/strings.subr
 
 BSDCFG_LIBE="/usr/libexec/bsdconfig"
@@ -662,7 +663,7 @@ f_package_review()
 f_package_config()
 {
 	# Did we get an INDEX?
-	f_index_initialize packages/INDEX || return $FAILURE
+	f_index_initialize || return $FAILURE
 		# Creates following variables (indirectly via f_index_read())
 		#   CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
 		#   PACKAGE_CATEGORIES _npkgs
@@ -839,7 +840,7 @@ f_package_add()
 	{ # Verify and initialize device media if-defined
 		f_media_verify &&
 		f_device_init device_media &&
-		f_index_initialize packages/INDEX
+		f_index_initialize
 	} || return $FAILURE
 
 	# Now we have (indirectly via f_index_read()):
@@ -946,6 +947,8 @@ f_package_extract()
 	local device="$1" name="$2" depended="$3"
 	local devname=
 
+	f_musthavepkg_init # Make sure we have a usable pkg(8) with $PKG_ABI
+
 	$device get name devname
 	f_dprintf "$funcname: device=[%s] name=[%s] depended=[%s]" \
 	          "$devname" "$name" "$depended"
@@ -1065,7 +1068,7 @@ f_package_delete()
 	{ # Verify and initialize device media if-defined
 		f_media_verify &&
 		f_device_init device_media &&
-		f_index_initialize packages/INDEX
+		f_index_initialize
 	} || return $FAILURE
 
 	# Now we have (indirectly via f_index_read()):



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407222310.s6MNACJM060347>