etc-update: handle symlinked files
authorMike Frysinger <vapier@gentoo.org>
Sun, 11 Mar 2012 03:57:43 +0000 (22:57 -0500)
committerMike Frysinger <vapier@gentoo.org>
Sun, 11 Mar 2012 03:57:43 +0000 (22:57 -0500)
If the config file is symlinked somewhere, then update the target rather
then discarding the symlink and replacing it with a real file.

URL: http://bugs.gentoo.org/330221
Reported-by: Jack Byer <ftn768@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
bin/etc-update

index 7b05f113777fbfa6cd75b1789f6050a06ce0caf0..644512a96dc3d7dd7b143be81663618b6f49913d 100755 (executable)
@@ -43,6 +43,24 @@ diff_command() {
        ${cmd//%file2/$2}
 }
 
+# Usage: do_mv_ln [options] <src> <dst>
+# Files have to be the last two args, and has to be
+# files so we can handle symlinked target sanely.
+do_mv_ln() {
+       local opts=( ${@:1:$(( $# - 2 ))} )
+       local src=${@:$(( $# - 1 )):1}
+       local dst=${@:$(( $# - 0 )):1}
+
+       if [[ -L ${dst} ]] ; then #330221
+               local lfile=$(readlink "${dst}")
+               [[ ${lfile} == /* ]] || lfile="${dst%/*}/${lfile}"
+               echo " Target is a symlink; replacing ${lfile}"
+               dst=${lfile}
+       fi
+
+       mv "${opts[@]}" "${src}" "${dst}"
+}
+
 scan() {
        echo "Scanning Configuration files..."
        rm -rf "${TMP}"/files > /dev/null 2>&1
@@ -121,7 +139,7 @@ scan() {
 
                                if [[ ${MATCHES} == 1 ]] ; then
                                        echo "Automerging trivial changes in: ${live_file}"
-                                       mv "${cfg_file}" "${live_file}"
+                                       do_mv_ln "${cfg_file}" "${live_file}"
                                        continue
                                else
                                        : $(( ++count ))
@@ -404,12 +422,12 @@ do_cfg() {
 
                case ${my_input} in
                        1)      echo "Replacing ${ofile} with ${file}"
-                               mv ${mv_opts} ${file} ${ofile}
+                               do_mv_ln ${mv_opts} "${file}" "${ofile}"
                                [ -n "${OVERWRITE_ALL}" ] && my_input=-1
                                continue
                                ;;
                        2)      echo "Deleting ${file}"
-                               rm ${rm_opts} ${file}
+                               rm ${rm_opts} "${file}"
                                [ -n "${DELETE_ALL}" ] && my_input=-1
                                continue
                                ;;
@@ -474,7 +492,7 @@ do_merge() {
                                                chown --reference="${ofile}" "${mfile}"
                                                chmod --reference="${ofile}" "${mfile}"
                                        fi
-                                       mv ${mv_opts} "${mfile}" "${ofile}"
+                                       do_mv_ln ${mv_opts} "${mfile}" "${ofile}"
                                        rm ${rm_opts} "${file}"
                                        return 255
                                        ;;