#!/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 %%PORTVERSION%%" } 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 ( $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 ${PM_NEEDS_UPDATE}" > ~/portmasterfail.txt echo '' echo "===>>> You can restart from the point of failure with this command line:" echo " $progname ${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=] [--packages-local] [--delete-packages]" echo " [--backup-format=] [--no-confirm] [--no-term-title] [--no-index-fetch]" echo " [--index|--index-first|--index-only] [-m ]" echo " [-x ]" echo "$progname [Common flags] " echo "$progname [Common flags] " echo "$progname [Common flags] " echo "$progname [Common flags] [-U|--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 ] " echo '' echo "$progname [Common flags] -o " echo "$progname [Common flags] [-R] -r " echo ' (-r 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 " 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 (default, this option does nothing)' echo '-d always clean distfiles' echo '--prompt-clean-distfiles prompt to clean distfiles' echo "-m " echo "-x " 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 '-U|--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= 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=} ;; -U|--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 ;; --prompt-clean-distfiles) PROMPT_SCRUB_DISTFILES=prompt_clean_distfiles ;; --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 if [ -n "$PROMPT_SCRUB_DISTFILES" -a -n "$DONT_SCRUB_DISTFILES" ]; then test_command_line PROMPT_SCRUB_DISTFILES DONT_SCRUB_DISTFILES || fail "The --prompt-clean-distfiles and -D options are mutually exclusive" fi if [ -n "$ALWAYS_SCRUB_DISTFILES" -a -n "$PROMPT_SCRUB_DISTFILES" ]; then test_command_line ALWAYS_SCRUB_DISTFILES PROMPT_SCRUB_DISTFILES || fail "The -d and --prompt-clean-distfiles 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' # Set PAGER if undefined, enforce PAGER=cat for --no-confirm case : ${PAGER:='less -E'} if [ -n "$PM_NO_CONFIRM" ]; then PAGER=cat fi 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 [ -n "$ALWAYS_SCRUB_DISTFILES" -o -n "$PROMPT_SCRUB_DISTFILES" ]; then pm_v "===>>> There is no ports tree, so using -D option" unset ALWAYS_SCRUB_DISTFILES unset PROMPT_SCRUB_DISTFILES DONT_SCRUB_DISTFILES=Dopt_es; ARGS="-D $ARGS" fi fi fi # set DONT_SCRUB_DISTFILES for convenience if neither # ALWAYS_SCRUB_DISTFILES nor PROMPT_SCRUB_DISTFILES are set if [ -z "$ALWAYS_SCRUB_DISTFILES" -a -z "$PROMPT_SCRUB_DISTFILES" ]; then DONT_SCRUB_DISTFILES=Dopt_implicit; ARGS="-D $ARGS" 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 sed -i "" 1s/############/%%%%%%%%%%%%/ $DI_FILES } 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 sed -i "" 1s/############/%%%%%%%%%%%%/ $DI_FILES } di_file_complete= pm_wait_di_file_complete () { if [ -z "$di_file_complete" ] && [ -n "$DI_FILES" ] \ && [ `head -1 $DI_FILES` = '############' ]; then echo "===>>> Waiting for background read of distinfo files to finish" while [ `head -1 $DI_FILES` = '############' ]; do sleep 1 done fi di_file_complete=yes } 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 '' pm_cd "$DISTDIR" || fail "Cannot cd to $DISTDIR" for f in $(find . -type f | sed -e 's:^\./::;s: :\\?:g' | LANG=C sort); do f=$(echo "$f" | sed -e 's:\\\?: :g') if ! grep -Fxql "$f" $DI_FILES; then get_answer_yn n "\t===>>> Delete stale file: $f" case "$?" in 0) echo " Deleting $f" ; echo '' /bin/unlink "$f" ;; *) 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 '+COMPACT_MANIFEST' 2>/dev/null | sed -ne 's/.*"origin":"\([^"]*\)".*/\1/p' && [ -n "$origin" ]` || fail "Empty origin in $package" flavor=`$PKG_CMD query -F $package %At=%Av 2>/dev/null | sed -ne 's/^flavor=//p'` || flavor=`tar -O -zxvf $package '+COMPACT_MANIFEST' 2>/dev/null | sed -ne 's/.*"flavor":"\([^"]*\)".*/\1/p'` if [ -z "$PM_INDEX" ]; then if pm_isdir_pd "$origin"; then pm_cd $pd/$origin && port_ver=`pm_make ${flavor:+FLAVOR=$flavor} -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 if egrep -ql '^(FORBIDDEN|BROKEN|IGNORE)' Makefile; then [ -z "$TRY_BROKEN" ] && [ -z `pm_make -V TRYBROKEN` ] && \ makevars="FORBIDDEN BROKEN IGNORE" || \ makevars="FORBIDDEN" 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 # 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 pm_wait_di_file_complete if [ -s "$DI_FILES" ]; then if grep -Fxql "${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 pm_wait_di_file_complete 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 pm_wait_di_file_complete 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 -e '%a = 1 && %?r == 0' '%n-%v'` 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=install # assume install 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=$(target_part "$1") [ "$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 # $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 # 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.