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