summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrank Lichtenheld <djpig@debian.org>2006-01-18 08:30:03 +0000
committerFrank Lichtenheld <djpig@debian.org>2006-01-18 08:30:03 +0000
commit53696310976b88bb01197796044ae92c571c89c3 (patch)
treeb853b364ffb8136a480c8e374d954b1daefed32d /src
parentbaa3c192761f69c5413d230c26fd2f56d79f7193 (diff)
downloaddpkg-53696310976b88bb01197796044ae92c571c89c3.tar.gz
Import latest release as a temporary trunk which should be
later merged into a branch with the full history from CVS and arch
Diffstat (limited to 'src')
-rw-r--r--src/archives.c51
-rw-r--r--src/cleanup.c17
-rw-r--r--src/filesdb.c22
-rw-r--r--src/filesdb.h1
-rw-r--r--src/processarc.c15
-rw-r--r--src/query.c5
-rw-r--r--src/remove.c2
7 files changed, 74 insertions, 39 deletions
diff --git a/src/archives.c b/src/archives.c
index 3c8b78e64..78daddc4f 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -166,12 +166,6 @@ int filesavespackage(struct fileinlist *file, struct pkginfo *pkgtobesaved,
* installed nor part of any 3rd package (this is important so that
* shared directories don't stop packages from disappearing).
*/
- /* Is the file in the package being installed ? If so then it can't save.
- */
- if (file->namenode->flags & fnnf_new_inarchive) {
- debug(dbg_eachfiledetail,"filesavespackage ... in new archive -- no save");
- return 0;
- }
/* If the file is a contended one and it's overridden by either
* the package we're considering disappearing or the package
* we're installing then they're not actually the same file, so
@@ -184,6 +178,12 @@ int filesavespackage(struct fileinlist *file, struct pkginfo *pkgtobesaved,
return 1;
}
}
+ /* Is the file in the package being installed ? If so then it can't save.
+ */
+ if (file->namenode->flags & fnnf_new_inarchive) {
+ debug(dbg_eachfiledetail,"filesavespackage ... in new archive -- no save");
+ return 0;
+ }
/* Look for a 3rd package which can take over the file (in case
* it's a directory which is shared by many packages.
*/
@@ -517,10 +517,15 @@ int tarobject(struct TarInfo *ti) {
}
/* Now we start to do things that we need to be able to undo
- * if something goes wrong.
+ * if something goes wrong. Watch out for the CLEANUP comments to
+ * keep an eye on what's installed on the disk at each point.
*/
push_cleanup(cu_installnew,~ehflag_normaltidy, 0,0, 1,(void*)nifd);
+ /* CLEANUP: Now we either have the old file on the disk, or not, in
+ * its original filename.
+ */
+
#ifdef WITH_SELINUX
/* Set selinux_enabled if it is not already set (singleton) */
if (selinux_enabled < 0)
@@ -620,12 +625,15 @@ int tarobject(struct TarInfo *ti) {
debug(dbg_eachfiledetail,"tarobject SymbolicLink creating");
#ifdef HAVE_LCHOWN
if (lchown(fnamenewvb.buf,
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->uid : ti->UserID,
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->gid : ti->GroupID))
+ ohshite(_("error setting ownership of symlink `%.255s'"),ti->Name);
#else
if (chown(fnamenewvb.buf,
-#endif
nifd->namenode->statoverride ? nifd->namenode->statoverride->uid : ti->UserID,
nifd->namenode->statoverride ? nifd->namenode->statoverride->gid : ti->GroupID))
ohshite(_("error setting ownership of symlink `%.255s'"),ti->Name);
+#endif
break;
case Directory:
/* We've already checked for an existing directory. */
@@ -637,11 +645,12 @@ int tarobject(struct TarInfo *ti) {
default:
internerr("bad tar type, but already checked");
}
- /*
- * Now we have extracted the new object in .dpkg-new (or, if the
- * file already exists as a directory and we were trying to extract
+ /* CLEANUP: Now we have extracted the new object in .dpkg-new (or,
+ * if the file already exists as a directory and we were trying to extract
* a directory or symlink, we returned earlier, so we don't need
* to worry about that here).
+ *
+ * The old file is still in the original filename,
*/
/* First, check to see if it's a conffile. If so we don't install
@@ -653,9 +662,8 @@ int tarobject(struct TarInfo *ti) {
return 0;
}
- /* Now we install it. If we can do an atomic overwrite we do so.
- * If not we move aside the old file and then install the new.
- * The backup file will be deleted later.
+ /* Now we move the old file out of the way, the backup file will
+ * be deleted later.
*/
if (statr) { /* Don't try to back it up if it didn't exist. */
debug(dbg_eachfiledetail,"tarobject new - no backup");
@@ -681,10 +689,11 @@ int tarobject(struct TarInfo *ti) {
ohshite(_("unable to make backup symlink for `%.255s'"),ti->Name);
#ifdef HAVE_LCHOWN
if (lchown(fnametmpvb.buf,stab.st_uid,stab.st_gid))
+ ohshite(_("unable to chown backup symlink for `%.255s'"),ti->Name);
#else
if (chown(fnametmpvb.buf,stab.st_uid,stab.st_gid))
-#endif
ohshite(_("unable to chown backup symlink for `%.255s'"),ti->Name);
+#endif
} else {
debug(dbg_eachfiledetail,"tarobject nondirectory, `link' backup");
if (link(fnamevb.buf,fnametmpvb.buf))
@@ -693,6 +702,10 @@ int tarobject(struct TarInfo *ti) {
}
}
+ /* CLEANUP: now the old file is in dpkg-tmp, and the new file is still
+ * in dpkg-new.
+ */
+
#ifdef WITH_SELINUX
/*
* if selinux is enabled, try and set the default security context
@@ -710,6 +723,14 @@ int tarobject(struct TarInfo *ti) {
if (rename(fnamenewvb.buf,fnamevb.buf))
ohshite(_("unable to install new version of `%.255s'"),ti->Name);
+ /* CLEANUP: now the new file is in the destination file, and the
+ * old file is in dpkg-tmp to be cleaned up later. We now need
+ * to take a different attitude to cleanup, because we need to
+ * remove the new file.
+ */
+
+ nifd->namenode->flags |= fnnf_placed_on_disk;
+
#ifdef WITH_SELINUX
/*
* if selinux is enabled, restore the default security context
diff --git a/src/cleanup.c b/src/cleanup.c
index 3d93e8e42..d1996b16c 100644
--- a/src/cleanup.c
+++ b/src/cleanup.c
@@ -49,12 +49,11 @@ void cu_installnew(int argc, void **argv) {
* We have the following possible situations for non-conffiles:
* <foo>.dpkg-tmp exists - in this case we want to remove
* <foo> if it exists and replace it with <foo>.dpkg-tmp.
- * This undoes the backup operation. We also make sure
- * we delete <foo>.dpkg-new in case that's still hanging around.
- * <foo>.dpkg-tmp does not exist - in this case we haven't
- * got as far as creating it (or there wasn't an old version).
- * In this case we just delete <foo>.dpkg-new if it exists,
- * as it may be a half-extracted thing.
+ * This undoes the backup operation.
+ * <foo>.dpkg-tmp does not exist - <foo> may be on the disk,
+ * as a new file which didn't fail, remove it if it is.
+ * In both cases, we also make sure we delete <foo>.dpkg-new in
+ * case that's still hanging around.
* For conffiles, we simply delete <foo>.dpkg-new. For these,
* <foo>.dpkg-tmp shouldn't exist, as we don't make a backup
* at this stage. Just to be on the safe side, though, we don't
@@ -89,6 +88,11 @@ void cu_installnew(int argc, void **argv) {
/* Either we can do an atomic restore, or we've made room: */
if (rename(fnametmpvb.buf,fnamevb.buf))
ohshite(_("unable to restore backup version of `%.250s'"),namenode->name);
+ } else if (namenode->flags & fnnf_placed_on_disk) {
+ debug(dbg_eachfiledetail,"cu_installnew removing new file");
+ if (unlinkorrmdir(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
+ ohshite(_("unable to remove newly-installed version of `%.250s'"),
+ namenode->name);
} else {
debug(dbg_eachfiledetail,"cu_installnew not restoring");
}
@@ -165,6 +169,7 @@ void cu_preinstverynew(int argc, void **argv) {
"abort-install",(char*)0);
pkg->status= stat_notinstalled;
pkg->eflag &= ~eflagf_reinstreq;
+ blankpackageperfile(&pkg->installed);
modstatdb_note(pkg);
cleanup_pkg_failed--;
}
diff --git a/src/filesdb.c b/src/filesdb.c
index 35f1d2ed5..ed7e56fac 100644
--- a/src/filesdb.c
+++ b/src/filesdb.c
@@ -364,56 +364,56 @@ void ensure_statoverrides(void) {
/* Extract the uid */
if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
- ohshit("syntax error in statusoverride file ");
+ ohshit("syntax error in statoverride file ");
*ptr=0;
if (thisline[0]=='#') {
fso->uid=strtol(thisline + 1, &endptr, 10);
if (*endptr!=0)
- ohshit("syntax error: invalid uid in statusoverride file ");
+ ohshit("syntax error: invalid uid in statoverride file ");
} else {
struct passwd* pw = getpwnam(thisline);
if (pw==NULL)
- ohshit("syntax error: unknown user `%s' in statusoverride file ", thisline);
+ ohshit("syntax error: unknown user `%s' in statoverride file ", thisline);
fso->uid=pw->pw_uid;
}
/* Move to the next bit */
thisline=ptr+1;
if (thisline>=loaded_list_end)
- ohshit("unexpected end of line in statusoverride file");
+ ohshit("unexpected end of line in statoverride file");
/* Extract the gid */
if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
- ohshit("syntax error in statusoverride file ");
+ ohshit("syntax error in statoverride file ");
*ptr=0;
if (thisline[0]=='#') {
fso->gid=strtol(thisline + 1, &endptr, 10);
if (*endptr!=0)
- ohshit("syntax error: invalid gid in statusoverride file ");
+ ohshit("syntax error: invalid gid in statoverride file ");
} else {
struct group* gr = getgrnam(thisline);
if (gr==NULL)
- ohshit("syntax error: unknown group `%s' in statusoverride file ", thisline);
+ ohshit("syntax error: unknown group `%s' in statoverride file ", thisline);
fso->gid=gr->gr_gid;
}
/* Move to the next bit */
thisline=ptr+1;
if (thisline>=loaded_list_end)
- ohshit("unexecpted end of line in statusoverride file");
+ ohshit("unexecpted end of line in statoverride file");
/* Extract the mode */
if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
- ohshit("syntax error in statusoverride file ");
+ ohshit("syntax error in statoverride file ");
*ptr=0;
fso->mode=strtol(thisline, &endptr, 8);
if (*endptr!=0)
- ohshit("syntax error: invalid mode in statusoverride file ");
+ ohshit("syntax error: invalid mode in statoverride file ");
/* Move to the next bit */
thisline=ptr+1;
if (thisline>=loaded_list_end)
- ohshit("unexecpted end of line in statusoverride file");
+ ohshit("unexecpted end of line in statoverride file");
fnn= findnamenode(thisline, 0);
if (fnn->statoverride)
diff --git a/src/filesdb.h b/src/filesdb.h
index cedaafeaf..3abaa205d 100644
--- a/src/filesdb.h
+++ b/src/filesdb.h
@@ -67,6 +67,7 @@ struct filenamenode {
fnnf_old_conff= 000004, /* in the old package's conffiles list */
fnnf_elide_other_lists= 000010, /* must remove from other packages' lists */
fnnf_no_atomic_overwrite= 000020, /* >=1 instance is a dir, cannot rename over */
+ fnnf_placed_on_disk= 000040, /* new file has been placed on the disk */
} flags; /* Set to zero when a new node is created. */
const char *oldhash; /* valid iff this namenode is in the newconffiles list */
struct stat *filestat;
diff --git a/src/processarc.c b/src/processarc.c
index 71454526c..56536e2d2 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -551,7 +551,7 @@ void process_archive(const char *filename) {
if (errno) {
ohshite(_("error reading dpkg-deb tar output"));
} else {
- ohshite(_("corrupted filesystem tarfile - corrupted package archive"));
+ ohshit(_("corrupted filesystem tarfile - corrupted package archive"));
}
}
fd_null_copy(tc.backendpipe,-1,_("dpkg-deb: zap possible trailing zeros"));
@@ -596,7 +596,11 @@ void process_archive(const char *filename) {
(namenode->flags & fnnf_new_conff) ||
(namenode->flags & fnnf_new_inarchive))
continue;
- if (isdirectoryinuse(namenode,pkg)) continue;
+ if (!stat(namenode->name,&stab) && S_ISDIR(stab.st_mode)) {
+ debug(dbg_eachfiledetail, "process_archive: %s is a directory",
+ namenode->name);
+ if (isdirectoryinuse(namenode,pkg)) continue;
+ }
fnamevb.used= fnameidlu;
varbufaddstr(&fnamevb, namenodetouse(namenode,pkg)->name);
varbufaddc(&fnamevb,0);
@@ -649,7 +653,7 @@ void process_archive(const char *filename) {
* to another file.
*/
struct stat stat_buf;
- if (stat(fnamevb.buf,&stat_buf)==0) {
+ if (lstat(fnamevb.buf,&stat_buf)==0) {
if (S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode))
chmod(fnamevb.buf, 0);
if (stat_buf.st_mode & (S_ISUID|S_ISGID))
@@ -781,7 +785,10 @@ void process_archive(const char *filename) {
newpossi->ed= possi->ed;
newpossi->next= 0; newpossi->nextrev= newpossi->backrev= 0;
newpossi->verrel= possi->verrel;
- if (possi->verrel != dvr_none) newpossi->version= possi->version;
+ if (possi->verrel != dvr_none)
+ newpossi->version= possi->version;
+ else
+ blankversion(&newpossi->version);
newpossi->cyclebreak= 0;
*newpossilastp= newpossi;
newpossilastp= &newpossi->next;
diff --git a/src/query.c b/src/query.c
index 7c9b72556..02dc1dea0 100644
--- a/src/query.c
+++ b/src/query.c
@@ -387,8 +387,9 @@ void enqperpackage(const char *const *argv) {
default:
internerr("unknown action");
}
-
- putchar('\n');
+
+ if (*(argv + 1) == 0)
+ putchar('\n');
if (ferror(stdout)) werr("stdout");
}
diff --git a/src/remove.c b/src/remove.c
index 8964de7c3..be7c71c8b 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -264,7 +264,7 @@ static void removal_bulk_remove_files(
* to another file
*/
struct stat stat_buf;
- if (stat(fnvb.buf,&stat_buf)==0) {
+ if (lstat(fnvb.buf,&stat_buf)==0) {
if (S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode)) {
chmod(fnvb.buf,0);
}