diff options
author | kami <kami@FreeBSD.org> | 2017-05-17 17:24:24 +0800 |
---|---|---|
committer | kami <kami@FreeBSD.org> | 2017-05-17 17:24:24 +0800 |
commit | 670e6eaa73b793fe621f455d46c0f767aa053de0 (patch) | |
tree | 0f90a4f9be35243e8faf7fc8603bd279f486e4ce /sysutils | |
parent | d28332745b8c38fa5cdcba96c26a7029366ecec5 (diff) | |
download | freebsd-ports-gnome-670e6eaa73b793fe621f455d46c0f767aa053de0.tar.gz freebsd-ports-gnome-670e6eaa73b793fe621f455d46c0f767aa053de0.tar.zst freebsd-ports-gnome-670e6eaa73b793fe621f455d46c0f767aa053de0.zip |
ports-mgmt/bsdadminscripts2: new port
- Move sysutils/bsdadminscripts to ports-mgmt/bsdadminscripts
- Copy ports-mgmt/bsdadminscripts to ports-mgmt/bsdadminscripts2
- Update bsdadminscripts2 to the bsda2 project 0.2.0 release
Reviewed by: miwi
Approved by: miwi
Differential Revision: https://reviews.freebsd.org/D9434
Diffstat (limited to 'sysutils')
-rw-r--r-- | sysutils/Makefile | 1 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/Makefile | 58 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/distinfo | 2 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/files/distviper.in | 227 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/files/pkg_libchk.in | 484 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/files/pkg_upgrade.in | 2239 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/files/uma.in | 436 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/pkg-descr | 7 | ||||
-rw-r--r-- | sysutils/bsdadminscripts/pkg-plist | 35 |
9 files changed, 0 insertions, 3489 deletions
diff --git a/sysutils/Makefile b/sysutils/Makefile index d700c2332053..8a1a4ef28422 100644 --- a/sysutils/Makefile +++ b/sysutils/Makefile @@ -104,7 +104,6 @@ SUBDIR += boxbackup-devel SUBDIR += brasero SUBDIR += bsd-splash-changer - SUBDIR += bsdadminscripts SUBDIR += bsdconfig SUBDIR += bsdcrashtar SUBDIR += bsdhwmon diff --git a/sysutils/bsdadminscripts/Makefile b/sysutils/bsdadminscripts/Makefile deleted file mode 100644 index 5bebeee5f93b..000000000000 --- a/sysutils/bsdadminscripts/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# Created by: Dominic Fandrey <lon_kamikaze@gmx.de> -# $FreeBSD$ - -PORTNAME= bsdadminscripts -PORTVERSION= 6.1.1 -PORTREVISION= 8 -CATEGORIES= sysutils ports-mgmt -MASTER_SITES= SF/${PORTNAME}/${PORTNAME} - -MAINTAINER= ports@FreeBSD.org -COMMENT= Collection of administration scripts - -LICENSE= BSD2CLAUSE - -NO_BUILD= yes -NO_ARCH= yes - -TMP?= /tmp -VAR?= /var - -PORTDOCS= ABOUT CHANGES INSTALL NOTES THANKS - -OPTIONS_DEFINE= DOCS - -SUB_FILES= distviper pkg_libchk pkg_upgrade uma -SUB_LIST= TMP=${TMP} PREFIX=${PREFIX} VAR=${VAR} PORTS=${PORTSDIR} - -DOCS_VARS_OFF= EVALDOCS=-nodoc - -do-install: - cd ${WRKSRC}/src && ${SH} install.sh \ - -prefix=${STAGEDIR}${PREFIX} \ - -ports=${STAGEDIR}${PORTSDIR} \ - -distdir=${STAGEDIR}${DISTDIR} \ - -datadir=${STAGEDIR}${DATADIR} \ - ${EVALDOCS} -.for n in distviper 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 -.endfor - ${MKDIR} ${STAGEDIR}${ETCDIR} - ${MV} ${STAGEDIR}${PREFIX}/etc/*.sample ${STAGEDIR}${ETCDIR} - ${RM} -r ${STAGEDIR}${PREFIX}/etc/*.sample - -post-install-DOCS-on: - ${MKDIR} ${STAGEDIR}${DOCSDIR} - cd ${WRKSRC} && ${INSTALL_DATA} ${PORTDOCS} ${STAGEDIR}${DOCSDIR} - -.include <bsd.port.mk> diff --git a/sysutils/bsdadminscripts/distinfo b/sysutils/bsdadminscripts/distinfo deleted file mode 100644 index db18c95f2235..000000000000 --- a/sysutils/bsdadminscripts/distinfo +++ /dev/null @@ -1,2 +0,0 @@ -SHA256 (bsdadminscripts-6.1.1.tar.gz) = 68b47c51801a8ce1e7b69ec654c7521b1b1fcf2d3fe9184f4d2e4a1b6f4656bb -SIZE (bsdadminscripts-6.1.1.tar.gz) = 73925 diff --git a/sysutils/bsdadminscripts/files/distviper.in b/sysutils/bsdadminscripts/files/distviper.in deleted file mode 100644 index e047e46b67de..000000000000 --- a/sysutils/bsdadminscripts/files/distviper.in +++ /dev/null @@ -1,227 +0,0 @@ -#!/bin/sh -# -# 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 name=distviper -readonly version=1.1 - -verbose= -demo= -quiet= -interactive= - -# Determine portsdir -portsdir="$(make -V PORTSDIR -f /usr/share/mk/bsd.port.mk)" -if [ ! -d "$portsdir" ]; then - echo "The PORTSDIR '$portsdir' is missing." - exit 1 -fi - -# Determine distdir -distdir="$(make -V DISTDIR -f /usr/share/mk/bsd.port.mk)" -if [ ! -d "$distdir" ]; then - echo "The DISTDIR '$distdir' is missing." - exit 2 -fi - -# Extract file from distinfo. -extractFileCmd="sed -E -e 's/^[^(]*\(//1' -e 's/\).*$//1'" - -# Display help. -printHelp() { - echo "$name v$version -usage: $name [-d] [-h] [-i] [-q] [-v] [fast|thorough]" -} - -# -# Handle parameters. -# -# @param $1 -# The parameter to handle. -# @param $verbose -# Is set to create verbose output. -# @param $demo -# Is set to only print the output that would occur. -# @param $quiet -# Is set to act without creating any output. -# @return -# Returns 0 if the processed parameter was a valid parameter, -# returns 1 if not. -# -readParams() { - case "$1" in - "-d" | "--demo") - demo=1 - return 0 - ;; - "-h" | "--help") - printHelp - exit 0 - ;; - "-i" | "--interactive") - interactive=-i - return 0 - ;; - "-q" | "--quiet") - quiet=1 - return 0 - ;; - "-v" | "--verbose") - verbose=1 - return 0 - ;; - -? | --*) - return 1 - ;; - -*) - # Split parameters. - # first parameter - readParams "${1%${1#-?}}" || return $? - # remaining parameters - readParams "-${1#-?}" - return $? - ;; - *) - return 1 - ;; - esac -} - -# -# This algorithm outputs the distfiles of installed ports. If a port downloads -# a distfile through depending on the fetch target of another port, it -# is missed, in case that other port is not installed as well. -# -# @param $portsdir -# The direcotry holding the ports tree. -# -getDistFiles_fast() { - for port in $(pkg_info -qoa); { - if [ -e "$portsdir/$port/distinfo" ]; then - eval "$extractFileCmd '$portsdir/$port/distinfo'" | uniq - fi - } -} - -# -# This algorithm outputs the distfiles of all ports. -# -# @param $portsdir -# The direcotry holding the ports tree. -# -getDistFiles_thorough() { - find -H "$portsdir" -type f -name distinfo | \ - eval "xargs $extractFileCmd" | uniq -} - -# The current parameter processing stage. -stage=params - -# The selected algorithm for finding distfiles to keep. -algorithm=thorough - -# Parse the command line parameters. -for command; { - # Read parameters until an unknown one is encountered. - # In that case switch into command stage. - if [ "$stage" = "params" ]; then - if ! readParams "$command"; then - stage=command - fi - fi - - # All parameters have been read, now either nothing or a mode - # command should occur. - if [ "$stage" = "command" ]; then - stage=end - case "$command" in - thorough | fast) - algorithm="$command" - ;; - -*) - echo "$name: Unknown parameter '$command'" \ - "encountered, exiting." 1>&2 - return 1 - ;; - *) - echo "$name: Unknown command '$command'" \ - "encountered, exiting." 1>&2 - return 2 - ;; - esac - # Skip everything following and continue with the next - # argument. - continue - fi - - # Still being in the loop at this stage means unexpected parameters - # have been encountered. - if [ "$stage" = "end" ]; then - echo "$name: The command '$command' is not allowed here, only" \ - "one command at a time is permitted." 1>&2 - return 3 - fi -} - -# Check for inprobable options. -if [ -n "$interactive" -a -n "$demo" ]; then - echo "$name: Interactive mode is ignored in demo mode." 1>&2 -fi - -test -n "$verbose" && echo "Create a list of up to date distfiles to keep" \ - "using a $algorithm algorithm:" - -# Create the list of files to keep, using the selected algorithm. -keepFiles="$(eval "getDistFiles_$algorithm" | sort -u)" -if [ -n "$verbose" ]; then - echo "$(($(echo "$keepFiles" | wc -l))) files recorded for keeping." - echo "Search and delete outdated distfiles:" -fi - -# Files before deletion. -filesCount="$(($(find -H "$distdir" -type f|wc -l)))" -filesDelete=0 - -# Seek and destroy files not in the $keepFiles list. -for file in $(find -H "$distdir" -type f); { - file="${file#$distdir/}" - - if (echo "$keepFiles" | grep -qx "$file"); then - test -n "$verbose" && echo "keep $file" - else - test -z "$quiet" && echo "delete $file" - test -z "$demo" && rm $interactive "$distdir/$file" - filesDelete=$(($filesDelete + 1)) - fi -} - -# The number of deleted files -filesDeleted="$(($filesCount - $(find -H "$distdir" -type f|wc -l)))" - -test -z "$demo" && find -H -d "$distdir" -type d -exec rmdir \{} \; 2> /dev/null - -if [ -n "$verbose" ]; then - echo "$filesDelete files were suggested for deletion." - echo "$filesDeleted files of $filesCount have been removed." -fi - -return 0 diff --git a/sysutils/bsdadminscripts/files/pkg_libchk.in b/sysutils/bsdadminscripts/files/pkg_libchk.in deleted file mode 100644 index 232e00947f54..000000000000 --- a/sysutils/bsdadminscripts/files/pkg_libchk.in +++ /dev/null @@ -1,484 +0,0 @@ -#!/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 diff --git a/sysutils/bsdadminscripts/files/pkg_upgrade.in b/sysutils/bsdadminscripts/files/pkg_upgrade.in deleted file mode 100644 index df50669e6ed4..000000000000 --- a/sysutils/bsdadminscripts/files/pkg_upgrade.in +++ /dev/null @@ -1,2239 +0,0 @@ -#!/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 - # index. - for package in $(pkg_version -IoL = ${PKG_INDEX}); { - origin="${package%% *}" - row="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin")" - pkgname="$(getIdxColumn $IDX_PKG "$row")" - printStatus "Checking <${pkgname:-$(pkg_info -qO $origin)}>." - operator="${package##* }" - case "$operator" in - '<') - older="$older${older:+$IFS}$origin;$pkgname" - ;; - '>') - newer="$newer${newer:+$IFS}$origin;$pkgname" - ;; - '?') - unindexed="$unindexed${unindexed:+$IFS}$origin" - ;; - '*') - multiple="$multiple${multiple:+$IFS}$origin" - ;; - '!') - error="$error${error:+$IFS}$origin" - ;; - esac - } - fi - - printStatus "Assemble checked packages ..." - - # Remove packages to upgrade from the list of outdated packages. - for package in $upgrade; { - older="$(echo "$older" | grep -vx "$package")" - } - - # Append outdated packages to the list of packages to update if all - # packages are to be updated. - if [ -n "$pAll" ]; then - downloadManagerMsgRequest "$older" - upgrade="$upgrade${older:+${upgrade:+$IFS}}$older" - older= - fi - - # Clear the status line. - printStatus - - # Print the discarded packages. - if [ -n "$pListDiscarded" ]; then - verbose "List discarded packages." - - discarded="$unindexed$IFS$multipleIFS$error" - discarded="$(echo "$discarded" | grep -vFx '' | sort -u)" - - test -n "$discarded" && echo "$discarded" - fi -} - -# -# Adds all missing dependencies to the list of packages to upgrade. -# -# @param 1 -# This is used to check the dependencies of newly added depending -# packages. -# @param upgrade -# The primary list of packages to upgrade (read only). -# @param upgradeDepends -# The list to add packages to upgrade to. -# @param older -# The list of outdated packages. Packages for upgrading are removed from -# it. -# @param dependsChecked -# A list of already checked dependencies, to avoid double checks. -# @param pRecursive -# If set, also add outdated dependencies to the upgrade list. -# @param pMoreRecursive -# If set, also update the dependencies of depending packages. -# @param pForce -# If set together with pRecursive, add all dependencies to the upgrade -# list. -# -pkgDepends() { - local pkgname package row rows depends origin escapedPkg upgradeList - - printStatus "Preparing dependency checks ..." - - # In thorough mode the depencies of depending packages are updated, too. - upgradeList="${1:-$upgrade}" - - # Luckily packages know their indirect dependencies, too. This way - # it is not necessary to check for dependencies recursively. - depends= - for package in $upgradeList; { - row="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/${package%;*}")" - row="$(getIdxColumn $IDX_DEPENDS "$row")" - depends="$depends${depends:+${row:+ }}$row" - } - - # Reformat depends and throw out duplicates. - depends="$( - echo "$depends" | sed "s/ /\\$IFS/g" | sort -u - )" - - # Do some prefiltering. - rows="$(getIdxRowsEscaped $IDX_PKG "$(echo "$depends" | rs -TC\|)")" - - # Check for missing or outdated dependencies. - for pkgname in $depends; { - escapedPkg="$(echo "$pkgname" | getIdxEscape)" - - # Skip packages already checked. - if echo "$dependsChecked" | grep -qFx "$pkgname"; then - continue - fi - dependsChecked="$dependsChecked${dependsChecked:+$IFS}$pkgname" - - printStatus "Check dependency <$pkgname>." - - # Skip this if this package is already scheduled for updating. - if echo "$upgrade${upgradeDepending:+$IFS$upgradeDepending}" | grep -qF ";$pkgname"; then - continue - fi - - row="$(getIdxRows $IDX_PKG "$escapedPkg" "$rows")" - - # If this package could not be identified this is an index - # incosistency, that can only be ignored. - if [ -z "$row" ]; then - warn "Ignore index inconsistency, the dependency <$pkgname> is not in the index." 1>&2 - continue - fi - - origin="$(getIdxColumn $IDX_ORIGIN "$row")" - origin="${origin#$idxports/}" - package="$origin;$(getIdxColumn $IDX_PKG "$row")" - - # - # Deal with dependencies according to set parameters. - # - if [ -z "$(pkg_info -qO "$origin")" ]; then - # The depency is not installed. - upgradeDepends="$upgradeDepends${upgradeDepends:+$IFS}$package" - # Request a package download. - downloadManagerMsgRequest "$package" - elif [ -n "$pMoreRecursive" -o -n "$pRecursive" -a -z "$1" ]; then - # Check whether the dependency is outdated. - if echo "$older" | grep -qFx "$package"; then - upgradeDepends="$upgradeDepends${upgradeDepends:+$IFS}$package" - older="$(echo "$older" | grep -vFx "$package")" - # Request a package download. - downloadManagerMsgRequest "$package" - fi - fi - } -} - -# -# Checks whether packages depending on the packages to update require updating. -# -# @param 1 -# This is used to check the depending packages of newly added -# dependencies. -# @param older -# The list of outdated packages. If pForce is set, this includes all -# installed packages listed in the index. -# @param upgrade -# The primary list of packages to upgrade (read only). -# @param upgradeDepending -# The list of depending packages to upgrade. -# @param pUpwardRecursive -# If not set nothing is done. -# @param pMoreUpwardRecursive -# Also check the depending packages of depencencies. -# @param pAll -# If this is set do nothing. -# -pkgDepending() { - # Without the upwardRecursive option this is completely - # unnecessary. - if [ -z "$pUpwardRecursive" ]; then - return 0 - fi - - # If all packages are already going to be upgraded, there is no - # need for this. - if [ -n "$pAll" ]; then - return 0 - fi - - # Only update depending packages of dependencies in thorough mode. - if [ -n "$1" -a -z "$pMoreUpwardRecursive" ]; then - return 0 - fi - - local package pkgname origin row depends escapedPkg upgradeList - - printStatus "Preparing upwards dependency checks ..." - - # In thorough mode the depencies of depending packages are updated, too. - upgradeList="${1:-$upgrade}" - - # Do some prefiltering. - rows="$(getIdxRowsEscaped $IDX_ORIGIN "$( - echo "$older" | rs -TC\| | sed -E "s'([^;|]*);[^|]*'$idxports/\1'g" - )")" - - # For each outdated package, check whether it depends on a package - # to upgrade. In force mode outdated packages are all packages, so - # the difference does not have to be made here. - for package in $older; { - # Skip this if this package is already scheduled for updating. - if echo "$upgrade${upgradeDepends:+$IFS$upgradeDepends}${upgradeDepending:+$IFS$upgradeDepending}" | grep -qFx "$package"; then - continue - fi - - printStatus "Check for upwards dependency <${package#*;}>." - - origin="${package%;*}" - row="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin" "$rows")" - - # Ignore unindexed packages. - if [ -z "$row" ]; then - continue - fi - - depends="$(getIdxColumn $IDX_DEPENDS "$row")" - - # It has no dependencies, so it cannot depend on anything - # in the upgrade list. - if [ -z "$depends" ]; then - continue - fi - - # Reformat dependencies. - depends="$(echo "$depends" | sed -Ee "s/([^ ]+)/;\1/g" -e "s/ /\\$IFS/g")" - - # Check every dependency for matching the upgrade packages. - if echo "$upgradeList" | grep -qF "$depends"; then - upgradeDepending="$upgradeDepending${upgradeDepending:+$IFS}$package" - older="$(echo "$older" | grep -vFx "$package")" - downloadManagerMsgRequest "$package" - fi - } -} - -# -# This function calls pkgDepending and pkgDepends until no new packages -# show up for updating. All the clever stuff happens in those functions. -# -# @param upgrade -# The list of packages to upgrade. -# @param upgradeDepends -# The list of dependencies to add to the list of packages to upgrade. -# @param upgradeDepending -# The list of depending packages to add to the list of packages -# to upgrade. -# -pkgDependencies() { - test -z "$upgrade" && return 0 - - verbose "Perform dependency checks." - - # Run the primary dependency checks. - pkgDepending - downloadManagerMsgRequest "$upgradeDepending" - pkgDepends - downloadManagerMsgRequest "$upgradeDepends" - - # The idea is to keep on checking until nothing new shows up. - # Whether that is the case depends on the level of recursiveness. - while [ -n "$upgradeDepends$upgradeDepending" ]; do - if [ -n "$upgradeDepends" ]; then - # Deal with packages depending on the updated packages. - pkgDepending "$upgradeDepends" - upgrade="$upgradeDepends$IFS$upgrade" - upgradeDepends= - fi - - if [ -n "$upgradeDepending" ]; then - # Deal with missing or outdated dependencies. - pkgDepends "$upgradeDepending" - upgrade="$upgrade$IFS$upgradeDepending" - upgradeDepending= - fi - done - - # Clear the status line. - printStatus -} - -# -# Prints a progress message to the terminal device /dev/tty. -# -# @param 1 -# Total amount of operations to do. -# @param 2 -# The amount of operations performed. -# @param 3 -# The name of the package that is currently operated on. -# @param 4 -# The text prepending the progress information. -# @param status -# The last printed message, used for clearing the status line before -# printing a new status. -# @param pClean -# If set, do not print progress messages. -# -printProgress() { - test -n "$pClean" && return 0 - printf "\r%${#status}s\r$4 %${#1}s of %${#1}s (%3s%%) <$3>.\r" '' "$2" "$1" "$(($2 * 100 / $1))" > /dev/tty - status="$4 $1 of $1 (100%) <$3>." -} - -# -# Sorts the packages to upgrade by dependency. -# -# The trick is to have a list of already sorted packages. Each package added -# to the list is inserted right behind its last dependency already present -# there. -# Packages without any dependencies in the sorted list are prepended. This -# way it is ensured that they end up before all already sorted packages -# that depend on them, without additional checking. -# -# @param upgrade -# The list of packages to sort. -# @param pParanoid -# If set, make cyclic dependency checks. -# -pkgSort() { - local rows sorted package row depends dependency pkgname - local totalCount count - - test -z "$upgrade" && return 0 - - verbose "Sort packages by dependency." - - printStatus "Prepare sorting of packages ..." - - # Limit rows to whatever is currently required. - rows="$(getIdxRowsEscaped $IDX_ORIGIN "$( - echo "$upgrade" | getIdxEscape -e 's/;.*//1' -e "s,^,$idxports/,1" | rs -TC\| - )")" - - # The number of packages - totalCount=$(($(echo "$upgrade" | wc -l))) - count=0 - - # Sort each package into the list of sorted packages. - sorted= - for package in $upgrade; { - count=$(($count + 1)) - pkgname="${package#*;}" - printProgress $totalCount $count "$pkgname" 'Sort' - - # Get the list of dependencies that should be updated before - # the current package. - row="$(getIdxRowsEscaped $IDX_PKG "$pkgname" "$rows")" - depends="$(getIdxColumn $IDX_DEPENDS "$row" | sed -E "s/ /\\$IFS/g")" - - # Get the last matching dependency in the list. - dependency="$(echo "$sorted" | grep -Fx "$depends" | tail -n 1)" - - # If there is no match, just prepend to the list. - if [ -z "$dependency" ]; then - sorted="$pkgname${sorted:+$IFS$sorted}" - continue - fi - - # Insert right behind the match. - dependency="$(echo "$dependency" | getIdxEscape)" - sorted="$(echo "$sorted" | sed -E "s/^$dependency$/$dependency\\$IFS$pkgname/1")" - } - - # Perform optional cyclic dependency check. - if [ -n "$pParanoid" ]; then - printStatus "Validate sorting order ..." - - # Validate the sort order. - count=0 - for pkgname in $sorted; { - count=$(($count + 1)) - printProgress $totalCount $count "$pkgname" 'Validate' - - # Get the list of dependencies that should be updated before - # the current package. - row="$(getIdxRowsEscaped $IDX_PKG "$pkgname" "$rows")" - depends="$(getIdxColumn $IDX_DEPENDS "$row" | sed -E "s/ /\\$IFS/g")" - - # Append the package to the list of dependencies to match. - depends="${depends:+$depends$IFS}$pkgname" - - # Get the last match in the list. - dependency="$(echo "$sorted" | grep -Fx "$depends" | tail -n 1)" - # The last match has to be the package. - if [ "$dependency" != "$pkgname" ]; then - error $ERR_SORT "The package <$pkgname> was not sorted properly, a likely cause is a circular dependency." - fi - } - fi - - printStatus "Assemble sorted packages ..." - - # Replace package names with <origin>;<package> pairs. - for package in $upgrade; { - pkgname="$(echo "${package#*;}" | getIdxEscape)" - sorted="$(echo "$sorted" | sed -E "s'^$pkgname\$'$package'1")" - } - - upgrade="$sorted" - printStatus -} - -# -# Prints the update/replace/install task. -# -# @param 1 -# The package to upgrade/install. -# @param replace -# The list of packages to replace. -# -printTask() { - local package newPkgname newOrigin oldPkgname oldOrigin - - # Get the name and origin of the new package. - newPkgname="${1#*;}" - newOrigin="${1%;*}" - - # Look for a package the new one replaces. - package="$(echo "$replace" | grep -F "$1|")" - - # Look for a package this one replaces. - # The current package actually replaces another one. - if [ -n "$package" ]; then - # Get the name and origin of the old package. - package="${package#*|}" - oldPkgname="${package#*;}" - oldOrigin="${package%;*}" - - echo "Replace <$oldPkgname> ($oldOrigin) with <$newPkgname> ($newOrigin)" - return 0 - fi - - # Check whether there's an old version of this package around. - package="$(pkg_info -qO "$newOrigin")" - - # An older package with this origin is installed. - if [ -n "$package" ]; then - echo "Update <$package> to <$newPkgname> ($newOrigin)" - return 0 - fi - - # Aparently this package will be newly installed. - echo "Install <$newPkgname> ($newOrigin)" -} - -# -# List the packages that are going to be upgraded, installed and replaced. -# If the 'no actions' mode is active. -# -# @param upgrade -# The list of packages to upgrade. -# @param pNoActions -# Print the list of tasks. -# -pkgList() { - # Only list packages in "no actions" mode. - test -z "$pNoActions" && return 0 - - test -z "$upgrade" && return 0 - - local package - - verbose "The following packages will be updated:" - - for package in $upgrade; { - printTask "$package" - } -} - -# -# Wait for downloaded packages and validate them. -# -# @param upgrade -# The list of packages to download. -# @param pending -# The list of pending downloads. -# @param packagerepos -# The location of the remote package repository (derived from -# PACKAGESITE). If this is identical with the local repository, -# the download manager was not started. -# @param pNoActions -# Do not download anything. -# -pkgDownload() { - test -n "$pNoActions" && return 0 - - test -z "$upgrade" && return 0 - - local package total count line - - verbose "Validate downloaded packages." - - printStatus "Waiting for downloads ..." - - # Create a list of the package names to validate. - # Entries are removed from this list by validatePackage(). - pending="$(echo "$upgrade" | sed 's/.*;//1')" - - # The total number of packages to validate. - total="$(($(echo "$upgrade" | wc -l)))" - - # Check whether the download manager is available. - if [ "$PACKAGES" = "$packagerepos" ]; then - # - # The local repository is identical with the remote repository - # so the assumption is all packages should already be there. - # - - # Validate all packages. - for package in $pending; { - count=$(($count + 1)) - printProgress $total $count "$package" "Validate" - validatePackage "$package" - } - else - # - # The download manager is available, so hang on to its message - # queue and proceed with validating as packages are finished. - # - count=0 - - while [ -n "$pending" ]; do - read line - case "$line" in - finished:*) - count=$(($count + 1)) - package="${line##*;}" - printProgress $total $count "$package" "Validate" - validatePackage "$package" - ;; - esac - done < "$queueMessages" - - # Stop the download manager. - downloadManagerMsgExit - fi - - # Clear the status line. - printStatus -} - -# -# Upgrade each package. -# -# @param upgrade -# The list of packages to upgrade. -# @param conflictReplace -# This list is reset for conflict handling. -# @param pNoActions -# Do not update anything. -# @param pFetchOnly -# Do not update anything. -# -pkgUpgrade() { - test -n "$pNoActions" -o -n "$pFetchOnly" && return 0 - - test -z "$upgrade" && return 0 - - local package - - verbose "Install $(($(echo "$upgrade" | wc -l))) package(s)." - - for package in $upgrade; { - upgradePackage "$package" - } -} - -# -# To handle conflicts this function removes dependencies from a given package -# and appends one or more new ones to take their place. Also the +REQUIRED_BY -# files of the appended dependencies are updated. -# -# @param 1 -# The name of the package to which to apply the substitutions. -# @param substituteDepends -# The list of dependency substitutions that should take place. -# -substituteDepends() { - # End here if there's nothing to substitute. - test -z "$substituteDepends" && return 0 - - local line originalOrigin originalPkgname newOrigin newPkgname - local contents append remove requiredBy - - printStatus "Adjust the dependencies of <$1> ..." - - # Get the contents file. - contents="$(cat "$PKG_DBDIR/$1/+CONTENTS")" - - # Because there can be several substitutions for a single package - # the new ones will be added to the end of the +CONTENTS file and all - # the matches will be removed later. - append= - remove= - for line in $substituteDepends; { - # Get original origin and package name from the line. - originalOrigin="${line%%;*}" - originalPkgname="${line%|*}" - originalPkgname="${originalPkgname#*;}" - - # Continue with the next line if this one does not match. - if ! echo "$contents" | grep -qFx "@pkgdep $originalPkgname"; then - continue - fi - - # Get new origin and package name from the line. - newOrigin="${line#*|}" - newPkgname="${newOrigin#*;}" - newOrigin="${newOrigin%;*}" - - warn "Add dependency <$newPkgname> ($newOrigin)." - - # Remember what to append and what to remove. - remove="${remove:+$remove$IFS}@pkgdep $originalPkgname$IFS@comment DEPORIGIN:$originalOrigin" - # Just for the very unlikely case that two dependencies get - # replaced for conflicting with the same package, check that - # a dependency is not added twice. - if ! echo "$append" | grep -qFx "@pkgdep $newPkgname"; then - append="$append$IFS@pkgdep $newPkgname$IFS@comment DEPORIGIN:$newOrigin" - fi - - # Make an entry for the package in the +REQUIRED_BY file of - # of the dependency to append. - requiredBy="$(cat "$PKG_DBDIR/$newPkgname/+REQUIRED_BY" 2> /dev/null)" - requiredBy="${requiredBy:+$requiredBy$IFS}$1" - echo "$requiredBy" | sort -u > "$PKG_DBDIR/$newPkgname/+REQUIRED_BY" - } - - # Remove the original dependency entries. - contents="$(echo "$contents" | grep -vFx "$remove")" - # Write the new file. Note that $append always starts with a newline. - echo "$contents$append" > "$PKG_DBDIR/$1/+CONTENTS" -} - -# -# Install the given package. This is where the magic happens. -# -# @param replace -# The list of packages to replace (read only). -# @param substituteDepends -# A list of dependency substitutions that should take place for each -# newly installed package to resolve conflicting packages. -# @param packagebackup -# The location for backup packages. This is derived from PACKAGES. -# @param pNoBackup -# If set, delete backups after successful completion. -# -upgradePackage() { - local task targetPackage targetPkgname targetOrigin package replace - local escapedPkg removePackages origin file conflict conflicting - local replacePkgdep requiredBy count - local signal - - # Get a string with the current upgrade task. - task="$(printTask "$1")" - echo "===> $task" - - targetPackage="$1" - targetPkgname="${1#*;}" - targetOrigin="${1%;*}" - - printStatus "Prepare installation of <$targetPkgname> ..." - - # Get the packages to replace with this one. Several packages can be - # replaced with a single one. - escapedPkg="$(echo "$targetPackage" | getIdxEscape)" - replace="$(echo "$replace" | grep -Ex "$escapedPkg\|.*" | sed -E "s'^$escapedPkg\|''1")" - - # Append the current package to the list of packages to replace. - replace="${replace:+$replace$IFS}$targetPackage" - - # Create the list of outdated packages that have to be backed up - # and for which pkgdb adjustments have to be made after successful - # installation of the new package. - # Also create the necessary sed expressions to update the - # package database. - removePackages= - replacePkgdep= - for package in $replace; { - origin="${package%;*}" - package="$(pkg_info -qO "$origin")" - test -z "$package" && continue - removePackages="$removePackages${removePackages:+$IFS}$package" - package="$(echo "$package" | getIdxEscape)" - replacePkgdep="$replacePkgdep -e 's|^@pkgdep $package\$|@pkgdep $targetPkgname|1'" - if [ "$origin" != "$targetOrigin" ]; then - replacePkgdep="$replacePkgdep -e 's|^@comment DEPORIGIN: $origin\$|@comment DEPORIGIN:$targetOrigin|1'" - fi - - } - - # Get a list of conflicting packages. The conflicts list is - # provided by readContents(). - readContents "$PACKAGES/All/$targetPkgname.tbz" - conflicting= - for conflict in $conflicts; { - # Match the conflict pattern against installed packages. - for conflict in $(pkg_info -E "$conflict"); { - escapedPkg="$(echo "$conflict" | getIdxEscape)" - # Only add to the conflicting list if the conflicting - # package is not in the list of packages to replace. - if ! echo "$removePackages" | grep -qEx "$escapedPkg"; then - conflicting="${conflicting:+$conflicting$IFS}$conflict" - fi - } - } - # Remove duplicated entries. - conflicting="$(echo "$conflicting" | sort -u)" - - # Check whether any conflicts were found. - if [ -n "$conflicting" ]; then - # What happens now depends on the user preferences. - if [ -n "$pExitOnConflict" ]; then - # The user has chosen to bail out when a conflict - # occurs. - log $ERR_CONFLICT "$task" - error $ERR_CONFLICT "The package <$targetPkgname> conflicts with the following packages:$IFS$conflicting" - elif [ -n "$pReplaceConflicts" ]; then - # The user has chosen that conflicting packages should - # be replaced as if they were explicitly listed for - # replacing. - conflicts= - for package in $conflicting; { - warn "The package <$package> conflicts with <$targetPkgname> and will be replaced." - removePackages="$removePackages${removePackages:+$IFS}$package" - origin="$(pkg_info -qo "$package")" - # The next line is just for prettier log output. - conflicts="${conflicts:+$conflicts, }<$package> ($origin)" - package="$(echo "$package" | getIdxEscape)" - replacePkgdep="$replacePkgdep -e 's|^@pkgdep $package\$|@pkgdep $targetPkgname|1'" - if [ "$origin" != "$targetOrigin" ]; then - replacePkgdep="$replacePkgdep -e 's|^@comment DEPORIGIN: $origin\$|@comment DEPORIGIN:$targetOrigin|1'" - fi - } - log 0 "Conflict <$targetPkgname> ($targetOrigin) remove package(s) $conflicts" - else - # The default action is to assume that the conflicting - # packages fulfill the required functionality. - conflicts= - for package in $conflicting; { - warn "The package <$targetPkgname> will not be installed in favour of <$package>, because they conflict." - origin="$(pkg_info -qo "$package")" - # Record the necessary substitutions. - # TODO: Later versions will have to store this - # for resume. - substituteDepends="${substituteDepends:+$substituteDepends$IFS}$targetPackage|$origin;$package" - # This is just for prettier log output. - conflicts="${conflicts:+$conflicts, }<$package> ($origin)" - } - # Log the conflict resolution. - log 0 "Conflict <$targetPkgname> ($targetOrigin) favour package(s) $conflicts" - # Skip to the next package. - return 0 - fi - fi - - # Backup packages. - mkdir -p "$packagebackup" - for package in $removePackages; { - printStatus "Backup <$package>." - pkg_create -b "$package" "$packagebackup/$package" - case $? in - 0) - # Everything went well. - ;; - 1) - # If this happens someone's been messing with - # the packages just milliseconds ago. - log $ERR_BACKUP_MISS "$task" - error $ERR_BACKUP_MISS "The backup of <$package> failed. The package is missing." - ;; - 2) - # Fortunately pkg_create backs up as much as - # as is possible. That the backup (and hence - # the present package) is incomplete is all - # the more reason to upgrade. - # I do not understand why portmaster is - # interactive in this case. - warn "Ignoring incomplete backup of <$package>." - ;; - *) - # Well, I've got no idea at all what else - # could go wrong. Too bad the return codes - # of pkg_create are not documented. - log $ERR_BACKUP_UNKNOWN "$task" - error $ERR_BACKUP_UNKNOWN "The backup of <$package> failed for unknown reasons." - ;; - esac - } - - # Block SIGINT (CTRL-C), because that would really wrack havoc upon - # the package database in the following section. - signal= - trap "signal=$ERR_USER" sigint - trap "signal=$ERR_TERM" sigterm - - # Delete packages. - requiredBy= - count=-1 - for package in $removePackages; { - printStatus "Delete <$package>." - # Remember +REQUIRED_BY contents for roll-back. - count=$(($count + 1)) - local "requiredBy$count" - setvar "requiredBy$count" "$(cat "$PKG_DBDIR/$package/+REQUIRED_BY" 2> /dev/null)" - # Remember +REQUIRED_BY contents for the new package. - requiredBy="${requiredBy:+$requiredBy$IFS}$(cat "$PKG_DBDIR/$package/+REQUIRED_BY" 2> /dev/null)" - # Finally delete the package. - pkg_delete -f "$package" - } - - # Update the package database. - printStatus "Update package database for <$targetPkgname>." - if [ -n "$replacePkgdep" ]; then - for file in $(find "$PKG_DBDIR" -name '+CONTENTS'); { - eval "sed -Ei '.$name' $replacePkgdep '$file'" - } - fi - - # If an old version of this package was favoured in a conflict, - # the substituteDepends list has to be changed. - substituteDepends="$(echo "$substituteDepends" | sed "s'\|$targetOrigin;.*'|$targetPackage'1")" - - # Try to install the new package. - printStatus "Install <$targetPkgname>." - if ! env PKG_PATH="$PACKAGES/All" pkg_add -f "$targetPkgname"; then - # Installation went wrong, roll back! - printStatus "Roll back changes for <$targetPkgname>." - for file in $(find "$PKG_DBDIR" -name "*.$name"); { - mv -f "$file" "${file%.$name}" - } - count=-1 - for package in $removePackages; { - # Restore package. - env PKG_PATH="$packagebackup" pkg_add -f "$package" - # Recover +REQUIRED_BY file. - count=$(($count + 1)) - eval "echo \"\$requiredBy$count\"" > "$PKG_DBDIR/$package/+REQUIRED_BY" - # Remove the backup if set. - test -n "$pNoBackup" && rm "$packagebackup/$package.tbz" - } - log $ERR_INSTALL "$task" - error $ERR_INSTALL "The installation of <$targetPkgname> failed." - fi - - # Add the +REQUIRED_BY contents of all deleted packages to the - # +REQUIRED_BY file of the new one. - requiredBy="$(echo "$(cat "$PKG_DBDIR/$targetPkgname/+REQUIRED_BY" 2> /dev/null)$IFS$requiredBy" | grep -vFx '' | sort -u)" - echo "$requiredBy" > "$PKG_DBDIR/$targetPkgname/+REQUIRED_BY" - - # Make dependency substitutions from conflict resolving. - substituteDepends "$targetPkgname" - - # Log successful completion of the task. - log 0 "$task" - - # Remove backups if set. - if [ -n "$pNoBackup" ]; then - for package in $removePackages; { - printStatus "Remove backup of <$package>." - rm "$packagebackup/$package.tbz" - } - fi - - # Remove package database backups. - # TODO: Later versions will instead store them to allow a rollback. - printStatus "Remove database backups for <$targetPkgname>." - find "$PKG_DBDIR" -name "*.$name" -exec rm \{\} \; - - # Clear the status line. - printStatus - echo "=> $task succeeded" - - # Bail out if SIGINT or SIGTERM were encountered. - if [ -n "$signal" ]; then - error $signal "The process was interrupted." - fi - - # Reactivate default signal handlers. - trap - sigint sigterm -} - -# -# Identify the package by a given string. Outputs the origin of all matched -# packages, as well as the package name of the newest available package. -# The output is in the following shape: -# <origin>;<package> -# -# The shell wildcards '*' and '?' are supported. -# Origin and package names with wildcards are matched against installed -# packages. Unambiguous package names and origins are matched against the -# index. -# -# @param 1 -# The package identifier to find matches for. -# -identifyPackage() { - local packages package mangledPackage rows matchingRows mangledRows - local origins origin guess escapedPkg - - # Check for wildcards. - guess= - if echo "$1" | grep -qE '\*|\?|\[.*]'; then - guess=1 - fi - package="$1" - - # Distuinguish between origins and packages. - case "$package" in - */*) - # An origin has been given. - if [ -n "$guess" ]; then - # Wildcards present, match against installed - # packages. - - # Get all matching packages. - packages="$(pkg_info -qO "$package")" - - # Convert for use in a regular expression. - package="$(echo "$package" | getIdxEscape -e 's/\*/[^|]*/g' -e 's/\?/[^|]/g')" - # Get rows matching the given package origin. - # This is a performance tweak, so the whole - # index will not have to be parsed in the - # following output loop. - rows="$(getIdxRows $IDX_ORIGIN "$idxports/$package")" - - # Output all matching packages. - for package in $packages; { - # Get the origin. - origin="$(pkg_info -qo "$package")" - - # Match this package origin against the - # previously filtered rows. - package="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin" "$rows")" - # Get the package name of the newest - # package from the index. - package="$(getIdxColumn $IDX_PKG "$package")" - # Output origin/package pair. - echo "$origin;$package" - } - - # If no matches have been found, terminate. - if [ -z "$packages" ]; then - error $ERR_ARG "Package origin <$package> not matched by any installed package!" 1>&2 - fi - else - # There is an unambigious origin, match it - # against the index. - origin="$package" - # Get the index row. - rows="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin")" - # Get the package name column. - package="$(getIdxColumn $IDX_PKG "$rows")" - # Output origin/package pair, if a package for - # the given origin was found. - if [ -n "$package" ]; then - # Output origin/package pair. - echo "$origin;$package" - else - error $ERR_ARG "Package origin <$origin> not in index!" 1>&2 - fi - fi - ;; - *) - # A package name has been given. - if [ -n "$guess" ]; then - # Wildcards present, match against installed - # packages. - - # Get the origins of matching packages. - origins="$(pkg_info -qo "$package")" - - # Prepare the package name for use in a - # regular expression. - package="$(echo "$package" | getIdxEscape -e 's/\*/[^|]*/g' -e 's/\?/[^|]/g')" - # Get rows matching the given package name. - # This is a performance tweak, so the whole - # index will not have to be parsed in the - # following output loop. - rows="$(getIdxRows $IDX_PKG "$package")" - # Output all matching packages. - for origin in $origins; { - # Get the index row for this origin. - package="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin" "$rows")" - # Get the latest package name from the - # index. - package="$(getIdxColumn $IDX_PKG "$package")" - # Output origin/package pair. - echo "$origin;$package" - } - - # If no matches have been found, terminate. - if [ -z "$origins" ]; then - error $ERR_ARG "Package identifier <$package> not matched!" 1>&2 - fi - else - # A package name without wildcards has been - # given. This is expected to either be an exact - # package name or a LATEST_LINK name. - - # TODO: This would be much better if - # LATEST_LINK was known. This is information - # simply missing in the index. - # To make up for this some guessing is done in - # case of no matches or more than one match. - # But this fails for apache13 and probably - # other packages as well. - - # First try whether it is the current version - # of a package. - origin="$(pkg_info -qo "$package" 2> /dev/null)" - if [ -n "$origin" ]; then - # Get the matching index rows. - rows="$(getIdxRowsEscaped $IDX_ORIGIN "$idxports/$origin")" - fi - - # If it's not a current version, match against - # the index. - if [ -z "$rows" ]; then - # Get the matching rows. This should be - # only one, but it won't be for ports - # that define a proprietary LATEST_LINK. - escapedPkg="$(echo "$package" | getIdxEscape)" - rows="$(getIdxRows $IDX_PKG "$escapedPkg(-[^-]+)?")" - fi - - # No match, start some guessing. - # This fails for packages with a version tail, - # which is just what is wanted. - if [ -z "$rows" ]; then - # Assume this is a LATEST_LINK kind - # package name and remove the trailing - # numbers. - mangledPackage="$(echo "$package" | sed -E 's/[0-9]+$//1')" - # Get the matching rows, this is likely - # to be too many (i.e. more than one). - rows="$(getIdxRows $IDX_PKG "$mangledPackage-[^-]+")" - fi - - # If there is more than one matching row, - # try to match against the origin. - if [ "$(($(echo "$rows" | wc -l)))" -gt "1" ]; then - # Match against the origin. - rows="$(getIdxRows $IDX_ORIGIN "[^|]*/$package" "$rows")" - - # If there is still more than one - # match, match against the origins - # of existing packages. - if [ "$(($(echo "$rows" | wc -l)))" -gt "1" ]; then - for origin in $(getIdxColumn $IDX_ORIGIN "$rows"); { - test -n "$(pkg_info -qO "$origin")" \ - && matchingRows="$matchingRows${matchingRows:+$IFS}$(getIdxRowsEscaped $IDX_ORIGIN "$origin" "$rows")" - } - rows="$matchingRows" - fi - - # Either a single origin is matched or - # it's time to bail out and give up. - if [ "$(($(echo "$rows" | wc -l)))" -ne "1" ]; then - # The wrong amount of matches - # has occured. Bail out. - error $ERR_ARG "Package identifier <$package> not unambiguously matched!" 1>&2 - fi - fi - - # Output if a package has been matched. - if [ -n "$rows" ]; then - # Get the origin of the given package. - origin="$(getIdxColumn $IDX_ORIGIN "$rows")" - # Geth the package name. - package="$(getIdxColumn $IDX_PKG "$rows")" - # Output origin/package pair. - echo "${origin#$idxports/};$package" - else - error $ERR_ARG "Package identifier <$package> not in index!" 1>&2 - fi - fi - ;; - esac -} - -# -# Prints the parameter list and terminates the program. -# -printHelp() { - printf "$name v$version -usage: - $name -h - $name -a [-b] [-bcCdfFlnpvX] [-o new existing] [update] [install] - $name [-bcCdfFlnpvX] [-r [-r]] [-R [-R]] [-o new existing] - %${#name}s [update] [install]\n" '' - exit 0 -} - -# -# Parse the command line parameters. -# -# @param upgrade -# A list of packages to upgrade. -# @param depth -# This is used by the function to store the recursion depth and -# should be unset when calling it. -# @param origin -# This is used by the function across differtent recursion depths to -# remember whether a package origin is expected. -# @param pAll -# Is set if all packages should be update. -# @param pNoBackup -# Is set if backups could not be fetched. -# @param pClean -# Is set to turn off status messages. -# @param pReplaceConflicts -# Is set to replace conflicting packages with new ones instead of -# leaving them alone. -# @param pExitOnConflict -# Is set to stop the program if a conflict is encountered. -# @param pForce -# Is set to force the update of packages that are not really updated. -# @param pFetchOnly -# Is set to only fetch packages instead of installing/upgrading them. -# @param pInteractive -# TODO: Reserved for future versions (resume/roll-back). -# @param pJobs -# TODO: Reserved for future versions (pkg_libchk tests). -# @param pListDiscarded -# Is set to activate the listing of packages that are ignored because -# they are not set in the INDEX. -# @param pNoActions -# Is set if no actions should be performed but a list of what would have -# been done should get printed. -# @param pNoLogging -# Turn off logging. -# @param pParanoid -# Is set to activate cyclic dependency checks. -# @param pRecursive -# Is set to activate updating of dependencies. -# @param pMoreRecursive -# Is set to activate updating of dependencies of depending packages. -# @param pUpwardRecursive -# Is set to activate updating of depending packages. -# @param pMoreUpwardRecursive -# Is set to activate updating of packages depending on dependencies. -# @param pVerbose -# Is set to activate informative output. -# -readParams() { - local arg package escapedPkg depth - # Store the recursion depth. Note that counting down is dealt with - # by making depth local. - depth=$((${depth:--1} + 1)) - - # This is used to remember whether the next parameter should - # be a replacing package or a packge to be replaced. - origin=${origin:-0} - - for arg { - # - # Handle package replacements. - # - if [ $origin -eq 1 ]; then - # Store the replacement. - package="$(identifyPackage "$arg")" || exit $? - if [ -z "$package" -o "$(($(echo "$package" | wc -l)))" -ne "1" ]; then - error $ERR_ARG "The package identifier <$arg> is not unambiguous." - fi - upgrade="$upgrade${upgrade:+$IFS}$package" - replace="$replace${replace:+$IFS}$package" - origin=2 - # Request the download. - downloadManagerMsgRequest "$package" - continue - fi - if [ $origin -eq 2 ]; then - # Store what to replace. - # This is taken from the package database not the index. - - case "$arg" in - */*) - # Assume arg is an origin. - package="$(pkg_info -qO "$arg")" - package="$(pkg_info -qo "$package" 2> /dev/null);$package" - ;; - *) - # Assume arg is a package identifier. - package="$(pkg_info -qo "$arg" 2> /dev/null);$(pkg_info -E "$arg" 2> /dev/null)" - - # Maybe arg is a package identifier - # without a version tail. - if [ "$package" = ";" ]; then - package="$(pkg_info -qo "$arg-*" 2> /dev/null);$(pkg_info -E "$arg-*" 2> /dev/null)" - fi - ;; - esac - - # Arg is not installed. - if [ "$package" = ";" ]; then - error $ERR_ARG "The package <$arg> is not installed and thus cannot be replaced." - fi - # It appears arg is an identifier that is - # not unambiguous. - if [ "$(($(echo "$package" | wc -l)))" -ne "1" ]; then - error $ERR_ARG "The package identifier <$arg> is not unambiguous." - fi - # A package can only be replaced once. - escapedPkg="$(echo "$package" | getIdxEscape)" - if echo "$replace" | grep -qEx ".*\|$escapedPkg"; then - error $ERR_ARG "The package <$arg> is already listed for replacement." - fi - replace="$replace|$package" - origin=0 - continue - fi - - # - # Identify arguments. - # - case "$arg" in - "-a" | "--all") - pAll=1 - if [ -n "$pRecursive" ]; then - error $ERR_ARG "Recursiveness has no effect, because all packages are already selected for processing." - fi - if [ -n "$pUpwardRecursive" ]; then - error $ERR_ARG "Upward recursiveness has no effect, because all packages are already selected for processing." - fi - ;; - "-b" | "--no-backup") - pNoBackup=1 - ;; - "-c" | "--clean") - pClean=-c - ;; - "-C" | "--replace-conflicts") - if [ -n "$pExitOnConflict" ]; then - error $ERR_ARG "The 'replace conflicts' and 'exit on conflict' modes are mutually exclusive." - fi - pReplaceConflicts=1 - ;; - "-d" | "--list-discarded") - pListDiscarded=1 - ;; - "-f" | "--force") - pForce=1 - ;; - "-F" | "--fetch-only") - if [ -n "$pNoActions" ]; then - error $ERR_ARG "The 'no actions' and 'fetch only' modes are mutually exclusive." - fi - pFetchOnly=1 - ;; - "-h" | "--help") - printHelp - ;; - "-i" | "--interactive") - # TODO: not yet used - pInteractive=1 - ;; - -j* | --jobs*) - # TODO: not yet used - pJobs="$arg" - if ! pkg_libchk "$pJobs" DUMMY/DUMMY 1>&2; then - exit $ERR_ARG - fi - ;; - "-l" | "--no-logging") - pNoLogging=1 - ;; - "-n" | "--no-actions") - if [ -n "$pFetchOnly" ]; then - error $ERR_ARG "The 'no actions' and 'fetch only' modes are mutually exclusive." - fi - pNoActions=1 - ;; - "-o" | "--origin") - # Make sure the local index copy is up to date. - getIndex - origin=1 - ;; - "-p" | "--paranoid") - pParanoid=1 - ;; - "-r" | "--recursive") - if [ -n "$pMoreRecursive" ]; then - error $ERR_ARG "There are only two levels of recursiveness." - elif [ -n "$pRecursive" ]; then - pMoreRecursive=1 - else - pRecursive=1 - fi - if [ -n "$pAll" ]; then - error $ERR_ARG "Recursiveness has no effect, because all packages are already selected for processing." - fi - ;; - "-R" | "--upward-recursive") - if [ -n "$pMoreUpwardRecursive" ]; then - error $ERR_ARG "There are only two levels of upward recursiveness." - elif [ -n "$pUpwardRecursive" ]; then - pMoreUpwardRecursive=1 - else - pUpwardRecursive=1 - fi - if [ -n "$pAll" ]; then - error $ERR_ARG "Upward recursiveness has no effect, because all packages are already selected for processing." - fi - ;; - "-v" | "--verbose") - pVerbose=-v - ;; - "-X" | "--exit-on-conflict") - if [ -n "$pReplaceConflicts" ]; then - error $ERR_ARG "The 'exit on conflict' and 'replace conflicts' modes are mutually exclusive." - fi - pExitOnConflict=1 - ;; - -? | --*) - error $ERR_ARG "Unknown parameter \"$arg\"." - ;; - -*) - # Split parmeters. - readParams "${arg%%${arg#-?}}" "-${arg#-?}" - ;; - *) - # Make sure the local index copy is up to date. - getIndex - # Add package to the list of packages to - # upgrade/install. - package="$(identifyPackage "$arg")" || exit $? - upgrade="$upgrade${upgrade:+$IFS}$package" - # Request the download. - downloadManagerMsgRequest "$package" - ;; - esac - } - - # - # Only perform the following steps if this is the root call - # to this function (recursion depth = 0). - # - if [ $depth -eq 0 ]; then - # - # Deal with missing parameters. - # - if [ $origin -eq 1 ]; then - error $ERR_ARG "Incomplete parameters, missing origin." - fi - if [ $origin -eq 2 ]; then - error $ERR_ARG "Incomplete parameters, missing package to replace." - fi - - # - # Deal with invalid levels of recursiveness. - # - if [ -n "$pMoreRecursive" -a -z "$pUpwardRecursive" ]; then - error $ERR_ARG "Thorough recursiveness can only be used in conjunction with upwards recursiveness." - fi - - # - # Remove duplicates in the list of packages to upgrade. - # - upgrade="$(echo "$upgrade" | sort -u)" - # Reset global variables. - origin= - fi -} - -# -# Reads all the required +CONTENTS information from a package. -# The information is stored in variables. -# -# @param 1 -# The name of the package file. -# @param pkgname -# The name of the package. -# @param origin -# The origin of the package. -# @param depends -# The dependencies of the package in the format "<origin>;<package>", -# in reverse order. -# @param conflicts -# A list of regular expressions that can be used to identify conflicting -# packages. -# -readContents() { - local contents line format - contents="$(tar -xOf "$1" '+CONTENTS')" - format= - - pkgname= - origin= - depends= - conflicts= - for line in $contents; { - case "$line" in - @name\ *) - pkgname="${line#@name }" - ;; - @pkgdep\ *) - depends=";${line#@pkgdep }${depends:+$IFS}$depends" - ;; - @comment\ *) - line="${line#@comment }" - case "$line" in - DEPORIGIN:*) - depends="${line#*:}$depends" - ;; - PKG_FORMAT_REVISION:*) - format="${line#*:}" - ;; - ORIGIN:*) - origin="${line#*:}" - ;; - esac - ;; - @conflicts\ *) - conflicts="${conflicts:+$conflicts$IFS}${line#@conflicts }" - ;; - esac - } - - if [ "$format" != "1.1" ]; then - error $ERR_PACKAGE_FORMAT "Unknown package format in <$1>, bailing out!" - fi - - return 0 -} - -# -# Starts a download manager that can be instructed through a queue. -# A process that wants to know what's going on with the download manager -# can simply read from the queue as well. -# -# The download manager keeps as many downloads running as there are -# PACKAGESITE_MIRRORS. Should a download fail, it is retried as soon -# as no untried downloads remain. Every download is only retried once. -# A download is never attempted from the master server. -# -# @param queueMessages -# The queue to create and read from. -# @param packagerepos -# The location of the remote package repository (derived from -# PACKAGESITE). If this is identical with the local repository, -# the download manager will not be started. -# @param pNoActions -# If set, the download manager will not be started. -# -downloadManager() { - # No actions mode, this includes no downloads. - test -n "$pNoActions" && return 0 - - # Packages are locally available, no downloads. - test "$PACKAGES" = "$packagerepos" && return 0 - - verbose "Start the download manager." - - # Initialize the queue. - rm "$queueMessages" 2> /dev/null - touch "$queueMessages" - - # - # The following block is forked away. - # Note that all variable assignments happen in a separate process - # and hence have no effect on the outside. - # - ( - # Remove the queue when exiting and get rid of pending jobs. - trap " - kill \$(jobs -ls) > /dev/null 2>&1 - rm '$queueMessages' 2> /dev/null - exit - " EXIT sigint sigterm - - # The jobs yet to be done. - jobs= - # The available mirrors. - mirrors="$PACKAGESITE_MIRRORS" - # The jobs that should be retried. - retry= - # The jobs that have been retried. - retried= - # The last line read from the socket. - line= - - # Keep on running as long as the father process is around. - # Note that this while loop has the message queue as stdin. - while kill -0 "$pid" 2> /dev/null; do - # Check for a message in the queue. - # There is nothing to be done, if there was no message, - # none the less it times out to allow the terminal - # to catch signals. - read -t 2 line - # Process messages. - case "$line" in - finished:*) - # A download has been finished. - # Add the mirror that was used to - # the list of available mirrors. - mirror="${line#finished:}" - mirror="${mirror%;*}" - mirrors="${mirrors:+$mirrors$IFS}$mirror" - ;; - retry:*) - # A download was not finished - # successfuly. - mirror="${line#retry:}" - job="${mirror##*;}" - mirror="${mirror%;*}" - if echo "$retried" | grep -qFx "$job"; then - # If this package has already - # had a retry, mark it as - # finished to hand it over - # to the package validation - # that can fetch from the - # master server. - downloadManagerMsgFinished "$mirror" "$job" - else - # The first retry request. - # Free the mirror and list - # the package for retry. - mirrors="${mirrors:+$mirrors$IFS}$mirror" - retry="${retry:+$retry$IFS}$job" - fi - ;; - request:*) - # Append requested downloads to the - # list of available jobs. - jobs="${jobs:+$jobs$IFS}${line#request:}" - ;; - exit) - # The download manager has been told - # to terminate. - break - ;; - esac - # Delete the line, so it cannot be read again in the - # next iteration, if reading from the queue has - # timed out. - line= - - # If any mirrors are available and there are jobs - # in the queue, now is the time to dispatch them. - while [ -n "$jobs" -a -n "$mirrors" ]; do - mirror="${mirrors%%$IFS*}" - mirrors="${mirrors#$mirror}" - mirrors="${mirrors#$IFS}" - job="${jobs%%$IFS*}" - jobs="${jobs#$job}" - jobs="${jobs#$IFS}" - downloadManagerFetch "$mirror" "$job" & - done - - # If we have run out of jobs, give the retry stuff. - # a try. - while [ -n "$retry" -a -n "$mirrors" ]; do - mirror="${mirrors%%$IFS*}" - mirrors="${mirrors#$mirror}" - mirrors="${mirrors#$IFS}" - job="${retry%%$IFS*}" - retry="${retry#$job}" - retry="${retry#$IFS}" - # Remember that this job has been retried. - retried="${retried:+$retried$IFS}$job" - downloadManagerFetch "$mirror" "$job" & - done - done < "$queueMessages" - ) & -} - -# -# This is forked off by the download manager to download a package from -# a mirror. -# If the package is already present a download is not attempted. -# -# @param 1 -# The mirror to download from. -# @param 2 -# The name of the package to download. -# -downloadManagerFetch() { - # Get rid of pending jobs. - trap " - kill \$(jobs -ls) > /dev/null 2>&1 - exit - " EXIT sigint sigterm - - # Only do something if the package is not present. - if ! [ -e "$PACKAGES/All/$2.tbz" ]; then - # Create the download location. - mkdir -p "$PACKAGES/All" 2> /dev/null - - # Attempt download from mirror. - # This is forked off, to allow the shell to catch signals. - fetch -qmo "$PACKAGES/All/$2.tbz" "${1%/*?}/All/$2.tbz" > /dev/null 2>&1 & - if ! wait $!; then - # Release the mirror and mark the package for a retry. - downloadManagerMsgRetry "$1" "$2" - return 0 - fi - fi - - # Release the mirror and mark package finished. - downloadManagerMsgFinished "$1" "$2" -} - -# -# Tells the download manager, that a download was unsuccessful. -# -# @param 1 -# The mirror that was used. -# @param 2 -# The name of the package that was not downloaded. -# @param queueMessages -# The message queue to the download manager. -# -downloadManagerMsgRetry() { - # Do not send anything without a queue. - test ! -e "$queueMessages" && return 0 - - lockf -k "$queueMessages" sh -c "echo 'retry:$1;$2' >> '$queueMessages'" -} - -# -# Tells the download manager, that a download has been finished. -# -# @param 1 -# The mirror that was used. -# @param 2 -# The name of the downloaded package. -# @param queueMessages -# The message queue to the download manager. -# -downloadManagerMsgFinished() { - # Do not send anything without a queue. - test ! -e "$queueMessages" && return 0 - - lockf -k "$queueMessages" sh -c "echo 'finished:$1;$2' >> '$queueMessages'" -} - -# -# Requests the download of packages from the download manager. -# -# @param 1 -# A list of packages for download. -# @param queueMessages -# The message queue to the download manager. -# -downloadManagerMsgRequest() { - # Do not send anything without a queue. - test ! -e "$queueMessages" && return 0 - - local request - for request in $1; { - lockf -k "$queueMessages" sh -c "echo 'request:${request#*;}' >> '$queueMessages'" - } -} - -# -# Instructs the download manager to terminate. -# -# @param queueMessages -# The message queue to the download manager. -# -downloadManagerMsgExit() { - # Do not send anything without a queue. - test ! -e "$queueMessages" && return 0 - - lockf -k "$queueMessages" sh -c "echo 'exit' >> '$queueMessages'" -} - -# -# Validates a single package. Validation means it checks whether a package -# is a complete tar archive. Damaged or missing packages will be (re)downloaded -# from the master server (the one named by PACKAGESITE). -# If the package is a valid tar archive the +CONTENTS file will be checked, -# as well. -# -# @param 1 -# The name of the package to validate. -# @param packagerepos -# The location of the remote package collection. This is derived from -# PACKAGESITE. -# @param pending -# The list of pending packages. -# @return -# Return 0 on success. -# -validatePackage() { - local package - package="$1.tbz" - - # Check whether the package is intact and present. - if ! tar -tf "$PACKAGES/All/$package" > /dev/null 2>&1; then - # If the package repository and the local package collection - # are identical, there's no chance to get the package if it's - # not already there. - if [ "$PACKAGES" = "$packagerepos" ]; then - error $ERR_FETCH "The package <$package> is not present." - fi - - # Clean up whatever crap is there. - rm "$PACKAGES/All/$package" 2> /dev/null - - # Try to get the package from the master server. - fetch -mo "$PACKAGES/All/$package" "$packagerepos/All/$package" - - # Check whether the package is present. - if ! [ -e "$PACKAGES/All/$package" ]; then - error $ERR_FETCH "The package <$package> could not be fetched." - fi - - # Check whether the package is a valid tar archive. - if ! tar -tf "$PACKAGES/All/$package" > /dev/null 2>&1; then - error $ERR_FETCH "The package <$package> could not be read." - fi - fi - - # Check whether we can read the package +CONTENTS format. - readContents "$PACKAGES/All/$package" - - # Remove this package from the list of pending packages. - pending="$(echo "$pending" | grep -vFx "$1")" - - # The package is present and intact. - return 0 -} - -# -# Let's get it on! The declarative part is finally over. -# - -# Ignore some signals that should not occur. -trap 'warn "Discard signal SIGHUP."' sighup -trap 'warn "Discard signal SIGUSR1."' sigusr1 -trap 'warn "Discard signal SIGUSR2."' sigusr2 - -# -# Parse command line parameters. -# -readParams "$@" - -# Make sure the index is available for the following operations. -getIndex - -# -# Populate the list of packages out of sync with the index. -# -pkgAll - -# -# Perform dependency checking. -# -pkgDependencies - -# -# Sort packages by their dependencies. -# -pkgSort - -# -# Display tasks. -# -pkgList - -# -# Download packages. -# -pkgDownload - -# -# Upgrade packages. -# -pkgUpgrade - -exit 0 diff --git a/sysutils/bsdadminscripts/files/uma.in b/sysutils/bsdadminscripts/files/uma.in deleted file mode 100644 index 6bba2b122d8b..000000000000 --- a/sysutils/bsdadminscripts/files/uma.in +++ /dev/null @@ -1,436 +0,0 @@ -#!/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.1 -readonly name=uma - -# Return value. -errno=0 -# Allow things to fail properly by ignoring SIGINT in the main process. -trap '' int - -# Used to activate verbose output. -verbose= -# Will be set if files are locally available. -local= - -vardir="%%VAR%%" -lock="$vardir/run/$name.lock" -lockpid="$vardir/run/$name.pid" -identpid="$vardir/run/$name.ident.pid" -conf="%%PREFIX%%/etc/$name.conf" - -# Use line breaks as a delimiter. -IFS=' -' -# Timezone UTC for age comparisons. -export TZ=UTC - -# The bit position of errors. -readonly ERR_LOCK=0 -readonly ERR_ARG=1 -readonly ERR_FETCH_PORTS=2 -readonly ERR_FETCH_VULNDB=3 -readonly ERR_FETCH_INDEX=4 -readonly ERR_EXTRACT_PORTS=5 -readonly ERR_UPDATE_PORTS=6 - -# -# Get environment variables. -# - -# Load the configuration file if present. -if [ -e "$conf" ]; then - . "$conf" -fi - -# Local index location. -: ${PKG_INDEX="$vardir/db/uma/FTPINDEX"} -: ${FTP_TIMEOUT=60} - -# Logic from src/usr.sbin/pkg_install/add/main.c, plus the possibility to -# override the architecture with ARCH. -: ${PACKAGEROOT="ftp://ftp.freebsd.org"} -: ${ARCH="$(uname -m)"} -branch="$(uname -r | tr '[:upper:]' '[:lower:]')" -number="${branch%%.*}" -branch="${branch##*-}" -case "$branch" in - release) - branch=$number-$branch - ;; - stable|current) - branch=${number%%.*}-$branch - ;; - *) - # Fallback to stable for prerelease and the like. - branch=${number%%.*}-stable - ;; -esac -: ${BRANCH=$branch} -: ${PACKAGESITE="$PACKAGEROOT/pub/FreeBSD/ports/$ARCH/packages-$BRANCH/Latest"} -packagetree="${PACKAGESITE%/*?}" -ftp="${PACKAGESITE#*://}" -ftp="${ftp%%/*}" - -# -# Generate PACKAGESITE_MIRRORS if only PACKAGEROOT_MIRRORS are given. -# Note that PACKAGEROOT_MIRRORS and PACKAGESITE_MIRRORS are supposed to be -# a ";" or line feed separated list. Semicolons will be converted to line -# feeds in any case. -# - -# Set PACKAGEROOT_MIRRORS if not set. -if [ -z "$PACKAGEROOT_MIRRORS" ]; then - PACKAGEROOT_MIRRORS= - for i in $(jot 14); { - PACKAGEROOT_MIRRORS="${PACKAGEROOT_MIRRORS:+$PACKAGEROOT_MIRRORS$IFS}ftp://ftp$i.FreeBSD.org" - } -fi - -# Convert semicolon in PACKAGEROOT_MIRRORS. -PACKAGEROOT_MIRRORS="$(echo "$PACKAGEROOT_MIRRORS" | sed "s/;/\\$IFS/g")" -# Build PACKAGESITE_MIRRORS. -if [ -z "${PACKAGESITE_MIRRORS}" ]; then - PACKAGESITE_MIRRORS= - for MIRROR in $PACKAGEROOT_MIRRORS; { - PACKAGESITE_MIRRORS="${PACKAGESITE_MIRRORS:+$PACKAGESITE_MIRRORS$IFS}$MIRROR/pub/FreeBSD/ports/$ARCH/packages-$BRANCH/Latest" - } -fi -# Convert semicolon in PACKAGESITE_MIRRORS. -PACKAGESITE_MIRRORS="$(echo "$PACKAGESITE_MIRRORS" | sed "s/;/\\$IFS/g")" - -# Remove duplicates. -PACKAGEROOT_MIRRORS="$(echo "$PACKAGEROOT_MIRRORS" | sort -u)" -PACKAGESITE_MIRRORS="$(echo "$PACKAGESITE_MIRRORS" | sort -u)" - -# Determine portsdir -portsdir=$(make -V PORTSDIR -f /usr/share/mk/bsd.port.mk 2> /dev/null) -portsdir="${portsdir:-%%PORTS%%}" - -export ARCH BRANCH PKG_INDEX FTP_TIMEOUT PACKAGEROOT PACKAGESITE -export PACKAGEROOT_MIRRORS PACKAGESITE_MIRRORS - -# -# This function is called by a trap when the script exits in verbose mode. -# It reads errno to construct error messages. -# -# @param errno -# The exit status of the script. -# -verbose() { - if [ $(($errno >> $ERR_LOCK & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_LOCK))): Lock owned by someone else." - fi - if [ $(($errno >> $ERR_ARG & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_ARG))): An unknown parameter was supplied." - fi - if [ $(($errno >> $ERR_FETCH_PORTS & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_FETCH_PORTS))): Fetching the ports tree failed." - fi - if [ $(($errno >> $ERR_FETCH_VULNDB & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_FETCH_VULNDB))): Fetching security database failed." - fi - if [ $(($errno >> $ERR_FETCH_INDEX & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_FETCH_INDEX))): Fetching remote INDEX failed." - fi - if [ $(($errno >> $ERR_EXTRACT_PORTS & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_EXTRACT_PORTS))): Extracting the ports tree failed." - fi - if [ $(($errno >> $ERR_UPDATE_PORTS & 1)) -eq 1 ]; then - echo "ERROR($((1 << $ERR_UPDATE_PORTS))): Updating the ports tree failed." - fi -} - -# -# This function spawns a process that takes over a lock. -# -# @param pid -# The PID of the process that requested the lock. -# @param lock -# The location of the lock file. -# @param lockpid -# The location of the PID file for the lock holding process. -# -secureLock() { - lockf "$lock" sh -c " - trap 'exit 0' term - echo '$pid' > '$lock' - echo \"\$\$\" > '$lockpid' - trap 'rm \"$lockpid\"; exit 0' EXIT - while kill -0 '$pid' 2> /dev/null; do - sleep 2 - done - " 2> /dev/null & -} - -# -# Checks whether the currently requesting process holds the lock. -# -# @param pid -# The PID of the process that requested the lock. -# @param lock -# The location of the lock file. -# @return -# Returns 0 if the lock is held for the requesting process or 1 -# if the lock is missing or owned by another process. -# -hasLock() { - test "$pid" -eq "$(cat "$lock" 2> /dev/null)" 2> /dev/null - return $? -} - -# -# Creates a lock for the requesting process. -# -# @param pid -# The PID of the process that requested the lock. -# @param lock -# The location of the lock file. -# @param lockpid -# The location of the PID file for the lock holding process. -# @param portsdir -# The location of the FreeBSD ports tree. -# @return -# Returns 0 on success, 1 on failure. -# -lock() { - local location - - # The requestor already holds the lock. - hasLock && return 0 - - # The process requesting the lock does not exist. - kill -0 "$pid" 2> /dev/null || return 1 $(errno=1) - - # Follow symlinks - location="$(pwd)" - if cd "$portsdir" && portsdir="$(pwd -P)"; then - # Portsdir exists, so we can test for make activity. This - # does not cover all cases, but it covers a lot. - if fstat "$portsdir" | awk '{print $2}' | grep -q make; then - errno=1 - return 1 - fi - fi - cd "$location" - - # Try acquiring the lock. - lockf -st 0 "$lock" "$0" secure $pid 2> /dev/null || return 1 $(errno=1) - # Wait until the locking process is properly set up. - while ! [ -e "$lockpid" -a -e "$lock" ]; do - sleep 0.1 - done - return 0 -} - -# -# Frees a lock unless it is held for another process than the requestor. -# -# @param lock -# The location of the lock file. -# @param lockpid -# The location of the PID file for the lock holding process. -# @return -# Returns 0 on success, 1 on failure. -# -unlock() { - if hasLock; then - # Free the lock. - kill -TERM "$(cat "$lockpid")" - # Wait for the locking process to clean up. - while [ -e "$lockpid" -o -e "$lock" ]; do - sleep 0.1 - done - return 0 - else - errno=1 - return 1 - fi -} - -# -# Prints the command and available parameters. -# -# @param name -# The name of the script. -# @param version -# The version of the script. -# -printHelp() { - echo "$name v$version -usage: - $name [-hv] [pid] [fetch] [extract] [update] [...] - $name [-hv] [pid] fetch [ports] [audit] [ftpindex] - $name [-hv] [pid] extract [ports] - $name [-hv] [pid] update [ports] - $name [-hv] lock [pid] - $name [-hv] unlock [pid]" -} - -# -# Reads the parameters and creates variables that indicates the presence -# of these parameters. -# -# The last numeric value is treated as the requestor PID. It also deals -# -# @param @ -# All parameters to process. -# @param verbose -# Set to 1 if verbose mode is activated. -# @param cmd_* -# Set by this function to indicate the presence of a parameter. -# -readParams() { - local flag - for flag; { - # A numerical parameter is the PID. - if [ "$flag" -eq "$flag" ] 2> /dev/null; then - pid="${flag}" - continue - fi - - # Activate verbose mode for -v. - case "$flag" in - -v | --verbose) - trap 'verbose 1>&2' EXIT - verbose=1 - continue - ;; - -h | --help) - printHelp - continue - ;; - -? | --*) - errno=$((1 << $ERR_ARG)) - exit $errno - ;; - -*) - # Split parameters. - readParams "${flag%${flag#-?}}" "-${flag#-?}" - continue - ;; - esac - - # If the variable is not predefined, the command is unknown. - if eval "test -n \"\${cmd_$flag=1}\""; then - errno=$((1 << $ERR_ARG)) - exit $errno - fi - setvar "cmd_$flag" 1 - } -} - -pid="$$" -cmd_lock= -cmd_unlock= -cmd_secure= -cmd_env= -cmd_fetch= -cmd_extract= -cmd_update= -cmd_ports= -cmd_audit= -cmd_ftpindex= -readParams "$@" - -# -# Exclusive commands that will cause all others to be ignored, in order -# of priority. -# - -if [ -n "$cmd_unlock" ]; then - unlock - return $? -fi - -if [ -n "$cmd_secure" ]; then - secureLock - return $? -fi - -if [ -n "$cmd_lock" ]; then - lock - return $? -fi - -# -# Non-exclusive commands that do not require a lock. -# - -if [ -n "$cmd_env" ]; then - echo "ARCH='$ARCH'" - echo "BRANCH='$BRANCH'" - echo "FTP_TIMEOUT='$FTP_TIMEOUT'" - echo "PACKAGEROOT='$PACKAGEROOT'" - echo "PACKAGESITE='$PACKAGESITE'" - echo "PKG_INDEX='$PKG_INDEX'" - echo "PACKAGEROOT_MIRRORS='$PACKAGEROOT_MIRRORS'" - echo "PACKAGESITE_MIRRORS='$PACKAGESITE_MIRRORS'" -fi - -# Create a local lock if need be. -localLock= -if ! hasLock; then - localLock=1 - lock || return $? -fi - -# Ports tree commands. -if [ -n "$cmd_ports" ]; then - if [ -n "$cmd_fetch" ]; then - portsnap fetch || errno="$((1 << $ERR_FETCH_PORTS | $errno))" - fi - if [ -n "$cmd_extract" ]; then - portsnap extract || errno=$((1 << $ERR_EXTRACT_PORTS | $errno)) - fi - if [ -n "$cmd_update" ]; then - portsnap update || errno=$((1 << $ERR_UPDATE_PORTS | $errno)) - fi -fi - -# Portaudit commands. -if [ -n "$cmd_audit" ]; then - if [ -n "$cmd_fetch" ]; then - portaudit -F || errno=$((1 << $ERR_FETCH_VULNDB | $errno)) - fi -fi - -# Package index commands. -if [ -n "$cmd_ftpindex" ]; then - if ! mkdir -p "${PKG_INDEX%/*}" 2> /dev/null; then - test -n "$verbose" \ - && echo "The directory ${PKG_INDEX%/*} does not exist and cannot be created!" - errno=$((1 << $ERR_FETCH_INDEX | $errno)) - elif [ -n "$cmd_fetch" ]; then - fetch -mo "$PKG_INDEX" "$packagetree/INDEX" \ - || errno=$((1 << $ERR_FETCH_INDEX | $errno)) - fi -fi - - -# Free a local lock. -test -n "$localLock" && unlock - -return $errno - diff --git a/sysutils/bsdadminscripts/pkg-descr b/sysutils/bsdadminscripts/pkg-descr deleted file mode 100644 index 92784ff0e091..000000000000 --- a/sysutils/bsdadminscripts/pkg-descr +++ /dev/null @@ -1,7 +0,0 @@ -This is a collection of administration scripts. At the moment it -consists of a script to control rc.d scripts at runtime, a -script that runs common make targets on batches of ports, scripts to set -variables for make jobs (like portconf, but with more possibilities). -And scripts to check for broken packages and missing libraries. - -WWW: https://sourceforge.net/projects/bsdadminscripts/ diff --git a/sysutils/bsdadminscripts/pkg-plist b/sysutils/bsdadminscripts/pkg-plist deleted file mode 100644 index 4bf4787dc387..000000000000 --- a/sysutils/bsdadminscripts/pkg-plist +++ /dev/null @@ -1,35 +0,0 @@ -sbin/distviper -sbin/pkg_libchk -sbin/pkg_upgrade -sbin/pkg_validate -sbin/portconfig -sbin/rcstart -sbin/uma -sbin/rcstatus -sbin/rcstop -sbin/rcrestart -sbin/rconestart -sbin/rconestatus -sbin/rconestop -sbin/rconerestart -sbin/portbuild -sbin/portclean -sbin/portfetch -sbin/portpackage -sbin/portconfig-recursive -sbin/portfetch-recursive -man/man1/bsdadminscripts.1.gz -man/man1/buildflags.awk.1.gz -man/man1/buildflags.conf.1.gz -man/man1/buildflags.mk.1.gz -man/man1/distviper.1.gz -man/man1/pkg_libchk.1.gz -man/man1/pkg_upgrade.1.gz -man/man1/pkg_validate.1.gz -man/man1/portconfig.1.gz -man/man1/rcstart.1.gz -man/man1/uma.1.gz -%%ETCDIR%%/buildflags.conf.sample -%%ETCDIR%%/uma.conf.sample -%%DATADIR%%/buildflags.awk -%%DATADIR%%/buildflags.mk |