diff options
Diffstat (limited to 'apt-pkg')
59 files changed, 1707 insertions, 693 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 453fce109..f231c42b4 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -438,7 +438,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); SHA1Summation SHA1; - SHA1.AddFD(fd.Fd(), fd.Size()); + SHA1.AddFD(fd); string const local_sha1 = SHA1.Result(); if(local_sha1 == ServerSha1) @@ -669,7 +669,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ FileFd fd(FinalFile, FileFd::ReadOnly); SHA1Summation SHA1; - SHA1.AddFD(fd.Fd(), fd.Size()); + SHA1.AddFD(fd); string local_sha1 = string(SHA1.Result()); if(Debug) std::clog << "QueueNextDiff: " diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 27b8e887b..51d539450 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -25,6 +25,14 @@ #include <apt-pkg/weakptr.h> #include <apt-pkg/pkgcache.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/indexfile.h> +#include <apt-pkg/vendor.h> +#include <apt-pkg/sourcelist.h> +#include <apt-pkg/pkgrecords.h> +#include <apt-pkg/indexrecords.h> +#endif + /** \addtogroup acquire * @{ * diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index c3f042ee0..2dd9ad685 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -25,6 +25,11 @@ #include <string> #include <vector> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/configuration.h> +#include <apt-pkg/strutl.h> +#endif + class Hashes; class pkgAcqMethod { diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 93772403d..3d5d7a4b7 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -75,6 +75,11 @@ #include <sys/time.h> #include <unistd.h> +#ifndef APT_8_CLEANER_HEADERS +using std::vector; +using std::string; +#endif + class pkgAcquireStatus; /** \brief The core download scheduler. {{{ diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 948fe1103..185d11e96 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -36,6 +36,11 @@ #include <iostream> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/acquire.h> +using std::ostream; +#endif + class pkgAcquireStatus; class pkgSimulate : public pkgPackageManager /*{{{*/ diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index b56e42855..802b12b61 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -20,6 +20,12 @@ #include <apt-pkg/depcache.h> #include <apt-pkg/macros.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/acquire.h> +#include <apt-pkg/policy.h> +#include <apt-pkg/sourcelist.h> +#endif + class pkgPolicy; class pkgSourceList; class OpProgress; diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 6b95eab70..b892ab4bf 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -29,7 +29,7 @@ /*}}}*/ namespace APT { // FromTask - Return all packages in the cache from a specific task /*{{{*/ -PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { +bool PackageContainerInterface::FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { size_t const archfound = pattern.find_last_of(':'); std::string arch = "native"; if (archfound != std::string::npos) { @@ -38,13 +38,16 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS } if (pattern[pattern.length() -1] != '^') - return APT::PackageSet(TASK); + return false; pattern.erase(pattern.length()-1); if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) - return APT::PackageSet(TASK); + return false; + + bool const wasEmpty = pci->empty(); + if (wasEmpty == true) + pci->setConstructor(TASK); - PackageSet pkgset(TASK); // get the records pkgRecords Recs(Cache); @@ -54,9 +57,10 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str()); if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) { _error->Error("Failed to compile task regexp"); - return pkgset; + return false; } + bool found = false; for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) { pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); if (Pkg.end() == true) @@ -75,22 +79,33 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS if (regexec(&Pattern, buf, 0, 0, 0) != 0) continue; - pkgset.insert(Pkg); + pci->insert(Pkg); + helper.showTaskSelection(Pkg, pattern); + found = true; } regfree(&Pattern); - if (pkgset.empty() == true) - return helper.canNotFindTask(Cache, pattern); + if (found == false) { + helper.canNotFindTask(pci, Cache, pattern); + pci->setConstructor(UNKNOWN); + return false; + } + + if (wasEmpty == false && pci->getConstructor() != UNKNOWN) + pci->setConstructor(UNKNOWN); - helper.showTaskSelection(pkgset, pattern); - return pkgset; + return true; } /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { +bool PackageContainerInterface::FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { static const char * const isregex = ".?+*|[^$"; if (pattern.find_first_of(isregex) == std::string::npos) - return PackageSet(REGEX); + return false; + + bool const wasEmpty = pci->empty(); + if (wasEmpty == true) + pci->setConstructor(REGEX); size_t archfound = pattern.find_last_of(':'); std::string arch = "native"; @@ -103,11 +118,11 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache } if (unlikely(Cache.GetPkgCache() == 0)) - return PackageSet(REGEX); + return false; APT::CacheFilter::PackageNameMatchesRegEx regexfilter(pattern); - PackageSet pkgset(REGEX); + bool found = false; for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexfilter(Grp) == false) continue; @@ -123,18 +138,25 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache continue; } - pkgset.insert(Pkg); + pci->insert(Pkg); + helper.showRegExSelection(Pkg, pattern); + found = true; } - if (pkgset.empty() == true) - return helper.canNotFindRegEx(Cache, pattern); + if (found == false) { + helper.canNotFindRegEx(pci, Cache, pattern); + pci->setConstructor(UNKNOWN); + return false; + } + + if (wasEmpty == false && pci->getConstructor() != UNKNOWN) + pci->setConstructor(UNKNOWN); - helper.showRegExSelection(pkgset, pattern); - return pkgset; + return true; } /*}}}*/ // FromName - Returns the package defined by this string /*{{{*/ -pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache, +pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { std::string pkg = str; size_t archfound = pkg.find_last_of(':'); @@ -160,144 +182,131 @@ pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache, return Pkg; } /*}}}*/ -// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ -std::map<unsigned short, PackageSet> PackageSet::GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list<PackageSet::Modifier> const &mods, - unsigned short const &fallback, CacheSetHelper &helper) { - std::map<unsigned short, PackageSet> pkgsets; - for (const char **I = cmdline; *I != 0; ++I) { - unsigned short modID = fallback; - std::string str = *I; - bool modifierPresent = false; - for (std::list<PackageSet::Modifier>::const_iterator mod = mods.begin(); - mod != mods.end(); ++mod) { - size_t const alength = strlen(mod->Alias); - switch(mod->Pos) { - case PackageSet::Modifier::POSTFIX: - if (str.compare(str.length() - alength, alength, - mod->Alias, 0, alength) != 0) - continue; - str.erase(str.length() - alength); - modID = mod->ID; - break; - case PackageSet::Modifier::PREFIX: - continue; - case PackageSet::Modifier::NONE: - continue; - } - modifierPresent = true; - break; - } - if (modifierPresent == true) { - bool const errors = helper.showErrors(false); - pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper); - helper.showErrors(errors); - if (Pkg.end() == false) { - pkgsets[fallback].insert(Pkg); - continue; - } - } - pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper)); - } - return pkgsets; -} - /*}}}*/ -// FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) { - PackageSet pkgset; - for (const char **I = cmdline; *I != 0; ++I) { - PackageSet pset = FromString(Cache, *I, helper); - pkgset.insert(pset.begin(), pset.end()); - } - return pkgset; -} - /*}}}*/ // FromString - Return all packages matching a specific string /*{{{*/ -PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { +bool PackageContainerInterface::FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { + bool found = true; _error->PushToStack(); - PackageSet pkgset; pkgCache::PkgIterator Pkg = FromName(Cache, str, helper); if (Pkg.end() == false) - pkgset.insert(Pkg); - else { - pkgset = FromTask(Cache, str, helper); - if (pkgset.empty() == true) { - pkgset = FromRegEx(Cache, str, helper); - if (pkgset.empty() == true) - pkgset = helper.canNotFindPackage(Cache, str); - } + pci->insert(Pkg); + else if (FromTask(pci, Cache, str, helper) == false && + FromRegEx(pci, Cache, str, helper) == false) + { + helper.canNotFindPackage(pci, Cache, str); + found = false; } - if (pkgset.empty() == false) + if (found == true) _error->RevertToStack(); else _error->MergeWithStack(); - return pkgset; + return found; } /*}}}*/ -// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ -std::map<unsigned short, VersionSet> VersionSet::GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list<VersionSet::Modifier> const &mods, - unsigned short const &fallback, CacheSetHelper &helper) { - std::map<unsigned short, VersionSet> versets; - for (const char **I = cmdline; *I != 0; ++I) { - unsigned short modID = fallback; - VersionSet::Version select = VersionSet::NEWEST; - std::string str = *I; - bool modifierPresent = false; - for (std::list<VersionSet::Modifier>::const_iterator mod = mods.begin(); - mod != mods.end(); ++mod) { - if (modID == fallback && mod->ID == fallback) - select = mod->SelectVersion; - size_t const alength = strlen(mod->Alias); - switch(mod->Pos) { - case VersionSet::Modifier::POSTFIX: - if (str.compare(str.length() - alength, alength, - mod->Alias, 0, alength) != 0) - continue; - str.erase(str.length() - alength); - modID = mod->ID; - select = mod->SelectVersion; - break; - case VersionSet::Modifier::PREFIX: - continue; - case VersionSet::Modifier::NONE: +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +bool PackageContainerInterface::FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) { + bool found = false; + for (const char **I = cmdline; *I != 0; ++I) + found |= PackageContainerInterface::FromString(pci, Cache, *I, helper); + return found; +} + /*}}}*/ +// FromModifierCommandLine - helper doing the work for PKG:GroupedFromCommandLine /*{{{*/ +bool PackageContainerInterface::FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci, + pkgCacheFile &Cache, const char * cmdline, + std::list<Modifier> const &mods, CacheSetHelper &helper) { + std::string str = cmdline; + bool modifierPresent = false; + for (std::list<Modifier>::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) continue; - } - modifierPresent = true; + str.erase(str.length() - alength); + modID = mod->ID; break; + case Modifier::PREFIX: + continue; + case Modifier::NONE: + continue; } - - if (modifierPresent == true) { - bool const errors = helper.showErrors(false); - VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true); - helper.showErrors(errors); - if (vset.empty() == false) { - versets[fallback].insert(vset); + modifierPresent = true; + break; + } + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + pkgCache::PkgIterator Pkg = FromName(Cache, cmdline, helper); + helper.showErrors(errors); + if (Pkg.end() == false) { + pci->insert(Pkg); + return true; + } + } + return FromString(pci, Cache, str, helper); +} + /*}}}*/ +// FromModifierCommandLine - helper doing the work for VER:GroupedFromCommandLine /*{{{*/ +bool VersionContainerInterface::FromModifierCommandLine(unsigned short &modID, + VersionContainerInterface * const vci, + pkgCacheFile &Cache, const char * cmdline, + std::list<Modifier> const &mods, + CacheSetHelper &helper) { + Version select = NEWEST; + std::string str = cmdline; + bool modifierPresent = false; + unsigned short fallback = modID; + for (std::list<Modifier>::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + if (modID == fallback && mod->ID == fallback) + select = mod->SelectVersion; + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) continue; - } + str.erase(str.length() - alength); + modID = mod->ID; + select = mod->SelectVersion; + break; + case Modifier::PREFIX: + continue; + case Modifier::NONE: + continue; } - versets[modID].insert(VersionSet::FromString(Cache, str, select , helper)); + modifierPresent = true; + break; } - return versets; + + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + bool const found = VersionContainerInterface::FromString(vci, Cache, cmdline, select, helper, true); + helper.showErrors(errors); + if (found == true) + return true; + } + return FromString(vci, Cache, str, select, helper); } /*}}}*/ // FromCommandLine - Return all versions specified on commandline /*{{{*/ -APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { - VersionSet verset; +bool VersionContainerInterface::FromCommandLine(VersionContainerInterface * const vci, + pkgCacheFile &Cache, const char **cmdline, + Version const &fallback, CacheSetHelper &helper) { + bool found = false; for (const char **I = cmdline; *I != 0; ++I) - verset.insert(VersionSet::FromString(Cache, *I, fallback, helper)); - return verset; + found |= VersionContainerInterface::FromString(vci, Cache, *I, fallback, helper); + return found; } /*}}}*/ // FromString - Returns all versions spedcified by a string /*{{{*/ -APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper, - bool const &onlyFromName) { +bool VersionContainerInterface::FromString(VersionContainerInterface * const vci, + pkgCacheFile &Cache, std::string pkg, + Version const &fallback, CacheSetHelper &helper, + bool const onlyFromName) { std::string ver; bool verIsRel = false; size_t const vertag = pkg.find_last_of("/="); @@ -308,19 +317,20 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } PackageSet pkgset; if (onlyFromName == false) - pkgset = PackageSet::FromString(Cache, pkg, helper); + PackageContainerInterface::FromString(&pkgset, Cache, pkg, helper); else { - pkgset.insert(PackageSet::FromName(Cache, pkg, helper)); + pkgset.insert(PackageContainerInterface::FromName(Cache, pkg, helper)); } - VersionSet verset; bool errors = true; if (pkgset.getConstructor() != PackageSet::UNKNOWN) errors = helper.showErrors(false); + + bool found = false; for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { if (vertag == std::string::npos) { - verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); + found |= VersionContainerInterface::FromPackage(vci, Cache, P, fallback, helper); continue; } pkgCache::VerIterator V; @@ -350,75 +360,78 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, if (V.end() == true) continue; helper.showSelectedVersion(P, V, ver, verIsRel); - verset.insert(V); + vci->insert(V); + found = true; } if (pkgset.getConstructor() != PackageSet::UNKNOWN) helper.showErrors(errors); - return verset; + return found; } /*}}}*/ // FromPackage - versions from package based on fallback /*{{{*/ -VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, - VersionSet::Version const &fallback, CacheSetHelper &helper) { - VersionSet verset; +bool VersionContainerInterface::FromPackage(VersionContainerInterface * const vci, + pkgCacheFile &Cache, + pkgCache::PkgIterator const &P, + Version const &fallback, + CacheSetHelper &helper) { pkgCache::VerIterator V; bool showErrors; + bool found = false; switch(fallback) { - case VersionSet::ALL: + case ALL: if (P->VersionList != 0) for (V = P.VersionList(); V.end() != true; ++V) - verset.insert(V); + found |= vci->insert(V); else - verset.insert(helper.canNotFindAllVer(Cache, P)); + helper.canNotFindAllVer(vci, Cache, P); break; - case VersionSet::CANDANDINST: - verset.insert(getInstalledVer(Cache, P, helper)); - verset.insert(getCandidateVer(Cache, P, helper)); + case CANDANDINST: + found |= vci->insert(getInstalledVer(Cache, P, helper)); + found |= vci->insert(getCandidateVer(Cache, P, helper)); break; - case VersionSet::CANDIDATE: - verset.insert(getCandidateVer(Cache, P, helper)); + case CANDIDATE: + found |= vci->insert(getCandidateVer(Cache, P, helper)); break; - case VersionSet::INSTALLED: - verset.insert(getInstalledVer(Cache, P, helper)); + case INSTALLED: + found |= vci->insert(getInstalledVer(Cache, P, helper)); break; - case VersionSet::CANDINST: + case CANDINST: showErrors = helper.showErrors(false); V = getCandidateVer(Cache, P, helper); if (V.end() == true) V = getInstalledVer(Cache, P, helper); helper.showErrors(showErrors); if (V.end() == false) - verset.insert(V); + found |= vci->insert(V); else - verset.insert(helper.canNotFindInstCandVer(Cache, P)); + helper.canNotFindInstCandVer(vci, Cache, P); break; - case VersionSet::INSTCAND: + case INSTCAND: showErrors = helper.showErrors(false); V = getInstalledVer(Cache, P, helper); if (V.end() == true) V = getCandidateVer(Cache, P, helper); helper.showErrors(showErrors); if (V.end() == false) - verset.insert(V); + found |= vci->insert(V); else - verset.insert(helper.canNotFindInstCandVer(Cache, P)); + helper.canNotFindInstCandVer(vci, Cache, P); break; - case VersionSet::NEWEST: + case NEWEST: if (P->VersionList != 0) - verset.insert(P.VersionList()); + found |= vci->insert(P.VersionList()); else - verset.insert(helper.canNotFindNewestVer(Cache, P)); + helper.canNotFindNewestVer(Cache, P); break; } - return verset; + return found; } /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ -pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, +pkgCache::VerIterator VersionContainerInterface::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { pkgCache::VerIterator Cand; - if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false) - { + if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false) { if (unlikely(Cache.GetPolicy() == 0)) return pkgCache::VerIterator(Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); @@ -431,13 +444,14 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, } /*}}}*/ // getInstalledVer - Returns the installed version of the given package /*{{{*/ -pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, +pkgCache::VerIterator VersionContainerInterface::getInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { if (Pkg->CurrentVer == 0) return helper.canNotFindInstalledVer(Cache, Pkg); return Pkg.CurrentVer(); } /*}}}*/ + // canNotFindPkgName - handle the case no package has this name /*{{{*/ pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache, std::string const &str) { @@ -447,46 +461,40 @@ pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache, } /*}}}*/ // canNotFindTask - handle the case no package is found for a task /*{{{*/ -PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) { +void CacheSetHelper::canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) { if (ShowError == true) _error->Insert(ErrorType, _("Couldn't find task '%s'"), pattern.c_str()); - return PackageSet(); } /*}}}*/ // canNotFindRegEx - handle the case no package is found by a regex /*{{{*/ -PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) { +void CacheSetHelper::canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) { if (ShowError == true) _error->Insert(ErrorType, _("Couldn't find any package by regex '%s'"), pattern.c_str()); - return PackageSet(); } /*}}}*/ // canNotFindPackage - handle the case no package is found from a string/*{{{*/ -PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) { - return PackageSet(); +void CacheSetHelper::canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str) { } /*}}}*/ // canNotFindAllVer /*{{{*/ -VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache, +void CacheSetHelper::canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Insert(ErrorType, _("Can't select versions from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str()); - return VersionSet(); } /*}}}*/ // canNotFindInstCandVer /*{{{*/ -VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache, +void CacheSetHelper::canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str()); - return VersionSet(); } /*}}}*/ // canNotFindInstCandVer /*{{{*/ -VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache, +void CacheSetHelper::canNotFindCandInstVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str()); - return VersionSet(); } /*}}}*/ // canNotFindNewestVer /*{{{*/ @@ -513,4 +521,21 @@ pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache return pkgCache::VerIterator(Cache, 0); } /*}}}*/ +// showTaskSelection /*{{{*/ +void CacheSetHelper::showTaskSelection(pkgCache::PkgIterator const &pkg, + std::string const &pattern) { +} + /*}}}*/ +// showRegExSelection /*{{{*/ +void CacheSetHelper::showRegExSelection(pkgCache::PkgIterator const &pkg, + std::string const &pattern) { +} + /*}}}*/ +// showSelectedVersion /*{{{*/ +void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const Ver, + std::string const &ver, + bool const verIsRel) { +} + /*}}}*/ } diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 3b1118bdc..91d7eec1c 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -14,17 +14,24 @@ #include <list> #include <map> #include <set> +#include <list> #include <string> +#include <iterator> #include <apt-pkg/error.h> #include <apt-pkg/pkgcache.h> + +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/cachefile.h> +#endif /*}}}*/ class pkgCacheFile; namespace APT { -class PackageSet; -class VersionSet; +class PackageContainerInterface; +class VersionContainerInterface; + class CacheSetHelper { /*{{{*/ /** \class APT::CacheSetHelper Simple base class with a lot of virtual methods which can be overridden @@ -35,25 +42,28 @@ class CacheSetHelper { /*{{{*/ printed out. */ public: /*{{{*/ - CacheSetHelper(bool const &ShowError = true, + CacheSetHelper(bool const ShowError = true, GlobalError::MsgType ErrorType = GlobalError::ERROR) : ShowError(ShowError), ErrorType(ErrorType) {}; virtual ~CacheSetHelper() {}; - virtual void showTaskSelection(PackageSet const &pkgset, std::string const &pattern) {}; - virtual void showRegExSelection(PackageSet const &pkgset, std::string const &pattern) {}; + virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern); + virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern); virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, - std::string const &ver, bool const &verIsRel) {}; + std::string const &ver, bool const verIsRel); - virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str); - virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern); - virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern); - virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str); - virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); - virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, + virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); + virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); + virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str); + + virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + virtual void canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); - virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, + virtual void canNotFindCandInstVer(VersionContainerInterface * const vci, + pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + + virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str); virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, @@ -62,7 +72,7 @@ public: /*{{{*/ pkgCache::PkgIterator const &Pkg); bool showErrors() const { return ShowError; }; - bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }; + bool showErrors(bool const newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }; GlobalError::MsgType errorType() const { return ErrorType; }; GlobalError::MsgType errorType(GlobalError::MsgType const &newValue) { @@ -79,53 +89,134 @@ protected: bool ShowError; GlobalError::MsgType ErrorType; }; /*}}}*/ -class PackageSet : public std::set<pkgCache::PkgIterator> { /*{{{*/ -/** \class APT::PackageSet - - Simple wrapper around a std::set to provide a similar interface to - a set of packages as to the complete set of all packages in the - pkgCache. */ -public: /*{{{*/ - /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {/*{{{*/ +class PackageContainerInterface { /*{{{*/ +/** \class PackageContainerInterface + + * Interface ensuring that all operations can be executed on the yet to + * define concrete PackageContainer - access to all methods is possible, + * but in general the wrappers provided by the PackageContainer template + * are nicer to use. + + * This class mostly protects use from the need to write all implementation + * of the methods working on containers in the template */ +public: + class const_iterator { /*{{{*/ public: - const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) : - std::set<pkgCache::PkgIterator>::const_iterator(x) {} - - operator pkgCache::PkgIterator(void) { return **this; } - - inline const char *Name() const {return (**this).Name(); } - inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } - inline std::string FullName() const { return (**this).FullName(); } - inline const char *Section() const {return (**this).Section(); } - inline bool Purge() const {return (**this).Purge(); } - inline const char *Arch() const {return (**this).Arch(); } - inline pkgCache::GrpIterator Group() const { return (**this).Group(); } - inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } - inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } - inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } - inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } - inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } - inline const char *CandVersion() const { return (**this).CandVersion(); } - inline const char *CurVersion() const { return (**this).CurVersion(); } - inline pkgCache *Cache() const { return (**this).Cache(); }; - inline unsigned long Index() const {return (**this).Index();}; + virtual pkgCache::PkgIterator getPkg() const = 0; + operator pkgCache::PkgIterator(void) const { return getPkg(); } + + inline const char *Name() const {return getPkg().Name(); } + inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); } + inline std::string FullName() const { return getPkg().FullName(); } + inline const char *Section() const {return getPkg().Section(); } + inline bool Purge() const {return getPkg().Purge(); } + inline const char *Arch() const {return getPkg().Arch(); } + inline pkgCache::GrpIterator Group() const { return getPkg().Group(); } + inline pkgCache::VerIterator VersionList() const { return getPkg().VersionList(); } + inline pkgCache::VerIterator CurrentVer() const { return getPkg().CurrentVer(); } + inline pkgCache::DepIterator RevDependsList() const { return getPkg().RevDependsList(); } + inline pkgCache::PrvIterator ProvidesList() const { return getPkg().ProvidesList(); } + inline pkgCache::PkgIterator::OkState State() const { return getPkg().State(); } + inline const char *CandVersion() const { return getPkg().CandVersion(); } + inline const char *CurVersion() const { return getPkg().CurVersion(); } + inline pkgCache *Cache() const { return getPkg().Cache(); }; + inline unsigned long Index() const {return getPkg().Index();}; // we have only valid iterators here inline bool end() const { return false; }; - friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } + inline pkgCache::Package const * operator->() const {return &*getPkg();}; + }; + /*}}}*/ + + virtual bool insert(pkgCache::PkgIterator const &P) = 0; + virtual bool empty() const = 0; + virtual void clear() = 0; + + enum Constructor { UNKNOWN, REGEX, TASK }; + virtual void setConstructor(Constructor const &con) = 0; + virtual Constructor getConstructor() const = 0; + + static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); + static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper); + static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper); + static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); + + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; + }; - inline pkgCache::Package const * operator->() const { - return &***this; - }; + static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci, + pkgCacheFile &Cache, const char * cmdline, + std::list<Modifier> const &mods, CacheSetHelper &helper); +}; + /*}}}*/ +template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/ +/** \class APT::PackageContainer + + Simple wrapper around a container class like std::set to provide a similar + interface to a set of packages as to the complete set of all packages in the + pkgCache. */ + Container _cont; +public: /*{{{*/ + /** \brief smell like a pkgCache::PkgIterator */ + class const_iterator : public PackageContainerInterface::const_iterator,/*{{{*/ + public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> { + typename Container::const_iterator _iter; + public: + const_iterator(typename Container::const_iterator i) : _iter(i) {} + pkgCache::PkgIterator getPkg(void) const { return *_iter; } + inline pkgCache::PkgIterator operator*(void) const { return *_iter; }; + operator typename Container::const_iterator(void) const { return _iter; } + inline const_iterator& operator++() { ++_iter; return *this; } + inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; } + inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; }; + inline bool operator==(const_iterator const &i) const { return _iter == i._iter; }; + friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); } + }; + class iterator : public PackageContainerInterface::const_iterator, + public std::iterator<std::forward_iterator_tag, typename Container::iterator> { + typename Container::iterator _iter; + public: + iterator(typename Container::iterator i) : _iter(i) {} + pkgCache::PkgIterator getPkg(void) const { return *_iter; } + inline pkgCache::PkgIterator operator*(void) const { return *_iter; }; + operator typename Container::iterator(void) const { return _iter; } + operator typename PackageContainer<Container>::const_iterator() { return PackageContainer<Container>::const_iterator(_iter); } + inline iterator& operator++() { ++_iter; return *this; } + inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } + inline bool operator!=(iterator const &i) const { return _iter != i._iter; }; + inline bool operator==(iterator const &i) const { return _iter == i._iter; }; + friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); } }; - // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef APT::PackageSet::const_iterator iterator; /*}}}*/ - using std::set<pkgCache::PkgIterator>::insert; - inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set<pkgCache::PkgIterator>::insert(P); }; - inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); }; + bool insert(pkgCache::PkgIterator const &P) { if (P.end() == true) return false; _cont.insert(P); return true; }; + template<class Cont> void insert(PackageContainer<Cont> const &pkgcont) { _cont.insert((typename Cont::const_iterator)pkgcont.begin(), (typename Cont::const_iterator)pkgcont.end()); }; + void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }; + + bool empty() const { return _cont.empty(); }; + void clear() { return _cont.clear(); }; + void erase(iterator position) { _cont.erase((typename Container::iterator)position); }; + size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); }; + void erase(iterator first, iterator last) { _cont.erase(first, last); }; + size_t size() const { return _cont.size(); }; + + const_iterator begin() const { return const_iterator(_cont.begin()); }; + const_iterator end() const { return const_iterator(_cont.end()); }; + iterator begin() { return iterator(_cont.begin()); }; + iterator end() { return iterator(_cont.end()); }; + const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); }; + + void setConstructor(Constructor const &by) { ConstructedBy = by; }; + Constructor getConstructor() const { return ConstructedBy; }; + + PackageContainer() : ConstructedBy(UNKNOWN) {}; + PackageContainer(Constructor const &by) : ConstructedBy(by) {}; /** \brief returns all packages in the cache who belong to the given task @@ -135,8 +226,12 @@ public: /*{{{*/ \param Cache the packages are in \param pattern name of the task \param helper responsible for error and message handling */ - static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); - static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { + static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) { + PackageContainer cont(TASK); + PackageContainerInterface::FromTask(&cont, Cache, pattern, helper); + return cont; + } + static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; return FromTask(Cache, pattern, helper); } @@ -149,32 +244,43 @@ public: /*{{{*/ \param Cache the packages are in \param pattern regular expression for package names \param helper responsible for error and message handling */ - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { + static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { + PackageContainer cont(REGEX); + PackageContainerInterface::FromRegEx(&cont, Cache, pattern, helper); + return cont; + } + + static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; return FromRegEx(Cache, pattern, helper); } - /** \brief returns all packages specified by a string + /** \brief returns a package specified by a string - \param Cache the packages are in - \param string String the package name(s) should be extracted from + \param Cache the package is in + \param pattern String the package name should be extracted from \param helper responsible for error and message handling */ - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) { + return PackageContainerInterface::FromName(Cache, pattern, helper); + } + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; - return FromString(Cache, string, helper); + return PackageContainerInterface::FromName(Cache, pattern, helper); } - /** \brief returns a package specified by a string + /** \brief returns all packages specified by a string - \param Cache the package is in - \param string String the package name should be extracted from + \param Cache the packages are in + \param pattern String the package name(s) should be extracted from \param helper responsible for error and message handling */ - static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); - static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) { + static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) { + PackageContainer cont; + PackageContainerInterface::FromString(&cont, Cache, pattern, helper); + return cont; + } + static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; - return FromName(Cache, string, helper); + return FromString(Cache, pattern, helper); } /** \brief returns all packages specified on the commandline @@ -184,20 +290,16 @@ public: /*{{{*/ \param Cache the packages are in \param cmdline Command line the package names should be extracted from \param helper responsible for error and message handling */ - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) { + PackageContainer cont; + PackageContainerInterface::FromCommandLine(&cont, Cache, cmdline, helper); + return cont; + } + static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { CacheSetHelper helper; return FromCommandLine(Cache, cmdline, helper); } - struct Modifier { - enum Position { NONE, PREFIX, POSTFIX }; - unsigned short ID; - const char * const Alias; - Position Pos; - Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; - }; - /** \brief group packages by a action modifiers At some point it is needed to get from the same commandline @@ -209,76 +311,93 @@ public: /*{{{*/ \param mods list of modifiers the method should accept \param fallback the default modifier group for a package \param helper responsible for error and message handling */ - static std::map<unsigned short, PackageSet> GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list<PackageSet::Modifier> const &mods, - unsigned short const &fallback, CacheSetHelper &helper); - static std::map<unsigned short, PackageSet> GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list<PackageSet::Modifier> const &mods, - unsigned short const &fallback) { + static std::map<unsigned short, PackageContainer> GroupedFromCommandLine( + pkgCacheFile &Cache, + const char **cmdline, + std::list<Modifier> const &mods, + unsigned short const &fallback, + CacheSetHelper &helper) { + std::map<unsigned short, PackageContainer> pkgsets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + PackageContainer pkgset; + PackageContainerInterface::FromModifierCommandLine(modID, &pkgset, Cache, *I, mods, helper); + pkgsets[modID].insert(pkgset); + } + return pkgsets; + } + static std::map<unsigned short, PackageContainer> GroupedFromCommandLine( + pkgCacheFile &Cache, + const char **cmdline, + std::list<Modifier> const &mods, + unsigned short const &fallback) { CacheSetHelper helper; return GroupedFromCommandLine(Cache, cmdline, mods, fallback, helper); } - - enum Constructor { UNKNOWN, REGEX, TASK }; - Constructor getConstructor() const { return ConstructedBy; }; - - PackageSet() : ConstructedBy(UNKNOWN) {}; - PackageSet(Constructor const &by) : ConstructedBy(by) {}; /*}}}*/ private: /*{{{*/ Constructor ConstructedBy; /*}}}*/ }; /*}}}*/ -class VersionSet : public std::set<pkgCache::VerIterator> { /*{{{*/ -/** \class APT::VersionSet - Simple wrapper around a std::set to provide a similar interface to - a set of versions as to the complete set of all versions in the - pkgCache. */ -public: /*{{{*/ +template<> template<class Cont> void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) { + for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p) + _cont.push_back(*p); +}; +// these two are 'inline' as otherwise the linker has problems with seeing these untemplated +// specializations again and again - but we need to see them, so that library users can use them +template<> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) { + if (P.end() == true) + return false; + _cont.push_back(P); + return true; +}; +template<> inline void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) { + for (const_iterator p = begin; p != end; ++p) + _cont.push_back(*p); +}; +typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet; +typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList; + +class VersionContainerInterface { /*{{{*/ +/** \class APT::VersionContainerInterface + + Same as APT::PackageContainerInterface, just for Versions */ +public: /** \brief smell like a pkgCache::VerIterator */ - class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {/*{{{*/ + class const_iterator { /*{{{*/ public: - const_iterator(std::set<pkgCache::VerIterator>::const_iterator x) : - std::set<pkgCache::VerIterator>::const_iterator(x) {} - - operator pkgCache::VerIterator(void) { return **this; } - - inline pkgCache *Cache() const { return (**this).Cache(); }; - inline unsigned long Index() const {return (**this).Index();}; + virtual pkgCache::VerIterator getVer() const = 0; + operator pkgCache::VerIterator(void) { return getVer(); } + + inline pkgCache *Cache() const { return getVer().Cache(); }; + inline unsigned long Index() const {return getVer().Index();}; + inline int CompareVer(const pkgCache::VerIterator &B) const { return getVer().CompareVer(B); }; + inline const char *VerStr() const { return getVer().VerStr(); }; + inline const char *Section() const { return getVer().Section(); }; + inline const char *Arch() const { return getVer().Arch(); }; + inline pkgCache::PkgIterator ParentPkg() const { return getVer().ParentPkg(); }; + inline pkgCache::DescIterator DescriptionList() const { return getVer().DescriptionList(); }; + inline pkgCache::DescIterator TranslatedDescription() const { return getVer().TranslatedDescription(); }; + inline pkgCache::DepIterator DependsList() const { return getVer().DependsList(); }; + inline pkgCache::PrvIterator ProvidesList() const { return getVer().ProvidesList(); }; + inline pkgCache::VerFileIterator FileList() const { return getVer().FileList(); }; + inline bool Downloadable() const { return getVer().Downloadable(); }; + inline const char *PriorityType() const { return getVer().PriorityType(); }; + inline std::string RelStr() const { return getVer().RelStr(); }; + inline bool Automatic() const { return getVer().Automatic(); }; + inline pkgCache::VerFileIterator NewestFile() const { return getVer().NewestFile(); }; // we have only valid iterators here inline bool end() const { return false; }; - inline pkgCache::Version const * operator->() const { - return &***this; - }; - - inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); }; - inline const char *VerStr() const { return (**this).VerStr(); }; - inline const char *Section() const { return (**this).Section(); }; - inline const char *Arch() const { return (**this).Arch(); }; - inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; - inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; - inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; - inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); }; - inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }; - inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); }; - inline bool Downloadable() const { return (**this).Downloadable(); }; - inline const char *PriorityType() const { return (**this).PriorityType(); }; - inline std::string RelStr() const { return (**this).RelStr(); }; - inline bool Automatic() const { return (**this).Automatic(); }; - inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; + inline pkgCache::Version const * operator->() const { return &*getVer(); }; }; /*}}}*/ - // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef APT::VersionSet::const_iterator iterator; - using std::set<pkgCache::VerIterator>::insert; - inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set<pkgCache::VerIterator>::insert(V); }; - inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); }; + virtual bool insert(pkgCache::VerIterator const &V) = 0; + virtual bool empty() const = 0; + virtual void clear() = 0; /** \brief specifies which version(s) will be returned if non is given */ enum Version { @@ -298,6 +417,116 @@ public: /*{{{*/ NEWEST }; + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + Version SelectVersion; + Modifier (unsigned short const &id, const char * const alias, Position const &pos, + Version const &select) : ID(id), Alias(alias), Pos(pos), + SelectVersion(select) {}; + }; + + static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache, + const char **cmdline, Version const &fallback, + CacheSetHelper &helper); + + static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache, + std::string pkg, Version const &fallback, CacheSetHelper &helper, + bool const onlyFromName = false); + + static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache, + pkgCache::PkgIterator const &P, Version const &fallback, + CacheSetHelper &helper); + + static bool FromModifierCommandLine(unsigned short &modID, + VersionContainerInterface * const vci, + pkgCacheFile &Cache, const char * cmdline, + std::list<Modifier> const &mods, + CacheSetHelper &helper); + + + static bool FromDependency(VersionContainerInterface * const vci, + pkgCacheFile &Cache, + pkgCache::DepIterator const &D, + Version const &selector, + CacheSetHelper &helper); + +protected: /*{{{*/ + + /** \brief returns the candidate version of the package + + \param Cache to be used to query for information + \param Pkg we want the candidate version from this package */ + static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); + + /** \brief returns the installed version of the package + + \param Cache to be used to query for information + \param Pkg we want the installed version from this package */ + static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); + /*}}}*/ +}; + /*}}}*/ +template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/ +/** \class APT::VersionContainer + + Simple wrapper around a container class like std::set to provide a similar + interface to a set of versions as to the complete set of all versions in the + pkgCache. */ + Container _cont; +public: /*{{{*/ + /** \brief smell like a pkgCache::VerIterator */ + class const_iterator : public VersionContainerInterface::const_iterator, + public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {/*{{{*/ + typename Container::const_iterator _iter; + public: + const_iterator(typename Container::const_iterator i) : _iter(i) {} + pkgCache::VerIterator getVer(void) const { return *_iter; } + inline pkgCache::VerIterator operator*(void) const { return *_iter; }; + operator typename Container::const_iterator(void) const { return _iter; } + inline const_iterator& operator++() { ++_iter; return *this; } + inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; } + inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; }; + inline bool operator==(const_iterator const &i) const { return _iter == i._iter; }; + friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); } + }; + class iterator : public VersionContainerInterface::const_iterator, + public std::iterator<std::forward_iterator_tag, typename Container::iterator> { + typename Container::iterator _iter; + public: + iterator(typename Container::iterator i) : _iter(i) {} + pkgCache::VerIterator getVer(void) const { return *_iter; } + inline pkgCache::VerIterator operator*(void) const { return *_iter; }; + operator typename Container::iterator(void) const { return _iter; } + operator typename VersionContainer<Container>::const_iterator() { return VersionContainer<Container>::const_iterator(_iter); } + inline iterator& operator++() { ++_iter; return *this; } + inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } + inline bool operator!=(iterator const &i) const { return _iter != i._iter; }; + inline bool operator==(iterator const &i) const { return _iter == i._iter; }; + friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); } + }; + /*}}}*/ + + bool insert(pkgCache::VerIterator const &V) { if (V.end() == true) return false; _cont.insert(V); return true; }; + template<class Cont> void insert(VersionContainer<Cont> const &vercont) { _cont.insert((typename Cont::const_iterator)vercont.begin(), (typename Cont::const_iterator)vercont.end()); }; + void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }; + bool empty() const { return _cont.empty(); }; + void clear() { return _cont.clear(); }; + void erase(iterator position) { _cont.erase((typename Container::iterator)position); }; + size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); }; + void erase(iterator first, iterator last) { _cont.erase(first, last); }; + size_t size() const { return _cont.size(); }; + + const_iterator begin() const { return const_iterator(_cont.begin()); }; + const_iterator end() const { return const_iterator(_cont.end()); }; + iterator begin() { return iterator(_cont.begin()); }; + iterator end() { return iterator(_cont.end()); }; + const_iterator find(pkgCache::VerIterator const &V) const { return const_iterator(_cont.find(V)); }; + /** \brief returns all versions specified on the commandline Get all versions from the commandline, uses given default version if @@ -305,26 +534,34 @@ public: /*{{{*/ \param Cache the packages and versions are in \param cmdline Command line the versions should be extracted from \param helper responsible for error and message handling */ - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper); - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback) { + static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + Version const &fallback, CacheSetHelper &helper) { + VersionContainer vercon; + VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, fallback, helper); + return vercon; + } + static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + Version const &fallback) { CacheSetHelper helper; return FromCommandLine(Cache, cmdline, fallback, helper); } - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { return FromCommandLine(Cache, cmdline, CANDINST); } - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper, - bool const &onlyFromName = false); - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback) { + static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg, + Version const &fallback, CacheSetHelper &helper, + bool const onlyFromName = false) { + VersionContainer vercon; + VersionContainerInterface::FromString(&vercon, Cache, pkg, fallback, helper); + return vercon; + } + static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg, + Version const &fallback) { CacheSetHelper helper; return FromString(Cache, pkg, fallback, helper); } - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { + static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) { return FromString(Cache, pkg, CANDINST); } @@ -334,57 +571,80 @@ public: /*{{{*/ \param P the package in question \param fallback the version(s) you want to get \param helper the helper used for display and error handling */ - static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, - VersionSet::Version const &fallback, CacheSetHelper &helper); - static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, - APT::VersionSet::Version const &fallback) { + static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + Version const &fallback, CacheSetHelper &helper) { + VersionContainer vercon; + VersionContainerInterface::FromPackage(&vercon, Cache, P, fallback, helper); + return vercon; + } + static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + Version const &fallback) { CacheSetHelper helper; return FromPackage(Cache, P, fallback, helper); } - static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) { - return FromPackage(Cache, P, CANDINST); + static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) { + return FromPackage(Cache, P, CANDIDATE); } - struct Modifier { - enum Position { NONE, PREFIX, POSTFIX }; - unsigned short ID; - const char * const Alias; - Position Pos; - VersionSet::Version SelectVersion; - Modifier (unsigned short const &id, const char * const alias, Position const &pos, - VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos), - SelectVersion(select) {}; - }; + static std::map<unsigned short, VersionContainer> GroupedFromCommandLine( + pkgCacheFile &Cache, + const char **cmdline, + std::list<Modifier> const &mods, + unsigned short const fallback, + CacheSetHelper &helper) { + std::map<unsigned short, VersionContainer> versets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + VersionContainer verset; + VersionContainerInterface::FromModifierCommandLine(modID, &verset, Cache, *I, mods, helper); + versets[modID].insert(verset); + } + return versets; - static std::map<unsigned short, VersionSet> GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list<VersionSet::Modifier> const &mods, - unsigned short const &fallback, CacheSetHelper &helper); - static std::map<unsigned short, VersionSet> GroupedFromCommandLine( + } + static std::map<unsigned short, VersionContainer> GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, - std::list<VersionSet::Modifier> const &mods, - unsigned short const &fallback) { + std::list<Modifier> const &mods, + unsigned short const fallback) { CacheSetHelper helper; return GroupedFromCommandLine(Cache, cmdline, mods, fallback, helper); } - /*}}}*/ -protected: /*{{{*/ - /** \brief returns the candidate version of the package - - \param Cache to be used to query for information - \param Pkg we want the candidate version from this package */ - static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); - - /** \brief returns the installed version of the package - - \param Cache to be used to query for information - \param Pkg we want the installed version from this package */ - static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); + static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D, + Version const &selector, CacheSetHelper &helper) { + VersionContainer vercon; + VersionContainerInterface::FromDependency(&vercon, Cache, D, selector, helper); + return vercon; + } + static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D, + Version const &selector) { + CacheSetHelper helper; + return FromPackage(Cache, D, selector, helper); + } + static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) { + return FromPackage(Cache, D, CANDIDATE); + } /*}}}*/ }; /*}}}*/ + +template<> template<class Cont> void VersionContainer<std::list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) { + for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v) + _cont.push_back(*v); +}; +// these two are 'inline' as otherwise the linker has problems with seeing these untemplated +// specializations again and again - but we need to see them, so that library users can use them +template<> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) { + if (V.end() == true) + return false; + _cont.push_back(V); + return true; +}; +template<> inline void VersionContainer<std::list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) { + for (const_iterator v = begin; v != end; ++v) + _cont.push_back(*v); +}; +typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet; +typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList; } #endif diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index a9c63fd21..4462d4e24 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -58,66 +58,91 @@ bool pkgCdrom::FindPackages(string CD, return _error->Errno("chdir","Unable to change to %s",CD.c_str()); // Look for a .disk subdirectory - struct stat Buf; - if (stat(".disk",&Buf) == 0) + if (DirectoryExists(".disk") == true) { if (InfoDir.empty() == true) InfoDir = CD + ".disk/"; } // Don't look into directories that have been marked to ingore. - if (stat(".aptignr",&Buf) == 0) + if (RealFileExists(".aptignr") == true) return true; - /* Check _first_ for a signature file as apt-cdrom assumes that all files under a Packages/Source file are in control of that file and stops the scanning */ - if (stat("Release.gpg",&Buf) == 0) + if (RealFileExists("Release.gpg") == true || RealFileExists("InRelease") == true) { SigList.push_back(CD); } + /* Aha! We found some package files. We assume that everything under this dir is controlled by those package files so we don't look down anymore */ - if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0) + std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors(); + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { + if (RealFileExists(std::string("Packages").append(c->Extension).c_str()) == false) + continue; + + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found Packages in " << CD << std::endl; List.push_back(CD); - + // Continue down if thorough is given if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; + break; } - if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0) + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { + if (RealFileExists(std::string("Sources").append(c->Extension).c_str()) == false) + continue; + + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found Sources in " << CD << std::endl; SList.push_back(CD); - + // Continue down if thorough is given if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; + break; } - // see if we find translatin indexes - if (stat("i18n",&Buf) == 0) + // see if we find translation indices + if (DirectoryExists("i18n") == true) { D = opendir("i18n"); for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) { - if(strstr(Dir->d_name,"Translation") != NULL) + if(strncmp(Dir->d_name, "Translation-", strlen("Translation-")) != 0) + continue; + string file = Dir->d_name; + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { - if (_config->FindB("Debug::aptcdrom",false) == true) - std::clog << "found translations: " << Dir->d_name << "\n"; - string file = Dir->d_name; - if(file.substr(file.size()-3,file.size()) == ".gz") - file = file.substr(0,file.size()-3); - TransList.push_back(CD+"i18n/"+ file); + string fileext = flExtension(file); + if (file == fileext) + fileext.clear(); + else if (fileext.empty() == false) + fileext = "." + fileext; + + if (c->Extension == fileext) + { + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found translation " << Dir->d_name << " in " << CD << "i18n/" << std::endl; + file.erase(file.size() - fileext.size()); + TransList.push_back(CD + "i18n/" + file); + break; + } } } closedir(D); } - D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@ -252,30 +277,43 @@ bool pkgCdrom::DropBinaryArch(vector<string> &List) /* Here we go and stat every file that we found and strip dup inodes. */ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name) { + bool couldFindAllFiles = true; // Get a list of all the inodes ino_t *Inodes = new ino_t[List.size()]; - for (unsigned int I = 0; I != List.size(); I++) + for (unsigned int I = 0; I != List.size(); ++I) { struct stat Buf; - if (stat((List[I] + Name).c_str(),&Buf) != 0 && - stat((List[I] + Name + ".gz").c_str(),&Buf) != 0) - _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), - Name); - Inodes[I] = Buf.st_ino; - } - - if (_error->PendingError() == true) { - delete[] Inodes; - return false; + bool found = false; + + std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors(); + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) + { + std::string filename = std::string(List[I]).append(Name).append(c->Extension); + if (stat(filename.c_str(), &Buf) != 0) + continue; + Inodes[I] = Buf.st_ino; + found = true; + break; + } + + if (found == false) + { + _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name); + couldFindAllFiles = false; + Inodes[I] = 0; + } } - + // Look for dups for (unsigned int I = 0; I != List.size(); I++) { + if (Inodes[I] == 0) + continue; for (unsigned int J = I+1; J < List.size(); J++) { // No match - if (Inodes[J] != Inodes[I]) + if (Inodes[J] == 0 || Inodes[J] != Inodes[I]) continue; // We score the two paths.. and erase one @@ -301,7 +339,7 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name) List.erase(List.begin()+I); } - return true; + return couldFindAllFiles; } /*}}}*/ // ReduceSourceList - Takes the path list and reduces it /*{{{*/ @@ -680,7 +718,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ DropBinaryArch(List); DropRepeats(List,"Packages"); DropRepeats(SourceList,"Sources"); + // FIXME: We ignore stat() errors here as we usually have only one of those in use + // This has little potencial to drop 'valid' stat() errors as we know that one of these + // files need to exist, but it would be better if we would check it here + _error->PushToStack(); DropRepeats(SigList,"Release.gpg"); + DropRepeats(SigList,"InRelease"); + _error->RevertToStack(); DropRepeats(TransList,""); if(log != NULL) { msg.str(""); diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index 319254fd0..cedfccff7 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -4,6 +4,11 @@ #include<string> #include<vector> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/init.h> +using namespace std; +#endif + class Configuration; class OpProgress; diff --git a/apt-pkg/contrib/cdromutl.h b/apt-pkg/contrib/cdromutl.h index 2c6afac0f..e94045b5c 100644 --- a/apt-pkg/contrib/cdromutl.h +++ b/apt-pkg/contrib/cdromutl.h @@ -12,6 +12,10 @@ #include <string> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + // mount cdrom, DeviceName (e.g. /dev/sr0) is optional bool MountCdrom(std::string Path, std::string DeviceName=""); bool UnmountCdrom(std::string Path); diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h index b201d9855..9f505fd41 100644 --- a/apt-pkg/contrib/cmndline.h +++ b/apt-pkg/contrib/cmndline.h @@ -44,6 +44,10 @@ #ifndef PKGLIB_CMNDLINE_H #define PKGLIB_CMNDLINE_H +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/configuration.h> +#endif + class Configuration; class CommandLine diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index f6f2a3c1d..4c2e75041 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -34,6 +34,10 @@ #include <vector> #include <iostream> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class Configuration { public: diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 95058cbde..b350973af 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -24,6 +24,7 @@ #include <apt-pkg/strutl.h> #include <apt-pkg/error.h> #include <apt-pkg/sptr.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/configuration.h> #include <cstdlib> @@ -43,6 +44,16 @@ #include <set> #include <algorithm> +// FIXME: Compressor Fds have some speed disadvantages and are a bit buggy currently, +// so while the current implementation satisfies the testcases it is not a real option +// to disable it for now +#define APT_USE_ZLIB 1 +#if APT_USE_ZLIB +#include <zlib.h> +#else +#pragma message "Usage of zlib is DISABLED!" +#endif + #ifdef WORDS_BIGENDIAN #include <inttypes.h> #endif @@ -52,6 +63,23 @@ using namespace std; +class FileFdPrivate { + public: +#if APT_USE_ZLIB + gzFile gz; +#else + void* gz; +#endif + int compressed_fd; + pid_t compressor_pid; + bool pipe; + APT::Configuration::Compressor compressor; + unsigned int openmode; + unsigned long long seekpos; + FileFdPrivate() : gz(NULL), compressed_fd(-1), compressor_pid(-1), pipe(false), + openmode(0), seekpos(0) {}; +}; + // RunScripts - Run a set of scripts from a configuration subtree /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -718,85 +746,288 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap) // FileFd::Open - Open a file /*{{{*/ // --------------------------------------------------------------------- /* The most commonly used open mode combinations are given with Mode */ -bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) +bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms) { - Close(); - Flags = AutoClose; - switch (Mode) + if (Mode == ReadOnlyGzip) + return Open(FileName, ReadOnly, Gzip, Perms); + + if (Compress == Auto && (Mode & WriteOnly) == WriteOnly) + return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str()); + + // FIXME: Denote inbuilt compressors somehow - as we don't need to have the binaries for them + std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors(); + std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin(); + if (Compress == Auto) { - case ReadOnly: - iFd = open(FileName.c_str(),O_RDONLY); - break; - - case ReadOnlyGzip: - iFd = open(FileName.c_str(),O_RDONLY); - if (iFd > 0) { - gz = gzdopen (iFd, "r"); - if (gz == NULL) { - close (iFd); - iFd = -1; - } - } - break; - - case WriteAtomic: + for (; compressor != compressors.end(); ++compressor) { - Flags |= Replace; - char *name = strdup((FileName + ".XXXXXX").c_str()); - TemporaryFileName = string(mktemp(name)); - iFd = open(TemporaryFileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms); - free(name); + std::string file = std::string(FileName).append(compressor->Extension); + if (FileExists(file) == false) + continue; + FileName = file; break; } - - case WriteEmpty: + } + else if (Compress == Extension) + { + std::string::size_type const found = FileName.find_last_of('.'); + std::string ext; + if (found != std::string::npos) { - struct stat Buf; - if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode)) - unlink(FileName.c_str()); - iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms); - break; + ext = FileName.substr(found); + if (ext == ".new" || ext == ".bak") + { + std::string::size_type const found2 = FileName.find_last_of('.', found - 1); + if (found2 != std::string::npos) + ext = FileName.substr(found2, found - found2); + else + ext.clear(); + } } - - case WriteExists: - iFd = open(FileName.c_str(),O_RDWR); - break; + for (; compressor != compressors.end(); ++compressor) + if (ext == compressor->Extension) + break; + // no matching extension - assume uncompressed (imagine files like 'example.org_Packages') + if (compressor == compressors.end()) + for (compressor = compressors.begin(); compressor != compressors.end(); ++compressor) + if (compressor->Name == ".") + break; + } + else + { + std::string name; + switch (Compress) + { + case None: name = "."; break; + case Gzip: name = "gzip"; break; + case Bzip2: name = "bzip2"; break; + case Lzma: name = "lzma"; break; + case Xz: name = "xz"; break; + case Auto: + case Extension: + // Unreachable + return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); + } + for (; compressor != compressors.end(); ++compressor) + if (compressor->Name == name) + break; + if (compressor == compressors.end()) + return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); + } + + if (compressor == compressors.end()) + return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str()); + return Open(FileName, Mode, *compressor, Perms); +} +bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms) +{ + Close(); + d = new FileFdPrivate; + d->openmode = Mode; + Flags = AutoClose; - case WriteAny: - iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms); - break; + if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0) + return _error->Error("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str()); + if ((Mode & ReadWrite) == 0) + return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str()); - case WriteTemp: + if ((Mode & Atomic) == Atomic) + { + Flags |= Replace; + char *name = strdup((FileName + ".XXXXXX").c_str()); + TemporaryFileName = string(mktemp(name)); + free(name); + } + else if ((Mode & (Exclusive | Create)) == (Exclusive | Create)) + { + // for atomic, this will be done by rename in Close() unlink(FileName.c_str()); - iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms); - break; - } + } + if ((Mode & Empty) == Empty) + { + struct stat Buf; + if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode)) + unlink(FileName.c_str()); + } + + int fileflags = 0; + #define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE + if_FLAGGED_SET(ReadWrite, O_RDWR); + else if_FLAGGED_SET(ReadOnly, O_RDONLY); + else if_FLAGGED_SET(WriteOnly, O_WRONLY); + + if_FLAGGED_SET(Create, O_CREAT); + if_FLAGGED_SET(Empty, O_TRUNC); + if_FLAGGED_SET(Exclusive, O_EXCL); + else if_FLAGGED_SET(Atomic, O_EXCL); + #undef if_FLAGGED_SET + + if (TemporaryFileName.empty() == false) + iFd = open(TemporaryFileName.c_str(), fileflags, Perms); + else + iFd = open(FileName.c_str(), fileflags, Perms); + + if (iFd == -1 || OpenInternDescriptor(Mode, compressor) == false) + { + if (iFd != -1) + { + close (iFd); + iFd = -1; + } + return _error->Errno("open",_("Could not open file %s"), FileName.c_str()); + } - if (iFd < 0) - return _error->Errno("open",_("Could not open file %s"),FileName.c_str()); - this->FileName = FileName; SetCloseExec(iFd,true); return true; } + /*}}}*/ +// FileFd::OpenDescriptor - Open a filedescriptor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose) +{ + std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors(); + std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin(); + std::string name; + switch (Compress) + { + case None: name = "."; break; + case Gzip: name = "gzip"; break; + case Bzip2: name = "bzip2"; break; + case Lzma: name = "lzma"; break; + case Xz: name = "xz"; break; + case Auto: + case Extension: + return _error->Error("Opening Fd %d in Auto or Extension compression mode is not supported", Fd); + } + for (; compressor != compressors.end(); ++compressor) + if (compressor->Name == name) + break; + if (compressor == compressors.end()) + return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); -bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose) + return OpenDescriptor(Fd, Mode, *compressor, AutoClose); +} +bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose) { Close(); + d = new FileFdPrivate; + d->openmode = Mode; Flags = (AutoClose) ? FileFd::AutoClose : 0; iFd = Fd; - if (Mode == ReadOnlyGzip) { - gz = gzdopen (iFd, "r"); - if (gz == NULL) { - if (AutoClose) - close (iFd); - return _error->Errno("gzdopen",_("Could not open file descriptor %d"), - Fd); - } + if (OpenInternDescriptor(Mode, compressor) == false) + { + if (AutoClose) + close (iFd); + return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd); } this->FileName = ""; return true; } +bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor) +{ + d->compressor = compressor; + if (compressor.Name == "." || compressor.Binary.empty() == true) + return true; +#if APT_USE_ZLIB + else if (compressor.Name == "gzip") + { + if ((Mode & ReadWrite) == ReadWrite) + d->gz = gzdopen(iFd, "r+"); + else if ((Mode & WriteOnly) == WriteOnly) + d->gz = gzdopen(iFd, "w"); + else + d->gz = gzdopen (iFd, "r"); + if (d->gz == NULL) + return false; + Flags |= Compressed; + return true; + } +#endif + + if ((Mode & ReadWrite) == ReadWrite) + return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str()); + + bool const Comp = (Mode & WriteOnly) == WriteOnly; + // Handle 'decompression' of empty files + if (Comp == false) + { + struct stat Buf; + fstat(iFd, &Buf); + if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false) + return true; + + // We don't need the file open - instead let the compressor open it + // as he properly knows better how to efficiently read from 'his' file + if (FileName.empty() == false) + close(iFd); + } + + // Create a data pipe + int Pipe[2] = {-1,-1}; + if (pipe(Pipe) != 0) + return _error->Errno("pipe",_("Failed to create subprocess IPC")); + for (int J = 0; J != 2; J++) + SetCloseExec(Pipe[J],true); + + d->compressed_fd = iFd; + d->pipe = true; + + if (Comp == true) + iFd = Pipe[1]; + else + iFd = Pipe[0]; + + // The child.. + d->compressor_pid = ExecFork(); + if (d->compressor_pid == 0) + { + if (Comp == true) + { + dup2(d->compressed_fd,STDOUT_FILENO); + dup2(Pipe[0],STDIN_FILENO); + } + else + { + if (FileName.empty() == true) + dup2(d->compressed_fd,STDIN_FILENO); + dup2(Pipe[1],STDOUT_FILENO); + } + + SetCloseExec(STDOUT_FILENO,false); + SetCloseExec(STDIN_FILENO,false); + + std::vector<char const*> Args; + Args.push_back(compressor.Binary.c_str()); + std::vector<std::string> const * const addArgs = + (Comp == true) ? &(compressor.CompressArgs) : &(compressor.UncompressArgs); + for (std::vector<std::string>::const_iterator a = addArgs->begin(); + a != addArgs->end(); ++a) + Args.push_back(a->c_str()); + if (Comp == false && FileName.empty() == false) + { + Args.push_back("--stdout"); + if (TemporaryFileName.empty() == false) + Args.push_back(TemporaryFileName.c_str()); + else + Args.push_back(FileName.c_str()); + } + Args.push_back(NULL); + + execvp(Args[0],(char **)&Args[0]); + cerr << _("Failed to exec compressor ") << Args[0] << endl; + _exit(100); + } + if (Comp == true) + close(Pipe[0]); + else + close(Pipe[1]); + if (Comp == true || FileName.empty() == true) + close(d->compressed_fd); + + return true; +} /*}}}*/ // FileFd::~File - Closes the file /*{{{*/ // --------------------------------------------------------------------- @@ -817,12 +1048,14 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) errno = 0; if (Actual != 0) *Actual = 0; - + *((char *)To) = '\0'; do { - if (gz != NULL) - Res = gzread(gz,To,Size); +#if APT_USE_ZLIB + if (d->gz != NULL) + Res = gzread(d->gz,To,Size); else +#endif Res = read(iFd,To,Size); if (Res < 0 && errno == EINTR) continue; @@ -834,6 +1067,7 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) To = (char *)To + Res; Size -= Res; + d->seekpos += Res; if (Actual != 0) *Actual += Res; } @@ -853,6 +1087,35 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) return _error->Error(_("read, still have %llu to read but none left"), Size); } /*}}}*/ +// FileFd::ReadLine - Read a complete line from the file /*{{{*/ +// --------------------------------------------------------------------- +/* Beware: This method can be quiet slow for big buffers on UNcompressed + files because of the naive implementation! */ +char* FileFd::ReadLine(char *To, unsigned long long const Size) +{ + *To = '\0'; +#if APT_USE_ZLIB + if (d->gz != NULL) + return gzgets(d->gz, To, Size); +#endif + + unsigned long long read = 0; + while ((Size - 1) != read) + { + unsigned long long done = 0; + if (Read(To + read, 1, &done) == false) + return NULL; + if (done == 0) + break; + if (To[read++] == '\n') + break; + } + if (read == 0) + return NULL; + To[read] = '\0'; + return To; +} + /*}}}*/ // FileFd::Write - Write to the file /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -862,9 +1125,11 @@ bool FileFd::Write(const void *From,unsigned long long Size) errno = 0; do { - if (gz != NULL) - Res = gzwrite(gz,From,Size); +#if APT_USE_ZLIB + if (d->gz != NULL) + Res = gzwrite(d->gz,From,Size); else +#endif Res = write(iFd,From,Size); if (Res < 0 && errno == EINTR) continue; @@ -876,6 +1141,7 @@ bool FileFd::Write(const void *From,unsigned long long Size) From = (char *)From + Res; Size -= Res; + d->seekpos += Res; } while (Res > 0 && Size > 0); @@ -891,17 +1157,55 @@ bool FileFd::Write(const void *From,unsigned long long Size) /* */ bool FileFd::Seek(unsigned long long To) { + if (d->pipe == true) + { + // Our poor man seeking in pipes is costly, so try to avoid it + unsigned long long seekpos = Tell(); + if (seekpos == To) + return true; + else if (seekpos < To) + return Skip(To - seekpos); + + if ((d->openmode & ReadOnly) != ReadOnly) + return _error->Error("Reopen is only implemented for read-only files!"); + close(iFd); + iFd = 0; + if (TemporaryFileName.empty() == false) + iFd = open(TemporaryFileName.c_str(), O_RDONLY); + else if (FileName.empty() == false) + iFd = open(FileName.c_str(), O_RDONLY); + else + { + if (d->compressed_fd > 0) + if (lseek(d->compressed_fd, 0, SEEK_SET) != 0) + iFd = d->compressed_fd; + if (iFd <= 0) + return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!"); + } + + if (OpenInternDescriptor(d->openmode, d->compressor) == false) + return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str()); + + if (To != 0) + return Skip(To); + + d->seekpos = To; + return true; + } int res; - if (gz) - res = gzseek(gz,To,SEEK_SET); +#if APT_USE_ZLIB + if (d->gz) + res = gzseek(d->gz,To,SEEK_SET); else +#endif res = lseek(iFd,To,SEEK_SET); if (res != (signed)To) { Flags |= Fail; return _error->Error("Unable to seek to %llu", To); } - + + d->seekpos = To; return true; } /*}}}*/ @@ -910,17 +1214,34 @@ bool FileFd::Seek(unsigned long long To) /* */ bool FileFd::Skip(unsigned long long Over) { + if (d->pipe == true) + { + d->seekpos += Over; + char buffer[1024]; + while (Over != 0) + { + unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over); + if (Read(buffer, toread) == false) + return _error->Error("Unable to seek ahead %llu",Over); + Over -= toread; + } + return true; + } + int res; - if (gz) - res = gzseek(gz,Over,SEEK_CUR); +#if APT_USE_ZLIB + if (d->gz != NULL) + res = gzseek(d->gz,Over,SEEK_CUR); else +#endif res = lseek(iFd,Over,SEEK_CUR); if (res < 0) { Flags |= Fail; return _error->Error("Unable to seek ahead %llu",Over); } - + d->seekpos = res; + return true; } /*}}}*/ @@ -929,7 +1250,7 @@ bool FileFd::Skip(unsigned long long Over) /* */ bool FileFd::Truncate(unsigned long long To) { - if (gz) + if (d->gz != NULL) { Flags |= Fail; return _error->Error("Truncating gzipped files is not implemented (%s)", FileName.c_str()); @@ -948,13 +1269,23 @@ bool FileFd::Truncate(unsigned long long To) /* */ unsigned long long FileFd::Tell() { + // In theory, we could just return seekpos here always instead of + // seeking around, but not all users of FileFd use always Seek() and co + // so d->seekpos isn't always true and we can just use it as a hint if + // we have nothing else, but not always as an authorityā¦ + if (d->pipe == true) + return d->seekpos; + off_t Res; - if (gz) - Res = gztell(gz); +#if APT_USE_ZLIB + if (d->gz != NULL) + Res = gztell(d->gz); else +#endif Res = lseek(iFd,0,SEEK_CUR); if (Res == (off_t)-1) _error->Errno("lseek","Failed to determine the current file position"); + d->seekpos = Res; return Res; } /*}}}*/ @@ -964,9 +1295,19 @@ unsigned long long FileFd::Tell() unsigned long long FileFd::FileSize() { struct stat Buf; - - if (fstat(iFd,&Buf) != 0) + if (d->pipe == false && fstat(iFd,&Buf) != 0) return _error->Errno("fstat","Unable to determine the file size"); + + // for compressor pipes st_size is undefined and at 'best' zero + if (d->pipe == true || S_ISFIFO(Buf.st_mode)) + { + // we set it here, too, as we get the info here for free + // in theory the Open-methods should take care of it already + d->pipe = true; + if (stat(FileName.c_str(), &Buf) != 0) + return _error->Errno("stat","Unable to determine the file size"); + } + return Buf.st_size; } /*}}}*/ @@ -977,16 +1318,29 @@ unsigned long long FileFd::Size() { unsigned long long size = FileSize(); + // for compressor pipes st_size is undefined and at 'best' zero, + // so we 'read' the content and 'seek' back - see there + if (d->pipe == true) + { + unsigned long long const oldSeek = Tell(); + char ignore[1000]; + unsigned long long read = 0; + do { + Read(ignore, sizeof(ignore), &read); + } while(read != 0); + size = Tell(); + Seek(oldSeek); + } +#if APT_USE_ZLIB // only check gzsize if we are actually a gzip file, just checking for - // "gz" is not sufficient as uncompressed files will be opened with + // "gz" is not sufficient as uncompressed files could be opened with // gzopen in "direct" mode as well - if (gz && !gzdirect(gz) && size > 0) + else if (d->gz && !gzdirect(d->gz) && size > 0) { /* unfortunately zlib.h doesn't provide a gzsize(), so we have to do * this ourselves; the original (uncompressed) file size is the last 32 * bits of the file */ // FIXME: Size for gz-files is limited by 32bitā¦ no largefile support - off_t orig_pos = lseek(iFd, 0, SEEK_CUR); if (lseek(iFd, -4, SEEK_END) < 0) return _error->Errno("lseek","Unable to seek to end of gzipped file"); size = 0L; @@ -1000,28 +1354,62 @@ unsigned long long FileFd::Size() size = tmp_size; #endif - if (lseek(iFd, orig_pos, SEEK_SET) < 0) + if (lseek(iFd, d->seekpos, SEEK_SET) < 0) return _error->Errno("lseek","Unable to seek in gzipped file"); return size; } +#endif return size; } /*}}}*/ +// FileFd::ModificationTime - Return the time of last touch /*{{{*/ +// --------------------------------------------------------------------- +/* */ +time_t FileFd::ModificationTime() +{ + struct stat Buf; + if (d->pipe == false && fstat(iFd,&Buf) != 0) + { + _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); + return 0; + } + + // for compressor pipes st_size is undefined and at 'best' zero + if (d->pipe == true || S_ISFIFO(Buf.st_mode)) + { + // we set it here, too, as we get the info here for free + // in theory the Open-methods should take care of it already + d->pipe = true; + if (stat(FileName.c_str(), &Buf) != 0) + { + _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); + return 0; + } + } + + return Buf.st_mtime; +} + /*}}}*/ // FileFd::Close - Close the file if the close flag is set /*{{{*/ // --------------------------------------------------------------------- /* */ bool FileFd::Close() { + if (iFd == -1) + return true; + bool Res = true; if ((Flags & AutoClose) == AutoClose) { - if (gz != NULL) { - int const e = gzclose(gz); +#if APT_USE_ZLIB + if (d != NULL && d->gz != NULL) { + int const e = gzclose(d->gz); // gzdopen() on empty files always fails with "buffer error" here, ignore that if (e != 0 && e != Z_BUF_ERROR) Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str()); } else +#endif if (iFd > 0 && close(iFd) != 0) Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str()); } @@ -1031,16 +1419,23 @@ bool FileFd::Close() Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str()); FileName = TemporaryFileName; // for the unlink() below. + TemporaryFileName.clear(); } iFd = -1; - gz = NULL; if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && FileName.empty() == false) if (unlink(FileName.c_str()) != 0) Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str()); + if (d != NULL) + { + if (d->compressor_pid > 0) + ExecWait(d->compressor_pid, "FileFdCompressor", true); + delete d; + d = NULL; + } return Res; } @@ -1057,3 +1452,5 @@ bool FileFd::Sync() return true; } /*}}}*/ + +gzFile FileFd::gzFd() { return (gzFile) d->gz; } diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 0d0451a46..147535df1 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -22,30 +22,51 @@ #define PKGLIB_FILEUTL_H #include <apt-pkg/macros.h> +#include <apt-pkg/aptconfiguration.h> #include <string> #include <vector> #include <zlib.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + /* Define this for python-apt */ #define APT_HAS_GZIP 1 +class FileFdPrivate; class FileFd { protected: int iFd; enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2), - HitEof = (1<<3), Replace = (1<<4) }; + HitEof = (1<<3), Replace = (1<<4), Compressed = (1<<5) }; unsigned long Flags; std::string FileName; std::string TemporaryFileName; - gzFile gz; public: - enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp,ReadOnlyGzip, - WriteAtomic}; + enum OpenMode { + ReadOnly = (1 << 0), + WriteOnly = (1 << 1), + ReadWrite = ReadOnly | WriteOnly, + + Create = (1 << 2), + Exclusive = (1 << 3), + Atomic = Exclusive | (1 << 4), + Empty = (1 << 5), + + WriteEmpty = ReadWrite | Create | Empty, + WriteExists = ReadWrite, + WriteAny = ReadWrite | Create, + WriteTemp = ReadWrite | Create | Exclusive, + ReadOnlyGzip, + WriteAtomic = ReadWrite | Create | Atomic + }; + enum CompressMode { Auto = 'A', None = 'N', Extension = 'E', Gzip = 'G', Bzip2 = 'B', Lzma = 'L', Xz = 'X' }; inline bool Read(void *To,unsigned long long Size,bool AllowEof) { @@ -55,6 +76,7 @@ class FileFd return Read(To,Size); } bool Read(void *To,unsigned long long Size,unsigned long long *Actual = 0); + char* ReadLine(char *To, unsigned long long const Size); bool Write(const void *From,unsigned long long Size); bool Seek(unsigned long long To); bool Skip(unsigned long long To); @@ -62,6 +84,7 @@ class FileFd unsigned long long Tell(); unsigned long long Size(); unsigned long long FileSize(); + time_t ModificationTime(); /* You want to use 'unsigned long long' if you are talking about a file to be able to support large files (>2 or >4 GB) properly. @@ -77,30 +100,54 @@ class FileFd return T; } - bool Open(std::string FileName,OpenMode Mode,unsigned long Perms = 0666); - bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false); + bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const Perms = 0666); + bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666); + inline bool Open(std::string const &FileName,unsigned int const Mode, unsigned long const Perms = 0666) { + return Open(FileName, Mode, None, Perms); + }; + bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false); + bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false); + inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) { + return OpenDescriptor(Fd, Mode, None, AutoClose); + }; bool Close(); bool Sync(); // Simple manipulators inline int Fd() {return iFd;}; inline void Fd(int fd) {iFd = fd;}; - inline gzFile gzFd() {return gz;}; + __deprecated gzFile gzFd(); + inline bool IsOpen() {return iFd >= 0;}; inline bool Failed() {return (Flags & Fail) == Fail;}; inline void EraseOnFailure() {Flags |= DelOnFail;}; inline void OpFail() {Flags |= Fail;}; inline bool Eof() {return (Flags & HitEof) == HitEof;}; + inline bool IsCompressed() {return (Flags & Compressed) == Compressed;}; inline std::string &Name() {return FileName;}; - FileFd(std::string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), - Flags(0), gz(NULL) + FileFd(std::string FileName,unsigned int const Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) { - Open(FileName,Mode,Perms); + Open(FileName,Mode, None, Perms); + }; + FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) + { + Open(FileName,Mode, Compress, Perms); + }; + FileFd() : iFd(-1), Flags(AutoClose), d(NULL) {}; + FileFd(int const Fd, unsigned int const Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL) + { + OpenDescriptor(Fd, Mode, Compress); + }; + FileFd(int const Fd, bool const AutoClose) : iFd(-1), Flags(0), d(NULL) + { + OpenDescriptor(Fd, ReadWrite, None, AutoClose); }; - FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose), gz(NULL) {}; - FileFd(int Fd,bool) : iFd(Fd), Flags(0), gz(NULL) {}; virtual ~FileFd(); + + private: + FileFdPrivate* d; + bool OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor); }; bool RunScripts(const char *Cnf); diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 05001f042..e1a431823 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -61,25 +61,25 @@ bool HashString::VerifyFile(std::string filename) const /*{{{*/ if(Type == "MD5Sum") { MD5Summation MD5; - MD5.AddFD(Fd.Fd(), Fd.Size()); + MD5.AddFD(Fd); fileHash = (std::string)MD5.Result(); } else if (Type == "SHA1") { SHA1Summation SHA1; - SHA1.AddFD(Fd.Fd(), Fd.Size()); + SHA1.AddFD(Fd); fileHash = (std::string)SHA1.Result(); } else if (Type == "SHA256") { SHA256Summation SHA256; - SHA256.AddFD(Fd.Fd(), Fd.Size()); + SHA256.AddFD(Fd); fileHash = (std::string)SHA256.Result(); } else if (Type == "SHA512") { SHA512Summation SHA512; - SHA512.AddFD(Fd.Fd(), Fd.Size()); + SHA512.AddFD(Fd); fileHash = (std::string)SHA512.Result(); } Fd.Close(); @@ -135,5 +135,35 @@ bool Hashes::AddFD(int const Fd,unsigned long long Size, bool const addMD5, } return true; } +bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, bool const addMD5, + bool const addSHA1, bool const addSHA256, bool const addSHA512) +{ + unsigned char Buf[64*64]; + bool const ToEOF = (Size == 0); + while (Size != 0 || ToEOF) + { + unsigned long long n = sizeof(Buf); + if (!ToEOF) n = std::min(Size, n); + unsigned long long a = 0; + if (Fd.Read(Buf, n, &a) == false) // error + return false; + if (ToEOF == false) + { + if (a != n) // short read + return false; + } + else if (a == 0) // EOF + break; + Size -= a; + if (addMD5 == true) + MD5.Add(Buf, a); + if (addSHA1 == true) + SHA1.Add(Buf, a); + if (addSHA256 == true) + SHA256.Add(Buf, a); + if (addSHA512 == true) + SHA512.Add(Buf, a); + } + return true; +} /*}}}*/ - diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 81851dede..0c0b6c6a7 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -17,11 +17,18 @@ #include <apt-pkg/md5.h> #include <apt-pkg/sha1.h> #include <apt-pkg/sha2.h> +#include <apt-pkg/fileutl.h> #include <algorithm> #include <vector> #include <cstring> + +#ifndef APT_8_CLEANER_HEADERS +using std::min; +using std::vector; +#endif + // helper class that contains hash function name // and hash class HashString @@ -68,6 +75,10 @@ class Hashes { return AddFD(Fd, Size, true, true, true, true); }; bool AddFD(int const Fd, unsigned long long Size, bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512); + inline bool AddFD(FileFd &Fd,unsigned long long Size = 0) + { return AddFD(Fd, Size, true, true, true, true); }; + bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5, + bool const addSHA1, bool const addSHA256, bool const addSHA512); inline bool Add(const unsigned char *Beg,const unsigned char *End) {return Add(Beg,End-Beg);}; }; diff --git a/apt-pkg/contrib/hashsum.cc b/apt-pkg/contrib/hashsum.cc index ff3b112bb..289e43aa4 100644 --- a/apt-pkg/contrib/hashsum.cc +++ b/apt-pkg/contrib/hashsum.cc @@ -25,4 +25,26 @@ bool SummationImplementation::AddFD(int const Fd, unsigned long long Size) { } return true; } +bool SummationImplementation::AddFD(FileFd &Fd, unsigned long long Size) { + unsigned char Buf[64 * 64]; + bool ToEOF = (Size == 0); + while (Size != 0 || ToEOF) + { + unsigned long long n = sizeof(Buf); + if (!ToEOF) n = std::min(Size, n); + unsigned long long a = 0; + if (Fd.Read(Buf, n, &a) == false) // error + return false; + if (ToEOF == false) + { + if (a != n) // short read + return false; + } + else if (a == 0) // EOF + break; + Size -= a; + Add(Buf, a); + } + return true; +} /*}}}*/ diff --git a/apt-pkg/contrib/hashsum_template.h b/apt-pkg/contrib/hashsum_template.h index d2d9f92ed..9bf160b2b 100644 --- a/apt-pkg/contrib/hashsum_template.h +++ b/apt-pkg/contrib/hashsum_template.h @@ -10,6 +10,8 @@ #ifndef APTPKG_HASHSUM_TEMPLATE_H #define APTPKG_HASHSUM_TEMPLATE_H +#include <apt-pkg/fileutl.h> + #include <string> #include <cstring> #include <algorithm> @@ -17,6 +19,11 @@ #include <apt-pkg/strutl.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::min; +#endif + template<int N> class HashSumValue { @@ -105,6 +112,7 @@ class SummationImplementation { return Add((const unsigned char *)Beg, End - Beg); }; bool AddFD(int Fd, unsigned long long Size = 0); + bool AddFD(FileFd &Fd, unsigned long long Size = 0); }; #endif diff --git a/apt-pkg/contrib/md5.h b/apt-pkg/contrib/md5.h index a207da4e4..25631b166 100644 --- a/apt-pkg/contrib/md5.h +++ b/apt-pkg/contrib/md5.h @@ -31,6 +31,11 @@ #include "hashsum_template.h" +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::min; +#endif + typedef HashSumValue<128> MD5SumValue; class MD5Summation : public SummationImplementation diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index f76169a92..a67ab3698 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -66,7 +66,7 @@ MMap::~MMap() bool MMap::Map(FileFd &Fd) { iSize = Fd.Size(); - + // Set the permissions. int Prot = PROT_READ; int Map = MAP_SHARED; @@ -77,7 +77,18 @@ bool MMap::Map(FileFd &Fd) if (iSize == 0) return _error->Error(_("Can't mmap an empty file")); - + + // We can't mmap compressed fd's directly, so we need to read it completely + if (Fd.IsCompressed() == true) + { + if ((Flags & ReadOnly) != ReadOnly) + return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str()); + Base = new unsigned char[iSize]; + if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false) + return false; + return true; + } + // Map it. Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); if (Base == (void *)-1) @@ -86,6 +97,13 @@ bool MMap::Map(FileFd &Fd) { // The filesystem doesn't support this particular kind of mmap. // So we allocate a buffer and read the whole file into it. + if ((Flags & ReadOnly) == ReadOnly) + { + // for readonly, we don't need sync, so make it simple + Base = new unsigned char[iSize]; + return Fd.Read(Base, iSize); + } + // FIXME: Writing to compressed fd's ? int const dupped_fd = dup(Fd.Fd()); if (dupped_fd == -1) return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd()); diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 2ed4a95f8..6bd4a2d86 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -28,6 +28,11 @@ #include <string> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/fileutl.h> +using std::string; +#endif + class FileFd; /* This should be a 32 bit type, larger tyes use too much ram and smaller diff --git a/apt-pkg/contrib/netrc.h b/apt-pkg/contrib/netrc.h index 7b94eba88..5931d4a42 100644 --- a/apt-pkg/contrib/netrc.h +++ b/apt-pkg/contrib/netrc.h @@ -16,6 +16,10 @@ #include <string> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/strutl.h> +#endif + #define DOT_CHAR "." #define DIR_CHAR "/" diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h index 7635719bc..3a6943aee 100644 --- a/apt-pkg/contrib/progress.h +++ b/apt-pkg/contrib/progress.h @@ -25,6 +25,10 @@ #include <string> #include <sys/time.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class Configuration; class OpProgress { diff --git a/apt-pkg/contrib/sha1.h b/apt-pkg/contrib/sha1.h index b4b139a22..a8d55eb13 100644 --- a/apt-pkg/contrib/sha1.h +++ b/apt-pkg/contrib/sha1.h @@ -20,6 +20,11 @@ #include "hashsum_template.h" +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::min; +#endif + typedef HashSumValue<160> SHA1SumValue; class SHA1Summation : public SummationImplementation diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 93f4bef4f..337139d5d 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -27,6 +27,12 @@ #include "macros.h" +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::vector; +using std::ostream; +#endif + bool UTF8ToCodeset(const char *codeset, const std::string &orig, std::string *dest); char *_strstrip(char *String); char *_strtabexpand(char *String,size_t Len); diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 27c1f7f32..5dc2a2ac2 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -26,6 +26,8 @@ #include <sys/stat.h> /*}}}*/ +using std::string; + // SourcesIndex::debSourcesIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -159,7 +161,7 @@ unsigned long debSourcesIndex::Size() const /* we need to ignore errors here; if the lists are absent, just return 0 */ _error->PushToStack(); - FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnlyGzip); + FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension); if (!f.Failed()) size = f.Size(); @@ -288,7 +290,7 @@ unsigned long debPackagesIndex::Size() const /* we need to ignore errors here; if the lists are absent, just return 0 */ _error->PushToStack(); - FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnlyGzip); + FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension); if (!f.Failed()) size = f.Size(); @@ -305,7 +307,7 @@ unsigned long debPackagesIndex::Size() const bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { string PackageFile = IndexFile("Packages"); - FileFd Pkg(PackageFile,FileFd::ReadOnlyGzip); + FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension); debListParser Parser(&Pkg, Architecture); if (_error->PendingError() == true) @@ -319,11 +321,8 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const // Store the IMS information pkgCache::PkgFileIterator File = Gen.GetCurFile(); pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - File->Size = St.st_size; - File->mtime = St.st_mtime; + File->Size = Pkg.FileSize(); + File->mtime = Pkg.ModificationTime(); if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",PackageFile.c_str()); @@ -489,7 +488,7 @@ unsigned long debTranslationsIndex::Size() const /* we need to ignore errors here; if the lists are absent, just return 0 */ _error->PushToStack(); - FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnlyGzip); + FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnly, FileFd::Extension); if (!f.Failed()) size = f.Size(); @@ -509,7 +508,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const string TranslationFile = IndexFile(Language); if (FileExists(TranslationFile)) { - FileFd Trans(TranslationFile,FileFd::ReadOnlyGzip); + FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension); debListParser TransParser(&Trans); if (_error->PendingError() == true) return false; @@ -521,11 +520,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const // Store the IMS information pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); - struct stat TransSt; - if (fstat(Trans.Fd(),&TransSt) != 0) - return _error->Errno("fstat","Failed to stat"); - TransFile->Size = TransSt.st_size; - TransFile->mtime = TransSt.st_mtime; + TransFile->Size = Trans.FileSize(); + TransFile->mtime = Trans.ModificationTime(); if (Gen.MergeList(TransParser) == false) return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); @@ -590,7 +586,7 @@ unsigned long debStatusIndex::Size() const /* */ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { - FileFd Pkg(File,FileFd::ReadOnlyGzip); + FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension); if (_error->PendingError() == true) return false; debListParser Parser(&Pkg); @@ -604,11 +600,8 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - CFile->Size = St.st_size; - CFile->mtime = St.st_mtime; + CFile->Size = Pkg.FileSize(); + CFile->mtime = Pkg.ModificationTime(); CFile->Archive = Gen.WriteUniqString("now"); if (Gen.MergeList(Parser) == false) diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 28568d5e3..bdb50f6bf 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -773,6 +773,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, // file. to provide Component pinning we use the section name now FileI->Component = WriteUniqString(component); + // FIXME: Code depends on the fact that Release files aren't compressed FILE* release = fdopen(dup(File.Fd()), "r"); if (release == NULL) return false; diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 9519d9711..386d291a2 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -14,6 +14,10 @@ #include <apt-pkg/pkgcachegen.h> #include <apt-pkg/tagfile.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/indexfile.h> +#endif + class debListParser : public pkgCacheGenerator::ListParser { public: diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 0cba2d8a8..b9ecab97c 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -8,6 +8,10 @@ #include <string> #include <vector> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/sourcelist.h> +#endif + class debReleaseIndex : public metaIndex { public: diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 1afa7b74d..184c07c33 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -25,7 +25,7 @@ using std::string; // --------------------------------------------------------------------- /* */ debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : - File(FileName,FileFd::ReadOnlyGzip), + File(FileName,FileFd::ReadOnly, FileFd::Extension), Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200) { diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index 9c7ea6b48..b5e3bbdba 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -18,6 +18,10 @@ #include <apt-pkg/tagfile.h> #include <apt-pkg/fileutl.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/indexfile.h> +#endif + class debRecordParser : public pkgRecords::Parser { /** \brief dpointer placeholder (for later in case we need it) */ diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index 4c8d03224..5d2a67f4f 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -50,7 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser virtual bool Files(std::vector<pkgSrcRecords::File> &F); debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) - : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), + : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), Buffer(NULL) {} virtual ~debSrcRecordParser(); }; diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 6b62360b7..aab39f633 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -15,6 +15,11 @@ #include <map> #include <stdio.h> +#ifndef APT_8_CLEANER_HEADERS +using std::vector; +using std::map; +#endif + class pkgDPkgPMPrivate; class pkgDPkgPM : public pkgPackageManager diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 529e9240d..031fca5c0 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -23,7 +23,9 @@ #include <apt-pkg/pkgsystem.h> #include <apt-pkg/tagfile.h> #include <apt-pkg/progress.h> +#include <apt-pkg/cacheset.h> +#include <algorithm> #include <iostream> #include <sstream> #include <set> @@ -940,6 +942,51 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg, // DepCache::MarkInstall - Put the package in the install state /*{{{*/ // --------------------------------------------------------------------- /* */ +struct CompareProviders { + pkgCache::PkgIterator const Pkg; + CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {}; + //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV) + bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV) + { + pkgCache::PkgIterator const A = AV.ParentPkg(); + pkgCache::PkgIterator const B = BV.ParentPkg(); + // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64 + if (A->Group != B->Group) + { + if (A->Group == Pkg->Group && B->Group != Pkg->Group) + return false; + else if (B->Group == Pkg->Group && A->Group != Pkg->Group) + return true; + } + // we like essentials + if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential)) + { + if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + return false; + else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + return true; + } + // higher priority seems like a good idea + if (AV->Priority != BV->Priority) + return AV->Priority < BV->Priority; + // prefer native architecture + if (strcmp(A.Arch(), B.Arch()) != 0) + { + if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0) + return false; + else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0) + return true; + std::vector<std::string> archs = APT::Configuration::getArchitectures(); + for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a) + if (*a == A.Arch()) + return false; + else if (*a == B.Arch()) + return true; + } + // unable to decideā¦ + return A->ID < B->ID; + } +}; bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, unsigned long Depth, bool FromUser, bool ForceImportantDeps) @@ -1102,41 +1149,28 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, /* This bit is for processing the possibilty of an install/upgrade fixing the problem */ - SPtrArray<Version *> List = Start.AllTargets(); if (Start->Type != Dep::DpkgBreaks && (DepState[Start->ID] & DepCVer) == DepCVer) { - // Right, find the best version to install.. - Version **Cur = List; - PkgIterator P = Start.TargetPkg(); - PkgIterator InstPkg(*Cache,0); - - // See if there are direct matches (at the start of the list) - for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++) + APT::VersionList verlist; + pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this); + if (Cand.end() == false && VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == true) + verlist.insert(Cand); + for (PrvIterator Prv = Start.TargetPkg().ProvidesList(); Prv.end() != true; ++Prv) { - PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); - if (PkgState[Pkg->ID].CandidateVer != *Cur) + pkgCache::VerIterator V = Prv.OwnerVer(); + pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this); + if (Cand.end() == true || V != Cand || + VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == false) continue; - InstPkg = Pkg; - break; + verlist.insert(Cand); } + CompareProviders comp(Start); + APT::VersionList::iterator InstVer = std::max_element(verlist.begin(), verlist.end(), comp); - // Select the highest priority providing package - if (InstPkg.end() == true) - { - pkgPrioSortList(*Cache,Cur); - for (; *Cur != 0; Cur++) - { - PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); - if (PkgState[Pkg->ID].CandidateVer != *Cur) - continue; - InstPkg = Pkg; - break; - } - } - - if (InstPkg.end() == false) + if (InstVer != verlist.end()) { + pkgCache::PkgIterator InstPkg = InstVer.ParentPkg(); if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name() << " as " << Start.DepType() << " of " << Pkg.Name() @@ -1154,7 +1188,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, // mark automatic dependency MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps); // Set the autoflag, after MarkInstall because MarkInstall unsets it - if (P->CurrentVer == 0) + if (InstPkg->CurrentVer == 0) PkgState[InstPkg->ID].Flags |= Flag::Auto; } } @@ -1166,6 +1200,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, upgrade the package. */ if (Start.IsNegative() == true) { + SPtrArray<Version *> List = Start.AllTargets(); for (Version **I = List; *I != 0; I++) { VerIterator Ver(*this,*I); diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index f6e6c0afc..7358048ed 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -46,6 +46,11 @@ #include <set> #include <list> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/progress.h> +#include <apt-pkg/error.h> +#endif + class OpProgress; class pkgDepCache : protected pkgCache::Namespace diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index c14309422..12b06d143 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -10,13 +10,16 @@ #define PKGLIB_EDSP_H #include <apt-pkg/pkgcache.h> +#include <apt-pkg/cacheset.h> #include <list> #include <string> -namespace APT { - class PackageSet; -}; +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/depcache.h> +#include <apt-pkg/progress.h> +#endif + class pkgDepCache; class OpProgress; diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc index 058cef636..482581979 100644 --- a/apt-pkg/edsp/edspindexfile.cc +++ b/apt-pkg/edsp/edspindexfile.cc @@ -24,7 +24,7 @@ // edspIndex::edspIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -edspIndex::edspIndex(string File) : debStatusIndex(File) +edspIndex::edspIndex(std::string File) : debStatusIndex(File) { } /*}}}*/ @@ -44,16 +44,13 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const if (Prog != NULL) Prog->SubProgress(0,File); - if (Gen.SelectFile(File,string(),*this) == false) + if (Gen.SelectFile(File,std::string(),*this) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - CFile->Size = St.st_size; - CFile->mtime = St.st_mtime; + CFile->Size = Pkg.FileSize(); + CFile->mtime = Pkg.ModificationTime(); CFile->Archive = Gen.WriteUniqString("edsp::scenario"); if (Gen.MergeList(Parser) == false) diff --git a/apt-pkg/edsp/edspindexfile.h b/apt-pkg/edsp/edspindexfile.h index 9670c4837..de10f2d2f 100644 --- a/apt-pkg/edsp/edspindexfile.h +++ b/apt-pkg/edsp/edspindexfile.h @@ -10,6 +10,10 @@ #include <apt-pkg/debindexfile.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/indexfile.h> +#endif + class edspIndex : public debStatusIndex { /** \brief dpointer placeholder (for later in case we need it) */ diff --git a/apt-pkg/edsp/edsplistparser.h b/apt-pkg/edsp/edsplistparser.h index 5d82716c7..a7bf9de95 100644 --- a/apt-pkg/edsp/edsplistparser.h +++ b/apt-pkg/edsp/edsplistparser.h @@ -13,6 +13,12 @@ #include <apt-pkg/deblistparser.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/pkgcachegen.h> +#include <apt-pkg/indexfile.h> +#include <apt-pkg/tagfile.h> +#endif + class FileFd; class edspListParser : public debListParser diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 4df018ef4..3747e3570 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -16,6 +16,7 @@ #include <apt-pkg/progress.h> #include <apt-pkg/strutl.h> #include <apt-pkg/fileutl.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/configuration.h> #include <apt-pkg/tagfile.h> #include <apt-pkg/indexrecords.h> @@ -37,8 +38,6 @@ using namespace std; - - // IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -57,15 +56,25 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List, // Prepare the progress indicator off_t TotalSize = 0; + std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors(); for (vector<string>::iterator I = List.begin(); I != List.end(); ++I) { struct stat Buf; - if (stat(string(*I + GetFileName()).c_str(),&Buf) != 0 && - stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0) - return _error->Errno("stat","Stat failed for %s", - string(*I + GetFileName()).c_str()); + bool found = false; + std::string file = std::string(*I).append(GetFileName()); + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) + { + if (stat(std::string(file + c->Extension).c_str(), &Buf) != 0) + continue; + found = true; + break; + } + + if (found == false) + return _error->Errno("stat", "Stat failed for %s", file.c_str()); TotalSize += Buf.st_size; - } + } off_t CurrentSize = 0; unsigned int NotFound = 0; @@ -74,57 +83,11 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List, for (vector<string>::iterator I = List.begin(); I != List.end(); ++I) { string OrigPath = string(*I,CDROM.length()); - off_t FileSize = 0; // Open the package file - FileFd Pkg; - if (RealFileExists(*I + GetFileName()) == true) - { - Pkg.Open(*I + GetFileName(),FileFd::ReadOnly); - FileSize = Pkg.Size(); - } - else - { - FileFd From(*I + GetFileName() + ".gz",FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - FileSize = From.Size(); - - // Get a temp file - FILE *tmp = tmpfile(); - if (tmp == 0) - return _error->Errno("tmpfile","Unable to create a tmp file"); - Pkg.Fd(dup(fileno(tmp))); - fclose(tmp); - - // Fork gzip - pid_t Process = fork(); - if (Process < 0) - return _error->Errno("fork","Couldn't fork gzip"); - - // The child - if (Process == 0) - { - dup2(From.Fd(),STDIN_FILENO); - dup2(Pkg.Fd(),STDOUT_FILENO); - SetCloseExec(STDIN_FILENO,false); - SetCloseExec(STDOUT_FILENO,false); - - const char *Args[3]; - string Tmp = _config->Find("Dir::bin::gzip","gzip"); - Args[0] = Tmp.c_str(); - Args[1] = "-d"; - Args[2] = 0; - execvp(Args[0],(char **)Args); - exit(100); - } - - // Wait for gzip to finish - if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) - return _error->Error("gzip failed, perhaps the disk is full."); - - Pkg.Seek(0); - } + FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Extension); + off_t const FileSize = Pkg.Size(); + pkgTagFile Parser(&Pkg); if (_error->PendingError() == true) return false; @@ -602,13 +565,19 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, string const releasegpg = *I+"Release.gpg"; string const release = *I+"Release"; + string const inrelease = *I+"InRelease"; + bool useInRelease = true; // a Release.gpg without a Release should never happen - if(RealFileExists(release) == false) + if (RealFileExists(inrelease) == true) + ; + else if(RealFileExists(release) == false || RealFileExists(releasegpg) == false) { delete MetaIndex; continue; } + else + useInRelease = false; pid_t pid = ExecFork(); if(pid < 0) { @@ -616,11 +585,16 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, return false; } if(pid == 0) - RunGPGV(release, releasegpg); + { + if (useInRelease == true) + RunGPGV(inrelease, inrelease); + else + RunGPGV(release, releasegpg); + } if(!ExecWait(pid, "gpgv")) { _error->Warning("Signature verification failed for: %s", - releasegpg.c_str()); + (useInRelease ? inrelease.c_str() : releasegpg.c_str())); // something went wrong, don't copy the Release.gpg // FIXME: delete any existing gpg file? continue; @@ -650,8 +624,13 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, delete MetaIndex; // everything was fine, copy the Release and Release.gpg file - CopyMetaIndex(CDROM, Name, prefix, "Release"); - CopyMetaIndex(CDROM, Name, prefix, "Release.gpg"); + if (useInRelease == true) + CopyMetaIndex(CDROM, Name, prefix, "InRelease"); + else + { + CopyMetaIndex(CDROM, Name, prefix, "Release"); + CopyMetaIndex(CDROM, Name, prefix, "Release.gpg"); + } } return true; @@ -789,15 +768,25 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ // Prepare the progress indicator off_t TotalSize = 0; + std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors(); for (vector<string>::iterator I = List.begin(); I != List.end(); ++I) { struct stat Buf; - if (stat(string(*I).c_str(),&Buf) != 0 && - stat(string(*I + ".gz").c_str(),&Buf) != 0) - return _error->Errno("stat","Stat failed for %s", - string(*I).c_str()); + bool found = false; + std::string file = *I; + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) + { + if (stat(std::string(file + c->Extension).c_str(), &Buf) != 0) + continue; + found = true; + break; + } + + if (found == false) + return _error->Errno("stat", "Stat failed for %s", file.c_str()); TotalSize += Buf.st_size; - } + } off_t CurrentSize = 0; unsigned int NotFound = 0; @@ -806,57 +795,11 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ for (vector<string>::iterator I = List.begin(); I != List.end(); ++I) { string OrigPath = string(*I,CDROM.length()); - off_t FileSize = 0; - + // Open the package file - FileFd Pkg; - if (RealFileExists(*I) == true) - { - Pkg.Open(*I,FileFd::ReadOnly); - FileSize = Pkg.Size(); - } - else - { - FileFd From(*I + ".gz",FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - FileSize = From.Size(); - - // Get a temp file - FILE *tmp = tmpfile(); - if (tmp == 0) - return _error->Errno("tmpfile","Unable to create a tmp file"); - Pkg.Fd(dup(fileno(tmp))); - fclose(tmp); - - // Fork gzip - pid_t Process = fork(); - if (Process < 0) - return _error->Errno("fork","Couldn't fork gzip"); - - // The child - if (Process == 0) - { - dup2(From.Fd(),STDIN_FILENO); - dup2(Pkg.Fd(),STDOUT_FILENO); - SetCloseExec(STDIN_FILENO,false); - SetCloseExec(STDOUT_FILENO,false); - - const char *Args[3]; - string Tmp = _config->Find("Dir::bin::gzip","gzip"); - Args[0] = Tmp.c_str(); - Args[1] = "-d"; - Args[2] = 0; - execvp(Args[0],(char **)Args); - exit(100); - } - - // Wait for gzip to finish - if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) - return _error->Error("gzip failed, perhaps the disk is full."); - - Pkg.Seek(0); - } + FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Extension); + off_t const FileSize = Pkg.Size(); + pkgTagFile Parser(&Pkg); if (_error->PendingError() == true) return false; diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 21294ae7e..e3de1afd9 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -14,6 +14,11 @@ #include <string> #include <stdio.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::vector; +#endif + class pkgTagSection; class FileFd; class indexRecords; diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 5e162a846..1d34dc773 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -29,6 +29,10 @@ #include <apt-pkg/pkgrecords.h> #include <apt-pkg/macros.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class pkgAcquire; class pkgCacheGenerator; class OpProgress; diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index fa60a0847..a98b939bc 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -13,6 +13,10 @@ #include <vector> #include <ctime> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/fileutl.h> +#endif + class indexRecords { bool parseSumData(const char *&Start, const char *End, std::string &Name, diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 0c1c7ae5a..b6f3df753 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -13,6 +13,11 @@ #ifndef PKGLIB_INIT_H #define PKGLIB_INIT_H +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/configuration.h> +#include <apt-pkg/pkgsystem.h> +#endif + class pkgSystem; class Configuration; diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 9cc79a7a6..5783735ff 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -6,6 +6,13 @@ #include <apt-pkg/pkgcache.h> #include <apt-pkg/indexfile.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/srcrecords.h> +#include <apt-pkg/pkgrecords.h> +#include <apt-pkg/vendor.h> +using std::string; +#endif + class pkgAcquire; class pkgCacheGenerator; class OpProgress; diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index d4989a6e0..1a6a9f01c 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -29,6 +29,11 @@ #include <iostream> #include <set> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/depcache.h> +using std::string; +#endif + class pkgAcquire; class pkgDepCache; class pkgSourceList; diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 7e32a3a96..1a7013551 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -74,11 +74,14 @@ #ifndef PKGLIB_PKGCACHE_H #define PKGLIB_PKGCACHE_H - #include <string> #include <time.h> #include <apt-pkg/mmap.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class pkgVersioningSystem; class pkgCache /*{{{*/ { @@ -198,6 +201,7 @@ class pkgCache /*{{{*/ inline PkgFileIterator FileEnd(); inline bool MultiArchCache() const { return MultiArchEnabled; }; + inline char const * const NativeArch() const; // Make me a function pkgVersioningSystem *VS; @@ -213,7 +217,6 @@ class pkgCache /*{{{*/ private: bool MultiArchEnabled; PkgIterator SingleArchFindPkg(const std::string &Name); - inline char const * const NativeArch() const; }; /*}}}*/ // Header structure /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 9f999c41b..ec072fddd 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -35,12 +35,14 @@ #include <apti18n.h> /*}}}*/ -typedef vector<pkgIndexFile *>::iterator FileIterator; +typedef std::vector<pkgIndexFile *>::iterator FileIterator; template <typename Iter> std::vector<Iter*> pkgCacheGenerator::Dynamic<Iter>::toReMap; bool IsDuplicateDescription(pkgCache::DescIterator Desc, MD5SumValue const &CurMd5, std::string const &CurLang); +using std::string; + // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- /* We set the dirty flag and make sure that is written to the disk */ @@ -1221,14 +1223,14 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress MMap **OutMap,bool AllowMem) { bool const Debug = _config->FindB("Debug::pkgCacheGen", false); - - vector<pkgIndexFile *> Files; - for (vector<metaIndex *>::const_iterator i = List.begin(); + + std::vector<pkgIndexFile *> Files; + for (std::vector<metaIndex *>::const_iterator i = List.begin(); i != List.end(); ++i) { - vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles(); - for (vector<pkgIndexFile *>::const_iterator j = Indexes->begin(); + std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles(); + for (std::vector<pkgIndexFile *>::const_iterator j = Indexes->begin(); j != Indexes->end(); ++j) Files.push_back (*j); @@ -1418,7 +1420,7 @@ __deprecated bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutM { return pkgCacheGenerator::MakeOnlyStatusCache(&Progress, OutMap); } bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap) { - vector<pkgIndexFile *> Files; + std::vector<pkgIndexFile *> Files; unsigned long EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) return false; diff --git a/apt-pkg/pkgsystem.h b/apt-pkg/pkgsystem.h index 211fd0d56..75f7b9fcc 100644 --- a/apt-pkg/pkgsystem.h +++ b/apt-pkg/pkgsystem.h @@ -41,6 +41,10 @@ #include <vector> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/depcache.h> +#endif + class pkgDepCache; class pkgPackageManager; class pkgVersioningSystem; diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index 3c8246e3b..5172a3c3b 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -38,6 +38,10 @@ #include <apt-pkg/versionmatch.h> #include <vector> +#ifndef APT_8_CLEANER_HEADERS +using std::vector; +#endif + class pkgPolicy : public pkgDepCache::Policy { protected: diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index 4509e54b9..02e27101a 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -32,9 +32,11 @@ #include <map> #include <apt-pkg/pkgcache.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/metaindex.h> using std::string; using std::vector; - +#endif class pkgAcquire; class pkgIndexFile; @@ -57,32 +59,32 @@ class pkgSourceList const char *Name; const char *Label; - bool FixupURI(string &URI) const; - virtual bool ParseLine(vector<metaIndex *> &List, + bool FixupURI(std::string &URI) const; + virtual bool ParseLine(std::vector<metaIndex *> &List, const char *Buffer, - unsigned long const &CurLine,string const &File) const; - virtual bool CreateItem(vector<metaIndex *> &List,string const &URI, - string const &Dist,string const &Section, - std::map<string, string> const &Options) const = 0; + unsigned long const &CurLine,std::string const &File) const; + virtual bool CreateItem(std::vector<metaIndex *> &List,std::string const &URI, + std::string const &Dist,std::string const &Section, + std::map<std::string, std::string> const &Options) const = 0; Type(); virtual ~Type() {}; }; - typedef vector<metaIndex *>::const_iterator const_iterator; + typedef std::vector<metaIndex *>::const_iterator const_iterator; protected: - vector<metaIndex *> SrcList; + std::vector<metaIndex *> SrcList; public: bool ReadMainList(); - bool Read(string File); + bool Read(std::string File); // CNC:2003-03-03 void Reset(); - bool ReadAppend(string File); - bool ReadSourceDir(string Dir); + bool ReadAppend(std::string File); + bool ReadSourceDir(std::string Dir); // List accessors inline const_iterator begin() const {return SrcList.begin();}; @@ -98,7 +100,7 @@ class pkgSourceList time_t GetLastModifiedTime(); pkgSourceList(); - pkgSourceList(string File); + pkgSourceList(std::string File); ~pkgSourceList(); }; diff --git a/apt-pkg/srcrecords.cc b/apt-pkg/srcrecords.cc index f6d2d5158..48b643eac 100644 --- a/apt-pkg/srcrecords.cc +++ b/apt-pkg/srcrecords.cc @@ -29,8 +29,8 @@ pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0) { for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I) { - vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles(); - for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin(); + std::vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles(); + for (std::vector<pkgIndexFile *>::const_iterator J = Indexes->begin(); J != Indexes->end(); ++J) { Parser* P = (*J)->CreateSrcParser(); @@ -58,7 +58,7 @@ pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0) pkgSrcRecords::~pkgSrcRecords() { // Blow away all the parser objects - for(vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I) + for(std::vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I) delete *I; } /*}}}*/ @@ -68,7 +68,7 @@ pkgSrcRecords::~pkgSrcRecords() bool pkgSrcRecords::Restart() { Current = Files.begin(); - for (vector<Parser*>::iterator I = Files.begin(); + for (std::vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I) (*I)->Restart(); diff --git a/apt-pkg/srcrecords.h b/apt-pkg/srcrecords.h index a55bc74fa..06f0dce6c 100644 --- a/apt-pkg/srcrecords.h +++ b/apt-pkg/srcrecords.h @@ -17,6 +17,11 @@ #include <string> #include <vector> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +using std::vector; +#endif + class pkgSourceList; class pkgIndexFile; class pkgSrcRecords diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index a5bf5ac90..fd24471c1 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -24,6 +24,10 @@ #include <string> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/fileutl.h> +#endif + class FileFd; class pkgTagSection diff --git a/apt-pkg/vendor.h b/apt-pkg/vendor.h index 9b157378c..6484adf9b 100644 --- a/apt-pkg/vendor.h +++ b/apt-pkg/vendor.h @@ -6,6 +6,10 @@ #include <apt-pkg/macros.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + // A class representing a particular software provider. class __deprecated Vendor { diff --git a/apt-pkg/vendorlist.h b/apt-pkg/vendorlist.h index 733d23a32..a86ccde7c 100644 --- a/apt-pkg/vendorlist.h +++ b/apt-pkg/vendorlist.h @@ -17,6 +17,13 @@ #include <vector> #include <apt-pkg/macros.h> +#ifndef APT_8_CLEANER_HEADERS +#include <apt-pkg/vendor.h> +#include <apt-pkg/configuration.h> +using std::string; +using std::vector; +#endif + class Vendor; class Configuration; diff --git a/apt-pkg/version.h b/apt-pkg/version.h index 92dbc2576..e0e0e6c14 100644 --- a/apt-pkg/version.h +++ b/apt-pkg/version.h @@ -23,6 +23,10 @@ #include <apt-pkg/strutl.h> #include <string> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class pkgVersioningSystem { public: diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index da103fc5b..433396fc9 100644 --- a/apt-pkg/versionmatch.h +++ b/apt-pkg/versionmatch.h @@ -39,6 +39,10 @@ #include <string> #include <apt-pkg/pkgcache.h> +#ifndef APT_8_CLEANER_HEADERS +using std::string; +#endif + class pkgVersionMatch { // Version Matching |