# dpkg-maintscript-helper

## NAME



           dpkg-maintscript-helper - works around known dpkg limitations in
           maintainer scripts
    


## SYNOPSIS



           **dpkg-maintscript-helper** _command_ [_parameter_...] **--**
           _maint-script-parameter_...
    


## COMMANDS AND PARAMETERS



           **supports** _command_
           **rm_conffile** _conffile_ [_prior-version_ [_package_]]
           **mv_conffile** _old-conffile new-conffile_ [_prior-version_ [_package_]]
           **symlink_to_dir** _pathname old-target_ [_prior-version_ [_package_]]
           **dir_to_symlink** _pathname new-target_ [_prior-version_ [_package_]]
    


## DESCRIPTION



           This program is designed to be run within maintainer scripts to
           achieve some tasks that **dpkg** can't (yet) handle natively either
           because of design decisions or due to current limitations.
    
           Many of those tasks require coordinated actions from several
           maintainer scripts (**preinst** , **postinst** , **prerm** , **postrm**).  To avoid
           mistakes the same call simply needs to be put in all scripts and
           the program will automatically adapt its behavior based on the
           environment variable **DPKG_MAINTSCRIPT_NAME** and on the maintainer
           scripts arguments that you have to forward after a double hyphen.
    
           This program was introduced in dpkg 1.15.7.
    


## COMMON PARAMETERS



           _prior-version_
               Defines the latest version of the package whose upgrade should
               trigger the operation.  It is important to calculate
               _prior-version_ correctly so that the operations are correctly
               performed even if the user rebuilt the package with a local
               version.  If _prior-version_ is empty or omitted, then the
               operation is tried on every upgrade (note: it's safer to give
               the version and have the operation tried only once).
    
               If the conffile has not been shipped for several versions, and
               you are now modifying the maintainer scripts to clean up the
               obsolete file, _prior-version_ should be based on the version of
               the package that you are now preparing, not the first version
               of the package that lacked the conffile.  This applies to all
               other actions in the same way.
    
               For example, for a conffile removed in version **2.0-1** of a
               package, _prior-version_ should be set to **2.0-1~**.  This will
               cause the conffile to be removed even if the user rebuilt the
               previous version **1.0-1** as **1.0-1local1**.  Or a package switching
               a path from a symlink (shipped in version **1.0-1**) to a
               directory (shipped in version **2.0-1**), but only performing the
               actual switch in the maintainer scripts in version **3.0-1** ,
               should set _prior-version_ to **3.0-1~**.
    
           _package_
               The package name owning the pathname(s).  When the package is
               “Multi-Arch: same” this parameter must include the
               architecture qualifier, otherwise it should **not** usually
               include the architecture qualifier (as it would disallow
               cross-grades, or switching from being architecture specific to
               architecture **all** or vice versa).  If the parameter is empty or
               omitted, the **DPKG_MAINTSCRIPT_PACKAGE** and
               **DPKG_MAINTSCRIPT_ARCH** environment variables (as set by **dpkg**
               when running the maintainer scripts) will be used to generate
               an arch-qualified package name.
    
           **--** All the parameters of the maintainer scripts have to be
               forwarded to the program after **--**.
    


## CONFFILE RELATED TASKS



           When upgrading a package, **dpkg** will not automatically remove a
           conffile (a configuration file for which **dpkg** should preserve user
           changes) if it is not present in the newer version.  There are two
           principal reasons for this; the first is that the conffile
           could've been dropped by accident and the next version could
           restore it, users wouldn't want their changes thrown away.  The
           second is to allow packages to transition files from a
           dpkg-maintained conffile to a file maintained by the package's
           maintainer scripts, usually with a tool like debconf or ucf.
    
           This means that if a package is intended to rename or remove a
           conffile, it must explicitly do so and **dpkg-maintscript-helper** can
           be used to implement graceful deletion and moving of conffiles
           within maintainer scripts.
    
       **Removing a conffile**
           **Note** : This can be replaced in most cases by the
           "remove-on-upgrade" flag in _DEBIAN/conffiles_ (since dpkg 1.20.6),
           see deb-conffiles(5).
    
           If a conffile is completely removed, it should be removed from
           disk, unless the user has modified it.  If there are local
           modifications, they should be preserved.  If the package upgrade
           aborts, the newly obsolete conffile should not disappear.
    
           All of this is implemented by putting the following shell snippet
           in the **preinst** , **postinst** and **postrm** maintainer scripts:
    
                dpkg-maintscript-helper rm_conffile \
                   _conffile prior-version package_ -- "$@"
    
           _conffile_ is the filename of the conffile to remove.
    
           Current implementation: in the **preinst** , it checks if the conffile
           was modified and renames it either to _conffile_**.dpkg-remove**(if not
           modified) or to _conffile_**.dpkg-backup**(if modified).  In the
           **postinst** , the latter file is renamed to _conffile_**.dpkg-bak** and kept
           for reference as it contains user modifications but the former
           will be removed.  If the package upgrade aborts, the **postrm**
           reinstalls the original conffile.  During purge, the **postrm** will
           also delete the **.dpkg-bak** file kept up to now.
    
       **Renaming a conffile**
           If a conffile is moved from one location to another, you need to
           make sure you move across any changes the user has made.  This may
           seem a simple change to the **preinst** script at first, however that
           will result in the user being prompted by **dpkg** to approve the
           conffile edits even though they are not responsible of them.
    
           Graceful renaming can be implemented by putting the following
           shell snippet in the **preinst** , **postinst** and **postrm** maintainer
           scripts:
    
                dpkg-maintscript-helper mv_conffile \
                   _old-conffile new-conffile prior-version package_ -- "$@"
    
           _old-conffile_ and _new-conffile_ are the old and new name of the
           conffile to rename.
    
           Current implementation: the **preinst** checks if the conffile has
           been modified, if yes it's left on place otherwise it's renamed to
           _old-conffile_**.dpkg-remove**.  On configuration, the **postinst** removes
           _old-conffile_**.dpkg-remove** and renames _old-conffile_ to _new-conffile_
           if _old-conffile_ is still available.  On
           abort-upgrade/abort-install, the **postrm** renames
           _old-conffile_**.dpkg-remove** back to _old-conffile_ if required.
    


