diff options
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r-- | apt-pkg/deb/debindexfile.cc | 18 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.h | 6 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 5 | ||||
-rw-r--r-- | apt-pkg/deb/debsystem.cc | 2 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 80 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.h | 17 |
6 files changed, 102 insertions, 26 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index b89429d86..6d9e99497 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -262,15 +262,15 @@ unsigned long debPackagesIndex::Size() const // PackagesIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { string PackageFile = IndexFile("Packages"); FileFd Pkg(PackageFile,FileFd::ReadOnly); debListParser Parser(&Pkg, Architecture); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); - - Prog.SubProgress(0,Info("Packages")); + if (Prog != NULL) + Prog->SubProgress(0,Info("Packages")); ::URI Tmp(URI); if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); @@ -445,7 +445,7 @@ unsigned long debTranslationsIndex::Size() const // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { // Check the translation file, if in use string TranslationFile = IndexFile(Language); @@ -456,7 +456,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const if (_error->PendingError() == true) return false; - Prog.SubProgress(0, Info(TranslationFile.c_str())); + if (Prog != NULL) + Prog->SubProgress(0, Info(TranslationFile.c_str())); if (Gen.SelectFile(TranslationFile,string(),*this) == false) return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); @@ -529,7 +530,7 @@ unsigned long debStatusIndex::Size() const // StatusIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { FileFd Pkg(File,FileFd::ReadOnly); if (_error->PendingError() == true) @@ -537,8 +538,9 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const debListParser Parser(&Pkg); if (_error->PendingError() == true) return false; - - Prog.SubProgress(0,File); + + if (Prog != NULL) + Prog->SubProgress(0,File); if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index 766e8b214..b5085992d 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -35,7 +35,7 @@ class debStatusIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(string File); @@ -67,7 +67,7 @@ class debPackagesIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debPackagesIndex(string const &URI, string const &Dist, string const &Section, @@ -99,7 +99,7 @@ class debTranslationsIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debTranslationsIndex(string URI,string Dist,string Section, char const * const Language); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 0551a5f7c..83c5b8d2e 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -133,10 +133,9 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) } // Archive Size - Ver->Size = (unsigned)Section.FindI("Size"); - + Ver->Size = Section.FindULL("Size"); // Unpacked Size (in K) - Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size"); + Ver->InstalledSize = Section.FindULL("Installed-Size"); Ver->InstalledSize *= 1024; // Priority diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 59f826d96..31c26ab2f 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -158,7 +158,7 @@ bool debSystem::Initialize(Configuration &Cnf) /* These really should be jammed into a generic 'Local Database' engine which is yet to be determined. The functions in pkgcachegen should be the only users of these */ - Cnf.CndSet("Dir::State::userstatus","status.user"); // Defunct + Cnf.CndSet("Dir::State::extended_states", Cnf.FindDir("Dir::State").append("extended_states")); Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status"); Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg"); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8318fe37f..0ac6ac168 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -470,7 +470,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::clog << "send: '" << status.str() << "'" << endl; if (strncmp(action, "disappear", strlen("disappear")) == 0) - disappearedPkgs.insert(string(pkg_or_trigger)); + handleDisappearAction(pkg_or_trigger); return; } @@ -530,6 +530,51 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << " action: " << action << endl; } /*}}}*/ +// DPkgPM::handleDisappearAction /*{{{*/ +void pkgDPkgPM::handleDisappearAction(string const &pkgname) +{ + // record the package name for display and stuff later + disappearedPkgs.insert(pkgname); + + pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); + if (unlikely(Pkg.end() == true)) + return; + // the disappeared package was auto-installed - nothing to do + if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + return; + pkgCache::VerIterator PkgVer = Pkg.CurrentVer(); + if (unlikely(PkgVer.end() == true)) + return; + /* search in the list of dependencies for (Pre)Depends, + check if this dependency has a Replaces on our package + and if so transfer the manual installed flag to it */ + for (pkgCache::DepIterator Dep = PkgVer.DependsList(); Dep.end() != true; ++Dep) + { + if (Dep->Type != pkgCache::Dep::Depends && + Dep->Type != pkgCache::Dep::PreDepends) + continue; + pkgCache::PkgIterator Tar = Dep.TargetPkg(); + if (unlikely(Tar.end() == true)) + continue; + // the package is already marked as manual + if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto) + continue; + pkgCache::VerIterator TarVer = Tar.CurrentVer(); + for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep) + { + if (Rep->Type != pkgCache::Dep::Replaces) + continue; + if (Pkg != Rep.TargetPkg()) + continue; + // okay, they are strongly connected - transfer manual-bit + if (Debug == true) + std::clog << "transfer manual-bit from disappeared »" << pkgname << "« to »" << Tar.FullName() << "«" << std::endl; + Cache[Tar].Flags &= ~Flag::Auto; + break; + } + } +} + /*}}}*/ // DPkgPM::DoDpkgStatusFd /*{{{*/ // --------------------------------------------------------------------- /* @@ -568,15 +613,15 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) } /*}}}*/ // DPkgPM::WriteHistoryTag /*{{{*/ -void pkgDPkgPM::WriteHistoryTag(string tag, string value) +void pkgDPkgPM::WriteHistoryTag(string const &tag, string value) { - if (value.size() > 0) - { - // poor mans rstrip(", ") - if (value[value.size()-2] == ',' && value[value.size()-1] == ' ') - value.erase(value.size() - 2, 2); - fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); - } + size_t const length = value.length(); + if (length == 0) + return; + // poor mans rstrip(", ") + if (value[length-2] == ',' && value[length-1] == ' ') + value.erase(length - 2, 2); + fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); } /*}}}*/ // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() @@ -663,7 +708,22 @@ bool pkgDPkgPM::CloseLog() if(history_out) { - if (dpkg_error.size() > 0) + if (disappearedPkgs.empty() == false) + { + string disappear; + for (std::set<std::string>::const_iterator d = disappearedPkgs.begin(); + d != disappearedPkgs.end(); ++d) + { + pkgCache::PkgIterator P = Cache.FindPkg(*d); + disappear.append(*d); + if (P.end() == true) + disappear.append(", "); + else + disappear.append(" (").append(Cache[P].CurVersion).append("), "); + } + WriteHistoryTag("Disappeared", disappear); + } + if (dpkg_error.empty() == false) fprintf(history_out, "Error: %s\n", dpkg_error.c_str()); fprintf(history_out, "End-Date: %s\n", timestr); fclose(history_out); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 330c788a2..9a4478f7c 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -32,6 +32,21 @@ class pkgDPkgPM : public pkgPackageManager FILE *history_out; string dpkg_error; + /** \brief record the disappear action and handle accordingly + + dpkg let packages disappear then they have no files any longer and + nothing depends on them. We need to collect this as dpkg as well as + APT doesn't know beforehand that the package will disappear, so the + only possible option is to tell the user afterwards about it. + To enhance the experience we also try to forward the auto-install + flag so the disappear-causer(s) are not autoremoved next time - + for the transfer to happen the disappeared version needs to depend + on the package the flag should be forwarded to and this package + needs to declare a Replaces on the disappeared package. + \param pkgname Name of the package that disappeared + */ + void handleDisappearAction(string const &pkgname); + protected: // progress reporting @@ -68,7 +83,7 @@ class pkgDPkgPM : public pkgPackageManager // Helpers bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); - void WriteHistoryTag(string tag, string value); + void WriteHistoryTag(string const &tag, string value); // dpkg log bool OpenLog(); |