3 # This is the X Strike Force shell library for X Window System package
4 # maintainer scripts. It serves to define shell functions commonly used by
5 # such packages, and performs some error checking necessary for proper operation
6 # of those functions. By itself, it does not "do" much; the maintainer scripts
7 # invoke the functions defined here to accomplish package installation and
10 # If you are reading this within a Debian package maintainer script (e.g.,
11 # /var/lib/dpkg)info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
12 # skip past this library by scanning forward in this file to the string
15 SOURCE_VERSION=@SOURCE_VERSION@
16 OFFICIAL_BUILD=@OFFICIAL_BUILD@
18 # Use special abnormal exit codes so that problems with this library are more
19 # easily tracked down.
20 SHELL_LIB_INTERNAL_ERROR=86
21 SHELL_LIB_THROWN_ERROR=74
22 SHELL_LIB_USAGE_ERROR=99
24 # old -> new variable names
25 if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
26 DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
28 if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
29 DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
32 # initial sanity checks
33 if [ -z "$THIS_PACKAGE" ]; then
35 Error: package maintainer script attempted to use shell library without
36 definining \$THIS_PACKAGE shell variable. Please report the package name,
37 version, and the text of this error message to the Debian Bug Tracking System.
38 Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
39 instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
40 "doc-debian" package, or install the "reportbug" package and use the command of
41 the same name to file a report against version $SOURCE_VERSION of this package.
43 exit $SHELL_LIB_USAGE_ERROR
46 if [ -z "$THIS_SCRIPT" ]; then
48 Error: package maintainer script attempted to use shell library without
49 definining \$THIS_SCRIPT shell variable. Please report the package name,
50 version, and the text of this error message to the Debian Bug Tracking System.
51 Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
52 instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
53 "doc-debian" package, or install the "reportbug" package and use the command of
54 the same name to file a report against version $SOURCE_VERSION of the
55 "$THIS_PACKAGE" package.
57 exit $SHELL_LIB_USAGE_ERROR
60 ARCHITECTURE="$(dpkg --print-installation-architecture)"
62 if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
68 if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
72 if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
77 message \"Received signal. Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
79 exit 1" HUP INT QUIT TERM
82 # syntax: reject_nondigits [ operand ... ]
84 # scan operands (typically shell variables whose values cannot be trusted) for
85 # characters other than decimal digits and barf if any are found
87 # does the operand contain anything but digits?
88 if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
89 # can't use die(), because it wraps message() which wraps this function
90 echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
91 "possibly malicious garbage \"$1\"" >&2
92 exit $SHELL_LIB_THROWN_ERROR
98 reject_whitespace () {
99 # syntax: reject_whitespace [ operand ]
101 # scan operand (typically a shell variable whose value cannot be trusted) for
102 # whitespace characters and barf if any are found
104 # does the operand contain any whitespace?
105 if expr "$1" : "[[:space:]]" > /dev/null 2>&1; then
106 # can't use die(), because I want to avoid forward references
107 echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_whitespace() encountered" \
108 "possibly malicious garbage \"$1\"" >&2
109 exit $SHELL_LIB_THROWN_ERROR
114 reject_unlikely_path_chars () {
115 # syntax: reject_unlikely_path_chars [ operand ... ]
117 # scan operands (typically shell variables whose values cannot be trusted) for
118 # characters unlikely to be seen in a path and which the shell might
119 # interpret and barf if any are found
120 while [ -n "$1" ]; do
121 # does the operand contain any funny characters?
122 if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
123 # can't use die(), because I want to avoid forward references
124 echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
125 "encountered possibly malicious garbage \"$1\"" >&2
126 exit $SHELL_LIB_THROWN_ERROR
132 # Query the terminal to establish a default number of columns to use for
133 # displaying messages to the user. This is used only as a fallback in the
134 # event the COLUMNS variable is not set. ($COLUMNS can react to SIGWINCH while
135 # the script is running, and this cannot, only being calculated once.)
136 DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
137 if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
142 # pretty-print messages of arbitrary length
143 reject_nondigits "$COLUMNS"
144 echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
148 # syntax: observe message ...
150 # issue observational message suitable for logging someday when support for
152 if [ -n "$DEBUG_XORG_PACKAGE" ]; then
153 message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
158 # syntax: warn message ...
160 # issue warning message suitable for logging someday when support for
161 # it exists in dpkg; also send to standard error
162 message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
166 # syntax: die message ...
168 # exit script with error message
169 message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
170 exit $SHELL_LIB_THROWN_ERROR
174 # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
175 message "internal error: $*"
176 if [ -n "$OFFICIAL_BUILD" ]; then
177 message "Please report a bug in the $THIS_SCRIPT script of the" \
178 "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
179 "Tracking System. Include all messages above that mention the" \
180 "$THIS_PACKAGE package. Visit " \
181 "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
182 "instructions, read the file" \
183 "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
184 "package, or install the reportbug package and use the command of" \
185 "the same name to file a report."
187 exit $SHELL_LIB_INTERNAL_ERROR
191 message "usage error: $*"
192 message "Please report a bug in the $THIS_SCRIPT script of the" \
193 "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
194 "Tracking System. Include all messages above that mention the" \
195 "$THIS_PACKAGE package. Visit " \
196 "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
197 "instructions, read the file" \
198 "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
199 "package, or install the reportbug package and use the command of" \
200 "the same name to file a report."
201 exit $SHELL_LIB_USAGE_ERROR
206 # returns what symlink should point to; i.e., what the "sane" answer is
207 # Keep this in sync with the debian/*.links files.
208 # This is only needed for symlinks to directories.
210 # XXX: Most of these look wrong in the X11R7 world and need to be fixed.
211 # If we've stopped using this function, fixing it might enable us to re-enable
212 # it again and catch more errors.
214 /etc/X11/xkb/compiled) echo /var/lib/xkb ;;
215 /etc/X11/xkb/xkbcomp) echo /usr/X11R6/bin/xkbcomp ;;
216 /usr/X11R6/lib/X11/app-defaults) echo /etc/X11/app-defaults ;;
217 /usr/X11R6/lib/X11/fs) echo /etc/X11/fs ;;
218 /usr/X11R6/lib/X11/lbxproxy) echo /etc/X11/lbxproxy ;;
219 /usr/X11R6/lib/X11/proxymngr) echo /etc/X11/proxymngr ;;
220 /usr/X11R6/lib/X11/rstart) echo /etc/X11/rstart ;;
221 /usr/X11R6/lib/X11/twm) echo /etc/X11/twm ;;
222 /usr/X11R6/lib/X11/xdm) echo /etc/X11/xdm ;;
223 /usr/X11R6/lib/X11/xinit) echo /etc/X11/xinit ;;
224 /usr/X11R6/lib/X11/xkb) echo /etc/X11/xkb ;;
225 /usr/X11R6/lib/X11/xserver) echo /etc/X11/xserver ;;
226 /usr/X11R6/lib/X11/xsm) echo /etc/X11/xsm ;;
227 /usr/bin/X11) echo ../X11R6/bin ;;
228 /usr/bin/rstartd) echo ../X11R6/bin/rstartd ;;
229 /usr/include/X11) echo ../X11R6/include/X11 ;;
230 /usr/lib/X11) echo ../X11R6/lib/X11 ;;
231 *) internal_error "maplink() called with unknown path \"$1\"" ;;
236 # given a supplied set of pathnames, break each one up by directory and do an
237 # ls -dl on each component, cumulatively; i.e.
238 # analyze_path /usr/X11R6/bin -> ls -dl /usr /usr/X11R6 /usr/X11R6/bin
239 # Thanks to Randolph Chung for this clever hack.
243 while [ -n "$1" ]; do
244 reject_whitespace "$1"
246 message "Analyzing $1:"
247 for f in $(echo "$1" | tr / \ ); do
248 if [ -e /$g$f ]; then
249 ls -dl /$g$f /$g$f.dpkg-* 2> /dev/null || true
252 message "/$g$f: nonexistent; directory contents of /$g:"
262 local f p dpkg_info_dir possible_culprits smoking_guns bad_packages package \
265 reject_whitespace "$1"
266 message "Searching for overlapping packages..."
267 dpkg_info_dir=/var/lib/dpkg/info
268 if [ -d $dpkg_info_dir ]; then
269 if [ "$(echo $dpkg_info_dir/*.list)" != "$dpkg_info_dir/*.list" ]; then
270 possible_culprits=$(ls -1 $dpkg_info_dir/*.list | egrep -v \
271 "(xbase-clients|x11-common|xfs|xlibs)")
272 if [ -n "$possible_culprits" ]; then
273 smoking_guns=$(grep -l "$1" $possible_culprits || true)
274 if [ -n "$smoking_guns" ]; then
275 bad_packages=$(printf "\\n")
276 for f in $smoking_guns; do
277 # too bad you can't nest parameter expansion voodoo
278 p=${f%*.list} # strip off the trailing ".list"
279 package=${p##*/} # strip off the directories
280 bad_packages=$(printf "%s\n%s" "$bad_packages" "$package")
283 The following packages appear to have file overlaps with the X.Org packages;
284 these packages are either very old, or in violation of Debian Policy. Try
285 upgrading each of these packages to the latest available version if possible:
286 for example, with the command "apt-get install". If no newer version of a
287 package is available, you will have to remove it; for example, with the command
288 "apt-get remove". If even the latest available version of the package has
289 this file overlap, please file a bug against that package with the Debian Bug
290 Tracking System. You may want to refer the package maintainer to section 12.8
291 of the Debian Policy manual.
295 message "The overlapping packages are: $bad_packages"
297 message "no overlaps found."
301 message "cannot search; no matches for $dpkg_info_dir/*.list."
304 message "cannot search; $dpkg_info_dir does not exist."
308 # we require a readlink command or shell function
309 if ! which readlink > /dev/null 2>&1; then
310 message "The readlink command was not found. Please install version" \
311 "1.13.1 or later of the debianutils package."
313 # returns what symlink in $1 actually points to
314 perl -e '$l = shift; exit 1 unless -l $l; $r = readlink $l; exit 1 unless $r; print "$r\n"' "$1"
319 # syntax: check_symlink symlink
321 # See if specified symlink points where it is supposed to. Return 0 if it
322 # does, and 1 if it does not.
324 # Primarily used by check_symlinks_and_warn() and check_symlinks_and_bomb().
329 if [ $# -ne 1 ]; then
330 usage_error "check_symlink() called with wrong number of arguments;" \
332 exit $SHELL_LIB_USAGE_ERROR
337 if [ "$(maplink "$symlink")" = "$(readlink "$symlink")" ]; then
344 check_symlinks_and_warn () {
345 # syntax: check_symlinks_and_warn symlink ...
347 # For each argument, check for symlink sanity, and warn if it isn't sane.
349 # Call this function from a preinst script in the event $1 is "upgrade" or
355 if [ $# -lt 1 ]; then
356 usage_error "check_symlinks_and_warn() called with wrong number of" \
357 "arguments; expected at least 1, got $#"
358 exit $SHELL_LIB_USAGE_ERROR
361 while [ -n "$1" ]; do
363 if [ -L "$symlink" ]; then
364 if ! check_symlink "$symlink"; then
365 observe "$symlink symbolic link points to wrong location" \
366 "$(readlink "$symlink"); removing"
369 elif [ -e "$symlink" ]; then
370 errmsg="$symlink exists and is not a symbolic link; this package cannot"
371 errmsg="$errmsg be installed until this"
372 if [ -f "$symlink" ]; then
373 errmsg="$errmsg file"
374 elif [ -d "$symlink" ]; then
375 errmsg="$errmsg directory"
377 errmsg="$errmsg thing"
379 errmsg="$errmsg is removed"
386 check_symlinks_and_bomb () {
387 # syntax: check_symlinks_and_bomb symlink ...
389 # For each argument, check for symlink sanity, and bomb if it isn't sane.
391 # Call this function from a postinst script.
393 local problem symlink
396 if [ $# -lt 1 ]; then
397 usage_error "check_symlinks_and_bomb() called with wrong number of"
398 "arguments; expected at least 1, got $#"
399 exit $SHELL_LIB_USAGE_ERROR
402 while [ -n "$1" ]; do
405 if [ -L "$symlink" ]; then
406 if ! check_symlink "$symlink"; then
408 warn "$symlink symbolic link points to wrong location" \
409 "$(readlink "$symlink")"
411 elif [ -e "$symlink" ]; then
413 warn "$symlink is not a symbolic link"
416 warn "$symlink symbolic link does not exist"
418 if [ -n "$problem" ]; then
419 analyze_path "$symlink" "$(readlink "$symlink")"
420 find_culprits "$symlink"
421 die "bad symbolic links on system"
428 # run $UPDATECMDS in $FONTDIRS
430 local dir cmd shortcmd x_font_dir_prefix
432 x_font_dir_prefix="/usr/share/fonts/X11"
434 if [ -z "$UPDATECMDS" ]; then
435 usage_error "font_update() called but \$UPDATECMDS not set"
437 if [ -z "$FONTDIRS" ]; then
438 usage_error "font_update() called but \$FONTDIRS not set"
441 reject_unlikely_path_chars "$UPDATECMDS"
442 reject_unlikely_path_chars "$FONTDIRS"
444 for dir in $FONTDIRS; do
445 if [ -d "$x_font_dir_prefix/$dir" ]; then
446 for cmd in $UPDATECMDS; do
447 if which "$cmd" > /dev/null 2>&1; then
449 observe "running $shortcmd in $dir font directory"
451 if [ "$shortcmd" = "update-fonts-alias" ]; then
452 cmd_opts=--x11r7-layout
454 if [ "$shortcmd" = "update-fonts-dir" ]; then
455 cmd_opts=--x11r7-layout
457 if [ "$shortcmd" = "update-fonts-scale" ]; then
458 cmd_opts=--x11r7-layout
460 $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
461 "failed; font directory data may not" \
464 warn "$cmd not found; not updating corresponding $dir font" \
469 warn "$dir is not a directory; not updating font directory data"
474 remove_conffile_prepare () {
475 # syntax: remove_conffile_prepare filename official_md5sum ...
477 # Check a conffile "filename" against a list of canonical MD5 checksums.
478 # If the file's current MD5 checksum matches one of the "official_md5sum"
479 # operands provided, then prepare the conffile for removal from the system.
480 # We defer actual deletion until the package is configured so that we can
481 # roll this operation back if package installation fails.
483 # Call this function from a preinst script in the event $1 is "upgrade" or
484 # "install" and verify $2 to ensure the package is being upgraded from a
485 # version (or installed over a version removed-but-not-purged) prior to the
486 # one in which the conffile was obsoleted.
488 local conffile current_checksum
491 if [ $# -lt 2 ]; then
492 usage_error "remove_conffile_prepare() called with wrong number of" \
493 "arguments; expected at least 2, got $#"
494 exit $SHELL_LIB_USAGE_ERROR
500 # does the conffile even exist?
501 if [ -e "$conffile" ]; then
502 # calculate its checksum
503 current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
504 # compare it to each supplied checksum
505 while [ -n "$1" ]; do
506 if [ "$current_checksum" = "$1" ]; then
507 # we found a match; move the confffile and stop looking
508 observe "preparing obsolete conffile $conffile for removal"
509 mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
517 remove_conffile_lookup () {
518 # syntax: remove_conffile_lookup package filename
520 # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
521 # if it matches the actual file's md5sum.
523 # Call this function when you would call remove_conffile_prepare but only
524 # want to check against dpkg's status database instead of known checksums.
526 local package conffile old_md5sum
529 if [ $# -ne 2 ]; then
530 usage_error "remove_conffile_lookup() called with wrong number of" \
531 "arguments; expected 1, got $#"
532 exit $SHELL_LIB_USAGE_ERROR
538 if ! [ -e "$conffile" ]; then
541 old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
542 awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
543 if [ -n "$old_md5sum" ]; then
544 remove_conffile_prepare "$conffile" "$old_md5sum"
548 remove_conffile_commit () {
549 # syntax: remove_conffile_commit filename
551 # Complete the removal of a conffile "filename" that has become obsolete.
553 # Call this function from a postinst script after having used
554 # remove_conffile_prepare() in the preinst.
559 if [ $# -ne 1 ]; then
560 usage_error "remove_conffile_commit() called with wrong number of" \
561 "arguments; expected 1, got $#"
562 exit $SHELL_LIB_USAGE_ERROR
567 # if the temporary file created by remove_conffile_prepare() exists, remove it
568 if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
569 observe "committing removal of obsolete conffile $conffile"
570 rm "$conffile.$THIS_PACKAGE-tmp"
574 remove_conffile_rollback () {
575 # syntax: remove_conffile_rollback filename
577 # Roll back the removal of a conffile "filename".
579 # Call this function from a postrm script in the event $1 is "abort-upgrade"
580 # or "abort-install" is after having used remove_conffile_prepare() in the
586 if [ $# -ne 1 ]; then
587 usage_error "remove_conffile_rollback() called with wrong number of" \
588 "arguments; expected 1, got $#"
589 exit $SHELL_LIB_USAGE_ERROR
594 # if the temporary file created by remove_conffile_prepare() exists, move it
596 if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
597 observe "rolling back removal of obsolete conffile $conffile"
598 mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
602 replace_conffile_with_symlink_prepare () {
603 # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
604 # official_md5sum ...
606 # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
607 # If the file's current MD5 checksum matches one of the "official_md5sum"
608 # operands provided, then prepare the conffile for removal from the system.
609 # We defer actual deletion until the package is configured so that we can
610 # roll this operation back if package installation fails. Otherwise copy it
611 # to newfilename and let dpkg handle it through conffiles mechanism.
613 # Call this function from a preinst script in the event $1 is "upgrade" or
614 # "install" and verify $2 to ensure the package is being upgraded from a
615 # version (or installed over a version removed-but-not-purged) prior to the
616 # one in which the conffile was obsoleted.
618 local conffile current_checksum
621 if [ $# -lt 3 ]; then
622 usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
623 " number of arguments; expected at least 3, got $#"
624 exit $SHELL_LIB_USAGE_ERROR
632 remove_conffile_prepare "$_oldconffile" "$@"
633 # If $oldconffile still exists, then md5sums didn't match.
634 # Copy it to new one.
635 if [ -f "$oldconffile" ]; then
636 cp "$oldconffile" "$newconffile"
641 replace_conffile_with_symlink_commit () {
642 # syntax: replace_conffile_with_symlink_commit oldfilename
644 # Complete the removal of a conffile "oldfilename" that has been
645 # replaced by a symlink.
647 # Call this function from a postinst script after having used
648 # replace_conffile_with_symlink_prepare() in the preinst.
653 if [ $# -ne 1 ]; then
654 usage_error "replace_conffile_with_symlink_commit() called with wrong" \
655 "number of arguments; expected 1, got $#"
656 exit $SHELL_LIB_USAGE_ERROR
661 remove_conffile_commit "$conffile"
664 replace_conffile_with_symlink_rollback () {
665 # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
667 # Roll back the replacing of a conffile "oldfilename" with symlink to
670 # Call this function from a postrm script in the event $1 is "abort-upgrade"
671 # or "abort-install" and verify $2 to ensure the package failed to upgrade
672 # from a version (or install over a version removed-but-not-purged) prior
673 # to the one in which the conffile was obsoleted.
674 # You should have used replace_conffile_with_symlink_prepare() in the
680 if [ $# -ne 2 ]; then
681 usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
682 "number of arguments; expected 2, got $#"
683 exit $SHELL_LIB_USAGE_ERROR
689 remove_conffile_rollback "$_oldconffile"
690 if [ -f "$newconffile" ]; then
696 # syntax: run command [ argument ... ]
698 # Run specified command with optional arguments and report its exit status.
699 # Useful for commands whose exit status may be nonzero, but still acceptable,
700 # or commands whose failure is not fatal to us.
702 # NOTE: Do *not* use this function with db_get or db_metaget commands; in
703 # those cases the return value of the debconf command *must* be checked
704 # before the string returned by debconf is used for anything.
709 if [ $# -lt 1 ]; then
710 usage_error "run() called with wrong number of arguments; expected at" \
712 exit $SHELL_LIB_USAGE_ERROR
717 if [ ${retval:-0} -ne 0 ]; then
718 observe "command \"$*\" exited with status $retval"
722 register_x_lib_dir_with_ld_so () {
723 # syntax: register_x_lib_dir_with_ld_so
725 # Configure the dynamic loader ld.so to search /usr/X11R6/lib for shared
728 # Call this function from the postinst script of a package that places a
729 # shared library in /usr/X11R6/lib, before invoking ldconfig.
734 ldsoconf="/etc/ld.so.conf"
736 # is the line not already present?
737 if ! fgrep -qsx "$dir" "$ldsoconf"; then
738 observe "adding $dir directory to $ldsoconf"
739 echo "$dir" >> "$ldsoconf"
743 deregister_x_lib_dir_with_ld_so () {
744 # syntax: deregister_x_lib_dir_with_ld_so
746 # Configure dynamic loader ld.so to not search /usr/X11R6/lib for shared
747 # libraries, if and only if no shared libaries remain there.
749 # Call this function from the postrm script of a package that places a shared
750 # library in /usr/X11R6/lib, in the event "$1" is "remove", and before
753 local dir ldsoconf fgrep_status cmp_status
756 ldsoconf="/etc/ld.so.conf"
758 # is the line present?
759 if fgrep -qsx "$dir" "$ldsoconf"; then
760 # are there any shared objects in the directory?
761 if [ "$(echo "$dir"/lib*.so.*.*)" = "$dir/lib*.so.*.*" ]; then
762 # glob expansion produced nothing, so no shared libraries are present
763 observe "removing $dir directory from $ldsoconf"
764 # rewrite the file (very carefully)
766 fgrep -svx "$dir" "$ldsoconf" > "$ldsoconf.dpkg-tmp"
769 case $fgrep_status in
770 0|1) ;; # we don't actually care if any lines matched or not
771 *) die "error reading \"$ldsoconf\"; fgrep exited with status" \
775 cmp -s "$ldsoconf.dpkg-tmp" "$ldsoconf"
779 0) rm "$ldsoconf.dpkg-tmp" ;; # files are identical
780 1) mv "$ldsoconf.dpkg-tmp" "$ldsoconf" ;; # files differ
781 *) die "error comparing \"$ldsoconf.dpkg-tmp\" to \"$ldsoconf\";" \
782 "cmp exited with status $cmp_status" ;;
788 make_symlink_sane () {
789 # syntax: make_symlink_sane symlink target
791 # Ensure that the symbolic link symlink exists, and points to target.
793 # If symlink does not exist, create it and point it at target.
795 # If symlink exists but is not a symbolic link, back it up.
797 # If symlink exists, is a symbolic link, but points to the wrong location, fix
800 # If symlink exists, is a symbolic link, and already points to target, do
803 # This function wouldn't be needed if ln had an -I, --idempotent option.
805 # Validate arguments.
806 if [ $# -ne 2 ]; then
807 usage_error "make_symlink_sane() called with wrong number of arguments;" \
809 exit $SHELL_LIB_USAGE_ERROR
812 # We could just use the positional parameters as-is, but that makes things
819 if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
820 observe "link from $symlink to $target already exists"
822 observe "creating symbolic link from $symlink to $target"
823 mkdir -p "${target%/*}" "${symlink%/*}"
824 ln -s -b -S ".dpkg-old" "$target" "$symlink"
828 migrate_dir_to_symlink () {
829 # syntax: migrate_dir_to_symlink old_location new_location
831 # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
832 # symbolic link to a directory or vice versa; instead, the existing state
833 # (symlink or not) will be left alone and dpkg will follow the symlink if
836 # We have to do it ourselves.
838 # This function moves the contents of old_location, a directory, into
839 # new_location, a directory, then makes old_location a symbolic link to
842 # old_location need not exist, but if it does, it must be a directory (or a
843 # symlink to a directory). If it is not, it is backed up. If new_location
844 # exists already and is not a directory, it is backed up.
846 # This function should be called from a package's preinst so that other
847 # packages unpacked after this one --- but before this package's postinst runs
848 # --- are unpacked into new_location even if their payloads contain
849 # old_location filespecs.
851 # Validate arguments.
852 if [ $# -ne 2 ]; then
853 usage_error "migrate_dir_to_symlink() called with wrong number of"
854 "arguments; expected 2, got $#"
855 exit $SHELL_LIB_USAGE_ERROR
858 # We could just use the positional parameters as-is, but that makes things
865 # Is old location a symlink?
866 if [ -L "$old" ]; then
867 # Does it already point to new location?
868 if [ "$(readlink "$old")" = "$new" ]; then
869 # Nothing to do; migration has already been done.
870 observe "migration of $old to $new already done"
874 warn "backing up symbolic link $old as $old.dpkg-old"
875 mv -b "$old" "$old.dpkg-old"
879 # Does old location exist, but is not a directory?
880 if [ -e "$old" ] && ! [ -d "$old" ]; then
882 warn "backing up non-directory $old as $old.dpkg-old"
883 mv -b "$old" "$old.dpkg-old"
886 observe "migrating $old to $new"
888 # Is new location a symlink?
889 if [ -L "$new" ]; then
890 # Does it point the wrong way, i.e., back to where we're migrating from?
891 if [ "$(readlink "$new")" = "$old" ]; then
893 observe "removing symbolic link $new which points to $old"
897 warn "backing up symbolic link $new as $new.dpkg-old"
898 mv -b "$new" "$new.dpkg-old"
902 # Does new location exist, but is not a directory?
903 if [ -e "$new" ] && ! [ -d "$new" ]; then
904 warn "backing up non-directory $new as $new.dpkg-old"
905 mv -b "$new" "$new.dpkg-old"
908 # Create new directory if it does not yet exist.
909 if ! [ -e "$new" ]; then
910 observe "creating $new"
914 # Copy files in old location to new location. Back up any filenames that
915 # already exist in the new location with the extension ".dpkg-old".
916 observe "copying files from $old to $new"
917 if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
918 die "error(s) encountered while copying files from $old to $new"
921 # Remove files at old location.
922 observe "removing $old"
925 # Create symlink from old location to new location.
926 make_symlink_sane "$old" "$new"
929 # vim:set ai et sw=2 ts=2 tw=80:
931 # GOBSTOPPER: The X Strike Force shell library ends here.