--- portmaster.orig	2018-01-14 21:53:23 UTC
+++ portmaster
@@ -7,9 +7,9 @@ trap trap_exit INT
 
 umask 022
 
-progcmd="$0"			# actual invocation of this program for search in ps output
-progname="${0##*/}"		# program name in messages
-program="$(realpath $0)"	# full path to program for recursive calls
+progcmd="$0"				# actual invocation of this program for search in ps output
+progname="${0##*/}"			# program name in messages
+program="$(realpath $0 || echo $0)"	# full path to program for recursive calls
 
 # Initialize crucial values for the parent, and export them for the children
 if [ -z "$PM_PARENT_PID" ]; then
@@ -45,7 +45,7 @@ if [ -z "$PM_PARENT_PID" ]; then
 	my_environment=`set`
 
 	# If we are already root, unset this to avoid potential conflict
-	[ `ps -o uid= $$` -eq 0 ] && unset PM_SU_CMD PM_SU_VERBOSE
+	[ `id -u` -eq 0 ] && unset PM_SU_CMD PM_SU_VERBOSE
 fi
 
 #=============== Begin functions we always want to have ===============
@@ -181,7 +181,7 @@ parent_exit () {
 
 		pm_v "===>>> Removing empty directories from WRKDIRPREFIX"
 		[ -n "$needws" ] && echo '' || pm_v
-		find $PM_WRKDIRPREFIX -depth -mindepth 1 -type d -empty -delete 2>/dev/null
+		find $PM_WRKDIRPREFIX -depth -mindepth 1 -maxdepth 2 -type d -empty -delete 2>/dev/null
 	fi
 
 	case "$DISPLAY_LIST" in
@@ -308,20 +308,19 @@ safe_exit () {
 	exit ${1:-0}
 } # safe_exit()
 
-flavor_part	() { expr "$1" : ".*@" >/dev/null && echo "${1#*@}"; }
-dir_part	() { echo "${1%%@*}"; }
-export_flavor	() { local flavor="$1"; if [ "$FLAVOR" != "$flavor" ]; then
-			pm_v "===>>> Setting FLAVOR to '$flavor' (was '$FLAVOR')";
-			export FLAVOR="$flavor"; fi; }
- 
+target_part	() { [ -z "${1##*:*}" ] && echo "${1#*:}" || echo install; }
+flavor_part	() { local tmp="${1%%:*}"; [ -z "${tmp##*@*}" ] && echo "${tmp#*@}"; }
+dir_part	() { local tmp="${1%%:*}"; echo "${tmp%%@*}"; }
+export_flavor	() { [ "$FLAVOR" != "$1" ] && export FLAVOR="$1"; }
+
 pm_cd     () { builtin cd $1 2>/dev/null || return 1; }
 pm_cd_pd  () { [ -n "$PM_INDEX_ONLY" ] && return 2;
 			local dir=$pd/$(dir_part $1);
 			builtin cd $dir 2>/dev/null ||
 			fail "Cannot cd to port directory: $dir"; }
 pm_isdir	() { builtin test -d "$1"; }
-pm_isdir_pd	() { local dir=$pd/$(dir_part "$1");
-			builtin test -d "$dir"; }
+pm_isdir_pd	() { local dir=$(dir_part "$1");
+			builtin test -n "$dir" -a -d "$pd/$dir"; }
 pm_kill   () { kill $* >/dev/null 2>/dev/null; }
 pm_make   () { ( unset -v CUR_DEPS INSTALLED_LIST PM_DEPTH build_l PM_URB_LIST;
 		 /usr/bin/nice /usr/bin/make $PM_MAKE_ARGS $*; ); }
@@ -332,7 +331,7 @@ pm_mktemp () {
 }
 pm_unlink () { [ -e "$1" ] && /bin/unlink $1; }
 pm_islocked	() { local locked; [ -n "$1" ] && locked=`pkg query %k "$1"` &&
-			[ "$locked" = 1 -o -e "$pdb/$1/+IGNOREME" ]; }
+			[ "$locked" = 1 ] || [ -e "$pdb/$1/+IGNOREME" ]; }
 
 # Superuser versions for commands that need root privileges
 
