It is possible to have dpkg
not overwrite a file
when it reinstalls the package it belongs to, and to have it
put the file from the package somewhere else instead.
This can be used locally to override a package's version of a file, or by one package to override another's version (or provide a wrapper for it).
Before deciding to use a diversion, read Alternative versions of an interface -
update-alternatives
, chapter 10 to see if you really want a diversion
rather than several alternative versions of a program.
There is a diversion list, which is read by dpkg
,
and updated by a special program dpkg-divert
.
Please see dpkg-divert(8)
for full
details of its operation.
When a package wishes to divert a file from another, it should
call dpkg-divert
in its preinst to add the
diversion and rename the existing file. For example,
supposing that a smailwrapper
package wishes to
install a wrapper around /usr/sbin/smail:
if [ install = "$1" ]; then dpkg-divert --package smailwrapper --add --rename \ --divert /usr/sbin/smail.real /usr/sbin/smail fiTesting $1 is necessary so that the script doesn't try to add the diversion again when
smailwrapper
is upgraded. The --package
smailwrapper ensures that smailwrapper
's
copy of /usr/sbin/smail can bypass the diversion and
get installed as the true version.
The postrm has to do the reverse:
if [ remove = "$1" ]; then dpkg-divert --package smailwrapper --remove --rename \ --divert /usr/sbin/smail.real /usr/sbin/smail fi
Do not attempt to divert a file which is vitally important for
the system's operation - when using dpkg-divert
there is a time, after it has been diverted but before
dpkg
has installed the new version, when the file
does not exist.