diff options
author | Frank Lichtenheld <djpig@debian.org> | 2006-01-18 08:30:03 +0000 |
---|---|---|
committer | Frank Lichtenheld <djpig@debian.org> | 2006-01-18 08:30:03 +0000 |
commit | 53696310976b88bb01197796044ae92c571c89c3 (patch) | |
tree | b853b364ffb8136a480c8e374d954b1daefed32d /src | |
parent | baa3c192761f69c5413d230c26fd2f56d79f7193 (diff) | |
download | dpkg-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.c | 51 | ||||
-rw-r--r-- | src/cleanup.c | 17 | ||||
-rw-r--r-- | src/filesdb.c | 22 | ||||
-rw-r--r-- | src/filesdb.h | 1 | ||||
-rw-r--r-- | src/processarc.c | 15 | ||||
-rw-r--r-- | src/query.c | 5 | ||||
-rw-r--r-- | src/remove.c | 2 |
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); } |