Hello,
In my v4l-utils package I want to replace a documentation symlink with a
directory. When I was searching for the proper solution I stumbled upon
this bug.
Attached you'll find my proposal how to implement the symlink_to_dir
function. (Please disregard any indention problems for now).
I'd like to call the new function the following way:
dpkg-maintscript-helper.sh symlink_to_dir /usr/share/doc/libv4l-dev
libv4l0 -- "$@"
The first parameter is the symlink that should be replaced, the second
is the target it pointed to when an old package installed it first.
Via the "original target" it should be possible to detect any changes by
the system administrator and leave the "symlink" as is.
There are some open questions on my side:
1) Do you see a demand to also require a LASTVERSION argument?
2) Shold I also check where $SYMLINK.dpkg-remove is pointing to in the
post* scripts?
3) Is there a testbed where I can add tests for this?
4) What about downgrading packages? Would that be an use case, too?
Thanks,
Gregor
diff --git a/scripts/dpkg-maintscript-helper.sh
b/scripts/dpkg-maintscript-helper.sh
index 48793b8..36792fe 100755
--- a/scripts/dpkg-maintscript-helper.sh
+++ b/scripts/dpkg-maintscript-helper.sh
@@ -216,6 +216,55 @@ abort_mv_conffile() {
fi
}
+##
+## Functions to replace a symlink with a directory
+##
+symlink_to_dir() {
+ local SYMLINK="$1"
+ local SYMLINK_TARGET="$2"
+
+ # Skip remaining parameters up to --
+ while [ "$1" != "--" -a $# -gt 0 ]; do shift; done
+ [ $# -gt 0 ] || badusage
+ shift
+
+ [ -n "SYMLINK" ] || error "symlink parameter is missing"
+ [ -n "SYMLINK_TARGET" ] || "original symlink target is missing"
+ [ -n "$1" ] || error "maintainer script parameters are missing"
+ [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \
+ error "environment variable DPKG_MAINTSCRIPT_NAME is required"
+
+ debug "Executing $0 symlink_to_dir in $DPKG_MAINTSCRIPT_NAME" \
+ "of $DPKG_MAINTSCRIPT_PACKAGE"
+ debug "SYMLINK=$SYMLINK -> $SYMLINK_TARGET " \
+ "ACTION=$1 PARAM=$2"
+
+ case "$DPKG_MAINTSCRIPT_NAME" in
+ preinst)
+ if [ "$1" = "install" -o "$1" = "upgrade" ] && [ -n "$2" ] && [
-L "$SYMLINK" ] && [ "$(readlink "$SYMLINK")" = "$SYMLINK_TARGET" ]; then
+ mv -f "$SYMLINK" "$SYMLINK.dpkg-remove"
+ fi
+ ;;
+ postinst)
+ if [ "$1" = "configure" ] && [ -L "$SYMLINK.dpkg-remove" ]; then
+ rm -f "$SYMLINK.dpkg-remove"
+ fi
+ ;;
+ postrm)
+ if [ "$1" = "purge" ] && [ -L "$SYMLINK.dpkg-remove" ]; then
+ rm -f "$SYMLINK.dpkg-remove"
+ fi
+ if [ "$1" = "abort-install" -o "$1" = "abort-upgrade" ] && [ -n
"$2" ] && [ -L "$SYMLINK.dpkg-remove" ] && [ ! -e "$SYMLINK" ]; then
+ echo "Reinstalling $SYMLINK that was moved away"
+ mv "$SYMLINK.dpkg-remove" "$SYMLINK"
+ fi
+ ;;
+ *)
+ debug "$0 symlink_to_dir not required in $DPKG_MAINTSCRIPT_NAME"
+ ;;
+ esac
+}
+
# Common functions
debug() {
if [ -n "$DPKG_DEBUG" ]; then
@@ -244,6 +293,9 @@ Commands:
postrm.
mv_conffile <old-conf> <new-conf> [<last-version> [<package>]]
Rename a conffile. Must be called in preinst, postinst and postrm.
+ symlink_to_dir <symlink> <original-symlink-target>
+ Replace a symlink with a directory. Must be called in preinst,
+ postinst and postrm.
help
Display this usage information.
END
@@ -266,7 +318,7 @@ shift
case "$command" in
supports)
case "$1" in
- rm_conffile|mv_conffile)
+ rm_conffile|mv_conffile|symlink_to_dir)
code=0
;;
*)
@@ -289,6 +341,9 @@ rm_conffile)
mv_conffile)
mv_conffile "$@"
;;
+symlink_to_dir)
+ symlink_to_dir "$@"
+ ;;
--help|help|-?)
usage
;;