Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Aug 2014 18:57:57 +0000 (UTC)
From:      Rene Ladan <rene@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r366248 - in head/sysutils/bsdadminscripts: . files
Message-ID:  <201408261857.s7QIvvxJ051123@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rene
Date: Tue Aug 26 18:57:57 2014
New Revision: 366248
URL: http://svnweb.freebsd.org/changeset/ports/366248
QAT: https://qat.redports.org/buildarchive/r366248/

Log:
  sysutils/bsdadminscripts: fix scripts at runtime.
  
  Previously, pkg_libchk, pkg_upgrade, and uma failed to run.
  Bump PORTREVISION
  
  PR:		193003
  Submitted by:	Carlos Jacobo Puga Medina <cpm@fbsd.es>
  Reviewed by:	marino

Added:
  head/sysutils/bsdadminscripts/files/pkg_libchk.in   (contents, props changed)
  head/sysutils/bsdadminscripts/files/pkg_upgrade.in   (contents, props changed)
  head/sysutils/bsdadminscripts/files/uma.in   (contents, props changed)
Deleted:
  head/sysutils/bsdadminscripts/files/patch-pkg_libchk
Modified:
  head/sysutils/bsdadminscripts/Makefile

Modified: head/sysutils/bsdadminscripts/Makefile
==============================================================================
--- head/sysutils/bsdadminscripts/Makefile	Tue Aug 26 18:55:22 2014	(r366247)
+++ head/sysutils/bsdadminscripts/Makefile	Tue Aug 26 18:57:57 2014	(r366248)
@@ -3,7 +3,7 @@
 
 PORTNAME=	bsdadminscripts
 PORTVERSION=	6.1.1
-PORTREVISION=	6
+PORTREVISION=	7
 CATEGORIES=	sysutils ports-mgmt
 MASTER_SITES=	SF/${PORTNAME}/${PORTNAME}
 
@@ -13,10 +13,17 @@ COMMENT=	Collection of administration sc
 LICENSE=	BSD2CLAUSE
 
 NO_BUILD=	yes
+
+TMP?=	/tmp
+VAR?=	/var
+
 PORTDOCS=	ABOUT CHANGES INSTALL NOTES THANKS
 
 OPTIONS_DEFINE=	DOCS
 
+SUB_FILES=	pkg_libchk pkg_upgrade uma
+SUB_LIST=	TMP=${TMP} PREFIX=${PREFIX} VAR=${VAR} PORTS=${PORTSDIR}
+
 .include <bsd.port.options.mk>
 
 .if ! ${PORT_OPTIONS:MDOCS}
@@ -31,12 +38,14 @@ do-install:
 		-datadir=${STAGEDIR}${DATADIR} \
 		${EVALDOCS}
 .for n in pkg_libchk pkg_upgrade uma
+	${MV} ${WRKDIR}/${n} ${WRKSRC}/src
 	${INSTALL_SCRIPT} ${WRKSRC}/src/${n} ${STAGEDIR}${PREFIX}/sbin
 .endfor
 	${INSTALL_DATA} ${WRKSRC}/src/buildflags.mk ${STAGEDIR}${DATADIR}
 	${INSTALL_DATA} ${WRKSRC}/src/buildflags.conf.sample \
 		${STAGEDIR}${PREFIX}/etc
 	${INSTALL_DATA} ${WRKSRC}/src/uma.conf.sample ${STAGEDIR}${PREFIX}/etc
+
 .for f in bsdadminscripts buildflags.awk buildflags.conf buildflags.mk \
 	distviper pkg_libchk pkg_upgrade pkg_validate portconfig rcstart uma
 	${INSTALL_MAN} ${WRKSRC}/src/${f}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1
