Index: user/dougb/portmaster/portmaster =================================================================== --- user/dougb/portmaster/portmaster (revision 209087) +++ user/dougb/portmaster/portmaster (revision 209088) @@ -1,3580 +1,3582 @@ #!/bin/sh # Copyright (c) 2005-2010 Douglas Barton, All rights reserved # Please see detailed copyright below trap trap_exit INT # Initialize crucial values for the parent, and export them for the children if [ -z "$PM_PARENT_PID" ]; then PM_PARENT_PID=$$ : ${TMPDIR:=/tmp} 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 -a ! -L /usr/X11R6 ] && PATH=$PATH:/usr/X11R6/bin if [ -n "$CCACHE_PATH" ]; then if [ -z "$NOCCACHE" ]; then PATH="/usr/local/libexec/ccache:$PATH" fi fi export PM_PARENT_PID TMPDIR UPGRADE_TOOL PATH set -o allexport # Read a global rc file first 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 is deprecated, and will be removed in a future version.' echo '' ; echo ' The proper location for this file is /usr/local/etc' echo '' ; sleep 5 ; . /etc/portmaster.rc fi [ -r /usr/local/etc/portmaster.rc ] && . /usr/local/etc/portmaster.rc # Read a local one next, and allow the command line to override [ -r "$HOME/.portmasterrc" ] && . $HOME/.portmasterrc set +o allexport my_environment=`set` # If we are already root, unset this to avoid potential conflict euid=`ps -o uid $$` ; euid=${euid##* } [ "$euid" -eq 0 ] && unset PM_SU_CMD PM_SU_VERBOSE unset euid fi umask 022 #=============== Begin functions we always want to have =============== version () { local cvs cvs='$FreeBSD$' cvs="${cvs#*,v }" ; cvs="${cvs#*/portmaster }" ; cvs="${cvs%% *}" echo '' [ "${cvs#$}" != 'FreeBSD$' ] && { echo "===>>> Version $cvs" ; return 0; } echo "===>>> Version unknown!" } fail () { echo '' ; echo "===>>> $*" ; echo "===>>> Aborting update" [ "$$" -eq "$PM_PARENT_PID" ] && trap_exit fail safe_exit 1 } trap_exit () { TRAP=trap 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 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 fi [ -n "$logs" ] && echo '' fi fi safe_exit 1 } kill_bad_children () { local mypgid pid ppid pgid command ; IFS=' ' mypgid=`ps -o pgid -p $PM_PARENT_PID` ; mypgid=${mypgid##*PGID[^0-9]} ps -axo pid,ppid,pgid,command | sed '1d' | while read pid ppid pgid command; do [ "$pid" -gt 25 ] || continue case "$ppid" in 1) case "$command" in *" $0 "*) pm_kill $pid ;; *'make -DBATCH checksum'*|*'/fetch '*|\[sh\]) pm_kill -9 $pid ;; esac ;; *) [ $pgid -eq $mypgid ] || continue case "$command" in *" $0 "*) [ $pid -ne $PM_PARENT_PID ] && pm_kill $pid ;; *'make -DBATCH checksum'*|*'/fetch '*|\[sh\]) pm_kill $pid ;; esac ;; esac done } parent_exit () { local files f show_list if [ -s "$DI_FILES" ]; then grep -q '%%%%%%%%%%%%' $DI_FILES || kill_bad_children fi [ -n "$FETCH_ONLY" -a -z "$FETCH_ONLY_DONE" ] && kill_bad_children if [ -z "$TRAP" ]; then if [ -n "$UPDATE_REQ_BYS" -o -n "$PM_FORCE" ]; then [ -n "$UPDATE_REQ_BYS" -o -n "$PM_FORCE" ] && 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 fi fi if [ -z "$BACKUP" -a -z "$NO_BACKUP" -a -n "$NB_DELETE" ]; then pm_sv Deleting safety packages for successful installs pm_cd $pbu || fail "Cannot cd to $pbu" pm_rm_s $NB_DELETE fi fi [ -n "$pbu" ] && pbu=`find $pbu -type d -empty 2>/dev/null` if [ -d "$pbu" ]; then pm_sv Removing empty backup package directory pm_rmdir_s $pbu fi for f in ${TMPDIR}/f-${PM_PARENT_PID}-*; do pm_unlink $f ; done case "$DISPLAY_LIST" in *' '*) if [ -n "$TRAP" ]; then echo "===>>> There are messages from installed ports to display," echo " but first take a moment to review the error messages" echo -n " above. Then press Enter when ready to proceed. " read DISCARD echo '' fi : ${PAGER:='less -e'} ( for f in $DISPLAY_LIST; do echo "===>>> pkg-message for $f" ; cat $pdb/$f/+DISPLAY ; echo '' done 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 ;; esac fi case "$show_list" in all) echo "===>>> The following actions were performed:" echo -e $INSTALLED_LIST ;; one) echo "===>>> $ilist complete" ; echo '' ;; esac fi if [ -n "$build_deps_il" ]; then echo "===>>> Deleting installed build-only dependencies" cd for f in $build_deps_il; do [ -n "$PM_VERBOSE" ] && echo " $f" pm_pkg_delete_s -f $f done echo '' fi } safe_exit () { if [ "$$" -eq "$PM_PARENT_PID" ]; then parent_exit else [ -n "$grep_deps" ] && pm_unlink $grep_deps # Save state for the parent process to read back in echo "CUR_DEPS='$CUR_DEPS'" >> $IPC_SAVE echo "dep_of_deps='$dep_of_deps'" >> $IPC_SAVE if [ -z "$CONFIG_ONLY" ]; 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 else # Do these here so +IGNOREME can modify them echo "num_of_deps='$num_of_deps'" >> $IPC_SAVE echo "build_l='$build_l'" >> $IPC_SAVE if [ -z "$NO_DEP_UPDATES" ]; then echo 'unset NO_DEP_UPDATES' >> $IPC_SAVE fi fi [ -z "$NO_BACKUP" -a -z "$BACKUP" ] && echo "NB_DELETE='$NB_DELETE'" >> $IPC_SAVE [ -n "$PM_MULTI_BUILT" ] && echo "PM_MULTI_BUILT='$PM_MULTI_BUILT'" >> $IPC_SAVE if [ -n "$INTERACTIVE_UPDATE" ]; then echo "INTERACTIVE_YES='$INTERACTIVE_YES'" >> $IPC_SAVE echo "INTERACTIVE_NO='$INTERACTIVE_NO'" >> $IPC_SAVE fi [ -n "$URB_YES" ] && echo "URB_DONE_LIST='$URB_DONE_LIST'" >> $IPC_SAVE fi exit ${1:-0} } usage () { 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 " [--no-confirm] [--no-term-title] [--no-index-fetch]" echo " [--index|--index-first|--index-only]" echo " [-m ] [-x ]" echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] " echo "${0##*/} [Common flags] Multiple full names/paths from $pdb|$pd" echo " and/or multiple globs from $pdb" echo '' 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##*/} [Common flags] -a" echo '' echo "${0##*/} -[l|L]" echo '' echo "${0##*/} [-b D|d] -e " echo "${0##*/} [-b D|d] -s" echo '' echo "${0##*/} [--force-config] [-aftv] -F" echo '' echo "${0##*/} --clean-distfiles" echo "${0##*/} --clean-distfiles-all" echo '' echo "${0##*/} --check-depends" echo '' echo "${0##*/} --check-port-dbdir [-v]" echo '' echo "${0##*/} --list-origins" echo '' echo "${0##*/} -h|--help" echo "${0##*/} --version" echo '' echo "--force-config 'make config' for all ports" echo "-C prevents 'make clean' from being run before building" echo "-G prevents recursive 'make config' (overrides --force-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 configure, 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 "-u DEPRECATED" echo '[-R] -f always rebuild ports (overrides -i)' echo '-i interactive update -- ask whether to rebuild ports' echo '-D no cleaning of distfiles' echo '-d always 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-[6-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 '--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 '-a check all ports, update as necessary' echo '' echo '--delete-build-only delete ports that are build-only dependencies' echo ' after a successful run, only if installed this run' 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 '-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 '[--force-config] [-aftv] -F fetch distfiles only (mutually exclusive of -G)' echo '' echo '--clean-distfiles offer to delete stale distfiles' echo '--clean-distfiles-all delete stale distfiles without prompting' echo '' echo '--check-depends cross-check and update dependency information for all ports' echo '' echo "--check-port-dbdir [-v] check for stale entries in $port_dbdir" echo '' echo "--list-origins list directories from $pd for root and leaf ports" 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} } pm_cd () { builtin cd $1 2>/dev/null || return 1; } pm_cd_pd () { builtin cd $pd/$1 2>/dev/null || fail "Cannot cd to port directory: $pd/$1"; } pm_kill () { /bin/kill $* >/dev/null 2>/dev/null; } pm_make () { ( unset -v CUR_DEPS INSTALLED_LIST PM_DEPTH; unset -v MASTER_RB_LIST CONFIG_SEEN_LIST; /usr/bin/make $PM_MAKE_ARGS $*; ); } pm_make_b () { /usr/bin/make $PM_MAKE_ARGS BEFOREPORTMK=bpm $*; } pm_mktemp () { /usr/bin/mktemp -t f-${PM_PARENT_PID}-$1 || fail "mktemp for $1 failed"; } pm_unlink () { /bin/test -e $1 && /bin/unlink $1; } # Superuser versions for commands that need root privileges # # The following are used once, so they have $PM_SU_CMD in line: # truncate, pkg_create, cp, /etc/rc.d/ldconfig, touch pm_find_s () { $PM_SU_CMD /usr/bin/find $*; } pm_install_s () { $PM_SU_CMD /usr/bin/install -o root \ -g wheel -m 644 $1 $2; } pm_make_s () { ( unset -v CUR_DEPS INSTALLED_LIST PM_DEPTH; unset -v MASTER_RB_LIST CONFIG_SEEN_LIST; $PM_SU_CMD /usr/bin/make $PM_MAKE_ARGS $*; ); } pm_mkdir_s () { $PM_SU_CMD /bin/mkdir -p $1; } pm_pkg_delete_s () { $PM_SU_CMD /usr/sbin/pkg_delete $*; } pm_rm_s () { $PM_SU_CMD /bin/rm $*; } pm_rmdir_s () { $PM_SU_CMD /bin/rmdir $*; } pm_unlink_s () { /bin/test -e $1 && $PM_SU_CMD /bin/unlink $1; } pm_sv () { [ -n "$PM_SU_VERBOSE" ] && echo "===>>> SU $*"; } #=============== End functions we always want to have =============== 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 "$1" in index) [ -n "$PM_INDEX_FIRST" -o -n "$PM_INDEX_ONLY" ] && fail $e1 ;; first) [ -n "$PM_INDEX" -o -n "$PM_INDEX_ONLY" ] && fail $e1 ;; only) [ -n "$PM_INDEX" -o -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 ;; -[A-Za-z0-9]*) newopts="$newopts $var" ;; --delete-build-only) PM_DEL_BUILD_ONLY=pm_dbo export PM_DEL_BUILD_ONLY ;; --no-confirm) PM_NO_CONFIRM=pm_no_confirm export PM_NO_CONFIRM ;; --no-term-title) PM_NO_TERM_TITLE=pm_no_term_title export PM_NO_TERM_TITLE ;; --no-index-fetch) PM_NO_INDEX_FETCH=pm_no_index_fetch ;; --index) cross_idx index ; PM_INDEX=pm_index ; export PM_INDEX ;; --index-first) cross_idx first ; PM_INDEX=pm_index PM_INDEX_FIRST=pm_index_first export PM_INDEX PM_INDEX_FIRST ;; --index-only) cross_idx only ; PM_INDEX=pm_index PM_INDEX_ONLY=pm_index_only export PM_INDEX PM_INDEX_ONLY ;; --help) usage 0 ;; --version) version ; exit 0 ;; --clean-distfiles) CLEAN_DISTFILES=clean_distfiles ;; --clean-distfiles-all) CLEAN_DISTFILES=clean_distfiles_all ; ALL=cda ;; --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 ; RECURSE_THOROUGH=thorough ;; --force-config) export FORCE_CONFIG=force_config ;; --*) echo "Illegal option $var" ; echo '' echo "===>>> Try ${0##*/} --help"; exit 1 ;; *) newopts="$newopts $var" ;; esac done unset var [ -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' # Do this here so it can use the fancy functions above, and default values # can be overridden in the rc files if [ "$$" -eq "$PM_PARENT_PID" ]; then if [ -n "$PM_PACKAGES" -o -n "$PM_PACKAGES_BUILD" ]; then [ `/sbin/sysctl -n kern.osreldate 2>/dev/null` -lt 600400 ] && fail Package installation support requires FreeBSD 6.4 or newer fi if [ -z "$pd" ]; then if [ -z "$PORTSDIR" ]; then [ -d /usr/ports ] && pd=/usr/ports [ -z "$pd" ] && pd=`pm_make_b -f/usr/share/mk/bsd.port.mk -V PORTSDIR 2>/dev/null` else pd=$PORTSDIR fi fi if [ -n "$PM_INDEX" ]; then if [ -z "$INDEXFILE" ]; then ver=`uname -r` INDEXFILE=INDEX-${ver%%\.*} unset ver fi PM_INDEX="${INDEXDIR:-$pd}/${INDEXFILE}" if [ -z "$PM_NO_INDEX_FETCH" ]; then : ${FETCHINDEX:='fetch -am -o'} : ${MASTER_SITE_INDEX:='http://www.FreeBSD.org/ports/'} index_fetch="$FETCHINDEX ${PM_INDEX}.bz2 ${MASTER_SITE_INDEX}${INDEXFILE}.bz2" do_index_fetch=yes_index_fetch index_time=`stat -f '%Um' ${PM_INDEX}.bz2 2>/dev/null` [ -n "$index_time" ] && { $index_fetch 2>/dev/null && do_index_fetch=no_index_fetch; } [ "$do_index_fetch" = yes_index_fetch ] && { pm_sv 'Updating INDEX file'; $PM_SU_CMD $index_fetch; } if [ ${index_time:-0} -ne `stat -f '%Um' ${PM_INDEX}.bz2 2>/dev/null` ]; then temp_index=`pm_mktemp index` bunzip2 < ${PM_INDEX}.bz2 > $temp_index pm_install_s $temp_index $PM_INDEX unlink $temp_index unset temp_index fi unset index_fetch do_index_fetch index_time else [ -r "$PM_INDEX" ] || fail "The --no-index-fetch option was used, but $PM_INDEX does not exist" fi PM_INDEX_PORTS=`pkg_version -Ivl\< $PM_INDEX | cut -f1 -d\<` export PM_INDEX_PORTS fi if [ -z "$pd" ]; then if [ -n "$PM_INDEX_ONLY" ]; then pd=`head -1 $PM_INDEX | cut -f 2 -d\|` pd=${pd%/*} pd=${pd%/*} fi [ -z "$pd" ] && fail 'The value of PORTSDIR cannot be empty' fi if [ -z "$pdb" ]; then if [ -z "$PKG_DBDIR" ]; then [ -d /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 [ -d /var/db/pkg ]; then pdb='/var/db/pkg' else fail 'The value of PKG_DBDIR cannot be empty' fi fi fi export pd pdb if [ -z "$DISTDIR" -a "$PM_PACKAGES" != only -a -z "$CHECK_DEPENDS" -a \ -z "$CHECK_PORT_DBDIR" -a -z "$LIST_ORIGINS" ]; then DISTDIR=`pm_make_b -f/usr/share/mk/bsd.port.mk -V DISTDIR 2>/dev/null` fi [ -n "$DISTDIR" ] && { DISTDIR="${DISTDIR%/}/"; export DISTDIR; } [ -z "$port_dbdir" -a -d /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 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 set -- $newopts unset var newopts #=============== Begin functions relevant to --features and main =============== iport_from_origin () { local dir dir=`grep -l "@comment ORIGIN:${1}$" $pdb/*/+CONTENTS` || return 1 # It should not happen that more than one port meets this # requirement, but it can if the pkg data is corrupted. dir="${dir%%/+CONTENTS*}" echo ${dir#$pdb/} } origin_from_pdb () { local o o=`grep -m1 '@comment ORIGIN:' $pdb/$1/+CONTENTS 2>/dev/null` && { echo ${o#@comment ORIGIN:}; return 0; } case "$1" in bsdpan-*) return 3 ;; esac if [ -e "$pdb/$1/+IGNOREME" ]; then if [ -n "$PM_VERBOSE" -o -n "$LIST_ORIGINS" ]; then echo " ===>>> No ORIGIN in $pdb/$1/+CONTENTS" >&2 echo " ===>>> $pdb/$1/+IGNOREME exists" >&2 echo '' >&2 fi return 2 else echo " ===>>> No ORIGIN in $pdb/$1/+CONTENTS" >&2 echo '' >&2 fi return 1 } check_regular_file () { [ ! -L "$1" -a -f "$1" ] || fail "ERROR: $1 is not a regular file!" } strip_to_iport () { local in while read in; do in="${in%/+CONTENTS}" in="${in##*/}" echo $in done } check_dependency_files () { # Global: grep_deps local origin iport ro_opd origin=$1 ; iport=$2 # egrep hates + in file names case "$origin" in *+*) origin=`echo $origin | sed 's#\+#\\\\+#g'` ;; esac case "$ro_opd" in '') ro_opd=a/a ;; *+*) ro_opd=`echo $ro_opd | sed 's#\+#\\\\+#g'` ;; esac # Always rely on the grep'ed dependencies instead of +REQUIRED_BY grep_deps=`pm_mktemp grep-deps-${iport}` egrep -l "DEPORIGIN:($origin|$ro_opd)$" $pdb/*/+CONTENTS | strip_to_iport | sort -u > $grep_deps if [ ! -s "$grep_deps" ]; then if [ -s "$pdb/$iport/+REQUIRED_BY" ]; then # No actual dependencies exist, so this file is stale # Zero it out so that -s mode can find it # Outdent if [ -n "$PM_VERBOSE" -o -n "$CHECK_DEPENDS" ]; then echo " ===>>> No installed ports depend on $iport" echo " ===>>> Emptying +REQUIRED_BY file. Try ${0##*/} -s" fi # Outdent check_regular_file $pdb/$iport/+REQUIRED_BY $PM_SU_CMD truncate -s0 $pdb/$iport/+REQUIRED_BY fi fi return 0 } update_contents () { local IFS delete contents origin n_port old_origin iport new_cont local o_seen line d_missing d_origin d_iport prev_line answer # To prevent words in a line being treated individually IFS=' ' [ "$1" = 'delete' ] && { delete=delete ; shift; } contents=$1 ; origin=$2 ; n_port=$3 ; old_origin=$4 iport=${contents#$pdb/} ; iport=${iport%/+CONTENTS} new_cont=`pm_mktemp contents-${iport}` if [ -z "$delete" ]; then o_seen=':'; else o_seen=":${origin}:"; fi for line in `cat $contents`; do if [ -n "$d_missing" ]; then unset d_missing d_origin=${line#*DEPORIGIN:} case "$o_seen" in *:${d_origin}:*) unset prev_line line ; continue ;; esac o_seen="${o_seen}${d_origin}:" if [ "$d_origin" = "$old_origin" ]; then d_iport=$n_port d_origin=$origin else d_iport=`iport_from_origin $d_origin` fi if [ -n "$d_iport" ]; then [ -n "$PM_VERBOSE" -o -n "$CHECK_DEPENDS" ] && echo " ===>>> Updating @pkgdep for $d_origin" else echo " ===>>> $d_origin is listed as a dependency" echo " ===>>> but there is no installed version" echo '' if [ -n "$CHECK_DEPENDS" ]; then echo -n " ===>>> Delete this dependency data? y/n [n] " read answer case "$answer" in [yY]) unset prev_line line ; continue ;; esac else echo " ===>>> Try ${0##*/} --check-depends" fi fi # Could be fixed or not, but if we get here write it # so we can warn the user again later if we need to. echo "@pkgdep $d_iport" >> $new_cont echo "@comment DEPORIGIN:$d_origin" >> $new_cont unset prev_line continue fi case "$line" in "@comment DEPORIGIN:$origin"|"@comment DEPORIGIN:$old_origin") d_origin=${line#*DEPORIGIN:} unset prev_line line case "$o_seen" in *:${d_origin}:*) continue ;; esac o_seen="${o_seen}${d_origin}:" echo "@pkgdep $n_port" >> $new_cont echo "@comment DEPORIGIN:$origin" >> $new_cont ;; '@comment DEPORIGIN:'*) d_origin=${line#*DEPORIGIN:} case "$o_seen" in *:${d_origin}:*) unset prev_line line ; continue ;; esac o_seen="${o_seen}${d_origin}:" ;; '@pkgdep '|@pkgdep) d_missing=d_missing ;; @pkgdep*) d_iport="${line#@pkgdep }" [ -d "$pdb/$d_iport" ] || d_missing=dm2 ;; esac [ -n "$prev_line" ] && echo $prev_line >> $new_cont prev_line=$line done [ -n "$prev_line" ] && echo $prev_line >> $new_cont cmp -s $contents $new_cont && { pm_unlink $new_cont ; return; } check_regular_file $contents [ -n "$PM_VERBOSE" -o -n "$CHECK_DEPENDS" ] && echo " ===>>> Installing the new +CONTENTS file" pm_install_s $new_cont $contents pm_unlink $new_cont } find_moved_port () { # Global: moved_npd local sf iport IFS l reason sf=$1 # Search for iport=$2 # To avoid having each word of the reason treated separately IFS=' ' for l in `grep "^$sf|" $pd/MOVED`; do case "$l" in ${sf}\|\|*) [ -n "$iport" ] || iport=`iport_from_origin $sf` if [ -e "$pdb/$iport/+IGNOREME" ]; then if [ -n "$PM_VERBOSE" ]; then echo '' echo " ===>>> The $sf port has been deleted" echo " ===>>> Reason: ${l##*|}" echo " ===>>> Skipping it due to +IGNOREME file" echo '' fi return 0 else reason=${l##*|} [ "$3" != 'nonfatal' ] && fail "The $sf port has been deleted: $reason" fi ;; ${sf}\|*) moved_npd=${l#*\|} # New port directory moved_npd=${moved_npd%%\|*} echo '' echo " ===>>> The $sf port moved to $moved_npd" echo " ===>>> Reason: ${l##*|}" echo '' find_moved_port $moved_npd ;; esac done if [ -z "$moved_npd" ]; then if [ -z "$reason" ]; then echo '' echo " ===>>> No $pd/$1 exists, and no information" echo " ===>>> about $1 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 $sf` if [ -e "$pdb/$iport/+IGNOREME" ]; then return 0 else return 1 fi fi return 0 } read_distinfos () { local pkg iport origin distinfo disc1 f disc2 echo '############' > $DI_FILES # Make the file > 0 bytes echo "===>>> Gathering distinfo list for installed ports" echo '' for pkg in ${pdb}/*; do [ -d $pkg ] || continue iport=${pkg#$pdb/} origin=`origin_from_pdb $iport` || continue if [ ! -d "$pd/$origin" ]; then find_moved_port $origin $iport nonfatal >/dev/null [ -n "$moved_npd" ] || continue origin=$moved_npd fi pm_cd $pd/$origin || continue if [ -s distinfo ]; then distinfo=distinfo else distinfo=`pm_make -V MD5_FILE` fi if [ -s "$distinfo" ]; then grep '^MD5' $distinfo | while read disc1 f disc2; do f=${f#(} ; f=${f%)} echo $f >> $DI_FILES done fi done # Tell safe_exit that we are done [ -e "${DI_FILES}-e" ] && unlink ${DI_FILES}-e sed -i -e 1s/############/%%%%%%%%%%%%/ $DI_FILES [ -e "${DI_FILES}-e" ] && unlink ${DI_FILES}-e } globstrip () { local in in=${1%[*]} in=${in%\\} echo $in } ports_by_category () { local pkg [ -n "$PM_VERBOSE" ] && echo "===>>> Sorting ports by category" for pkg in $pdb/*; do if [ -s "$pkg/+REQUIRED_BY" ]; then if grep -ql '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then branches="$branches ${pkg#$pdb/}" else trunks="$trunks ${pkg#$pdb/}" fi else if grep -ql '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then leaves="$leaves ${pkg#$pdb/}" else [ -d "$pkg" ] || continue roots="$roots ${pkg#$pdb/}" fi fi done } 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 -d $DISTDIR -type d \( -empty -and ! -path \*\.zfs/\* \) -delete } # 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=`find $pdb -maxdepth 1 -type d -name ${pattern}\*` case "$glob_dirs" in # Match a newline in multiple responses from find *' '*) return 2 ;; $pdb/*) return ;; esac unset glob_dirs return 1 } #=============== 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 DI_FILES=`pm_mktemp DI-FILES` read_distinfos echo "===>>> Checking for stale distfiles" for df in `find $DISTDIR -type f | sort`; do f=${df#$DISTDIR} if ! grep -ql $f $DI_FILES; then if [ -n "$ALL" ]; then echo "===>>> Deleting $f" pm_unlink $df else echo -n "===>>> Delete stale file: ${f}? y/n [y] " read answer case "$answer" in [nN]*) continue ;; *) pm_unlink $df ;; esac fi fi done delete_empty_dist_subdirs safe_exit fi if [ -n "$CHECK_DEPENDS" ]; then d_orig_ok=':' IFS=' ' for pkg in $pdb/*; do [ -d "$pkg" ] || continue iport=${pkg#$pdb/} echo "===>>> Checking $iport" [ -r "$pkg/+CONTENTS" ] || { echo " ===>>> Warning: No +CONTENTS file!"; continue; } origin=`origin_from_pdb $iport` || continue if [ ! -d "$pd/$origin" ]; then echo " ===>>> $pd/$origin does not exist" echo " ===>>> This port should probably be updated" continue fi check_dependency_files $origin $iport if [ -s "$grep_deps" ]; then if [ -e "$pkg/+REQUIRED_BY" ]; then sort $pkg/+REQUIRED_BY | cmp -s $grep_deps - || do_update=do_update check_regular_file $pkg/+REQUIRED_BY else do_update=do_update2 fi if [ -n "$do_update" ]; then unset do_update echo " ===>>> Updating +REQUIRED_BY" pm_install_s $grep_deps $pkg/+REQUIRED_BY fi fi [ -n "$grep_deps" ] && { pm_unlink $grep_deps && unset grep_deps; } update_contents $pkg/+CONTENTS done exit 0 fi if [ -n "$CHECK_PORT_DBDIR" ]; then [ -d "$port_dbdir" ] || fail 'PORT_DBIR is empty, or the directory $port_dbdir does not exist' if [ "$1" = "-v" ]; then PM_VERBOSE=vopt; fi unique_list=':' echo "===>>> Building list of installed port names"; echo '' for pkg in $pdb/*; do [ -d $pkg ] || continue unset unique_name iport=${pkg#$pdb/} origin=`origin_from_pdb $iport` || continue if [ ! -d "$pd/$origin" ]; then find_moved_port $origin $iport nonfatal >/dev/null [ -n "$moved_npd" ] || continue origin=$moved_npd fi pm_cd $pd/$origin || { echo " ===>>> $pd/$origin does not exist for $pkg"; continue; } unique_name=`make -V UNIQUENAME` unique_list="${unique_list}${unique_name}:" done 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 [ -n "$PM_VERBOSE" ] && echo '' for dir in ${port_dbdir}/*; do dbdir=${dir#$port_dbdir/} [ -n "$PM_VERBOSE" ] && echo -n "===>>> Checking ${dbdir}: " case "$unique_list" in *:${dbdir}:*) [ -n "$PM_VERBOSE" ] && echo "Ok" ;; *) [ -n "$PM_VERBOSE" ] && echo '' echo '' echo " ===>>> $dbdir does not seem to be installed" echo -n " ===>>> Delete ${dir}? y/n [n] " read answer case "$answer" in [yY]) pm_rm_s -rf $dir ;; esac echo '' ;; esac done exit 0 fi if [ -n "$LIST_ORIGINS" ]; then ports_by_category for iport in $roots $leaves; do origin=`origin_from_pdb $iport` || continue echo $origin done exit 0 fi #=============== End code relevant only to --features =============== # Save switches for potential child processes while getopts 'BCDFGHKLPRabde:fghilm:nop:r:stuvwx:' 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) NO_RECURSIVE_CONFIG=Gopt; ARGS="-G $ARGS" ;; H) HIDE_BUILD=Hopt; ARGS="-H $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 ;; p) echo "===>>> The -p option has been deprecated" ; echo '' portdir="${OPTARG#$pd/}" ; portdir=${portdir%/} ;; r) UPDATE_REQ_BYS=ropt if [ -d "$pdb/$OPTARG" ]; then glob_dirs=$OPTARG else find_glob_dirs $OPTARG case $? in 1) fail "$pdb/$OPTARG does not exist" ;; 2) fail 'The argument to -r must match only one port' ;; esac fi portdir=`origin_from_pdb ${glob_dirs##*/}` ; unset glob_dirs ;; s) CLEAN_STALE=sopt ;; t) RECURSE_THOROUGH=topt; ARGS="-t $ARGS" ;; u) echo "===>>> The -u option has been deprecated" ; echo '' ;; 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}` " ;; *) echo '' ; echo "===>>> Try ${0##*/} --help"; exit 1 ;; esac done shift $(( $OPTIND - 1 )) unset -f packages_init cross_idx [ -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 "$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 "$NO_RECURSIVE_CONFIG" ]; then [ -n "$FETCH_ONLY" ] && unset NO_RECURSIVE_CONFIG [ -n "$PM_PACKAGES_BUILD" ] && fail 'The --packages-build and -G options are mutually exclusive' [ -n "$PM_DEL_BUILD_ONLY" ] && fail 'The --delete-build-only and -G options are mutually exclusive' [ -n "$FORCE_CONFIG" ] && fail 'The --force-config and -G options are mutually exclusive' fi 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 "$UPDATE_REQ_BYS" -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 unset my_environment unset -f test_command_line #=============== Begin functions for getopts features and main =============== check_state () { # Global: state local state_set if egrep -ql '^(FORBIDDEN|DEPRECATED|BROKEN|IGNORE)' Makefile; then for state in FORBIDDEN DEPRECATED BROKEN IGNORE; do state_set=`pm_make -V $state` if [ -n "$state_set" ]; then echo " ===>>> This port is marked $state" printf " ===>>> $state_set\n" echo '' return 1 fi done fi return 0 } parse_index () { local pd line [ -z "$pd" -a -n "$PM_INDEX_ONLY" ] && pd=/usr/ports line=`grep -m1 .*\|${pd}/${1}\|.* $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 } check_pkg_version () { local iport port_ver udf iport=$1 ; port_ver=$2 ; udf=$3 case `pkg_version -t $iport $port_ver` in \<) return 1 ;; =) return ;; \>) if [ -n "$PM_VERBOSE" ]; then echo " ===>>> Port version $port_ver does not" echo " ===>>> seem newer than installed $iport" fi if [ -n "$PM_FORCE" ]; then check_restart_and_udf $udf $iport || return 1 elif [ -n "$URB_YES" ]; then case "$MASTER_RB_LIST" in *" $iport "*) if ! check_restart_and_udf $udf $iport; then return 1 else URB_DONE_LIST="${URB_DONE_LIST}${upg_port}:" fi ;; esac fi ;; esac } check_for_updates () { # Global: num_updates local list_only nf iport origin port_ver skip udf do_update [ "$1" = 'list' ] && { list_only=list_only; nf=nonfatal; shift; } iport=$1 origin=${2:-`origin_from_pdb $iport`} || return 0 if [ -n "$PM_INDEX" ]; then case "$PM_INDEX_PORTS" in *${iport}*) port_ver=`parse_index $origin name` ; do_update=upd_idx ;; esac [ -n "$PM_INDEX_FIRST" ] || skip=index_skip fi if [ -d "$pd/$origin" -a -z "$do_update" -a -z "$skip" ]; then if ! pm_cd $pd/$origin; then if [ -e "$pdb/$iport/+IGNOREME" ]; then echo " ===>>> Warning: Unable to cd to $pd/$origin" echo " ===>>> Continuing due to $pdb/$iport/+IGNOREME" return 0 else fail "Cannot cd to port directory: $pd/$origin" fi fi port_ver=`pm_make -V PKGNAME` [ -z "$port_ver" ] && fail "Is $pd/$origin/Makefile missing?" elif [ -z "$do_update" -a -z "$skip" ]; 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 [ ! -e "$pdb/$iport/+IGNOREME" ]; then do_update=do_update_moved else echo " ===>>> Continuing due to $pdb/$iport/+IGNOREME" echo '' CUR_DEPS="${CUR_DEPS}${iport}:${origin}:" return 0 fi fi fi if [ -z "$do_update" -a -n "$port_ver" ]; then udf="$pdb/$iport/PM_UPGRADE_DONE_FLAG" if [ "$iport" = "$port_ver" ]; then if [ -n "$PM_FORCE" ]; then check_restart_and_udf $udf $iport || do_update=do_update_force elif [ -n "$URB_YES" ]; then # Outdent case "$MASTER_RB_LIST" in *" $iport "*) if ! check_restart_and_udf $udf $iport; then do_update=do_update_urb else URB_DONE_LIST="${URB_DONE_LIST}${upg_port}:" fi ;; esac # Outdent elif [ -n "$PM_MULTI_PORTS" ]; then case "$PM_MULTI_PORTS" in *:${iport}:*) do_update=do_update_mi ;; *:${origin}:*) do_update=do_update_mo ;; esac elif [ -n "$LIST_PLUS" ]; then [ -z "$PM_INDEX_ONLY" ] && check_state return 0 elif [ -n "$LIST" ]; then return 0 fi else check_pkg_version $iport $port_ver $udf || do_update=do_update_check fi fi [ -z "$do_update" ] && { CUR_DEPS="${CUR_DEPS}${iport}:${origin}:" ; return 0; } if [ -n "$list_only" ]; then if [ -z "$moved_npd" ]; then echo " ===>>> New version available: $port_ver" [ -e "$pdb/$iport/+IGNOREME" ] && echo " ===>>> +IGNOREME file is present for $1" [ -z "$PM_INDEX_ONLY" ] && { pm_cd_pd $origin ; check_state; } num_updates=$(( $num_updates + 1 )) else unset moved_npd fi return 0 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_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 /usr/ports/packages -a -w /usr/ports/packages ]; then PACKAGES='/usr/ports/packages' else if [ -d /usr/ports/ -a -w /usr/ports/ ]; then PACKAGES='/usr/ports/packages' else fail 'The value of PACKAGES cannot be empty and the directory must be writable' fi fi fi export PACKAGES } init_packages () { # Global: pbu [ -n "$FETCH_ONLY" ] && return init_packages_var [ -n "$NO_BACKUP" ] && return pbu=$PACKAGES/portmaster-backup if [ ! -d "$pbu" ]; then pm_sv Creating $pbu pm_mkdir_s $pbu fi export pbu } pm_pkg_create () { local pkgdir init_packages 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 echo "===>>> Creating a package for new version $2" else pkgdir=$1 ; echo '' echo "===>>> Creating a backup package for old version $2" fi pm_cd $pkgdir || fail "Cannot cd into $pkgdir to create a package" if $PM_SU_CMD pkg_create -b $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=`echo $2.*` if [ -z "$PM_INDEX_ONLY" ]; then local latest_link pm_cd_pd $portdir latest_link=`pm_make -V LATEST_LINK` cd ${1}/Latest $PM_SU_CMD ln -sf ../All/$pkg ${latest_link}.tbz fi cd ${1}/${portdir%/*} $PM_SU_CMD ln -sf ../All/$pkg $pkg echo " ===>>> Package saved to ${1}/All" ; echo '' fi else echo '' echo "===>>> Package creation failed for ${2}!" echo '' echo "===>>> Ignore this error [i]" echo "===>>> Abort [a]" echo '' echo -n "===>>> How would you like to proceed? [i] " local answer ; read answer case "$answer" in a) fail "Package creation failed for $2" ;; esac fi } find_dl_distfiles () { # Global: dist_list dist_list_files local file # We need to define these for use in the deletion/update process. if pm_cd $pd/$1; then dist_list=`pm_make_b -V OPTIONSFILE` dist_list="${dist_list%options}distfiles" [ -s "$dist_list" ] || { unset dist_list ; return 0; } [ -n "$DONT_SCRUB_DISTFILES" ] && return 0 # The grep is needed to allow for comments, etc. for file in `grep ^DISTFILE $dist_list`; do file=${file#DISTFILE:} ; file=${file%%:*} dist_list_files="${dist_list_files}${file#*/} " done else # The port might have moved, etc.; so take a stab at it, # but do not take a chance with a possibly wrong answer dist_list="$port_dbdir/${1##*/}/distfiles" [ -s "$dist_list" ] || { unset dist_list ; return 0; } [ -n "$DONT_SCRUB_DISTFILES" ] && return 0 # Do not strip the subdir, we will use it in delete_all for file in `grep ^DISTFILE $dist_list`; do file=${file#DISTFILE:} ; file=${file%%:*} dist_list_files="${dist_list_files}${file} " done fi } delete_dist_list () { [ -n "$dist_list" ] || return 0 local dir pm_sv Deleting $dist_list pm_unlink_s $dist_list dir=`find ${dist_list%/distfiles} -type d -empty 2>/dev/null` if [ -d "$dir" ]; then pm_sv Deleting the $dir directory pm_rmdir_s $dir fi } find_and_delete_distfiles () { # Global: port_subdir DISTDIR distfiles distfiles_checked delete_all local ps pattern file answer ps=${port_subdir#$DISTDIR} pattern=${1%[_-]*} for file in ${pattern}*; do # This generally means the pattern did not match case "$file" in *\*) [ "$pattern" = "${pattern%[_-]*}" ] && return 0 # This will happen for files like foo-bar_baz-1.23 find_and_delete_distfiles $pattern ;; esac case "$distfiles_checked" in *:${file}:*) continue ;; esac [ -f "$file" ] || continue case "$distfiles" in *" ${file} "*) distfiles_checked="${distfiles_checked}${file}:" [ -n "$PM_VERBOSE" ] && echo "===>>> Keeping current distfile: $file" continue # Do not delete current version ;; *) if [ -e "$DI_FILES" ]; then grep -ql ${ps}$file $DI_FILES && continue fi if [ -n "$ALWAYS_SCRUB_DISTFILES" -o \ -n "$delete_all" ]; then echo "===>>> Deleting stale distfile: $file" pm_unlink $file continue fi echo -n "===>>> Delete $file? y/n [n] " read answer case "$answer" in [yY]) pm_unlink $file ;; *) distfiles_checked="${distfiles_checked}${file}:" ;; esac ;; esac done } set_distfiles_and_subdir () { # Global: dist_list_files distfiles port_subdir DISTDIR [ -z "$dist_list_files" ] && find_dl_distfiles $1 if [ -d "$pd/$1" ]; then pm_cd_pd $1 else return 1 fi if [ -z "$distfiles" ]; then distfiles=`pm_make -V ALLFILES | sed -e 's# *$##g'` [ -n "$distfile" ] && distfiles=" ${distfiles} " fi # Ports may have no distfiles [ -z "$dist_list_files" -a -z "$distfiles" ] && return 2 if [ -z "$port_subdir" ]; then port_subdir=`pm_make -V DIST_SUBDIR` if [ -n "$port_subdir" ]; then port_subdir="${DISTDIR}${port_subdir}/" else port_subdir=$DISTDIR fi fi if [ -d "$port_subdir" ]; then pm_cd $port_subdir || fail "cd to $port_subdir failed!" else echo '' echo "===>>> $port_subdir does not exist, therefore we" echo ' will assume that all relevant distfiles are gone.' echo '' echo " Try ${0##*/} --clean-distfiles[-all] for a full cleanup" echo '' return 3 fi return 0 } delete_stale_distfiles () { # Global: distfiles port_subdir distfiles_checked delete_all local file answer set_distfiles_and_subdir $1 || return 0 distfiles_checked=':' # If these two match, it means that the distfiles in the +CONTENTS # file are the current set, so do not delete them. if [ ! " $dist_list_files" = "$distfiles" ]; then for file in $dist_list_files; do [ -f "$file" ] || continue case "$distfiles" in *" ${file} "*) distfiles_checked="${distfiles_checked}${file}:" [ -n "$PM_VERBOSE" ] && echo "===>>> Keeping current distfile: $file" continue # Do not delete current version ;; esac if [ -n "$ALWAYS_SCRUB_DISTFILES" -o \ -n "$delete_all" ]; then echo "===>>> Deleting stale distfile: $file" pm_unlink $file continue fi echo -n "===>>> Delete $file? y/n [n] " read answer case "$answer" in [yY]) pm_unlink $file ;; *) 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 in PORT_DBDIR, # keep doing it both ways. for file in $distfiles $dist_list_files; do find_and_delete_distfiles $file done [ -n "$PM_VERBOSE" ] && { echo "===>>> Distfile cleaning complete" ; echo ''; } } delete_all_distfiles () { # 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 ${0##*/} --clean-distfiles[-all] for a full cleanup" echo '' if [ -n "$dist_list_files" ]; then local answer f # Outdent if [ -z "$ALWAYS_SCRUB_DISTFILES" ]; then echo "===>>> However, the list of files in $dist_list" echo -n " should be current. Delete the files on this list? y/n [n] " read answer else answer=y fi # Outdent case "$answer" in [yY]) for f in $dist_list_files; do if [ -f "${DISTDIR}${f}" ]; then echo " Deleting ${DISTDIR}${f}" pm_unlink ${DISTDIR}${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" echo -n " without prompting? y/n [n] " local answer ; read answer case "$answer" in [yY]) delete_all=delete_all2 ;; *) echo -n "===>>> Delete the current distfiles? y/n [n] " read answer case "$answer" in [yY]) 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 [ -n "$PM_VERBOSE" ] && echo '' num_roots=0; num_trunks=0; num_branches=0; num_leaves=0; 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 num_roots=$(( $num_roots + 1 )) 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 num_trunks=$(( $num_trunks + 1 )) 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 num_branches=$(( $num_branches + 1 )) 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 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" elif [ -n "$LIST_PLUS" ]; then echo " ===>>> There are no new versions available" fi exit 0 fi if [ -n "$EXPUNGE" ]; then if [ ! -d "$pdb/$EXPUNGE" ]; then if find_glob_dirs $EXPUNGE; then EXPUNGE=${glob_dirs#$pdb/} unset glob_dirs else fail "No such directory/port: $pdb/$EXPUNGE" fi fi origin=`origin_from_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 dep=${dep%/+CON*} ; echo " ${dep##*/}" done echo '' echo -n "===>>> Delete this dependency data? y/n [n] " read answer case "$answer" in [yY]) 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 delete_dist_list echo "===>>> Running pkg_delete -f $EXPUNGE" pm_pkg_delete_s -f $EXPUNGE || fail 'pkg_delete failed' echo '' ; echo "===>>> Running ${0##*/} -s $ARGS" exec $0 -s $ARGS exit 0 # Should not be reached fi if [ -n "$CLEAN_STALE" ]; then [ -z "$no_del_list" ] && export no_del_list=':' for file in `find $pdb -type f -name \+REQUIRED_BY -empty` ; do iport="${file%/+REQUIRED_BY}" ; iport=${iport#$pdb/} case "$no_del_list" in *:${iport}:*) continue ;; esac origin=`origin_from_pdb $iport` deplist=`grep -l DEPORIGIN:$origin$ $pdb/*/+CONTENTS` 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 ${0##*/} --check-depends" echo '' continue fi pkg_info $iport echo -n "===>>> ${iport} is no longer depended on, delete? y/n [n] " read answer case "$answer" in [yY]) [ -n "$BACKUP" ] && { init_packages ; pm_pkg_create $pbu $iport; } [ -z "$DONT_SCRUB_DISTFILES" ] && delete_all_distfiles $origin delete_dist_list echo "===>>> Running pkg_delete -f $iport" pm_pkg_delete_s -f $iport || fail 'pkg_delete failed' exec $0 -s $ARGS ;; *) echo -n " ===>>> Keep listing $iport as a dependency? y/n [n] " read answer case "$answer" in [yY]) no_del_list="${no_del_list}${iport}:" ;; *) pm_unlink_s $file ;; esac ;; 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 () { [ -n "$PM_VERBOSE" ] || return 0 echo "===>>> The update for $1 is already done" } 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. if [ -z "$RESTART" ]; then return 1 elif [ ! -e "$1" ]; then return 1 else already_done $2 ; echo '' fi return 0 } 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 [ -e "$pdb/$1/+IGNOREME" ]; then echo '' echo "===>>> +IGNOREME file is present for $1" fi echo '' ; echo -n "===>>> Update ${1}${update_to}? y/n [y] " local answer ; read answer case "$answer" in [nN]*) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:" ; return 1 ;; *) INTERACTIVE_YES="${INTERACTIVE_YES}${1}:" ;; esac return 0 } 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 local sleep nf fetches echo '' sleep=5 while `ls ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-* >/dev/null 2>&1`; do nf=`ps -ax | grep [f]etch | wc -l` nf=${nf##* } fetches=fetches ; [ "$nf" -eq 1 ] && fetches=fetch echo "===>>> Waiting for ${nf##* } distfile $fetches to finish" sleep $sleep if [ $sleep -eq 10 ]; then sleep=5 else sleep=$(( $sleep + 1 )) fi done echo "===>>> Distfile fetching is complete" FETCH_ONLY_DONE=fetch_only_done safe_exit } term_printf () { [ -n "$PM_NO_TERM_TITLE" ] && return case "$TERM" in cons*) return ;; esac printf "\033]0;${0##*/}: ${PM_PARENT_PORT}${1}\007" } update_build_l () { local origin iport new_port case "$1" in */*) origin=$1 case "$build_l" in *\ $origin\\*) return ;; esac iport=`iport_from_origin $origin` if [ -z "$iport" ]; then build_l="${build_l}\tInstall $origin\n" return fi ;; *) iport=$1 case "$build_l" in *\ $iport\ *|*\ $iport\\*) return ;; esac origin=`origin_from_pdb $1` ;; esac if [ -z "$PM_INDEX_ONLY" ]; then pm_cd $pd/$origin && new_port=`pm_make -V PKGNAME` else new_port=`parse_index $origin name` || fail "No INDEX entry for $origin" fi case `pkg_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 update_to [ -n "$2" ] && update_to=" to $2" echo "===>>> Launching child to update ${1#$pd/}${update_to}" if [ -z "$NO_RECURSIVE_CONFIG" ]; then local deps dep_of_deps=$(( $dep_of_deps + 1 )) if [ -n "$CONFIG_ONLY" ]; then num_of_deps=$(( $num_of_deps + 1 )) update_build_l $1 fi deps=" (${dep_of_deps}/${num_of_deps})" fi if [ -n "$PM_DEPTH" ]; then echo " ${PM_DEPTH}>> ${1#$pd/}" term_printf " ${PM_DEPTH#* }>> ${1#$pd/}${deps}" else if [ -n "$UPDATE_ALL" ]; then term_printf " >> ${1#$pd/}${deps}" fi fi [ -n "$doing_dep_check" -o \ \( -n "$UPDATE_ALL" -a -n "$CONFIG_ONLY" \) ] && unset NO_DEP_UPDATES if [ -z "$NO_ACTION" -o -n "$CONFIG_ONLY" ]; then ($0 $ARGS $1) || fail "Update for $1 failed" . $IPC_SAVE else [ -n "$PM_VERBOSE" ] && echo "===>>> Build canceled due to -n flag" fi if [ -n "$UPDATE_ALL" ]; then term_printf " (${num_of_deps})" echo "===>>> Returning to update check of installed ports" echo '' elif [ -n "$UPDATE_REQ_BYS" ]; then return 0 elif [ -n "$CONFIG_ONLY" -a -z "$PM_PACKAGES" ]; then echo "===>>> Continuing 'make config' dependency check for $portdir" else term_printf " ${PM_DEPTH#* }${deps}" echo "===>>> Returning to dependency check for $portdir" fi return 0 } uniquify_list () { local item temp_list for item in "$@"; do case "$temp_list" in *" $item "*) ;; *) temp_list=" $item $temp_list" ;; esac done echo $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` " } gen_dep_list () { local list if [ -z "$PM_INDEX_ONLY" ]; then pm_cd_pd $portdir list=`pm_make $* | sort -u` 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" } 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. echo "===>>> Gathering dependency list for $portdir from ports" d_port_list=`gen_dep_list $1` if [ -z "$d_port_list" ]; then echo "===>>> No dependencies for $portdir" [ -n "$SHOW_WORK" ] && safe_exit return 0 else if [ -n "$SHOW_WORK" ]; then echo '' elif [ -n "$CONFIG_ONLY" -a -z "$PM_PACKAGES" ]; then echo "===>>> Starting recursive 'make config' check" else echo "===>>> 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 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 "$RECURSE_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 udf # Do not export, for THIS parent process only [ -n "$CONFIG_ONLY" ] && doing_dep_check=doing_dep_check for d_port in $d_port_list; do 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 [ -n "$PM_VERBOSE" ] && echo "===>>> Checking dependency: $origin" # Do this first to catch out of date dependencies if [ -n "$CONFIG_ONLY" ]; then case "$CONFIG_SEEN_LIST" in *:${origin}:*) continue ;; esac fi [ -z "$URB_YES" ] && case "$CUR_DEPS" in *:${origin}:*) continue ;; esac if [ -z "$PM_INDEX_ONLY" ]; then local conflicts glob confl_p conflicts='' if pm_cd $d_port; then grep -ql ^CONFLICTS Makefile && conflicts=`pm_make_b -V CONFLICTS` else fail "Cannot cd to $d_port" fi for glob in $conflicts; do confl_p=`pkg_info -I $glob 2>/dev/null` if [ -n "$confl_p" ]; then confl_p=${confl_p%% *} echo '' echo "===>>> The dependency for ${origin}" echo " seems to be handled by $confl_p" echo '' d_port="$pd/`origin_from_pdb $confl_p`" fi done fi # In case d_port changed above origin="${d_port#$pd/}" ; iport=`iport_from_origin ${origin}` if [ -n "$iport" ]; then check_exclude $iport || continue else check_exclude $origin || continue fi udf="$pdb/$iport/PM_UPGRADE_DONE_FLAG" if [ -n "$PM_FORCE" -a -n "$iport" ]; then if ! check_restart_and_udf $udf $iport; then echo "===>>> Forcing update for $pd/$origin" update_port $iport else CUR_DEPS="${CUR_DEPS}${iport}:${origin}:" fi continue elif [ -n "$URB_YES" -a -n "$iport" ]; then case "$URB_DONE_LIST" in *:${iport}:*) already_done ; continue ;; esac case "$MASTER_RB_LIST" in *" $iport "*) check_interactive $iport || continue if ! check_restart_and_udf $udf $iport; then update_port $iport else CUR_DEPS="${CUR_DEPS}${iport}:${origin}:" URB_DONE_LIST="${URB_DONE_LIST}${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 update_port $origin fi done [ -n "$CONFIG_ONLY" ] && unset doing_dep_check if [ -n "$SHOW_WORK" ]; then safe_exit elif [ -n "$CONFIG_ONLY" -a -z "$PM_PACKAGES" ]; then echo "===>>> Recursive 'make config' check complete for $portdir" case "$PM_DEPTH" in *\>\>*) echo " $PM_DEPTH" ;; esac else echo "===>>> Dependency check complete for $portdir" case "$PM_DEPTH" in *\>\>*) echo " $PM_DEPTH" ;; *) if [ "$PM_PARENT_PORT" = All ]; then if [ -z "$NO_RECURSIVE_CONFIG" ]; then local deps deps=" (${dep_of_deps}/${num_of_deps})" fi term_printf " >> ${upg_port:-$portdir}${deps}" else term_printf fi ;; esac fi } create_master_rb_list () { # Global: MASTER_RB_LIST local req_by for req_by in `grep -l DEPORIGIN:$portdir$ $pdb/*/+CONTENTS`; do req_by="${req_by%/+CONTENTS}" req_by="${req_by##*/}" MASTER_RB_LIST="${MASTER_RB_LIST}${req_by} " done [ -n "$MASTER_RB_LIST" ] && export MASTER_RB_LIST=" $MASTER_RB_LIST" } post_config () { local action if [ $num_of_deps -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" echo -n "===>>> Proceed? y/n [y] " read answer case "$answer" in [nN]*) 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 ;; esac unset build_l fi else term_printf fi action=build if [ "$PM_PACKAGES" = only ]; then action=install elif [ -n "$PM_PACKAGES" ]; then action='build and/or install' fi echo '' echo "===>>> Starting $action for $* <<<===" echo '' unset CONFIG_SEEN_LIST CONFIG_ONLY dep_of_deps=0 if [ -n "$PM_BUILD_ONLY_LIST" ]; then local var real_rundep deplist dep 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 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 } multiport () { # Global PM_MULTI_PORTS=':' ; PM_MULTI_BUILT=':' export PM_MULTI_PORTS PM_MULTI_BUILT local port worklist_temp worklist portlist numports num # Expand globs and check that the directories exist for port in $@; do port=${port#$pdb/} case "$port" in */*) port=${port#$pd/} if [ -d "$pd/${port}" ]; then worklist_temp="$worklist_temp $port" else fail "$pd/${port} does not exist" fi ;; *) if [ -d "$pdb/$port" ]; then worklist_temp="$worklist_temp $port" else find_glob_dirs $port case $? in 1) fail "$pdb/$port does not exist" ;; *) 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 worklist="$worklist $port" portlist="${portlist}\t${port}\n" PM_MULTI_PORTS="${PM_MULTI_PORTS}${port}:" numports=$(( $numports + 1 )) update_build_l $port done echo "===>>> Working on multiple ports:" echo -e $portlist if [ -n "$CONFIG_ONLY" ]; then 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 num=1 for port in $worklist; do init_term_printf "$port ${num}/${numports}" ($0 $ARGS $port) || fail "Update for $port failed" . $IPC_SAVE num=$(( $num + 1 )) done check_fetch_only post_config multiple ports fi export PM_BUILDING=pmbuildingmultiport num=1 for port in $worklist; do case "$PM_MULTI_BUILT" in *:${port}:*) continue ;; esac case "$port" in */*) ;; # Ok to proceed *) # If an installed version does not exist at this # point it probably got updated as a dependency if [ ! -d "$pdb/$port" ]; then numports=$(( $numports - 1 )) continue fi ;; esac init_term_printf "$port ${num}/${numports}" ($0 $ARGS $port) || fail "Update for $port failed" . $IPC_SAVE num=$(( $num + 1 )) done safe_exit } make_config () { config_type=config-conditional [ -n "$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 CUR_DEPS=':' ; DISPLAY_LIST='' ; INSTALLED_LIST='' PM_DEPTH='' ; IPC_SAVE=`pm_mktemp IPC_SAVE` export CUR_DEPS DISPLAY_LIST INSTALLED_LIST PM_DEPTH IPC_SAVE if [ -n "$LOCALBASE" ]; then LOCALBASE_COMPAT="$LOCALBASE/lib/compat/pkg" else 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 PLB=`head -1 $PM_INDEX | cut -f 3 -d\| 2>/dev/null` if [ -d "$PLB" ]; then LOCALBASE_COMPAT="${PLB}/lib/compat/pkg" else 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 [ -n "$UPDATE_REQ_BYS" ] && export URB_DONE_LIST=':' if [ -n "$UPDATE_REQ_BYS" -o -n "$PM_FORCE" ]; then if [ -z "$RESTART" ]; then # Outdent files=`find $pdb -type f -name PM_UPGRADE_DONE_FLAG` if [ -n "$files" ]; then echo "===>>> There are 'install complete' flags from a previous" echo -n " -[rf] run of ${0##*/}, delete them? y/n [n] " read answer case "$answer" in [yY]) pm_sv Deleting \'install complete\' flags pm_find_s $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete ;; *) echo -n "===>>> Enable the -R option? y/n [n] " read answer case "$answer" in [yY]) RESTART=Ropt ; ARGS="-R $ARGS" ;; esac ;; esac fi # Outdent fi fi if [ -z "$NO_RECURSIVE_CONFIG" ]; then CONFIG_SEEN_LIST=':' ; CONFIG_ONLY=config_only NO_DEP_UPDATES=no_dep_updates ; build_l='' export CONFIG_SEEN_LIST CONFIG_ONLY NO_DEP_UPDATES build_l 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 fi [ -z "$NO_BACKUP" ] && init_packages [ -z "$NO_BACKUP" -a -z "$BACKUP" ] && export NB_DELETE if [ -n "$MAKE_PACKAGE" ]; then init_packages_var if [ ! -d "$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 export DI_FILES=`pm_mktemp DI-FILES` fi if [ $# -gt 1 -a -z "$REPLACE_ORIGIN" ]; then multiport $@ fi elif [ -z "$SHOW_WORK" ]; then # Zero out this file so that we can save our data to it safely > $IPC_SAVE fi # This has to come after the initialization, it uses all the same stuff if [ -n "$UPDATE_ALL" ]; then all_config () { local iport origin for iport in $@; do [ -n "$PM_VERBOSE" ] && echo "===>>> $iport" case "$CUR_DEPS" in *:${iport}:*) continue ;; esac origin=`origin_from_pdb $iport` || { case "$?" in 3) ;; 2) [ -z "$PM_VERBOSE" ] && echo " ===>>> No ORIGIN for $iport, and +IGNOREME is present" echo " ===>>> Skipping" echo '' ;; *) fail 'Cannot continue' ;; esac; # Prevent the user from getting reprompted during build CUR_DEPS="${CUR_DEPS}${iport}:"; continue; } case "$CONFIG_SEEN_LIST" in *:${origin}:*) continue ;; esac [ -n "$PM_BUILD_ONLY_LIST" ] && run_dl_g="$run_dl_g ${pd}/${origin} " check_exclude $iport || continue PM_DEPTH= check_for_updates $iport $origin || fail 'Update failed' CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${origin}:" done } [ -n "$DI_FILES" ] && (read_distinfos)& init_term_printf All ports_by_category echo "===>>> Starting check of installed ports for available updates" [ -n "$PM_BUILD_ONLY_LIST" ] && PM_BUILD_ONLY_LIST=pmp_doing_build_deps if [ -n "$CONFIG_ONLY" ]; then [ -n "$FETCH_ONLY" ] && export ALL_FETCH=all_fetch [ -z "$PM_PACKAGES" ] && echo "===>>> Checking ports for recursive 'make config'" [ -n "$PM_VERBOSE" ] && { echo '' ; echo "===>>> Root ports:"; } all_config $roots [ -n "$PM_VERBOSE" ] && { echo '' ; echo "===>>> Trunk ports:"; } all_config $trunks [ -n "$PM_VERBOSE" ] && { echo '' ; echo "===>>> Branch ports:"; } all_config $branches [ -n "$PM_VERBOSE" ] && { echo '' ; echo "===>>> Leaf ports:"; } all_config $leaves check_fetch_only if [ -n "$NO_DEP_UPDATES" ]; then echo "===>>> All ports are up to date" safe_exit fi post_config for ports that need updating [ -n "$PM_BUILD_ONLY_LIST" ] && clean_build_only_list fi export PM_BUILDING=pmbuildingall for iport in $roots $trunks $branches $leaves; do # Probably got updated as a dependency for something else [ -d "$pdb/$iport" ] || continue case "$CUR_DEPS" in *:${iport}:*) continue ;; esac check_exclude $iport || continue case "$iport" in bsdpan-*) continue ;; esac PM_DEPTH= if [ -n "$PM_FORCE" ]; then udf="$pdb/$iport/PM_UPGRADE_DONE_FLAG" if ! check_restart_and_udf $udf $iport; then echo "===>>> Forcing update for $iport" update_port $iport else CUR_DEPS="${CUR_DEPS}${iport}:" fi continue fi if [ -z "$NO_RECURSIVE_CONFIG" ]; then check_interactive $iport || continue # We got here, so we know we have to build it update_port $iport else [ -n "$PM_VERBOSE" ] && echo "===>>> Checking installed port: $iport" check_for_updates $iport || fail 'Update failed' fi done echo "===>>> Update check of installed ports complete" ; echo '' safe_exit fi no_valid_port () { echo "===>>> No valid installed port, or port directory given"; echo "===>>> Try ${0##*/} --help" ; echo '' ; safe_exit 1 } # Figure out what we are going to be working on if [ -z "$REPLACE_ORIGIN" ]; then [ -n "$portdir" ] && { argv=$portdir ; unset portdir; } argv=${argv:-$1} ; argv=${argv%/} ; argv=`globstrip $argv` case "$argv" in '') echo '' ; no_valid_port ;; $pd/*) portdir=${argv#$pd/} ;; $pdb/*) upg_port=${argv#$pdb/} ;; /*) echo '' ; no_valid_port ;; */*) portdir=$argv ;; \.) portdir=${PWD##*/ports/} ;; # Not always $pd, could be symlink *) [ -d "$pdb/$argv" ] && upg_port=$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 else portdir="${1#$pd/}" ; portdir="${portdir%/}" [ -d "$pd/$portdir" ] || { echo '' echo "===>>> The first argument to -o must be a directory in $pd" echo '' ; no_valid_port; } upg_port=`iport_from_origin $portdir` arg2=${2#$pd/} ; arg2=${arg2#$pdb/} ; arg2=${arg2%/} case "$arg2" in */*) ro_opd=$arg2 ; ro_upg_port=`iport_from_origin $ro_opd` ;; *) if [ -d "$pdb/$arg2" ]; then ro_upg_port=$arg2 else find_glob_dirs $arg2 && ro_upg_port=${glob_dirs#$pdb/} unset glob_dirs fi [ -n "$ro_upg_port" ] && ro_opd=`origin_from_pdb $ro_upg_port` esac unset arg2 if [ -z "$ro_upg_port" ]; then if ! grep -ql "DEPORIGIN:$ro_opd$" $pdb/*/+CONTENTS; then echo '' echo "===>>> The second argument to -o can be a port in $pdb," echo " or a port directory from $pd" 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 ;; 2) [ -z "$PM_VERBOSE" ] && { echo " ===>>> No ORIGIN for $upg_port, and +IGNOREME is present"; echo ''; }; safe_exit ;; *) fail 'Cannot continue' ;; esac ; } elif [ -z "$portdir" ]; then no_valid_port fi if [ ! -d "$pd/$portdir" -a -z "$PM_INDEX_ONLY" ]; then find_moved_port $portdir $upg_port || no_valid_port [ -n "$moved_npd" ] || no_valid_port [ -d "$pd/$moved_npd" ] || no_valid_port [ "$$" -eq "$PM_PARENT_PID" ] && parent_exit exec $0 $ARGS -o $moved_npd $upg_port fi [ -z "$upg_port" -a -z "$REPLACE_ORIGIN" ] && upg_port=`iport_from_origin ${portdir}` if [ -e "$pdb/$upg_port/+IGNOREME" ]; then # Adding to CUR_DEPS means we will not get here in the build unless -G 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" echo '' echo -n "===>>> Update anyway? y/n [n] " read answer case "$answer" in [yY]) ;; # Let it build *) CUR_DEPS="${CUR_DEPS}${upg_port}:${portdir}:" # Outdent if [ $dep_of_deps -gt 0 ]; then dep_of_deps=$(( $dep_of_deps - 1 )) if [ -n "$CONFIG_ONLY" ]; then num_of_deps=$(( $num_of_deps - 1 )) build_l="${build_l%\\t*}" fi fi # Outdent safe_exit ;; esac else echo '' echo "===>>> $upg_port has an +IGNOREME file, ignoring" echo '' CUR_DEPS="${CUR_DEPS}${upg_port}:${portdir}:" safe_exit fi ;; esac elif [ -n "$NO_RECURSIVE_CONFIG" -o -n "$URB_YES" ]; then echo '' echo "===>>> $upg_port has an +IGNOREME file, ignoring" echo '' safe_exit fi fi # START # Should only be reached for multiport already built as a dependency case "$CONFIG_SEEN_LIST" in *:${portdir}:*) safe_exit ;; esac [ -z "$PM_INDEX_ONLY" ] && { pm_cd $pd/$portdir || 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 if [ -n "$CONFIG_ONLY" -a "$$" -eq "$PM_PARENT_PID" ]; then if [ -n "$upg_port" ]; then update_build_l $upg_port else update_build_l $portdir fi fi echo '' [ "$$" -eq "$PM_PARENT_PID" -a -n "$upg_port" ] && echo "===>>> Currently installed version: $upg_port" if [ -z "$PM_INDEX_ONLY" ]; then echo "===>>> Port directory: $pd/$portdir" check_state || { echo " ===>>> If you are sure you can build it, remove the"; echo " $state line in the Makefile and try again."; safe_exit 1; } # Do not start this in the background until we are sure we are going to build [ "$$" -eq "$PM_PARENT_PID" -a -n "$DI_FILES" ] && { echo ''; (read_distinfos)& } # Do these things first time through, with or without 'make config' if [ -z "$PM_BUILDING" -a -z "$SHOW_WORK" -a -z "$NO_ACTION" ]; then dofetch () { local fetchlog allfiles echo "===>>> Launching 'make checksum' for $portdir in background" fetchlog=`pm_mktemp fetchlog-${portdir#*/}` (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#*/}.* )& } # Handle the problem of manual fetching [ -z "$PM_PACKAGES" ] && master_sites=`pm_make_b -V MASTER_SITES` if [ -n "$master_sites" ]; then # PATCHFILES may get added post-config, but we want to # do as much of this as we can, as early as we can, and # patch files are usually small anyway. distfiles=`pm_make -V ALLFILES | sed -e 's# *$##g'` [ -n "$distfiles" ] && distfiles=" ${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 DONT_FETCH=dont_fetch break fi done [ -z "$DONT_FETCH" -a -n "$distfiles" ] && dofetch fi unset master_sites distfiles file DONT_FETCH if [ -z "$FETCH_ONLY" -a ! "$PM_PACKAGES" = only ]; then TESTINT=`grep -l ^IS_INTERACTIVE Makefile` else [ -n "$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 fi # [ -z "$PM_INDEX_ONLY" ] if [ -n "$CONFIG_ONLY" ]; then [ "$$" -eq "$PM_PARENT_PID" -a -n "$PM_BUILD_ONLY_LIST" ] && PM_BUILD_ONLY_LIST=pmp_doing_build_deps [ -z "$PM_PACKAGES" ] && make_config CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${portdir}:" dep_check_type='build-depends-list run-depends-list' [ -n "$RECURSE_THOROUGH" ] && dep_check_type=all-depends-list dependency_check "$dep_check_type" [ -n "$UPDATE_REQ_BYS" -o -n "$URB_YES" ] && URB_DONE_LIST="${URB_DONE_LIST}${upg_port}:" if [ ! "$$" -eq "$PM_PARENT_PID" ]; then # Save state for the parent process to read back in echo "CONFIG_SEEN_LIST='$CONFIG_SEEN_LIST'" > $IPC_SAVE 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 safe_exit elif [ -n "$UPDATE_REQ_BYS" ]; then export URB_YES=urb_yes echo "===>>> Checking ports that depend on $upg_port" echo '' create_master_rb_list [ -n "$MASTER_RB_LIST" ] || { echo "===>>> No ports depend on $upg_port" ; echo ''; } for req_by in $MASTER_RB_LIST; do # Probably not needed, but JIC [ -d "$pdb/$req_by" ] || continue case "$URB_DONE_LIST" in *:${req_by}:*) already_done $req_by continue ;; esac [ -n "$PM_VERBOSE" ] && echo "===>>> $upg_port is required by $req_by" 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 check of ports depending on $upg_port" done echo "===>>> Done checking ports that depend on $upg_port" echo '' unset URB_YES MASTER_RB_LIST ; URB_DONE_LIST=':' fi check_fetch_only post_config $portdir fi [ -z "$PM_BUILDING" ] && export PM_BUILDING=pmbuildingmain [ -z "$PM_INDEX_ONLY" ] && pm_cd_pd $portdir if [ -n "$PM_BUILD_ONLY_LIST" ]; then case "$build_only_dl_g" in *" $pd/$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 "$RECURSE_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" dependency_check all-depends-list fi [ -z "$PM_INDEX_ONLY" ] && pm_cd_pd $portdir elif [ -z "$NO_RECURSIVE_CONFIG" -a "$$" -eq "$PM_PARENT_PID" ]; then echo "===>>> All dependencies are up to date" echo '' fi if [ -n "$NO_ACTION" -a -z "$CONFIG_ONLY" ]; then [ -n "$PM_VERBOSE" ] && echo "===>>> Build canceled due to -n flag" safe_exit fi if [ -z "$new_port" ]; then if [ -z "$PM_INDEX_ONLY" ]; then new_port=`pm_make -V PKGNAME` else new_port=`parse_index $portdir name` || fail "No INDEX entry for $origin" fi fi if [ -n "$PM_PACKAGES" -o "$PM_PACKAGES_BUILD" = doing_build_only_dep ]; then fetch_package () { local do_fetch if [ -z "$ppd" ]; then init_packages_var ppd=$PACKAGES/portmaster-download export ppd fi if [ ! -d "$ppd" ]; then pm_sv Creating $ppd pm_mkdir_s $ppd fi 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}.tbz" ]; then [ -n "$PM_VERBOSE" ] && echo "===>>> Package exists, skipping fetch" return 0 else do_fetch=1 fi else do_fetch=1 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}.tbz $PM_SU_CMD fetch $FETCH_ARGS -o $ppd ${sitepath}${1}.tbz 2>/dev/null || { pm_unlink_s ${ppd}/${1}.tbz; $PM_SU_CMD fetch $FETCH_ARGS -o $ppd ${sitepath}${1}.tbz 2>/dev/null; } fi } if [ -z "$PACKAGESITE" -a -z "$PM_PACKAGES_LOCAL" ]; then release=`uname -r` case "$release" in [678]\.[0-9]-STABLE) release=packages-${release%%\.*}-stable ;; [678]\.[0-9]-RELEASE*) release=packages-${release%-RELEASE*}-release ;; 9\.0-CURRENT) release=packages-9-current ;; *RC[0-9]*) release=${release%-RC[0-9]} release=packages-${release}-release ;; *BETA[0-9]*) release=${release%-BETA[0-9]} release=packages-${release}-release ;; esac sitepath="${PACKAGEROOT:-"http://ftp.freebsd.org"}/pub/FreeBSD/ports/`uname -p`/${release}/" unset release else sitepath="${PACKAGESITE%/}" sitepath="${sitepath%Latest}" sitepath="${sitepath%All}" fi sitepath="${sitepath%/}/${portdir%/*}/" echo "===>>> Checking package repository for latest available version" if [ -n "$LOCAL_PACKAGEDIR" ]; then if [ -z "$PM_INDEX_ONLY" ]; then s=`pm_make -V LATEST_LINK` if [ -r "${LOCAL_PACKAGEDIR}/Latest/${s}.tbz" ]; then local_package=${LOCAL_PACKAGEDIR}/Latest/${s}.tbz latest_pv=`readlink ${LOCAL_PACKAGEDIR}/Latest/${s}.tbz` latest_pv=${latest_pv##*/} else [ -n "$PM_VERBOSE" ] && echo "===>>> No local package for $new_port exists, attempting fetch" fi else if [ -r "${LOCAL_PACKAGEDIR}/All/${new_port}.tbz" ]; then local_package=${LOCAL_PACKAGEDIR}/All/${new_port}.tbz latest_pv=${local_package##*/} 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 dirlist=`pm_mktemp dl-${portdir%/*}` 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 if [ -z "$latest_pv" -a -z "$PM_PACKAGES_LOCAL" ]; then fetch_package $new_port try if [ $? -eq 0 ]; then latest_pv=$new_port fi fi 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" if [ -z "$PM_PACKAGES_LOCAL" ]; then echo ' or' fi fi [ -z "$PM_PACKAGES_LOCAL" ] && echo " ${sitepath}" echo '' echo " Check the pkg_add(1) man page for information" echo " on setting the PACKAGESITE environment variable" [ "$PM_PACKAGES" = only ] && fail $ponly_err else latest_pv=${latest_pv#*href=\"} latest_pv=${latest_pv%%\.tbz*} 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 [ -n "$PM_VERBOSE" ] && echo "===>>> 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_version -t $upg_port $latest_pv` in \<) use_package=up_newer [ -n "$PM_VERBOSE" ] && { echo "===>>> Available package ($latest_pv)"; echo " 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 [ -n "$PM_VERBOSE" ] && echo "===>>> There is a package available ($latest_pv)" fi elif [ -n "$latest_pv" ]; then case `pkg_version -t $new_port $latest_pv` in \<) # Could happen if ports tree is out of date use_package=up_old_tree [ -n "$PM_VERBOSE" ] && { echo "===>>> Available package ($latest_pv)"; echo " 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 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 '' echo "===>>> There is no valid package to install, building port instead" echo '' fi fi fi if [ -z "$use_package" ]; then if [ -n "$PM_PACKAGES" ]; then make_config if [ -z "$RECURSE_THOROUGH" ]; then echo "===>>> Starting check for build dependencies" dependency_check build-depends-list fi fi [ -z "$PM_INDEX_ONLY" ] && pm_cd_pd $portdir [ -z "$DONT_PRE_CLEAN" ] && { pm_make clean NOCLEANDEPENDS=ncd || fail 'make clean failed'; echo ''; } sleep=3 fl_read=`echo ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-${portdir#*/}.*` while [ -f "$fl_read" ]; do echo "===>>> Waiting on fetch & checksum for $portdir <<<===" tail -10 $fl_read 2>/dev/null echo '' ; echo '' sleep $sleep if [ $sleep -eq 10 ]; then sleep=3 else sleep=$(( $sleep + 1 )) fi done unset sleep if [ -n "$HIDE_BUILD" ]; then port_log=`mktemp -t port_log-${PM_PARENT_PID}-${portdir#*/}` || fail "mktemp for $1 failed" port_log_args=">> $port_log 2>&1" echo "===>>> Logging build to $port_log" fi eval pm_make $port_log_args || fail "make failed for $portdir" else [ -z "$local_package" ] && { fetch_package $latest_pv || fail "Fetch for ${latest_pv}.tbz failed"; } fi # Ignore if no old port exists if [ -n "$upg_port" -o -n "$ro_upg_port" ]; then UPGRADE_PORT="${ro_upg_port:-$upg_port}" UPGRADE_PORT_VER=`echo $UPGRADE_PORT | sed 's#.*-\(.*\)#\1#'` export UPGRADE_PORT UPGRADE_PORT_VER [ -z "$NO_BACKUP" ] && pm_pkg_create $pbu $UPGRADE_PORT if [ -n "$SAVE_SHARED" ]; then ldconfig_out=`pm_mktemp ldconfig` ldconfig -r | sed 's#.* ##' | grep -v ^$LOCALBASE_COMPAT > $ldconfig_out unset temp for file in `pkg_info -q -L $UPGRADE_PORT | sort - $ldconfig_out | \ uniq -d`; do temp="${temp}$file " done if [ -n "$temp" ]; then if [ ! -d "$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 pm_unlink $ldconfig_out ; unset ldconfig_out temp file fi find_dl_distfiles $portdir if [ -n "$REPLACE_ORIGIN" -a -n "$ro_upg_port" ]; then # Delete any existing versions of the old port pm_sv Running pkg_delete for $ro_upg_port pm_pkg_delete_s -f $ro_upg_port fi # Could be empty if -o if [ -n "$upg_port" ]; then pm_sv Running pkg_delete for $upg_port pm_pkg_delete_s -f $upg_port fi [ -z "$PM_INDEX_ONLY" ] && pm_cd_pd $portdir fi if [ -z "$RECURSE_THOROUGH" -a -z "$NO_DEP_UPDATES" ]; then echo '' ; echo "===>>> Starting check for runtime dependencies" dependency_check run-depends-list [ -z "$PM_INDEX_ONLY" ] && pm_cd_pd $portdir fi install_failed () { local upg_port 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 [ -n "$PM_SU_UNSET_PORT_LOG_ARGS" ]; then unset port_log_args else [ -n "$HIDE_BUILD" ] && echo "===>>> Logging install to $port_log" fi # Defining NO_DEPENDS ensures that we will control the installation # of the depends, not bsd.port.mk. 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" if $PM_SU_CMD pkg_add --no-deps --force ${ppd}/${latest_pv}.tbz; then [ -n "$PM_DELETE_PACKAGES" ] && { [ -n "$PM_VERBOSE" ] && echo "===>>> Deleting ${latest_pv}.tbz"; pm_unlink_s ${ppd}/${latest_pv}.tbz; } else install_failed ${latest_pv}.tbz fi 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" -a -d "$LOCALBASE_COMPAT" ]; then unset files for file in `pkg_info -q -L $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 $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 [ -d "$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" ] && distfiles=`pm_make -V ALLFILES | sed -e 's# *$##g'` if [ -n "$distfiles" ]; then distfiles=" ${distfiles} " # 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=`pm_make_b -V OPTIONSFILE` dist_list="${dist_list%options}distfiles" if [ ! -d "${dist_list%/distfiles}" ]; then pm_sv Creating ${dist_list%/distfiles} pm_mkdir_s ${dist_list%/distfiles} fi ds=`pm_make -V DIST_SUBDIR` [ -n "$ds" ] && ds="${ds}/" port_subdir="${DISTDIR}${ds}" # Also for *delete*distfiles() if [ -s distinfo ]; then distinfo=distinfo else distinfo=`pm_make -V MD5_FILE` fi dist_list_temp=`pm_mktemp dist_list` echo '# Added by portmaster' > $dist_list_temp for file in $distfiles; do size=`grep "^SIZE (${ds}${file})" $distinfo` sha256=`grep "^SHA256 (${ds}${file})" $distinfo` md5=`grep "^MD5 (${ds}${file})" $distinfo` echo "DISTFILE:${ds}${file}:SIZE=${size##* }:SHA256=${sha256##* }:MD5=${md5##* }" >> $dist_list_temp # Make sure any new distfiles get added to the list [ -z "$DONT_SCRUB_DISTFILES" -a ! "$$" -eq "$PM_PARENT_PID" ] && echo "${ds}$file" >> $DI_FILES done pm_sv Installing $dist_list pm_install_s $dist_list_temp $dist_list pm_unlink $dist_list_temp ; unset ds dist_list_temp fi if [ -n "$use_package" ]; then if grep -q DEPORIGIN $pdb/$new_port/+CONTENTS; then echo "===>>> Updating dependencies for $new_port to match installed versions" update_contents $pdb/$new_port/+CONTENTS echo '' fi fi if [ -n "$MAKE_PACKAGE" ]; then if [ -z "$use_package" ]; then echo "===>>> Creating a package for new version $new_port" pm_make_s 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" ]; then [ -z "$DONT_POST_CLEAN" ] && { pm_sv Running \'make clean\' pm_make_s clean NOCLEANDEPENDS=ncd2 ; echo ''; } fi check_dependency_files $portdir $new_port if [ -s "$grep_deps" ]; then echo "===>>> Updating dependency entry for $new_port in each dependent port" [ -n "$PM_VERBOSE" ] && echo '' while read d_port; do [ -n "$PM_VERBOSE" ] && echo "===>>> $d_port" dp_cont=$pdb/$d_port/+CONTENTS [ -e "$dp_cont" ] || continue if [ -n "$ro_opd" ]; then grep -ql "DEPORIGIN:$ro_opd$" $dp_cont && update_contents $dp_cont $portdir $new_port $ro_opd fi # Do this one last so it can get deleted as a duplicate # if ro_opd is present. if grep -ql "DEPORIGIN:$portdir$" $dp_cont; then update_contents $dp_cont $portdir $new_port fi done < $grep_deps unset d_port dp_cont do_update if [ -e "$pdb/$new_port/+REQUIRED_BY" ]; then sort $pdb/$new_port/+REQUIRED_BY | cmp -s $grep_deps - || do_update=do_update check_regular_file $pdb/$new_port/+REQUIRED_BY else do_update=do_update2 fi if [ -n "$do_update" ]; then [ -n "$PM_VERBOSE" ] && { echo ''; echo " ===>>> Updating $new_port/+REQUIRED_BY"; } pm_install_s $grep_deps $pdb/$new_port/+REQUIRED_BY fi pm_unlink $grep_deps && unset grep_deps do_update echo '' fi if [ -n "$upg_port" ]; then 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 "$UPDATE_REQ_BYS" ]; then echo "===>>> $ilist succeeded" ; echo '' fi [ -n "$PM_MULTI_BUILT" ] && PM_MULTI_BUILT="${PM_MULTI_BUILT}${new_port}:${portdir}:" INSTALLED_LIST="${INSTALLED_LIST}\t${ilist}\n" [ -e "$pdb/$new_port/+DISPLAY" ] && 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 "$URB_YES" -o -n "$UPDATE_REQ_BYS" ] && URB_DONE_LIST="${URB_DONE_LIST}${new_port}:" [ -n "$URB_YES" -o -n "$UPDATE_REQ_BYS" -o -n "$PM_FORCE" ] && $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 delete_dist_list fi fi if [ -n "$UPDATE_REQ_BYS" -a -s "$pdb/$new_port/+REQUIRED_BY" ]; then export URB_YES=urb_yes2 echo "===>>> Updating ports that depend on $new_port" echo '' create_master_rb_list for req_by in $MASTER_RB_LIST; do # Probably not needed, but JIC [ -d "$pdb/$req_by" ] || continue case "$URB_DONE_LIST" in *:${req_by}:*) already_done $req_by ; continue ;; esac # Check here since if "no" it will not prompt check_interactive $req_by || continue [ -n "$PM_VERBOSE" ] && echo "===>>> $new_port is required by $req_by" check_exclude $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 check of ports depending on $upg_port" done echo "===>>> Done updating ports that depend on $new_port" echo '' fi safe_exit #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Copyright (c) 2005-2010 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.