[pacman-dev] difficult symlink "puzzle"

Andrew Fyfe andrew at neptune-one.net
Tue Jul 3 11:14:37 EDT 2007


Well this is how dpkg does it (src/processarc.c:471)

/*
    * Now we unpack the archive, backing things up as we go.
    * For each file, we check to see if it already exists.
    * There are several possibilities:
    * + We are trying to install a non-directory ...
    *  - It doesn't exist.  In this case we simply extract it.
    *  - It is a plain file, device, symlink, &c.  We do an `atomic
    *    overwrite' using link() and rename(), but leave a backup copy.
    *    Later, when we delete the backup, we remove it from any other
    *    packages' lists.
    * -  It is a directory.  In this case it depends on whether we're
    *    trying to install a symlink or something else.
    *   = If we're not trying to install a symlink we move the directory
    *     aside and extract the node.  Later, when we recursively remove
    *     the backed-up directory, we remove it from any other packages'
    *     lists.
    *   = If we are trying to install a symlink we do nothing - ie,
    *     dpkg will never replace a directory tree with a symlink.  This
    *     is to avoid embarrassing effects such as replacing a directory
    *     tree with a link to a link to the original directory tree.
    * + We are trying to install a directory ...
    *  - It doesn't exist.  We create it with the appropriate modes.
    *  - It exists as a directory or a symlink to one.  We do nothing.
    *  - It is a plain file or a symlink (other than to a directory).
    *    We move it aside and create the directory.  Later, when we
    *    delete the backup, we remove it from any other packages' lists.
    *
    *                   Install non-dir   Install symlink   Install dir
    *  Exists not               X               X                X
    *  File/node/symlink       LXR             LXR              BXR
    *  Directory               BXR              -                -
    *
    *    X: extract file/node/link/directory
    *   LX: atomic overwrite leaving backup
    *    B: ordinary backup
    *    R: later remove from other packages' lists
    *    -: do nothing
    *
    * After we've done this we go through the remaining things in the
    * lists of packages we're trying to remove (including the old
    * version of the current package).  This happens in reverse order,
    * so that we process files before the directories (or symlinks-to-
    * directories) containing them.
    * + If the thing is a conffile then we leave it alone for the purge
    *   operation.
    * + Otherwise, there are several possibilities too:
    *  - The listed thing does not exist.  We ignore it.
    *  - The listed thing is a directory or a symlink to a directory.
    *    We delete it only if it isn't listed in any other package.
    *  - The listed thing is not a directory, but was part of the package
    *    that was upgraded, we check to make sure the files aren't the
    *    same ones from the old package by checking dev/inode
    *  - The listed thing is not a directory or a symlink to one (ie,
    *    it's a plain file, device, pipe, &c, or a symlink to one, or a
    *    dangling symlink).  We delete it.
    * The removed packages' list becomes empty (of course, the new
    * version of the package we're installing will have a new list,
    * which replaces the old version's list).
    *
    * If at any stage we remove a file from a package's list, and the
    * package isn't one we're already processing, and the package's
    * list becomes empty as a result, we `vanish' the package.  This
    * means that we run its postrm with the `disappear' argument, and
    * put the package in the `not-installed' state.  If it had any
    * conffiles, their hashes and ownership will have been transferred
    * already, so we just ignore those and forget about them from the
    * point of view of the disappearing package.
    *
    * NOTE THAT THE OLD POSTRM IS RUN AFTER THE NEW PREINST, since the
    * files get replaced `as we go'.
    */

Andrew




More information about the pacman-dev mailing list