@@ -46,6 +55,7 @@ post-install:
 	${MKDIR} ${STAGEDIR}${ETCDIR}
 	${MV} ${STAGEDIR}${PREFIX}/etc/*.sample ${STAGEDIR}${ETCDIR}
 	${RM} -rf ${STAGEDIR}${PREFIX}/etc/*.sample
+
 .if ${PORT_OPTIONS:MDOCS}
 	${MKDIR} ${STAGEDIR}${DOCSDIR}
 	cd ${WRKSRC} && ${INSTALL_DATA} ${PORTDOCS} ${STAGEDIR}${DOCSDIR}

Added: head/sysutils/bsdadminscripts/files/pkg_libchk.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/bsdadminscripts/files/pkg_libchk.in	Tue Aug 26 18:57:57 2014	(r366248)
@@ -0,0 +1,484 @@
+#!/bin/sh -f
+#
+# Copyright (c) 2007-2009
+# Dominic Fandrey <kamikaze@bsdforen.de>
+#
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+#
+
+readonly name=pkg_libchk
+readonly version=1.6.1
+readonly osname=`uname -s`
+readonly pkgng=`make -f /usr/share/mk/bsd.port.mk -V WITH_PKGNG`
+
+# Use a line break as delimiter.
+IFS='
+'
+
+# Filename prefix for shared data
+sharedprefix="%%TMP%%/$$"
+shared="locks"
+
+#
+# This function remembers a lock to allow later deletion with the 
+# lockUnregisterAll() function.
+#
+# @param $1
+#	The name of the lock.
+lockRegister() {
+	local lock
+	lock="$sharedprefix-$shared"
+	lockf -k "$lock" sh -c "
+		if ! grep -qE '^$1\$' '$lock'; then
+			echo '$1' >> '$lock'
+		fi
+	"
+}
+
+#
+# Unregisters all locks.
+#
+lockUnregisterAll() {
+	wait
+	for register in $(cat "$sharedprefix-$shared"); {
+		lockf "$sharedprefix-$register" wait
+	}
+	lockf "$sharedprefix-$shared" wait
+}
+
+#
+# This function creates a semaphore.
+#
+# @param $1
+#	The name of the semaphore.
+# @param $2
+#	The size of the semaphore.
+#
+semaphoreCreate() {
+	local lock
+	lockRegister "semaphore-$1"
+	lock="$sharedprefix-semaphore-$1"
+	lockf -k "$lock" echo "$2" > "$lock"
+	eval "semaphore_$1_size=$2"
+}
+
+#
+# This function waits until the semaphore is free und registers its use.
+# Everything that uses this also has to call the semaphoreFree() function.
+#
+# @param $1
+#	The name of the semaphore.
+#
+semaphoreUse() {
+	local lock semaphores
+	lock="$sharedprefix-semaphore-$1"
+	while ! lockf -k "$lock" sh -c "
+			state=\$(cat '$lock')
+			if [ \"\$state\" -gt 0 ]; then
+				echo \"\$((\$state - 1))\" > '$lock'
+				exit 0
+			fi
+			exit 1
+		"; do
+		sleep 0.1
+	done
+}
+
+#
+# This function frees a semaphore.
+#
+# @param $1
+#	The name of the semaphore.
+#
+semaphoreFree() {
+	local lock
+	lock="$sharedprefix-semaphore-$1"
+	lockf -k "$lock" sh -c "
+		state=\"\$((\"\$(cat '$lock')\" + 1))\"
+		echo \"\$state\" > '$lock'
+	"
+}
+
+#
+# This function sets a new status and prints it.
+#
+# @param $1
+#	The status message.
+# @param $clean
+#	If set status handling is disabled.
+#
+statusSet() {
+	# In clean mode status handling is disabled.
+	test -z "$clean" || return 0
+	local lock
+	lock="$sharedprefix-status"
+	lockf -k "$lock" sh -c "
+		status=\"\$(cat '$lock')\"
+		echo '$1' > '$lock'
+		printf \"\\r%-\${#status}s\\r\" '$1' > /dev/tty
+	"
+}
+
+#
+# This function prints a message and the current status behind it.
+#
+# @param $1
+#	The message to print.
+# @param $clean
+#	If set the status will not be printed.
+#
+statusPrint() {
+	if [ -z "$clean" ]; then
+		local lock
+		lock="$sharedprefix-status"
+		lockf -k "$lock" sh -c "
+			status=\"\$(cat '$lock')\"
+			printf \"%-\${#status}s\\r\" '' > /dev/tty
+			echo '$1'
+			printf '%s\\r' \"\$status\" > /dev/tty
+		"
+	else
+		echo "$1"
+	fi
+}
+
+#
+# Waits for a semaphore to be completely free and counts down the remaining
+# number of locks.
+#
+# @param $1
+#	The semaphore to watch.
+# @param $2
+#	The status message to print, insert %d in the place where the number
+#	of remaining locks belong.
+#
+semaphoreCountDown() {
+	local free size
+	while read -t1 free < "$sharedprefix-semaphore-$1"; do
+		size=$(eval "echo \$semaphore_$1_size")
+		statusSet "$(printf "$2" $(( $size - $free )))"
+		test "$free" -eq "$size" && break
+		sleep 0.1
+	done
+	wait
+}
+
+# Clean up upon exit.
+trap '
+	semaphoreCountDown jobs "Terminated by signal, waiting for %d jobs to die."
+	echo > /dev/tty
+	lockUnregisterAll
+	exit 255
+' int term
+
+#
+# This function checks whether a given binary or library directly depends
+# on a missing library.
+# It goes a long way to prevent all kinds of false positives.
+# It always returns 2 (false) for Linux and other non-native libraries
+# and binaries.
+# It also checks whether the missing dependency is really a direct dependency
+# (indirect dependencies have to be fixed somewhere else).
+#
+# @param $1
+#	The library or binary to check.
+# @return
+#	Returns 0 (true) if a library is missing.
+#	Returns 1 if everything is all right.
+#	Returns 2 if the check cannot be performed (not a native library).
+#
+dependencyMissing() {
+	local missing file direct libfound
+
+	# We cannot handle non-native binaries,
+	# so assume everything is in order.
+	if ! readelf -e "$1" 2>&1 | \
+		grep -E "^[[:space:]]*OS/ABI:[[:space:]]*UNIX - $osname\$" \
+		> /dev/null
+	then
+		return 2
+	# Nothing is missing.
+	elif ! missing="$(ldd "$1" 2>&1 | grep -E "$match_expr")"; then
+		return 1
+	fi
+
+	# The return status. The value 1 assumes that this is a false positive.
+	status=1
+
+	# Only report misses for direct dependencies.
+	direct="$(
+			readelf -d "$1" 2> /dev/null | \
+				grep 'Shared library:' | \
+				sed -E -e 's|^[^[]*\[||1' -e 's|\]$||1'
+	)"
+
+	# Compare every missing depency with the list of direct dependencies
+	# and report that the dependency is missing if the missing file is
+	# a direct dependency.
+	for file in $missing; {
+		# Strip the missing file of additional information.
+		file="$(echo "$file" | sed -E \
+			-e 's| => .*$||1' \
+			-e 's|^[[:space:]]*||1' \
+			-e 's|^.*dependency ||1' \
+			-e 's| not found$||1'
+		)"
+
+		# If in mean mode we do not check for false positives.
+		if [ -n "$mean" ]; then
+			test -n "$raw" && return 0
+			statusPrint "$package_name: $1 misses $file"
+			continue
+		fi
+
+		# Handle the case where a library is not found, but exists
+		# somewhere in the package. This is for packages that do not
+		# rely on the OS to find libraries.
+		libfound=
+		for library in $(echo "$libraries" | grep -E "/$file\$"); {
+			# The library exists after all.
+			test -e "$library" && libfound=1 && break
+		}
+		if test "$libfound"; then
+			test -n "$verbose" && statusPrint "$package_name: \
+located: $1 misses $file found at $library."
+			continue
+		fi
+
+		# Compare the file with the list of direct dependencies.
+		# If it's not in than it's only an indirect dependency and
+		# cannot be fixed by rebuilding this port.
+		if echo "$direct" | grep -E "^$file\$" > /dev/null; then
+			test -n "$raw" && return 0
+			statusPrint "$package_name: $1 misses $file"
+			status=0
+		elif [ -n "$verbose" ]; then
+			statusPrint "$package_name: inderect: $1 \
+misses $file is an inderect dependency."
+		fi
+	}
+
+	return $status
+}
+
+#
+# Checks the parameters for options.
+#
+# @param $packages
+#	The parameters to pkg_info -E that will result in the
+#	names of the packages to work on.
+# @param $recursive
+#	Contains the appropriate parameter to get the
+#	dependencies of the given packages from pkg_info.
+# @param $Recursive
+#	Contains the appropriate parameter to get the
+#	packages depending on the given packages from pkg_info.
+# @param $raw
+#	Is set to trigger raw printing.
+# @param $clean
+#	Is set to trigger printing without status messages.
+# @param $verbose
+#	Is set to be verbose about false positives.
+# @param $mean
+#	Is set to switch into mean mode. That means no
+#	checking of false positives.
+# @param $compat
+#	Delete to avoid detecting compat libraries as misses.
+# @param $origin
+#	Is set to turn the print origin mode on.
+# @semaphore jobs
+#	Is set to limit the amount of parallel jobs.
+#
+readParams() {
+	local option
+
+	for option {
+		case "$option" in
+			"-a" | "--all")
+				packages="-a"
+			;;
+			"-c" | "--clean")
+				clean=1
+			;;
+			"-h" | "--help")
+				printHelp
+			;;
+			-j* | --jobs*)
+				local jobs
+				jobs="${option#-j}"
+				jobs="${jobs#--jobs}"
+				if [ "$jobs" -ne "$jobs" ] 2> /dev/null; then
+					echo "The -j option must be followed" \
+						"by a number."
+					exit 3
+				elif [ "$jobs" -lt 1 ]; then
+					echo "The -j option must specify at" \
+						"least 1 job."
+					exit 3
+				else
+					semaphoreCreate jobs "$jobs"
+				fi
+			;;
+			"-m" | "--mean")
+				mean=1
+			;;
+			"-n" | "--no-compat")
+				compat=
+			;;
+			"-o" | "--origin")
+				origin=1
+			;;
+			"-q" | "--raw")
+				raw=1
+				if [ -n "$verbose" ]; then
+					echo "The parameters -v and -q may" \
+						"not be used at the same time."
+					exit 2
+				fi
+			;;
+			"-r" | "--recursive")
+				recursive="-r"
+			;;
+			"-R" | "--upward-recursive")
+				Recursive="-R"
+			;;
+			"-v" | "--verbose")
+				verbose=1
+				if [ -n "$raw" ]; then
+					echo "The parameters -q and -v may" \
+						"not be used at the same time."
+					exit 2
+				fi
+			;;
+			-? | --*)
+				echo "Unknown parameter \"$option\"."
+				exit 1
+			;;
+			-*)
+				readParams "${option%${option#-?}}"
+				readParams "-${option#-?}"
+			;;
+			*)
+				packages="$packages${packages:+$IFS}$option"
+			;;
+		esac
+	}
+}
+
+#
+# Display a short help message.
+#
+printHelp() {
+	echo "$name v$version
+usage:	$name [-a] [-c] [-h] [-jN] [-m] [-n] [-o] [-q] [-r] [-R] [-v] [packages]"
+        exit 0
+}
+
+# Create the expression to match to find files linking against compat libraries.
+# This can be emptied by readParams to deactivate that feature.
+prefix="$(make -f /usr/share/mk/bsd.port.mk -VPREFIX 2> /dev/null || \
+	echo '%%PREFIX%%')"
+compat="=> $prefix/lib/compat|"
+
+# Create the semaphore with CPU cores * 2 jobs.
+semaphoreCreate jobs "$(($(sysctl -n hw.ncpu 2> /dev/null || echo 1) * 2))"
+# Register the status lock.
+lockRegister status
+
+# Read the parameters.
+readParams "$@"
+
+statusSet 'Preparing ...'
+
+# Get the packages to work on.
+test -z "$packages" && packages="-a"
+if [ -n "$pkgng" ]; then
+	packages="$(pkg info -q $packages)"
+	test -z "$recursive" -a -z "$Recursive" || packages="$packages
+	$(pkg info -q $recursive $Recursive "$packages" 2> /dev/null | \
+	sed -E 's|^@pkgdep[[:space:]]*||1')"
+else
+	packages="$(pkg_info -E $packages)"
+	test -z "$recursive" -a -z "$Recursive" || packages="$packages
+	$(pkg_info -q $recursive $Recursive "$packages" 2> /dev/null | \
+	sed -E 's|^@pkgdep[[:space:]]*||1')"
+fi
+
+# Create the regexp to match ldd output
+match_expr="$compat=> not found|dependency .+ not found"
+
+# The packages to check.
+package_amount="$(echo "$packages" | wc -l | sed 's|[[:space:]]||g')"
+package_num=0
+
+# Check each selected package.
+for package in $packages; {
+	package_num="$(($package_num + 1))"
+	if [ -n "$pkgng" ]; then
+		test $origin \
+			&& package_name="$(pkg info -qo "$package")" \
+			|| package_name="$package"
+	else
+		test $origin \
+			&& package_name="$(pkg_info -qo "$package")" \
+			|| package_name="$package"
+	fi
+
+	# Print what we're doing.
+	statusSet "Starting job $package_num of $package_amount: $package_name"
+
+	semaphoreUse jobs
+	(
+		# Remember freeing the semaphore.
+		trap 'semaphoreFree jobs' EXIT
+
+		files=""
+		if [ -n "$pkgng" ]; then
+			files="$(pkg info -lq "$package")"
+		else
+			files="$(pkg_info -qL "$package")"
+		fi
+		# Get the programs libraries in case it doesn't use the
+		# operating system to find its libraries.
+		libraries="$(echo "$files" | grep -E '\.so[\.0-9]*$')"
+
+		outdated=0
+		broken=
+
+		# Check each file of each package.
+		for file in $files; {
+			if [ ! -L "$file" -a \( \
+				-x "$file" -o \
+				-n "$(echo "$file" | grep -E '\.so[\.0-9]*$')" \
+			 \) ]; then
+				if dependencyMissing "$file"; then
+					if [ -n "$raw" ]; then
+						statusPrint "$package_name"
+						break 1
+					fi
+				fi
+			fi
+		}
+	) &
+}
+
+semaphoreCountDown jobs "Waiting for %d remaining jobs to finish."
+statusSet
+lockUnregisterAll
+
+exit 0

Added: head/sysutils/bsdadminscripts/files/pkg_upgrade.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/bsdadminscripts/files/pkg_upgrade.in	Tue Aug 26 18:57:57 2014	(r366248)
@@ -0,0 +1,2239 @@
+#!/bin/sh -f
+#
+# Copyright (c) 2009
+# Dominic Fandrey <kamikaze@bsdforen.de>
+#
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+#
+
+readonly version=1.1
+readonly name=pkg_upgrade
+
+# Error table.
+readonly ERR_LOCK=1
+readonly ERR_ARG=2
+readonly ERR_INDEX=3
+readonly ERR_FETCH=4
+readonly ERR_SORT=5
+readonly ERR_BACKUP_MISS=6
+readonly ERR_BACKUP_UNKNOWN=7
+readonly ERR_INSTALL=8
+readonly ERR_USER=9
+readonly ERR_TERM=10
+readonly ERR_PACKAGE_FORMAT=11
+readonly ERR_CONFLICT=12
+
+# Constant assignments.
+readonly logfile="%%VAR%%/log/$name.log"
+readonly pid=$$
+
+# Get some environment variables from uma. This includes PACKAGESITE,
+# TMPDIR and PKG_INDEX.
+eval "$(uma env $pid)"
+
+# The remote package repository, derived from PACKAGESITE.
+# If this matches the PACKAGES environment variable all downloading operations
+# will be omitted.
+readonly packagerepos="${PACKAGESITE%/*?}"
+
+# Environment variables.
+: ${PACKAGES="$(make -V PACKAGES -f /usr/share/mk/bsd.port.mk 2> /dev/null)"}
+PACKAGES="${PACKAGES:-%%PORTS%%/packages}"
+: ${PKG_DBDIR=%%VAR%%/db/pkg}
+: ${TMPDIR=%%TMP%%}
+: ${PKG_TMPDIR=$TMPDIR}
+
+# This is where backup packages will be stored.
+readonly packagebackup="$PACKAGES/$name-backup"
+# This is where the download manager will listen for messages.
+readonly queueMessages="$TMPDIR/pkg_upgrade.messages.queue"
+
+# Export environment variables to ensure that every tool uses the same ones.
+export ARCH PACKAGEROOT PACKAGESITE FTP_TIMEOUT PKG_INDEX
+export PACKAGEROOT_MIRRORS PACKAGESITE_MIRRORS
+export PACKAGES PKG_DBDIR TMPDIR PKG_TMPDIR
+
+# Direct index access.
+readonly IDX_PKG=0
+readonly IDX_ORIGIN=1
+readonly IDX_PREFIX=2
+readonly IDX_COMMENT=3
+readonly IDX_DESCRIPTION=4
+readonly IDX_MAINTAINER=5
+readonly IDX_CATEGORIES=6
+readonly IDX_DIRECTDEPENDS=7
+readonly IDX_DEPENDS=8
+readonly IDX_WWW=9
+readonly IDX_PERLVERSION=10
+readonly IDX_PERLMODULES=11
+
+# Input field seperator without spaces.
+IFS='
+'
+
+# Parameter flags.
+pAll=
+pNoBackup=
+pClean=
+pExitOnConflict=
+pForce=
+pFetchOnly=
+pInteractive=
+pJobs=
+pListDiscarded=
+pNoActions=
+pNoLogging=
+pParanoid=
+pRecursive=
+pReplaceConflicts=
+pMoreRecursive=
+pUpwardRecursive=
+pMoreUpwardRecursive=
+pVerbose=
+
+# The categories for packages.
+older=
+newer=
+unindexed=
+multiple=
+error=
+
+# A cache for the pkgDepends function.
+dependsChecked=
+
+# The names of packages that do not have a verified download.
+pending=
+
+#
+# The list of packages to upgrade.
+#
+
+# <origin>;<newPackage>
+upgrade=
+upgradeDepends=
+upgradeDepending=
+
+# The <newOrgin>;<newPackage> part can also be found in $upgrade.
+# <newOrigin>;<newPackage>|<oldOrigin>;<oldPackage>
+replace=
+
+# A list of dependency substitutions for new packages.
+# <originalOrigin>;<originalName>|<newDependencyOrigin>;<newDependencyName>
+substituteDepends=
+
+# The current status line.
+status=
+
+# The ports directory as used in the index file.
+idxports=
+
+#
+# Table Of Functions
+# In order of appearance.
+#
+# getIndex()		Fetch the latest INDEX
+# getLock()		Acquire a lock
+# printStatus()		Print status messages on the terminal
+# error()		Terminate with an error message
+# warn()		Print a warning on stderr
+# verbose()		Print a message, but only in verbose mode
+# log()			Log activity into a log file
+# getIdxEscape()	Escape origins and packages for regular expressions
+# getIdxRows()		Filter index rows with an escaped expression
+# getIdxRowsEscaped()	Filter index rows with an expression
+# getIdxColumn()	Get a certain column from index rows
+# pkgAll()		Make a list of outdated packages
+# pkgDepends()		Check dependencies
+# pkgDepending()	Check upwards dependencies
+# pkgDependencies()	Run all dependency checks
+# printProgress()	Print numerical progress output
+# pkgSort()		Sort packages by dependency
+# printTask()		Print the tasks to perform for a package
+# pkgList()		List all tasks in 'no actions' mode
+# pkgDownload()		Download all required packages
+# pkgUpgrade()		Upgrade all scheduled packages
+# substituteDepends()	Adjust dependencies of upgraded packages
+# upgradePackage()	Upgrade a given package
+# identifyPackage()	Identify a package by a user given string
+# printHelp()		Print program parameters and terminate
+# readParams()		Read the command line parameters
+# readContents()	Read the +CONTENTS of a package file
+# downloadManager()	Start a background download manager
+# downloadManagerFetch()
+#			Try to fetch a package from a mirror
+# downloadManagerMsgRetry()
+#			Tell the download manager to retry a download
+# downloadManagerMsgFinished()
+#			Tell the download manager a download has been completed
+# downloadManagerMsgRequest()
+#			Request a download from the download manager
+# downloadManagerMsgExit()
+#			Tell the download manager to terminate
+# validatePackage()	Validate a downloaded package
+# 
+
+
+#
+# Update the local copy of the index and start the download manager.
+#
+# @param idxports
+#	This is set to the ports directory used in the index file. This is
+#	required for many index operations. If already set the index is
+#	assumed to be up to date and nothing is done.
+# @param pVerbose
+#	Activate verbose output.
+#
+getIndex() {
+	# The index has already been updated.
+	if [ -n "$idxports" ]; then
+		return 0
+	fi
+
+	# Free the lock upon termination.
+	trap "uma unlock $pid" EXIT
+
+	# First acquire the lock.
+	getLock
+
+	verbose "Synchronize the local index copy with the package server."
+
+	# Try to update the index.
+	if ! uma $pVerbose fetch ftpindex $pid; then
+		exit $ERR_INDEX
+	fi
+
+	# Set the ports directory used in the index.
+	idxports="$(getIdxColumn $IDX_ORIGIN "$(head -n 1 "$PKG_INDEX")")"
+	idxports="${idxports%/*/*}"
+
+	# Start the download manager.
+	downloadManager
+}
+
+#
+# Acquires the uma (Update Manager) lock. And spawns a process that locks
+# onto PKG_DBDIR to block the ports from messing with us.
+#
+getLock() {
+	# Acquire the lock.
+	if ! uma lock $pid; then
+		if [ "$USER" != "root" ]; then
+			error $ERR_LOCK "The command $name has to be run as root."
+		else
+		 	error $ERR_LOCK "The uma (Update MAnager) lock could not be acquired, it appears the package/ports infrastructure is in use."
+		fi
+	fi
+
+	# Lock onto PKG_DBDIR to avoid ports getting into our way.
+	# The ports tree locks onto PKG_DBDIR during install and deinstall.
+	# Since it does not use uma we use this lock to make sure the ports
+	# tree does not get into our way later.
+	if ! lockf -kst 0 "$PKG_DBDIR" sh -c "lockf -k '$PKG_DBDIR' sh -c 'while kill -0  $pid 2> /dev/null; do sleep 2; done' &"; then
+		error $ERR_LOCK "Locking $PKG_DBDIR failed, the ports tree might be in use."
+	fi
+}
+
+#
+# Prints a status message to the terminal device /dev/tty.
+#
+# @param 1
+#	The message to print
+# @param status
+#	The last printed message, used for clearing the status line before
+#	printing a new status.
+# @param pClean
+#	If set, do not print status messages.
+#
+printStatus() {
+	test -n "$pClean" && return 0
+	printf "\r%${#status}s\r%s\r" '' "$1" > /dev/tty
+	status="$1"
+}
+
+#
+# Exits with the given error and message on stderr.
+#
+# @param 1
+#	The error number to exit with.
+# @param 2
+#	The message to exit with.
+#
+error() {
+	# Clear the status line.
+	printStatus
+	echo "$name: $2" 1>&2
+	exit "$1"
+}
+
+#
+# Writes a warning message to stderr.
+#
+# @param 1
+#	The message to write.
+#
+warn() {
+	# Clear the status line.
+	printStatus
+	echo "$name: $1" 1>&2
+}
+
+#
+# Outputs verbose messages on stdout.
+#
+# @param @
+#	All the parameters to be output.
+# @param pVerbose
+#	If this is not set, do not output anything.
+#
+verbose() {
+	test -z "$pVerbose" && return 0
+	echo "$@"
+}
+
+#
+# Logs the given message into a log file.
+#
+# The following format is used.
+#
+# <UTC timestamp> - <date> - (<error>|DONE): <message>
+#
+# UTC timestamp := The output of 'date -u '+%s'
+# date := The output of 'date'
+#
+# @param 1
+#	The error number for the log, if this is 0, the message will be
+#	preceded by "DONE:" instead of "ERROR($1):".
+# @param 2
+#	The message to log.
+# @param logfile
+#	The name of the file to log into.
+# @param pNoLogging
+#	If set, logging is not performed.
+#
+log() {
+	test -n "$pNoLogging" && return 0
+
+	if [ $1 -eq 0 ]; then
+		echo "$(date -u '+%s') - $(date) - DONE: $2" >> $logfile
+	else
+		echo "$(date -u '+%s') - $(date) - ERROR($1): $2" >> $logfile
+	fi
+}
+
+#
+# An escape function for package names fed to the getIdxColumn function.
+# This function reads from the standard input unless a file is named
+# in the parameters.
+# Note that the escaping is done for extended regular expressions, however
+# only characters that can appear in package names are escaped.
+#
+# @param @
+#	More parameters can be added to the sed command.
+#
+getIdxEscape() {
+	sed -E -e 's/([+.])/\\\1/g' "$@"
+}
+
+#
+# Outputs all rows of the index that match a given pattern in a column.
+# The pattern should not match '|'.
+#
+# @param 1
+#	The column that has to match the pattern.
+# @param 2
+#	The pattern that has to be matched, an extended regular expression.
+# @param 3
+#	Optional, the rows to match against instead of using the index file.
+#
+getIdxRows() {
+	if [ -z "$3" ]; then
+		grep -E "^([^|]*\|){$1}($2)(\|.*)?\$" "$PKG_INDEX"
+	else
+		echo "$3" | grep -E "^([^|]*\|){$1}($2)(\|.*)?\$"
+	fi
+}
+
+#
+# Outputs all rows of the index that match a given string.
+# The string should not contain '|'.
+#
+# @param 1
+#	The column that has to match the string.
+# @param 2
+#	The string that has to be matched.
+# @param 3
+#	Optional, the rows to match against instead of using the index file.
+#	
+getIdxRowsEscaped() {
+	getIdxRows $1 "$(echo "$2" | getIdxEscape)" "$3"
+}
+
+#
+# Outputs a column of each index row piped into it.
+#
+# @param 1
+#	The column to output.
+# @param 2
+#	The rows to output the columns from.
+#
+getIdxColumn() {
+	echo "$2" | sed -E "s,^([^|]*\|){$1}([^|]*)\|.*,\2,1"
+}
+
+#
+# Stores all the packages not in sync with the index file in categories.
+#
+# @param older
+#	The list of packages older than those in the index.
+# @param newer
+#	The list of packages newer than those in the index.
+# @param unindexed
+#	The list of packages not in the index.
+# @param multiple
+#	The list of packages that have multiple index entries.
+# @param error
+#	The list of packages with broken package database entries.
+# @param pForce
+#	If set, register all installed packages in the index as outdated.
+# @param pAll
+#	If set, add all outdated packages to the list of packages to upgrade.
+# @param pListDiscarded
+#	If set, list all the packages that are ignored.
+# @param upgrade
+#	The list to add packages to if pAll is set.
+#
+pkgAll() {
+	local package pkgname origin operator row discarded
+
+	# There's nothing to be done if all of the following conditions are
+	# met:
+	# - Nothing is yet listed for upgrading, so we do not need a list
+	#   of outdated packages for dependency checking.
+	# - The updating of all packages is not requested.
+	# - The listing of ignored (i.e. not indexed) packages is not
+	#   requested.
+	test -z "$upgrade" -a -z "$pAll" -a -z "$pListDiscarded" && return 0
+
+	verbose "Make a list of outdated packages."
+
+	printStatus "Reading version information of installed packages ..."
+
+	if [ -n "$pForce" ]; then
+		# In force mode it is assumed that all installed packages to
+		# be found in the index are outdated.
+		for package in $(pkg_version -Io "${PKG_INDEX}"); {
+			origin="${package%% *}"
+			row="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin")"
+			pkgname="$(getIdxColumn $IDX_PKG "$row")"
+			printStatus "Checking <$pkgname>."
+			operator="${package##* }"
+			case "$operator" in
+				'?')
+					unindexed="$unindexed${unindexed:+$IFS}$origin"
+				;;
+				'!')
+					error="$error${error:+$IFS}$origin"
+				;;
+				*)
+					older="$older${older:+$IFS}$origin;$pkgname"
+				;;
+			esac
+		}
+	else
+		# Categorize installed packages and their relations to the

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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