From: Wichert Akkerman Date: Wed, 13 Oct 1999 16:08:32 +0000 (+0000) Subject: Check if a file isn't also in the new package when upgrading X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b1362c1c0ebe910c413c022fd9fca12bcb07eb7;p=dpkg Check if a file isn't also in the new package when upgrading --- diff --git a/ChangeLog b/ChangeLog index 20232f03..96e99460 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ Wed Oct 13 17:51:17 CEST 1999 Wichert Akkerman - * Merge patch from Ben Collins to fix windowresizing in dselect + * Merge patches from Ben Collins : + + 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 diff --git a/main/filesdb.c b/main/filesdb.c index bc4e1b1f..99681734 100644 --- a/main/filesdb.c +++ b/main/filesdb.c @@ -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: diff --git a/main/filesdb.h b/main/filesdb.h index 7a3ecf29..83c6533c 100644 --- a/main/filesdb.h +++ b/main/filesdb.h @@ -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 { diff --git a/main/processarc.c b/main/processarc.c index 923313d5..d155d8d9 100644 --- a/main/processarc.c +++ b/main/processarc.c @@ -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; }