@@ -563,11 +562,15 @@ find_glob_dirs () {
 }
 
 origin_from_pdb () {
-	local flavor pkgname
+	local flavor pkgname origin_flavor
 
 	pkgname="$1"
 	flavor=$(pkg annotate -Sq "$pkgname" flavor)
-	pkg query '%o'"${flavor:+@$flavor}" "$pkgname" 2>/dev/null && return
+	
+	if origin_flavor=$(pkg query '%o'"${flavor:+@$flavor}" "$pkgname" 2>/dev/null); then
+		match_flavor $origin_flavor $pkgname
+		return 0
+	fi
 
 	case "$pkgname" in bsdpan-*) return 3 ;; esac
 
@@ -789,6 +792,7 @@ if [ -n "$ALWAYS_SCRUB_DISTFILES" -a -n "$DONT_SCRUB_D
 		fail "The -d and -D options are mutually exclusive"
 fi
 
+[ -n "$NO_ACTION" ] && PM_NO_MAKE_CONFIG=no_action PM_FORCE_CONFIG=""
 [ -n "$PM_NO_MAKE_CONFIG" -a -n "$PM_FORCE_CONFIG" ] && unset PM_NO_MAKE_CONFIG
 
 if [ -n "$LIST" -o -n "$LIST_PLUS" ]; then
@@ -1004,21 +1008,23 @@ get_answer_yn () {
 
 match_flavor () {
 	local origin=$(dir_part $1)
-	local flavor=$(flavor_part $1)
+	local flavor	# =$(flavor_part $1)
 	local iport="$2"
 	local dir="$pd/$origin"
 
-	[ -n "$flavor" -a -d "$dir" ] || return
+	if [ -d "$dir" ]; then
 	local IFS=' '
 	local pkgname=${iport%-*}
 	local flavors=$(pm_make -C "$dir" -V FLAVORS)
 	for flavor in $flavors; do
 		local p=$(pm_make -C "$dir" FLAVOR=$flavor -V PKGNAME)
 		if [ -n "$p" -a "${p%-*}" = "$pkgname" ]; then
-			moved_npd="$origin@$flavor"
-			break
+			echo "$origin@$flavor"
+			return
 		fi
 	done
+	fi
+	echo "$1"	# should not be reached!
 }
 
 # Find the new origin for moved ports
@@ -1056,7 +1062,8 @@ find_moved_port () {
 			fi ;;
 		${sf}\|*) moved_npd=${moved#*\|}	# New port directory
 			moved_npd=${moved_npd%%\|*}
-			[ -n $(flavor_part $moved_npd) ] && match_flavor $moved_npd $iport
+			[ -n $(flavor_part $moved_npd) ] && moved_npd=$(match_flavor $moved_npd $iport)
+				
 			echo ''
 			echo "	===>>> The $sf port moved to $moved_npd"
 			echo "	===>>> Reason: ${moved##*|}"
@@ -1146,7 +1153,6 @@ read_distinfos_all () {
 	echo ''
 
 	for origin in ${pd}/*/*; do
-#		origin=$(dir_part "$origin")
 		case "${origin#$pd/}" in
 		Mk/*|T*|distfiles/*|packages/*|*/[Mm]akefile*|CVS/*|*/CVS|base/*) continue ;; esac
 
@@ -1377,14 +1383,14 @@ if [ -n "$CHECK_PORT_DBDIR" ]; then
 		if ! pm_isdir_pd "$origin"; then
 			find_moved_port $origin $pkg nonfatal >/dev/null
 			[ -n "$moved_npd" ] || continue
-			origin=$moved_npd
+			origin=$(dir_part $moved_npd)
 		fi
 
 		if ! pm_cd $pd/$origin; then
 			echo "	===>>> $pd/$origin does not exist for $pkg"
 			continue
 		fi
-		unique_list="${unique_list}`make -V UNIQUENAME -V OPTIONS_NAME | tr '\n' ':'`"
+		unique_list="${unique_list}`pm_make -V OPTIONS_NAME | tr '\n' ':'`"
 	done <<-EOF
 	$(all_pkgs_by_origin)
 	EOF
@@ -1502,7 +1508,7 @@ check_for_updates () {
 	fi
 
 	if [ -z "$do_update" -a -z "$skip" -a -z "$PM_INDEX_ONLY" ] && pm_isdir "$pd/$origin"; then
-		if ! pm_cd $pd/$origin; then
+		if ! pm_cd $pd/$origin; then # <se> cannot happen - see pm_isdir test above
 			if pm_islocked "$iport"; then
 				echo "	===>>> Warning: Unable to cd to $pd/$origin"
 				echo "	===>>> Continuing due to $pdb/$iport/+IGNOREME"
@@ -2175,23 +2181,29 @@ update_pm_nu () {
 }
 
 update_build_l () {
-	local originflavor origin flavor iport
+	local originflavor origin flavor iport make_target
 
 	originflavor=$1 ; update_pm_nu $originflavor
 	origin=$(dir_part "$originflavor")
 	flavor=$(flavor_part "$originflavor")
 	iport="$2"
+	make_target=$3
 
 	[ -n "$PM_NO_CONFIRM" ] && return
 
 	if [ -z "$iport" ]; then
 		case "$build_l" in *\ $origin\\*) return ;; esac
-		build_l="${build_l}\tInstall $originflavor\n"
+		case $make_target in
+		install)
+			build_l="${build_l}\tInstall $originflavor\n" ;;
+		*)
+			build_l="${build_l}\tExecute make $make_target for $originflavor\n" ;;
+		esac
 		return
-	else
-		case "$build_l" in *\ $iport\ *|*\ $iport\\*) return ;; esac
 	fi
 
+	case "$build_l" in *\ $iport\ *|*\ $iport\\*) return ;; esac
+
 	find_new_port "$originflavor" # sets global variable new_port
 
 	case `pkg version -t $iport $new_port 2>/dev/null` in
@@ -2203,8 +2215,9 @@ update_build_l () {
 }
 
 update_port () {
-	local deps
+	local make_target deps
 
+	make_target=$(target_part "$1")
 	if [ -n "$2" ]; then
 		echo "===>>> Launching child to update $1 to $2"
 	else
@@ -2300,7 +2313,7 @@ make_dep_list () {
 			fail "make_dep_list: Unsupported option '$dep_type'"
 		esac
 	done
-	[ -n "$var_opt" ] && make $var_opt | tr ' ' '\n' | cut -d: -f2 | sort -u
+	[ -n "$var_opt" ] && pm_make $var_opt | tr ' ' '\n' | cut -d: -f2-3 | sort -u
 }
 
 gen_dep_list () {
@@ -2368,15 +2381,17 @@ dependency_check () {
 		rundeps=`gen_dep_list run-depends-list`
 
 		for dep in $d_port_list; do
+			# strip optional make target
+			local depdir=${dep%:*}
 			# If the port is already installed, do not mark
 			# it as a build-only dependency, or it will be
 			# installed by package and/or removed
-			pkg info -e ${dep#$pd/} &&
-				run_dl="$run_dl $dep" &&
+			pkg info -e ${depdir#$pd/} &&
+				run_dl="$run_dl $depdir" &&
 				continue
 			case "$rundeps" in
 			*" ${dep} "*|*${dep}*)
-				varname=`echo ${dep#$pd/} | sed 's#[-+/\.@]#_#g'`
+				varname=`echo ${dep#$pd/} | sed 's#[-+/\.@:]#_#g'`
 				rundep_list="$rundep_list $varname"
 				eval $varname=\"$portdir \$$varname\"
 				eval ${varname}_p=$dep
@@ -2409,7 +2424,10 @@ dependency_check () {
 
 	# Do not export, for THIS parent process only
 	[ -n "$PM_FIRST_PASS" ] && doing_dep_check=doing_dep_check
-	for d_port in $d_port_list; do
+	for d_port_target in $d_port_list; do
+		# strip optional make target
+		local d_port=${d_port_target%:*}
+		local make_target=$(target_part "$d_port_target")
 		origin="${d_port#$pd/}"
 		if [ -n "$SHOW_WORK" ]; then
 			iport=`iport_from_origin $origin`
@@ -2429,20 +2447,14 @@ dependency_check () {
 		[ -z "$PM_URB_UP" ] &&
 			case "$CUR_DEPS" in *:${origin}:*) continue ;; esac
 
-		if [ -z "$PM_INDEX_ONLY" ]; then
+		if [ -z "$PM_INDEX_ONLY" -a "$make_target" = install ]; then
 			local conflicts glob confl_p dir flavor
 			dir=$(dir_part $d_port)
 			flavor=$(flavor_part $d_port)
 			conflicts=''
-			if pm_cd "$pd/$dir"; then
-				if grep -ql ^CONFLICTS Makefile ; then
-					conflicts=`FLAVOR=$flavor pm_make_b \
-							-V CONFLICTS \
-							-V CONFLICTS_BUILD \
-							-V CONFLICTS_INSTALL`
-				fi
-			else
-				fail "Cannot cd to $dir"
+			pm_cd "$pd/$dir" || fail "Cannot cd to $dir"
+			if grep -ql ^CONFLICTS Makefile ; then
+				conflicts=`FLAVOR=$flavor pm_make_b -V CONFLICTS -V CONFLICTS_BUILD -V CONFLICTS_INSTALL`	 
 			fi
 			for glob in $conflicts; do
 				confl_p=`pkg query -g "%n-%v" $glob 2>/dev/null`
@@ -2498,7 +2510,11 @@ dependency_check () {
 			check_for_updates $iport $origin || fail 'Update failed'
 		else
 			check_interactive $origin || continue
-			update_port $origin
+			if [ "$make_target" != "install" ]; then
+				[ -z "$PM_FIRST_PASS" ] && post_clean_l="$post_clean_l $origin"
+				origin="$origin:$make_target"
+			fi
+			update_port "$origin"
 		fi
 	done
 	[ -n "$PM_FIRST_PASS" ] && unset doing_dep_check
@@ -2773,7 +2789,7 @@ multiport () {
 
 		num=$(( $num + 1 ))
 		init_term_printf "$port ${num}/${numports}"
-		("$program" $ARGS $port) || update_failed=update_failed
+		($program $ARGS $port) || update_failed=update_failed
 		. $IPC_SAVE && > $IPC_SAVE
 		[ -n "$update_failed" ] && fail "Update for $port failed"
 
@@ -3029,8 +3045,12 @@ no_valid_port () {
 	echo "===>>> Try $progname --help" ; echo '' ; safe_exit 1
 }
 
+make_target=$(target_part "$1")
+post_clean_l=""
+
 # Figure out what we are going to be working on
 if [ -z "$REPLACE_ORIGIN" ]; then
+	portdir="${1%:*}"
 	export_flavor $(flavor_part $portdir)
 	[ -n "$portdir" ] && { argv=$portdir ; unset portdir; }
 	argv=${argv:-$1} ; argv=${argv%/} ; argv=`globstrip $argv`
@@ -3061,6 +3081,8 @@ if [ -z "$REPLACE_ORIGIN" ]; then
 		unset glob_dirs
 	fi
 	unset argv
+
+	[ "$make_target" != install ] && PM_MAKE_ARGS="-DDISABLE_CONFLICTS $PM_MAKE_ARGS"
 else
 	portdir="${1#$pd/}" ; portdir="${portdir%/}"
 	export_flavor=$(flavor_part $portdir)
@@ -3142,8 +3164,9 @@ iport_from_pkgname () {
 
 	dir=$(dir_part $1)
 	flavor=$(flavor_part $1)
-	pkgname=$(FLAVOR=$flavor make -C "$pd/$dir" -V PKGNAME) || return 1
-	pkg info -x "^${pkgname%-*}"'-[^-]*' 2>/dev/null
+	pkgname=$(FLAVOR=$flavor pm_make -C "$pd/$dir" -V PKGNAME) &&
+		pkg query "%n-%v" "${pkgname%-*}"
+#	pkg info -xC "^${pkgname%-*}\$" 2>/dev/null
 }
 
 if [ -z "$upg_port" -a -z "$REPLACE_ORIGIN" ]; then
@@ -3229,11 +3252,14 @@ if [ -n "$PM_FIRST_PASS" -a -z "$FETCH_ONLY" ]; then
 		fi
 	fi
 
-	update_build_l $portdir $upg_port
+	update_build_l "$portdir" "$upg_port" "$make_target"
 elif [ -n "$FETCH_ONLY" -a -n "$PM_PACKAGES" ]; then
 	update_pm_nu $portdir
 fi
 
+# Test for necessary privileges to actually install ports
+[ -n "$NO_ACTION" ] || [ "$($PM_SU_CMD id -u)" = 0 ] || fail "Insufficient privileges to install ports (run as root or set PM_SU_CMD)"
+
 # Do these things first time through
 if [ -z "$PM_INDEX_ONLY" -a -z "$PM_BUILDING" -a -z "$SHOW_WORK" -a -z "$NO_ACTION" ]; then
 	# Do not start this in the background until we are sure we are going to proceed
@@ -3636,15 +3662,21 @@ pkg_flavor () {
 	pm_make pretty-flavors-package-names | sed -ne 's!^\([A-Za-z0-9_]*\): *'$pkg'$!\1!p';
 }
 	export_flavor=$(pkg_flavor $new_port)
-	if [ -n "$HIDE_BUILD" ] && [ -n "$(pm_make -V LICENSE)" ]; then
+	if [ -n "$HIDE_BUILD" ] && [ -n "$(pm_make -V LICENSE)" ] && [ -z "$(pm_make -V DISABLE_LICENSES)" ]; then
 		pm_make extract ask-license || fail "make extract ask-license failed for $portdir"
 	fi
+	if [ "$make_target" = "extract" -o "$make_target" = "patch" ]; then
+		eval pm_make -DNO_DEPENDS $make_target $port_log_args || fail "make $make_target failed for $portdir"
+		safe_exit
+	fi
 	eval pm_make build $port_log_args || fail "make build failed for $portdir"
+	[ "$make_target" = "build" ] && safe_exit
 
 	pm_sv Running make stage
 	# Defining NO_DEPENDS ensures that we will control the installation
 	# of the depends, not bsd.port.mk.
 	eval pm_make -DNO_DEPENDS stage $port_log_args || fail "make stage failed for $portdir"
+	[ "$make_target" = "stage" ] && safe_exit
 else
 	[ -z "$local_package" ] && {
 		fetch_package $latest_pv || fail "Fetch for ${latest_pv}.txz failed"; }
@@ -3808,7 +3840,7 @@ if [ -z "$temp" ] && pm_isdir "$LOCALBASE_COMPAT"; the
 
 	if [ -n "$files" ]; then
 		pm_sv Removing old shared libraries, and running ldconfig
-		pm_rm_s `make -V FILES:O:u FILES="$files"`
+		pm_rm_s `pm_make -V FILES:O:u FILES="$files"`
 		$PM_SU_CMD /etc/rc.d/ldconfig start > /dev/null
 	fi
 	unset temp file files
@@ -3876,9 +3908,12 @@ if [ -n "$MAKE_PACKAGE" ]; then
 fi
 
 if [ -z "$use_package" -a -z "$DONT_POST_CLEAN" ]; then
-#	export_flavor $(flavor_part $portdir)
+	for dir in $post_clean_l; do
+		pm_v "===>>> Running 'make clean' for special build dependency $dir"
+		(FLAVOR=$(flavor_part $portdir) pm_make_s -C "$pd/$dir" clean NOCLEANDEPENDS=ncd2 >/dev/null)&
+	done
 	pm_v "===>>> Running 'make clean' in the background"
-	(pm_make_s clean NOCLEANDEPENDS=ncd2 >/dev/null)&
+	(FLAVOR=$(flavor_part $portdir) pm_make_s clean NOCLEANDEPENDS=ncd2 >/dev/null)&
 	pm_v
 fi
 if [ -n "$ro_opd" ]; then
