#!/bin/sh # Local version: 1.183 # $FreeBSD$ # Copyright (c) 2005-2007 Douglas Barton, All rights reserved # Please see detailed copyright below trap trap_exit INT # Keep track of the parent process if [ -z "$PARENT_PID" ]; then PARENT_PID=$$ : ${TMPDIR:=/tmp} UPGRADE_TOOL=portmaster export PARENT_PID TMPDIR UPGRADE_TOOL fi # %%LOCALBASE%% and %%X11BASE%% are needed in path for make PATH=/bin:/usr/bin:/sbin:/usr/sbin:%%LOCALBASE%%/bin:%%LOCALBASE%%/sbin:%%X11BASE%%/bin if [ -n "$CCACHE_PATH" ]; then if [ -z "$NOCCACHE" ]; then PATH="%%LOCALBASE%%/libexec/ccache:$PATH" fi fi export PATH umask 022 usage () { echo "portmaster version `grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`" echo '' echo 'Usage:' echo "Common flags: [--force-config] [-CGgntvw B|b uf|i D|d]" echo " [-m ]" echo " [-x ]" echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] Multiple full names/paths from $pdb|$pd" echo '' echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] -p " echo "${0##*/} [Common flags] . [Use in $pd/foo/bar to build that port]" echo '' echo "${0##*/} --show-work [-Gv] [-m ] " echo '' echo "${0##*/} [Common flags] -o " echo "${0##*/} [Common flags] [-R] -r " echo '' echo "${0##*/} -a [Common flags]" echo '' echo "${0##*/} -[l|L]" echo '' echo "${0##*/} [-b D|d] -e " echo "${0##*/} [-b D|d] -s" echo '' echo "${0##*/} --clean-distfiles" echo "${0##*/} --clean-distfiles-all" echo '' echo "${0##*/} -h" echo '' echo "--force-config 'make config' for all ports (must be first option)" echo "-C prevents 'make clean' being run in port directory" echo "-G prevents recursive 'make config' (unsets --force-config)" 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 do not actually 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 "-u unattended mode -- accept defaults for all but 'make config'" echo '[-R] -f always rebuild ports (overrides -i)' echo '-i interactive update mode' echo '-D prevents cleaning of distfiles' echo '-d always clean distfiles' echo "-m " echo "-x " 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 restart an update, skipping ports already up to date' echo '-a check all ports, update as necessary' echo '' echo '-l list installed ports by category' echo '-L list installed ports by category, and search for updates' echo '' echo '-e expunge a port via pkg_delete, and remove its distfiles' echo '-s clean out stale ports that used to be depended on' echo '' echo '--clean-distfiles offer to delete stale distfiles' echo '--clean-distfiles-all delete stale distfiles without prompting' echo '' echo '-h display this help message' echo '' echo 'Please see the portmaster(8) man page for more information' exit ${1:-1} } fail () { echo '' echo "===>>> $1" echo "===>>> Aborting update" if [ "$$" -eq "$PARENT_PID" ]; then trap_exit fail else safe_exit 1 fi } pmkill () { /bin/kill $1 >/dev/null 2>/dev/null return $? } kill_bad_children () { # Make parent_N global in case PIDs are random, # and we have to come back in here after them. local rc pid ppid command rc=0 ps -axo pid,ppid,command | while read pid ppid command; do case "$ppid" in 1) case "$command" in *" $0 "*) rc=1 ; parent_2=$pid ; pmkill $pid ;; *dialog*) pmkill $pid ;; esac ;; $PARENT_PID) case "$command" in # Don't kill this pipeline's subshell, but do chase it *" $0 "*) rc=1 ; parent_2=$pid ;; *dialog*) pmkill $pid ;; esac ;; $parent_2) case "$command" in *" $0 "*) rc=1 ; parent_3=$pid ; pmkill $pid ;; 'make checksum') rc=1 ; parent_3=$pid ; pmkill $pid ;; *dialog*) pmkill $pid ;; esac ;; $parent_3|1) case "$command" in \[sh\]|*'/sh '*) rc=1 ; parent_4=$pid ; pmkill $pid ;; *dialog*) pmkill $pid ;; esac ;; $parent_4|1) case "$command" in \[sh\]|*'/sh '*) rc=1 ; parent_5=$pid ; pmkill $pid ;; *dialog*) pmkill $pid ;; esac ;; $parent_5|1) case "$command" in *'/fetch '*) rc=1 ; pmkill $pid ;; *dialog*) pmkill $pid ;; esac ;; esac done return $rc } trap_exit () { local pid TRAP=yes if [ -n "$portdir" -a -z "$1" ]; then echo '' echo "===>>> Upgrade for $portdir exiting due to signal" elif [ -z "$1" ]; then echo "===>>> Exiting due to signal" fi if [ "$$" -eq "$PARENT_PID" ]; then for file in ${TMPDIR}/fetchlog-${PARENT_PID}-*; do pid=`awk '/^MCS_CHILD_PID / {print $2}' $file 2>/dev/null` test -n "$pid" || continue echo -n "===>>> Child process $pid: " if ! pmkill $pid ; then if ps -p $pid >/dev/null; then echo "Did not die!" fi fi rm -f $file done while ! kill_bad_children ; do # cheap way to keep it looping done fi safe_exit 1 } safe_exit () { echo '' test -n "$grep_deps" && rm -f $grep_deps test -n "$req_deps" && rm -f $req_deps if [ "$$" -eq "$PARENT_PID" ]; then test -n "$NO_DEP_UPDATES" && rm -f $NO_DEP_UPDATES test -n "$IPC_SAVE" && rm -f $IPC_SAVE test -n "$DI_FILES" && rm -f $DI_FILES && kill_bad_children if [ -n "$MASTER_RB_LIST" ]; then case "$MASTER_RB_LIST" in */+REQUIRED_BY) ;; *) rm -f $MASTER_RB_LIST ;; esac fi if [ -z "$TRAP" -a \ -e "${TMPDIR}/f-${PARENT_PID}-package-flag" ]; then find ${pkgrep}/ -type f -newer ${TMPDIR}/f-${PARENT_PID}-package-flag -delete fi for file in ${TMPDIR}/f-${PARENT_PID}-*; do test -f $file && unlink $file done if [ -n "$RESTART" -o -n "$FORCE" ]; then if [ -z "$TRAP" ]; then find $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete fi fi if [ -n "$DISPLAY_LIST" ]; then for f in $DISPLAY_LIST; do echo "===>>> pkg-message for ${f%/+DISPLAY}" cat $pdb/$f echo '' done echo "===>>> Done displaying pkg-message files" fi else # Save state for the parent process to read back in echo "CURRENT_DEPS_O='$CURRENT_DEPS_O'" >> $IPC_SAVE echo "CURRENT_DEPS_I='$CURRENT_DEPS_I'" >> $IPC_SAVE echo "IGNOREME_YES='$IGNOREME_YES'" >> $IPC_SAVE echo "DISPLAY_LIST='$DISPLAY_LIST'" >> $IPC_SAVE if [ -n "$INTERACTIVE_UPDATE" ]; then echo "INTERACTIVE_YES='$INTERACTIVE_YES'" >> $IPC_SAVE echo "INTERACTIVE_NO='$INTERACTIVE_NO'" >> $IPC_SAVE fi if [ -n "$URB_YES" ]; then echo "URB_DONE_LIST='$URB_DONE_LIST'" >> $IPC_SAVE fi if [ -n "$FORCE" ]; then echo "FORCE_DONE_LIST='$FORCE_DONE_LIST'" >> $IPC_SAVE fi fi exit ${1:-0} } update_contents () { local tempfile tempfile=`mktemp -t tempfile-${new_port}` sed "s/@pkgdep $1/@pkgdep $2/" $dep_port_contents > $tempfile && mv $tempfile $pdb/$dep_port/+CONTENTS chmod 644 $pdb/$dep_port/+CONTENTS if [ -n "$oldportdir" ]; then sed "s%N:${oldportdir}\$%N:${newportdir}%" $dep_port_contents > $tempfile && mv $tempfile $pdb/$dep_port/+CONTENTS chmod 644 $pdb/$dep_port/+CONTENTS fi } dep_warn () { local num_ports1 echo '' echo "===>>> Warning! Potential unrecorded dependencies on $new_port" echo "===>>> From existing +CONTENTS files:" grep -B1 DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS | sort -u | sed -e "s#$pdb/##" -e 1d num_ports1=`grep DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS | sort -u | wc -l | awk '{print $1}'` echo "===>>> $num_ports1 ports" echo '' } update_reqfile () { local num_ports2 sdiff_deps dep_warn num_ports2=`wc -l $req_deps | awk '{print $1}'` echo "===>>> From $pdb/$upg_port/+REQUIRED_BY:" cat $req_deps echo "===>>> $num_ports2 ports" echo '' echo "===>>> Use dependencies from existing +CONTENTS files [c]" echo "===>>> Use dependencies from existing +REQUIRED_BY file [r]" echo "===>>> Use sdiff to edit both files into a new file [s]" echo '' if [ -z "$UNATTENDED" ]; then echo -n "===>>> Update dependency list? [r] " read DEPUPDATE case "$DEPUPDATE" in [cC]) mv $grep_deps $req_deps ; unset grep_deps ;; [sS]) sdiff_deps=`mktemp -t sdiff-deps-${short_port}` sdiff -o $sdiff_deps --text --suppress-common-lines \ --width=`tput columns` $req_deps $grep_deps mv $sdiff_deps $req_deps ;; esac else echo "===>>> Default (use +REQUIRED_BY file) in unattended mode" fi } update_port () { local upd upd_origin if [ -n "$NO_DEP_UPDATES" ]; then rm -f $NO_DEP_UPDATES unset NO_DEP_UPDATES fi case "$1" in -p) upd=$2 test -n "$URB_YES" && upd_origin=${2#$pd/} ;; *) upd=$1 test -n "$URB_YES" && upd_origin=`origin_from_pdb $pdb/$1` ;; esac echo "===>>> Launching child to update ${upd#$pd/}" echo '' if [ -z "$NO_ACTION" ]; then ($0 $ARGS $@) || fail "Update for $upd failed" . $IPC_SAVE # Only do this if we are in the +REQUIRED_BY code to # avoid nasty (potential) circular dependencies if [ -n "$URB_YES" ]; then URB_DONE_LIST="${URB_DONE_LIST}${upd_origin}:" fi else test -n "$VERBOSE" && echo "===>>> Build canceled due to -n flag" fi if [ -n "$UPDATE_ALL" ]; then echo "===>>> Returning to update check of installed ports" elif [ -n "$UPDATE_REQ_BYS" ]; then return 0 elif [ -n "$CONFIG_ONLY" ]; then echo "===>>> Continuing 'make config' dependency check for $portdir" else echo "===>>> Returning to dependency check for $portdir" fi return 0 } check_interactive () { local UPD_OR_NOT if [ -n "$INTERACTIVE_UPDATE" ]; then case "$INTERACTIVE_YES" in *:${1}:*) return 0 ;; esac case "$INTERACTIVE_NO" in *:${1}:*) return 1 ;; esac echo -n "===>>> Update ${1}? [y] " read UPD_OR_NOT case "$UPD_OR_NOT" in [nN]*) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:" return 1 ;; *) INTERACTIVE_YES="${INTERACTIVE_YES}${1}:" ;; esac fi return 0 } iport_from_origin () { local dir dir=`grep -l "@comment ORIGIN:${1}$" $pdb/*/+CONTENTS` # It should not happen that more than one port meets this # requirement, but it can if the pkg data is corrupted. dir="${dir%%/+CONTENTS*}" dir="${dir#$pdb/}" echo $dir } origin_from_pdb () { grep '@comment ORIGIN' ${1}/+CONTENTS 2>/dev/null | cut -f2 -d':' } check_for_updates () { local upd_port port_ver do_update upd_port=`origin_from_pdb $pdb/$1` if [ -z "$upd_port" ]; then if [ -n "$VERBOSE" ]; then echo "===>>> No ORIGIN in $pdb/$1/+CONTENTS" echo '' fi return 0 fi if [ -d "$pd/$upd_port" ]; then if ! cd $pd/$upd_port 2>/dev/null; then if [ -e "$pdb/$1/+IGNOREME" ]; then echo "===>>> Warning: Unable to cd to $pd/$upd_port" echo "===>>> Continuing due to $pdb/$1/+IGNOREME" return 0 else fail "Cannot cd to port directory: $pd/$upd_port" fi fi port_ver=`make $PM_MAKE_ARGS -V PKGNAME` [ -z "$port_ver" ] && fail "Is $pd/$upd_port/Makefile missing?" if [ "$1" = "$port_ver" ]; then if [ -z "$LIST" -a -z "$LIST_PLUS" ]; then # Keep list both ways to increase performance CURRENT_DEPS_O="${CURRENT_DEPS_O}${upd_port}:" CURRENT_DEPS_I="${CURRENT_DEPS_I}${1}:" fi if [ -n "$FORCE" ]; then if [ ! -e "$pdb/$1/PM_UPGRADE_DONE_FLAG" ]; then do_update=yes fi elif [ -n "$URB_YES" -a -n "$RESTART" ]; then if [ ! -e "$pdb/$1/PM_UPGRADE_DONE_FLAG" ]; then if grep -q $1 $MASTER_RB_LIST; then do_update=yes fi else return 0 fi else return 0 fi else case `pkg_version -t $1 $port_ver` in \<) do_update=yes ;; =) ;; # Should not be reached *) if [ -n "$VERBOSE" ]; then echo '' echo " ===>>> Port version $port_ver does not" echo " ===>>> seem newer than installed $1" echo '' fi ;; esac fi else # This will fail if it doesn't exist anymore # It will return 1 if we know nothing about the port find_moved_port $upd_port || return 0 # If the port has moved, we have to update it do_update=yes fi if [ -n "$do_update" ]; then case "$2" in list) if [ -z "$newportdir" ]; then echo " ===>>> New version available: $port_ver" num_updates=$(( $num_updates + 1 )) else unset newportdir fi return 0 ;; esac if ! check_interactive $1 ; then return 0 fi update_port $1 || return 1 fi return 0 } find_moved_port () { # newportdir and oldportdir are used globally local sf IFS l sf=$1 # To avoid having each word of the reason treated separately IFS=' ' for l in `grep "^$sf" /usr/ports/MOVED`; do case "$l" in ${sf}\|\|*) fail "The $sf port has been deleted: ${l##*|}" ;; ${sf}\|*) newportdir=${l#*\|} newportdir=${newportdir%%\|*} echo '' echo "===>>> The $sf port moved to $newportdir" echo "===>>> Reason: ${l##*|}" echo '' find_moved_port $newportdir ;; esac done if [ -z "$newportdir" ]; then echo '' echo "===>>> No $pd/$1 exists, and no information" echo "===>>> about $1 can be found in $pd/MOVED" echo '' return 1 fi oldportdir=$1 return 0 } ports_by_category () { local pkg for pkg in $pdb/*; do if [ -s "$pkg/+REQUIRED_BY" ]; then if grep -q '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then branches="$branches $pkg" else trunks="$trunks $pkg" fi else if grep -q '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then leaves="$leaves $pkg" else test -s $pkg/+CONTENTS && roots="$roots $pkg" fi fi done } dependency_check () { local dep_port_list dep_port ign_p cur_p upd_args p op old_p conflicts glob conflict_port # Print a message here because sometimes list generation takes # a long time to return. echo "===>>> Gathering dependency list for $portdir from ports" dep_port_list=`make $PM_MAKE_ARGS $1 | sort -u` if [ -z "$dep_port_list" ]; then echo "===>>> No dependencies for $portdir" return 0 else if [ -n "$CONFIG_ONLY" ]; then echo "===>>> Starting recursive 'make config' check" else echo "===>>> Starting dependency check" fi fi for dep_port in $dep_port_list; do case "$dep_port" in *${EXCL}*) test -n "$VERBOSE" && echo "===>>> Skipping ${dep_port#$pd/} because it matches the pattern: *${EXCL}*" continue ;; esac if [ -n "$SHOW_WORK" ]; then orig=${dep_port#$pd/} dir=`iport_from_origin $orig` case "$dir" in '') echo "===>>> NOT INSTALLED $orig" ;; *) echo "===>>> Installed $orig" ;; esac continue fi test -n "$VERBOSE" && echo "===>>> Checking dependency: $dep_port" # Do this first to catch out of date dependencies if [ -n "$CONFIG_ONLY" ]; then case "$CONFIG_SEEN_LIST" in *:${dep_port#$pd/}:*) continue ;; esac CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${dep_port#$pd/}:" fi case "$CURRENT_DEPS_O" in *:${dep_port#$pd/}:*) continue ;; esac case "$FORCE_DONE_LIST" in *:${dep_port#$pd/}:*) continue ;; esac cd $dep_port && conflicts=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V CONFLICTS` for glob in $conflicts; do conflict_port=`pkg_info -I $glob 2>/dev/null | cut -f1 -d' '` if [ -n "$conflict_port" ]; then echo '' echo "===>>> The dependency for ${dep_port#$pd/}" echo " seems to be handled by $conflict_port" echo '' dep_port="$pd/`origin_from_pdb $pdb/$conflict_port`" fi done ign_p='' cur_p=`iport_from_origin ${dep_port#$pd/}` if [ -n "$cur_p" ]; then upd_args=$cur_p ign_p=$cur_p else upd_args="-p $dep_port" # Sensible default # Check to see if the dependency has moved because # if so, we need to update the old port to fix it p=${dep_port#$pd/} op=`sed -ne "s#\([^|]*\)|$p|.*#\1#p" $pd/MOVED` # In case there is more than one match, use the latest op=`echo $op | sed 's/.* //'` if [ -n "$op" ]; then old_p=`iport_from_origin ${op}` if [ -n "$old_p" ]; then upd_args=$old_p ign_p=$old_p fi fi fi if [ -e "$pdb/$ign_p/+IGNOREME" ]; then if [ -n "$VERBOSE" ]; then echo '' echo "===>>> Skipping $ign_p due to +IGNOREME file" echo '' fi continue fi if [ -n "$FORCE" ]; then if [ ! -e "$pdb/$cur_p/PM_UPGRADE_DONE_FLAG" ]; then echo "===>>> Forcing update for $dep_port" update_port $upd_args continue fi fi if [ -z "$cur_p" -a -n "$old_p" ]; then cur_p=$old_p fi if [ -n "$URB_YES" -a -n "$cur_p" ]; then case "$URB_DONE_LIST" in *:${dep_port#$pd/}:*) continue ;; esac if grep -q $cur_p $MASTER_RB_LIST; then if ! check_interactive $cur_p ; then continue fi if [ -z "$RESTART" -a -z "$FORCE" ]; then update_port $cur_p || return 1 else check_for_updates $cur_p || return 1 fi continue fi fi if [ -n "$cur_p" ]; then check_for_updates $cur_p else if ! check_interactive $dep_port ; then continue fi update_port -p $dep_port fi done if [ -n "$CONFIG_ONLY" ]; then echo "===>>> Recursive 'make config' check complete for $portdir" else echo "===>>> Dependency check complete for $portdir" echo '' fi [ -n "$SHOW_WORK" ] && safe_exit } unset_recursive_config () { unset CONFIG_SEEN_LIST CONFIG_ONLY } req_by_error () { local DISCARD echo "===>>> WARNING! $pdb/$1/+REQUIRED_BY " echo "===>>> shows that $2 requires $1, but " echo "===>>> $2 does not seem to be installed" echo -n "===>>> Press Enter to proceed " read DISCARD } find_and_delete_distfiles () { # old_distpattern is used for subsequent invocations of the function local distpattern file DELORNOT distpattern=${1%[_-]*} [ "$distpattern" = "$old_distpattern" ] && return 0 for file in ${distpattern}*; do # This generally means the pattern did not match case "$file" in *\*) old_distpattern=$distpattern find_and_delete_distfiles ${distpattern} continue ;; esac case "$distfiles" in *${file}*) if [ -n "$VERBOSE" -a -z "$do_delete" ]; then echo "===>>> Keeping current distfile: $file" fi continue # Do not delete current version ;; *) [ ! -d "$file" ] || continue if [ -e "$DI_FILES" ]; then grep -q \(${file}\) $DI_FILES && continue fi if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then echo "===>>> Deleting stale distfile: $file" rm -f $file continue fi echo -n "===>>> Delete $file? [n] " read DELORNOT case "$DELORNOT" in [yY]) rm -f $file ;; esac ;; esac done } delete_stale_distfiles () { # distfiles is used globally # inherit distdir from the environment, but only modify our copy local distdir dist_subdir file DELORNOT distfile dist_subdir=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V DIST_SUBDIR` test -n "$dist_subdir" && distdir="${distdir}/${dist_subdir}" # Also used in find_and_delete_distfiles() to make sure # we do not delete the current set of distfiles distfiles=`make $PM_MAKE_ARGS -V ALLFILES` if [ -d "$distdir" ]; then cd $distdir || fail "cd to $distdir failed!" else echo '' ; echo '' echo "===>>> $distdir does not exist, therefore we" echo " will assume that all relevant distfiles are gone." echo '' return 0 fi # If these two match, it means that the distfiles in the +CONTENTS # file are the current set, so do not delete them. if [ ! "$cont_distfiles" = "${distfiles% }" ]; then for file in $cont_distfiles; do [ -f $file ] || continue if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then echo "===>>> Deleting stale distfile: $file" rm -f $file continue fi echo -n "===>>> Delete $file? [n] " read DELORNOT case "$DELORNOT" in [yY]) rm -f $file ;; esac done fi # Eventually we will hide this behind an "aggressive distfile purge" # flag, but until the DISTFILE stuff is well populated in +CONTENTS, # keep doing it both ways. for distfile in $distfiles; do find_and_delete_distfiles $distfile done } delete_all_distfiles () { # do_delete is used globally local DELORNOT if ! cd $pd/$1 2>/dev/null; then echo '' echo "===>>> No $pd/$1 to cd to in order to delete" echo " old distfiles, remove by hand if desired" else if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then echo "===>>> Deleting all distfiles for $1" do_delete=1 else echo -n "===>>> Delete all distfiles for ${1}? [n] " read DELORNOT case "$DELORNOT" in [yY]) do_delete=1 ;; *) delete_stale_distfiles ;; esac fi if [ -n "$do_delete" ]; then delete_stale_distfiles rm -f $distfiles find $pd/distfiles/ -type d -empty -delete fi fi } backup_package () { # bu_pkg_name is used globally echo "===>>> Creating a backup package for old version $1" if pkg_create -b $1; then bu_pkg_name=`echo ${1}.*` mv $bu_pkg_name $pkgrep/ && echo " ===>>> Package can be found in $pkgrep" else local PROCEED if [ -z "$UNATTENDED" ]; then echo '' echo "===>>> Backup package creation failed for ${1}!" echo '' echo "===>>> Ignore this error [i]" echo "===>>> Abort update [a]" echo '' echo -n "===>>> How would you like to proceed? [i] " read PROCEED case "$PROCEED" in a) fail "Backup package creation failed for $1" ;; esac else fail "Backup package creation failed for $1" fi fi } # Read a global rc file first if [ -r /etc/portmaster.rc ]; then . /etc/portmaster.rc fi # Read a local one next, and allow the command line to override if [ -r "$HOME/.portmasterrc" ]; then . $HOME/.portmasterrc fi # Set default values here so that they can be overriden above if [ -z "$pd" ]; then pd=`make BEFOREPORTMK=yes -f/usr/share/mk/bsd.port.mk -V PORTSDIR` export pd fi if [ -z "$pdb" ]; then pdb=`make -f/usr/share/mk/bsd.port.mk -V PKG_DBDIR` export pdb fi if [ -z "$distdir" ]; then distdir=`make BEFOREPORTMK=yes -f/usr/share/mk/bsd.port.mk -V DISTDIR` export distdir fi case "$1" in --clean-distfiles) CLEAN_DISTFILES=yes ;; --clean-distfiles-all) CLEAN_DISTFILES=yes ; ALL=yes ;; --show-work) SHOW_WORK=yes ; RECURSE_THOROUGH=yes ; shift ;; --force-config) FORCE_CONFIG=yes ; export FORCE_CONFIG ; shift ;; esac read_distinfos () { local origin distinfo disc1 file disc2 for pkg in ${pdb}/*; do [ -d $pkg ] || continue origin=`origin_from_pdb $pkg` if [ ! -d "$pd/$origin" ]; then find_moved_port $origin >/dev/null || continue origin=$newportdir fi cd $pd/$origin 2>/dev/null || continue distinfo=`make $PM_MAKE_ARGS -V MD5_FILE` if [ -s "$distinfo" ]; then while read disc1 file disc2; do echo $file >> $DI_FILES done < $distinfo fi done } if [ -n "$CLEAN_DISTFILES" ]; then # Set the file name here because this function is # usually called in a subshell. DI_FILES=`mktemp -t DI-FILES-$PARENT_PID` export DI_FILES echo "===>>> Gathering distinfo list for installed ports" read_distinfos echo "===>>> Checking for stale distfiles" for df in `find $distdir -type f`; do f=${df#$distdir/} if ! grep -q \(${f}\) $DI_FILES; then if [ -n "$ALL" ]; then echo "===>>> Deleting $f" rm $df else echo -n "===>>> Delete stale file: ${f}? [y] " read DEL_OR_NOT case "$DEL_OR_NOT" in [nN]*) continue ;; *) rm $df ;; esac fi fi done safe_exit fi # Save switches for potential child processes while getopts 'BCDGLRabde:fghilm:nop:r:stuvwx:' COMMAND_LINE_ARGUMENT ; do case "${COMMAND_LINE_ARGUMENT}" in B) NO_BACKUP=yes; ARGS="-B $ARGS" ;; C) DONT_PRE_CLEAN=yes; ARGS="-C $ARGS" ;; D) DONT_SCRUB_DISTFILES=yes; ARGS="-D $ARGS" ;; G) NO_RECURSIVE_CONFIG=yes; unset FORCE_CONFIG ; ARGS="-G $ARGS" ;; L) LIST_PLUS=yes ;; R) RESTART=yes ; ARGS="-R $ARGS" ;; a) UPDATE_ALL=yes ;; b) BACKUP=yes; ARGS="-b $ARGS" ;; d) ALWAYS_SCRUB_DISTFILES=yes; ARGS="-d $ARGS" ;; e) EXPUNGE=$OPTARG ;; f) FORCE=yes FORCE_DONE_LIST=':' export FORCE FORCE_DONE_LIST ;; g) MAKE_PACKAGE=yes; ARGS="-g $ARGS" ;; h) usage 0 ;; i) INTERACTIVE_UPDATE=yes; ARGS="-i $ARGS" ;; l) LIST=yes ;; m) PM_MAKE_ARGS=$OPTARG export PM_MAKE_ARGS # For 'make checksum' ARGS="-m $PM_MAKE_ARGS $ARGS" ;; n) NO_ACTION=yes; ARGS="-n $ARGS" ;; o) REPLACE_ORIGIN=yes ;; p) portdir="${OPTARG#$pd/}" ; portdir=${portdir%/} ;; r) UPDATE_REQ_BYS=yes; upg_port=$OPTARG ;; s) CLEAN_STALE=yes ;; t) RECURSE_THOROUGH=yes; ARGS="-t $ARGS" ;; u) UNATTENDED=yes; ARGS="-u $ARGS" ;; v) VERBOSE=yes; ARGS="-v $ARGS" ;; w) SAVE_SHARED=yes; ARGS="-w $ARGS" ;; x) EXCL=$OPTARG ; ARGS="-x $EXCL $ARGS" ;; *) usage ;; esac done shift $(( $OPTIND - 1 )) : ${EXCL:=Ishouldthinkofsomethingclevertosayhere} if [ -n "$LIST" -o -n "$LIST_PLUS" ]; then ports_by_category num_roots=0 num_trunks=0 num_branches=0 num_leaves=0 num_updates=0 echo "===>>> Root ports (No dependencies, not depended on)" for port in $roots; do echo "===>>> ${port##*/}" [ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list num_roots=$(( $num_roots + 1 )) done echo "===>>> $num_roots root ports" echo '' echo "===>>> Trunk ports (No dependencies, are depended on)" for port in $trunks; do echo "===>>> ${port##*/}" [ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list num_trunks=$(( $num_trunks + 1 )) done echo "===>>> $num_trunks trunk ports" echo '' echo "===>>> Branch ports (Have dependencies, are depended on)" for port in $branches; do echo "===>>> ${port##*/}" [ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list num_branches=$(( $num_branches + 1 )) done echo "===>>> $num_branches branch ports" echo '' echo "===>>> Leaf ports (Have dependencies, not depended on)" for port in $leaves; do echo "===>>> ${port##*/}" [ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list num_leaves=$(( $num_leaves + 1 )) done echo "===>>> $num_leaves leaf ports" echo '' num_ports=$(( $num_roots + $num_trunks + $num_branches + $num_leaves )) 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" fi exit 0 fi find_contents_distfiles () { [ -n "$DONT_SCRUB_DISTFILES" ] && return 0 # cont_distfiles is used globally local file for file in `grep DISTFILE $pdb/$1/+CONTENTS | cut -f2 -d:`; do cont_distfiles="${cont_distfiles} ${file#*/}" done cont_distfiles=${cont_distfiles# } } if [ -n "$EXPUNGE" ]; then if [ -d "$pdb/$EXPUNGE" ]; then origin=`origin_from_pdb $pdb/$EXPUNGE` deplist=`grep -l DEPORIGIN:$origin$ $pdb/*/+CONTENTS` if [ -n "$deplist" ]; then echo "===>>> Warning: ports with dependencies on ${EXPUNGE}:" for dep in $deplist; do echo ${dep%/+CON*}; done exit 1 fi [ -n "$BACKUP" ] && backup_package $EXPUNGE find_contents_distfiles $EXPUNGE echo "===>>> Running pkg_delete -f $EXPUNGE" pkg_delete -f $EXPUNGE if [ -z "$DONT_SCRUB_DISTFILES" ]; then delete_all_distfiles $origin fi exec $0 -s $ARGS else fail "No such directory/port: $pdb/$EXPUNGE" fi exit 0 # Should not be reached fi if [ -n "$CLEAN_STALE" ]; then if [ -z "$do_not_delete" ]; then do_not_delete=':' export do_not_delete fi for file in `find $pdb/ -name \+REQUIRED_BY -empty` ; do dir="${file%/+REQUIRED_BY}" iport=${dir#$pdb/} case "$do_not_delete" in *:${iport}:*) continue ;; esac echo '' origin=`origin_from_pdb $dir` deplist=`grep -l DEPORIGIN:$origin$ $pdb/*/+CONTENTS` if [ -n "$deplist" ]; then echo "===>>> Warning: unrecorded dependencies on ${iport}:" for dep in $deplist; do echo ${dep%/+CON*}; done continue fi pkg_info $iport echo -n "===>>> ${iport} is no longer depended on, delete? [n] " read YESNO case "$YESNO" in [yY]) [ -n "$BACKUP" ] && backup_package $iport find_contents_distfiles $iport echo "===>>> Running pkg_delete -f $iport" pkg_delete -f ${iport} if [ -z "$DONT_SCRUB_DISTFILES" ]; then delete_all_distfiles $origin fi exec $0 -s $ARGS ;; *) echo -n " ===>>> Remove empty +REQUIRED_BY file? [n] " read DELORNOT case "$DELORNOT" in [yY]) rm -f $file ;; *) do_not_delete="${do_not_delete}${iport}:" ;; esac ;; esac done exit 0 fi test -n "$FORCE" && unset INTERACTIVE_UPDATE if [ -n "$UNATTENDED" ]; then unset INTERACTIVE_UPDATE if [ -z "$DONT_SCRUB_DISTFILES" -a -z "$ALWAYS_SCRUB_DISTFILES" ]; then ALWAYS_SCRUB_DISTFILES=yes ARGS="-d $ARGS" fi fi if [ "$$" -eq "$PARENT_PID" ]; then CURRENT_DEPS_O=':' CURRENT_DEPS_I=':' IGNOREME_YES=':' DISPLAY_LIST='' IPC_SAVE=`mktemp -t ipc_save-$PARENT_PID` export CURRENT_DEPS_O CURRENT_DEPS_I IGNOREME_YES DISPLAY_LIST IPC_SAVE PORTS_PREFIX=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -f/usr/share/mk/bsd.port.mk -VPREFIX` export PORTS_PREFIX if [ -n "$INTERACTIVE_UPDATE" ]; then INTERACTIVE_YES=':' INTERACTIVE_NO=':' export INTERACTIVE_YES INTERACTIVE_NO fi if [ -n "$UPDATE_REQ_BYS" ]; then URB_DONE_LIST=':' export URB_DONE_LIST fi if [ -n "$UPDATE_REQ_BYS" -o -n "$FORCE" ]; then if [ -z "$RESTART" ]; then find $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete fi fi if [ -z "$CONFIG_ONLY" -a -z "$NO_RECURSIVE_CONFIG" ]; then NO_DEP_UPDATES=`mktemp -t no_dep_updates-$PARENT_PID` CONFIG_SEEN_LIST=':' CONFIG_ONLY=yes export CONFIG_SEEN_LIST CONFIG_ONLY fi if [ -z "$NO_BACKUP" ]; then pkgrep=`make $PM_MAKE_ARGS -f/usr/share/mk/bsd.port.mk -VPKGREPOSITORY` export pkgrep mkdir -p $pkgrep if [ -z "$BACKUP" ]; then touch ${TMPDIR}/f-${PARENT_PID}-package-flag fi fi if [ $# -gt 1 -a -z "$REPLACE_ORIGIN" ]; then if [ -z "$NO_RECURSIVE_CONFIG" ]; then for port in $@; do ($0 $ARGS $port) || fail "Update for $port failed" . $IPC_SAVE done unset_recursive_config echo '' echo "===>>> Starting build for ports: <<<===" echo "===>>> $@ <<<===" echo '' fi for port in $@; do ($0 $ARGS $port) || fail "Update for $port failed" . $IPC_SAVE done safe_exit fi else # Zero out this file so that we can save our data to it safely > $IPC_SAVE fi if [ -n "$UPDATE_ALL" ]; then # Set the file name here so it's visible to the parent DI_FILES=`mktemp -t DI-FILES-$PARENT_PID` export DI_FILES echo "===>>> Gathering distinfo list for installed ports in background" (read_distinfos)& echo "===>>> Starting check of installed ports for available updates" ports_by_category if [ -n "$CONFIG_ONLY" ]; then echo "===>>> Checking ports for recursive 'make config'" for pkg in $roots $trunks $branches $leaves; do test -n "$VERBOSE" && echo "===>>> Checking installed port: ${pkg#$pdb/}" case "$pkg" in *${EXCL}*) test -n "$VERBOSE" && echo "===>>> Skipping ${pkg#$pdb/} because it matches the pattern: *${EXCL}*" continue ;; esac case "$CURRENT_DEPS_I" in *:${pkg#$pdb/}:*) continue ;; esac orig=`origin_from_pdb $pkg` case "$CONFIG_SEEN_LIST" in *:${orig}:*) continue ;; esac CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${orig}:" check_for_updates ${pkg#$pdb/} || fail 'Update failed' done if [ -e "$NO_DEP_UPDATES" ]; then echo "===>>> The 'make config' check revealed no ports to update" safe_exit fi unset_recursive_config echo '' echo "===>>> Starting build for ports that need updating <<<===" echo '' fi BUILDING=yes export BUILDING for pkg in $roots $trunks $branches $leaves; do case "$pkg" in *${EXCL}*) test -n "$VERBOSE" && echo "===>>> Skipping ${pkg#$pdb/} because it matches the pattern: *${EXCL}*" continue ;; esac if [ ! -d "$pkg" ]; then # This port probably got updated as a dependency # for something else continue fi if [ -n "$FORCE" ]; then p=`origin_from_pdb $pkg` case "$FORCE_DONE_LIST" in *:${p}:*) test -n "$VERBOSE" && echo "===>>> Update for $p already done" continue ;; esac if [ -e "${pkg}/PM_UPGRADE_DONE_FLAG" ]; then test -n "$VERBOSE" && echo "===>>> Update for $p already done" continue fi echo "===>>> Forcing update for ${pkg#$pdb/}" update_port ${pkg#$pdb/} continue else test -n "$VERBOSE" && echo "===>>> Checking installed port: ${pkg#$pdb/}" fi case "$CURRENT_DEPS_I" in *:${pkg#$pdb/}:*) continue ;; esac check_for_updates ${pkg#$pdb/} || fail 'Update failed' done echo "===>>> Update check of installed ports complete" safe_exit fi if [ -n "$REPLACE_ORIGIN" ]; then portdir="${1#$pd/}" portdir="${portdir%/}" newportdir=$portdir if [ -d "$pdb/$2" ]; then # Handle the portmaster'ish way to specify the port upg_port=$2 else # Handle existing portupgrade syntax upg_port=`grep -l " ORIGIN:${2#$pd/}$" $pdb/*/+CONTENTS` [ -n "$upg_port" ] || upg_port=`grep -l " ORIGIN:${2#$pd/}" $pdb/*/+CONTENTS` [ -n "$upg_port" ] || fail "Cannot find an installed port with ORIGIN $2" upg_port="${upg_port%/+CONTENTS}" upg_port="${upg_port#$pdb/}" fi oldportdir=`origin_from_pdb $pdb/$upg_port` fi # Exercised in the common case of not using -p option case "$portdir" in '') argv=${1%/} case "$argv" in '') test -z "$UPDATE_REQ_BYS" && usage ;; ${pd}/*) portdir="${argv#$pd/}" ;; /*) upg_port="${argv##*/}" ;; \.) portdir="${PWD##*/ports/}" ;; *) if [ -d "${pd}/${argv}" ]; then portdir=$argv else upg_port=$argv fi ;; esac esac case "$upg_port" in '') test -n "$portdir" || usage old_port_dir=`iport_from_origin ${portdir}` if [ -n "$old_port_dir" ]; then upg_port="${old_port_dir}" fi ;; *) if [ ! -d "$pdb/$upg_port" ]; then glob_dirs=`find $pdb -type d -name ${upg_port}\*` case "$glob_dirs" in *\*) fail "$upg_port did not match an installed port" ;; *) for dir in $glob_dirs; do echo -n "===>>> Update ${dir#$pdb/}? [n] " read GLOB_DIR case "$GLOB_DIR" in [yY]) upg_port=${dir#$pdb/} selected=yes break ;; esac done test -n "$selected" || usage ;; esac fi echo "===>>> Port to upgrade: $upg_port" if [ -z "$portdir" ]; then portdir=`origin_from_pdb $pdb/$upg_port` [ -n "$portdir" ] || fail "No ORIGIN in $pdb/$upg_port/+CONTENTS" fi ;; esac if [ -e "$pdb/$upg_port/+IGNOREME" ]; then echo '' if [ -z "$UNATTENDED" ]; then if [ -z "$BUILDING" ]; then echo "===>>> $upg_port has an +IGNOREME file" echo -n "===>>> Update anyway? [n] " read UPD_OR_NOT case "$UPD_OR_NOT" in [yY]*) IGNOREME_YES="${IGNOREME_YES}${upg_port}:" ;; *) safe_exit ;; esac else case "$IGNOREME_YES" in *:${upg_port}:*) ;; *) safe_exit ;; esac fi else echo "===>>> $upg_port has an +IGNOREME file, ignoring" safe_exit fi fi if [ -d "$pd/$portdir" ]; then echo "===>>> Port directory: $pd/$portdir" else find_moved_port $portdir || usage portdir=$newportdir fi cd $pd/$portdir || usage for state in FORBIDDEN BROKEN IGNORE; do state_set=`make -V $state` if [ -n "$state_set" ]; then echo "===>>> This port is marked $state:" echo "===>>> $state_set" echo "===>>> If you are sure you can build it, remove the" echo " $state line in the Makefile and try again." safe_exit 1 fi done if [ "$$" -eq "$PARENT_PID" -a -z "$SHOW_WORK" ]; then # Set the file name here so it's visible to the parent DI_FILES=`mktemp -t DI-FILES-$PARENT_PID` export DI_FILES echo "===>>> Gathering distinfo list for installed ports in background" (read_distinfos)& fi # Do these things first time through, with or without 'make config' if [ -z "$BUILDING" -a -z "$SHOW_WORK" ]; then dofetch () { echo "===>>> Launching 'make checksum' for $portdir in background" fetchlog=`mktemp -t fetchlog-${PARENT_PID}-${portdir##*/}` (make -DBATCH $PM_MAKE_ARGS checksum >> $fetchlog 2>&1 && { rm -f $fetchlog; \ rm -f ${TMPDIR}/f-${PARENT_PID}-*-${portdir##*/}.*; exit 0;} allfiles=`make $PM_MAKE_ARGS -V ALLFILES` make $PM_MAKE_ARGS delete-distfiles RESTRICTED_FILES="${allfiles}" \ >> $fetchlog 2>&1 && echo "===>>> RE-STARTING FETCH <<<===" >> $fetchlog make $PM_MAKE_ARGS checksum >> $fetchlog 2>&1; \ rm -f ${TMPDIR}/f-${PARENT_PID}-*-${portdir##*/}.*; \ rm -f $fetchlog)& echo "MCS_CHILD_PID $!" >> $fetchlog } distfiles=`make $PM_MAKE_ARGS -V ALLFILES` for file in $distfiles; do flag_file=f-${PARENT_PID}-${file} if ! ls ${TMPDIR}/${flag_file}-* >/dev/null 2>&1; then mktemp -t ${flag_file}-${portdir##*/} >/dev/null else DONT_FETCH=yes break fi done test -z "$DONT_FETCH" && dofetch TESTINT=`make -V IS_INTERACTIVE` if [ -n "$TESTINT" ]; then echo '' echo "===>>> Warning: $portdir is interactive, and will likely" echo " reqire attenton during the build" echo '' echo -n "===>>> Press the [Enter] or [Return] key to continue " read DISCARD echo '' fi if [ -n "$UPDATE_REQ_BYS" ]; then MASTER_RB_LIST=`mktemp -t master_rb_list-${PARENT_PID}` export MASTER_RB_LIST if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then old_rb=$pdb/$upg_port/+REQUIRED_BY fi upg_origin=`origin_from_pdb $pdb/$upg_port` grep -l DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS | cut -f 5 -d '/' | sort -u - $old_rb > $MASTER_RB_LIST fi fi if [ -n "$CONFIG_ONLY" ]; then config_type=config-conditional test -n "$FORCE_CONFIG" && config_type=config make $PM_MAKE_ARGS $config_type CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${portdir}:" if [ -z "$RECURSE_THOROUGH" ]; then dependency_check 'build-depends-list run-depends-list' else dependency_check all-depends-list fi if [ ! "$$" -eq "$PARENT_PID" ]; then # Save state for the parent process to read back in echo "CONFIG_SEEN_LIST='$CONFIG_SEEN_LIST'" > $IPC_SAVE safe_exit else if [ -n "$UPDATE_REQ_BYS" ]; then URB_YES=yes ; export URB_YES echo '' echo "===>>> Checking ports that depend on $upg_port" for req_by in `cat $MASTER_RB_LIST`; do case "$req_by" in *${EXCL}*) test -n "$VERBOSE" && echo "===>>> Skipping $req_by because it matches the pattern: *${EXCL}*" continue ;; esac rb_origin=`origin_from_pdb $pdb/$req_by` case "$URB_DONE_LIST" in *:${rb_origin}:*) continue ;; esac test -n "$VERBOSE" && echo "===>>> $upg_port is required by $req_by" if [ ! -d "$pdb/$req_by" ]; then # A failure here is probably just a # stale dependency, but warn the user. req_by_error $upg_port $req_by continue fi if ! check_interactive ${req_by} ; then continue fi if [ -z "$RESTART" -a -z "$FORCE" ]; then update_port $req_by else check_for_updates $req_by fi done rm -f $MASTER_RB_LIST echo "===>>> Done checking ports that depend on $upg_port" unset URB_YES URB_DONE_LIST=':' fi unset_recursive_config fi echo '' echo "===>>> Starting build for $portdir <<<===" echo '' fi BUILDING=yes export BUILDING cd $pd/$portdir if [ ! -e "$NO_DEP_UPDATES" ]; then if [ -z "$RECURSE_THOROUGH" ]; then echo "===>>> Starting check for build dependencies" dependency_check build-depends-list else echo "===>>> Starting check for all dependencies" dependency_check all-depends-list fi else if [ -z "$NO_RECURSIVE_CONFIG" ]; then echo "===>>> The 'make config' check revealed no dependencies to update" echo '' fi fi if [ -n "$NO_ACTION" ]; then test -n "$VERBOSE" && echo "===>>> Build canceled due to -n flag" safe_exit fi # In case we went elsewhere in the dependency check cd $pd/$portdir case "$DONT_PRE_CLEAN" in '') make $PM_MAKE_ARGS clean NOCLEANDEPENDS=yes || fail 'make clean failed' ;; esac fl_read=`echo ${TMPDIR}/fetchlog-${PARENT_PID}-${portdir##*/}.*` while [ -f "$fl_read" ]; do echo '' echo "===>>> Waiting on fetch & checksum for $portdir <<<===" tail -10 $fl_read 2>/dev/null | egrep -v '^$|MCS_CHILD_PID' echo '' echo "===>>> Waiting on fetch & checksum for $portdir <<<===" sleep 5 done make $PM_MAKE_ARGS || fail "make failed for $portdir" new_port=`make $PM_MAKE_ARGS -V PKGNAME` prefix=`make $PM_MAKE_ARGS -V PKGNAMEPREFIX` portname=`make $PM_MAKE_ARGS -V PORTNAME` suffix=`make $PM_MAKE_ARGS -V PKGNAMESUFFIX` short_port="${prefix}${portname}${suffix}" # Check for dependencies here in case +REQUIRED_BY is not up to date or missing grep_deps=`mktemp -t grep-deps-${short_port}` upg_origin=$portdir if [ -n "$upg_port" ]; then upg_origin=`origin_from_pdb $pdb/$upg_port` fi grep -l DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS | cut -f 5 -d '/' | sort -u > $grep_deps if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then req_deps=`mktemp -t req-deps-${short_port}` sort -u $pdb/$upg_port/+REQUIRED_BY > $req_deps fi if [ ! -s "$grep_deps" -a ! -s "$req_deps" ]; then if [ -n "$upg_port" ]; then echo "===>>> $upg_port is not depended on by any other ports" fi elif [ -s "$grep_deps" -a -s "$req_deps" ]; then if ! cmp -s $grep_deps $req_deps; then update_reqfile fi elif [ -s "$grep_deps" -a ! -s "$req_deps" ]; then dep_warn echo -n "===>>> Install these as the new +REQUIRED_BY file? [n] " if [ -z "$UNATTENDED" ]; then read INSTALLDEPS case "$INSTALLDEPS" in [yY]) req_deps=`mktemp -t req-deps-${short_port}` mv $grep_deps $req_deps ; unset grep_deps ;; esac else echo "===>>> Default (no) in unattended mode" fi else # It should not happen that req_deps exist but grep_deps does not echo '' echo "===>>> $pdb/$upg_port/+REQUIRED_BY indicates" echo " a dependency on this port, but no other ports have" echo " it recorded. If that file does not contain any valid" echo " dependency data, try removing it and then start again." fail "Stale dependency data in $pdb/$upg_port/+REQUIRED_BY" fi # Ignore if no old port exists if [ -n "$upg_port" ]; then find_contents_distfiles $upg_port UPGRADE_PORT=$upg_port UPGRADE_PORT_VER=`echo $UPGRADE_PORT | sed 's#.*-\(.*\)#\1#'` export UPGRADE_PORT UPGRADE_PORT_VER if [ -z "$NO_BACKUP" ]; then backup_package $upg_port fi if [ -n "$SAVE_SHARED" ]; then ldconfig_out=`mktemp -t f-${PARENT_PID}-ldconfig` ldconfig -r | sed 's#.* ##' | grep -v ^${PORTS_PREFIX}/lib/compat > $ldconfig_out mkdir -p ${PORTS_PREFIX}/lib/compat/pkg for file in `pkg_info -q -L $upg_port | sort - $ldconfig_out | \ uniq -d`; do cp -p $file ${PORTS_PREFIX}/lib/compat/pkg/ done ldconfig -m ${PORTS_PREFIX}/lib/compat/pkg fi pkg_delete -f $upg_port || fail 'pkg_delete failed' if [ -n "$REPLACE_ORIGIN" ]; then installed_newport=`iport_from_origin ${newportdir}` if [ -n "$installed_newport" ]; then pkg_delete -f $installed_newport fi fi fi if [ -z "$RECURSE_THOROUGH" -a ! -e "$NO_DEP_UPDATES" ]; then echo "===>>> Starting check for runtime dependencies" dependency_check run-depends-list fi # In case we went elsewhere in the dependency check cd $pd/$portdir make $PM_MAKE_ARGS install || { if [ -z "$NO_BACKUP" -a -n "$upg_port" ]; then echo '' echo "===>>> A backup package for $portdir should be located in $pkgrep" fi fail "Installation of new port failed";} # Remove saved libs that match newly installed files pkg_info -q -L $new_port | while read file; do if [ -e "${PORTS_PREFIX}/lib/compat/pkg/${file##*/}" ]; then unlink ${PORTS_PREFIX}/lib/compat/pkg/${file##*/} fi done test -d "${PORTS_PREFIX}/lib/compat/pkg" && ldconfig -m ${PORTS_PREFIX}/lib/compat/pkg # Implement storage of distfile information in the +CONTENTS file in the # same way that it will (hopefully, soon?) be implemented in bsd.port.mk # See http://www.freebsd.org/cgi/query-pr.cgi?pr=106483 if ! grep -q DISTFILE $pdb/$new_port/+CONTENTS; then ds=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V DIST_SUBDIR` test -n "$ds" && ds="${ds}/" allfiles=`make $PM_MAKE_ARGS -V ALLFILES` distinfo=`make $PM_MAKE_ARGS -V MD5_FILE` for file in $allfiles; do size=`grep "^SIZE (${ds}${file})" $distinfo | cut -f4 -d' '` sha256=`grep "^SHA256 (${ds}${file})" $distinfo | cut -f4 -d' '` md5=`grep "^MD5 (${ds}${file})" $distinfo | cut -f4 -d' '` echo "@comment DISTFILE:${ds}${file}:SIZE=${size}:SHA256=${sha256}:MD5=${md5}" >> $pdb/$new_port/+CONTENTS done fi if [ -n "$MAKE_PACKAGE" ]; then echo "===>>> Creating a package for new version $new_port" make $PM_MAKE_ARGS package || fail 'Package creation of new port failed' echo " ===>>> Package can be found in $pkgrep" fi make $PM_MAKE_ARGS clean NOCLEANDEPENDS=yes # By now, if this file exists, it should be authoritative if [ -s "$req_deps" ]; then update_dep_entries () { local upg_port test -n "$1" && upg_port=$1 echo "===>>> Updating package dependency entry for each dependent port" while read dep_port; do dep_port_contents="$pdb/$dep_port/+CONTENTS" [ -e "$pdb/$dep_port/+CONTENTS" ] || continue if grep -q "@pkgdep $upg_port" $dep_port_contents; then update_contents $upg_port $new_port else echo -n "===>>> In ${dep_port}" echo " no entry for $upg_port, trying $short_port" update_contents "$short_port.*" $new_port fi done < $req_deps } update_dep_entries mv $req_deps $pdb/$new_port/+REQUIRED_BY unset req_deps chmod 644 $pdb/$new_port/+REQUIRED_BY if [ -n "$REPLACE_ORIGIN" ]; then req_deps=`mktemp -t req-deps-${short_port}` grep -l DEPORIGIN:$newportdir$ $pdb/*/+CONTENTS | cut -f 5 -d '/' | sort -u > $req_deps update_dep_entries $new_port cat $req_deps >> $pdb/$new_port/+REQUIRED_BY fi fi echo '' test -z "$upg_port" && upg_port=$portdir echo "===>>> Upgrade for $upg_port to $new_port succeeded" test -n "$FORCE" && FORCE_DONE_LIST="${FORCE_DONE_LIST}${portdir}:" test -e "$pdb/$new_port/+DISPLAY" && DISPLAY_LIST="${DISPLAY_LIST}$new_port/+DISPLAY " if [ -n "$URB_YES" -o -n "$UPDATE_REQ_BYS" -o -n "$FORCE" ]; then touch $pdb/$new_port/PM_UPGRADE_DONE_FLAG fi if [ -z "$DONT_SCRUB_DISTFILES" ]; then if [ -z "$oldportdir" ]; then delete_stale_distfiles else delete_all_distfiles ${oldportdir} cd $pd/$newportdir && delete_stale_distfiles fi fi if [ -n "$UPDATE_REQ_BYS" -a -s "$pdb/$new_port/+REQUIRED_BY" ]; then URB_YES=yes ; export URB_YES MASTER_RB_LIST=$pdb/$new_port/+REQUIRED_BY echo '' echo "===>>> Updating ports that depend on $new_port" for req_by in `cat $pdb/$new_port/+REQUIRED_BY`; do if [ ! -d "$pdb/$req_by" ]; then # Since the dependency list was probably updated as # a result of updating the parent port, a missing # directory here is likely the result of the port # being updated as a dependency for something else. continue fi case "$req_by" in *${EXCL}*) test -n "$VERBOSE" && echo "===>>> Skipping $req_by because it matches the pattern: *${EXCL}*" continue ;; esac p=`origin_from_pdb $pdb/$req_by` case "$URB_DONE_LIST" in *:${p}:*) continue ;; esac case "$FORCE_DONE_LIST" in *:${p}:*) test -n "$VERBOSE" && echo "===>>> Update for $p already done" continue ;; esac if ! check_interactive ${req_by} ; then continue fi test -n "$VERBOSE" && echo "===>>> $new_port is required by $req_by" if [ -z "$RESTART" -a -z "$FORCE" ]; then update_port $req_by else check_for_updates $req_by fi done echo "===>>> Done updating ports that depend on $new_port" fi safe_exit #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Copyright (c) 2005-2007 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.