ucf [options] <New File> <Destination>
ucf [options] --purge <Destination>
This utility provides a means of asking the user whether or not to accept new versions of configuration files provided by the package maintainer, with various heuristics designed to minimize interaction time. It uses debconf to interact with the user, as per Debian policy. In the SYNOPSIS above, New file is the configuration file as provided by the package (either shipped with the package, or generated by the maintainer scripts on the fly), and Destination is the location (usually under /etc) where the real configuration file lives, and is potentially modified by the end user. Since the files edited would be real files, and not symbolic links, ucf follows and resolves symbolic links before acting. As far as possible, ucf attempts to preserve the ownership and permission of the New file as it is copied to the new location.
This script attempts to provide conffile like handling for files installed under /etc not shipped in a Debian package, but handled by the postinst instead. Debian policy states that files under /etc which are configuration files must preserve user changes, and this applies to files handled by maintainer scripts as well. Using ucf, one may ship a bunch of default configuration files somewhere in /usr ( /usr/share/<pkg> is a good location), and maintain files in /etc, preserving user changes and in general offering the same facilities while upgrading that dpkg normally provides for ``conffiles''
Additionally, this script provides facilities for transitioning a file that had not been provided conffile like protection to come under this schema, and attempts to minimize questions asked at install time. Indeed, the transitioning facility is better than the one offered by dpkg while transitioning a file from a non-conffile to conffile status. The second form in the SYNOPSIS above is for purging information about the configuration file when the package is purged; and is critical for allowing smooth reinstallations.
During the course of operations, when working with configuration files, ucf optionally creates copies of versions of the configuration file in question. For example, a file with the suffix ucf-old holds the old version of a configuration file replaced by ucf. Also, copies of the configuration file with the suffixes ucf-new and ucf-dist may be created; and the maintainer scripts should consider purging copies of the configuration file with these extensions during purge.
The most common case usage is pretty simple: a single line invocation in the postinst on configure, and another single line in the postrm to tell ucf to forget about the configuration file on purge (using the --purge option) is all that is needed (assuming ucf is still on the system).
It is recommended that you also register any file being managed by ucf with the ucf registry; this associates the configuration file with the package it belongs to. This is done with a simple call to ucfr. Users may then query the association between a configuration file and the package using the tool ucfq. Please see the appropriate manual pages for details.
If a file maintained by maintainer scripts is being transitioned from an unprotected status to the protection afforded by the script, the maintainer can help ease the transition by reducing the questions that may be asked at installation time. Specifically, questions should not be asked if the file in question is an unmodified version that was one shipped in a previous version of this package; and the maintainer can help by telling the script about the historical md5sums that published versions of this file contained.
The way to do this is to either create a file called <New file>.md5sum, with one md5sum on each line, (the file names you use are ignored, except for the entry named default), or create a directory, called <New file>.md5sum.d, which should contain any number of files, each containing a single line, namely, the md5sum of a previous version of <New file>. The names of these files are not important, with one exception: The file called default is treated specially. For example, the author personally uses either package version numbers or release code names, like 7.6.3, or potato. If none of the historical md5sums match, we are almost certain that either the historical record of md5sums is not complete, or the user has changed the configuration file.
If the file <New file>.md5sum, or the directory <New file>.md5sum.d does not exist, or none of the md5sums match, we test the installed <Destination> file to see whether it is the same as the <New file>. If not, we ask the user whether they want us to replace the file.
An additional facility is also offered: optionally, ucf can store one old version of the maintainers copy of the configuration file, and, on upgrade, calculate the changes made in the maintainers version of the configuration file, and apply that patch to the local version of the file (on user request, of course). There is also a preview facility where the user can inspect the results of such a merge, before asking the action to be taken.
The variable UCF_FORCE_CONFFNEW, if set, forces the new file to always overwrite the installed destination file, while the variable UCF_FORCE_CONFFOLD, if set silently retains the installed file. UCF_FORCE_CONFFMISS is only applicable when the installed destination file does not exist (perhaps due to user removal),and forces ucf to recreate the missing file (the default behaviour is to honor the users wishes and not recreate the locally deleted file).
This script creates the file new_file.md5sum, and it may copy the file (presumably shipped with the package) <New file> to its destination, <Destination>.
/var/lib/ucf/hashfile, and /var/lib/ucf/hashfile.X, where X is a small integer, where previous versions of the hashfile are stored.
If the package foo wants to use ucf to handle user interaction for configuration file foo.conf, a version of which is provided in the package as /usr/share/foo/configuration, a simple invocation of ucf in the post inst file is all that is needed:
ucf /usr/share/foo/configuration /etc/foo.conf
On purge, one should tell ucf to forget about the file (see detailed examples in /usr/share/doc/ucf/examples):
ucf --purge /etc/foo.conf Please note that purge can also be used to make ucf forget the previous state of the files, and when the package is next installed or updated, ucf will ask the user to replace the current cofiguration file. Do this if you want to change your decision to not update to a maintainer provided version of the configuration file.
The motivation for this script was to provide conffile like handling for start files for emacs lisp packages (for example, /etc/emacs21/site-start.d/50psgml-init.el ) These start files are not shipped with the package, instead, they are installed during the post installation configuration phase by the script /usr/lib/emacsen-common/emacs-package-install $package_name.
This script is meant to be invoked by the packages install script at /usr/lib/emacsen-common/packages/install/$package_name for each flavour of installed emacsen by calling it with the proper values of new file ( /usr/share/emacs/site-lisp/<pkg>/<pkg-init.el ), and dest file ( /etc/emacs21/site-start.d/50<pkg-init.el ), and it should do the rest.
ucf.conf(5), ucfr(1), ucfq(1), and diff3(1). The Debian Emacs policy, shipped with the package emacsen-common.
This manual page was written Manoj Srivastava <firstname.lastname@example.org>, for the Debian GNU/Linux system.