Ok, new patch. This just adds some to the comments about why we only check this package. I looked into the replaces issue, and it doesn't seem very feasible right now. I also added some debug() output. Ben
diff -urN dpkg-1.4.1.13.old/main/filesdb.c dpkg-1.4.1.13/main/filesdb.c
--- dpkg-1.4.1.13.old/main/filesdb.c Thu Sep 9 21:33:14 1999
+++ dpkg-1.4.1.13/main/filesdb.c Mon Oct 11 08:22:20 1999
@@ -515,6 +515,7 @@
for (fnn= bins[i]; fnn; fnn= fnn->next) {
fnn->flags= 0;
fnn->oldhash= 0;
+ fnn->stat= 0;
}
break;
case -1:
@@ -523,6 +524,7 @@
fnn= fnn->next) {
fnn->flags= 0;
fnn->oldhash= 0;
+ fnn->stat= 0;
}
break;
default:
diff -urN dpkg-1.4.1.13.old/main/filesdb.h dpkg-1.4.1.13/main/filesdb.h
--- dpkg-1.4.1.13.old/main/filesdb.h Sun Oct 25 17:25:40 1998
+++ dpkg-1.4.1.13/main/filesdb.h Mon Oct 11 08:22:20 1999
@@ -62,6 +62,7 @@
fnnf_no_atomic_overwrite= 000020, /* >=1 instance is a dir, cannot rename over */
} flags; /* Set to zero when a new node is created. */
const char *oldhash; /* valid iff this namenode is in the newconffiles list */
+ struct stat *stat;
};
struct fileinlist {
diff -urN dpkg-1.4.1.13.old/main/processarc.c dpkg-1.4.1.13/main/processarc.c
--- dpkg-1.4.1.13.old/main/processarc.c Thu Sep 9 19:56:34 1999
+++ dpkg-1.4.1.13/main/processarc.c Mon Oct 11 08:44:08 1999
@@ -473,6 +473,9 @@
* - 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.
@@ -569,6 +572,41 @@
if (!rmdir(fnamevb.buf)) continue;
if (errno == ENOENT || errno == ELOOP) continue;
if (errno == ENOTDIR) {
+ /* Ok, it's an old file, but is it really not in the new package?
+ * We need to check to make sure, so we stat the file, then compare
+ * it to the new list. If we find a dev/inode match, we assume they
+ * are the same file, and leave it alone. NOTE: we don't check in
+ * other packages for sanity reasons (we don't want to stat _all_
+ * the files on the system).
+ *
+ * We run down the list of _new_ files in this package. This keeps
+ * the process a little leaner. We are only worried about new ones
+ * since ones that stayed the same don't really apply here.
+ */
+ struct stat oldfs, *newfs;
+ int donotrm = 0;
+ /* If we can't stat the old or new file, or it's a directory,
+ * we leave it up to the normal code
+ */
+ debug(dbg_eachfile, "process_archive: checking %s for same files on
+ upgrade/downgrade", fnamevb.buf);
+ if (!lstat(fnamevb.buf, &oldfs) && !S_ISDIR(oldfs.st_mode)) {
+ for (cfile = newfileslist; cfile; cfile = cfile->next) {
+ if(!cfile->namenode->stat) {
+ newfs = nfmalloc(sizeof(struct stat));
+ if (lstat(cfile->namenode->name, newfs)) continue;
+ cfile->namenode->stat = newfs;
+ } else newfs = cfile->namenode->stat;
+ if (!S_ISDIR(newfs->st_mode) && oldfs.st_dev == newfs->st_dev &&
+ oldfs.st_ino == newfs->st_ino) {
+ donotrm = 1;
+ debug(dbg_eachfile, "process_archive: not removing %s, since it matches %s",
+ fnamevb.buf, cfile->namenode->name);
+ }
+ }
+ } else
+ debug(dbg_eachfile, "process_archive: could not stat %s, skipping", fnamevb.buf);
+ if (donotrm) continue;
if (!unlink(fnamevb.buf)) continue;
if (errno == ENOTDIR) continue;
}
Attachment:
pgpSvvh9bBUIF.pgp
Description: PGP signature