]> err.no Git - dpkg/commitdiff
Check if a file isn't also in the new package when upgrading
authorWichert Akkerman <wakkerma@debian.org>
Wed, 13 Oct 1999 16:08:32 +0000 (16:08 +0000)
committerWichert Akkerman <wakkerma@debian.org>
Wed, 13 Oct 1999 16:08:32 +0000 (16:08 +0000)
ChangeLog
main/filesdb.c
main/filesdb.h
main/processarc.c

index 20232f03763e0942b9d2e7fcd7ef833594617eef..96e99460f914019dafec58bf44a0ca47856d09b6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 Wed Oct 13 17:51:17 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
 
-  * Merge patch from Ben Collins to fix windowresizing in dselect
+  * Merge patches from Ben Collins <bcollins@debian.org>:
+    + fix windowresizing in dselect
+    + when upgrading check if a file is not also in the new package before removing
+         it, so we don't remove new files due to symlinks confusing us
 
 Tue Oct 12 17:15:08 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
 
index bc4e1b1fdf4216bc8ee581671fdf4a1f32ea5010..996817346fafa0f304f4dd3caf003a7bacd3ab07 100644 (file)
@@ -515,6 +515,7 @@ void filesdbinit(void) {
       for (fnn= bins[i]; fnn; fnn= fnn->next) {
         fnn->flags= 0;
         fnn->oldhash= 0;
+       fnn->stat= 0;
       }
     break;
   case -1:
@@ -523,6 +524,7 @@ void filesdbinit(void) {
          fnn= fnn->next) {
       fnn->flags= 0;
       fnn->oldhash= 0;
+      fnn->stat= 0;
     }
     break;
   default:
index 7a3ecf29f9ea66826dda7c821db2ee16d7aa6aaa..83c6533cd3c0565c4282147895b597042e910c53 100644 (file)
@@ -62,6 +62,7 @@ struct filenamenode {
     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 {
index 923313d55519141710b84e86073607248d3f555f..d155d8d9289dc57e511135800c3eaf25661a4dba 100644 (file)
@@ -490,6 +490,9 @@ void process_archive(const char *filename) {
    *  - 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.
@@ -586,6 +589,41 @@ void process_archive(const char *filename) {
     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;
     }