Some thoughts, fwiw: The seuqence of events seems to be: Setup: * /dir and /link refer to the same directory. * installed file known as /dir/filename * to-be-installed file known as /link/filename Check-for-overwriting: Are there any dpkg-controlled files that /link/filename will overwrite? dpkg checks this by just looking for /link/filename in /var/lib/dpkg/info/*.list If so: Is it in this package itself? Does this package replace it? Is --force-overwrites enabled? If so, overwrite it, but make a note not to delete the now-overwritten file later. Otherwise, there's an error. Write the file Delete any files left in the package Okay. Based on that, there are a few overwriting cases: * it's in the package, or a replaced package by the same name -- easily checked * it's in the package, or a replaced pacakge by a different name -- can be checked by stating each directory of files in the package, in the previously installed version of the package and in every installed package it replaces. the most directories in any package on my system is 281, (average is about 15), the most packages any package replaces is 14 (most replace no more than 4). This at least lets you get the `legal' situations correct. * it's in some other package by the same name -- easily checked * it's in some other package by a different name -- can be checked by stating each directory of files in any package and canoncolising them. There are about 2849 such directories on my system, and it takes about 30s to stat them all. (Which is probably twice? how long dpkg takes to start up) * it's installed locally by the sysadmin -- should get overwritten anyway Another possibility would be adding a --no-force-local-overwrite (or similar) option that warns/fails if dpkg tries to overwrite a file that doesn't appear to be in the dpkg database (which would be the case if the admin installed it, or if it appears under another name in some unrelated package). This could be used for testing in much the same way as --no-force-overwrite is at the moment. Somewhat relatedly, the sysadmin can already break things by, eg: # dpkg -i a.deb b.deb # rm -rf /usr/doc/a # ln -s b /usr/doc/a # dpkg --purge a # less /usr/doc/b/changelog.gz /usr/doc/b/changelog.gz: No such file or directory This could be avoided by doing the stating all the time, and noticing on the --purge that /usr/doc/a/changelog.gz and /usr/doc/b/changelog.gz are actually the same file and not actually rm'ing it until no packages are using it. Anyway, assuming we're not going to go worry too much about correct behaviour in the above example, just stating the directories in packages that are actually getting replaced would probably be both efficient, and correct in most cases. Cheers, aj -- Anthony Towns <aj@humbug.org.au> <http://azure.humbug.org.au/~aj/> I don't speak for anyone save myself. PGP encrypted mail preferred. ``The thing is: trying to be too generic is EVIL. It's stupid, it results in slower code, and it results in more bugs.'' -- Linus Torvalds
Attachment:
pgpbmRKu6nVFm.pgp
Description: PGP signature