## SYMLINK AND DIRECTORY SWITCHES



           When upgrading a package, **dpkg** will not automatically switch a
           symlink to a directory or vice-versa.  Downgrades are not
           supported and the path will be left as is.
    
           **Note** : The symlinks and directories created during these switches
           need to be shipped in the new packages, or **dpkg** will not be able
           to remove them on purge.
    
       **Switching a symlink to directory**
           If a symlink is switched to a real directory, you need to make
           sure before unpacking that the symlink is removed.  This may seem
           a simple change to the **preinst** script at first, however that will
           result in some problems in case of admin local customization of
           the symlink or when downgrading the package.
    
           Graceful renaming can be implemented by putting the following
           shell snippet in the **preinst** , **postinst** and **postrm** maintainer
           scripts:
    
                dpkg-maintscript-helper symlink_to_dir \
                   _pathname old-target prior-version package_ -- "$@"
    
           _pathname_ is the absolute name of the old symlink (the path will be
           a directory at the end of the installation) and _old-target_ is the
           target name of the former symlink at _pathname_.  It can either be
           absolute or relative to the directory containing _pathname_.
    
           Current implementation: the **preinst** checks if the symlink exists
           and points to _old-target_ , if not then it's left in place,
           otherwise it's renamed to _pathname_**.dpkg-backup**.  On configuration,
           the **postinst** removes _pathname_**.dpkg-backup** if _pathname_**.dpkg-backup**
           is still a symlink.  On abort-upgrade/abort-install, the **postrm**
           renames _pathname_**.dpkg-backup** back to _pathname_ if required.
    
       **Switching a directory to symlink**
           If a real directory is switched to a symlink, you need to make
           sure before unpacking that the directory is removed.  This may
           seem a simple change to the **preinst** script at first, however that
           will result in some problems in case the directory contains
           conffiles, pathnames owned by other packages, locally created
           pathnames, or when downgrading the package.
    
           Graceful switching can be implemented by putting the following
           shell snippet in the **preinst** , **postinst** and **postrm** maintainer
           scripts:
    
                dpkg-maintscript-helper dir_to_symlink \
                   _pathname new-target prior-version package_ -- "$@"
    
           _pathname_ is the absolute name of the old directory (the path will
           be a symlink at the end of the installation) and _new-target_ is the
           target of the new symlink at _pathname_.  It can either be absolute
           or relative to the directory containing _pathname_.
    
           Current implementation: the **preinst** checks if the directory
           exists, does not contain conffiles, pathnames owned by other
           packages, or locally created pathnames, if not then it's left in
           place, otherwise it's renamed to _pathname_**.dpkg-backup** , and an
           empty staging directory named _pathname_ is created, marked with a
           file so that dpkg can track it.  On configuration, the **postinst**
           finishes the switch if _pathname_**.dpkg-backup** is still a directory
           and _pathname_ is the staging directory; it removes the staging
           directory mark file, moves the newly created files inside the
           staging directory to the symlink target _new-target_ /, replaces the
           now empty staging directory _pathname_ with a symlink to _new-target_ ,
           and removes _pathname_**.dpkg-backup**.  On abort-upgrade/abort-install,
           the **postrm** renames _pathname_**.dpkg-backup** back to _pathname_ if
           required.
    


## INTEGRATION IN PACKAGES



           When using a packaging helper, please check if it has native
           **dpkg-maintscript-helper** integration, which might make your life
           easier.  See for example dh_installdeb(1).
    
           Given that **dpkg-maintscript-helper** is used in the **preinst** , using
           it unconditionally requires a versioned pre-dependency to ensure
           that the required version of **dpkg** has been unpacked before, unless
           we know we are upgrading from a release where the required dpkg
           version is going to be satisfied.  The required version depends on
           the command used, for **rm_conffile** and **mv_conffile** it is 1.15.7.2,
           for **symlink_to_dir** and **dir_to_symlink** it is 1.17.14.  For example,
           if we required support for **symlink_to_dir** when upgrading from a
           release that had a dpkg version earlier than 1.17.14, we would
           need to add:
    
            Pre-Depends: dpkg (>= 1.17.14)
    
           But in many cases the operation done by the program is not
           critical for the package, and instead of using a pre-dependency we
           can call the program only if we know that the required command is
           supported by the currently installed **dpkg** :
    
                if dpkg-maintscript-helper supports _command_ ; then
                   dpkg-maintscript-helper _command_ ...
                fi
    
           The command **supports** will return 0 on success, 1 otherwise.  The
           **supports** command will check if the environment variables as set by
           dpkg and required by the script are present, and will consider it
           a failure in case the environment is not sufficient.
    


## ENVIRONMENT



           **DPKG_ROOT**
               If set, it will be used as the filesystem root directory.
    
           **DPKG_ADMINDIR**
               If set, it will be used as the **dpkg** data directory.
    
           **DPKG_COLORS**
               Sets the color mode (since dpkg 1.19.1).  The currently
               accepted values are: **auto**(default), **always** and **never**.
    


* * *