1 |
From: Zac Medico <zmedico@g.o> |
2 |
|
3 |
This includes numerous logic adjustments that are needed to support |
4 |
protected symlinks. The show_diff function now supports arbitrary |
5 |
file types. For example, a diff between two symlinks looks like this: |
6 |
|
7 |
-SYM: /foo/bar -> baz |
8 |
+SYM: /foo/bar -> blah |
9 |
|
10 |
X-Gentoo-Bug: 485598 |
11 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=485598 |
12 |
--- |
13 |
bin/etc-update | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
14 |
1 file changed, 85 insertions(+), 8 deletions(-) |
15 |
|
16 |
diff --git a/bin/etc-update b/bin/etc-update |
17 |
index 7ac6f0b..3c03d7a 100755 |
18 |
--- a/bin/etc-update |
19 |
+++ b/bin/etc-update |
20 |
@@ -51,11 +51,15 @@ do_mv_ln() { |
21 |
local src=${@:$(( $# - 1 )):1} |
22 |
local dst=${@:$(( $# - 0 )):1} |
23 |
|
24 |
- if [[ -L ${dst} ]] ; then #330221 |
25 |
+ if [[ ! -L ${src} && -L ${dst} ]] ; then #330221 |
26 |
local lfile=$(readlink "${dst}") |
27 |
[[ ${lfile} == /* ]] || lfile="${dst%/*}/${lfile}" |
28 |
echo " Target is a symlink; replacing ${lfile}" |
29 |
dst=${lfile} |
30 |
+ elif [[ -d ${dst} && ! -L ${dst} ]] ; then |
31 |
+ # If ${dst} is a directory, do not move the file |
32 |
+ # inside of it if this fails. |
33 |
+ rmdir "${dst}" || return |
34 |
fi |
35 |
|
36 |
mv "${opts[@]}" "${src}" "${dst}" |
37 |
@@ -115,6 +119,24 @@ scan() { |
38 |
continue 2 |
39 |
fi |
40 |
done |
41 |
+ if [[ -L ${file} ]] ; then |
42 |
+ if [[ -L ${live_file} && \ |
43 |
+ $(readlink "${live_file}") == $(readlink "${file}") ]] |
44 |
+ then |
45 |
+ rm -f "${file}" |
46 |
+ continue |
47 |
+ fi |
48 |
+ if [[ "${ofile:10}" != "${rfile:10}" ]] || |
49 |
+ [[ ${opath} != ${rpath} ]] |
50 |
+ then |
51 |
+ : $(( ++count )) |
52 |
+ echo "${live_file}" > "${TMP}"/files/${count} |
53 |
+ fi |
54 |
+ echo "${cfg_file}" >> "${TMP}"/files/${count} |
55 |
+ ofile="${rfile}" |
56 |
+ opath="${rpath}" |
57 |
+ continue |
58 |
+ fi |
59 |
if [[ ! -f ${file} ]] ; then |
60 |
${QUIET} || echo "Skipping non-file ${file} ..." |
61 |
continue |
62 |
@@ -124,7 +146,9 @@ scan() { |
63 |
[[ ${opath} != ${rpath} ]] |
64 |
then |
65 |
MATCHES=0 |
66 |
- if [[ ${eu_automerge} == "yes" ]] ; then |
67 |
+ if ! [[ -f ${cfg_file} && -f ${live_file} ]] ; then |
68 |
+ MATCHES=0 |
69 |
+ elif [[ ${eu_automerge} == "yes" ]] ; then |
70 |
if [[ ! -e ${cfg_file} || ! -e ${live_file} ]] ; then |
71 |
MATCHES=0 |
72 |
else |
73 |
@@ -377,17 +401,48 @@ do_file() { |
74 |
|
75 |
show_diff() { |
76 |
clear |
77 |
- local file1=$1 file2=$2 |
78 |
+ local file1=$1 file2=$2 files=("$1" "$2") \ |
79 |
+ diff_files=() file i tmpdir |
80 |
+ |
81 |
+ if [[ -L ${file1} && ! -L ${file2} && |
82 |
+ -f ${file1} && -f ${file2} ]] ; then |
83 |
+ # If a regular file replaces a symlink to a regular file, then |
84 |
+ # show the diff between the regular files (bug #330221). |
85 |
+ diff_files=("${file1}" "${file2}") |
86 |
+ else |
87 |
+ for i in 0 1 ; do |
88 |
+ if [[ ! -L ${files[$i]} && -f ${files[$i]} ]] ; then |
89 |
+ diff_files[$i]=${files[$i]} |
90 |
+ continue |
91 |
+ fi |
92 |
+ [[ -n ${tmpdir} ]] || \ |
93 |
+ tmpdir=$(mktemp -d "${TMP}/symdiff-XXX") |
94 |
+ diff_files[$i]=${tmpdir}/${i} |
95 |
+ if [[ -L ${files[$i]} ]] ; then |
96 |
+ echo "SYM: ${file1} -> $(readlink "${files[$i]}")" > \ |
97 |
+ "${diff_files[$i]}" |
98 |
+ elif [[ -d ${files[$i]} ]] ; then |
99 |
+ echo "DIR: ${file1}" > "${diff_files[$i]}" |
100 |
+ elif [[ -p ${files[$i]} ]] ; then |
101 |
+ echo "FIF: ${file1}" > "${diff_files[$i]}" |
102 |
+ else |
103 |
+ echo "DEV: ${file1}" > "${diff_files[$i]}" |
104 |
+ fi |
105 |
+ done |
106 |
+ fi |
107 |
+ |
108 |
if [[ ${using_editor} == 0 ]] ; then |
109 |
( |
110 |
echo "Showing differences between ${file1} and ${file2}" |
111 |
- diff_command "${file1}" "${file2}" |
112 |
+ diff_command "${diff_files[0]}" "${diff_files[1]}" |
113 |
) | ${pager} |
114 |
else |
115 |
echo "Beginning of differences between ${file1} and ${file2}" |
116 |
- diff_command "${file1}" "${file2}" |
117 |
+ diff_command "${diff_files[0]}" "${diff_files[1]}" |
118 |
echo "End of differences between ${file1} and ${file2}" |
119 |
fi |
120 |
+ |
121 |
+ [[ -n ${tmpdir} ]] && rm -rf "${tmpdir}" |
122 |
} |
123 |
|
124 |
do_cfg() { |
125 |
@@ -395,14 +450,14 @@ do_cfg() { |
126 |
local ofile=$2 |
127 |
local -i my_input=0 |
128 |
|
129 |
- until (( my_input == -1 )) || [ ! -f "${file}" ] ; do |
130 |
+ until (( my_input == -1 )) || [[ ! -f ${file} && ! -L ${file} ]] ; do |
131 |
if [[ "${OVERWRITE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then |
132 |
my_input=1 |
133 |
elif [[ "${DELETE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then |
134 |
my_input=2 |
135 |
else |
136 |
show_diff "${ofile}" "${file}" |
137 |
- if [[ -L ${file} ]] ; then |
138 |
+ if [[ -L ${file} && ! -L ${ofile} ]] ; then |
139 |
cat <<-EOF |
140 |
|
141 |
------------------------------------------------------------- |
142 |
@@ -461,6 +516,19 @@ do_merge() { |
143 |
local ofile="${2}" |
144 |
local mfile="${TMP}/${2}.merged" |
145 |
local -i my_input=0 |
146 |
+ |
147 |
+ if [[ -L ${file} && -L ${ofile} ]] ; then |
148 |
+ echo "Both files are symlinks, so they will not be merged." |
149 |
+ return 0 |
150 |
+ elif [[ ! -f ${file} ]] ; then |
151 |
+ echo "Non-regular file cannot be merged: ${file}" |
152 |
+ return 0 |
153 |
+ elif [[ ! -f ${ofile} ]] ; then |
154 |
+ echo "Non-regular file cannot be merged: ${ofile}" |
155 |
+ return 0 |
156 |
+ fi |
157 |
+ |
158 |
+ |
159 |
echo "${file} ${ofile} ${mfile}" |
160 |
|
161 |
if [[ -e ${mfile} ]] ; then |
162 |
@@ -533,9 +601,18 @@ do_distconf() { |
163 |
for (( count = 0; count <= 9999; ++count )) ; do |
164 |
suffix=$(printf ".dist_%04i" ${count}) |
165 |
efile="${ofile}${suffix}" |
166 |
- if [[ ! -f ${efile} ]] ; then |
167 |
+ if [[ ! -f ${efile} && ! -L ${efile} ]] ; then |
168 |
mv ${mv_opts} "${file}" "${efile}" |
169 |
break |
170 |
+ elif [[ -L ${efile} && -L ${file} ]] ; then |
171 |
+ if [[ $(readlink "${efile}") == $(readlink "${file}") ]] ; then |
172 |
+ # replace identical copy |
173 |
+ mv "${file}" "${efile}" |
174 |
+ break |
175 |
+ fi |
176 |
+ elif [[ -L ${efile} || -L ${file} ]] ; then |
177 |
+ # not the same file types |
178 |
+ continue |
179 |
elif diff_command "${file}" "${efile}" &> /dev/null; then |
180 |
# replace identical copy |
181 |
mv "${file}" "${efile}" |
182 |
-- |
183 |
2.0.4 |