File: //usr/local/sbin/portmaster
#!/bin/sh
# Copyright (c) 2005-2012 Douglas Barton, All rights reserved
# Please see detailed copyright below
trap trap_exit INT
umask 022
progcmd="$0" # actual invocation of this program for search in ps output
progname="${0##*/}" # program name in messages
program="$(realpath $0 || echo $0)" # full path to program for recursive calls
PKG_CMD="/usr/local/sbin/pkg-static"
# Initialize crucial values for the parent, and export them for the children
if [ -z "$PM_PARENT_PID" ]; then
PM_PARENT_PID=$$
: ${TMPDIR:=/tmp} ; /bin/mkdir -p $TMPDIR
UPGRADE_TOOL=portmaster
# /usr/local is needed in the path for make
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
[ -e /usr/X11R6 ] && [ ! -L /usr/X11R6 ] && PATH=$PATH:/usr/X11R6/bin
[ -n "$CCACHE_PATH" -a -z "$NOCCACHE" ] && PATH="/usr/local/libexec/ccache:$PATH"
export PM_PARENT_PID TMPDIR UPGRADE_TOOL PATH
if [ -r /etc/portmaster.rc ]; then
echo '' ; echo "===>>> WARNING"
echo ' Your portmaster.rc is in /etc, however support for the file in this'
echo ' location has been removed.'
echo '' ; echo ' The proper location for this file is /usr/local/etc'
exit 1
fi
set -o allexport
# Read a global rc file first
[ -s /usr/local/etc/portmaster.rc ] && . /usr/local/etc/portmaster.rc
# Allow the config file to be stored with the script
[ -s "${0%/*}/portmaster.rc" ] && . ${0%/*}/portmaster.rc
# Read a local one next, and allow the command line to override
[ -s "$HOME/.portmasterrc" ] && . $HOME/.portmasterrc
set +o allexport
my_environment=`set`
# If we are already root, unset this to avoid potential conflict
[ `id -u` -eq 0 ] && unset PM_SU_CMD PM_SU_VERBOSE
fi
#=============== Begin functions we always want to have ===============
version () {
echo '' ; echo "===>>> Version 3.20"
}
fail () {
echo -e "\n===>>> $*" ; echo "===>>> Aborting update"
[ "$$" -eq "$PM_PARENT_PID" ] && trap_exit fail
safe_exit 1
}
trap_exit () {
echo '' # Helps if the previous message was 'echo -n'
if [ -n "$portdir" -a -z "$1" ]; then
echo "===>>> Build/Install for $portdir exiting due to signal"
elif [ -z "$1" ]; then
echo "===>>> Exiting due to signal"
fi
if [ "$$" -eq "$PM_PARENT_PID" ]; then
[ -s "$IPC_SAVE" ] && . $IPC_SAVE
local n=0
while ps -axo pid,ppid,command | grep -v egrep |
egrep -q "(make -DBATCH checksum|/fetch |\[sh\])"; do
# Protect from infinite loop if there is another fetch
[ $n -gt 9 ] && break
n=$(( $n + 1 ))
kill_bad_children
done
if [ -n "$HIDE_BUILD" ]; then
local logs file
logs=`echo ${TMPDIR}/port_log-${PM_PARENT_PID}-*`
case "$logs" in *\*) unset logs ;; esac
if [ -n "$logs" ]; then
echo ''
echo "===>>> Build/Install logs available:"
for file in $logs; do echo " $file"; done
echo ''
fi
fi
else
# Signal the parent if a child trap'ed, or read the file if we are
# an intermediate process.
if ! ls ${TMPDIR}/f-${PM_PARENT_PID}-TEAC\.* >/dev/null 2>&1; then
pm_mktemp TEAC # Trap Exit Already Called
else
[ -s "$IPC_SAVE" ] && . $IPC_SAVE
fi
fi
safe_exit 1
}
kill_bad_children () {
local mypgid pid ppid pgid command ; IFS=' '
mypgid=`ps -o pgid= -p $PM_PARENT_PID`
while read pid ppid pgid command; do
[ "$pid" -gt 25 ] || continue
case "$ppid" in
1) case "$command" in
*" $progcmd "*) pm_kill $pid ;;
*'make -DBATCH checksum'*|*'/fetch '*|\[sh\]) pm_kill -9 $pid ;;
esac ;;
*) [ $pgid -eq $mypgid ] || continue
[ $pid -eq $PM_PARENT_PID ] && continue
case "$command" in
*" $progcmd "*) pm_kill $pid ;;
*'make -DBATCH checksum'*|*'/fetch '*|\[sh\]) pm_kill $pid ;;
esac ;;
esac
done <<-EOF
$(ps -axo pid,ppid,pgid,command | sed '1d')
EOF
}
parent_exit () {
local need_kbc files f count DISCARD show_list
[ -s "$DI_FILES" ] && { grep -q '%%%%%%%%%%%%' $DI_FILES || need_kbc=need_kbc_dif; }
[ -n "$FETCH_ONLY" -a -z "$FETCH_ONLY_DONE" ] && need_kbc=need_kbc_fo
if [ -z "$1" ]; then
if [ -n "$PM_URB" -o -n "$PM_FORCE" ]; then
files=`find $pdb -type f -name PM_UPGRADE_DONE_FLAG`
if [ -n "$files" ]; then
pm_sv Deleting \'install complete\' flags
pm_find_s $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete
pm_find_s $pdb -type d -depth 1 -empty ! -path \*\.zfs/\* -delete 2>/dev/null
fi
fi
if [ -z "$BACKUP" -a -z "$NO_BACKUP" -a -n "$NB_DELETE" ]; then
pm_sv 'Deleting safety packages for successful installs\n'
pm_cd $pbu || fail "Cannot cd to $pbu"
pm_rm_s $NB_DELETE
fi
else
need_kbc=need_kbc_ec
fi
[ -n "$need_kbc" ] && kill_bad_children
[ -n "$pbu" ] && pbu=`find $pbu -type d -empty 2>/dev/null`
if pm_isdir "$pbu"; then
pm_sv 'Removing empty backup package directory'
pm_rmdir_s $pbu
fi
for f in ${TMPDIR}/f-${PM_PARENT_PID}-*; do
case "$f" in */f-${PM_PARENT_PID}-\*) continue ;; esac
/bin/unlink $f
done
if [ -n "$PM_WRKDIRPREFIX" ] && [ -n "$PM_BUILDING" -a -z "$1" ]; then
count=0
while : ; do
ps axww | grep '[m]ake clean NOCLEANDEPENDS=ncd' >/dev/null || break
count=$(( $count + 1 ))
if [ $count -eq 1 ]; then
echo "===>>> Waiting for background 'make clean' processes to finish"
needws=needws
elif [ $count -eq 10 ]; then
count=0
fi
sleep 2
done
pm_v "===>>> Removing empty directories from WRKDIRPREFIX"
[ -n "$needws" ] && echo '' || pm_v
find $PM_WRKDIRPREFIX -depth -mindepth 1 -maxdepth 2 -type d -empty -delete 2>/dev/null
fi
case "$DISPLAY_LIST" in
*' '*) if [ -n "$1" ]; then
echo "===>>> There are messages from installed ports to display,"
echo " but first take a moment to review the error messages"
echo -n " above. Then press Enter when ready to proceed. "
read DISCARD
echo ''
fi
: ${PAGER:='less -e'}
if [ -n "$PM_NO_CONFIRM" ]; then
PAGER=cat
fi
(
$PKG_CMD query "===>>> pkg-message for %n-%v\n%M" $DISPLAY_LIST
echo "===>>> Done displaying pkg-message files" ; echo '' ) | $PAGER ;;
esac
if [ -n "$INSTALLED_LIST" ]; then
if [ -n "$UPDATE_ALL" -o -n "$PM_MULTI_PORTS" ]; then
show_list=all
else
case "$INSTALLED_LIST" in
*\\n\\t*) show_list=all ;;
*\\n) show_list=one
if [ -z "$ilist" ]; then
ilist="${INSTALLED_LIST#\\t}"
ilist="${ilist%\\n}"
fi ;;
esac
fi
if [ -n "$PM_LOG" ]; then
if [ -w "$PM_LOG" ]; then
echo '' >> $PM_LOG
elif [ -e "$PM_LOG" -a ! -w "$PM_LOG" ]; then
echo "===>>> Warning: $PM_LOG exists, but is not writable"
unset PM_LOG
elif [ -e "$PM_LOG" -o -L "$PM_LOG" ]; then
echo "===>>> Warning: $PM_LOG exists, but is not a regular file"
unset PM_LOG
else
pm_mktemp pm_log ; mv $pm_mktemp_file $PM_LOG
fi
[ -n "$PM_LOG" ] && date >> $PM_LOG
fi
case "$show_list" in
all) echo "===>>> The following actions were performed:"
echo -e $INSTALLED_LIST
[ -n "$PM_LOG" ] && echo -e ${INSTALLED_LIST%\\n} >> $PM_LOG ;;
one) echo "===>>> $ilist complete" ; echo ''
[ -n "$PM_LOG" ] && echo " $ilist" >> $PM_LOG ;;
esac
fi
if [ -n "$build_deps_il" ]; then
echo "===>>> Deleting installed build-only dependencies"
cd
pm_pkg_delete_s $build_deps_il
echo ''
fi
if [ -n "$1" -a -n "${PM_NEEDS_UPDATE# }" -a -n "$PM_BUILDING" -a -z "$FETCH_ONLY" ]; then
echo "$progname <flags>${PM_NEEDS_UPDATE}" > ~/portmasterfail.txt
echo ''
echo "===>>> You can restart from the point of failure with this command line:"
echo " $progname <flags>${PM_NEEDS_UPDATE}"
echo ''
echo "This command has been saved to ~/portmasterfail.txt"
echo ''
fi
}
safe_exit () {
[ -n "$grep_deps" ] && pm_unlink $grep_deps
if [ "$$" -eq "$PM_PARENT_PID" ]; then
parent_exit $1
else
# Save state for the parent process to read back in
: > $IPC_SAVE
if [ -z "$PM_FIRST_PASS" ]; then
echo "DISPLAY_LIST='$DISPLAY_LIST'" >> $IPC_SAVE
echo "INSTALLED_LIST='$INSTALLED_LIST'" >> $IPC_SAVE
[ -n "$PM_DEL_BUILD_ONLY" ] &&
echo "build_deps_il='$build_deps_il'" >> $IPC_SAVE
# Do not remove a child from the list if we trapped or failed
if [ -z "$1" ]; then
for i in $PM_NEEDS_UPDATE; do
[ "$i" = "$portdir" ] && continue
pnu_temp="${pnu_temp}${i} "
done
PM_NEEDS_UPDATE=" ${pnu_temp}"
fi
[ -z "$NO_BACKUP" -a -z "$BACKUP" ] && echo "NB_DELETE='$NB_DELETE'" >> $IPC_SAVE
else
if [ "$PM_BUILD_ONLY_LIST" = pmp_doing_build_deps ]; then
echo "build_only_dl_g='$build_only_dl_g'" >> $IPC_SAVE
echo "run_dl_g='$run_dl_g'" >> $IPC_SAVE
rundep_list=`uniquify_list $rundep_list`
echo "rundep_list='$rundep_list'" >> $IPC_SAVE
for f in $rundep_list; do
eval echo "export $f=\'\$$f\'" >> $IPC_SAVE
eval echo "export ${f}_p=\'\$${f}_p\'" >> $IPC_SAVE
done
fi
# Do these here so +IGNOREME can modify them
echo "num_of_deps='$num_of_deps'" >> $IPC_SAVE
echo "build_l='$build_l'" >> $IPC_SAVE
[ -z "$NO_DEP_UPDATES" ] && echo 'unset NO_DEP_UPDATES' >> $IPC_SAVE
fi
echo "CUR_DEPS='$CUR_DEPS'" >> $IPC_SAVE
echo "dep_of_deps='$dep_of_deps'" >> $IPC_SAVE
echo "PM_NEEDS_UPDATE='$PM_NEEDS_UPDATE'" >> $IPC_SAVE
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo "INTERACTIVE_YES='$INTERACTIVE_YES'" >> $IPC_SAVE
echo "INTERACTIVE_NO='$INTERACTIVE_NO'" >> $IPC_SAVE
fi
[ -n "$PM_URB" -o -n "$PM_URB_UP" ] && echo "PM_URB_DONE='$PM_URB_DONE'" >> $IPC_SAVE
fi
exit ${1:-0}
} # safe_exit()
target_part () { [ -z "${1##*:*}" ] && echo "${1#*:}" || echo install; }
flavor_part () { local tmp="${1%%:*}"; [ -z "${tmp##*@*}" ] && echo "${tmp#*@}"; }
dir_part () { local tmp="${1%%:*}"; echo "${tmp%%@*}"; }
export_flavor () { if [ -n "$1" ]; then export FLAVOR="$1"; else unset FLAVOR; fi; }
pm_cd () { builtin cd $1 2>/dev/null || return 1; }
pm_cd_pd () { [ -n "$PM_INDEX_ONLY" ] && return 2;
local dir=$pd/$(dir_part $1);
builtin cd $dir 2>/dev/null ||
fail "Cannot cd to port directory: $dir"; }
pm_isdir () { builtin test -d "$1"; }
pm_isdir_pd () { local dir=$(dir_part "$1");
builtin test -n "$dir" -a -d "$pd/$dir"; }
pm_kill () { kill "$@" >/dev/null 2>/dev/null; }
pm_make () { ( unset -v CUR_DEPS INSTALLED_LIST PM_DEPTH build_l PM_URB_LIST;
/usr/bin/nice /usr/bin/make $PM_MAKE_ARGS "$@"; ); }
pm_make_b () { /usr/bin/make $PM_MAKE_ARGS BEFOREPORTMK=bpm "$@"; }
pm_mktemp () {
pm_mktemp_file=`/usr/bin/mktemp -t f-${PM_PARENT_PID}-$1 2>&1` ||
fail "mktemp for $1 failed:\n ${pm_mktemp_file#mktemp: }"
}
pm_unlink () { [ -e "$1" ] && /bin/unlink $1; }
pm_islocked () { local locked; [ -n "$1" ] && locked=`$PKG_CMD query %k "$1"` &&
[ "$locked" = 1 ] || [ -e "$pdb/$1/+IGNOREME" ]; }
# Superuser versions for commands that need root privileges
pm_find_s () { $PM_SU_CMD /usr/bin/find "$@"; }
pm_install_s () { $PM_SU_CMD /usr/bin/install -p -o root -g wheel -m 644 $1 $2; }
pm_make_s () { ( unset -v CUR_DEPS INSTALLED_LIST PM_DEPTH build_l PM_URB_LIST;
$PM_SU_CMD /usr/bin/nice /usr/bin/make $PM_MAKE_ARGS "$@"; ); }
pm_mkdir_s () { $PM_SU_CMD /bin/mkdir -p $1; }
pm_pkg_delete_s () {
for f in "$@"; do
if [ "$($PKG_CMD query %k $f)" = 1 ]; then
was_locked=1
$PKG_CMD unlock -qy $f
fi
done
$PM_SU_CMD /usr/local/sbin/pkg-static delete -yf "$@";
for d in $* ; do
pm_rm_s -rf $pdb/$d
done
}
pm_rm_s () { $PM_SU_CMD /bin/rm "$@"; }
pm_rmdir_s () { $PM_SU_CMD /bin/rmdir "$@"; }
pm_unlink_s () { [ -e "$1" ] && $PM_SU_CMD /bin/unlink $1; }
pm_v () { [ -n "$PM_VERBOSE" ] && echo -e "$@"; }
pm_sv () { [ -n "$PM_SU_VERBOSE" ] && echo -e "===>>> SU $*"; }
# Do this here so we can have a reasonably good guess.
# May be modified below.
if [ "$$" -eq "$PM_PARENT_PID" ]; then
if [ -z "$pd" ]; then
if [ -z "$PORTSDIR" ]; then
pd=`pm_make_b -f/usr/share/mk/bsd.port.mk -V PORTSDIR 2>/dev/null` || pd=""
[ -z "$pd" ] && pm_isdir /usr/ports && pd=/usr/ports
else
pd=$PORTSDIR
fi
fi
if [ -n "$pd" ]; then
[ ! -r "${pd}/Mk/bsd.port.mk" ] &&
fail "The ports directory ($pd) does not seem to contain a ports tree"
export pd
fi
if [ -z "$pdb" ]; then
if [ -z "$PKG_DBDIR" ]; then
pm_isdir /var/db/pkg && pdb=/var/db/pkg
[ -z "$pdb" ] &&
pdb=`pm_make -f/usr/share/mk/bsd.port.mk -V PKG_DBDIR 2>/dev/null`
else
pdb=$PKG_DBDIR
fi
if [ -z "$pdb" ]; then
if pm_isdir /var/db/pkg; then
pdb='/var/db/pkg'
else
fail 'The value of PKG_DBDIR cannot be empty'
fi
fi
fi
export pdb
[ -z "$port_dbdir" ] && pm_isdir /var/db/ports && port_dbdir=/var/db/ports
[ -z "$port_dbdir" ] &&
port_dbdir=`pm_make_b -f/usr/share/mk/bsd.port.mk -V PORT_DBDIR 2>/dev/null`
[ -n "$port_dbdir" ] && export port_dbdir
fi
usage () {
local pd pdb port_dbdir
[ -z "$pd" ] && pd=/usr/ports
[ -z "$pdb" ] && pdb=/var/db/pkg
[ -z "$port_dbdir" ] && port_dbdir=/var/db/ports
version
echo ''
echo 'Usage:'
echo "Common flags: [--force-config -CGHKgntvw -[B|b] -[f|i] -[D|d]]"
echo " [[[--packages|-P]|[--packages-only|-PP]] | [--packages-build]]"
echo " [--packages-if-newer] [--delete-build-only] [--always-fetch]"
echo " [--local-packagedir=<path>] [--packages-local] [--delete-packages]"
echo " [--backup-format=<fmt>] [--no-confirm] [--no-term-title] [--no-index-fetch]"
echo " [--index|--index-first|--index-only] [-m <arguments for make>]"
echo " [-x <glob pattern to exclude from building>]"
echo "$progname [Common flags] <full name of port directory in $pdb>"
echo "$progname [Common flags] <full path to $pd/foo/bar>"
echo "$progname [Common flags] <glob pattern of directories in $pdb>"
echo "$progname [Common flags] [--update-if-newer] Multiple full names/paths"
echo " from $pdb|$pd and/or multiple globs from $pdb"
echo ''
echo "$progname [Common flags] . [Use in $pd/foo/bar to build that port]"
echo ''
echo "$progname [Common flags] -a"
echo ''
echo "$progname --show-work [-Gv] [-m <args>] <single port, as above>"
echo ''
echo "$progname [Common flags] -o <new port dir in $pd> <installed port>"
echo "$progname [Common flags] [-R] -r <name/glob of port directory in $pdb>"
echo ' (-r <port> can be specified multiple times)'
echo ''
echo "$progname -l"
echo "$progname [--index-only [-t]] -L"
echo ''
echo "$progname --list-origins"
echo ''
echo "$progname --try-broken"
echo ''
echo "$progname [--force-config|-G] [-P|-PP] [-aftv] -F"
echo ''
echo "$progname [-n|y] [-b] [-D|d] -e <name/glob of a single port in $pdb>"
echo "$progname [-n|y] [-b] [-D|d] -s"
echo ''
echo "$progname [-n|y] [-t] --clean-distfiles"
echo ''
echo "$progname [-n|y] [--index|--index-only] --clean-packages"
echo ''
echo "$progname [-n|y] [--index|--index-only] [-v] --check-depends"
echo ''
echo "$progname [-n|y] [-v] --check-port-dbdir"
echo ''
echo "$progname -h|--help"
echo "$progname --version"
echo ''
echo "--force-config run 'make config' for all ports (overrides -G)"
echo "-C prevents 'make clean' from being run before building"
echo "-G prevents 'make config'"
echo "-H hide details of the port build and install in a log file"
echo "-K prevents 'make clean' from being run after building"
echo '-B prevents creation of the backup package for the installed port'
echo '-b create and keep a backup package of an installed port'
echo '-g create a package of the new port'
echo '-n run through all steps, but do not make or install any ports'
echo '-t recurse dependencies thoroughly, using all-depends-list'
echo '-v verbose output'
echo '-w save old shared libraries before deinstall'
echo '[-R] -f always rebuild ports (overrides -i)'
echo '-i interactive update mode -- ask whether to rebuild ports'
echo '-D no cleaning of distfiles'
echo '-d always clean distfiles'
echo "-m <arguments for the 'make' command line>"
echo "-x <avoid building or updating ports that match this pattern>"
echo ' Can be specified more than once'
echo ''
echo '--no-confirm do not ask user to confirm list of ports to be'
echo ' installed and/or updated before proceeding'
echo '--no-term-title do not update the xterm title bar'
echo ''
echo '--no-index-fetch skip fetching the INDEX file'
echo '--index use INDEX-[7-9] exclusively to check if a port is up to date'
echo '--index-first use the INDEX for status, but double-check with the port'
echo '--index-only do not try to use /usr/ports'
echo ''
echo '--delete-build-only delete ports that are build-only dependencies'
echo ' after a successful run, only if installed this run'
echo ''
echo '--update-if-newer (only for multiple ports listed on command line)'
echo ' do not rebuild/reinstall if the installed version is up to date'
echo ''
echo '-P|--packages use packages, but build port if not available'
echo '-PP|--packages-only fail if no package is available'
echo '--packages-build use packages for all build dependencies'
echo '--packages-if-newer use package if newer than installed even'
echo ' if the package is not the latest according to the ports tree'
echo '--always-fetch fetch package even if it already exists locally'
echo '--local-packagedir=<path> where local packages can be found,'
echo ' will fall back to fetching if no local version exists'
echo '--packages-local use packages from --local-packagedir only'
echo '--delete-packages after installing from a package, delete it'
echo ''
echo '-a check all ports, update as necessary'
echo ''
echo '--show-work list what ports are and would be installed'
echo ''
echo '-o replace the installed port with a port from a different origin'
echo '[-R] -r rebuild port, and all ports that depend on it'
echo '-R used with -[rf] to skip ports updated on a previous run'
echo ''
echo '-l list all installed ports by category'
echo '-L list all installed ports by category, and search for updates'
echo ''
echo "--list-origins list directories from $pd for root and leaf ports"
echo ''
echo '[--force-config|-G] [-aftv] -F fetch distfiles only'
echo ''
echo '-n answer no to all user prompts for the features below'
echo '-y answer yes to all user prompts for the features below'
echo ''
echo '--try-broken do not skip ports marked as broken'
echo ''
echo '[-n|y] [-b] [-D|d] -e expunge one port via pkg delete, and remove its distfiles'
echo '[-n|y] [-b] [-D|d] -s clean out stale ports that used to be depended on'
echo ''
echo '[-t] [-n] --clean-distfiles offer to delete stale distfiles'
echo '[-t] -y --clean-distfiles delete stale distfiles without prompting'
echo ' with -t distfile is valid from any port, not just those installed'
echo ''
echo '[--index|--index-only] [-n] --clean-packages offer to delete stale packages'
echo '[--index|--index-only] -y --clean-packages delete without prompting'
echo ' --index-only is required if no ports tree is available'
echo ''
echo '[-n|y] [-v] --check-depends cross-check and update dependency info for all ports'
echo ''
echo "[-n|y] [-v] --check-port-dbdir check for stale entries in $port_dbdir"
echo ''
echo '-h|--help display this help message'
echo '--version display the version number'
echo ''
echo 'Please see the portmaster(8) man page for more information'
safe_exit ${1:-1}
}
globstrip () { local in ; in=${1%[*]} ; in=${in%\\} ; echo $in ; }
# Takes a pattern as input
# Return values:
# 0 - Matched one and only one directory in $pdb
# 1 - No match
# 2 - Matched multiple directories
#
find_glob_dirs () {
# Global: glob_dirs
local pattern
pattern=`globstrip $1`
glob_dirs=`$PKG_CMD query -g "%n-%v" ${pattern}\*`
case "$glob_dirs" in
# Match a newline in multiple responses from find
*'
'*) return 2 ;;
'') ;;
*) return ;;
esac
unset glob_dirs
return 1
}
match_flavor () {
local origin=$(dir_part $1)
local flavor # =$(flavor_part $1)
local iport="$2"
local dir="$pd/$origin"
if [ -d "$dir" ]; then
local IFS=' '
local pkgname=${iport%-*}
local flavors=$(pm_make -C "$dir" -V FLAVORS)
for flavor in $flavors; do
local p=$(pm_make -C "$dir" FLAVOR=$flavor -V PKGNAME)
if [ -n "$p" -a "${p%-*}" = "$pkgname" ]; then
echo "$origin@$flavor"
return
fi
done
fi
echo "$1" # should not be reached!
}
origin_from_pdb () {
local flavor pkgname origin_flavor
pkgname="$1"
flavor=$($PKG_CMD annotate -Sq "$pkgname" flavor)
if origin_flavor=$($PKG_CMD query '%o'"${flavor:+@$flavor}" "$pkgname" 2>/dev/null); then
match_flavor $origin_flavor $pkgname
return 0
fi
case "$pkgname" in bsdpan-*) return 3 ;; esac
if pm_islocked "$pkgname"; then
if [ -n "$PM_VERBOSE" -o -n "$LIST_ORIGINS" ]; then
# An error above doesn't necessarily mean there's
# a problem in +MANIFEST, so don't mention it
echo " ===>>> No origin available for $pkgname" >&2
echo " ===>>> $pdb/$pkgname/+IGNOREME exists or the package is locked" >&2
echo '' >&2
fi
return 2
else
# Same as above
echo " ===>>> No origin available for $pkgname" >&2
echo '' >&2
fi
return 1
}
#=============== End functions we always want to have ===============
#=============== Begin Command Line Option Processing ===============
packages_init () {
local e1 e2 e3
e1="The -P/--packages and -PP/--packages-only options are mutually exclusive"
e2="The --packages-build option and the -P[P] options are mutually exclusive"
e3="The --packages-if-newer and -PP/--packages-only options are mutually exclusive"
case "$1" in
first) [ "$PM_PACKAGES" = only ] && fail $e1
[ -n "$PM_PACKAGES_BUILD" ] && fail $e2
[ -z "$PM_PACKAGES" ] && { PM_PACKAGES=first ; export PM_PACKAGES; } ;;
only) [ "$PM_PACKAGES" = first ] && fail $e1
[ "$PM_PACKAGES" = newer ] && fail $e3
[ -n "$PM_PACKAGES_BUILD" ] && fail $e2 ;;
build) case "$PM_PACKAGES" in first|only) fail $e2 ;; esac ;;
newer) [ "$PM_PACKAGES" = only ] && fail $e3
[ -z "$PM_PACKAGES" -a -z "$PM_PACKAGES_BUILD" ] && {
PM_PACKAGES=newer ; export PM_PACKAGES; } ;;
local) [ -z "$PM_PACKAGES" -a -z "$PM_PACKAGES_BUILD" ] && {
PM_PACKAGES=local ; export PM_PACKAGES; } ;;
esac
}
cross_idx () {
local e1
e1='The --index, --index-first, and --index-only options are mutually exclusive'
case "$*" in
*--index*--index*) fail $e1 ;;
index\ *) [ -n "$PM_INDEX_FIRST" -o -n "$PM_INDEX_ONLY" ] && fail $e1 ;;
first\ *) [ -n "$PM_INDEX_ONLY" ] && fail $e1 ;;
only\ *) [ -n "$PM_INDEX_FIRST" ] && fail $e1 ;;
esac
}
for var in "$@" ; do
case "$var" in
-PP[A-Za-z0-9]*|-*[A-Za-z0-9]PP*)
fail "The -PP option must stand alone" ;;
--packages) packages_init first ;;
-PP|--packages-only) packages_init only
PM_PACKAGES=only ; export PM_PACKAGES ;;
--packages-build) packages_init build
unset PM_PACKAGES
PM_PACKAGES_BUILD=pmp_build
export PM_PACKAGES_BUILD ;;
--packages-if-newer) packages_init newer
PM_PACKAGES_NEWER=pmp_newer
export PM_PACKAGES_NEWER ;;
--packages-local) packages_init local
PM_PACKAGES_LOCAL=pmp_local
export PM_PACKAGES_LOCAL ;;
--always-fetch) PM_ALWAYS_FETCH=pm_always_fetch
export PM_ALWAYS_FETCH ;;
--local-packagedir=*) LOCAL_PACKAGEDIR=${var#--local-packagedir=}
export LOCAL_PACKAGEDIR ;;
--delete-packages) PM_DELETE_PACKAGES=pm_delete_packages
export PM_DELETE_PACKAGES ;;
--backup-format=*) BACKUP_FORMAT=${var#--backup-format=}
export BACKUP_FORMAT ;;
--package-format=*) PACKAGE_FORMAT=${var#--package-format=}
export PACKAGE_FORMAT ;;
# --flavor=*) PM_FLAVOR=${var#--flavor=} ;;
--update-if-newer) PM_UPDATE_IF_NEWER=pm_update_if_newer
export PM_UPDATE_IF_NEWER ;;
--delete-build-only) PM_DEL_BUILD_ONLY=pm_dbo
export PM_DEL_BUILD_ONLY ;;
--no-confirm) PM_NO_CONFIRM=pm_no_confirm
export PM_NO_CONFIRM ;;
--no-term-title) PM_NO_TERM_TITLE=pm_no_term_title
export PM_NO_TERM_TITLE ;;
--no-index-fetch) PM_NO_INDEX_FETCH=pm_no_index_fetch ;;
--index) cross_idx "index $*" ; PM_INDEX=pm_index ; export PM_INDEX ;;
--index-first) cross_idx "first $*" ; PM_INDEX=pm_index
PM_INDEX_FIRST=pm_index_first
export PM_INDEX PM_INDEX_FIRST ;;
--index-only) cross_idx "only $*" ; PM_INDEX=pm_index
PM_INDEX_ONLY=pm_index_only
export PM_INDEX PM_INDEX_ONLY ;;
--help) usage 0 ;;
--version) version ; exit 0 ;;
--clean-distfiles) CLEAN_DISTFILES=clean_distfiles ;;
--clean-distfiles-all) echo "===>>> The -all form is deprecated, please use -y instead"
CLEAN_DISTFILES=clean_distfiles ; PM_YES=yopt ;;
--clean-packages) CLEAN_PACKAGES=clean_packages ;;
--clean-packages-all) echo "===>>> The -all form is deprecated, please use -y instead"
CLEAN_PACKAGES=clean_packages ; PM_YES=yopt ;;
--check-depends) CHECK_DEPENDS=check_depends ;;
--check-port-dbdir) CHECK_PORT_DBDIR=check_port_dbdir ;;
--list-origins) LIST_ORIGINS=list_origins ;;
--show-work) SHOW_WORK=show ; PM_THOROUGH=thorough ;;
--force-config) export PM_FORCE_CONFIG=pm_force_config ;;
--try-broken) TRY_BROKEN=try_broken; PM_MAKE_ARGS="$PM_MAKE_ARGS -DTRYBROKEN" ;;
--*) echo "Illegal option $var" ; echo ''
echo "===>>> Try $progname --help"; exit 1 ;;
*) newopts="$newopts $var" ;;
esac
done
[ -n "$PM_INDEX" -a -n "$CHECK_PORT_DBDIR" ] &&
fail 'The --index* and --check-port-dbdir options are mutually exclusive'
[ -n "$PM_PACKAGES_LOCAL" -a -z "$LOCAL_PACKAGEDIR" ] &&
fail 'The --packages-local option requires --local-packagedir to be defined'
set -- $newopts
unset var newopts
# Save switches for potential child processes
while getopts 'BCDFGHIKLPRabde:fghilm:nop:r:stvwx:y' COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
B) NO_BACKUP=Bopt; ARGS="-B $ARGS" ;;
C) DONT_PRE_CLEAN=Copt; ARGS="-C $ARGS" ;;
D) DONT_SCRUB_DISTFILES=Dopt; ARGS="-D $ARGS" ;;
F) FETCH_ONLY=Fopt; ARGS="-F $ARGS" ;;
G) [ -z "$PM_FORCE_CONFIG" ] && {
PM_NO_MAKE_CONFIG=Gopt; ARGS="-G $ARGS"; } ;;
H) HIDE_BUILD=Hopt; ARGS="-H $ARGS" ;;
I) NON_INTERACTIVE=Iopt; ARGS="-I $ARGS" ;;
K) DONT_POST_CLEAN=Kopt; ARGS="-K $ARGS" ;;
L) LIST_PLUS=Lopt ;;
P) packages_init first ;;
R) RESTART=Ropt ; ARGS="-R $ARGS" ;;
a) UPDATE_ALL=aopt ;;
b) BACKUP=bopt; ARGS="-b $ARGS" ;;
d) ALWAYS_SCRUB_DISTFILES=dopt; ARGS="-d $ARGS" ;;
e) EXPUNGE=$OPTARG ;;
f) export PM_FORCE=fopt ;;
g) MAKE_PACKAGE=gopt; ARGS="-g $ARGS" ;;
h) usage 0 ;;
i) INTERACTIVE_UPDATE=iopt; ARGS="-i $ARGS" ;;
l) LIST=lopt ;;
m) export PM_MAKE_ARGS=$OPTARG # For 'make checksum'
ARGS="-m $PM_MAKE_ARGS $ARGS" ;;
n) NO_ACTION=nopt; ARGS="-n $ARGS" ;;
o) REPLACE_ORIGIN=oopt ;; # -o should take a parameter and $OPTARG should be assigned here
p) fail 'The -p option has been deprecated' ;;
r) PM_URB=ropt
if [ -d "$pdb/$OPTARG" ] && $PKG_CMD info -e $OPTARG; then
glob_dirs=$OPTARG
else
case "$OPTARG" in */*) fail 'The argument to -r must be a package name, or a glob pattern' ;; esac
find_glob_dirs $OPTARG
case $? in
1) fail "$OPTARG is not installed" ;;
2) fail 'The argument to -r must match only one port' ;;
esac
fi
PM_URB_IPORTS="${PM_URB_IPORTS}${glob_dirs##*/} "
PM_URB_ORIGINS="${PM_URB_ORIGINS}`origin_from_pdb ${glob_dirs##*/}` "
unset glob_dirs ;;
s) CLEAN_STALE=sopt ;;
t) PM_THOROUGH=topt; ARGS="-t $ARGS" ;;
v) PM_VERBOSE=vopt; ARGS="-v $ARGS" ;;
w) SAVE_SHARED=wopt; ARGS="-w $ARGS" ;;
x) case "$OPTARG" in
-*) fail 'The -x option requires an argument' ;;
esac
PM_EXCL="${PM_EXCL}`globstrip ${OPTARG}` " ;;
y) PM_YES=yopt; ARGS="-y $ARGS" ;;
*) echo '' ; echo "===>>> Try $progname --help"; exit 1 ;;
esac
done
shift $(( $OPTIND - 1 ))
[ -n "$PM_YES" -a -n "$NO_ACTION" ] && fail 'The -y and -n options are mutually exclusive'
[ -n "$PM_EXCL" ] && export PM_EXCL
test_command_line () {
local var envar
for var in $my_environment; do
case "$var" in
${1}=*) envar=$1 ;;
${2}=*) envar=$2 ;;
esac
done
if [ -n "$envar" ]; then
unset $envar
return 0
fi
return 1
}
# Error checking for getopts
[ -n "$PM_FORCE" -a -n "$INTERACTIVE_UPDATE" ] &&
fail "The -f and -i options are mutually exclusive"
if [ -n "$BACKUP" -a -n "$NO_BACKUP" ]; then
test_command_line NO_BACKUP BACKUP ||
fail "The -b and -B options are mutually exclusive"
fi
if [ -n "$ALWAYS_SCRUB_DISTFILES" -a -n "$DONT_SCRUB_DISTFILES" ]; then
test_command_line ALWAYS_SCRUB_DISTFILES DONT_SCRUB_DISTFILES ||
fail "The -d and -D options are mutually exclusive"
fi
[ -n "$NO_ACTION" ] && PM_NO_MAKE_CONFIG=no_action PM_FORCE_CONFIG=""
[ -n "$PM_NO_MAKE_CONFIG" -a -n "$PM_FORCE_CONFIG" ] && unset PM_NO_MAKE_CONFIG
if [ -n "$LIST" -o -n "$LIST_PLUS" ]; then
if [ -n "$FETCH_ONLY" -o -n "$RESTART" -o -n "$UPDATE_ALL" -o \
-n "$EXPUNGE" -o -n "$PM_FORCE" -o -n "$NO_ACTION" -o \
-n "$REPLACE_ORIGIN" -o -n "$PM_URB" -o -n "$CLEAN_STALE" ]; then
fail 'The -[lL] options are not compatible with -FRaefnors'
fi
[ $# -gt 0 ] && fail 'The -[lL] options are not compatible with updates or installs'
fi
[ -n "$PM_PACKAGES" -a -n "$FETCH_ONLY" ] && export PM_NO_CONFIRM=pm_no_confirm
unset my_environment COMMAND_LINE_ARGUMENT
unset -f packages_init cross_idx test_command_line
#=============== End Command Line Option Processing ===============
# Update based on options chosen above
if [ "$$" -eq "$PM_PARENT_PID" ]; then
# Continue error checking in parent only
[ -n "$PM_URB" -o -n "$UPDATE_ALL" ] && [ -n "$1" ] &&
fail 'The -[ar] options are not compatible with other updates'
if [ -n "$PM_INDEX" ] &&
[ -z "$LIST" -a -z "$LIST_ORIGINS" -a -z "$EXPUNGE" -a -z "$CLEAN_STALE" ]; then
if [ -z "$INDEXFILE" ]; then
ver=`uname -r`
INDEXFILE=INDEX-${ver%%\.*}
unset ver
fi
[ -z "$INDEXDIR" -a -n "$PM_INDEX_ONLY" -a -z "$pd" ] && INDEXDIR="$TMPDIR"
PM_INDEX="${INDEXDIR:=$pd}/${INDEXFILE}"
if [ -z "$PM_NO_INDEX_FETCH" ]; then
: ${FETCHINDEX:='fetch -am -o'}
: ${MASTER_SITE_INDEX:='http://www.FreeBSD.org/ports/'}
do_index_fetch=yes_index_fetch
index_time=`stat -f '%Um' ${PM_INDEX}.bz2 2>/dev/null`
if [ -n "$index_time" ]; then
# If root, this will succeed either way
if $FETCHINDEX ${PM_INDEX}.bz2 ${MASTER_SITE_INDEX}${INDEXFILE}.bz2 2>/dev/null; then
unset do_index_fetch
newindex="${PM_INDEX}.bz2"
fi
fi
if [ -n "$do_index_fetch" ] ||
[ ${index_time:-0} -ne `stat -f '%Um' ${PM_INDEX}.bz2 2>/dev/null` ]; then
dli=`/usr/bin/mktemp -d ${TMPDIR}/d-${PM_PARENT_PID}-index 2>/dev/null` ||
fail "Could not create a temporary directory for index in $TMPDIR"
if [ -n "$do_index_fetch" ]; then
ift="$FETCHINDEX ${dli}/${INDEXFILE}.bz2 ${MASTER_SITE_INDEX}${INDEXFILE}.bz2"
$ift || fail Could not perform $ift
unset ift
newindex="${dli}/${INDEXFILE}.bz2"
fi
bunzip2 --keep < $newindex > ${dli}/$INDEXFILE
if [ -w "${INDEXDIR}/" ]; then
pm_unlink $PM_INDEX
mv ${dli}/$INDEXFILE $PM_INDEX
if [ -n "$do_index_fetch" ]; then
pm_unlink ${PM_INDEX}.bz2
mv ${dli}/${INDEXFILE}.bz2 ${PM_INDEX}.bz2
fi
else
pm_sv 'Installing new INDEX file'
pm_install_s ${dli}/$INDEXFILE $PM_INDEX
[ -n "$do_index_fetch" ] &&
pm_install_s ${dli}/${INDEXFILE}.bz2 ${PM_INDEX}.bz2
fi
rm -rf $dli ; unset dli
fi
unset FETCHINDEX MASTER_SITE_INDEX do_index_fetch index_time newindex
else
[ -r "$PM_INDEX" ] ||
fail "The --no-index-fetch option was used, but $PM_INDEX does not exist"
fi
unset INDEXFILE INDEXDIR
PM_INDEX_PORTS=`$PKG_CMD version -Ivl\< $PM_INDEX | cut -f1 -d\<`
export PM_INDEX_PORTS
if [ -z "$pd" -o "$pd" != /usr/ports ]; then
PM_IPD=`head -1 $PM_INDEX | cut -f 2 -d\|`
PM_IPD=${PM_IPD%/*}
PM_IPD=${PM_IPD%/*}
[ -n "$PM_INDEX_ONLY" ] && pd=$PM_IPD
else
PM_IPD=$pd
fi
export PM_IPD
fi # [ -n "$PM_INDEX" ]
if [ -z "$EXPUNGE" -a -z "$CLEAN_STALE" ]; then
if [ -n "$pd" ]; then
export pd
elif [ -z "$LIST" -a -z "$LIST_ORIGINS" ]; then
fail 'The value of PORTSDIR cannot be empty'
fi
else
if [ -n "$pd" ] && pm_isdir "$pd" ]; then
export pd
else
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
pm_v "===>>> There is no ports tree, so using -D option"
unset ALWAYS_SCRUB_DISTFILES
DONT_SCRUB_DISTFILES=Dopt_es; ARGS="-D $ARGS"
fi
fi
fi
if [ -z "$DISTDIR" -a "$PM_PACKAGES" != only -a -z "$CHECK_DEPENDS" -a \
-z "$CHECK_PORT_DBDIR" -a -z "$LIST_ORIGINS" ]; then
if ! DISTDIR=`pm_make_b -f/usr/share/mk/bsd.port.mk -V DISTDIR 2>/dev/null`; then
if ! pm_isdir "$PWD"; then
echo ''
echo "===>>> Your current working directory no longer seems to exist"
fail 'Try: cd'
fi
fi
fi
[ -n "$DISTDIR" ] && { DISTDIR="${DISTDIR%/}/"; export DISTDIR; }
if [ -n "$PM_PACKAGES_BUILD" -o -n "$PM_DEL_BUILD_ONLY" ]; then
PM_BUILD_ONLY_LIST=pm_bol
export PM_BUILD_ONLY_LIST
fi
fi # [ "$$" -eq "$PM_PARENT_PID" ]
#=============== cache some build parameters in the environment ===============
SCRIPTSDIR="$pd/Mk/Scripts" PORTSDIR="$pd" MAKE=make . "$pd/Mk/Scripts/ports_env.sh" > /dev/null
#=============== Begin functions relevant to --features and main ===============
# find installed port for given origin (with optional @flavor) in the pkg DB
# return values:
# 0 - package name has been printed to STDOUT
# 1 - no matching installed packages found
iport_from_origin () {
local origin flavor pkgname_l pkgname pkgflavor
origin=$(dir_part "$1")
flavor=$(flavor_part "$1")
if [ -z "$flavor" ]; then
unset FLAVOR
flavor=$(pm_make -C "${pd}/${origin}" -V FLAVOR)
fi
pkgname_l=$(echo $($PKG_CMD query '%n-%v' $origin)) || return 1
# if multiple flavors registered then fall back to $FLAVOR if no flavor has been passed in $1
[ "${pkgname_l}" != "${pkgname_l#* }" ] && : ${flavor:=$FLAVOR}
for pkgname in $pkgname_l; do
pkgflavor=$($PKG_CMD annotate -Sq "$pkgname" flavor)
if [ "$pkgflavor" = "$flavor" ]; then
echo $pkgname
return 0
fi
done
return 1
}
# Takes default value, optional value, and message as input
# Return values:
# 0 - Default value chosen
# 1 - Optional value chosen
#
get_answer_g () {
local default option answer
default=$1 ; option=$2 ; shift 2
while : ; do
echo -e "${*} [${default}] \c"
read answer
echo ''
case "$answer" in
[A-Z]) answer=`echo $answer | tr [:upper:] [:lower:]` ;;
esac
case "$answer" in
${default}|'') return 0 ;;
${option}) return 1 ;;
*) echo " ===>>> $answer is not a valid response" ; echo '' ;;
esac
done
}
# Takes a default value and message as input
# Return values:
# 0 - Answer is "Yes"
# 1 - Answer is "No"
#
get_answer_yn () {
local default option
default=$1 ; shift
[ "$default" = 'y' ] && option=n || option=y
if [ -z "$PM_YES" -a -z "$NO_ACTION" ]; then
get_answer_g $default $option "${*}? y/n"
case "${?}${default}" in
0y|1n) return 0 ;;
0n|1y) return 1 ;;
esac
else
[ -n "$PM_YES" ] && return 0
return 1
fi
}
# Find the new origin for moved ports
# Set global variable moved_npd on success
# Return values:
# 0 - The new origin has been stored in the global variable moved_npd
# 1 - The port has not been moved to a new origin
find_moved_port () {
# Global: moved_npd
local sf iport flag IFS moved reason
sf=$(dir_part "$1") # Search for origin without flavor
iport="$2" # initial package name
flag="$3" # optional flag "nonfatal"
# To avoid having each word of the reason treated separately
IFS='
'
for moved in `grep "^$sf|" $pd/MOVED`; do
case "$moved" in
${sf}\|\|*) [ -n "$iport" ] || iport=`iport_from_origin $sf`
if pm_islocked $iport; then
if [ -n "$PM_VERBOSE" ]; then
echo ''
echo " ===>>> The $sf port has been deleted"
echo " ===>>> Reason: ${moved##*|}"
echo " ===>>> Skipping it due to +IGNOREME file or the package being locked"
echo ''
fi
return 0
else
reason=${moved##*|}
[ "$flag" != 'nonfatal' ] &&
fail "The $sf port has been deleted: $reason"
fi ;;
${sf}\|*) moved_npd=${moved#*\|} # New port directory
moved_npd=${moved_npd%%\|*}
[ -n "$(flavor_part $moved_npd)" ] && moved_npd=$(match_flavor $moved_npd $iport)
echo ''
echo " ===>>> The $sf port moved to $moved_npd"
echo " ===>>> Reason: ${moved##*|}"
echo ''
find_moved_port $moved_npd ;;
esac
done
if [ -z "$moved_npd" ]; then
if [ -z "$reason" ]; then
echo ''
echo " ===>>> No $pd/$sf exists, and no information"
echo " ===>>> about $sf can be found in $pd/MOVED"
else # Only reached in LIST_PLUS
echo " ===>>> The $sf port has been deleted: $reason"
fi
echo ''
[ -n "$iport" ] || iport=`iport_from_origin $1` || return 1
pm_islocked $iport || return 1
fi
return 0
}
all_pkgs_by_origin () {
namesorigins=`$PKG_CMD query -a "%n-%v %o"`
echo "$namesorigins"
return
}
read_distinfos () {
local iport origin distinfo s f discard
echo '############' > $DI_FILES # Make the file > 0 bytes
echo "===>>> Gathering distinfo list for installed ports"
echo ''
all_pkgs_by_origin | while read iport origin; do
if ! pm_isdir_pd "$origin"; then
find_moved_port $origin $iport nonfatal >/dev/null
[ -n "$moved_npd" ] || continue
origin=$moved_npd
fi
origin="${pd}/"$(dir_part $origin)
if [ -s "${origin}/distinfo" ]; then
distinfo="${origin}/distinfo"
else
pm_cd $origin || continue
distinfo=`pm_make -V DISTINFO_FILE`
# Do not make this error fatal unless using
# --clean-distfiles. This will prevent accidentally
# killing other background processes when running
# in the background itself.
if [ -z "$distinfo" ]; then
if [ -z "$CLEAN_DISTFILES" ]; then
continue
else
fail "No DISTINFO_FILE in $origin"
fi
fi
fi
if [ -s "$distinfo" ]; then
while read s f discard; do
case "$s" in
SHA256) f=${f#(} ; echo ${f%)} >> $DI_FILES ;;
esac
done < $distinfo
fi
done
# Tell safe_exit that we are done
pm_unlink ${DI_FILES}-e
sed -i -e 1s/############/%%%%%%%%%%%%/ $DI_FILES
pm_unlink ${DI_FILES}-e
}
read_distinfos_all () {
local origin distinfo s f discard
echo '############' > $DI_FILES # Make the file > 0 bytes
echo "===>>> Gathering distinfo list for all ports"
echo ' (This will take several minutes)'
echo ''
for origin in ${pd}/*/*; do
case "${origin#$pd/}" in
Mk/*|T*|distfiles/*|packages/*|*/[Mm]akefile*|CVS/*|*/CVS|base/*) continue ;; esac
pm_isdir "$origin" || continue
if [ -s "${origin}/distinfo" ]; then
distinfo="${origin}/distinfo"
else
pm_cd $origin || continue
distinfo=`pm_make -V DISTINFO_FILE`
[ -n "$distinfo" ] ||
{ echo ''; echo "===>>> No DISTINFO_FILE in $origin"; echo ''; }
fi
if [ -s "$distinfo" ]; then
while read s f discard; do
case "$s" in
SHA256) f=${f#(} ; echo ${f%)} >> $DI_FILES ;;
esac
done < $distinfo
fi
done
# Tell safe_exit that we are done
pm_unlink ${DI_FILES}-e
sed -i -e 1s/############/%%%%%%%%%%%%/ $DI_FILES
pm_unlink ${DI_FILES}-e
}
ports_by_category () {
# Global: num_roots num_trunks num_branches num_leaves num_ports
local pkg
pm_v "===>>> Sorting ports by category"
roots=` $PKG_CMD query -e "%#d = 0 && %#r = 0" "%n-%v"`
trunks=` $PKG_CMD query -e "%#d = 0 && %#r > 0" "%n-%v"`
branches=`$PKG_CMD query -e "%#d > 0 && %#r > 0" "%n-%v"`
leaves=` $PKG_CMD query -e "%#d > 0 && %#r = 0" "%n-%v"`
num_roots=$(echo $(echo $roots | wc -w))
num_trunks=$(echo $(echo $trunks | wc -w))
num_branches=$(echo $(echo $branches | wc -w))
num_leaves=$(echo $(echo $leaves | wc -w))
num_ports=$(echo $($PKG_CMD query -a "%n-%v" | wc -w))
}
delete_empty_dist_subdirs () {
# Get back to somewhere safe so we do not
# delete our CWD out from under ourselves
pm_cd $DISTDIR || fail "Cannot cd into $DISTDIR"
find $DISTDIR -depth -mindepth 1 -type d \( -empty -and ! -path \*\.zfs/\* \) -delete
}
init_packages_var () {
# Global: PACKAGES
[ -n "$PACKAGES" ] && return
PACKAGES=`pm_make -f/usr/share/mk/bsd.port.mk -V PACKAGES 2>/dev/null`
if [ -z "$PACKAGES" ]; then
if [ -d "${pd}/packages" -a -w "${pd}/packages" ]; then
PACKAGES="${pd}/packages"
else
if [ -d "${pd}/" -a -w "${pd}/" ]; then
PACKAGES="${pd}/packages"
else
fail 'The value of PACKAGES cannot be empty and the directory must be writable'
fi
fi
fi
export PACKAGES
}
parse_index () {
local line origin
origin=$(dir_part $1)
line=`grep -m1 "|${PM_IPD}/${origin}|" $PM_INDEX` || return 1
case "$2" in
name) echo ${line%%|*} ;;
localbase) echo $line | cut -f 3 -d\| ;;
comment) echo $line | cut -f 4 -d\| ;;
descr) echo $line | cut -f 5 -d\| ;;
maintainer) echo $line | cut -f 6 -d\| ;;
category) echo $line | cut -f 7 -d\| ;;
b-deps) echo $line | cut -f 8 -d\| ;;
r-deps) echo $line | cut -f 9 -d\| ;;
www) echo $line | cut -f 10 -d\| ;;
esac
}
#=============== End functions relevant to --features and main ===============
#=============== Begin code relevant only to --features ===============
if [ -n "$CLEAN_DISTFILES" ]; then
[ -n "$DISTDIR" ] || fail 'There is no DISTDIR to clean'
# Set the file name here since we are usually called in a subshell
pm_mktemp DI-FILES ; DI_FILES=$pm_mktemp_file
if [ -z "$PM_THOROUGH" ]; then
read_distinfos
else
read_distinfos_all
fi
echo "===>>> Checking for stale distfiles" ; echo ''
for df in `find $DISTDIR -type f | sort`; do
f=${df#$DISTDIR}
if ! grep -ql ^$f $DI_FILES; then
get_answer_yn n "\t===>>> Delete stale file: $f"
case "$?" in
0) echo " Deleting $f" ; echo ''
/bin/unlink $df ;;
*) continue ;;
esac
fi
done
delete_empty_dist_subdirs
safe_exit
fi
if [ -n "$CLEAN_PACKAGES" ]; then
init_packages_var
echo "===>>> Checking for stale packages"
for package in `find $PACKAGES -type f | sort`; do
pkg_dir=${package##*/} ; pkg_dir=${pkg_dir%\.*} ; echo ''
origin=`$PKG_CMD query -F $package "%o" 2>/dev/null` ||
origin=`tar -O -zxvf $package '+CONTENTS' 2>/dev/null | grep '@comment ORIGIN:'` ||
origin=`tar -O -zxvf $package '+MANIFEST' 2>/dev/null | grep '^origin:'` ||
fail "Empty origin in $package"
origin=${origin#@comment ORIGIN:}
origin=${origin#origin: }
if [ -z "$PM_INDEX" ]; then
if pm_isdir_pd "$origin"; then
pm_cd $pd/$origin && port_ver=`pm_make -V PKGNAME`
[ -n "$port_ver" ] || fail "Is $pd/$origin/Makefile missing?"
else
echo "===>>> The origin for ${package##*/} ($origin) is missing"
fi
else
if ! port_ver=`parse_index $origin name`; then
echo "===>>> Cannot determine latest version of ${package##*/} from $PM_INDEX"
fi
fi
if [ -n "$port_ver" ]; then
if [ "$port_ver" = "$pkg_dir" ]; then
echo "===>>> ${package##*/} is up to date"
if ! $PKG_CMD info -e $pkg_dir; then
echo " ===>>> $pkg_dir is not installed"
echo " ===>>> Path: ${package}"
get_answer_yn y "\n\t===>>> Delete stale package: ${package##*/}"
case "$?" in
0) echo " ===>>> Deleting $package"
pm_unlink_s $package ;;
esac
fi
unset port_ver
continue
fi
echo "===>>> Package version: $pkg_dir"
echo " Latest version: $port_ver"
unset port_ver
if $PKG_CMD info -e $pkg_dir; then
echo " ===>>> ${package##*/} matches the installed version"
else
echo " ===>>> ${package##*/} is not installed"
fi
fi
echo " ===>>> Path: ${package}"
get_answer_yn n "\n\t===>>> Delete stale package: ${package##*/}"
case "$?" in
0) echo " ===>>> Deleting $package"
pm_unlink_s $package ;;
esac
done
echo '' ; echo ''
echo "===>>> Deleting stale symlinks"
pm_cd $PACKAGES || fail "Cannot cd to $PACKAGES"
for link in `find . -type l | sort` ; do
if [ ! -e "$link" ]; then
echo " ===>>> ${link#./}"
$PM_SU_CMD /bin/unlink $link
fi
done
echo '' ; echo ''
empty_dirs=`find . -type d -empty -print | sort`
case "$empty_dirs" in
\.|'') echo "===>>> No empty directories in $PACKAGES" ;;
*) echo "===>>> Deleting empty directories"
for dir in $empty_dirs; do
echo " ===>>> ${dir#\.\/}"
done
pm_find_s . -type d -empty -delete ;;
esac
echo ''
safe_exit
fi # [ -n "$CLEAN_PACKAGES" ]
if [ -n "$CHECK_DEPENDS" ]; then
$PKG_CMD check -dn
exit 0
fi
if [ -n "$CHECK_PORT_DBDIR" ]; then
pm_isdir "$port_dbdir" ||
fail 'PORT_DBIR is empty, or the directory $port_dbdir does not exist'
unique_list=':'
echo "===>>> Building list of installed port names"; echo ''
while read pkg origin; do
if ! pm_isdir_pd "$origin"; then
find_moved_port $origin $pkg nonfatal >/dev/null
[ -n "$moved_npd" ] || continue
origin=$(dir_part $moved_npd)
fi
if ! pm_cd $pd/$origin; then
echo " ===>>> $pd/$origin does not exist for $pkg"
continue
fi
unique_list="${unique_list}`pm_make -V OPTIONS_NAME | tr '\n' ':'`"
done <<-EOF
$(all_pkgs_by_origin)
EOF
echo "===>>> Checking $port_dbdir"
[ -n "$PM_VERBOSE" ] && { print='-print'; echo '';
echo "===>>> Deleting empty directories (if any)"; }
pm_find_s $port_dbdir -type d -empty $print -delete
pm_v
for dir in ${port_dbdir}/*; do
dbdir=${dir#$port_dbdir/}
[ -n "$PM_VERBOSE" ] && echo -n "===>>> Checking ${dbdir}: "
case "$unique_list" in
*:${dbdir}:*) pm_v "Ok" ;;
*) pm_v
echo " ===>>> $dbdir does not seem to be installed"
get_answer_yn n "\n\t===>>> Delete ${dir}"
case "$?" in 0) pm_rm_s -rf $dir ;; esac
echo '' ;;
esac
done
exit 0
fi
if [ -n "$LIST_ORIGINS" ]; then
$PKG_CMD query -e '%#r = 0' '%o'
exit 0
fi
#=============== End code relevant only to --features ===============
#=============== Begin functions for getopts features and main ===============
check_state () {
# Global: state
local state_set makevars
[ -z "$TRY_BROKEN" ] && makevars="FORBIDDEN BROKEN IGNORE" || makevars="FORBIDDEN"
if egrep -ql '^(FORBIDDEN|BROKEN|IGNORE)' Makefile; then
for state in $makevars; do
state_set=`pm_make -V $state`
if [ -n "$state_set" ]; then
echo " ===>>> This port is marked $state"
echo -e "\t===>>> $state_set\n\n"
return 1
fi
done
fi
return 0
}
# Takes $iport and $origin as arguments
#
check_force_multi () {
if [ -n "$PM_FORCE" ]; then
check_restart_and_udf $1 || return 1
elif [ -n "$PM_URB_UP" ]; then
case " $PM_URB_LIST " in *" $1 "*) check_restart_and_udf $1 || return 1 ;;
esac
elif [ -n "$PM_MULTI_PORTS" ]; then
case "$PM_MULTI_PORTS" in
*:${1}:*) return 1 ;;
*:${2}:*) return 1 ;;
esac
fi
}
find_new_port () {
# Global: new_port
local portdir flavor
[ -n "$new_port" ] && return
portdir=$(dir_part "$1")
flavor=$(flavor_part "$1")
if pm_cd_pd $portdir; then
new_port=`FLAVOR=$flavor pm_make -V PKGNAME`
else
new_port=`parse_index $portdir name` ||
fail "No entry for $portdir in $PM_INDEX"
fi
}
check_for_updates () {
# Global: num_updates
local nf iport originflavor flavor origin port_ver do_update skip
[ "$1" = 'list' -o "$1" = 'multi' ] && { nf=nonfatal; shift; }
iport=$1
originflavor=${2:-`origin_from_pdb $iport`} || return 0
flavor=$(flavor_part "$originflavor")
export_flavor $flavor
origin=$(dir_part "$originflavor")
if [ -n "$PM_INDEX" ]; then
case "$PM_INDEX_PORTS" in
*${iport}*) port_ver=`parse_index $origin name` ||
fail "No entry for $origin in $PM_INDEX"
do_update=upd_idx ;;
esac
[ -z "$do_update" -a -z "$LIST_PLUS" ] && {
check_force_multi $iport $originflavor || do_update=upd_fm_idx; }
if [ -z "$do_update" -a -n "$PM_INDEX_ONLY" -a -n "$PM_THOROUGH" ]; then
port_ver=`parse_index $origin name` || {
echo " ===>>> $pd/$origin does not exist in $PM_INDEX";
echo " ===>>> This port should probably be updated"; }
else
[ -n "$PM_INDEX_FIRST" ] || skip=index_skip
fi
fi
if [ -z "$do_update" -a -z "$skip" -a -z "$PM_INDEX_ONLY" ] && pm_isdir "$pd/$origin"; then
if ! pm_cd $pd/$origin; then # <se> cannot happen - see pm_isdir test above
if pm_islocked "$iport"; then
echo " ===>>> Warning: Unable to cd to $pd/$origin"
echo " ===>>> Continuing due to $pdb/$iport/+IGNOREME or the package being locked"
echo ''
CUR_DEPS="${CUR_DEPS}${iport}:${originflavor}:"
return 0
else
fail "Cannot cd to port directory: $pd/$origin"
fi
fi
port_ver=`FLAVOR=$flavor pm_make -V PKGNAME`
[ -z "$port_ver" ] && fail "Is $pd/$origin/Makefile missing?"
elif [ -z "$do_update" -a -z "$skip" -a -z "$PM_INDEX_ONLY" ]; then
find_moved_port $origin $iport $nf
# If the port has moved and no +IGNOREME, we have to update it
if [ -n "$moved_npd" ]; then
if pm_islocked "$iport"; then
echo " ===>>> Continuing due to $pdb/$iport/+IGNOREME or the package being locked"
echo ''
CUR_DEPS="${CUR_DEPS}${iport}:${originflavor}:"
return 0
else
do_update=do_update_moved
new_port=""
find_new_port "$moved_npd" && port_ver=$new_port
fi
fi
fi
if [ -z "$do_update" -a -n "$port_ver" ]; then
if [ "$iport" = "$port_ver" ]; then
if [ -n "$LIST_PLUS" -a -z "$PM_INDEX_ONLY" ]; then
check_state
return 0
elif [ -n "$LIST" ]; then
return 0
else
check_force_multi $iport $originflavor || do_update=upd_fm_eq
unset port_ver
fi
else
case `$PKG_CMD version -t $iport $port_ver` in
\<) do_update=upd_lt ;;
=) ;; # Can be reached if same version with different options
\>) if [ -n "$PM_VERBOSE" ]; then
echo " ===>>> Port version $port_ver does not"
echo " ===>>> seem newer than installed $iport"
fi ;;
*) fail "pkg version -t $iport $port_ver gave an unexpected result"
esac
[ -z "$do_update" ] && {
check_force_multi $iport $originflavor || do_update=upd_fm_ne; }
fi
fi
if [ -z "$do_update" ]; then
[ -z "$LIST_PLUS" ] && CUR_DEPS="${CUR_DEPS}${iport}:${originflavor}:"
return 0
fi
if [ -n "$LIST_PLUS" ]; then
if [ -z "$moved_npd" ]; then
echo " ===>>> New version available: $port_ver"
if pm_islocked "$iport"; then
echo " ===>>> +IGNOREME file is present for $1 or the package is locked"
fi
pm_cd_pd $origin && check_state
num_updates=$(( $num_updates + 1 ))
else
unset moved_npd
fi
return 0
elif [ -n "$PM_UPDATE_IF_NEWER" ]; then
return 1
fi
# No need for check_exclude here because it is already
# run in the places that call check_for_updates().
check_interactive $iport $port_ver || return 0
update_port $iport $port_ver || return 1
return 0
}
init_packages () {
# Global: pbu
[ -n "$FETCH_ONLY" ] && return
init_packages_var
[ -n "$NO_BACKUP" ] && return
pbu=$PACKAGES/portmaster-backup
if ! pm_isdir "$pbu"; then
pm_sv Creating $pbu
pm_mkdir_s $pbu
fi
export pbu
}
pm_pkg_create () {
local pkgdir backup format_option
init_packages
[ -z "$BACKUP_FORMAT" -a -n "$PACKAGE_FORMAT" ] && export BACKUP_FORMAT=$PACKAGE_FORMAT
if [ "$1" = "$PACKAGES" ]; then
for pkgdir in All Latest ${portdir%/*}; do
pm_mkdir_s ${PACKAGES}/${pkgdir} ||
fail "Cannot mkdir -p ${PACKAGES}/${pkgdir}"
done
pkgdir=${PACKAGES}/All
format_option=${PACKAGE_FORMAT:+-f $PACKAGE_FORMAT}
echo "===>>> Creating a package for new version $2"
else
pkgdir=$1 ; echo ''
format_option=${BACKUP_FORMAT:+-f $BACKUP_FORMAT}
echo "===>>> Creating a backup package for old version $2"
backup=backup
fi
pm_cd $pkgdir || fail "Cannot cd into $pkgdir to create a package"
if $PM_SU_CMD $PKG_CMD create $format_option $2; then
if [ "$1" = "$pbu" ]; then
if [ -n "$BACKUP" ]; then
echo " ===>>> Package saved to $1" ; echo ''
else
local pkg ; pkg=`echo $2.*`
NB_DELETE="${NB_DELETE}${pkg} "
fi
elif [ "$1" = "$PACKAGES" ]; then
local pkg ; pkg=$2.pkg
if [ -z "$PM_INDEX_ONLY" ]; then
local pkg_latest_file
pm_cd_pd $portdir
pkg_latest_file=`pm_make -V PKGLATESTFILE`
$PM_SU_CMD install -lr $1/All/$pkg ${pkg_latest_file}
fi
cd ${1}/${portdir%/*}
$PM_SU_CMD ln -sf ../All/$pkg $pkg
echo " ===>>> Package saved to ${1}/All" ; echo ''
fi
else
local answer
while : ; do
echo -e "\n===>>> Package creation failed for ${2}!\n"
[ -n "$backup" -a -n "$PM_IGNORE_FAILED_BACKUP_PACKAGE" ] && return
echo "===>>> Ignore this error [i]"
echo "===>>> Abort update [a]"
echo "===>>> Retry [r]"
echo -e "\n===>>> How would you like to proceed? [i] \c"
read answer ; echo ''
case "$answer" in
''|[iI]) break ;;
[aA]) fail "Package creation failed for $2" ;;
[rR]) pm_pkg_create $1 $2 ; break ;;
*) echo " ===>>> $answer is not a valid response" ;;
esac
done
unset answer
fi
}
find_dl_distfiles () {
# Global: dist_list dist_list_files
# We need to define these for use in the deletion/update process.
if [ -s "${pdb}/${upg_port}/distfiles" ]; then
dist_list="${pdb}/${upg_port}/distfiles"
else
local d=$(dir_part $1)
# Old method, for now
if pm_cd $pd/$d; then
dist_list=`pm_make_b -V OPTIONS_FILE`
dist_list="${dist_list%options}distfiles"
else
# The port might have moved, etc.; so take a stab at it,
# but do not take a chance with a possibly wrong answer
local dd=$(echo "$d" | tr "/" "_")
dist_list="$port_dbdir/${dd##*/}/distfiles"
fi
[ -s "$dist_list" ] || { unset dist_list ; return 0; }
fi
[ -n "$DONT_SCRUB_DISTFILES" ] && return 0
local line
while read line; do
case "$line" in
DISTFILE*) line=${line#DISTFILE:} ; line=${line%%:*}
dist_list_files="${dist_list_files}${line#*/} " ;;
esac
done < $dist_list
# Clean up after the old method
case "$dist_list" in
${port_dbdir}*)
pm_sv Deleting $dist_list
pm_unlink_s $dist_list
local dir=`find ${dist_list%/distfiles} -type d -empty 2>/dev/null`
if pm_isdir "$dir"; then
pm_sv Deleting empty $dir directory
pm_rmdir_s $dir
fi
unset dist_list ;;
esac
}
check_di_files () {
# Global: distfiles_checked
if [ -s "$DI_FILES" ]; then
if grep -ql ^${port_subdir}${1} $DI_FILES; then
distfiles_checked="${distfiles_checked}${1}:"
pm_v "===>>> Keeping distfile, valid for another port: $1"
return 0
fi
fi
return 1
}
find_and_delete_distfiles () {
# Global: distfiles_checked
local file answer
for file in ${1}*; do
# This generally means the pattern did not match
case "$file" in
*\*) [ "$1" = "${1%[_-]*}" ] && return 0
# This will happen for files like foo-bar_baz-1.23
find_and_delete_distfiles ${1%[_-]*} ;;
esac
case "$distfiles_checked" in *:${file}:*) continue ;; esac
[ -f "$file" ] || continue
case "$distfiles" in
*" ${file} "*)
distfiles_checked="${distfiles_checked}${file}:"
pm_v "===>>> Keeping current distfile: ${port_subdir}${file}"
continue ;; # Do not delete current version
*) check_di_files $file && continue
if [ -n "$ALWAYS_SCRUB_DISTFILES" -o -n "$delete_all" ]; then
echo "===>>> Deleting stale distfile: ${port_subdir}${file}"
pm_unlink $file
continue
fi
get_answer_g n y "\n===>>> Delete ${port_subdir}${file}? y/n"
case "$?" in
1) pm_unlink $file ;;
0) distfiles_checked="${distfiles_checked}${file}:" ;;
esac ;;
esac
done
}
make_distfiles () {
# Global: distfiles
# Even if there are no distfiles there will be a space returned
distfiles=`pm_make -V ALLFILES` ; distfiles=${distfiles%% }
if [ -n "$distfiles" ]; then
distfiles=" $distfiles "
else
unset distfiles
fi
}
make_port_subdir () {
# Global: port_subdir full_port_subdir
port_subdir=`pm_make -V DIST_SUBDIR`
port_subdir="${port_subdir:+${port_subdir}/}"
full_port_subdir="${DISTDIR}${port_subdir}"
}
set_distfiles_and_subdir () {
[ -z "$dist_list_files" ] && find_dl_distfiles $1
if pm_isdir_pd "$1"; then
pm_cd_pd $1
else
return 1
fi
[ -n "$distfiles" ] || make_distfiles
# Ports may have no distfiles
[ -z "$dist_list_files" -a -z "$distfiles" ] && return 2
[ -n "$full_port_subdir" ] || make_port_subdir
if pm_isdir "$full_port_subdir"; then
pm_cd $full_port_subdir || fail "cd to $full_port_subdir failed!"
else
echo ''
echo "===>>> $full_port_subdir does not exist, therefore we"
echo ' will assume that all relevant distfiles are gone.'
echo ''
echo " Try $progname [-y] --clean-distfiles for a full cleanup"
echo ''
return 3
fi
return 0
}
delete_stale_distfiles () {
[ -n "$DISTDIR" ] || return # DISTDIR not set because of PM_PACKAGES
# Global: distfiles_checked
local file answer
set_distfiles_and_subdir $1 || return 0
distfiles_checked=':'
# If these two match, it means that the distfiles in the
# file are the current set, so do not delete them.
if [ ! " $dist_list_files" = "$distfiles" ]; then
for file in $dist_list_files; do
[ -f "$file" ] || continue
case "$distfiles" in
*" ${file} "*)
distfiles_checked="${distfiles_checked}${file}:"
pm_v "===>>> Keeping current distfile: ${port_subdir}${file}"
continue ;; # Do not delete current version
esac
check_di_files $file && continue
if [ -n "$ALWAYS_SCRUB_DISTFILES" -o -n "$delete_all" ]; then
echo "===>>> Deleting stale distfile: ${port_subdir}${file}"
pm_unlink $file
continue
fi
get_answer_g n y "\n===>>> Delete ${port_subdir}${file}? y/n"
case "$?" in
1) pm_unlink $file ;;
0) distfiles_checked="${distfiles_checked}${file}:" ;;
esac
done
fi
# Eventually we will hide this behind an "aggressive distfile purge"
# flag, but until the DISTFILE stuff is well populated
# keep doing it both ways.
for file in $distfiles $dist_list_files; do
find_and_delete_distfiles ${file%[-]*}-[0-9]
done
pm_v "===>>> Distfile cleaning complete\n"
}
delete_all_distfiles () {
[ -n "$DISTDIR" ] || return # DISTDIR not set because of PM_PACKAGES
# Global: delete_all DISTDIR
local origin rc delete_current
# In case we are called more than once
unset delete_all dist_list dist_list_files
origin=$1
set_distfiles_and_subdir $origin ; rc=$?
case "$rc" in
1) echo ''
echo "===>>> No $pd/$origin exists to find the distfile list"
echo " Try $progname [-y] --clean-distfiles for a full cleanup"
echo ''
if [ -n "$dist_list_files" ]; then
local answer f
answer=y
if [ -z "$ALWAYS_SCRUB_DISTFILES" ]; then
echo "===>>> However, the list of files from $dist_list"
get_answer_g n y " should be current. Delete the files on this list? y/n"
case "$?" in 0) answer=n ;; esac
fi
case "$answer" in
[yY]) for f in $dist_list_files; do
if [ -f "$f" ]; then
echo " Deleting ${port_subdir}${f}"
/bin/unlink $f
fi
done ;;
esac
fi
return 0 ;;
2) echo "===>>> This port has no distfiles" ; return 0 ;;
3) return 0 ;; # port_subdir does not exist
esac
if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then
echo "===>>> Deleting all distfiles for $origin"
delete_all=delete_all
else
echo "===>>> Delete old and new distfiles for $origin"
get_answer_g n y " without prompting? y/n"
case "$?" in
1) delete_all=delete_all2 ;;
0) get_answer_g n y "===>>> Delete the current distfiles? y/n"
case "$?" in 1) delete_current=delete_current ;; esac ;;
esac
fi
if [ -n "$delete_all" -o -n "$delete_current" ]; then
# Doing this now means less work in delete_stale()
[ -n "$distfiles" ] && eval rm -f $distfiles
fi
delete_stale_distfiles $origin
delete_empty_dist_subdirs
}
#=============== End functions for getopts features and main ===============
#=============== Begin code relevant only to getopts features ===============
if [ -n "$LIST" -o -n "$LIST_PLUS" ]; then
ports_by_category ; pm_v
num_updates=0
echo "===>>> Root ports (No dependencies, not depended on)"
for iport in $roots; do
echo "===>>> $iport"
[ -n "$LIST_PLUS" ] && check_for_updates list $iport
done
echo "===>>> $num_roots root ports"
echo ''
echo "===>>> Trunk ports (No dependencies, are depended on)"
for iport in $trunks; do
echo "===>>> $iport"
[ -n "$LIST_PLUS" ] && check_for_updates list $iport
done
echo "===>>> $num_trunks trunk ports"
echo ''
echo "===>>> Branch ports (Have dependencies, are depended on)"
for iport in $branches; do
echo "===>>> $iport"
[ -n "$LIST_PLUS" ] && check_for_updates list $iport
done
echo "===>>> $num_branches branch ports"
echo ''
echo "===>>> Leaf ports (Have dependencies, not depended on)"
for iport in $leaves; do
echo "===>>> $iport"
[ -n "$LIST_PLUS" ] && check_for_updates list $iport
done
echo "===>>> $num_leaves leaf ports"
echo ''
echo "===>>> $num_ports total installed ports"
if [ "$num_updates" -gt 1 ]; then
echo " ===>>> $num_updates have new versions available"
elif [ "$num_updates" -eq 1 ]; then
echo " ===>>> 1 has a new version available"
elif [ -n "$LIST_PLUS" ]; then
echo " ===>>> There are no new versions available"
fi
exit 0
fi
if [ -n "$EXPUNGE" ]; then
if ! pm_isdir "$pdb/$EXPUNGE" || ! $PKG_CMD info -e $EXPUNGE; then
find_glob_dirs $EXPUNGE
case $? in
1) fail "No such port: $EXPUNGE" ;;
2) echo "===>>> $EXPUNGE matched multiple ports"
fail "The -e option works with only one port at a time" ;;
0) EXPUNGE=${glob_dirs#$pdb/}
unset glob_dirs ;;
esac
fi
origin=`origin_from_pdb $EXPUNGE`
deplist=`$PKG_CMD query "%rn-%rv" $origin`
if [ -n "$deplist" ]; then
echo "===>>> Warning: Ports with dependencies on ${EXPUNGE}:"
echo "$deplist" | sed 's/^/ /'
get_answer_yn n "\n\t===>>> Delete this dependency data"
case "$?" in
0) exit 1 #TODO
for f in $deplist; do
update_contents delete $f $origin
done ;;
*) exit 1 ;;
esac
fi
[ -n "$BACKUP" ] && { init_packages ; pm_pkg_create $pbu $EXPUNGE; }
[ -z "$DONT_SCRUB_DISTFILES" ] && delete_all_distfiles $origin
echo "===>>> Running pkg delete -f $EXPUNGE"
pm_pkg_delete_s $EXPUNGE || fail "pkg delete failed"
echo '' ; echo "===>>> Running $progname -s $ARGS"
exec "$program" -s $ARGS
exit 0 # Should not be reached
fi
if [ -n "$CLEAN_STALE" ]; then
[ -z "$no_del_list" ] && export no_del_list=':'
stale_ports=`$PKG_CMD query -ae '%a = 1' '%?r %n-%v' | awk '/^0 / { print \$2 }'`
for file in $stale_ports; do
iport="${file%/+REQUIRED_BY}" ; iport=${iport#$pdb/}
case "$no_del_list" in *:${iport}:*) continue ;; esac
origin=`origin_from_pdb $iport`
deplist=""
if [ -n "$deplist" ]; then
echo ''
echo "===>>> Warning: Unrecorded dependencies on ${iport}:"
for dep in $deplist; do
dep=${dep%/+CON*} ; echo " ${dep##*/}"
done
echo ''
echo "===>>> Try $progname --check-depends"
echo ''
continue
fi
echo '' ; $PKG_CMD info -f $iport
get_answer_yn n "\t===>>> ${iport} is no longer depended on, delete"
case "$?" in
0) [ -n "$BACKUP" ] && { init_packages ; pm_pkg_create $pbu $iport; }
[ -z "$DONT_SCRUB_DISTFILES" ] && delete_all_distfiles $origin
echo "===>>> Running pkg delete -f $iport"
pm_pkg_delete_s $iport || fail "pkg delete failed"
exec "$program" -s $ARGS ;;
*) no_del_list="${no_del_list}${iport}:" ;;
esac
done
exit 0
fi
#=============== End code relevant only to getopts features ===============
[ -z "$DISTDIR" -a "$PM_PACKAGES" != only -a -z "$DONT_SCRUB_DISTFILES" ] &&
fail 'The value of DISTDIR cannot be empty'
#=============== Begin functions for main ===============
already_done () {
echo "===>>> The update for $1 is already done" ; echo ''
}
check_restart_and_udf () {
# RESTART will usually be empty, and we don't want
# to go out to the disk if we don't have to.
[ -z "$RESTART" ] && return 1
if [ ! -e "$pdb/${1}/PM_UPGRADE_DONE_FLAG" ] || ! $PKG_CMD info -e $1; then
return 1
else
already_done $1
fi
}
check_interactive () {
[ -n "$INTERACTIVE_UPDATE" ] || return 0
local update_to
[ -n "$2" ] && update_to=" to $2"
case "$INTERACTIVE_YES" in *:${1}:*) return 0 ;; esac
case "$INTERACTIVE_NO" in *:${1}:*) return 1 ;; esac
if pm_islocked $1; then
echo ''
echo "===>>> package is locked or +IGNOREME file is present for $1"
echo ''
get_answer_g n y "===>>> Update ${1}${update_to}? y/n"
case "$?" in
1) INTERACTIVE_YES="${INTERACTIVE_YES}${1}:" ;;
0) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:" ; return 1 ;;
esac
else
get_answer_g y n "===>>> Update ${1}${update_to}? y/n"
case "$?" in
0) INTERACTIVE_YES="${INTERACTIVE_YES}${1}:" ;;
1) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:" ; return 1 ;;
esac
fi
}
check_exclude () {
[ -n "$PM_EXCL" ] || return 0
local pat
for pat in $PM_EXCL; do
case "$1" in
*${pat}*)
if [ -n "$PM_VERBOSE" ]; then
echo "===>>> Skipping $1"
echo " because it matches the pattern: *${pat}*"
echo ''
fi
return 1 ;;
esac
done
return 0
}
check_fetch_only () {
[ -n "$FETCH_ONLY" ] || return 0
[ -z "$1" -a -n "$PM_PACKAGES" ] && return 0
local count nf fetches
echo ''
count=0
while nf=`ls ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-* 2>/dev/null | wc -l`; do
nf=${nf##* }
[ $nf -eq 0 ] && break
fetches=fetches ; [ $nf -eq 1 ] && fetches=fetch
count=$(( $count + 1 ))
if [ $count -eq 1 ]; then
echo "===>>> Waiting for $nf distfile $fetches to finish"
elif [ $count -eq 3 ]; then
count=0
fi
sleep 2
done
echo "===>>> ${1:-Distfile} fetching is complete"
FETCH_ONLY_DONE=fetch_only_done
safe_exit
}
term_printf () {
case "$1" in
'') [ -n "$PM_MULTI_PORTS" ] && echo -e "\n===>>> ${PM_PARENT_PORT}" ;;
*\>\>*) echo -e "\n===>>> ${PM_PARENT_PORT}${1}" ;;
esac
[ -n "$PM_NO_TERM_TITLE" ] && return
case "$TERM" in cons*) return ;; esac
printf "\033]0;$progname: ${PM_PARENT_PORT}${1}\007"
}
update_pm_nu () {
case "$PM_NEEDS_UPDATE" in *\ $1\ *) return ;; esac
PM_NEEDS_UPDATE="${PM_NEEDS_UPDATE}${1} "
}
update_build_l () {
local originflavor origin flavor iport make_target
originflavor=$1 ; update_pm_nu $originflavor
origin=$(dir_part "$originflavor")
flavor=$(flavor_part "$originflavor")
iport="$2"
make_target=$3
[ -n "$PM_NO_CONFIRM" ] && return
if [ -z "$iport" ]; then
case "$build_l" in *\ $origin\\*) return ;; esac
case $make_target in
install)
build_l="${build_l}\tInstall $originflavor\n" ;;
*)
build_l="${build_l}\tExecute make $make_target for $originflavor\n" ;;
esac
return
fi
case "$build_l" in *\ $iport\ *|*\ $iport\\*) return ;; esac
find_new_port "$originflavor" # sets global variable new_port
case `$PKG_CMD version -t $iport $new_port 2>/dev/null` in
\<) build_l="${build_l}\tUpgrade $iport to $new_port\n" ;;
=) build_l="${build_l}\tRe-install $iport\n" ;;
\>) build_l="${build_l}\tDowngrade $iport to $new_port\n" ;;
*) build_l="${build_l}\tUpgrade $iport\n" ;;
esac
}
update_port () {
local make_target deps
make_target=$(target_part "$1")
if [ -n "$2" ]; then
echo "===>>> Launching child to update $1 to $2"
else
if [ -z "$FETCH_ONLY" ]; then
case "$1" in
*/*) echo "===>>> Launching child to install ${1#$pd/}" ;;
*) echo "===>>> Launching child to reinstall $1" ;;
esac
else
if [ "$PM_PACKAGES" != 'only' ]; then
echo "===>>> Launching child to check distfiles for $1"
else
echo "===>>> Launching child to check package files for $1"
fi
fi
fi
dep_of_deps=$(( $dep_of_deps + 1 ))
[ -n "$PM_FIRST_PASS" ] && [ ! \( -n "$PM_FORCE" -a -n "$PM_ALL_FETCH" \) ] &&
num_of_deps=$(( $num_of_deps + 1 ))
deps="(${dep_of_deps}/${num_of_deps})"
term_printf " ${PM_DEPTH#* }>> ${1#$pd/} ${deps}"
[ -n "$doing_dep_check" -o \( -n "$UPDATE_ALL" -a -n "$PM_FIRST_PASS" \) ] &&
unset NO_DEP_UPDATES
if [ -z "$NO_ACTION" -o -n "$PM_FIRST_PASS" ]; then
("$program" $ARGS $*) || update_failed=update_failed
. $IPC_SAVE && > $IPC_SAVE
[ -n "$update_failed" ] && fail "Update for $1 failed"
else
pm_v "===>>> Build canceled due to -n flag"
fi
if [ -n "$UPDATE_ALL" ]; then
# Fix terminal titlebar in case of a long delay between ports to update
term_printf " (${num_of_deps})"
echo -e "===>>> Returning to update check of installed ports\n"
elif [ -n "$PM_URB" ]; then
return 0
elif [ -n "$PM_FIRST_PASS" -a -z "$PM_PACKAGES" ]; then
echo "===>>> Continuing initial dependency check for $portdir"
else
term_printf " ${PM_DEPTH#* }${deps}"
echo -e "\n===>>> Returning to dependency check for $portdir"
fi
return 0
} # update_port()
uniquify_list () {
local ul_item ul_temp_list
for ul_item in "$@"; do
case "$ul_temp_list" in
*" $ul_item "*) ;;
*) ul_temp_list=" $ul_temp_list $ul_item " ;;
esac
done
echo $ul_temp_list
}
clean_build_only_list () {
local dep temp_bodlg
for dep in $build_only_dl_g; do
case "$run_dl_g" in
*" ${dep} "*) ;;
*) temp_bodlg="$temp_bodlg $dep" ;;
esac
done
build_only_dl_g=" `uniquify_list $temp_bodlg` "
}
make_dep_list () {
local dep_type var_opt
for dep_type in $*; do
case $dep_type in
all-depends-list|build-depends-list)
var_opt="$var_opt -V PKG_DEPENDS -V EXTRACT_DEPENDS \
-V PATCH_DEPENDS -V FETCH_DEPENDS -V BUILD_DEPENDS -V LIB_DEPENDS"
[ "$dep_type" = all-depends-list ] && var_opt="$var_opt -V RUN_DEPENDS" ;;
run-depends-list)
var_opt="$var_opt -V RUN_DEPENDS -V LIB_DEPENDS" ;;
test-depends-list)
var_opt="$var_opt -V TEST_DEPENDS" ;;
*)
fail "make_dep_list: Unsupported option '$dep_type'"
esac
done
[ -n "$var_opt" ] && pm_make $var_opt | tr ' ' '\n' | cut -d: -f2-3 | sort -u
}
gen_dep_list () {
local list
if [ -z "$PM_INDEX_ONLY" ]; then
pm_cd_pd $portdir
export_flavor $(flavor_part $portdir)
make_dep_list $*
else
local temp_list l
case "$*" in
'build-depends-list run-depends-list'|all-depends-list)
temp_list="`parse_index $portdir b-deps` `parse_index $portdir r-deps`" ;;
build-depends-list) temp_list=`parse_index $portdir b-deps` ;;
run-depends-list) temp_list=`parse_index $portdir r-deps` ;;
esac
temp_list=`uniquify_list $temp_list`
for l in $temp_list ; do
list="$list `grep -m1 ^${l}\| $PM_INDEX | cut -f 2 -d \|`"
done
list=" $list "
fi
echo "$list"
}
#
#
# changes PWD!!!
dependency_check () {
# Global: doing_dep_check
# Global: run_dl_g build_only_dl_g
local d_port_list
# Print a message here because sometimes list generation takes
# a long time to return.
if [ -z "$PM_INDEX_ONLY" ]; then
echo "===>>> Gathering dependency list for $portdir from ports"
else
echo "===>>> Gathering dependency list for $portdir from ${PM_INDEX##*/}"
fi
d_port_list=`gen_dep_list $1`
if [ -z "$d_port_list" ]; then
echo -e "===>>> No dependencies for $portdir\n"
[ -n "$SHOW_WORK" ] && safe_exit
return 0
else
if [ -n "$SHOW_WORK" ]; then
echo ''
else
pm_v "===>>> Starting dependency check"
fi
fi
if [ "$PM_BUILD_ONLY_LIST" = pmp_doing_build_deps ]; then
local rundeps dep varname run_dl build_only_dl
rundeps=`gen_dep_list run-depends-list`
for dep in $d_port_list; do
# strip optional make target
local depdir=${dep%:*}
# If the port is already installed, do not mark
# it as a build-only dependency, or it will be
# installed by package and/or removed
$PKG_CMD info -e ${depdir#$pd/} &&
run_dl="$run_dl $depdir" &&
continue
case "$rundeps" in
*" ${dep} "*|*${dep}*)
varname=`echo ${dep#$pd/} | sed 's#[-+/\.@:]#_#g'`
rundep_list="$rundep_list $varname"
eval $varname=\"$portdir \$$varname\"
eval ${varname}_p=$dep
eval export $varname ${varname}_p
run_dl="$run_dl $dep" ;;
*) build_only_dl="$build_only_dl $dep" ;;
esac
done
if [ -z "$PM_THOROUGH" ]; then
d_port_list="$build_only_dl $run_dl"
else
build_only_dl=`gen_dep_list build-depends-list`
fi
run_dl_g="$run_dl_g $run_dl "
for dep in $build_only_dl; do
case "$build_only_dl_g" in
*" ${dep} "*) ;;
*) build_only_dl_g="$build_only_dl_g $dep " ;;
esac
done
clean_build_only_list
fi
local d_port origin iport
# Do not export, for THIS parent process only
[ -n "$PM_FIRST_PASS" ] && doing_dep_check=doing_dep_check
for d_port_target in $d_port_list; do
# strip optional make target
local d_port=${d_port_target%:*}
local make_target=$(target_part "$d_port_target")
origin="${d_port#$pd/}"
if [ -n "$SHOW_WORK" ]; then
iport=`iport_from_origin $origin`
case "$iport" in
'') echo "===>>> NOT INSTALLED $origin" ;;
*) echo "===>>> Installed $origin" ;;
esac
continue
fi
pm_v "===>>> Checking dependency: $origin"
# Do this first to catch out of date dependencies
[ -n "$PM_FIRST_PASS" ] &&
case "$PM_NEEDS_UPDATE" in *\ $origin\ *) continue ;; esac
[ -z "$PM_URB_UP" ] &&
case "$CUR_DEPS" in *:${origin}:*) continue ;; esac
if [ -z "$PM_INDEX_ONLY" -a "$make_target" = install ]; then
local conflicts glob confl_p dir flavor
dir=$(dir_part $d_port)
flavor=$(flavor_part $d_port)
pm_cd "$pd/$dir" || fail "Cannot cd to $dir"
conflicts=`FLAVOR=$flavor pm_make_b -V CONFLICTS -V CONFLICTS_BUILD -V CONFLICTS_INSTALL`
for glob in $conflicts; do
confl_p=`$PKG_CMD query -g "%n-%v" $glob 2>/dev/null`
if [ -n "$confl_p" ]; then
confl_p=${confl_p%% *}
d_port="$pd/`origin_from_pdb $confl_p`"
if [ "${d_port#$pd/}" = "$portdir" ]; then
echo -e "\n===>>> $origin seems to depend on $portdir"
echo ' which looks like a dependency loop'
fail "Try pkg updating $portdir"
fi
echo ''
echo "===>>> The dependency for ${origin}"
echo " seems to be handled by $confl_p"
echo ''
fi
done
fi
# In case d_port changed above
origin="${d_port#$pd/}" ; iport=`iport_from_origin ${origin}`
check_exclude ${iport:-$origin} || continue
if [ -n "$PM_FORCE" -a -n "$iport" ]; then
if ! check_restart_and_udf $iport; then
echo "===>>> Forcing update for $pd/$origin"
update_port $iport
else
CUR_DEPS="${CUR_DEPS}${iport}:${originflavor}:"
fi
continue
elif [ -n "$PM_URB_UP" -a -n "$iport" ]; then
case "$PM_URB_DONE" in
*:${iport}:*) already_done $iport ; continue ;; esac
case " $PM_URB_LIST " in *" $iport "*)
check_interactive $iport || continue
if ! check_restart_and_udf $iport; then
update_port $iport
else
CUR_DEPS="${CUR_DEPS}${iport}:${originflavor}:"
PM_URB_DONE="${PM_URB_DONE}${upg_port}:"
fi
continue ;;
esac
fi
if [ -n "$iport" ]; then
# No check_interactive here because we want to tell
# the user whether or not there is a new version first
check_for_updates $iport $origin || fail 'Update failed'
else
check_interactive $origin || continue
if [ "$make_target" != "install" ]; then
[ -z "$PM_FIRST_PASS" ] && post_clean_l="$post_clean_l $origin"
origin="$origin:$make_target"
fi
update_port "$origin"
fi
done
[ -n "$PM_FIRST_PASS" ] && unset doing_dep_check
if [ -n "$SHOW_WORK" ]; then
safe_exit
elif [ -n "$PM_FIRST_PASS" -a -z "$PM_PACKAGES" ]; then
echo -e "===>>> Initial dependency check complete for $portdir\n"
else
echo "===>>> Dependency check complete for $portdir"
local deps ; deps="(${dep_of_deps}/${num_of_deps})"
case "$PM_DEPTH" in
*\>\>*) term_printf " ${PM_DEPTH#* }${deps}" ; echo '' ;;
*) if [ "$PM_PARENT_PORT" = All ]; then
term_printf " >> ${upg_port:-$portdir}${deps}"
elif [ -n "$PM_URB_UP" ]; then
term_printf " >> ${upg_port:-$portdir} ${deps}"
echo ''
else
term_printf ; echo '' # multiport
fi ;;
esac
fi
} # dependency_check()
post_first_pass () {
local action
if [ ${num_of_deps:-0} -gt 0 ]; then
term_printf " >> (${num_of_deps})"
if [ -z "$PM_NO_CONFIRM" ]; then
local answer
echo ''
echo "===>>> The following actions will be taken if you choose to proceed:"
echo -e "$build_l"
get_answer_g y n "===>>> Proceed? y/n"
case "$?" in
1) echo ''
echo "===>>> If you would like to upgrade or install some, but not"
echo " all of the above try adding '-i' to the command line."
safe_exit 1 ;;
esac
unset build_l
fi
else
term_printf
fi
# Only when -a or multi and user said no to update +IGNOREME(s)
[ "$PM_NEEDS_UPDATE" = ' ' ] && return
action=build
if [ -n "$FETCH_ONLY" ]; then
action='fetch'
elif [ "$PM_PACKAGES" = only ]; then
action=install
elif [ -n "$PM_PACKAGES" ]; then
action='build and/or install'
fi
echo ''; echo "===>>> Starting $action for $* <<<==="; echo ''
unset PM_FIRST_PASS PM_NO_CONFIRM
dep_of_deps=0
if [ -n "$PM_BUILD_ONLY_LIST" ]; then
local var real_rundep deplist dep temp_bodlg
for var in $rundep_list ; do
real_rundep=no
eval deplist=\$$var
for dep in $deplist ; do
case "$build_only_dl_g" in
*" $pd/$dep "*) ;;
*) real_rundep=yes ; break ;;
esac
done
[ "$real_rundep" = 'no' ] &&
eval build_only_dl_g=\"${build_only_dl_g}\$${var}_p \"
eval unset $var ${var}_p
done
for dep in $build_only_dl_g; do
[ "`$PKG_CMD query "%?r" ${dep#$pd/}`" = "1" ] && continue
[ -n "$PM_DEL_BUILD_ONLY" ] &&
iport_from_origin ${dep#$pd/} >/dev/null && continue
temp_bodlg="$temp_bodlg $dep"
done
build_only_dl_g=" `uniquify_list $temp_bodlg` "
unset run_dl_g rundep_list
PM_BUILD_ONLY_LIST=pm_bol
fi
}
init_term_printf () {
PM_PARENT_PORT=$1
[ -z "$num_of_deps" ] && num_of_deps=0
[ -z "$dep_of_deps" ] && dep_of_deps=0
export PM_PARENT_PORT num_of_deps dep_of_deps
term_printf
}
if [ -n "$PM_URB" ]; then
[ -n "$RESTART" ] && PM_UPDATE_IF_NEWER=pm_update_if_newer_urb
urb_update () {
# Global: PM_URB_UP
local verb origin req_by req_by_o
verb=Checking ; [ -n "$1" ] && verb=Updating
export PM_URB_UP=pm_urb_up
init_term_printf "$verb ports that depend on $PM_URB_IPORTS" ; echo ''
PM_PARENT_PORT="$verb dependent ports"
for origin in $PM_URB_ORIGINS; do
while read req_by req_by_o; do
case " $PM_URB_IPORTS" in *" $req_by "*) continue ;; esac
case " $PM_URB_ORIGINS" in *" $req_by_o "*) continue ;; esac
PM_URB_LIST="${PM_URB_LIST} ${req_by}"
done <<-EOF
$($PKG_CMD query "%rn-%rv %ro" ${origin})
EOF
done
if [ -n "$PM_URB_LIST" ]; then
PM_URB_LIST="`uniquify_list $PM_URB_LIST`"
export PM_URB_LIST
else
echo "===>>> No ports depend on $PM_URB_IPORTS" ; echo ''
fi
for req_by in $PM_URB_LIST; do
# Probably not needed, but JIC
$PKG_CMD info -e $req_by || continue
pm_v "===>>> $req_by depends on $PM_URB_IPORTS"
case "$PM_URB_DONE" in
*:${req_by}:*) already_done $req_by ; continue ;; esac
check_exclude $req_by || continue
check_interactive $req_by || continue
# Shortcut, since check_for will force it
if [ -z "$RESTART" -a -z "$PM_FORCE" ]; then
update_port $req_by
else
check_for_updates $req_by || fail 'Update failed'
fi
echo "===>>> Returning to list of ports depending on $PM_URB_IPORTS"
done
echo ''
echo "===>>> $verb done for ports that depend on $PM_URB_IPORTS"
echo ''
unset PM_URB_UP PM_URB_LIST PM_URB_DONE
}
fi
multiport () {
# Global
PM_MULTI_PORTS=':' ; export PM_MULTI_PORTS
local port worklist_temp iport worklist portlist numports origin num
# Expand globs and check that the directories exist
for port in "$@"; do
port=${port#$pdb/}
case "$port" in
*/*) port=${port#$pd/}
if [ -n "$PM_INDEX_ONLY" ] || pm_isdir_pd "${port}"; then
worklist_temp="$worklist_temp $port"
else
fail "$pd/${port} does not exist"
fi ;;
*) if pm_isdir "$pdb/$port" && $PKG_CMD info -e $port; then
worklist_temp="$worklist_temp $port"
else
find_glob_dirs $port
case $? in
1) fail "$port is not installed" ;;
*) local dir
for dir in $glob_dirs; do
worklist_temp="$worklist_temp ${dir#$pdb/}"
done ;;
esac
unset glob_dirs
fi ;;
esac
done
numports=0
for port in $worklist_temp; do
check_exclude $port || continue
check_interactive $port || continue
if [ -n "$PM_UPDATE_IF_NEWER" ]; then
case "$port" in
*/*) iport=`iport_from_origin $port` ;;
*) iport=$port ;;
esac
if [ -n "$iport" ] && check_for_updates multi $iport; then
if [ -n "$PM_URB" -a -n "$RESTART" ]; then
echo ''
echo "===>>> $iport is up to date, skipping rebuild due to -R flag"
udl_prime="${udl_prime}${iport}:"
elif [ -n "$PM_VERBOSE" ]; then
echo ''
echo "===>>> $port is up to date, skipping"
fi
continue
fi
fi
numports=$(( $numports + 1 ))
worklist="$worklist $port"
portlist="${portlist}\t${port}\n"
PM_MULTI_PORTS="${PM_MULTI_PORTS}${port}:"
done
unset PM_UPDATE_IF_NEWER
if [ -z "$worklist" ]; then
if [ -z "$PM_URB" ]; then
echo ''
echo "===>>> All listed ports are up to date, exiting" ; echo ''
safe_exit
fi
else
echo ''
echo "===>>> Working on:"
echo -e $portlist
fi
unset portlist
[ -n "$DI_FILES" ] && (read_distinfos)&
# First Pass
if [ -n "$PM_BUILD_ONLY_LIST" ]; then
PM_BUILD_ONLY_LIST=pmp_doing_build_deps
for port in $worklist; do
case "$port" in
*/*) run_dl_g="$run_dl_g ${pd}/${port} " ;;
*) run_dl_g="$run_dl_g ${pd}/`origin_from_pdb $port` " ;;
esac
done
fi
[ -n "$PM_URB" ] && export PM_URB
num=0
for port in $worklist; do
case "$port" in
*/*) origin=$port ;;
*) origin=`origin_from_pdb $port` ;;
esac
case "$PM_NEEDS_UPDATE" in
*\ $origin\ *) numports=$(( $numports - 1 ))
pm_v "===>>> $port already encountered as a dependency\n"
continue ;;
esac
num=$(( $num + 1 ))
init_term_printf "$port ${num}/${numports}"
($program $ARGS $port) || update_failed=update_failed
. $IPC_SAVE && : > $IPC_SAVE
[ -n "$update_failed" ] && fail "Update for $port failed"
case "$PM_NEEDS_UPDATE" in
*\ $origin\ *) continue ;; # Handle +IGNOREME in child
*) numports=$(( $numports - 1 )) ;;
esac
done
if [ -n "$PM_URB" ]; then
unset PM_URB ; PM_URB=pm_urb_post_first_pass
PM_URB_DONE=":${udl_prime}" ; export PM_URB_DONE
urb_update
fi
PM_PARENT_PORT="Total ports: $numports"
check_fetch_only
post_first_pass multiple ports
[ -n "$PM_URB" ] && export PM_URB
export PM_BUILDING=pmbuildingmultiport
num=0
for port in $worklist; do
case "$port" in
*/*) origin=$port ;;
*) # If an installed version does not exist at this
# point it probably got updated as a dependency
if ! $PKG_CMD info -e $port; then
numports=$(( $numports - 1 ))
continue
fi
origin=$(origin_from_pdb $port)
unset PM_OLD_ORIGIN
if [ -n "$origin" ] && ! pm_isdir_pd "$origin"; then
export PM_OLD_ORIGIN=$origin
find_moved_port $origin $port nonfatal && origin=$moved_npd
fi ;;
esac
case "$PM_NEEDS_UPDATE" in
*\ $origin\ *) ;; # Ok to proceed
*) continue ;; # Already updated as a dependency
esac
num=$(( $num + 1 ))
init_term_printf "$port ${num}/${numports}"
("$program" $ARGS $port) || update_failed=update_failed
. $IPC_SAVE && : > $IPC_SAVE
[ -n "$update_failed" ] && fail "Update for $port failed"
done
if [ -n "$PM_URB" ]; then
unset PM_URB ; PM_URB=pm_urb_post_build
PM_URB_DONE=":${udl_prime}" ; export PM_URB_DONE
urb_update urb_update_after_build
fi
if [ "$PM_PACKAGES" != 'only' ]; then
check_fetch_only
else
check_fetch_only Package
fi
safe_exit
}
make_config () {
local config_type
config_type=config-conditional
[ -n "$PM_FORCE_CONFIG" ] && config_type=config
pm_sv Running \'make $config_type\'
pm_cd_pd $portdir
pm_make_s $config_type
}
#=============== End functions for main ===============
# INIT Parent
if [ "$$" -eq "$PM_PARENT_PID" -a -z "$SHOW_WORK" ]; then
[ -f Makefile ] || pm_cd
CUR_DEPS=':' ; DISPLAY_LIST='' ; INSTALLED_LIST=''
PM_DEPTH='' ; pm_mktemp IPC_SAVE ; IPC_SAVE=$pm_mktemp_file
PM_FIRST_PASS=pm_first_pass ; PM_NEEDS_UPDATE=' ' # Used with -F for multiport and -a
export CUR_DEPS DISPLAY_LIST INSTALLED_LIST PM_DEPTH IPC_SAVE PM_FIRST_PASS PM_NEEDS_UPDATE
if [ -n "$LOCALBASE" ]; then
LOCALBASE_COMPAT="$LOCALBASE/lib/compat/pkg"
elif [ -z "$FETCH_ONLY" ]; then
PLB=`pm_make_b -f/usr/share/mk/bsd.port.mk -V LOCALBASE 2>/dev/null`
if [ -n "$PLB" ]; then
LOCALBASE_COMPAT="$PLB/lib/compat/pkg"
else
[ -n "$PM_INDEX" ] && PLB=`head -1 $PM_INDEX | cut -f 3 -d\| 2>/dev/null`
if [ -n "$PLB" ] && pm_idsdir "$PLB"; then
LOCALBASE_COMPAT="${PLB}/lib/compat/pkg"
else
echo "===>>> Unable to determine the value of LOCALBASE"
echo " Try setting it in the environment, or /etc/make.conf"
fail 'The value of LOCALBASE cannot be empty'
fi
fi
unset PLB
fi
export LOCALBASE_COMPAT
if [ -n "$INTERACTIVE_UPDATE" ]; then
INTERACTIVE_YES=':' ; INTERACTIVE_NO=':'
export INTERACTIVE_YES INTERACTIVE_NO
fi
if [ -n "$PM_URB" -o -n "$PM_FORCE" ]; then
if [ -z "$RESTART" ]; then
files=`find $pdb -type f -name PM_UPGRADE_DONE_FLAG`
if [ -n "$files" ]; then
echo "===>>> There are 'install complete' flags from a previous"
get_answer_g n y " -[rf] run of $progname, delete them? y/n"
case "$?" in
1) pm_sv Deleting \'install complete\' flags
pm_find_s $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete ;;
0) get_answer_g n y "===>>> Enable the -R option? y/n"
case "$?" in 1) RESTART=Ropt ; ARGS="-R $ARGS" ;; esac ;;
esac
fi
fi
fi
if [ -z "$FETCH_ONLY" ]; then
NO_DEP_UPDATES=no_dep_updates ; build_l=''
export NO_DEP_UPDATES build_l
pm_cd_pd Mk && PM_WRKDIRPREFIX=`pm_make_b -V WRKDIRPREFIX` && pm_cd "$OLDPWD"
fi
if [ -n "$PM_BUILD_ONLY_LIST" ]; then
run_dl_g='' ; build_only_dl_g='' ; rundep_list=''
export run_dl_g build_only_dl_g rundep_list
fi
if [ -n "$PM_DEL_BUILD_ONLY" ]; then
build_deps_il='' ; export build_deps_il
fi
[ -z "$NO_BACKUP" ] && init_packages
[ -z "$NO_BACKUP" -a -z "$BACKUP" ] && export NB_DELETE
if [ -n "$MAKE_PACKAGE" -a -z "$FETCH_ONLY" ]; then
init_packages_var
if ! pm_isdir "$PACKAGES"; then
pm_sv Creating $PACKAGES
pm_mkdir_s $PACKAGES
fi
fi
# Set the file name here so it's visible to the children
if [ -z "$DONT_SCRUB_DISTFILES" -a -z "$FETCH_ONLY" -a -z "$PM_PACKAGES" ]; then
pm_mktemp DI-FILES ; DI_FILES=$pm_mktemp_file ; export DI_FILES
fi
[ -n "$PM_URB" ] && multiport $PM_URB_IPORTS
[ $# -gt 1 -a -z "$REPLACE_ORIGIN" ] && multiport "$@"
fi
# This has to come after the initialization, it uses all the same stuff
if [ -n "$UPDATE_ALL" ]; then
all_first_pass () {
local iport origin
for iport in "$@"; do
[ -z "$FETCH_ONLY" ] && pm_v "===>>> $iport"
case "$CUR_DEPS" in *:${iport}:*) continue ;; esac
origin=`origin_from_pdb $iport` || {
case "$?" in
3) ;;
2) pm_v " ===>>> No ORIGIN for $iport, and +IGNOREME is present or the package is locked"
echo " ===>>> Skipping"
echo '' ;;
*) fail 'Cannot continue' ;;
esac;
# Prevent the user from getting reprompted during build
CUR_DEPS="${CUR_DEPS}${iport}:";
continue; }
case "$PM_NEEDS_UPDATE" in *\ $origin\ *) continue ;; esac
[ -n "$PM_BUILD_ONLY_LIST" ] && run_dl_g="$run_dl_g ${pd}/${origin} "
check_exclude $iport || continue
PM_DEPTH="$iport "
check_for_updates $iport $origin || fail 'Update failed'
done
}
[ -n "$DI_FILES" ] && (read_distinfos)&
ports_by_category
if [ -n "$FETCH_ONLY" ]; then
# UPDATE_ALL is not exported
export PM_ALL_FETCH=pm_all_fetch
[ -n "$PM_FORCE" ] && num_of_deps=$num_ports
fi
unset num_ports
init_term_printf All
echo "===>>> Starting check of installed ports for available updates"
[ -n "$PM_BUILD_ONLY_LIST" ] && PM_BUILD_ONLY_LIST=pmp_doing_build_deps
pm_v "\n===>>> Root ports: $num_roots" ; unset num_roots
all_first_pass $roots
pm_v "\n===>>> Trunk ports: $num_trunks" ; unset num_trunks
all_first_pass $trunks
pm_v "\n===>>> Branch ports: $num_branches" ; unset num_branches
all_first_pass $branches
pm_v "\n===>>> Leaf ports: $num_leaves" ; unset num_leaves
all_first_pass $leaves
check_fetch_only
if [ -n "$NO_DEP_UPDATES" ]; then
echo '' ; echo "===>>> All ports are up to date" ; echo ''
safe_exit
fi
post_first_pass 'ports that need updating'
[ -n "$PM_BUILD_ONLY_LIST" ] && clean_build_only_list
export PM_BUILDING=pmbuildingall
unset roots trunks branches leaves
for origin in $PM_NEEDS_UPDATE; do
case $PM_NEEDS_UPDATE in
*\ $origin\ *) update_port $origin ;;
*) continue ;; # Already updated as a dependency
esac
done
echo "===>>> Update check of installed ports complete" ; echo ''
safe_exit
fi # [ -n "$UPDATE_ALL" ]
no_valid_port () {
echo "===>>> No valid installed port, or port directory given"
echo "===>>> Try $progname --help" ; echo '' ; safe_exit 1
}
make_target=$(target_part "$1")
post_clean_l=""
# Figure out what we are going to be working on
if [ -z "$REPLACE_ORIGIN" ]; then
portdir="${1%:*}"
export_flavor $(flavor_part $portdir)
[ -n "$portdir" ] && { argv=$portdir ; unset portdir; }
argv=${argv:-$1} ; argv=${argv%/} ; argv=`globstrip $argv`
case "$argv" in
$pd/*) portdir=${argv#$pd/} ;;
$pdb/*) echo '' ; no_valid_port ;;
/*) echo '' ; no_valid_port ;;
*/*) portdir=$argv ;;
\.|'') portdir="$PWD"
while : ; do
case "$portdir" in
/) echo ''; no_valid_port ;;
*/*/*) portdir="${portdir#*/}" ;;
*/*) break ;;
*) echo '' ; no_valid_port ;;
esac
done ;;
*) upg_port=$($PKG_CMD query %n-%v "$argv") ;;
esac
if [ -z "$portdir" -a -z "$upg_port" ]; then
find_glob_dirs $argv
case $? in
1) echo '' ; no_valid_port ;;
2) multiport $glob_dirs ;;
0) upg_port=${glob_dirs#$pdb/} ;;
esac
unset glob_dirs
fi
unset argv
[ "$make_target" != install ] && PM_MAKE_ARGS="-DDISABLE_CONFLICTS $PM_MAKE_ARGS"
else
portdir="${1#$pd/}" ; portdir="${portdir%/}"
export_flavor $(flavor_part $portdir)
if [ -z "$PM_INDEX_ONLY" ]; then
pm_isdir_pd "$portdir" ] || missing=missing
else
parse_index $portdir name >/dev/null || missing=missing
fi
if [ -n "$missing" ]; then
echo ''
echo "===>>> The first argument to -o must be a directory in $pd"
echo '' ; no_valid_port
fi
upg_port=`iport_from_origin $portdir` || upg_port=$opd # <se> $opd is never set???
arg2=${2#$pd/} ; arg2=${arg2#$pdb/} ; arg2=${arg2%/}
case "$arg2" in
*/*) ro_opd=$arg2 ; ro_upg_port=`iport_from_origin $ro_opd` ;;
*) if pm_isdir "$pdb/$arg2" && $PKG_CMD info -e $arg2; then
ro_upg_port=$arg2
else
find_glob_dirs $arg2 && ro_upg_port=${glob_dirs#$pdb/}
unset glob_dirs
fi
if [ -n "$ro_upg_port" ]; then
ro_opd=`origin_from_pdb $ro_upg_port`
else
ro_opd=$arg2
fi
esac
upg_port="${upg_port:-$ro_upg_port}"
unset arg2
if [ -z "$ro_upg_port" ]; then
$PKG_CMD query -a "%do" | grep -q "^$ro_opd$"
if [ "$?" -eq 1 ]; then
echo ''
echo "===>>> The second argument to -o can be a package name,"
echo " or a port directory from $pd"
echo ''
echo " $ro_opd does not seem to be installed,"
echo ' or listed as a dependency'
echo '' ; no_valid_port
fi
fi
PM_MAKE_ARGS="-DDISABLE_CONFLICTS $PM_MAKE_ARGS"
fi
if [ -n "$upg_port" -a -z "$portdir" ]; then
portdir=`origin_from_pdb $upg_port` || {
case "$?" in
3) echo ''; echo "===>>> BSDPAN ports cannot be upgraded with portmaster"
echo " (${upg_port})"; echo ''; safe_exit 1 ;;
2) pm_v " ===>>> No ORIGIN for $upg_port, and +IGNOREME is present\n"
safe_exit 1 ;;
*) fail 'Cannot continue' ;;
esac ; }
elif [ -z "$portdir" ]; then
no_valid_port
fi
if [ -z "$PM_INDEX_ONLY" ] && ! pm_isdir_pd "$portdir"; then
find_moved_port $portdir $upg_port || no_valid_port
[ -n "$moved_npd" ] || no_valid_port
flavor=$(flavor_part "$moved_npd")
export_flavor $flavor
pm_isdir_pd "$moved_npd" || no_valid_port
[ "$$" -eq "$PM_PARENT_PID" ] && parent_exit
[ -z "$upg_port" ] && upg_port="$portdir"
exec "$program" $ARGS -o $moved_npd $upg_port
# NOT REACHED
fi
iport_from_pkgname () {
local dir flavor pkgname
dir=$(dir_part $1)
flavor=$(flavor_part $1)
pkgname=$(FLAVOR=$flavor pm_make -C "$pd/$dir" -V PKGNAME) &&
$PKG_CMD query "%n-%v" "${pkgname%-*}"
}
if [ -z "$upg_port" -a -z "$REPLACE_ORIGIN" ]; then
upg_port=`iport_from_origin ${portdir}` ||
upg_port=`iport_from_pkgname $portdir` ||
upg_port="$PM_OLD_ORIGIN"
# || fail "XXX Cannot find installed port '$portdir'"
fi
if pm_islocked "$upg_port"; then
# Adding to CUR_DEPS means we will not get here in the build
if [ -z "$PM_BUILDING" ]; then
# Only need to prompt for this once if -ai
case "$INTERACTIVE_YES" in
*:${upg_port}:*) ;; # Let it build
*) if [ -z "$FETCH_ONLY" ]; then
echo ''
echo "===>>> $upg_port has an +IGNOREME file or the package is locked"
get_answer_g n y "\t===>>> Update anyway? y/n"
case "$?" in
1) ;; # Let it build
0) CUR_DEPS="${CUR_DEPS}${upg_port}:${portdir}:"
if [ ${dep_of_deps:-0} -gt 0 ]; then
dep_of_deps=$(( $dep_of_deps - 1 ))
[ -n "$PM_FIRST_PASS" ] &&
num_of_deps=$(( $num_of_deps - 1 ))
fi
safe_exit ;;
esac
else
echo ''
echo "===>>> $upg_port has an +IGNOREME file or the package is locked, ignoring"
echo ''
CUR_DEPS="${CUR_DEPS}${upg_port}:${portdir}:"
safe_exit
fi ;;
esac
elif [ -n "$PM_URB_UP" ]; then
echo ''
echo "===>>> $upg_port has an +IGNOREME file or the package is locked, ignoring"
echo ''
safe_exit
fi
fi
# START
if [ -z "$PM_INDEX_ONLY" ]; then
pm_cd $(dir_part $pd/$portdir) || no_valid_port
export_flavor $(flavor_part $portdir)
else
new_port=`parse_index $portdir name` ||
fail "No entry for $portdir in $PM_INDEX"
fi
unset -f no_valid_port
if [ -z "$PM_DEPTH" ]; then
PM_DEPTH="${upg_port:-$portdir} "
[ -z "$PM_PARENT_PORT" ] && init_term_printf ${upg_port:-$portdir}
else
PM_DEPTH="${PM_DEPTH}>> ${upg_port:-$portdir} "
fi
echo ''
[ -n "$upg_port" ] && echo "===>>> Currently installed version: $upg_port"
echo "===>>> Port directory: $pd/$portdir" ; echo ''
if [ -n "$PM_FIRST_PASS" -a -z "$FETCH_ONLY" ]; then
if [ -z "$PM_INDEX_ONLY" ]; then
if ! check_state; then
check_state_fail=check_state_fail
if [ -n "$PM_FORCE_CONFIG" ]; then
sleep 4
make_config
check_state && unset check_state_fail
fi
if [ -n "$check_state_fail" ]; then
echo " ===>>> If you are sure you can build it, remove the"
echo " $state line in the Makefile and try again."
safe_exit 1
fi
fi
fi
update_build_l "$portdir" "$upg_port" "$make_target"
elif [ -n "$FETCH_ONLY" -a -n "$PM_PACKAGES" ]; then
update_pm_nu $portdir
fi
# Test for necessary privileges to actually install ports
[ -n "$NO_ACTION" ] || [ "$($PM_SU_CMD id -u)" = 0 ] || fail "Insufficient privileges to install ports (run as root or set PM_SU_CMD)"
# Do these things first time through
if [ -z "$PM_INDEX_ONLY" -a -z "$PM_BUILDING" -a -z "$SHOW_WORK" -a -z "$NO_ACTION" ]; then
# Do not start this in the background until we are sure we are going to proceed
[ "$$" -eq "$PM_PARENT_PID" -a -n "$DI_FILES" ] && (read_distinfos)&
# Handle the problem of manual fetching
[ -z "$PM_PACKAGES" ] && master_sites=`pm_make -V MASTER_SITES`
if [ -n "$master_sites" ]; then
# PATCHFILES may get added after the first pass, but we want to
# do as much of this as we can, as early as we can, and
# patch files are usually small anyway.
make_distfiles
# Make sure that different ports using the same distfiles
# do not clobber each other's fetchs
for file in $distfiles; do
case "$file" in */*) file=`echo $file | sed s#/#_#g` ;; esac
if ! ls ${TMPDIR}/f-${PM_PARENT_PID}-${file}-* >/dev/null 2>&1; then
pm_mktemp ${file}-${portdir#*/} >/dev/null
else
[ -n "$FETCH_ONLY" ] &&
echo "===>>> Skipping $file due to previous fetch for it"
DONT_FETCH=dont_fetch
break
fi
done
if [ -z "$DONT_FETCH" -a -n "$distfiles" ]; then
echo "===>>> Launching 'make checksum' for $portdir in background"
pm_mktemp fetchlog-${portdir#*/} ; fetchlog=$pm_mktemp_file
(pm_make -DBATCH checksum >> $fetchlog 2>&1 && {
rm -f ${TMPDIR}/f-${PM_PARENT_PID}-*-${portdir#*/}.*; exit 0; }
allfiles=`pm_make -V ALLFILES`
pm_make delete-distfiles RESTRICTED_FILES="${allfiles}" \
>> $fetchlog 2>&1 &&
echo "===>>> RE-STARTING FETCH <<<===" >> $fetchlog
pm_make -DBATCH checksum >> $fetchlog 2>&1
rm -f ${TMPDIR}/f-${PM_PARENT_PID}-*-${portdir#*/}.* )&
fi
unset master_sites distfiles file DONT_FETCH fetchlog
elif [ -n "$FETCH_ONLY" ]; then
echo "===>>> No distfiles to fetch"
fi
if [ -z "$FETCH_ONLY" -a ! "$PM_PACKAGES" = only ]; then
TESTINT=`grep -l ^IS_INTERACTIVE Makefile` &&
TESTINT=`pm_make_b -V IS_INTERACTIVE`
else
[ -n "$PM_ALL_FETCH" ] && safe_exit
fi
if [ -n "$TESTINT" ]; then
echo ''
echo "===>>> Warning: $portdir is interactive, and will likely"
echo " require attention during the build"
echo ''
echo -n "===>>> Press the [Enter] or [Return] key to continue "
read DISCARD
echo ''
unset TESTINT DISCARD
fi
fi # [ -z "$PM_INDEX_ONLY" -a -z "$PM_BUILDING" -a -z "$SHOW_WORK" -a -z "$NO_ACTION" ]
if [ -n "$PM_FIRST_PASS" ]; then
[ "$$" -eq "$PM_PARENT_PID" -a -n "$PM_BUILD_ONLY_LIST" ] &&
PM_BUILD_ONLY_LIST=pmp_doing_build_deps
if [ -z "$PM_PACKAGES" ]; then
[ -z "$PM_NO_MAKE_CONFIG" ] && make_config
dep_check_type='build-depends-list run-depends-list'
[ -n "$PM_THOROUGH" ] && dep_check_type=all-depends-list
else
dep_check_type=run-depends-list
fi
dependency_check "$dep_check_type"
[ -n "$PM_URB" -o -n "$PM_URB_UP" ] &&
PM_URB_DONE="${PM_URB_DONE}${upg_port}:"
[ "$$" -eq "$PM_PARENT_PID" ] || safe_exit
check_fetch_only
post_first_pass $portdir
fi # [ -n "$PM_FIRST_PASS" ]
[ -z "$PM_BUILDING" ] && export PM_BUILDING=pmbuildingmain
pm_cd_pd $portdir
if [ -n "$PM_BUILD_ONLY_LIST" ]; then
case "$build_only_dl_g" in
*" $pd/$portdir "*|*" $portdir "*)
[ -n "$PM_PACKAGES_BUILD" ] && PM_PACKAGES_BUILD=doing_build_only_dep
[ -n "$PM_DEL_BUILD_ONLY" ] && PM_DEL_BUILD_ONLY=doing_build_only_dep ;;
*) [ -n "$PM_PACKAGES_BUILD" ] && PM_PACKAGES_BUILD=pmp_build
[ -n "$PM_DEL_BUILD_ONLY" ] && PM_DEL_BUILD_ONLY=pm_dbo ;;
esac
fi
if [ -z "$NO_DEP_UPDATES" ]; then
if [ -z "$PM_THOROUGH" ]; then
if [ -z "$PM_PACKAGES" ]; then
echo "===>>> Starting check for build dependencies"
dependency_check build-depends-list
fi
else
echo "===>>> Starting check for all dependencies"
if [ -z "$PM_PACKAGES" ]; then
dependency_check all-depends-list
else
dependency_check run-depends-list
fi
fi
pm_cd_pd $portdir
elif [ "$$" -eq "$PM_PARENT_PID" ]; then
echo "===>>> All dependencies are up to date"
echo ''
fi
if [ -n "$NO_ACTION" -a -z "$PM_FIRST_PASS" ]; then
pm_v "===>>> Build canceled due to -n flag"
safe_exit
fi
find_new_port $portdir
if [ -n "$PM_PACKAGES" -o "$PM_PACKAGES_BUILD" = doing_build_only_dep ]; then
case `pm_make_b -V PT_NO_INSTALL_PACKAGE` in
'') pm_package_time=yes ;;
*) if [ "$PM_PACKAGES" = 'only' ]; then
echo "===>>> The -PP/--packages-only option was specified, but"
echo " PT_NO_INSTALL_PACKAGE is defined for $portdir"
fail These 2 options are mutually exclusive
fi
echo "===>>> PT_NO_INSTALL_PACKAGE is set, building port"
echo '' ;;
esac
fi
if [ -n "$pm_package_time" ]; then
unset pm_package_time
fetch_package () {
# Global: ppd FETCH_ARGS
local do_fetch
if [ -z "$ppd" ]; then
init_packages_var
ppd=$PACKAGES/portmaster-download
export ppd
fi
pm_isdir "$ppd" || { pm_sv Creating $ppd; pm_mkdir_s $ppd; }
if [ -z "$FETCH_ARGS" ]; then
FETCH_ARGS=`pm_make -f/usr/share/mk/bsd.port.mk -V FETCH_ARGS 2>/dev/null`
[ -n "$FETCH_ARGS" ] || FETCH_ARGS='-ApRr'
export FETCH_ARGS
fi
if [ -z "$PM_ALWAYS_FETCH" ]; then
if [ -r "${ppd}/${1}.pkg" ]; then
pm_v "===>>> Package exists, skipping fetch"
return 0
else
do_fetch=do_fetch_no_package
fi
else
do_fetch=do_fetch_always_fetch
pm_unlink_s ${ppd}/${1}.pkg
fi
if [ -n "$do_fetch" ]; then
if [ -n "$PM_VERBOSE" ]; then
if [ -n "$2" ]; then
echo "===>>> Trying to fetch $1 directly"
else
echo "===>>> Starting package fetch"
fi
fi
pm_sv Fetching ${1}.pkg
if ! $PM_SU_CMD fetch $FETCH_ARGS -o $ppd ${sitepath}${1}.pkg 2>/dev/null; then
pm_unlink_s ${ppd}/${1}.pkg
$PM_SU_CMD fetch $FETCH_ARGS -o $ppd ${sitepath}${1}.pkg 2>/dev/null
fi
fi
}
if [ -z "$PACKAGESITE" -a -z "$PM_PACKAGES_LOCAL" ]; then
release=`uname -r`
major_rel=${release%.*}
arch=`uname -p`
sitepath="${PACKAGEROOT:-"http://pkg.freebsd.org"}/FreeBSD:$major_rel:$arch/latest/All/"
unset release major_rel arch
else
sitepath="${PACKAGESITE%/}"
sitepath="${sitepath%Latest}"
sitepath="${sitepath%All}"
fi
# sitepath="${sitepath%/}/${portdir%/*}/" # may be required for local packages
echo "===>>> Checking package repository for latest available version"
if [ -n "$LOCAL_PACKAGEDIR" ]; then
pm_v "===>>> ... checking: ${LOCAL_PACKAGEDIR}/All/${new_port}.pkg"
if [ -r "${LOCAL_PACKAGEDIR}/All/${new_port}.pkg" ]; then
local_package=${LOCAL_PACKAGEDIR}/All/${new_port}.pkg
latest_pv=${local_package##*/}
fi
if [ -z "$latest_pv" -a -z "$PM_INDEX_ONLY" ]; then
s=`pm_make -V PKGLATESTFILE`
echo "===>>> ... checking: ${s}"
if [ -r "${s}" ]; then
local_package=${s}
latest_pv=`readlink ${s}`
latest_pv=${latest_pv##*/}
else
pm_v "===>>> No local package for ${new_port}, attempting fetch"
fi
fi
fi
if [ -z "$latest_pv" -a -z "$PM_PACKAGES_LOCAL" ]; then
dirlist=`echo ${TMPDIR}/f-${PM_PARENT_PID}-dl-${portdir%/*}\.*`
if [ ! -r "$dirlist" ]; then
pm_unlink $dirlist # JIC
pm_mktemp dl-${portdir%/*} ; dirlist=$pm_mktemp_file
fetch -q -o - ${sitepath} 2>/dev/null |
sed -e "s#%2[cC]#,#g" -e "s#%2[bB]#+#g" > $dirlist
fi
for s in ${new_port%\.*} ${new_port%%\.*} ${new_port%-*}; do
latest_pv=`grep -m1 "href=\"${s}" $dirlist`
[ -n "$latest_pv" ] && break
done
fi
unset dirlist s
[ -z "$latest_pv" -a -z "$PM_PACKAGES_LOCAL" ] && {
fetch_package $new_port try && latest_pv=$new_port; }
ponly_err="Try --packages-if-newer, or do not use -PP/--packages-only"
if [ -z "$latest_pv" ]; then
echo "===>>> Package and/or archive not found at:"
if [ -n "$LOCAL_PACKAGEDIR" ]; then
echo " $LOCAL_PACKAGEDIR"
[ -z "$PM_PACKAGES_LOCAL" ] && echo ' or'
fi
[ -z "$PM_PACKAGES_LOCAL" ] && echo " ${sitepath}"
echo ''
echo " Check the pkg-add(8) man page for information"
echo " on setting the PACKAGESITE environment variable"
[ "$PM_PACKAGES" = only -a -z "$FETCH_ONLY" ] && fail $ponly_err
if [ -n "$FETCH_ONLY" ]; then
while : ; do
echo -e "\n===>>> There is no valid package to install\n"
echo "===>>> Abort update [a]"
echo "===>>> Retry fetch [r]"
echo "===>>> Continue if possible [c]"
echo -e "\n===>>> How would you like to proceed? [a] \c"
read answer ; echo ''
case "$answer" in
''|[aA]) fail "No package exists for $new_port" ;;
[rR]) if fetch_package $new_port try ; then
latest_pv=$new_port
break
fi ;;
[cC]) safe_exit ;;
*) echo " ===>>> $answer is not a valid response" ;;
esac
done
unset answer
fi
else
latest_pv=${latest_pv#*href=\"}
latest_pv=${latest_pv%%\.pkg*}
fi
notnewer () {
echo ''
echo "===>>> The newest available package ($latest_pv)"
echo " is not newer than the installed version ($upg_port)"
unset local_package
}
if [ "$latest_pv" = "$new_port" ]; then
use_package=up_equal
pm_v "===>>> Available package ($latest_pv) matches the current version"
elif [ -n "$latest_pv" -a -n "$PM_PACKAGES_NEWER" ]; then
if [ -n "$upg_port" ]; then
case `$PKG_CMD version -t $upg_port $latest_pv` in
\<) use_package=up_newer
pm_v "===>>> Available package ($latest_pv)"
pm_v " is newer than installed ($upg_port)" ;;
=) if [ -n "$PM_FORCE" ]; then
use_package=up_force
else
notnewer
fi ;;
*) notnewer ;;
esac
else
use_package=up_no_installed
pm_v "===>>> There is a package available ($latest_pv)"
fi
elif [ -n "$latest_pv" ]; then
case `$PKG_CMD version -t $new_port $latest_pv` in
\<) # Could happen if ports tree is out of date
use_package=up_old_tree
pm_v "===>>> Available package ($latest_pv)"
pm_v " is newer than ports tree ($new_port)" ;;
=) ;; # Should not be reached
*) # Packages like autoconf-2.1* vs. 2.6* can be false neg.
fetch_package $new_port try
if [ $? -eq 0 ]; then
latest_pv=$new_port
use_package=up_auto
else
echo ''
echo "===>>> The newest available package ($latest_pv)"
echo " is older than the version in ports ($new_port)"
if [ "$PM_PACKAGES" = only ]; then
if [ -n "$PM_FORCE" ]; then
use_package=up_force2
echo "===>>> Installing anyway due to -f"
else
fail $ponly_err
fi
fi
fi ;;
esac
fi
unset ponly_err ; unset -f notnewer
if [ -n "$use_package" ]; then
new_port=$latest_pv
else
if [ "$PM_PACKAGES" = only ]; then
fail "There is no valid package to install"
else
echo ''
[ -n "$FETCH_ONLY" ] && safe_exit
echo "===>>> There is no valid package to install, building port instead"
echo ''
fi
fi
fi # [ -n "$pm_package_time" ]
if [ -z "$use_package" ]; then
if [ -n "$PM_PACKAGES" ]; then
[ -z "$PM_NO_MAKE_CONFIG" ] && make_config
if [ -z "$PM_THOROUGH" ]; then
echo "===>>> Starting check for build dependencies"
dependency_check build-depends-list
fi
fi
pm_cd_pd $portdir
export_flavor $(flavor_part $portdir)
[ -z "$DONT_PRE_CLEAN" ] && { pm_make_s clean NOCLEANDEPENDS=ncd ||
fail 'make clean failed'; }
fl_read=`echo ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-${portdir#*/}.*`
count=0
while [ -f "$fl_read" ]; do
count=$(( $count + 1 ))
if [ $count -eq 1 ]; then
echo "===>>> Waiting on fetch & checksum for $portdir <<<==="
tail -10 $fl_read 2>/dev/null
echo '' ; echo ''
elif [ $count -eq 3 ]; then
count=0
fi
sleep 2
done
unset count fl_read
if [ -n "$HIDE_BUILD" ]; then
port_log=`/usr/bin/mktemp -t port_log-${PM_PARENT_PID}-${portdir#*/}` ||
fail "mktemp for port_log-${PM_PARENT_PID}-${portdir#*/} failed"
port_log_args=">> $port_log 2>&1"
echo "===>>> Logging build to $port_log"
fi
[ -n "$PM_NO_MAKE_CONFIG" ] && PM_MAKE_ARGS="$PM_MAKE_ARGS -D_OPTIONS_OK"
# Return flavor for named pkg (must be executed in port directory!)
pkg_flavor () {
local pkg="$1" flavor starttime
pm_make pretty-flavors-package-names | sed -ne 's!^\([A-Za-z0-9_]*\): *'$pkg'$!\1!p';
}
export_flavor=$(pkg_flavor $new_port)
if [ -n "$HIDE_BUILD" ] && [ -n "$(pm_make -V LICENSE)" ] && [ -z "$(pm_make -V DISABLE_LICENSES)" ]; then
pm_make extract ask-license || fail "make extract ask-license failed for $portdir"
fi
if [ "$make_target" = "extract" -o "$make_target" = "patch" ]; then
eval pm_make -DNO_DEPENDS $make_target $port_log_args || fail "make $make_target failed for $portdir"
safe_exit
fi
starttime=$(date "+%s")
eval pm_make build $port_log_args || fail "make build failed for $portdir"
[ "$make_target" = "build" ] && safe_exit
echo "===>>> Building the port required $(( `date "+%s"` - $starttime )) seconds"
pm_sv Running make stage
# Defining NO_DEPENDS ensures that we will control the installation
# of the depends, not bsd.port.mk.
eval pm_make -DNO_DEPENDS stage $port_log_args || fail "make stage failed for $portdir"
[ "$make_target" = "stage" ] && safe_exit
else
[ -z "$local_package" ] && {
fetch_package $latest_pv || fail "Fetch for ${latest_pv}.pkg failed"; }
fi
# Ignore if no old port exists, or -F
if [ -n "$upg_port" -o -n "$ro_upg_port" ] && [ -z "$FETCH_ONLY" ]; then
UPGRADE_PORT="${ro_upg_port:-$upg_port}"
UPGRADE_PORT_VER=`echo $UPGRADE_PORT | sed 's#.*-\(.*\)#\1#'`
export UPGRADE_PORT UPGRADE_PORT_VER
# the invocation of init_packages should be redundant, but pbu is not defined, without???
[ -z "$NO_BACKUP" ] && init_packages && pm_pkg_create "$pbu" $UPGRADE_PORT
if [ -n "$SAVE_SHARED" ]; then
pm_mktemp ldconfig
ldconfig -r | sed 's#.* ##' |
grep -v ^$LOCALBASE_COMPAT > $pm_mktemp_file
unset temp
for file in `$PKG_CMD query %Fp $UPGRADE_PORT |
sort - $pm_mktemp_file | uniq -d`; do
temp="${temp}$file "
done
if [ -n "$temp" ]; then
if ! pm_isdir "$LOCALBASE_COMPAT"; then
pm_sv "Creating $LOCALBASE_COMPAT for -w"
pm_mkdir_s $LOCALBASE_COMPAT
fi
pm_sv 'Copying old shared libraries for -w'
$PM_SU_CMD cp -p $temp ${LOCALBASE_COMPAT}/
pm_sv Running ldconfig
$PM_SU_CMD /etc/rc.d/ldconfig start > /dev/null
fi
/bin/unlink $pm_mktemp_file ; unset pm_mktemp_file temp file
fi
find_dl_distfiles $portdir
if [ -n "$REPLACE_ORIGIN" -a -n "$ro_upg_port" ]; then # <se> not always true for port moved to flavored version with no version update???
# Delete any existing versions of the old port
np_orphan=`$PKG_CMD query "%a" $ro_upg_port`
pm_sv "Running pkg delete for $ro_upg_port"
pm_pkg_delete_s $ro_upg_port
fi
# Could be empty if -o
if [ -n "$upg_port" ]; then
case " $PM_PRESERVE_PORTS " in
*" $portdir "*)
preserve_port=`echo $portdir | sed 's#[-+/\.@]#_#g'`
eval preserve_port_files="\$${preserve_port}_files"
preserve_dir=`/usr/bin/mktemp -d ${TMPDIR}/d-${PM_PARENT_PID}-${preserve_port} 2>/dev/null` ||
fail "Could not create a temporary directory for $preserve_port in $TMPDIR"
for file in $preserve_port_files; do
cp -p $file ${preserve_dir}/ ||
fail "Cannot copy $file, which is in \$${preserve_port}_files"
done
unset preserve_port files
esac
# If $ro_upg_port was non-automatic, keep its state
if [ "${np_orphan:-1}" -eq 1 ]; then
np_orphan=`$PKG_CMD query "%a" $upg_port`
fi
pm_sv "Running pkg delete for $upg_port"
pm_pkg_delete_s $upg_port
fi
echo ''
pm_cd_pd $portdir
fi
if [ -z "$PM_THOROUGH" -a -z "$NO_DEP_UPDATES" ]; then
echo "===>>> Starting check for runtime dependencies"
dependency_check run-depends-list
pm_cd_pd $portdir
fi
if [ -n "$FETCH_ONLY" ]; then # Only reached here if using packages
CUR_DEPS="${CUR_DEPS}${new_port}:${portdir}:"
if [ "$$" -eq "$PM_PARENT_PID" ]; then
check_fetch_only Package
else
safe_exit
fi
fi
install_failed () {
upg_port="${ro_upg_port:-$upg_port}"
if [ -z "$NO_BACKUP" -a -n "$upg_port" ]; then
echo ''
echo "===>>> A backup package for $upg_port should"
echo " be located in $pbu"
fi
fail "Installation of $1 ($portdir) failed"
}
if [ -z "$use_package" ]; then
pm_sv Running make install
if [ -z "$PM_SU_UNSET_PORT_LOG_ARGS" ]; then
[ -n "$HIDE_BUILD" ] && echo "===>>> Logging install to $port_log"
else
unset port_log_args
fi
if [ -z "$np_orphan" -a -z "$UPDATE_ALL" -a -z "$REPLACE_ORIGIN" -a -z "$PM_URB" ]; then
if [ -n "$PM_MULTI_PORTS" ]; then
case "$PM_MULTI_PORTS" in
*:${upg_port:-NONE}:*) np_orphan=0 ;;
*:${portdir}:*) np_orphan=0 ;;
esac
else
[ "$$" -eq "$PM_PARENT_PID" ] && np_orphan=0
fi
fi
[ "${np_orphan:-1}" -eq 1 ] && PM_MAKE_ARGS="${PM_MAKE_ARGS} -DINSTALLS_DEPENDS"
unset np_orphan
# Defining NO_DEPENDS ensures that we will control the installation
# of the depends, not bsd.port.mk.
# export_flavor $(flavor_part "$portdir")
eval pm_make_s -DNO_DEPENDS install $port_log_args || install_failed $new_port
else
[ -n "$local_package" ] && ppd=${LOCAL_PACKAGEDIR}/All
echo "===>>> Installing package from: ${ppd}/${latest_pv}.pkg"
if $PM_SU_CMD $PKG_CMD add --accept-missing --force ${ppd}/${latest_pv}.pkg; then
if [ -n "$PM_DELETE_PACKAGES" ]; then
pm_v "===>>> Deleting ${latest_pv}.pkg"
pm_unlink_s ${ppd}/${latest_pv}.pkg
fi
else
install_failed ${latest_pv}.pkg
fi
fi
if [ "$was_locked" = 1 ]; then
$PKG_CMD lock -qy "$new_port"
fi
if [ -n "$preserve_dir" ]; then
rmdir $preserve_dir 2>/dev/null
unset preserve_dir preserve_port_files
fi
echo ''
[ "$PM_DEL_BUILD_ONLY" = doing_build_only_dep ] &&
build_deps_il="$build_deps_il $new_port"
# Remove saved libs that match newly installed files
temp=`find $LOCALBASE_COMPAT -type d -empty 2>/dev/null`
if [ -z "$temp" ] && pm_isdir "$LOCALBASE_COMPAT"; then
unset files
for file in `$PKG_CMD query %Fp $new_port`; do
[ -f "${LOCALBASE_COMPAT}/${file##*/}" ] &&
files="${files}${LOCALBASE_COMPAT}/${file##*/} "
done
if [ -n "$files" ]; then
pm_sv Removing old shared libraries, and running ldconfig
pm_rm_s `pm_make -V FILES:O:u FILES="$files"`
$PM_SU_CMD /etc/rc.d/ldconfig start > /dev/null
fi
unset temp file files
fi
[ -z "$temp" ] && temp=`find $LOCALBASE_COMPAT -type d -empty 2>/dev/null`
if pm_isdir "$temp"; then
pm_sv Deleting the empty $LOCALBASE_COMPAT
pm_rmdir_s $temp
fi
unset temp
# This will serve for *delete*distfiles() as well
[ -z "$use_package" ] && make_distfiles
if [ -n "$distfiles" ]; then
# Implement storage of distfile information in the way that
# it will (hopefully, soon?) be implemented in bsd.port.mk
# See http://www.freebsd.org/cgi/query-pr.cgi?pr=106483
dist_list="${pdb}/${new_port}/distfiles"
make_port_subdir
if [ -s distinfo ]; then
distinfo=distinfo
else
distinfo=`pm_make -V DISTINFO_FILE`
[ -n "$distinfo" ] || fail "No DISTINFO_FILE in $portdir"
fi
pm_mktemp dist_list
echo '# Added by portmaster' > $pm_mktemp_file
for file in $distfiles; do
while read line ; do
case "$line" in
SHA256\ \(${port_subdir}${file}\)*) sha256=${line##* }
[ -z "$size" ] && continue
echo "DISTFILE:${port_subdir}${file}:SIZE=${size}:SHA256=${sha256}" \
>> $pm_mktemp_file ; unset sha256 size ; break ;;
SIZE\ \(${port_subdir}${file}\)*)
[ -z "$sha256" ] && { size=${line##* } ; continue; }
echo "DISTFILE:${port_subdir}${file}:SIZE=${line##* }:SHA256=${sha256}" \
>> $pm_mktemp_file ; unset sha256 ; break ;;
esac
done < $distinfo
# Make sure any new distfiles get added to the list
[ -n "$DI_FILES" -a ! "$$" -eq "$PM_PARENT_PID" ] &&
echo "${port_subdir}${file}" >> $DI_FILES
done
pm_sv "Installing $dist_list\n"
pm_mkdir_s ${dist_list%/*}
pm_install_s $pm_mktemp_file $dist_list
/bin/unlink $pm_mktemp_file ; unset distinfo pm_mktemp_file file line
fi
if [ -n "$MAKE_PACKAGE" ]; then
if [ -z "$use_package" ]; then
echo "===>>> Creating a package for new version $new_port"
pm_make_s -D_OPTIONS_OK ${PACKAGE_FORMAT:+PKG_COMPRESSION_FORMAT=$PACKAGE_FORMAT} package >/dev/null || fail "Package creation of $new_port failed"
echo " ===>>> Package saved to $PACKAGES/All" ; echo ''
else
pm_pkg_create $PACKAGES $new_port
fi
fi
if [ -z "$use_package" -a -z "$DONT_POST_CLEAN" ]; then
flavor=$(flavor_part $portdir)
for dir in $post_clean_l; do
pm_v "===>>> Running 'make clean' for special build dependency $dir"
(pm_make_s -C "$pd/$dir" ${flavor:+FLAVOR=$flavor} clean NOCLEANDEPENDS=ncd2 >/dev/null)&
done
pm_v "===>>> Running 'make clean' in the background"
(pm_make_s ${flavor:+FLAVOR=$flavor} clean NOCLEANDEPENDS=ncd2 >/dev/null)&
pm_v
fi
if [ -n "$ro_opd" ]; then
echo "===>>> Updating dependency entry for $new_port in each dependent port"
$PM_SU_CMD $PKG_CMD set -yo $ro_opd:$portdir
fi
if [ -n "$upg_port" ]; then
upg_port=$(dir_part $upg_port)
if [ ! "$upg_port" = "$new_port" ]; then
ilist="Upgrade of $upg_port to $new_port"
else
ilist="Re-installation of $upg_port"
fi
else
ilist="Installation of $portdir ($new_port)"
fi
if [ "$$" -ne "$PM_PARENT_PID" -o -n "$PM_URB" ]; then
echo "===>>> $ilist succeeded" ; echo ''
fi
INSTALLED_LIST="${INSTALLED_LIST}\t${ilist}\n"
[ -n "`$PKG_CMD query %M $new_port`" ] && DISPLAY_LIST="${DISPLAY_LIST}$new_port "
CUR_DEPS="${CUR_DEPS}${new_port}:${portdir}:"
[ -n "$HIDE_BUILD" -a -n "$port_log" ] && pm_unlink $port_log
[ -n "$PM_URB" -o -n "$PM_URB_UP" ] && PM_URB_DONE="${PM_URB_DONE}${new_port}:"
[ -n "$PM_URB" -o -n "$PM_URB_UP" -o -n "$PM_FORCE" ] &&
pm_mkdir_s $pdb/$new_port &&
$PM_SU_CMD touch $pdb/$new_port/PM_UPGRADE_DONE_FLAG
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
delete_stale_distfiles $portdir
if [ -n "$ro_opd" ]; then
delete_all_distfiles $ro_opd
fi
fi
safe_exit
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright (c) 2005-2012 Douglas Barton
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.