From: David Kalnischkies Date: Sat, 13 Feb 2010 00:53:17 +0000 (+0100) Subject: [BREAK] merge MultiArch-ABI. We don't support MultiArch, X-Git-Tag: 0.8.0~9^2~64^2~20^2~22 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/34e8a998eb9e4f75f989acc6f8b9db8010e56b7c?ds=inline;hp=-c [BREAK] merge MultiArch-ABI. We don't support MultiArch, but we support the usage of the new ABI so libapt users can start to prepare for MultiArch (Closes: #536029) MultiArch isn't ready for Primetime usage for now, but the branch has managed to be a NOP if used in SingleArch-mode so we can start to promote the use of the new MultiArchable API-extensions. --- 34e8a998eb9e4f75f989acc6f8b9db8010e56b7c diff --combined apt-pkg/aptconfiguration.cc index 899004d9f,1ec526646..0fe84db74 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@@ -11,6 -11,7 +11,7 @@@ #include #include #include -#include ++#include #include #include @@@ -223,4 -224,28 +224,28 @@@ std::vector const Configur return codes; } /*}}}*/ + // getArchitectures - Return Vector of prefered Architectures /*{{{*/ + std::vector const Configuration::getArchitectures(bool const &Cached) { + using std::string; + + std::vector static archs; + if (likely(Cached == true) && archs.empty() == false) + return archs; + + string const arch = _config->Find("APT::Architecture"); + archs = _config->FindVector("APT::Architectures"); + if (archs.empty() == true || + std::find(archs.begin(), archs.end(), arch) == archs.end()) + archs.push_back(arch); + return archs; + } + /*}}}*/ + // checkArchitecture - are we interested in the given Architecture? /*{{{*/ + bool const Configuration::checkArchitecture(std::string const &Arch) { + if (Arch == "all") + return true; + std::vector const archs = getArchitectures(true); + return (std::find(archs.begin(), archs.end(), Arch) != archs.end()); + } + /*}}}*/ } diff --combined apt-pkg/cdrom.cc index 96d4e9c91,271bca409..83165c6c0 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@@ -6,6 -6,8 +6,8 @@@ #include #include #include + #include + #include #include #include @@@ -216,33 -218,23 +218,23 @@@ int pkgCdrom::Score(string Path /* Here we drop everything that is not this machines arch */ bool pkgCdrom::DropBinaryArch(vector &List) { - char S[300]; - snprintf(S,sizeof(S),"/binary-%s/", - _config->Find("Apt::Architecture").c_str()); - + for (unsigned int I = 0; I < List.size(); I++) { const char *Str = List[I].c_str(); - - const char *Res; - if ((Res = strstr(Str,"/binary-")) == 0) + const char *Start, *End; + if ((Start = strstr(Str,"/binary-")) == 0) continue; - // Weird, remove it. - if (strlen(Res) < strlen(S)) - { - List.erase(List.begin() + I); - I--; - continue; - } - - // See if it is our arch - if (stringcmp(Res,Res + strlen(S),S) == 0) - continue; - - // Erase it + // Between Start and End is the architecture + Start += 8; + if ((End = strstr(Start,"/")) != 0 && Start != End && + APT::Configuration::checkArchitecture(string(Start, --End)) == true) + continue; // okay, architecture is accepted + + // not accepted -> Erase it List.erase(List.begin() + I); - I--; + --I; // the next entry is at the same index after the erase } return true; @@@ -829,6 -821,8 +821,6 @@@ bool pkgCdrom::Add(pkgCdromStatus *log } } - - // Unmount and finish if (_config->FindB("APT::CDROM::NoMount",false) == false) { log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST); @@@ -919,7 -913,6 +911,7 @@@ pkgUdevCdromDevices::Scan( pkgUdevCdromDevices::~pkgUdevCdromDevices() /*{{{*/ { - dlclose(libudev_handle); + if (libudev_handle != NULL) + dlclose(libudev_handle); } /*}}}*/ diff --combined apt-pkg/contrib/macros.h index 9aeb77b81,000000000..c39caf198 mode 100644,000000..100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@@ -1,88 -1,0 +1,88 @@@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Macros Header - Various useful macro definitions + + This source is placed in the Public Domain, do with it what you will + It was originally written by Brian C. White. + + ##################################################################### */ + /*}}}*/ +// Private header +#ifndef MACROS_H +#define MACROS_H + +// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF +#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) +#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) + +// Min/Max functions +#if !defined(MIN) +#if defined(__HIGHC__) +#define MIN(x,y) _min(x,y) +#define MAX(x,y) _max(x,y) +#endif + +// GNU C++ has a min/max operator +#if defined(__GNUG__) +#define MIN(A,B) ((A) ? (B)) +#endif + +/* Templates tend to mess up existing code that uses min/max because of the + strict matching requirements */ +#if !defined(MIN) +#define MIN(A,B) ((A) < (B)?(A):(B)) +#define MAX(A,B) ((A) > (B)?(A):(B)) +#endif +#endif + +/* Bound functions, bound will return the value b within the limits a-c + bounv will change b so that it is within the limits of a-c. */ +#define _bound(a,b,c) MIN(c,MAX(b,a)) +#define _boundv(a,b,c) b = _bound(a,b,c) +#define ABS(a) (((a) < (0)) ?-(a) : (a)) + +/* Usefull count macro, use on an array of things and it will return the + number of items in the array */ +#define _count(a) (sizeof(a)/sizeof(a[0])) + +// Flag Macros +#define FLAG(f) (1L << (f)) +#define SETFLAG(v,f) ((v) |= FLAG(f)) +#define CLRFLAG(v,f) ((v) &=~FLAG(f)) +#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) + +// some nice optional GNUC features +#if __GNUC__ >= 3 - #define __must_check __attribute__ ((warn_unused_result)) - #define __deprecated __attribute__ ((deprecated)) - /* likely() and unlikely() can be used to mark boolean expressions - as (not) likely true which will help the compiler to optimise */ - #define likely(x) __builtin_expect (!!(x), 1) - #define unlikely(x) __builtin_expect (!!(x), 0) ++ #define __must_check __attribute__ ((warn_unused_result)) ++ #define __deprecated __attribute__ ((deprecated)) ++ /* likely() and unlikely() can be used to mark boolean expressions ++ as (not) likely true which will help the compiler to optimise */ ++ #define likely(x) __builtin_expect (!!(x), 1) ++ #define unlikely(x) __builtin_expect (!!(x), 0) +#else - #define __must_check /* no warn_unused_result */ - #define __deprecated /* no deprecated */ - #define likely(x) (x) - #define unlikely(x) (x) ++ #define __must_check /* no warn_unused_result */ ++ #define __deprecated /* no deprecated */ ++ #define likely(x) (x) ++ #define unlikely(x) (x) +#endif + +// cold functions are unlikely() to be called +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 - #define __cold __attribute__ ((__cold__)) ++ #define __cold __attribute__ ((__cold__)) +#else - #define __cold /* no cold marker */ ++ #define __cold /* no cold marker */ +#endif + +#ifdef __GNUG__ +// Methods have a hidden this parameter that is visible to this attribute - #define __like_printf_1 __attribute__ ((format (printf, 2, 3))) - #define __like_printf_2 __attribute__ ((format (printf, 3, 4))) ++ #define __like_printf_1 __attribute__ ((format (printf, 2, 3))) ++ #define __like_printf_2 __attribute__ ((format (printf, 3, 4))) +#else - #define __like_printf_1 - #define __like_printf_2 ++ #define __like_printf_1 /* no like-printf */ ++ #define __like_printf_2 /* no like-printf */ +#endif + +#endif diff --combined apt-pkg/contrib/strutl.cc index 2913fbf44,bed51881f..b285a9f2e --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@@ -43,10 -43,9 +43,10 @@@ bool UTF8ToCodeset(const char *codeset { iconv_t cd; const char *inbuf; - char *inptr, *outbuf, *outptr; - size_t insize, outsize; - + char *inptr, *outbuf; + size_t insize, bufsize; + dest->clear(); + cd = iconv_open(codeset, "UTF-8"); if (cd == (iconv_t)(-1)) { // Something went wrong @@@ -56,49 -55,33 +56,49 @@@ else perror("iconv_open"); - // Clean the destination string - *dest = ""; - return false; } - insize = outsize = orig.size(); + insize = bufsize = orig.size(); inbuf = orig.data(); inptr = (char *)inbuf; - outbuf = new char[insize+1]; - outptr = outbuf; + outbuf = new char[bufsize]; + size_t lastError = -1; while (insize != 0) { + char *outptr = outbuf; + size_t outsize = bufsize; size_t const err = iconv(cd, &inptr, &insize, &outptr, &outsize); + dest->append(outbuf, outptr - outbuf); if (err == (size_t)(-1)) { - insize--; - outsize++; - inptr++; - *outptr = '?'; - outptr++; + switch (errno) + { + case EILSEQ: + insize--; + inptr++; + // replace a series of unknown multibytes with a single "?" + if (lastError != insize) { + lastError = insize - 1; + dest->append("?"); + } + break; + case EINVAL: + insize = 0; + break; + case E2BIG: + if (outptr == outbuf) + { + bufsize *= 2; + delete[] outbuf; + outbuf = new char[bufsize]; + } + break; + } } } - *outptr = '\0'; - *dest = outbuf; delete[] outbuf; iconv_close(cd); @@@ -1000,6 -983,23 +1000,23 @@@ bool TokSplitString(char Tok,char *Inpu return true; } /*}}}*/ + // ExplodeString - Split a string up into a vector /*{{{*/ + // --------------------------------------------------------------------- + /* This can be used to split a given string up into a vector, so the + propose is the same as in the method above and this one is a bit slower + also, but the advantage is that we an iteratable vector */ + vector ExplodeString(string const &haystack, char const &split) { + string::const_iterator start = haystack.begin(); + string::const_iterator end = start; + vector exploded; + do { + for (; end != haystack.end() && *end != split; ++end); + exploded.push_back(string(start, end)); + start = end; + } while (end != haystack.end() && (++end) != haystack.end()); + return exploded; + } + /*}}}*/ // RegexChoice - Simple regex list/list matcher /*{{{*/ // --------------------------------------------------------------------- /* */ diff --combined apt-pkg/deb/debindexfile.cc index 201fd7fdf,73d72c729..bb8fae7cb --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@@ -149,9 -149,12 +149,12 @@@ unsigned long debSourcesIndex::Size() c // PackagesIndex::debPackagesIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ - debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) + debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section, + bool const &Trusted, string const &Arch) : + pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch) { + if (Architecture == "native") + Architecture = _config->Find("APT::Architecture"); } /*}}}*/ // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/ @@@ -171,6 -174,8 +174,8 @@@ string debPackagesIndex::ArchiveInfo(pk Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; + Res += Ver.Arch(); + Res += " "; Res += Ver.VerStr(); return Res; } @@@ -204,6 -209,8 +209,8 @@@ string debPackagesIndex::Info(const cha else Info += Dist + '/' + Section; Info += " "; + Info += Architecture; + Info += " "; Info += Type; return Info; } @@@ -227,7 -234,7 +234,7 @@@ string debPackagesIndex::IndexURI(cons } else Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + _config->Find("APT::Architecture") + '/'; + "/binary-" + Architecture + '/'; Res += Type; return Res; @@@ -259,7 -266,7 +266,7 @@@ bool debPackagesIndex::Merge(pkgCacheGe { string PackageFile = IndexFile("Packages"); FileFd Pkg(PackageFile,FileFd::ReadOnly); - debListParser Parser(&Pkg); + debListParser Parser(&Pkg, Architecture); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); @@@ -306,19 -313,9 +313,19 @@@ pkgCache::PkgFileIterator debPackagesIn struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "PackagesIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "PackagesIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } @@@ -483,19 -480,9 +490,19 @@@ pkgCache::PkgFileIterator debTranslatio struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "TranslationIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "TranslationIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } return File; @@@ -562,19 -549,9 +569,19 @@@ pkgCache::PkgFileIterator debStatusInde struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "StatusIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "StatusIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } return File; diff --combined apt-pkg/deb/deblistparser.cc index 66108d822,1948aedf3..bfc0e762e --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@@ -17,9 -17,10 +17,9 @@@ #include #include #include +#include #include - -#include /*}}}*/ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important}, @@@ -31,10 -32,13 +31,13 @@@ // ListParser::debListParser - Constructor /*{{{*/ // --------------------------------------------------------------------- - /* */ - debListParser::debListParser(FileFd *File) : Tags(File) - { - Arch = _config->Find("APT::architecture"); + /* Provide an architecture and only this one and "all" will be accepted + in Step(), if no Architecture is given we will accept every arch + we would accept in general with checkArchitecture() */ + debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), + Arch(Arch) { + if (Arch == "native") + this->Arch = _config->Find("APT::Architecture"); } /*}}}*/ // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ @@@ -52,12 -56,38 +55,38 @@@ unsigned long debListParser::UniqFindTa // ListParser::Package - Return the package name /*{{{*/ // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ - string debListParser::Package() - { - string Result = Section.FindS("Package"); - if (Result.empty() == true) - _error->Error("Encountered a section with no Package: header"); - return Result; + string debListParser::Package() { + string const Result = Section.FindS("Package"); + if(unlikely(Result.empty() == true)) + _error->Error("Encountered a section with no Package: header"); + return Result; + } + /*}}}*/ + // ListParser::Architecture - Return the package arch /*{{{*/ + // --------------------------------------------------------------------- + /* This will return the Architecture of the package this section describes + Note that architecture "all" packages will get the architecture of the + Packages file parsed here. */ + string debListParser::Architecture() { + string const Result = Section.FindS("Architecture"); + if (Result.empty() == true || Result == "all") { + if (Arch.empty() == true) + /* FIXME: this is a problem for installed arch all + packages as we don't know from which arch this + package was installed - and therefore which + dependency this package resolves. */ + return _config->Find("APT::Architecture"); + else + return Arch; + } + return Result; + } + /*}}}*/ + // ListParser::ArchitectureAll /*{{{*/ + // --------------------------------------------------------------------- + /* */ + bool debListParser::ArchitectureAll() { + return Section.FindS("Architecture") == "all"; } /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ @@@ -77,8 -107,31 +106,31 @@@ bool debListParser::NewVersion(pkgCache { // Parse the section Ver->Section = UniqFindTagWrite("Section"); - Ver->Arch = UniqFindTagWrite("Architecture"); - + + // Parse multi-arch + if (Section.FindS("Architecture") == "all") + /* Arch all packages can't have a Multi-Arch field, + but we need a special treatment for them nonetheless */ + Ver->MultiArch = pkgCache::Version::All; + else + { + string const MultiArch = Section.FindS("Multi-Arch"); + if (MultiArch.empty() == true) + Ver->MultiArch = pkgCache::Version::None; + else if (MultiArch == "same") + Ver->MultiArch = pkgCache::Version::Same; + else if (MultiArch == "foreign") + Ver->MultiArch = pkgCache::Version::Foreign; + else if (MultiArch == "allowed") + Ver->MultiArch = pkgCache::Version::Allowed; + else + { + _error->Warning("Unknown Multi-Arch type »%s« for package »%s«", + MultiArch.c_str(), Section.FindS("Package").c_str()); + Ver->MultiArch = pkgCache::Version::None; + } + } + // Archive Size Ver->Size = (unsigned)Section.FindI("Size"); @@@ -95,6 -148,24 +147,24 @@@ Ver->Priority = pkgCache::State::Extra; } + if (Ver->MultiArch == pkgCache::Version::All) + { + /* We maintain a "pseudo" arch=all package for architecture all versions + on which these versions can depend on. This pseudo package is many used + for downloading/installing: The other pseudo-packages will degenerate + to a NOP in the download/install step - this package will ensure that + it is downloaded only one time and installed only one time -- even if + the architecture bound versions coming in and out on regular basis. */ + if (strcmp(Ver.Arch(true),"all") == 0) + return true; + else if (Ver.Pseudo() == true) + { + // our pseudo packages have no size to not confuse the fetcher + Ver->Size = 0; + Ver->InstalledSize = 0; + } + } + if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) return false; if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) @@@ -183,8 -254,12 +253,12 @@@ bool debListParser::UsePackage(pkgCache { if (Pkg->Section == 0) Pkg->Section = UniqFindTagWrite("Section"); - if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) - return false; + + // Packages which are not from "our" arch doesn't get the essential flag + string const static myArch = _config->Find("APT::Architecture"); + if (Pkg->Arch != 0 && myArch == Pkg.Arch()) + if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) + return false; if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false) return false; @@@ -536,6 -611,7 +610,7 @@@ bool debListParser::ParseDepends(pkgCac return true; string Package; + string const pkgArch = Ver.Arch(true); string Version; unsigned int Op; @@@ -545,7 -621,7 +620,7 @@@ if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); - if (NewDepends(Ver,Package,Version,Op,Type) == false) + if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) return false; if (Start == Stop) break; @@@ -560,29 -636,52 +635,52 @@@ bool debListParser::ParseProvides(pkgCa { const char *Start; const char *Stop; - if (Section.Find("Provides",Start,Stop) == false) - return true; - - string Package; - string Version; - unsigned int Op; - - while (1) + if (Section.Find("Provides",Start,Stop) == true) { - Start = ParseDepends(Start,Stop,Package,Version,Op); - if (Start == 0) - return _error->Error("Problem parsing Provides line"); - if (Op != pkgCache::Dep::NoOp) { - _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); - } else { - if (NewProvides(Ver,Package,Version) == false) - return false; + string Package; + string Version; + string const Arch = Ver.Arch(true); + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing Provides line"); + if (Op != pkgCache::Dep::NoOp) { + _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + } else { + if (NewProvides(Ver, Package, Arch, Version) == false) + return false; + } + + if (Start == Stop) + break; } + } - if (Start == Stop) - break; + if (Ver->MultiArch == pkgCache::Version::Allowed) + { + string const Package = string(Ver.ParentPkg().Name()).append(":").append("any"); + NewProvides(Ver, Package, "any", Ver.VerStr()); } - + + if (Ver->MultiArch != pkgCache::Version::Foreign) + return true; + + std::vector const archs = APT::Configuration::getArchitectures(); + if (archs.size() <= 1) + return true; + + string const Package = Ver.ParentPkg().Name(); + string const Version = Ver.VerStr(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end(); ++a) + { + if (NewProvides(Ver, Package, *a, Version) == false) + return false; + } + return true; } /*}}}*/ @@@ -613,16 -712,23 +711,23 @@@ bool debListParser::Step( /* See if this is the correct Architecture, if it isn't then we drop the whole section. A missing arch tag only happens (in theory) inside the Status file, so that is a positive return */ - const char *Start; - const char *Stop; - if (Section.Find("Architecture",Start,Stop) == false) + string const Architecture = Section.FindS("Architecture"); + if (Architecture.empty() == true) return true; - if (stringcmp(Arch,Start,Stop) == 0) - return true; + if (Arch.empty() == true) + { + if (APT::Configuration::checkArchitecture(Architecture) == true) + return true; + } + else + { + if (Architecture == Arch) + return true; - if (stringcmp(Start,Stop,"all") == 0) - return true; + if (Architecture == "all") + return true; + } iOffset = Tags.Offset(); } @@@ -640,8 -746,9 +745,9 @@@ bool debListParser::LoadReleaseInfo(pkg if (Tags.Step(Section) == false) return false; - //mvo: I don't think we need to fill that in (it's unused since apt-0.6) - //FileI->Architecture = WriteUniqString(Arch); + // FIXME: Do we need it now for multi-arch? + // mvo: I don't think we need to fill that in (it's unused since apt-0.6) + // FileI->Architecture = WriteUniqString(Arch); // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now diff --combined apt-pkg/depcache.cc index 5943d858a,e817adb77..eeb74a434 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@@ -17,6 -17,7 +17,7 @@@ #include #include #include + #include #include #include @@@ -192,10 -193,10 +193,10 @@@ bool pkgDepCache::readStateFile(OpProgr Prog->OverallProgress(amt, file_size, 1, _("Reading state information")); } - if(Prog != NULL) - Prog->OverallProgress(file_size, file_size, 1, - _("Reading state information")); } + if(Prog != NULL) + Prog->OverallProgress(file_size, file_size, 1, + _("Reading state information")); } return true; @@@ -243,7 -244,7 +244,7 @@@ bool pkgDepCache::writeStateFile(OpProg continue; bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); if(_config->FindB("Debug::pkgAutoRemove",false)) - std::clog << "Update exisiting AutoInstall info: " + std::clog << "Update existing AutoInstall info: " << pkg.Name() << std::endl; TFRewriteData rewrite[2]; rewrite[0].Tag = "Auto-Installed"; @@@ -596,6 -597,57 +597,57 @@@ void pkgDepCache::UpdateVerState(PkgIte } } /*}}}*/ + // DepCache::RemovePseudoInstalledPkg - MultiArch helper for Update() /*{{{*/ + // --------------------------------------------------------------------- + /* We "install" arch all packages for all archs if it is installed. Many + of these will be broken. This method will look at these broken Pkg and + "remove" it. */ + bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set &recheck) { + if (unlikely(Pkg->CurrentVer == 0)) + return false; + + VerIterator V = Pkg.CurrentVer(); + if (V->MultiArch != Version::All) + return false; + + unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + if ((DepState & DepInstMin) == DepInstMin) + return false; + + // Dependencies for this arch all are not statisfied + // so we installed it only for our convenience: get right of it now. + RemoveSizes(Pkg); + RemoveStates(Pkg); + + Pkg->CurrentVer = 0; + PkgState[Pkg->ID].InstallVer = 0; + + AddStates(Pkg); + Update(Pkg); + AddSizes(Pkg); + + // After the remove previously satisfied pseudo pkg could be now + // no longer satisfied, so we need to recheck the reverse dependencies + for (DepIterator d = Pkg.RevDependsList(); d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer != 0) + recheck.insert(P.Index()); + } + + if (V.end() != true) + for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) + for (DepIterator d = Prv.ParentPkg().RevDependsList(); + d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer != 0) + recheck.insert(P.Index()); + } + + return true; + } + /*}}}*/ // DepCache::Update - Figure out all the state information /*{{{*/ // --------------------------------------------------------------------- /* This will figure out the state of all the packages and all the @@@ -609,9 -661,13 +661,13 @@@ void pkgDepCache::Update(OpProgress *Pr iKeepCount = 0; iBrokenCount = 0; iBadCount = 0; - + + std::set recheck; + // Perform the depends pass int Done = 0; + bool const checkMultiArch = APT::Configuration::getArchitectures().size() > 1; + unsigned long killed = 0; for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) { if (Prog != 0 && Done%20 == 0) @@@ -619,7 -675,7 +675,7 @@@ for (VerIterator V = I.VersionList(); V.end() != true; V++) { unsigned char Group = 0; - + for (DepIterator D = V.DependsList(); D.end() != true; D++) { // Build the dependency state. @@@ -637,16 -693,43 +693,43 @@@ D->Type == Dep::DpkgBreaks || D->Type == Dep::Obsoletes) State = ~State; - } + } } - // Compute the pacakge dependency state and size additions + // Compute the package dependency state and size additions AddSizes(I); UpdateVerState(I); AddStates(I); + + if (checkMultiArch != true || I->CurrentVer == 0) + continue; + + VerIterator const V = I.CurrentVer(); + if (V->MultiArch != Version::All) + continue; + + recheck.insert(I.Index()); + --Done; // no progress if we need to recheck the package + } + + if (checkMultiArch == true) { + /* FIXME: recheck breaks proper progress reporting as we don't know + how many packages we need to recheck. To lower the effect + a bit we increase with a kill, but we should do something more clever… */ + for(std::set::const_iterator p = recheck.begin(); + p != recheck.end(); ++p) { + if (Prog != 0 && Done%20 == 0) + Prog->Progress(Done); + PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); + if (RemovePseudoInstalledPkg(P, recheck) == true) { + ++killed; + ++Done; + } + recheck.erase(p); + } } - if (Prog != 0) + if (Prog != 0) Prog->Progress(Done); readStateFile(Prog); @@@ -813,6 -896,10 +896,10 @@@ void pkgDepCache::MarkDelete(PkgIterato AddStates(Pkg); Update(Pkg); AddSizes(Pkg); + + // if we remove the pseudo package, we also need to remove the "real" + if (Pkg->CurrentVer != 0 && Pkg.CurrentVer().Pseudo() == true) + MarkDelete(Pkg.Group().FindPkg("all"), rPurge, Depth+1, FromUser); } /*}}}*/ // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/ diff --combined apt-pkg/packagemanager.cc index 491bff110,08e7fc00f..db882721e --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@@ -80,7 -80,10 +80,10 @@@ bool pkgPackageManager::GetArchives(pkg // Skip already processed packages if (List->IsNow(Pkg) == false) continue; - + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) + continue; + new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), FileNames[Pkg->ID]); } @@@ -277,8 -280,10 +280,10 @@@ bool pkgPackageManager::ConfigureAll( for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) { PkgIterator Pkg(Cache,*I); - - if (ConfigurePkgs == true && Configure(Pkg) == false) + + if (ConfigurePkgs == true && + pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@@ -293,9 -298,6 +298,9 @@@ of it's dependents. */ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { + if (Debug == true) + clog << "SmartConfigure " << Pkg.Name() << endl; + pkgOrderList OList(&Cache); if (DepAdd(OList,Pkg) == false) @@@ -313,7 -315,9 +318,9 @@@ { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && Configure(Pkg) == false) + if (ConfigurePkgs == true && + pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@@ -460,7 -464,10 +467,10 @@@ bool pkgPackageManager::SmartRemove(Pkg return true; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + return true; } /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ @@@ -492,9 -499,6 +502,9 @@@ bool pkgPackageManager::SmartUnPack(Pkg while (End->Type == pkgCache::Dep::PreDepends) { + if (Debug == true) + clog << "PreDepends order for " << Pkg.Name() << std::endl; + // Look for possible ok targets. SPtrArray VList = Start.AllTargets(); bool Bad = true; @@@ -508,8 -512,6 +518,8 @@@ Pkg.State() == PkgIterator::NeedsNothing) { Bad = false; + if (Debug == true) + clog << "Found ok package " << Pkg.Name() << endl; continue; } } @@@ -525,8 -527,6 +535,8 @@@ (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) continue; + if (Debug == true) + clog << "Trying to SmartConfigure " << Pkg.Name() << endl; Bad = !SmartConfigure(Pkg); } @@@ -575,7 -575,8 +585,8 @@@ P.end() == false; P++) CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - if (Install(Pkg,FileNames[Pkg->ID]) == false) + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Install(Pkg,FileNames[Pkg->ID]) == false) return false; List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); diff --combined apt-pkg/pkgcache.cc index 038bd7ec4,d4268b31c..29c27b58e --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@@ -27,7 -27,6 +27,7 @@@ #include #include #include +#include #include @@@ -36,6 -35,7 +36,6 @@@ #include #include -#include /*}}}*/ using std::string; @@@ -79,7 -79,8 +79,8 @@@ pkgCache::Header::Header( StringList = 0; VerSysName = 0; Architecture = 0; - memset(HashTable,0,sizeof(HashTable)); + memset(PkgHashTable,0,sizeof(PkgHashTable)); + memset(GrpHashTable,0,sizeof(GrpHashTable)); memset(Pools,0,sizeof(Pools)); } /*}}}*/ @@@ -118,6 -119,7 +119,7 @@@ bool pkgCache::ReMap( { // Apply the typecasts. HeaderP = (Header *)Map.Data(); + GrpP = (Group *)Map.Data(); PkgP = (Package *)Map.Data(); VerFileP = (VerFile *)Map.Data(); DescFileP = (DescFile *)Map.Data(); @@@ -165,7 -167,7 +167,7 @@@ unsigned long pkgCache::sHash(const str unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); I++) Hash = 5*Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->HashTable); + return Hash % _count(HeaderP->PkgHashTable); } unsigned long pkgCache::sHash(const char *Str) const @@@ -173,24 -175,53 +175,53 @@@ unsigned long Hash = 0; for (const char *I = Str; *I != 0; I++) Hash = 5*Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->HashTable); + return Hash % _count(HeaderP->PkgHashTable); } /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ - pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) - { - // Look at the hash bucket - Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)]; - for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) - { - if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && - stringcasecmp(Name,StrP + Pkg->Name) == 0) - return PkgIterator(*this,Pkg); - } - return PkgIterator(*this,0); + pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { + size_t const found = Name.find(':'); + if (found == string::npos) + return FindPkg(Name, "native"); + string const Arch = Name.substr(found+1); + if (Arch == "any") + return FindPkg(Name, "any"); + return FindPkg(Name.substr(0, found), Arch); + } + /*}}}*/ + // Cache::FindPkg - Locate a package by name /*{{{*/ + // --------------------------------------------------------------------- + /* Returns 0 on error, pointer to the package otherwise */ + pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) { + /* We make a detour via the GrpIterator here as + on a multi-arch environment a group is easier to + find than a package (less entries in the buckets) */ + pkgCache::GrpIterator Grp = FindGrp(Name); + if (Grp.end() == true) + return PkgIterator(*this,0); + + return Grp.FindPkg(Arch); + } + /*}}}*/ + // Cache::FindGrp - Locate a group by name /*{{{*/ + // --------------------------------------------------------------------- + /* Returns End-Pointer on error, pointer to the group otherwise */ + pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) { + if (unlikely(Name.empty() == true)) + return GrpIterator(*this,0); + + // Look at the hash bucket for the group + Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)]; + for (; Grp != GrpP; Grp = GrpP + Grp->Next) { + if (Grp->Name != 0 && StrP[Grp->Name] == Name[0] && + stringcasecmp(Name, StrP + Grp->Name) == 0) + return GrpIterator(*this, Grp); + } + + return GrpIterator(*this,0); } /*}}}*/ // Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/ @@@ -242,11 -273,84 +273,84 @@@ const char *pkgCache::Priority(unsigne return 0; } /*}}}*/ - // Bases for iterator classes /*{{{*/ - void pkgCache::VerIterator::_dummy() {} - void pkgCache::DepIterator::_dummy() {} - void pkgCache::PrvIterator::_dummy() {} - void pkgCache::DescIterator::_dummy() {} + // GrpIterator::FindPkg - Locate a package by arch /*{{{*/ + // --------------------------------------------------------------------- + /* Returns an End-Pointer on error, pointer to the package otherwise */ + pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { + if (unlikely(IsGood() == false || S->FirstPackage == 0)) + return PkgIterator(*Owner, 0); + + static string const myArch = _config->Find("APT::Architecture"); + /* Most of the time the package for our native architecture is + the one we add at first to the cache, but this would be the + last one we check, so we do it now. */ + if (Arch == "native" || Arch == myArch) { + Arch = myArch; + pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage; + if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0) + return PkgIterator(*Owner, Pkg); + } + + /* If we accept any package we simply return the "first" + package in this group (the last one added). */ + if (Arch == "any") + return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage); + + /* Iterate over the list to find the matching arch + unfortunately this list includes "package noise" + (= different packages with same calculated hash), + so we need to check the name also */ + for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP; + Pkg = Owner->PkgP + Pkg->NextPackage) { + if (S->Name == Pkg->Name && + stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0) + return PkgIterator(*Owner, Pkg); + if ((Owner->PkgP + S->LastPackage) == Pkg) + break; + } + + return PkgIterator(*Owner, 0); + } + /*}}}*/ + // GrpIterator::NextPkg - Locate the next package in the group /*{{{*/ + // --------------------------------------------------------------------- + /* Returns an End-Pointer on error, pointer to the package otherwise. + We can't simply ++ to the next as the list of packages includes + "package noise" (= packages with the same hash value but different name) */ + pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) { + if (unlikely(IsGood() == false || S->FirstPackage == 0 || + LastPkg.end() == true)) + return PkgIterator(*Owner, 0); + + // Iterate over the list to find the next package + pkgCache::Package *Pkg = Owner->PkgP + LastPkg.Index(); + Pkg = Owner->PkgP + Pkg->NextPackage; + for (; Pkg != Owner->PkgP; Pkg = Owner->PkgP + Pkg->NextPackage) { + if (S->Name == Pkg->Name) + return PkgIterator(*Owner, Pkg); + if ((Owner->PkgP + S->LastPackage) == Pkg) + break; + } + + return PkgIterator(*Owner, 0); + } + /*}}}*/ + // GrpIterator::operator ++ - Postfix incr /*{{{*/ + // --------------------------------------------------------------------- + /* This will advance to the next logical group in the hash table. */ + void pkgCache::GrpIterator::operator ++(int) + { + // Follow the current links + if (S != Owner->GrpP) + S = Owner->GrpP + S->Next; + + // Follow the hash table + while (S == Owner->GrpP && (HashIndex+1) < (signed)_count(Owner->HeaderP->GrpHashTable)) + { + HashIndex++; + S = Owner->GrpP + Owner->HeaderP->GrpHashTable[HashIndex]; + } + }; /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- @@@ -254,14 -358,14 +358,14 @@@ void pkgCache::PkgIterator::operator ++(int) { // Follow the current links - if (Pkg != Owner->PkgP) - Pkg = Owner->PkgP + Pkg->NextPackage; + if (S != Owner->PkgP) + S = Owner->PkgP + S->NextPackage; // Follow the hash table - while (Pkg == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->HashTable)) + while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->PkgHashTable)) { HashIndex++; - Pkg = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; + S = Owner->PkgP + Owner->HeaderP->PkgHashTable[HashIndex]; } }; /*}}}*/ @@@ -270,12 -374,12 +374,12 @@@ /* By this we mean if it is either cleanly installed or cleanly removed. */ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const { - if (Pkg->InstState == pkgCache::State::ReInstReq || - Pkg->InstState == pkgCache::State::HoldReInstReq) + if (S->InstState == pkgCache::State::ReInstReq || + S->InstState == pkgCache::State::HoldReInstReq) return NeedsUnpack; - if (Pkg->CurrentState == pkgCache::State::UnPacked || - Pkg->CurrentState == pkgCache::State::HalfConfigured) + if (S->CurrentState == pkgCache::State::UnPacked || + S->CurrentState == pkgCache::State::HalfConfigured) // we leave triggers alone complettely. dpkg deals with // them in a hard-to-predict manner and if they get // resolved by dpkg before apt run dpkg --configure on @@@ -284,8 -388,8 +388,8 @@@ //Pkg->CurrentState == pkgCache::State::TriggersPending) return NeedsConfigure; - if (Pkg->CurrentState == pkgCache::State::HalfInstalled || - Pkg->InstState != pkgCache::State::Ok) + if (S->CurrentState == pkgCache::State::HalfInstalled || + S->InstState != pkgCache::State::Ok) return NeedsUnpack; return NeedsNothing; @@@ -332,7 -436,7 +436,7 @@@ operator<<(ostream& out, pkgCache::PkgI string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion()); string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr()); - out << Pkg.Name() << " < " << current; + out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current; if (current != candidate) out << " -> " << candidate; if ( newest != "none" && candidate != newest) @@@ -347,11 -451,11 +451,11 @@@ conflicts (including dpkg's Breaks fields). */ bool pkgCache::DepIterator::IsCritical() { - if (Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes || - Dep->Type == pkgCache::Dep::Depends || - Dep->Type == pkgCache::Dep::PreDepends) + if (S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes || + S->Type == pkgCache::Dep::Depends || + S->Type == pkgCache::Dep::PreDepends) return true; return false; } @@@ -430,12 -534,12 +534,12 @@@ pkgCache::Version **pkgCache::DepIterat // Walk along the actual package providing versions for (VerIterator I = DPkg.VersionList(); I.end() == false; I++) { - if (Owner->VS->CheckDep(I.VerStr(),Dep->CompareOp,TargetVer()) == false) + if (Owner->VS->CheckDep(I.VerStr(),S->CompareOp,TargetVer()) == false) continue; - if ((Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes) && + if ((S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.ParentPkg()) continue; @@@ -447,12 -551,12 +551,12 @@@ // Follow all provides for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; I++) { - if (Owner->VS->CheckDep(I.ProvideVersion(),Dep->CompareOp,TargetVer()) == false) + if (Owner->VS->CheckDep(I.ProvideVersion(),S->CompareOp,TargetVer()) == false) continue; - if ((Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes) && + if ((S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.OwnerPkg()) continue; @@@ -490,7 -594,7 +594,7 @@@ void pkgCache::DepIterator::GlobOr(DepI End = *this; for (bool LastOR = true; end() == false && LastOR == true;) { - LastOR = (Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + LastOR = (S->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; (*this)++; if (LastOR == true) End = (*this); @@@ -545,6 -649,23 +649,23 @@@ bool pkgCache::VerIterator::Automatic( return false; } /*}}}*/ + // VerIterator::Pseudo - Check if this version is a pseudo one /*{{{*/ + // --------------------------------------------------------------------- + /* Sometimes you have the need to express dependencies with versions + which doesn't really exist or exist multiply times for "different" + packages. We need these versions for dependency resolution but they + are a problem everytime we need to download/install something. */ + bool pkgCache::VerIterator::Pseudo() const + { + if (S->MultiArch == pkgCache::Version::All && + strcmp(Arch(true),"all") != 0) + { + GrpIterator const Grp = ParentPkg().Group(); + return (Grp->LastPackage != Grp->FirstPackage); + } + return false; + } + /*}}}*/ // VerIterator::NewestFile - Return the newest file version relation /*{{{*/ // --------------------------------------------------------------------- /* This looks at the version numbers associated with all of the sources @@@ -625,7 -746,9 +746,9 @@@ string pkgCache::VerIterator::RelStr( else Res += File.Site(); } - } + } + if (S->ParentPkg != 0) + Res.append(" [").append(Arch()).append("]"); return Res; } /*}}}*/ @@@ -640,7 -763,7 +763,7 @@@ bool pkgCache::PkgFileIterator::IsOk( if (stat(FileName(),&Buf) != 0) return false; - if (Buf.st_size != (signed)File->Size || Buf.st_mtime != File->mtime) + if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime) return false; return true; @@@ -664,6 -787,8 +787,8 @@@ string pkgCache::PkgFileIterator::RelSt Res = Res + (Res.empty() == true?"l=":",l=") + Label(); if (Component() != 0) Res = Res + (Res.empty() == true?"c=":",c=") + Component(); + if (Architecture() != 0) + Res = Res + (Res.empty() == true?"b=":",b=") + Architecture(); return Res; } /*}}}*/ diff --combined apt-pkg/pkgcachegen.cc index 3eeb18cae,6d103c6b6..3d1a654d1 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@@ -18,10 -18,10 +18,11 @@@ #include #include #include + #include #include #include #include +#include #include @@@ -33,12 -33,13 +34,12 @@@ #include #include #include -#include /*}}}*/ typedef vector::iterator FileIterator; // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- - /* We set the diry flag and make sure that is written to the disk */ + /* We set the dirty flag and make sure that is written to the disk */ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : Map(*pMap), Cache(pMap,false), Progress(Prog), FoundFileDeps(0) @@@ -107,13 -108,26 +108,26 @@@ bool pkgCacheGenerator::MergeList(ListP unsigned int Counter = 0; while (List.Step() == true) { - // Get a pointer to the package structure - string PackageName = List.Package(); + string const PackageName = List.Package(); if (PackageName.empty() == true) return false; - + + /* As we handle Arch all packages as architecture bounded + we add all information to every (simulated) arch package */ + std::vector genArch; + if (List.ArchitectureAll() == true) { + genArch = APT::Configuration::getArchitectures(); + if (genArch.size() != 1) + genArch.push_back("all"); + } else + genArch.push_back(List.Architecture()); + + for (std::vector::const_iterator arch = genArch.begin(); + arch != genArch.end(); ++arch) + { + // Get a pointer to the package structure pkgCache::PkgIterator Pkg; - if (NewPackage(Pkg,PackageName) == false) + if (NewPackage(Pkg, PackageName, *arch) == false) return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str()); Counter++; if (Counter % 100 == 0 && Progress != 0) @@@ -256,6 -270,7 +270,7 @@@ if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str()); + } } FoundFileDeps |= List.HasFileDeps(); @@@ -323,33 -338,71 +338,71 @@@ bool pkgCacheGenerator::MergeFileProvid return true; } /*}}}*/ + // CacheGenerator::NewGroup - Add a new group /*{{{*/ + // --------------------------------------------------------------------- + /* This creates a new group structure and adds it to the hash table */ + bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) { + Grp = Cache.FindGrp(Name); + if (Grp.end() == false) + return true; + + // Get a structure + unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group)); + if (unlikely(Group == 0)) + return false; + + Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); + Grp->Name = Map.WriteString(Name); + if (unlikely(Grp->Name == 0)) + return false; + + // Insert it into the hash table + unsigned long const Hash = Cache.Hash(Name); + Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; + Cache.HeaderP->GrpHashTable[Hash] = Group; + + Cache.HeaderP->GroupCount++; + + return true; + } + /*}}}*/ // CacheGenerator::NewPackage - Add a new package /*{{{*/ // --------------------------------------------------------------------- /* This creates a new package structure and adds it to the hash table */ - bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name) - { - Pkg = Cache.FindPkg(Name); - if (Pkg.end() == false) - return true; + bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, + const string &Arch) { + pkgCache::GrpIterator Grp; + if (unlikely(NewGroup(Grp, Name) == false)) + return false; + + Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == false) + return true; // Get a structure - unsigned long Package = Map.Allocate(sizeof(pkgCache::Package)); - if (Package == 0) + unsigned long const Package = Map.Allocate(sizeof(pkgCache::Package)); + if (unlikely(Package == 0)) return false; - Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); - + // Insert it into the hash table - unsigned long Hash = Cache.Hash(Name); - Pkg->NextPackage = Cache.HeaderP->HashTable[Hash]; - Cache.HeaderP->HashTable[Hash] = Package; - - // Set the name and the ID - Pkg->Name = Map.WriteString(Name); - if (Pkg->Name == 0) + unsigned long const Hash = Cache.Hash(Name); + Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; + Cache.HeaderP->PkgHashTable[Hash] = Package; + + // remember the packages in the group + Grp->FirstPackage = Package; + if (Grp->LastPackage == 0) + Grp->LastPackage = Package; + + // Set the name, arch and the ID + Pkg->Name = Grp->Name; + Pkg->Group = Grp.Index(); + Pkg->Arch = WriteUniqString(Arch.c_str()); + if (unlikely(Pkg->Arch == 0)) return false; Pkg->ID = Cache.HeaderP->PackageCount++; - + return true; } /*}}}*/ @@@ -468,21 -521,87 +521,87 @@@ map_ptrloc pkgCacheGenerator::NewDescri return Description; } /*}}}*/ - // ListParser::NewDepends - Create a dependency element /*{{{*/ + // CacheGenerator::FinishCache - do various finish operations /*{{{*/ + // --------------------------------------------------------------------- + /* This prepares the Cache for delivery */ + bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { + // FIXME: add progress reporting for this operation + // Do we have different architectures in your groups ? + vector archs = APT::Configuration::getArchitectures(); + if (archs.size() > 1) { + // Create Conflicts in between the group + for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) { + string const PkgName = G.Name(); + for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) { + if (strcmp(P.Arch(),"all") == 0) + continue; + pkgCache::PkgIterator allPkg; + for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) { + string const Arch = V.Arch(true); + map_ptrloc *OldDepLast = NULL; + /* MultiArch handling introduces a lot of implicit Dependencies: + - MultiArch: same → Co-Installable if they have the same version + - Architecture: all → Need to be Co-Installable for internal reasons + - All others conflict with all other group members */ + bool const coInstall = (V->MultiArch == pkgCache::Version::All || + V->MultiArch == pkgCache::Version::Same); + if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true) + allPkg = G.FindPkg("all"); + for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) { + if (*A == Arch) + continue; + /* We allow only one installed arch at the time + per group, therefore each group member conflicts + with all other group members */ + pkgCache::PkgIterator D = G.FindPkg(*A); + if (D.end() == true) + continue; + if (coInstall == true) { + // Replaces: ${self}:other ( << ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::Replaces, + OldDepLast); + // Breaks: ${self}:other (!= ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks, + OldDepLast); + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, + OldDepLast); + if (V->MultiArch == pkgCache::Version::All) { + // Depend on ${self}:all which does depend on nothing + NewDepends(allPkg, V, V.VerStr(), + pkgCache::Dep::Equals, pkgCache::Dep::Depends, + OldDepLast); + } + } else { + // Conflicts: ${self}:other + NewDepends(D, V, "", + pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, + OldDepLast); + } + } + } + } + } + } + return true; + } + /*}}}*/ + // CacheGenerator::NewDepends - Create a dependency element /*{{{*/ // --------------------------------------------------------------------- /* This creates a dependency element in the tree. It is linked to the version and to the package that it is pointing to. */ - bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, - const string &PackageName, - const string &Version, - unsigned int Op, - unsigned int Type) + bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver, + string const &Version, + unsigned int const &Op, + unsigned int const &Type, + map_ptrloc *OldDepLast) { - pkgCache &Cache = Owner->Cache; - // Get a structure - unsigned long Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency)); - if (Dependency == 0) + unsigned long const Dependency = Map.Allocate(sizeof(pkgCache::Dependency)); + if (unlikely(Dependency == 0)) return false; // Fill it in @@@ -491,12 -610,7 +610,7 @@@ Dep->Type = Type; Dep->CompareOp = Op; Dep->ID = Cache.HeaderP->DependsCount++; - - // Locate the target package - pkgCache::PkgIterator Pkg; - if (Owner->NewPackage(Pkg,PackageName) == false) - return false; - + // Probe the reverse dependency list for a version string that matches if (Version.empty() == false) { @@@ -504,29 -618,23 +618,23 @@@ if (I->Version != 0 && I.TargetVer() == Version) Dep->Version = I->Version;*/ if (Dep->Version == 0) - if ((Dep->Version = WriteString(Version)) == 0) + if (unlikely((Dep->Version = Map.WriteString(Version)) == 0)) return false; } - + // Link it to the package Dep->Package = Pkg.Index(); Dep->NextRevDepends = Pkg->RevDepends; Pkg->RevDepends = Dep.Index(); - - /* Link it to the version (at the end of the list) - Caching the old end point speeds up generation substantially */ - if (OldDepVer != Ver) + + // Do we know where to link the Dependency to? + if (OldDepLast == NULL) { OldDepLast = &Ver->DependsList; for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) OldDepLast = &D->NextDepends; - OldDepVer = Ver; } - // Is it a file dependency? - if (PackageName[0] == '/') - FoundFileDeps = true; - Dep->NextDepends = *OldDepLast; *OldDepLast = Dep.Index(); OldDepLast = &Dep->NextDepends; @@@ -534,22 -642,58 +642,58 @@@ return true; } /*}}}*/ + // ListParser::NewDepends - Create the environment for a new dependency /*{{{*/ + // --------------------------------------------------------------------- + /* This creates a Group and the Package to link this dependency to if + needed and handles also the caching of the old endpoint */ + bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, + const string &PackageName, + const string &Arch, + const string &Version, + unsigned int Op, + unsigned int Type) + { + pkgCache::GrpIterator Grp; + if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) + return false; + + // Locate the target package + pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == true) { + if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) + return false; + } + + // Is it a file dependency? + if (unlikely(PackageName[0] == '/')) + FoundFileDeps = true; + + /* Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) { + OldDepLast = NULL; + OldDepVer = Ver; + } + + return Owner->NewDepends(Pkg, Ver, Version, Op, Type, OldDepLast); + } + /*}}}*/ // ListParser::NewProvides - Create a Provides element /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, - const string &PackageName, + const string &PkgName, + const string &PkgArch, const string &Version) { pkgCache &Cache = Owner->Cache; // We do not add self referencing provides - if (Ver.ParentPkg().Name() == PackageName) + if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch(true)) return true; // Get a structure - unsigned long Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); - if (Provides == 0) + unsigned long const Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); + if (unlikely(Provides == 0)) return false; Cache.HeaderP->ProvidesCount++; @@@ -558,12 -702,12 +702,12 @@@ Prv->Version = Ver.Index(); Prv->NextPkgProv = Ver->ProvidesList; Ver->ProvidesList = Prv.Index(); - if (Version.empty() == false && (Prv->ProvideVersion = WriteString(Version)) == 0) + if (Version.empty() == false && unlikely((Prv->ProvideVersion = WriteString(Version)) == 0)) return false; // Locate the target package pkgCache::PkgIterator Pkg; - if (Owner->NewPackage(Pkg,PackageName) == false) + if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false)) return false; // Link it to the package @@@ -664,23 -808,16 +808,23 @@@ unsigned long pkgCacheGenerator::WriteU static bool CheckValidity(const string &CacheFile, FileIterator Start, FileIterator End,MMap **OutMap = 0) { + bool const Debug = _config->FindB("Debug::pkgCacheGen", false); // No file, certainly invalid if (CacheFile.empty() == true || FileExists(CacheFile) == false) + { + if (Debug == true) + std::clog << "CacheFile doesn't exist" << std::endl; return false; - + } + // Map it FileFd CacheF(CacheFile,FileFd::ReadOnly); SPtr Map = new MMap(CacheF,0); pkgCache Cache(Map); if (_error->PendingError() == true || Map->Size() == 0) { + if (Debug == true) + std::clog << "Errors are pending or Map is empty()" << std::endl; _error->Discard(); return false; } @@@ -690,15 -827,9 +834,15 @@@ SPtrArray Visited = new bool[Cache.HeaderP->PackageFileCount]; memset(Visited,0,sizeof(*Visited)*Cache.HeaderP->PackageFileCount); for (; Start != End; Start++) - { + { + if (Debug == true) + std::clog << "Checking PkgFile " << (*Start)->Describe() << ": "; if ((*Start)->HasPackages() == false) + { + if (Debug == true) + std::clog << "Has NO packages" << std::endl; continue; + } if ((*Start)->Exists() == false) { @@@ -706,40 -837,23 +850,40 @@@ _error->WarningE("stat",_("Couldn't stat source package list %s"), (*Start)->Describe().c_str()); #endif + if (Debug == true) + std::clog << "file doesn't exist" << std::endl; continue; } // FindInCache is also expected to do an IMS check. pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache); if (File.end() == true) + { + if (Debug == true) + std::clog << "FindInCache returned end-Pointer" << std::endl; return false; + } Visited[File->ID] = true; + if (Debug == true) + std::clog << "with ID " << File->ID << " is valid" << std::endl; } for (unsigned I = 0; I != Cache.HeaderP->PackageFileCount; I++) if (Visited[I] == false) + { + if (Debug == true) + std::clog << "File with ID" << I << " wasn't visited" << std::endl; return false; + } if (_error->PendingError() == true) { + if (Debug == true) + { + std::clog << "Validity failed because of pending errors:" << std::endl; + _error->DumpErrors(); + } _error->Discard(); return false; } @@@ -826,8 -940,7 +970,8 @@@ static bool BuildCache(pkgCacheGenerato bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, MMap **OutMap,bool AllowMem) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",24*1024*1024); + bool const Debug = _config->FindB("Debug::pkgCacheGen", false); + unsigned long const MapSize = _config->FindI("APT::Cache-Limit",24*1024*1024); vector Files; for (vector::const_iterator i = List.begin(); @@@ -841,13 -954,13 +985,13 @@@ Files.push_back (*j); } - unsigned long EndOfSource = Files.size(); + unsigned long const EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) return false; // Decide if we can write to the files.. - string CacheFile = _config->FindFile("Dir::Cache::pkgcache"); - string SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + string const CacheFile = _config->FindFile("Dir::Cache::pkgcache"); + string const SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); // Decide if we can write to the cache bool Writeable = false; @@@ -856,9 -969,7 +1000,9 @@@ else if (SrcCacheFile.empty() == false) Writeable = access(flNotFile(SrcCacheFile).c_str(),W_OK) == 0; - + if (Debug == true) + std::clog << "Do we have write-access to the cache files? " << (Writeable ? "YES" : "NO") << std::endl; + if (Writeable == false && AllowMem == false && CacheFile.empty() == false) return _error->Error(_("Unable to write to %s"),flNotFile(CacheFile).c_str()); @@@ -868,12 -979,8 +1012,12 @@@ if (CheckValidity(CacheFile,Files.begin(),Files.end(),OutMap) == true) { Progress.OverallProgress(1,1,1,_("Reading package lists")); + if (Debug == true) + std::clog << "pkgcache.bin is valid - no need to build anything" << std::endl; return true; } + else if (Debug == true) + std::clog << "pkgcache.bin is NOT valid" << std::endl; /* At this point we know we need to reconstruct the package cache, begin. */ @@@ -887,15 -994,11 +1031,15 @@@ Map = new DynamicMMap(*CacheF,MMap::Public,MapSize); if (_error->PendingError() == true) return false; + if (Debug == true) + std::clog << "Open filebased MMap" << std::endl; } else { // Just build it in memory.. Map = new DynamicMMap(0,MapSize); + if (Debug == true) + std::clog << "Open memory Map (not filebased)" << std::endl; } // Lets try the source cache. @@@ -904,18 -1007,16 +1048,18 @@@ if (CheckValidity(SrcCacheFile,Files.begin(), Files.begin()+EndOfSource) == true) { + if (Debug == true) + std::clog << "srcpkgcache.bin is valid - populate MMap with it." << std::endl; // Preload the map with the source cache FileFd SCacheF(SrcCacheFile,FileFd::ReadOnly); - unsigned long alloc = Map->RawAllocate(SCacheF.Size()); + unsigned long const alloc = Map->RawAllocate(SCacheF.Size()); if ((alloc == 0 && _error->PendingError()) || SCacheF.Read((unsigned char *)Map->Data() + alloc, SCacheF.Size()) == false) return false; TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end()); - + // Build the status cache pkgCacheGenerator Gen(Map.Get(),&Progress); if (_error->PendingError() == true) @@@ -923,11 -1024,12 +1067,14 @@@ if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; + + // FIXME: move me to a better place + Gen.FinishCache(Progress); } else { + if (Debug == true) + std::clog << "srcpkgcache.bin is NOT valid - rebuild" << std::endl; TotalSize = ComputeSize(Files.begin(),Files.end()); // Build the source cache @@@ -965,9 -1067,10 +1112,12 @@@ if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; + + // FIXME: move me to a better place + Gen.FinishCache(Progress); } + if (Debug == true) + std::clog << "Caches are ready for shipping" << std::endl; if (_error->PendingError() == true) return false; @@@ -1012,7 -1115,10 +1162,10 @@@ bool pkgMakeOnlyStatusCache(OpProgress if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; - + + // FIXME: move me to a better place + Gen.FinishCache(Progress); + if (_error->PendingError() == true) return false; *OutMap = Map.UnGuard(); diff --combined apt-pkg/sourcelist.cc index 929259961,6b7a299d6..a860c7eac --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@@ -17,6 -17,13 +17,6 @@@ #include #include - -// CNC:2003-03-03 - This is needed for ReadDir stuff. -#include -#include -#include -#include -#include /*}}}*/ using namespace std; @@@ -72,13 -79,51 +72,51 @@@ bool pkgSourceList::Type::FixupURI(stri Weird types may override this. */ bool pkgSourceList::Type::ParseLine(vector &List, const char *Buffer, - unsigned long CurLine, - string File) const + unsigned long const &CurLine, + string const &File) const { + for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces + + // Parse option field if it exists + // e.g.: [ option1=value1 option2=value2 ] + map Options; + if (Buffer != 0 && Buffer[0] == '[') + { + ++Buffer; // ignore the [ + for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces + while (*Buffer != ']') + { + // get one option, e.g. option1=value1 + string option; + if (ParseQuoteWord(Buffer,option) == false) + return _error->Error(_("Malformed line %lu in source list %s ([option] unparseable)"),CurLine,File.c_str()); + + if (option.length() < 3) + return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str()); + + size_t const needle = option.find('='); + if (needle == string::npos) + return _error->Error(_("Malformed line %lu in source list %s ([%s] is not an assignment)"),CurLine,File.c_str(), option.c_str()); + + string const key = string(option, 0, needle); + string const value = string(option, needle + 1, option.length()); + + if (key.empty() == true) + return _error->Error(_("Malformed line %lu in source list %s ([%s] has no key)"),CurLine,File.c_str(), option.c_str()); + + if (value.empty() == true) + return _error->Error(_("Malformed line %lu in source list %s ([%s] key %s has no value)"),CurLine,File.c_str(),option.c_str(),key.c_str()); + + Options[key] = value; + } + ++Buffer; // ignore the ] + for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces + } + string URI; string Dist; - string Section; - + string Section; + if (ParseQuoteWord(Buffer,URI) == false) return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str()); if (ParseQuoteWord(Buffer,Dist) == false) @@@ -93,7 -138,7 +131,7 @@@ if (ParseQuoteWord(Buffer,Section) == true) return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str()); Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); - return CreateItem(List,URI,Dist,Section); + return CreateItem(List, URI, Dist, Section, Options); } // Grab the rest of the dists @@@ -102,7 -147,7 +140,7 @@@ do { - if (CreateItem(List,URI,Dist,Section) == false) + if (CreateItem(List, URI, Dist, Section, Options) == false) return false; } while (ParseQuoteWord(Buffer,Section) == true); @@@ -239,36 -284,7 +277,7 @@@ bool pkgSourceList::ReadAppend(string F if (Parse == 0) return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str()); - // Vendor name specified - if (C[0] == '[') - { - string VendorID; - - if (ParseQuoteWord(C,VendorID) == false) - return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str()); - - if (VendorID.length() < 2 || VendorID.end()[-1] != ']') - return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str()); - VendorID = string(VendorID,1,VendorID.size()-2); - - // for (vector::const_iterator iter = VendorList.begin(); - // iter != VendorList.end(); iter++) - // { - // if ((*iter)->GetVendorID() == VendorID) - // { - // if (_config->FindB("Debug::sourceList", false)) - // std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl; - // Verifier = *iter; - // break; - // } - // } - - // if (Verifier == 0) - // return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"), - // VendorID.c_str(),CurLine,File.c_str()); - } - - if (Parse->ParseLine(SrcList,C,CurLine,File) == false) + if (Parse->ParseLine(SrcList, C, CurLine, File) == false) return false; } return true; @@@ -315,7 -331,41 +324,7 @@@ bool pkgSourceList::GetIndexes(pkgAcqui /* */ bool pkgSourceList::ReadSourceDir(string Dir) { - DIR *D = opendir(Dir.c_str()); - if (D == 0) - return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); - - vector List; - - for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) - { - if (Ent->d_name[0] == '.') - continue; - - // CNC:2003-12-02 Only accept .list files as valid sourceparts - if (flExtension(Ent->d_name) != "list") - continue; - - // Skip bad file names ala run-parts - const char *C = Ent->d_name; - for (; *C != 0; C++) - if (isalpha(*C) == 0 && isdigit(*C) == 0 - && *C != '_' && *C != '-' && *C != '.') - break; - if (*C != 0) - continue; - - // Make sure it is a file and not something else - string File = flCombine(Dir,Ent->d_name); - struct stat St; - if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) - continue; - - List.push_back(File); - } - closedir(D); - - sort(List.begin(),List.end()); + vector const List = GetListOfFilesInDir(Dir, "list", true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) diff --combined cmdline/apt-cache.cc index 286f306cd,275daa187..8323a740e --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@@ -1417,11 -1417,15 +1417,15 @@@ bool ShowPackage(CommandLine &CmdL for (const char **I = CmdL.FileList + 1; *I != 0; I++) { + // FIXME: Handle the case in which pkgname name:arch is not found pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); if (Pkg.end() == true) { - _error->Warning(_("Unable to locate package %s"),*I); - continue; + Pkg = Cache.FindPkg(*I, "any"); + if (Pkg.end() == true) { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } } ++found; @@@ -1457,16 -1461,17 +1461,17 @@@ bool ShowPkgNames(CommandLine &CmdL) { pkgCache &Cache = *GCache; - pkgCache::PkgIterator I = Cache.PkgBegin(); - bool All = _config->FindB("APT::Cache::AllNames","false"); - + pkgCache::GrpIterator I = Cache.GrpBegin(); + bool const All = _config->FindB("APT::Cache::AllNames","false"); + if (CmdL.FileList[1] != 0) { for (;I.end() != true; I++) { - if (All == false && I->VersionList == 0) + if (All == false && I->FirstPackage == 0) + continue; + if (I.FindPkg("any")->VersionList == 0) continue; - if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0) cout << I.Name() << endl; } @@@ -1477,7 -1482,9 +1482,9 @@@ // Show all pkgs for (;I.end() != true; I++) { - if (All == false && I->VersionList == 0) + if (All == false && I->FirstPackage == 0) + continue; + if (I.FindPkg("any")->VersionList == 0) continue; cout << I.Name() << endl; } @@@ -1565,19 -1572,29 +1572,29 @@@ bool Policy(CommandLine &CmdL return true; } - + + string const myArch = _config->Find("APT::Architecture"); + // Print out detailed information for each package for (const char **I = CmdL.FileList + 1; *I != 0; I++) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + pkgCache::GrpIterator Grp = Cache.FindGrp(*I); + pkgCache::PkgIterator Pkg = Grp.FindPkg("any"); if (Pkg.end() == true) { _error->Warning(_("Unable to locate package %s"),*I); continue; } - - cout << Pkg.Name() << ":" << endl; - + + for (; Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) { + if (strcmp(Pkg.Arch(),"all") == 0) + continue; + + if (myArch == Pkg.Arch()) + cout << Pkg.Name() << ":" << endl; + else + cout << Pkg.Name() << ": [" << Pkg.Arch() << "]" << endl; + // Installed version cout << _(" Installed: "); if (Pkg->CurrentVer == 0) @@@ -1620,10 -1637,11 +1637,11 @@@ if (SrcList->FindIndex(VF.File(),Indx) == false && _system->FindIndex(VF.File(),Indx) == false) return _error->Error(_("Cache is out of sync, can't x-ref a package file")); - printf(_(" %4i %s\n"),Plcy.GetPriority(VF.File()), + printf(" %4i %s\n",Plcy.GetPriority(VF.File()), Indx->Describe(true).c_str()); - } - } + } + } + } } return true; diff --combined cmdline/apt-get.cc index 34ae2fed9,343226bc3..5ef5533e2 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@@ -227,6 -227,17 +227,17 @@@ bool ShowList(ostream &out,string Title return false; } /*}}}*/ + // ShowPkg - display a package name /*{{{*/ + // --------------------------------------------------------------------- + /* Displays the package name and maybe also the architecture + if it is not the main architecture */ + string ShowPkg(pkgCache::PkgIterator const Pkg) { + string p = Pkg.Name(); + if (strcmp(Pkg.Arch(),"all") != 0 && _config->Find("APT::Architecture") != Pkg.Arch()) + p.append(":").append(Pkg.Arch()); + return p; + } + /*}}}*/ // ShowBroken - Debugging aide /*{{{*/ // --------------------------------------------------------------------- /* This prints out the names of all the packages that are broken along @@@ -258,8 -269,8 +269,8 @@@ void ShowBroken(ostream &out,CacheFile } // Print out each package and the failed dependencies - out <<" " << I.Name() << ":"; - unsigned Indent = strlen(I.Name()) + 3; + out << " " << ShowPkg(I) << " :"; + unsigned const Indent = ShowPkg(I).size() + 3; bool First = true; pkgCache::VerIterator Ver; @@@ -312,7 -323,7 +323,7 @@@ out << ' ' << End.DepType() << ": "; FirstOr = false; - out << Start.TargetPkg().Name(); + out << ShowPkg(Start.TargetPkg()); // Show a quick summary of the version requirements if (Start.TargetVer() != 0) @@@ -374,7 -385,9 +385,9 @@@ void ShowNew(ostream &out,CacheFile &Ca { pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].NewInstall() == true) { - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CandVersion) + "\n"; } } @@@ -396,10 -409,12 +409,12 @@@ void ShowDel(ostream &out,CacheFile &Ca pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].Delete() == true) { + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) - List += string(I.Name()) + "* "; + List += ShowPkg(I) + "* "; else - List += string(I.Name()) + " "; + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CandVersion)+ "\n"; } @@@ -424,7 -439,7 +439,7 @@@ void ShowKept(ostream &out,CacheFile &C I->CurrentVer == 0 || Cache[I].Delete() == true) continue; - List += string(I.Name()) + " "; + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } ShowList(out,_("The following packages have been kept back:"),List,VersionsList); @@@ -444,8 -459,10 +459,10 @@@ void ShowUpgraded(ostream &out,CacheFil // Not interesting if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) continue; - - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } ShowList(out,_("The following packages will be upgraded:"),List,VersionsList); @@@ -465,8 -482,10 +482,10 @@@ bool ShowDowngraded(ostream &out,CacheF // Not interesting if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true) continue; - - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList); @@@ -484,7 -503,7 +503,7 @@@ bool ShowHold(ostream &out,CacheFile &C pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() && I->SelectedState == pkgCache::State::Hold) { - List += string(I.Name()) + " "; + List += ShowPkg(I) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } } @@@ -518,7 -537,7 +537,7 @@@ bool ShowEssential(ostream &out,CacheFi if (Added[I->ID] == false) { Added[I->ID] = true; - List += string(I.Name()) + " "; + List += ShowPkg(I) + " "; //VersionsList += string(Cache[I].CurVersion) + "\n"; ??? } } @@@ -566,6 -585,9 +585,9 @@@ void Stats(ostream &out,pkgDepCache &De unsigned long ReInstall = 0; for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++) { + if (pkgCache::VerIterator(Dep, Dep[I].CandidateVer).Pseudo() == true) + continue; + if (Dep[I].NewInstall() == true) Install++; else @@@ -1247,153 -1269,131 +1269,153 @@@ pkgSrcRecords::Parser *FindSrc(const ch pkgSrcRecords &SrcRecs,string &Src, pkgDepCache &Cache) { - string VerTag; - string DefRel = _config->Find("APT::Default-Release"); - string TmpSrc = Name; - const size_t found = TmpSrc.find_last_of("/="); - - // extract the version/release from the pkgname - if (found != string::npos) { - if (TmpSrc[found] == '/') - DefRel = TmpSrc.substr(found+1); - else - VerTag = TmpSrc.substr(found+1); - TmpSrc = TmpSrc.substr(0,found); - } - - /* Lookup the version of the package we would install if we were to - install a version and determine the source package name, then look - in the archive for a source package of the same name. */ - bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); - if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || DefRel.empty() == false) { - // we have a default release, try to locate the pkg. we do it like - // this because GetCandidateVer() will not "downgrade", that means - // "apt-get source -t stable apt" won't work on a unstable system - for (pkgCache::VerIterator Ver = Pkg.VersionList(); - Ver.end() == false; Ver++) { - for (pkgCache::VerFileIterator VF = Ver.FileList(); - VF.end() == false; VF++) { - /* If this is the status file, and the current version is not the - version in the status file (ie it is not installed, or somesuch) - then it is not a candidate for installation, ever. This weeds - out bogus entries that may be due to config-file states, or - other. */ - if ((VF.File()->Flags & pkgCache::Flag::NotSource) == - pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver) - continue; - - // We match against a concrete version (or a part of this version) - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0) - continue; - - // or we match against a release - if(VerTag.empty() == false || - (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) { - pkgRecords::Parser &Parse = Recs.Lookup(VF); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); - break; - } - } - } - if (Src.empty() == true) { - if (VerTag.empty() == false) - _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); - else - _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); - VerTag.clear(); - DefRel.clear(); - } - } - if (VerTag.empty() == true && DefRel.empty() == true) { - // if we don't have a version or default release, use the CandidateVer to find the Source - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); - if (Ver.end() == false) { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - VerTag = Parse.SourceVer(); - } - } - } - - if (Src.empty() == true) - Src = TmpSrc; - else { - /* if we have a source pkg name, make sure to only search - for srcpkg names, otherwise apt gets confused if there - is a binary package "pkg1" and a source package "pkg1" - with the same name but that comes from different packages */ - MatchSrcOnly = true; - if (Src != TmpSrc) { - ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str()); - } - } - - // The best hit - pkgSrcRecords::Parser *Last = 0; - unsigned long Offset = 0; - string Version; - - /* Iterate over all of the hits, which includes the resulting - binary packages in the search */ - pkgSrcRecords::Parser *Parse; - while (true) { - SrcRecs.Restart(); - while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) { - const string Ver = Parse->Version(); - - // Ignore all versions which doesn't fit - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0) - continue; - - // Newer version or an exact match? Save the hit - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; - } - - // was the version check above an exact match? If so, we don't need to look further - if (VerTag.empty() == false && VerTag.size() == Ver.size()) - break; - } - if (Last != 0 || VerTag.empty() == true) - break; - //if (VerTag.empty() == false && Last == 0) - _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); - VerTag.clear(); - } - - if (Last == 0 || Last->Jump(Offset) == false) - return 0; - - return Last; + string VerTag; + string DefRel = _config->Find("APT::Default-Release"); + string TmpSrc = Name; + + // extract the version/release from the pkgname + const size_t found = TmpSrc.find_last_of("/="); + if (found != string::npos) { + if (TmpSrc[found] == '/') + DefRel = TmpSrc.substr(found+1); + else + VerTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + + /* Lookup the version of the package we would install if we were to + install a version and determine the source package name, then look + in the archive for a source package of the same name. */ + bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); + const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); + if (MatchSrcOnly == false && Pkg.end() == false) + { + if(VerTag.empty() == false || DefRel.empty() == false) + { + // we have a default release, try to locate the pkg. we do it like + // this because GetCandidateVer() will not "downgrade", that means + // "apt-get source -t stable apt" won't work on a unstable system + for (pkgCache::VerIterator Ver = Pkg.VersionList(); + Ver.end() == false; Ver++) + { + for (pkgCache::VerFileIterator VF = Ver.FileList(); + VF.end() == false; VF++) + { + /* If this is the status file, and the current version is not the + version in the status file (ie it is not installed, or somesuch) + then it is not a candidate for installation, ever. This weeds + out bogus entries that may be due to config-file states, or + other. */ + if ((VF.File()->Flags & pkgCache::Flag::NotSource) == + pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver) + continue; + + // We match against a concrete version (or a part of this version) + if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0) + continue; + + // or we match against a release + if(VerTag.empty() == false || + (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || + (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) + { + pkgRecords::Parser &Parse = Recs.Lookup(VF); + Src = Parse.SourcePkg(); + // no SourcePkg name, so it is the "binary" name + if (Src.empty() == true) + Src = TmpSrc; + // no Version, so we try the Version of the SourcePkg - + // and after that the version of the binary package + if (VerTag.empty() == true) + VerTag = Parse.SourceVer(); + if (VerTag.empty() == true) + VerTag = Ver.VerStr(); + break; + } + } + if (Src.empty() == false) + break; + } + if (Src.empty() == true) + { + // Sources files have no codename information + if (VerTag.empty() == true && DefRel.empty() == false) + _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); + DefRel.clear(); + } + } + if (Src.empty() == true) + { + // if we don't have found a fitting package yet so we will + // choose a good candidate and proceed with that. + // Maybe we will find a source later on with the right VerTag + pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + if (Ver.end() == false) + { + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + Src = Parse.SourcePkg(); + if (VerTag.empty() == true) + VerTag = Parse.SourceVer(); + } + } + } + + if (Src.empty() == true) + Src = TmpSrc; + else + { + /* if we have a source pkg name, make sure to only search + for srcpkg names, otherwise apt gets confused if there + is a binary package "pkg1" and a source package "pkg1" + with the same name but that comes from different packages */ + MatchSrcOnly = true; + if (Src != TmpSrc) + { + ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str()); + } + } + + // The best hit + pkgSrcRecords::Parser *Last = 0; + unsigned long Offset = 0; + string Version; + + /* Iterate over all of the hits, which includes the resulting + binary packages in the search */ + pkgSrcRecords::Parser *Parse; + while (true) + { + SrcRecs.Restart(); + while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) + { + const string Ver = Parse->Version(); + + // Ignore all versions which doesn't fit + if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0) + continue; + + // Newer version or an exact match? Save the hit + if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; + } + + // was the version check above an exact match? If so, we don't need to look further + if (VerTag.empty() == false && VerTag.size() == Ver.size()) + break; + } + if (Last != 0 || VerTag.empty() == true) + break; + //if (VerTag.empty() == false && Last == 0) + _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); + VerTag.clear(); + } + + if (Last == 0 || Last->Jump(Offset) == false) + return 0; + + return Last; } /*}}}*/ // DoUpdate - Update the package lists /*{{{*/ @@@ -1776,8 -1776,7 +1798,8 @@@ bool DoInstall(CommandLine &CmdL if(!Remove && Cache[Pkg].Install() == false && (Cache[Pkg].Flags & pkgCache::Flag::Auto) && - _config->FindB("APT::Get::ReInstall",false) == false) + _config->FindB("APT::Get::ReInstall",false) == false && + _config->FindB("APT::Get::Download-Only",false) == false) { ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.Name()); diff --combined debian/changelog index df16a69dd,26b3e8c1e..a81a2abd0 --- a/debian/changelog +++ b/debian/changelog @@@ -1,150 -1,4 +1,153 @@@ -apt (0.7.25) UNRELEASED; urgency=low +apt (0.7.26) UNRELEASED; urgency=low + + [ David Kalnischkies ] + * [BREAK] add possibility to download and use multiply + Translation files, configurable with Acquire::Translation + (Closes: #444222, #448216, #550564) ++ * [BREAK] merge MultiArch-ABI. We don't support MultiArch, ++ but we support the usage of the new ABI so libapt users ++ can start to prepare for MultiArch (Closes: #536029) + * Ignore :qualifiers after package name in build dependencies + for now as long we don't understand them (Closes: #558103) + * apt-pkg/contrib/mmap.{cc,h}: + - extend it to have a growable flag - unused now but maybe... + * apt-pkg/pkgcache.h: + - use long instead of short for {Ver,Desc}File size, + patch from Víctor Manuel Jáquez Leal, thanks! (Closes: #538917) + * apt-pkg/acquire-item.cc: + - allow also to skip the last patch if target is reached, + thanks Bernhard R. Link! (Closes: #545699) + * ftparchive/writer.{cc,h}: + - add APT::FTPArchive::AlwaysStat to disable the too aggressive + caching if versions are build multiply times (not recommend) + Patch by Christoph Goehre, thanks! (Closes: #463260) + + [ Ivan Masár ] + * Slovak translation update. Closes: #568294 + + -- David Kalnischkies Sat, 13 Feb 2010 01:42:50 +0100 + +apt (0.7.25.3) unstable; urgency=low + + [ Christian Perrier ] + * Italian translation update. Closes: #567532 + + [ David Kalnischkies ] + * apt-pkg/contrib/macros.h: + - install the header system.h with a new name to be able to use + it in other headers (Closes: #567662) + * cmdline/acqprogress.cc: + - Set Mode to Medium so that the correct prefix is used. + Thanks Stefan Haller for the patch! (Closes: #567304 LP: #275243) + * ftparchive/writer.cc: + - generate sha1 and sha256 checksums for dsc (Closes: #567343) + * cmdline/apt-get.cc: + - don't mark as manually if in download only (Closes: #468180) + + -- Michael Vogt Mon, 01 Feb 2010 18:41:15 +0100 + +apt (0.7.25.2) unstable; urgency=low + + [ Michael Vogt ] + * apt-pkg/contrib/cdromutl.cc: + - fix UnmountCdrom() fails, give it a bit more time and try + the umount again + * apt-pkg/cdrom.cc: + - fix crash in pkgUdevCdromDevices + * methods/cdrom.cc: + - fixes in multi cdrom setup code (closes: #549312) + - add new "Acquire::cdrom::AutoDetect" config that enables/disables + the dlopen of libudev for automatic cdrom detection. Off by default + currently, feedback/testing welcome + * cmdline/apt-cdrom.cc: + - add new --auto-detect option that uses libudev to figure out + the cdrom/mount-point + * cmdline/apt-mark: + - merge fix from Gene Cash that supports markauto for + packages that are not in the extended_states file yet + (closes: #534920) + * ftparchive/writer.{cc,h}: + - merge crash fix for apt-ftparchive on hurd, thanks to + Samuel Thibault for the patch (closes: #566664) + + [ David Kalnischkies ] + * apt-pkg/contrib/fileutl.cc: + - Fix the newly introduced method GetListOfFilesInDir to not + accept every file if no extension is enforced + (= restore old behaviour). (Closes: #565213) + * apt-pkg/policy.cc: + - accept also partfiles with "pref" file extension as valid + * apt-pkg/contrib/configuration.cc: + - accept also partfiles with "conf" file extension as valid + * doc/apt.conf.5.xml: + - reorder description and split out syntax + - add partfile name convention (Closes: #558348) + * doc/apt_preferences.conf.5.xml: + - describe partfile name convention also here + * apt-pkg/deb/dpkgpm.cc: + - don't segfault if term.log file can't be opened. + Thanks Sam Brightman for the patch! (Closes: #475770) + * doc/*: + - replace the per language addendum with a global addendum + - add a explanation why translations include (maybe) english + parts to the new global addendum (Closes: #561636) + * apt-pkg/contrib/strutl.cc: + - fix malloc asseration fail with ja_JP.eucJP locale in + apt-cache search. Thanks Kusanagi Kouichi! (Closes: #548884) + + [ Christian Perrier ] + * French translation update + + -- Michael Vogt Wed, 27 Jan 2010 16:16:10 +0100 + +apt (0.7.25.1) unstable; urgency=low + + [ Christian Perrier ] + * French manpage translation update + * Russian translation update by Yuri Kozlov + Closes: #564171 + + [Chris Leick] + * spot & fix various typos in all manpages + * German manpage translation update + + [ David Kalnischkies ] + * cmdline/apt-cache.cc: + - remove translatable marker from the "%4i %s\n" string + * buildlib/po4a_manpage.mak: + - instruct debiandoc to build files with utf-8 encoding + * buildlib/tools.m4: + - fix some warning from the buildtools + * apt-pkg/acquire-item.cc: + - add configuration PDiffs::Limit-options to not download + too many or too big patches (Closes: #554349) + * debian/control: + - let all packages depend on ${misc:Depends} + * share/*-archive.gpg: + - remove the horrible outdated files. We already depend on + the keyring so we don't need to ship our own version + * cmdline/apt-key: + - errors out if wget is not installed (Closes: #545754) + - add --keyring option as we have now possibly many + * methods/gpgv.cc: + - pass all keyrings (TrustedParts) to gpgv instead of + using only one trusted.gpg keyring (Closes: #304846) + * methods/https.cc: + - finally merge the rest of the patchset from Arnaud Ebalard + with the CRL and Issuers options, thanks! (Closes: #485963) + * apt-pkg/deb/debindexfile.cc, apt-pkg/pkgcachegen.cc: + - add debug option Debug::pkgCacheGen + + [ Michael Vogt ] + * cmdline/apt-get.cc: + - merge fix for apt-get source pkg=version regression + (closes: #561971) + * po/ru.po: + - merged updated ru.po, thanks to Yuri Kozlov (closes: #564171) + + -- Michael Vogt Sat, 09 Jan 2010 21:52:36 +0100 + +apt (0.7.25) unstable; urgency=low [ Christian Perrier ] * Fix apt-ftparchive(1) wrt description of the "-o" option. @@@ -159,42 -13,17 +162,42 @@@ Closes: #548571 * German translation update by Holger Wansing Closes: #551534 - * German translation of manpages by Chris Leick - Closes: #552606 * Italian translation update by Milo Casagrande Closes: #555797 + * Simplified Chinese translation update by Aron Xu + Closes: #558737 + * Slovak translation update by Ivan Masár + Closes: #559277 + + [ Michael Vogt ] + * apt-pkg/packagemanager.cc: + - add output about pre-depends configuring when debug::pkgPackageManager + is used + * methods/https.cc: + - fix incorrect use of CURLOPT_TIMEOUT, closes: #497983, LP: #354972 + thanks to Brian Thomason for the patch + * merge lp:~mvo/apt/netrc branch, this adds support for a + /etc/apt/auth.conf that can be used to store username/passwords + in a "netrc" style file (with the extension that it supports "/" + in a machine definition). Based on the maemo git branch (Closes: #518473) + (thanks also to Jussi Hakala and Julian Andres Klode) + * apt-pkg/deb/dpkgpm.cc: + - add "purge" to list of known actions + * apt-pkg/init.h: + - add compatibility with old ABI name until the next ABI break + * merge segfault fix from Mario Sanchez Prada, many thanks + (closes: #561109) + + [ Brian Murray ] + * apt-pkg/depcache.cc, apt-pkg/indexcopy.cc: + - typo fix (LP: #462328) + + [ Loïc Minier ] + * cmdline/apt-key: + - Emit a warning if removed keys keyring is missing and skip associated + checks (LP: #218971) [ David Kalnischkies ] - * [BREAK] add possibility to download and use multiply - Translation files, configurable with Acquire::Translation - (Closes: #444222, #448216, #550564) - * Ignore :qualifiers after package name in build dependencies - for now as long we don't understand them (Closes: #558103) * apt-pkg/packagemanager.cc: - better debug output for ImmediateAdd with depth and why - improve the message shown for failing immediate configuration @@@ -208,7 -37,7 +211,7 @@@ * doc/apt-mark.8.xml: - correct showauto synopsis, thanks Andrew Schulman (Closes: #551440) * cmdline/apt-get.cc: - - source should displays his final pkg pick (Closes: #249383, #550952) + - source should display his final pkg pick (Closes: #249383, #550952) - source doesn't need the complete version for match (Closes: #245250) - source ignores versions/releases if not available (Closes: #377424) - only warn if (free) space overflows (Closes: #522238) @@@ -230,42 -59,46 +233,42 @@@ - bump policy to 3.8.3 as we have no outdated manpages anymore * debian/NEWS: - fix a typo in 0.7.24: Allready -> Already (Closes: #557674) + * ftparchive/writer.{cc,h}: + - add APT::FTPArchive::LongDescription to be able to disable them + * apt-pkg/deb/debsrcrecords.cc: + - use "diff" filetype for .debian.tar.* files (Closes: #554898) * methods/rred.cc: - rewrite to be able to handle even big patch files - adopt optional mmap+iovec patch from Morten Hustveit (Closes: #463354) which should speed up a bit. Thanks! - * apt-pkg/contrib/mmap.{cc,h}: - - extend it to have a growable flag - unused now but maybe... - * apt-pkg/pkgcache.h: - - use long instead of short for {Ver,Desc}File size, - patch from Víctor Manuel Jáquez Leal, thanks! (Closes: #538917) - * apt-pkg/acquire-item.cc: - - allow also to skip the last patch if target is reached, - thanks Bernhard R. Link! (Closes: #545699) - * cmdline/apt-mark: - - print an error if a new state file can't be created, - thanks Carl Chenet! (Closes: #521289) - - print an error and exit if python-apt is not installed, - thanks Carl Chenet! (Closes: #521284) * methods/http{,s}.cc - add config setting for User-Agent to the Acquire group, thanks Timothy J. Miller! (Closes: #355782) - add https options which default to http ones (Closes: #557085) - * ftparchive/writer.{cc,h}: - - add APT::FTPArchive::LongDescription to be able to disable them - - add APT::FTPArchive::AlwaysStat to disable the too aggressive - caching if versions are build multiply times (not recommend) - Patch by Christoph Goehre, thanks! (Closes: #463260) - * ftparchive/*: - - fix a few typos in strings, comments and manpage, - thanks Karl Goetz! (Closes: #558757) - * apt-pkg/deb/debsrcrecords.cc: - - use "diff" filetype for .debian.tar.* files (Closes: #554898) * debian/apt.cron.daily: - check cache size even if we do nothing else otherwise, thanks Francesco Poli for patch(s) and patience! (Closes: #459344) + * ftparchive/*: + - fix a few typos in strings, comments and manpage, + thanks Karl Goetz! (Closes: #558757) + + [ Carl Chenet ] + * cmdline/apt-mark: + - print an error if a new state file can't be created + (Closes: #521289) and + - exit nicely if python-apt is not installed (Closes: #521284) [ Chris Leick ] + * doc/de: German translation of manpages (Closes: #552606) * doc/ various manpages: - correct various errors, typos and oddities (Closes: #552535) * doc/apt-secure.8.xml: - replace literal with emphasis tags in Archive configuration + * doc/apt-ftparchive.1.xml: + - remove informalexample tag which hides the programlisting + * doc/apt-get.8.xml: + - change equivalent "for" to "to the" (purge command) + - clarify --fix-broken sentence about specifying packages [ Eugene V. Lyubimkin ] * apt-pkg/contib/strutl.h @@@ -280,12 -113,13 +283,12 @@@ - Restrict option names to alphanumerical characters and "/-:._+". - Deprecate #include, we have apt.conf.d nowadays which should be sufficient. - * methods/https.cc: - - Add support for authentication using netrc (Closes: #518473), patch - by Jussi Hakala . * ftparchive/apt-ftparchive.cc: - Call setlocale() so translations are actually used. + * debian/apt.conf.autoremove: + - Add kfreebsd-image-* to the list (Closes: #558803) - -- Michael Vogt Tue, 29 Sep 2009 15:51:34 +0200 + -- Michael Vogt Tue, 15 Dec 2009 09:21:55 +0100 apt (0.7.24) unstable; urgency=low