From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <gentoo-commits+bounces-744453-garchives=archives.gentoo.org@lists.gentoo.org>
Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80])
	by finch.gentoo.org (Postfix) with ESMTP id C14E4138A6C
	for <garchives@archives.gentoo.org>; Mon,  3 Nov 2014 04:42:06 +0000 (UTC)
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id 8600EE091B;
	Mon,  3 Nov 2014 04:42:04 +0000 (UTC)
Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183])
	(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by pigeon.gentoo.org (Postfix) with ESMTPS id BD72AE091E
	for <gentoo-commits@lists.gentoo.org>; Mon,  3 Nov 2014 04:42:03 +0000 (UTC)
Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52])
	(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id 3B04D34046F
	for <gentoo-commits@lists.gentoo.org>; Mon,  3 Nov 2014 04:42:02 +0000 (UTC)
Received: from localhost.localdomain (localhost [127.0.0.1])
	by oystercatcher.gentoo.org (Postfix) with ESMTP id 5CE5B9526
	for <gentoo-commits@lists.gentoo.org>; Mon,  3 Nov 2014 04:42:00 +0000 (UTC)
From: "Zac Medico" <zmedico@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: 8bit
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" <zmedico@gentoo.org>
Message-ID: <1414970138.6659c00a580254f68460608b4cdc5df8e057d17c.zmedico@gentoo>
Subject: [gentoo-commits] proj/portage:master commit in: bin/
X-VCS-Repository: proj/portage
X-VCS-Files: bin/etc-update
X-VCS-Directories: bin/
X-VCS-Committer: zmedico
X-VCS-Committer-Name: Zac Medico
X-VCS-Revision: 6659c00a580254f68460608b4cdc5df8e057d17c
X-VCS-Branch: master
Date: Mon,  3 Nov 2014 04:42:00 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
X-Archives-Salt: 6ee7469d-cfd7-4c2c-bf0d-71c3e0f38430
X-Archives-Hash: 2f1188bb640198fc48527c75f32fbb54

commit:     6659c00a580254f68460608b4cdc5df8e057d17c
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 26 09:41:09 2014 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Nov  2 23:15:38 2014 +0000
URL:        http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=6659c00a

etc-update: symlink support for bug #485598

This includes numerous logic adjustments that are needed to support
protected symlinks. The show_diff function now supports arbitrary
file types. For example, a diff between two symlinks looks like this:

-SYM: /foo/bar -> baz
+SYM: /foo/bar -> blah

X-Gentoo-Bug: 485598
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=485598

---
 bin/etc-update | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 87 insertions(+), 8 deletions(-)

diff --git a/bin/etc-update b/bin/etc-update
index 7ac6f0b..1d78e96 100755
--- a/bin/etc-update
+++ b/bin/etc-update
@@ -51,11 +51,15 @@ do_mv_ln() {
 	local src=${@:$(( $# - 1 )):1}
 	local dst=${@:$(( $# - 0 )):1}
 
-	if [[ -L ${dst} ]] ; then #330221
+	if [[ ! -L ${src} && -L ${dst} ]] ; then #330221
 		local lfile=$(readlink "${dst}")
 		[[ ${lfile} == /* ]] || lfile="${dst%/*}/${lfile}"
 		echo " Target is a symlink; replacing ${lfile}"
 		dst=${lfile}
+	elif [[ -d ${dst} && ! -L ${dst} ]] ; then
+		# If ${dst} is a directory, do not move the file
+		# inside of it if this fails.
+		rmdir "${dst}" || return
 	fi
 
 	mv "${opts[@]}" "${src}" "${dst}"
@@ -115,6 +119,24 @@ scan() {
 					continue 2
 				fi
 			done
+			if [[ -L ${file} ]] ; then
+				if [[ -L ${live_file} && \
+					$(readlink "${live_file}") == $(readlink "${file}") ]]
+				then
+					rm -f "${file}"
+					continue
+				fi
+				if [[ "${ofile:10}" != "${rfile:10}" ]] ||
+				   [[ ${opath} != ${rpath} ]]
+				then
+					: $(( ++count ))
+					echo "${live_file}" > "${TMP}"/files/${count}
+				fi
+				echo "${cfg_file}" >> "${TMP}"/files/${count}
+				ofile="${rfile}"
+				opath="${rpath}"
+				continue
+			fi
 			if [[ ! -f ${file} ]] ; then
 				${QUIET} || echo "Skipping non-file ${file} ..."
 				continue
@@ -124,7 +146,9 @@ scan() {
 			   [[ ${opath} != ${rpath} ]]
 			then
 				MATCHES=0
-				if [[ ${eu_automerge} == "yes" ]] ; then
+				if ! [[ -f ${cfg_file} && -f ${live_file} ]] ; then
+					MATCHES=0
+				elif [[ ${eu_automerge} == "yes" ]] ; then
 					if [[ ! -e ${cfg_file} || ! -e ${live_file} ]] ; then
 						MATCHES=0
 					else
@@ -377,17 +401,50 @@ do_file() {
 
 show_diff() {
 	clear
-	local file1=$1 file2=$2
+	local file1=$1 file2=$2 files=("$1" "$2") \
+		diff_files=() file i tmpdir
+
+	if [[ -L ${file1} && ! -L ${file2} &&
+		-f ${file1} && -f ${file2} ]] ; then
+		# If a regular file replaces a symlink to a regular file, then
+		# show the diff between the regular files (bug #330221).
+		diff_files=("${file1}" "${file2}")
+	else
+		for i in 0 1 ; do
+			if [[ ! -L ${files[$i]} && -f ${files[$i]} ]] ; then
+				diff_files[$i]=${files[$i]}
+				continue
+			fi
+			[[ -n ${tmpdir} ]] || \
+				tmpdir=$(mktemp -d "${TMP}/symdiff-XXX")
+			diff_files[$i]=${tmpdir}/${i}
+			if [[ ! -L ${files[$i]} && ! -e ${files[$i]} ]] ; then
+				echo "/dev/null" > "${diff_files[$i]}"
+			elif [[ -L ${files[$i]} ]] ; then
+				echo "SYM: ${file1} -> $(readlink "${files[$i]}")" > \
+					"${diff_files[$i]}"
+			elif [[ -d ${files[$i]} ]] ; then
+				echo "DIR: ${file1}" > "${diff_files[$i]}"
+			elif [[ -p ${files[$i]} ]] ; then
+				echo "FIF: ${file1}" > "${diff_files[$i]}"
+			else
+				echo "DEV: ${file1}" > "${diff_files[$i]}"
+			fi
+		done
+	fi
+
 	if [[ ${using_editor} == 0 ]] ; then
 		(
 			echo "Showing differences between ${file1} and ${file2}"
-			diff_command "${file1}" "${file2}"
+			diff_command "${diff_files[0]}" "${diff_files[1]}"
 		) | ${pager}
 	else
 		echo "Beginning of differences between ${file1} and ${file2}"
-		diff_command "${file1}" "${file2}"
+		diff_command "${diff_files[0]}" "${diff_files[1]}"
 		echo "End of differences between ${file1} and ${file2}"
 	fi
+
+	[[ -n ${tmpdir} ]] && rm -rf "${tmpdir}"
 }
 
 do_cfg() {
@@ -395,14 +452,14 @@ do_cfg() {
 	local ofile=$2
 	local -i my_input=0
 
-	until (( my_input == -1 )) || [ ! -f "${file}" ] ; do
+	until (( my_input == -1 )) || [[ ! -f ${file} && ! -L ${file} ]] ; do
 		if [[ "${OVERWRITE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then
 			my_input=1
 		elif [[ "${DELETE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then
 			my_input=2
 		else
 			show_diff "${ofile}" "${file}"
-			if [[ -L ${file} ]] ; then
+			if [[ -L ${file} && ! -L ${ofile} ]] ; then
 				cat <<-EOF
 
 					-------------------------------------------------------------
@@ -461,6 +518,19 @@ do_merge() {
 	local ofile="${2}"
 	local mfile="${TMP}/${2}.merged"
 	local -i my_input=0
+
+	if [[ -L ${file} && -L ${ofile} ]] ; then
+		echo "Both files are symlinks, so they will not be merged."
+		return 0
+	elif [[ ! -f ${file} ]] ; then
+		echo "Non-regular file cannot be merged: ${file}"
+		return 0
+	elif [[ ! -f ${ofile} ]] ; then
+		echo "Non-regular file cannot be merged: ${ofile}"
+		return 0
+	fi
+
+
 	echo "${file} ${ofile} ${mfile}"
 
 	if [[ -e ${mfile} ]] ; then
@@ -533,9 +603,18 @@ do_distconf() {
 	for (( count = 0; count <= 9999; ++count )) ; do
 		suffix=$(printf ".dist_%04i" ${count})
 		efile="${ofile}${suffix}"
-		if [[ ! -f ${efile} ]] ; then
+		if [[ ! -f ${efile} && ! -L ${efile} ]] ; then
 			mv ${mv_opts} "${file}" "${efile}"
 			break
+		elif [[ -L ${efile} && -L ${file} ]] ; then
+			if [[ $(readlink "${efile}") == $(readlink "${file}") ]] ; then
+				# replace identical copy
+				mv "${file}" "${efile}"
+				break
+			fi
+		elif [[ -L ${efile} || -L ${file} ]] ; then
+			# not the same file types
+			continue
 		elif diff_command "${file}" "${efile}" &> /dev/null; then
 			# replace identical copy
 			mv "${file}" "${efile}"