From: Michael Vogt Date: Sat, 9 Jun 2007 00:08:36 +0000 (+0200) Subject: * merged apt--no-pragma X-Git-Tag: 0.7.24ubuntu1~184 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/8d4b705ab0ef3a0de13a9ff9f1aa47f09112f374?hp=-c * merged apt--no-pragma --- 8d4b705ab0ef3a0de13a9ff9f1aa47f09112f374 diff --combined apt-pkg/acquire-item.cc index 04f0bb943,0c1aad485..c42c8af24 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@@ -13,9 -13,6 +13,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/acquire-item.h" - #endif #include #include #include @@@ -63,7 -60,6 +60,7 @@@ void pkgAcquire::Item::Failed(string Me { Status = StatIdle; ErrorText = LookupTag(Message,"Message"); + UsedMirror = LookupTag(Message,"UsedMirror"); if (QueueCounter <= 1) { /* This indicates that the file is not available right now but might @@@ -76,17 -72,10 +73,17 @@@ Dequeue(); return; } - + Status = StatError; Dequeue(); } + + // report mirror failure back to LP if we actually use a mirror + string FailReason = LookupTag(Message, "FailReason"); + if(FailReason.size() != 0) + ReportMirrorFailure(FailReason); + else + ReportMirrorFailure(ErrorText); } /*}}}*/ // Acquire::Item::Start - Item has begun to download /*{{{*/ @@@ -108,7 -97,6 +105,7 @@@ void pkgAcquire::Item::Done(string Mess { // We just downloaded something.. string FileName = LookupTag(Message,"Filename"); + UsedMirror = LookupTag(Message,"UsedMirror"); if (Complete == false && FileName == DestFile) { if (Owner->Log != 0) @@@ -117,6 -105,7 +114,6 @@@ if (FileSize == 0) FileSize= Size; - Status = StatDone; ErrorText = string(); Owner->Dequeue(this); @@@ -139,49 -128,6 +136,49 @@@ void pkgAcquire::Item::Rename(string Fr } /*}}}*/ +void pkgAcquire::Item::ReportMirrorFailure(string FailCode) +{ + // we only act if a mirror was used at all + if(UsedMirror.empty()) + return; +#if 0 + std::cerr << "\nReportMirrorFailure: " + << UsedMirror + << " Uri: " << DescURI() + << " FailCode: " + << FailCode << std::endl; +#endif + const char *Args[40]; + unsigned int i = 0; + string report = _config->Find("Methods::Mirror::ProblemReporting", + "/usr/lib/apt/apt-report-mirror-failure"); + if(!FileExists(report)) + return; + Args[i++] = report.c_str(); + Args[i++] = UsedMirror.c_str(); + Args[i++] = DescURI().c_str(); + Args[i++] = FailCode.c_str(); + Args[i++] = NULL; + pid_t pid = ExecFork(); + if(pid < 0) + { + _error->Error("ReportMirrorFailure Fork failed"); + return; + } + else if(pid == 0) + { + execvp(Args[0], (char**)Args); + std::cerr << "Could not exec " << Args[0] << std::endl; + _exit(100); + } + if(!ExecWait(pid, "report-mirror-failure")) + { + _error->Warning("Couldn't report problem to '%s'", + _config->Find("Methods::Mirror::ProblemReporting").c_str()); + } +} + + // AcqIndex::AcqIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The package file is added to the queue and a second class is @@@ -227,13 -173,13 +224,13 @@@ string pkgAcqIndex::Custom600Headers( struct stat Buf; if (stat(Final.c_str(),&Buf) != 0) return "\nIndex-File: true"; - return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) { + // no .bz2 found, retry with .gz if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") { Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz"; @@@ -245,15 -191,9 +242,15 @@@ Complete = false; Dequeue(); return; + } + + // on decompression failure, remove bad versions in partial/ + if(Decompression && Erase) { + string s = _config->FindDir("Dir::State::lists") + "partial/"; + s += URItoFileName(RealURI); + unlink(s.c_str()); } - Item::Failed(Message,Cnf); } @@@ -292,7 -232,6 +289,7 @@@ void pkgAcqIndex::Done(string Message,u Status = StatAuthError; ErrorText = _("MD5Sum mismatch"); Rename(DestFile,DestFile + ".FAILED"); + ReportMirrorFailure("HashChecksumFailure"); return; } // Done, move it into position @@@ -366,35 -305,6 +363,35 @@@ Mode = decompProg; } +// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* The Translation file is added to the queue */ +pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, + string URI,string URIDesc,string ShortDesc) : + pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, "", "") +{ +} + + /*}}}*/ +// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + if (Cnf->LocalOnly == true || + StringToBool(LookupTag(Message,"Transient-Failure"),false) == false) + { + // Ignore this + Status = StatDone; + Complete = false; + Dequeue(); + return; + } + + Item::Failed(Message,Cnf); +} + /*}}}*/ + pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, string URI,string URIDesc,string ShortDesc, string MetaIndexURI, string MetaIndexURIDesc, @@@ -408,9 -318,8 +405,9 @@@ DestFile = _config->FindDir("Dir::State::lists") + "partial/"; DestFile += URItoFileName(URI); - // remove any partial downloaded sig-file. it may confuse proxies - // and is too small to warrant a partial download anyway + // remove any partial downloaded sig-file in partial/. + // it may confuse proxies and is too small to warrant a + // partial download anyway unlink(DestFile.c_str()); // Create the item @@@ -477,22 -386,17 +474,22 @@@ void pkgAcqMetaSig::Done(string Message /*}}}*/ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) { + string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); // if we get a network error we fail gracefully - if(LookupTag(Message,"FailReason") == "Timeout" || - LookupTag(Message,"FailReason") == "TmpResolveFailure" || - LookupTag(Message,"FailReason") == "ConnectionRefused") { + if(Status == StatTransientNetworkError) + { Item::Failed(Message,Cnf); + // move the sigfile back on network failures (and re-authenticated?) + if(FileExists(DestFile)) + Rename(DestFile,Final); + + // set the status back to , Item::Failed likes to reset it + Status = pkgAcquire::Item::StatTransientNetworkError; return; } // Delete any existing sigfile when the acquire failed - string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); unlink(Final.c_str()); // queue a pkgAcqMetaIndex with no sigfile @@@ -730,7 -634,7 +727,7 @@@ bool pkgAcqMetaIndex::VerifyVendor(stri // check for missing sigs (that where not fatal because otherwise we had // bombed earlier) string missingkeys; - string msg = _("There are no public key available for the " + string msg = _("There is no public key available for the " "following key IDs:\n"); pos = Message.find("NO_PUBKEY "); if (pos != std::string::npos) @@@ -815,7 -719,6 +812,7 @@@ void pkgAcqMetaIndex::Failed(string Mes } // gpgv method failed + ReportMirrorFailure("GPGFailure"); _error->Warning("GPG error: %s: %s", Desc.Description.c_str(), LookupTag(Message,"Message").c_str()); diff --combined apt-pkg/acquire-item.h index f659bb459,b47e198d8..1885f7beb --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@@ -9,8 -9,8 +9,8 @@@ the Owner Acquire class. Derived classes will then call QueueURI to register all the URI's they wish to fetch at the initial moment. - Two item classes are provided to provide functionality for downloading - of Index files and downloading of Packages. + Three item classes are provided to provide functionality for + downloading of Index, Translation and Packages files. A Archive class is provided for downloading .deb files. It does Md5 checking and source location as well as a retry algorithm. @@@ -27,9 -27,6 +27,6 @@@ #include #include - #ifdef __GNUG__ - #pragma interface "apt-pkg/acquire-item.h" - #endif // Item to acquire class pkgAcquire::Item @@@ -48,8 -45,7 +45,8 @@@ public: // State of the item - enum {StatIdle, StatFetching, StatDone, StatError, StatAuthError} Status; + enum {StatIdle, StatFetching, StatDone, StatError, + StatAuthError, StatTransientNetworkError} Status; string ErrorText; unsigned long FileSize; unsigned long PartialSize; @@@ -57,7 -53,6 +54,7 @@@ unsigned long ID; bool Complete; bool Local; + string UsedMirror; // Number of queues we are inserted into unsigned int QueueCounter; @@@ -80,9 -75,6 +77,9 @@@ pkgAcquire *GetOwner() {return Owner;}; virtual bool IsTrusted() {return false;}; + // report mirror problems + void ReportMirrorFailure(string FailCode); + Item(pkgAcquire *Owner); virtual ~Item(); }; @@@ -112,16 -104,6 +109,16 @@@ class pkgAcqIndex : public pkgAcquire:: string ShortDesct, string ExpectedMD5, string compressExt=""); }; +// Item class for translated package index files +class pkgAcqIndexTrans : public pkgAcqIndex +{ + public: + + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc, + string ShortDesct); +}; + struct IndexTarget { string URI; diff --combined apt-pkg/acquire-method.cc index 180b52ad7,3360a8eae..dfadf800f --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@@ -15,9 -15,6 +15,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/acquire-method.h" - #endif #include #include #include @@@ -99,11 -96,12 +96,11 @@@ void pkgAcqMethod::Fail(string Err,boo } char S[1024]; + char *End = S; if (Queue != 0) { - snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n" - "Message: %s %s\n",Queue->Uri.c_str(),Err.c_str(), - FailExtra.c_str()); - + End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n" + "Message: %s %s\n",Queue->Uri.c_str(), Err.c_str(), IP.c_str()); // Dequeue FetchItem *Tmp = Queue; Queue = Queue->Next; @@@ -112,14 -110,10 +109,14 @@@ QueueBack = Queue; } else - snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: \n" - "Message: %s %s\n",Err.c_str(), - FailExtra.c_str()); - + { + End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: \n" + "Message: %s\n",Err.c_str()); + } + if(FailReason.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"FailReason: %s\n",FailReason.c_str()); + if (UsedMirror.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str()); // Set the transient flag if (Transient == true) strcat(S,"Transient-Failure: true\n\n"); @@@ -185,8 -179,6 +182,8 @@@ void pkgAcqMethod::URIDone(FetchResult End += snprintf(End,sizeof(S)-50 - (End - S),"MD5-Hash: %s\n",Res.MD5Sum.c_str()); if (Res.SHA1Sum.empty() == false) End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str()); + if (UsedMirror.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str()); if (Res.GPGVOutput.size() > 0) End += snprintf(End,sizeof(S)-50 - (End - S),"GPGVOutput:\n"); for (vector::iterator I = Res.GPGVOutput.begin(); diff --combined apt-pkg/acquire-method.h index 20691cc2c,1c0b9f67c..4e72d7094 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@@ -16,9 -16,6 +16,6 @@@ #include #include - #ifdef __GNUG__ - #pragma interface "apt-pkg/acquire-method.h" - #endif class Hashes; class pkgAcqMethod @@@ -54,9 -51,7 +51,9 @@@ vector Messages; FetchItem *Queue; FetchItem *QueueBack; - string FailExtra; + string FailReason; + string UsedMirror; + string IP; // Handlers for messages virtual bool Configuration(string Message); @@@ -65,14 -60,14 +62,14 @@@ // Outgoing messages void Fail(bool Transient = false); inline void Fail(const char *Why, bool Transient = false) {Fail(string(Why),Transient);}; - void Fail(string Why, bool Transient = false); - void URIStart(FetchResult &Res); - void URIDone(FetchResult &Res,FetchResult *Alt = 0); + virtual void Fail(string Why, bool Transient = false); + virtual void URIStart(FetchResult &Res); + virtual void URIDone(FetchResult &Res,FetchResult *Alt = 0); + bool MediaFail(string Required,string Drive); virtual void Exit() {}; public: - enum CnfFlags {SingleInstance = (1<<0), Pipeline = (1<<1), SendConfig = (1<<2), LocalOnly = (1<<3), NeedsCleanup = (1<<4), @@@ -82,8 -77,7 +79,8 @@@ void Status(const char *Format,...); int Run(bool Single = false); - inline void SetFailExtraMsg(string Msg) {FailExtra = Msg;}; + inline void SetFailReason(string Msg) {FailReason = Msg;}; + inline void SetIP(string aIP) {IP = aIP;}; pkgAcqMethod(const char *Ver,unsigned long Flags = 0); virtual ~pkgAcqMethod() {}; diff --combined apt-pkg/acquire-worker.cc index 8ab67778b,063aa5ed7..25d40ef54 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@@ -12,9 -12,6 +12,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/acquire-worker.h" - #endif #include #include #include @@@ -307,13 -304,6 +304,13 @@@ bool pkgAcquire::Worker::RunMessages( pkgAcquire::Item *Owner = Itm->Owner; pkgAcquire::ItemDesc Desc = *Itm; OwnerQ->ItemDone(Itm); + + // set some status + if(LookupTag(Message,"FailReason") == "Timeout" || + LookupTag(Message,"FailReason") == "TmpResolveFailure" || + LookupTag(Message,"FailReason") == "ConnectionRefused") + Owner->Status = pkgAcquire::Item::StatTransientNetworkError; + Owner->Failed(Message,Config); ItemDone(); diff --combined apt-pkg/acquire.cc index e1dccf25a,ed78ec971..cbd67055d --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@@ -13,9 -13,6 +13,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/acquire.h" - #endif #include #include #include @@@ -193,9 -190,9 +190,9 @@@ void pkgAcquire::Enqueue(ItemDesc &Item Item.Owner->Status = Item::StatIdle; // Queue it into the named queue - I->Enqueue(Item); - ToFetch++; - + if(I->Enqueue(Item)) + ToFetch++; + // Some trace stuff if (Debug == true) { @@@ -549,17 -546,11 +546,17 @@@ pkgAcquire::Queue::~Queue( // Queue::Enqueue - Queue an item to the queue /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgAcquire::Queue::Enqueue(ItemDesc &Item) +bool pkgAcquire::Queue::Enqueue(ItemDesc &Item) { QItem **I = &Items; - for (; *I != 0; I = &(*I)->Next); - + // move to the end of the queue and check for duplicates here + for (; *I != 0; I = &(*I)->Next) + if (Item.URI == (*I)->URI) + { + Item.Owner->Status = Item::StatDone; + return false; + } + // Create a new item QItem *Itm = new QItem; *Itm = Item; @@@ -569,7 -560,6 +566,7 @@@ Item.Owner->QueueCounter++; if (Items->Next == 0) Cycle(); + return true; } /*}}}*/ // Queue::Dequeue - Remove an item from the queue /*{{{*/ diff --combined apt-pkg/acquire.h index 1d5daf12e,6e836ac49..5fbc5c867 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@@ -38,9 -38,6 +38,6 @@@ using std::vector; using std::string; - #ifdef __GNUG__ - #pragma interface "apt-pkg/acquire.h" - #endif #include #include @@@ -173,7 -170,7 +170,7 @@@ class pkgAcquire::Queu public: // Put an item into this queue - void Enqueue(ItemDesc &Item); + bool Enqueue(ItemDesc &Item); bool Dequeue(Item *Owner); // Find a Queued item diff --combined apt-pkg/algorithms.cc index bd8147291,3ac98216b..402d01d69 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@@ -14,18 -14,13 +14,15 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/algorithms.h" - #endif #include #include #include +#include #include + #include - +#include #include /*}}}*/ using namespace std; @@@ -102,7 -97,6 +99,7 @@@ bool pkgSimulate::Install(PkgIterator i DepIterator End; D.GlobOr(Start,End); if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes || End->Type == pkgCache::Dep::PreDepends) { @@@ -152,8 -146,6 +149,8 @@@ bool pkgSimulate::Configure(PkgIterato cout << " Obsoletes:" << D.TargetPkg().Name(); else if (D->Type == pkgCache::Dep::Conflicts) cout << " Conflicts:" << D.TargetPkg().Name(); + else if (D->Type == pkgCache::Dep::DpkgBreaks) + cout << " Breaks:" << D.TargetPkg().Name(); else cout << " Depends:" << D.TargetPkg().Name(); } @@@ -225,8 -217,6 +222,8 @@@ void pkgSimulate::ShortBreaks( the necessary calculations to deal with the problems. */ bool pkgApplyStatus(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if (I->VersionList == 0) @@@ -237,13 -227,13 +234,13 @@@ I->InstState == pkgCache::State::HoldReInstReq) { if (I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); else { // Is this right? Will dpkg choke on an upgrade? if (Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable() == true) - Cache.MarkInstall(I); + Cache.MarkInstall(I, false, 0, false); else return _error->Error(_("The package %s needs to be reinstalled, " "but I can't find an archive for it."),I.Name()); @@@ -260,12 -250,12 +257,12 @@@ case pkgCache::State::HalfConfigured: if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) || I.State() != pkgCache::PkgIterator::NeedsUnpack) - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); else { if (Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable() == true) - Cache.MarkInstall(I); + Cache.MarkInstall(I, true, 0, false); else Cache.MarkDelete(I); } @@@ -291,12 -281,10 +288,12 @@@ on the result. */ bool pkgFixBroken(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + // Auto upgrade all broken packages for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (Cache[I].NowBroken() == true) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* Fix packages that are in a NeedArchive state but don't have a downloadable install version */ @@@ -309,7 -297,7 +306,7 @@@ if (Cache[I].InstVerIter(Cache).Downloadable() == false) continue; - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); } pkgProblemResolver Fix(&Cache); @@@ -326,25 -314,23 +323,25 @@@ */ bool pkgDistUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + /* Auto upgrade all installed packages, this provides the basis for the installation */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (I->CurrentVer != 0) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* Now, auto upgrade all essential packages - this ensures that the essential packages are present and working */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* We do it again over all previously installed packages to force conflict resolution on them all. */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (I->CurrentVer != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); pkgProblemResolver Fix(&Cache); @@@ -356,7 -342,7 +353,7 @@@ if (I->SelectedState == pkgCache::State::Hold) { Fix.Protect(I); - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } } } @@@ -371,8 -357,6 +368,8 @@@ to install packages not marked for install */ bool pkgAllUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + pkgProblemResolver Fix(&Cache); if (Cache.BrokenCount() != 0) @@@ -389,7 -373,7 +386,7 @@@ continue; if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); } return Fix.ResolveByKeep(); @@@ -402,8 -386,6 +399,8 @@@ the package is restored. */ bool pkgMinimizeUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + if (Cache.BrokenCount() != 0) return false; @@@ -420,9 -402,9 +417,9 @@@ continue; // Keep it and see if that is OK - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache.BrokenCount() != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); else { // If keep didnt actually do anything then there was no change.. @@@ -509,10 -491,8 +506,10 @@@ void pkgProblemResolver::MakeScores( Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority]; /* This helps to fix oddball problems with conflicting packages - on the same level. We enhance the score of installed packages */ - if (I->CurrentVer != 0) + on the same level. We enhance the score of installed packages + if those are not obsolete + */ + if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable()) Score += 1; } @@@ -582,8 -562,6 +579,8 @@@ installable */ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) { + pkgDepCache::ActionGroup group(Cache); + if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false) return false; if ((Flags[Pkg->ID] & Protected) == Protected) @@@ -592,7 -570,7 +589,7 @@@ Flags[Pkg->ID] &= ~Upgradable; bool WasKept = Cache[Pkg].Keep(); - Cache.MarkInstall(Pkg,false); + Cache.MarkInstall(Pkg, false, 0, false); // This must be a virtual package or something like that. if (Cache[Pkg].InstVerIter(Cache).end() == true) @@@ -656,7 -634,6 +653,7 @@@ /* We let the algorithm deal with conflicts on its next iteration, it is much smarter than us */ if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes) break; @@@ -678,7 -655,7 +675,7 @@@ if (Fail == true) { if (WasKept == true) - Cache.MarkKeep(Pkg); + Cache.MarkKeep(Pkg, false, false); else Cache.MarkDelete(Pkg); return false; @@@ -705,8 -682,6 +702,8 @@@ upgrade packages to advoid problems. */ bool pkgProblemResolver::Resolve(bool BrokenFix) { + pkgDepCache::ActionGroup group(Cache); + unsigned long Size = Cache.Head().PackageCount; // Record which packages are marked for install @@@ -722,7 -697,7 +719,7 @@@ { if (Cache[I].InstBroken() == true && BrokenFix == true) { - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Cache[I].Install() == true) Again = true; } @@@ -788,14 -763,14 +785,14 @@@ pkgCache::Version *OldVer = Cache[I].InstallVer; Flags[I->ID] &= ReInstateTried; - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Cache[I].InstBroken() == true || OldBreaks < Cache.BrokenCount()) { if (OldVer == 0) Cache.MarkDelete(I); else - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } else if (Debug == true) @@@ -806,7 -781,7 +803,7 @@@ continue; if (Debug == true) - cout << "Investigating " << I.Name() << endl; + clog << "Investigating " << I.Name() << endl; // Isolate the problem dependency PackageKill KillList[100]; @@@ -840,7 -815,7 +837,7 @@@ { if (Debug == true) clog << " Or group keep for " << I.Name() << endl; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); Change = true; } } @@@ -861,12 -836,7 +858,12 @@@ OldEnd = LEnd; } else + { Start++; + // We only worry about critical deps. + if (Start.IsCritical() != true) + continue; + } // Dep is ok if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) @@@ -884,7 -854,6 +881,7 @@@ SPtrArray VList = Start.AllTargets(); if (*VList == 0 && (Flags[I->ID] & Protected) != Protected && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && Cache[I].NowBroken() == false) { @@@ -896,7 -865,7 +893,7 @@@ } Change = true; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); break; } @@@ -915,7 -884,6 +912,7 @@@ if (Scores[I->ID] <= Scores[Pkg->ID] || ((Cache[Start] & pkgDepCache::DepNow) == 0 && End->Type != pkgCache::Dep::Conflicts && + End->Type != pkgCache::Dep::DpkgBreaks && End->Type != pkgCache::Dep::Obsoletes)) { // Try a little harder to fix protected packages.. @@@ -934,7 -902,7 +931,7 @@@ /* See if a keep will do, unless the package is protected, then installing it will be necessary */ bool Installed = Cache[I].Install(); - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache[I].InstBroken() == false) { // Unwind operation will be keep now @@@ -943,7 -911,7 +940,7 @@@ // Restore if (InOr == true && Installed == true) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Debug == true) clog << " Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; @@@ -981,22 -949,7 +978,22 @@@ (Start->Type == pkgCache::Dep::Conflicts || Start->Type == pkgCache::Dep::Obsoletes)) continue; - + + if (Start->Type == pkgCache::Dep::DpkgBreaks) + { + /* Would it help if we upgraded? */ + if (Cache[End] & pkgDepCache::DepGCVer) { + if (Debug) + clog << " Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl; + Cache.MarkInstall(Pkg, false, 0, false); + continue; + } + if (Debug) + clog << " Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <ID] & Protected) != 0) continue; @@@ -1017,7 -970,6 +1014,7 @@@ // Hm, nothing can possibly satisify this dep. Nuke it. if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && (Flags[I->ID] & Protected) != Protected) { @@@ -1031,7 -983,7 +1028,7 @@@ // Restore if (InOr == true && Installed == true) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Debug == true) clog << " Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl; @@@ -1076,7 -1028,7 +1073,7 @@@ { if (Debug == true) clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl; - Cache.MarkKeep(J->Pkg); + Cache.MarkKeep(J->Pkg, false, false); } if (Counter > 1) @@@ -1106,20 -1058,6 +1103,20 @@@ return _error->Error(_("Unable to correct problems, you have held broken packages.")); } + // set the auto-flags (mvo: I'm not sure if we _really_ need this, but + // I didn't managed + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) { + if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) { + if(_config->FindI("Debug::pkgAutoRemove",false)) { + std::clog << "Resolve installed new pkg: " << I.Name() + << " (now marking it as auto)" << std::endl; + } + Cache[I].Flags |= pkgCache::Flag::Auto; + } + } + + return true; } /*}}}*/ @@@ -1130,8 -1068,6 +1127,8 @@@ system was non-broken previously. */ bool pkgProblemResolver::ResolveByKeep() { + pkgDepCache::ActionGroup group(Cache); + unsigned long Size = Cache.Head().PackageCount; if (Debug == true) @@@ -1165,7 -1101,7 +1162,7 @@@ { if (Debug == true) clog << "Keeping package " << I.Name() << endl; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache[I].InstBroken() == false) { K = PList - 1; @@@ -1213,7 -1149,7 +1210,7 @@@ { if (Debug == true) clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl; - Cache.MarkKeep(Pkg); + Cache.MarkKeep(Pkg, false, false); } if (Cache[I].InstBroken() == false) @@@ -1250,21 -1186,14 +1247,21 @@@ /* This is used to make sure protected packages are installed */ void pkgProblemResolver::InstallProtect() { + pkgDepCache::ActionGroup group(Cache); + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if ((Flags[I->ID] & Protected) == Protected) { if ((Flags[I->ID] & ToRemove) == ToRemove) Cache.MarkDelete(I); - else - Cache.MarkInstall(I,false); + else + { + // preserver the information if the package was auto + // or manual installed + bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto); + Cache.MarkInstall(I, false, 0, !autoInst); + } } } } @@@ -1300,4 -1229,3 +1297,4 @@@ void pkgPrioSortList(pkgCache &Cache,pk qsort(List,Count,sizeof(*List),PrioComp); } /*}}}*/ + diff --combined apt-pkg/cacheiterators.h index d5a9c7b0d,c412eaa97..08eafca0f --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@@ -31,9 -31,6 +31,6 @@@ #ifndef PKGLIB_CACHEITERATORS_H #define PKGLIB_CACHEITERATORS_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/cacheiterators.h" - #endif // Package Iterator class pkgCache::PkgIterator @@@ -99,7 -96,7 +96,7 @@@ class pkgCache::VerIterato { Version *Ver; pkgCache *Owner; - + void _dummy(); public: @@@ -128,8 -125,6 +125,8 @@@ inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; + inline DescIterator DescriptionList() const; + DescIterator TranslatedDescription() const; inline DepIterator DependsList() const; inline PrvIterator ProvidesList() const; inline VerFileIterator FileList() const; @@@ -150,50 -145,6 +147,50 @@@ }; }; +// Description Iterator +class pkgCache::DescIterator +{ + Description *Desc; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Desc == Owner->DescP?true:false;}; + inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;}; + + // Comparison + inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;}; + inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;}; + int CompareDesc(const DescIterator &B) const; + + // Accessors + inline Description *operator ->() {return Desc;}; + inline Description const *operator ->() const {return Desc;}; + inline Description &operator *() {return *Desc;}; + inline Description const &operator *() const {return *Desc;}; + inline operator Description *() {return Desc == Owner->DescP?0:Desc;}; + inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;}; + inline const char *md5() const {return Owner->StrP + Desc->md5sum;}; + inline DescFileIterator FileList() const; + inline unsigned long Index() const {return Desc - Owner->DescP;}; + + inline DescIterator() : Desc(0), Owner(0) {}; + inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg), + Owner(&Owner) + { + if (Desc == 0) + Desc = Owner.DescP; + }; +}; + // Dependency iterator class pkgCache::DepIterator { @@@ -384,38 -335,6 +381,38 @@@ class pkgCache::VerFileIterato inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {}; }; +// Description File +class pkgCache::DescFileIterator +{ + pkgCache *Owner; + DescFile *FileP; + + public: + + // Iteration + void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return FileP == Owner->DescFileP?true:false;}; + + // Comparison + inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;}; + inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;}; + + // Accessors + inline DescFile *operator ->() {return FileP;}; + inline DescFile const *operator ->() const {return FileP;}; + inline DescFile const &operator *() const {return *FileP;}; + inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;}; + inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;}; + inline pkgCache *Cache() {return Owner;}; + + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; + inline unsigned long Index() const {return FileP - Owner->DescFileP;}; + + inline DescFileIterator() : Owner(0), FileP(0) {}; + inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {}; +}; + // Inlined Begin functions cant be in the class because of order problems inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; @@@ -425,15 -344,11 +422,15 @@@ inline pkgCache::DepIterator pkgCache:: {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; +inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const + {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);}; inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);}; inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);}; inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);}; +inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const + {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);}; #endif diff --combined apt-pkg/cdrom.cc index aefe9c9e9,9b0568d8f..55f342d9f --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@@ -1,9 -1,6 +1,6 @@@ /* */ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/cdrom.h" - #endif #include #include #include @@@ -30,16 -27,12 +27,16 @@@ using namespace std search that short circuits when it his a package file in the dir. This speeds it up greatly as the majority of the size is in the binary-* sub dirs. */ -bool pkgCdrom::FindPackages(string CD,vector &List, - vector &SList, vector &SigList, +bool pkgCdrom::FindPackages(string CD, + vector &List, + vector &SList, + vector &SigList, + vector &TransList, string &InfoDir, pkgCdromStatus *log, unsigned int Depth) { static ino_t Inodes[9]; + DIR *D; // if we have a look we "pulse" now if(log) @@@ -94,28 -87,8 +91,28 @@@ if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; } + + // see if we find translatin indexes + if (stat("i18n",&Buf) == 0) + { + D = opendir("i18n"); + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + if(strstr(Dir->d_name,"Translation") != NULL) + { + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "found translations: " << Dir->d_name << "\n"; + string file = Dir->d_name; + if(file.substr(file.size()-3,file.size()) == ".gz") + file = file.substr(0,file.size()-3); + TransList.push_back(CD+"i18n/"+ file); + } + } + closedir(D); + } + - DIR *D = opendir("."); + D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@@ -151,7 -124,7 +148,7 @@@ Inodes[Depth] = Buf.st_ino; // Descend - if (FindPackages(CD + Dir->d_name,List,SList,SigList,InfoDir,log,Depth+1) == false) + if (FindPackages(CD + Dir->d_name,List,SList,SigList,TransList,InfoDir,log,Depth+1) == false) break; if (chdir(CD.c_str()) != 0) @@@ -636,10 -609,9 +633,10 @@@ bool pkgCdrom::Add(pkgCdromStatus *log vector List; vector SourceList; vector SigList; + vector TransList; string StartDir = SafeGetCWD(); string InfoDir; - if (FindPackages(CDROM,List,SourceList, SigList,InfoDir,log) == false) + if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false) { log->Update("\n"); return false; @@@ -667,20 -639,17 +664,20 @@@ DropRepeats(List,"Packages"); DropRepeats(SourceList,"Sources"); DropRepeats(SigList,"Release.gpg"); + DropRepeats(TransList,""); if(log) { msg.str(""); - ioprintf(msg, _("Found %i package indexes, %i source indexes and " - "%i signatures\n"), - List.size(), SourceList.size(), SigList.size()); + ioprintf(msg, _("Found %i package indexes, %i source indexes, " + "%i translation indexes and %i signatures\n"), + List.size(), SourceList.size(), TransList.size(), + SigList.size()); log->Update(msg.str(), STEP_SCAN); } if (List.size() == 0 && SourceList.size() == 0) { - UnmountCdrom(CDROM); + if (_config->FindB("APT::CDROM::NoMount",false) == false) + UnmountCdrom(CDROM); return _error->Error("Unable to locate any package files, perhaps this is not a Debian Disc"); } @@@ -719,8 -688,7 +716,8 @@@ { if(!log) { - UnmountCdrom(CDROM); + if (_config->FindB("APT::CDROM::NoMount",false) == false) + UnmountCdrom(CDROM); return _error->Error("No disc name found and no way to ask for it"); } @@@ -765,10 -733,8 +762,10 @@@ // Copy the package files to the state directory PackageCopy Copy; SourceCopy SrcCopy; + TranslationsCopy TransCopy; if (Copy.CopyPackages(CDROM,Name,List, log) == false || - SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false) + SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false || + TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false) return false; // reduce the List so that it takes less space in sources.list @@@ -798,8 -764,7 +795,8 @@@ string::size_type Space = (*I).find(' '); if (Space == string::npos) { - UnmountCdrom(CDROM); + if (_config->FindB("APT::CDROM::NoMount",false) == false) + UnmountCdrom(CDROM); return _error->Error("Internal error"); } @@@ -816,8 -781,7 +813,8 @@@ string::size_type Space = (*I).find(' '); if (Space == string::npos) { - UnmountCdrom(CDROM); + if (_config->FindB("APT::CDROM::NoMount",false) == false) + UnmountCdrom(CDROM); return _error->Error("Internal error"); } diff --combined apt-pkg/cdrom.h index e18aaff3e,b8b208c30..68d61c098 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@@ -5,9 -5,6 +5,6 @@@ #include #include - #ifdef __GNUG__ - #pragma interface "apt-pkg/cdrom.h" - #endif using namespace std; @@@ -50,11 -47,8 +47,11 @@@ class pkgCdro }; - bool FindPackages(string CD,vector &List, - vector &SList, vector &SigList, + bool FindPackages(string CD, + vector &List, + vector &SList, + vector &SigList, + vector &TransList, string &InfoDir, pkgCdromStatus *log, unsigned int Depth = 0); bool DropBinaryArch(vector &List); diff --combined apt-pkg/contrib/cdromutl.h index db140ec02,1264982a8..f24bb8c70 --- a/apt-pkg/contrib/cdromutl.h +++ b/apt-pkg/contrib/cdromutl.h @@@ -8,19 -8,14 +8,15 @@@ ##################################################################### */ /*}}}*/ #ifndef PKGLIB_CDROMUTL_H -#define PKGLIB_ACQUIRE_METHOD_H +#define PKGLIB_CDROMUTL_H #include using std::string; - #ifdef __GNUG__ - #pragma interface "apt-pkg/cdromutl.h" - #endif - bool MountCdrom(string Path); bool UnmountCdrom(string Path); bool IdentCdrom(string CD,string &Res,unsigned int Version = 2); +bool IsMounted(string &Path); #endif diff --combined apt-pkg/contrib/progress.cc index e3db9a45a,ffd1191e5..6ce6e950a --- a/apt-pkg/contrib/progress.cc +++ b/apt-pkg/contrib/progress.cc @@@ -8,9 -8,6 +8,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/progress.h" - #endif #include #include #include @@@ -115,8 -112,6 +112,8 @@@ bool OpProgress::CheckChange(float Inte if ((int)LastPercent == (int)Percent) return false; + + LastPercent = Percent; if (Interval == 0) return false; @@@ -128,6 -123,7 +125,6 @@@ if (Diff < Interval) return false; LastTime = Now; - LastPercent = Percent; return true; } /*}}}*/ diff --combined apt-pkg/contrib/sha256.h index 70b3ae2ad,01b638d56..c490bfa4d --- a/apt-pkg/contrib/sha256.h +++ b/apt-pkg/contrib/sha256.h @@@ -14,12 -14,9 +14,8 @@@ #ifndef APTPKG_SHA256_H #define APTPKG_SHA256_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/sha256.h" - #endif - #include #include -#include using std::string; using std::min; diff --combined apt-pkg/contrib/strutl.cc index 37d263794,aa37a099a..ae5409aa1 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@@ -15,10 -15,6 +15,6 @@@ ##################################################################### */ /*}}}*/ // Includes /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/strutl.h" - #endif - #include #include #include @@@ -32,55 -28,12 +28,55 @@@ #include #include #include +#include #include "config.h" using namespace std; /*}}}*/ +// UTF8ToCodeset - Convert some UTF-8 string for some codeset /*{{{*/ +// --------------------------------------------------------------------- +/* This is handy to use before display some information for enduser */ +bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest) +{ + iconv_t cd; + const char *inbuf; + char *inptr, *outbuf, *outptr; + size_t insize, outsize; + + cd = iconv_open(codeset, "UTF-8"); + if (cd == (iconv_t)(-1)) { + // Something went wrong + if (errno == EINVAL) + _error->Error("conversion from 'UTF-8' to '%s' not available", + codeset); + else + perror("iconv_open"); + + // Clean the destination string + *dest = ""; + + return false; + } + + insize = outsize = orig.size(); + inbuf = orig.data(); + inptr = (char *)inbuf; + outbuf = new char[insize+1]; + outptr = outbuf; + + iconv(cd, &inptr, &insize, &outptr, &outsize); + *outptr = '\0'; + + *dest = outbuf; + delete[] outbuf; + + iconv_close(cd); + + return true; +} + /*}}}*/ // strstrip - Remove white space from the front and back of a string /*{{{*/ // --------------------------------------------------------------------- /* This is handy to use when parsing a file. It also removes \n's left diff --combined apt-pkg/contrib/strutl.h index 254087267,b8553ab58..ae1244ecd --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@@ -16,9 -16,7 +16,7 @@@ #ifndef STRUTL_H #define STRUTL_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/strutl.h" - #endif + #include #include @@@ -38,8 -36,7 +36,8 @@@ using std::ostream #define APT_FORMAT2 #define APT_FORMAT3 #endif - + +bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest); char *_strstrip(char *String); char *_strtabexpand(char *String,size_t Len); bool ParseQuoteWord(const char *&String,string &Res); diff --combined apt-pkg/deb/debindexfile.cc index 9f435bba5,2d52f7c45..ed7633803 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@@ -9,10 -9,6 +9,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/debindexfile.h" - #endif - #include #include #include @@@ -305,7 -301,7 +301,7 @@@ pkgCache::PkgFileIterator debPackagesIn pkgCache::PkgFileIterator File = Cache.FileBegin(); for (; File.end() == false; File++) { - if (FileName != File.FileName()) + if (File.FileName() == NULL || FileName != File.FileName()) continue; struct stat St; @@@ -320,170 -316,6 +316,170 @@@ } /*}}}*/ +// TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : + pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section) +{ +} + /*}}}*/ +// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ +// --------------------------------------------------------------------- +/* */ +inline string debTranslationsIndex::IndexFile(const char *Type) const +{ + return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); +} +string debTranslationsIndex::IndexURI(const char *Type) const +{ + string Res; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res = URI + Dist; + else + Res = URI; + } + else + Res = URI + "dists/" + Dist + '/' + Section + + "/i18n/Translation-"; + + Res += Type; + return Res; +} + /*}}}*/ +// TranslationsIndex::GetIndexes - Fetch the index files /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const +{ + if (TranslationsAvailable()) { + string TranslationFile = "Translation-" + LanguageCode(); + new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()), + Info(TranslationFile.c_str()), + TranslationFile); + } + + return true; +} + /*}}}*/ +// TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/ +// --------------------------------------------------------------------- +/* This should help the user find the index in the sources.list and + in the filesystem for problem solving */ +string debTranslationsIndex::Describe(bool Short) const +{ + char S[300]; + if (Short == true) + snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str()); + else + snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(), + IndexFile(LanguageCode().c_str()).c_str()); + return S; +} + /*}}}*/ +// TranslationsIndex::Info - One liner describing the index URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debTranslationsIndex::Info(const char *Type) const +{ + string Info = ::URI::SiteOnly(URI) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Info += Dist; + } + else + Info += Dist + '/' + Section; + Info += " "; + Info += Type; + return Info; +} + /*}}}*/ +bool debTranslationsIndex::HasPackages() const +{ + if(!TranslationsAvailable()) + return false; + + return FileExists(IndexFile(LanguageCode().c_str())); +} + +// TranslationsIndex::Exists - Check if the index is available /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debTranslationsIndex::Exists() const +{ + return FileExists(IndexFile(LanguageCode().c_str())); +} + /*}}}*/ +// TranslationsIndex::Size - Return the size of the index /*{{{*/ +// --------------------------------------------------------------------- +/* This is really only used for progress reporting. */ +unsigned long debTranslationsIndex::Size() const +{ + struct stat S; + if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0) + return 0; + return S.st_size; +} + /*}}}*/ +// TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +{ + // Check the translation file, if in use + string TranslationFile = IndexFile(LanguageCode().c_str()); + if (TranslationsAvailable() && FileExists(TranslationFile)) + { + FileFd Trans(TranslationFile,FileFd::ReadOnly); + debListParser TransParser(&Trans); + if (_error->PendingError() == true) + return false; + + Prog.SubProgress(0, Info(TranslationFile.c_str())); + if (Gen.SelectFile(TranslationFile,string(),*this) == false) + return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); + + // Store the IMS information + pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); + struct stat TransSt; + if (fstat(Trans.Fd(),&TransSt) != 0) + return _error->Errno("fstat","Failed to stat"); + TransFile->Size = TransSt.st_size; + TransFile->mtime = TransSt.st_mtime; + + if (Gen.MergeList(TransParser) == false) + return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); + } + + return true; +} + /*}}}*/ +// TranslationsIndex::FindInCache - Find this index /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const +{ + string FileName = IndexFile(LanguageCode().c_str()); + + pkgCache::PkgFileIterator File = Cache.FileBegin(); + for (; File.end() == false; File++) + { + if (FileName != File.FileName()) + continue; + + struct stat St; + if (stat(File.FileName(),&St) != 0) + return pkgCache::PkgFileIterator(Cache); + if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + return pkgCache::PkgFileIterator(Cache); + return File; + } + return File; +} + /*}}}*/ // StatusIndex::debStatusIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@@ -580,11 -412,6 +576,11 @@@ class debIFTypePkg : public pkgIndexFil }; debIFTypePkg() {Label = "Debian Package Index";}; }; +class debIFTypeTrans : public debIFTypePkg +{ + public: + debIFTypeTrans() {Label = "Debian Translation Index";}; +}; class debIFTypeStatus : public pkgIndexFile::Type { public: @@@ -597,7 -424,6 +593,7 @@@ }; static debIFTypeSrc _apt_Src; static debIFTypePkg _apt_Pkg; +static debIFTypeTrans _apt_Trans; static debIFTypeStatus _apt_Status; const pkgIndexFile::Type *debSourcesIndex::GetType() const @@@ -608,10 -434,6 +604,10 @@@ const pkgIndexFile::Type *debPackagesIn { return &_apt_Pkg; } +const pkgIndexFile::Type *debTranslationsIndex::GetType() const +{ + return &_apt_Trans; +} const pkgIndexFile::Type *debStatusIndex::GetType() const { return &_apt_Status; diff --combined apt-pkg/deb/debindexfile.h index 57005222f,2bc963567..b0012c96b --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@@ -16,9 -16,7 +16,7 @@@ #ifndef PKGLIB_DEBINDEXFILE_H #define PKGLIB_DEBINDEXFILE_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/debindexfile.h" - #endif + #include @@@ -74,36 -72,6 +72,36 @@@ class debPackagesIndex : public pkgInde debPackagesIndex(string URI,string Dist,string Section,bool Trusted); }; +class debTranslationsIndex : public pkgIndexFile +{ + string URI; + string Dist; + string Section; + + string Info(const char *Type) const; + string IndexFile(const char *Type) const; + string IndexURI(const char *Type) const; + + inline string TranslationFile() const {return "Translation-" + LanguageCode();}; + + public: + + virtual const Type *GetType() const; + + // Interface for acquire + virtual string Describe(bool Short) const; + virtual bool GetIndexes(pkgAcquire *Owner) const; + + // Interface for the Cache Generator + virtual bool Exists() const; + virtual bool HasPackages() const; + virtual unsigned long Size() const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; + + debTranslationsIndex(string URI,string Dist,string Section); +}; + class debSourcesIndex : public pkgIndexFile { string URI; diff --combined apt-pkg/deb/debmetaindex.cc index 8cf31b326,6830f9e83..73b2dda49 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@@ -1,9 -1,5 +1,5 @@@ // ijones, walters - #ifdef __GNUG__ - #pragma implementation "apt-pkg/debmetaindex.h" - #endif - #include #include #include @@@ -157,16 -153,6 +153,16 @@@ bool debReleaseIndex::GetIndexes(pkgAcq ComputeIndexTargets(), new indexRecords (Dist)); + // Queue the translations + for (vector::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); I++) { + + if((*I)->IsSrc) + continue; + debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); + i.GetIndexes(Owner); + } + return true; } @@@ -191,16 -177,11 +187,16 @@@ vector *debReleaseInde Indexes = new vector ; for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) + I != SectionEntries.end(); I++) { if ((*I)->IsSrc) Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); else + { Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); + Indexes->push_back(new debTranslationsIndex(URI, Dist, (*I)->Section)); + } + } + return Indexes; } diff --combined apt-pkg/deb/debrecords.cc index 5eb2d67bb,6ecbd15d6..5421b3db7 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@@ -8,13 -8,8 +8,10 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/debrecords.h" - #endif #include +#include #include +#include /*}}}*/ // RecordParser::debRecordParser - Constructor /*{{{*/ @@@ -32,10 -27,6 +29,10 @@@ debRecordParser::debRecordParser(strin bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) { return Tags.Jump(Section,Ver->Offset); +} +bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc) +{ + return Tags.Jump(Section,Desc->Offset); } /*}}}*/ // RecordParser::FileName - Return the archive filename on the site /*{{{*/ @@@ -67,7 -58,7 +64,7 @@@ string debRecordParser::MD5Hash( /* */ string debRecordParser::SHA1Hash() { - return Section.FindS("SHA1Sum"); + return Section.FindS("SHA1"); } /*}}}*/ // RecordParser::Maintainer - Return the maintainer email /*{{{*/ @@@ -83,7 -74,7 +80,7 @@@ string debRecordParser::Maintainer( /* */ string debRecordParser::ShortDesc() { - string Res = Section.FindS("Description"); + string Res = LongDesc(); string::size_type Pos = Res.find('\n'); if (Pos == string::npos) return Res; @@@ -95,20 -86,7 +92,20 @@@ /* */ string debRecordParser::LongDesc() { - return Section.FindS("Description"); + string orig, dest; + char *codeset = nl_langinfo(CODESET); + + if (!Section.FindS("Description").empty()) + orig = Section.FindS("Description").c_str(); + else + orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str(); + + if (strcmp(codeset,"UTF-8") != 0) { + UTF8ToCodeset(codeset, orig, &dest); + orig = dest; + } + + return orig; } /*}}}*/ // RecordParser::SourcePkg - Return the source package name if any /*{{{*/ diff --combined apt-pkg/deb/debrecords.h index 24e5aab88,3f1956164..fdf8d762b --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@@ -14,12 -14,7 +14,8 @@@ #ifndef PKGLIB_DEBRECORDS_H #define PKGLIB_DEBRECORDS_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/debrecords.h" - #endif - #include +#include #include class debRecordParser : public pkgRecords::Parser @@@ -31,7 -26,6 +27,7 @@@ protected: virtual bool Jump(pkgCache::VerFileIterator const &Ver); + virtual bool Jump(pkgCache::DescFileIterator const &Desc); public: diff --combined apt-pkg/deb/debsrcrecords.cc index 9e87ee5da,21d7392a0..7338de15d --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@@ -9,17 -9,11 +9,13 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/debsrcrecords.h" - #endif - #include #include #include #include #include + +using std::max; /*}}}*/ // SrcRecordParser::Binaries - Return the binaries field /*{{{*/ @@@ -36,19 -30,31 +32,19 @@@ const char **debSrcRecordParser::Binari if (Bins.empty() == true || Bins.length() >= 102400) return 0; - // Workaround for #236688. Only allocate a new buffer if the field - // is large, to avoid a performance penalty - char *BigBuf = NULL; - char *Buf; - if (Bins.length() > sizeof(Buffer)) - { - BigBuf = new char[Bins.length()]; - Buf = BigBuf; - } - else + if (Bins.length() >= BufSize) { - Buf = Buffer; + delete [] Buffer; + // allocate new size based on buffer (but never smaller than 4000) + BufSize = max((unsigned long)4000, max((unsigned long)Bins.length()+1,2*BufSize)); + Buffer = new char[BufSize]; } - strcpy(Buf,Bins.c_str()); - if (TokSplitString(',',Buf,StaticBinList, + strcpy(Buffer,Bins.c_str()); + if (TokSplitString(',',Buffer,StaticBinList, sizeof(StaticBinList)/sizeof(StaticBinList[0])) == false) - { - if (BigBuf != NULL) - delete BigBuf; return 0; - } - if (BigBuf != NULL) - delete BigBuf; return (const char **)StaticBinList; } /*}}}*/ diff --combined apt-pkg/deb/debsrcrecords.h index f4e2cb46c,51e063812..55fdcb667 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@@ -11,9 -11,6 +11,6 @@@ #ifndef PKGLIB_DEBSRCRECORDS_H #define PKGLIB_DEBSRCRECORDS_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/debsrcrecords.h" - #endif #include #include @@@ -24,10 -21,9 +21,10 @@@ class debSrcRecordParser : public pkgSr FileFd Fd; pkgTagFile Tags; pkgTagSection Sect; - char Buffer[10000]; char *StaticBinList[400]; unsigned long iOffset; + char *Buffer; + unsigned long BufSize; public: @@@ -50,9 -46,10 +47,9 @@@ }; virtual bool Files(vector &F); - debSrcRecordParser(string File,pkgIndexFile const *Index) : - Parser(Index), - Fd(File,FileFd::ReadOnly), - Tags(&Fd,102400) {}; + debSrcRecordParser(string File,pkgIndexFile const *Index) + : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), + Buffer(0), BufSize(0) {} }; #endif diff --combined apt-pkg/deb/dpkgpm.cc index 5c069458e,905ac93c4..4b4bba696 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@@ -8,14 -8,10 +8,11 @@@ ##################################################################### */ /*}}}*/ // Includes /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/dpkgpm.h" - #endif #include #include #include #include +#include #include #include @@@ -38,8 -34,7 +35,8 @@@ using namespace std // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) : pkgPackageManager(Cache) +pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) + : pkgPackageManager(Cache), pkgFailures(0) { } /*}}}*/ @@@ -476,8 -471,6 +473,8 @@@ bool pkgDPkgPM::Go(int OutStatusFd case Item::Install: Args[n++] = "--unpack"; Size += strlen(Args[n-1]); + Args[n++] = "--auto-deconfigure"; + Size += strlen(Args[n-1]); break; } @@@ -628,22 -621,15 +625,22 @@@ */ char* list[5]; - if(!TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]))) - // FIXME: dpkg sends multiline error messages sometimes (see - // #374195 for a example. we should support this by - // either patching dpkg to not send multiline over the - // statusfd or by rewriting the code here to deal with - // it. for now we just ignore it and not crash - continue; + // dpkg sends multiline error messages sometimes (see + // #374195 for a example. we should support this by + // either patching dpkg to not send multiline over the + // statusfd or by rewriting the code here to deal with + // it. for now we just ignore it and not crash + TokSplitString(':', line, list, sizeof(list)/sizeof(list[0])); char *pkg = list[1]; char *action = _strstrip(list[2]); + if( pkg == NULL || action == NULL) + { + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "ignoring line: not enough ':'" << std::endl; + // reset the line buffer + line[0]=0; + continue; + } if(strncmp(action,"error",strlen("error")) == 0) { @@@ -656,8 -642,6 +653,8 @@@ line[0]=0; if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) std::clog << "send: '" << status.str() << "'" << endl; + pkgFailures++; + WriteApportReport(list[1], list[3]); continue; } if(strncmp(action,"conffile",strlen("conffile")) == 0) @@@ -717,23 -701,14 +714,23 @@@ // Check for an error code. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) { - RunScripts("DPkg::Post-Invoke"); - if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) - return _error->Error("Sub-process %s received a segmentation fault.",Args[0]); - - if (WIFEXITED(Status) != 0) - return _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + // if it was set to "keep-dpkg-runing" then we won't return + // here but keep the loop going and just report it as a error + // for later + bool stopOnError = _config->FindB("Dpkg::StopOnError",true); - return _error->Error("Sub-process %s exited unexpectedly",Args[0]); + if(stopOnError) + RunScripts("DPkg::Post-Invoke"); + + if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) + _error->Error("Sub-process %s received a segmentation fault.",Args[0]); + else if (WIFEXITED(Status) != 0) + _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + else + _error->Error("Sub-process %s exited unexpectedly",Args[0]); + + if(stopOnError) + return false; } } @@@ -750,94 -725,3 +747,94 @@@ void pkgDPkgPM::Reset( List.erase(List.begin(),List.end()); } /*}}}*/ +// pkgDpkgPM::WriteApportReport - write out error report pkg failure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) +{ + string pkgname, reportfile, srcpkgname, pkgver, arch; + string::size_type pos; + FILE *report; + + if (_config->FindB("Dpkg::ApportFailureReport",true) == false) + return; + + // only report the first error if we are in StopOnError=false mode + // to prevent bogus reports + if((_config->FindB("Dpkg::StopOnError",true) == false) && pkgFailures > 1) + return; + + // get the pkgname and reportfile + pkgname = flNotDir(pkgpath); + pos = pkgname.rfind('_'); + if(pos != string::npos) + pkgname = string(pkgname, 0, pos); + + // find the package versin and source package name + pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); + if (Pkg.end() == true) + return; + pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + pkgver = Ver.VerStr(); + if (Ver.end() == true) + return; + pkgRecords Recs(Cache); + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + srcpkgname = Parse.SourcePkg(); + if(srcpkgname.empty()) + srcpkgname = pkgname; + + // if the file exists already, we check: + // - if it was reported already (touched by apport). + // If not, we do nothing, otherwise + // we overwrite it. This is the same behaviour as apport + // - if we have a report with the same pkgversion already + // then we skip it + reportfile = flCombine("/var/crash",pkgname+".0.crash"); + if(FileExists(reportfile)) + { + struct stat buf; + char strbuf[255]; + + // check atime/mtime + stat(reportfile.c_str(), &buf); + if(buf.st_mtime > buf.st_atime) + return; + + // check if the existing report is the same version + report = fopen(reportfile.c_str(),"r"); + while(fgets(strbuf, sizeof(strbuf), report) != NULL) + { + if(strstr(strbuf,"Package:") == strbuf) + { + char pkgname[255], version[255]; + if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2) + if(strcmp(pkgver.c_str(), version) == 0) + { + fclose(report); + return; + } + } + } + fclose(report); + } + + // now write the report + arch = _config->Find("APT::Architecture"); + report = fopen(reportfile.c_str(),"w"); + if(report == NULL) + return; + if(_config->FindB("DPkgPM::InitialReportOnly",false) == true) + chmod(reportfile.c_str(), 0); + else + chmod(reportfile.c_str(), 0600); + fprintf(report, "ProblemType: Package\n"); + fprintf(report, "Architecture: %s\n", arch.c_str()); + time_t now = time(NULL); + fprintf(report, "Date: %s" , ctime(&now)); + fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str()); + fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str()); + fprintf(report, "ErrorMessage:\n %s\n", errormsg); + fclose(report); +} + /*}}}*/ diff --combined apt-pkg/deb/dpkgpm.h index 1a1fdc191,45eb6b15b..a413f3a90 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@@ -10,10 -10,6 +10,6 @@@ #ifndef PKGLIB_DPKGPM_H #define PKGLIB_DPKGPM_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/dpkgpm.h" - #endif - #include #include #include @@@ -23,7 -19,6 +19,7 @@@ using std::vector class pkgDPkgPM : public pkgPackageManager { protected: + int pkgFailures; // used for progress reporting struct DpkgState @@@ -48,10 -43,7 +44,10 @@@ bool RunScripts(const char *Cnf); bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); - + + // apport integration + void WriteApportReport(const char *pkgpath, const char *errormsg); + // The Actuall installation implementation virtual bool Install(PkgIterator Pkg,string File); virtual bool Configure(PkgIterator Pkg); diff --combined apt-pkg/depcache.cc index 27e0ff73f,70bc9f086..9f0fa143d --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@@ -8,62 -8,21 +8,59 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/depcache.h" - #endif #include #include #include #include #include + +#include #include +#include +#include + +#include +#include +#include + +#include #include - /*}}}*/ + +pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : + cache(cache), released(false) +{ + ++cache.group_level; +} + +void pkgDepCache::ActionGroup::release() +{ + if(!released) + { + if(cache.group_level == 0) + std::cerr << "W: Unbalanced action groups, expect badness" << std::endl; + else + { + --cache.group_level; + + if(cache.group_level == 0) + cache.MarkAndSweep(); + } + + released = false; + } +} + +pkgDepCache::ActionGroup::~ActionGroup() +{ + release(); +} // DepCache::pkgDepCache - Constructors /*{{{*/ // --------------------------------------------------------------------- /* */ pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) : - Cache(pCache), PkgState(0), DepState(0) + group_level(0), Cache(pCache), PkgState(0), DepState(0) { delLocalPolicy = 0; LocalPolicy = Plcy; @@@ -86,10 -45,6 +83,10 @@@ pkgDepCache::~pkgDepCache( /* This allocats the extension buffers and initializes them. */ bool pkgDepCache::Init(OpProgress *Prog) { + // Suppress mark updates during this operation (just in case) and + // run a mark operation when Init terminates. + ActionGroup actions(*this); + delete [] PkgState; delete [] DepState; PkgState = new StateCache[Head().PackageCount]; @@@ -115,7 -70,7 +112,7 @@@ // Find the proper cache slot StateCache &State = PkgState[I->ID]; State.iFlags = 0; - + // Figure out the install version State.CandidateVer = GetCandidateVer(I); State.InstallVer = I.CurrentVer(); @@@ -137,134 -92,11 +134,134 @@@ if(Prog != 0) Prog->Done(); - + return true; } /*}}}*/ +bool pkgDepCache::readStateFile(OpProgress *Prog) +{ + FileFd state_file; + string state = _config->FindDir("Dir::State") + "extended_states"; + if(FileExists(state)) { + state_file.Open(state, FileFd::ReadOnly); + int file_size = state_file.Size(); + if(Prog != NULL) + Prog->OverallProgress(0, file_size, 1, + _("Reading state information")); + + pkgTagFile tagfile(&state_file); + pkgTagSection section; + int amt=0; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + // Silently ignore unknown packages and packages with no actual + // version. + if(!pkg.end() && !pkg.VersionList().end()) { + short reason = section.FindI("Auto-Installed", 0); + if(reason > 0) + PkgState[pkg->ID].Flags |= Flag::Auto; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Auto-Installed : " << pkgname << std::endl; + amt+=section.size(); + if(Prog != NULL) + Prog->OverallProgress(amt, file_size, 1, + _("Reading state information")); + } + if(Prog != NULL) + Prog->OverallProgress(file_size, file_size, 1, + _("Reading state information")); + } + } + + return true; +} + +bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) +{ + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "pkgDepCache::writeStateFile()" << std::endl; + + FileFd StateFile; + string state = _config->FindDir("Dir::State") + "extended_states"; + + // if it does not exist, create a empty one + if(!FileExists(state)) + { + StateFile.Open(state, FileFd::WriteEmpty); + StateFile.Close(); + } + + // open it + if(!StateFile.Open(state, FileFd::ReadOnly)) + return _error->Error(_("Failed to open StateFile %s"), + state.c_str()); + + FILE *OutFile; + string outfile = state + ".tmp"; + if((OutFile = fopen(outfile.c_str(),"w")) == NULL) + return _error->Error(_("Failed to write temporary StateFile %s"), + outfile.c_str()); + + // first merge with the existing sections + pkgTagFile tagfile(&StateFile); + pkgTagSection section; + std::set pkgs_seen; + const char *nullreorderlist[] = {0}; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + // Silently ignore unknown packages and packages with no actual + // version. + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + if(pkg.end() || pkg.VersionList().end()) + continue; + bool oldAuto = section.FindI("Auto-Installed"); + bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "Update exisiting AutoInstall info: " + << pkg.Name() << std::endl; + TFRewriteData rewrite[2]; + rewrite[0].Tag = "Auto-Installed"; + rewrite[0].Rewrite = newAuto ? "1" : "0"; + rewrite[0].NewTag = 0; + rewrite[1].Tag = 0; + TFRewrite(OutFile, section, nullreorderlist, rewrite); + fprintf(OutFile,"\n"); + pkgs_seen.insert(pkgname); + } + + // then write the ones we have not seen yet + std::ostringstream ostr; + for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) { + if(PkgState[pkg->ID].Flags & Flag::Auto) { + if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) { + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "Skipping already written " << pkg.Name() << std::endl; + continue; + } + // skip not installed ones if requested + if(InstalledOnly && pkg->CurrentVer == 0) + continue; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "Writing new AutoInstall: " + << pkg.Name() << std::endl; + ostr.str(string("")); + ostr << "Package: " << pkg.Name() + << "\nAuto-Installed: 1\n\n"; + fprintf(OutFile,ostr.str().c_str()); + fprintf(OutFile,"\n"); + } + } + fclose(OutFile); + + // move the outfile over the real file and set permissions + rename(outfile.c_str(), state.c_str()); + chmod(state.c_str(), 0644); + + return true; +} + // DepCache::CheckDep - Checks a single dependency /*{{{*/ // --------------------------------------------------------------------- /* This first checks the dependency against the main target package and @@@ -279,7 -111,7 +276,7 @@@ bool pkgDepCache::CheckDep(DepIterator we allow it anyhow because dpkg does. Technically it is a packaging bug. Conflicts may never self match */ if (Dep.TargetPkg() != Dep.ParentPkg() || - (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes)) + (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes)) { PkgIterator Pkg = Dep.TargetPkg(); // Check the base package @@@ -309,8 -141,7 +306,8 @@@ { /* Provides may never be applied against the same package if it is a conflicts. See the comment above. */ - if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts) + if (P.OwnerPkg() == Pkg && + (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks)) continue; // Check if the provides is a hit @@@ -406,11 -237,9 +403,11 @@@ void pkgDepCache::AddStates(const PkgIt { StateCache &State = PkgState[Pkg->ID]; - // The Package is broken + // The Package is broken (either minimal dep or policy dep) if ((State.DepState & DepInstMin) != DepInstMin) iBrokenCount += Add; + if ((State.DepState & DepInstPolicy) != DepInstPolicy) + iPolicyBrokenCount += Add; // Bad state if (Pkg.State() != PkgIterator::NeedsNothing) @@@ -464,9 -293,7 +461,9 @@@ void pkgDepCache::BuildGroupOrs(VerIter /* Invert for Conflicts. We have to do this twice to get the right sense for a conflicts group */ - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; // Add to the group if we are within an or.. @@@ -477,9 -304,7 +474,9 @@@ Group = 0; // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; } } @@@ -612,9 -437,7 +609,9 @@@ void pkgDepCache::Update(OpProgress *Pr Group = 0; // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; } } @@@ -627,14 -450,12 +624,14 @@@ if (Prog != 0) Prog->Progress(Done); + + readStateFile(Prog); } /*}}}*/ // DepCache::Update - Update the deps list of a package /*{{{*/ // --------------------------------------------------------------------- /* This is a helper for update that only does the dep portion of the scan. - It is mainly ment to scan reverse dependencies. */ + It is mainly meant to scan reverse dependencies. */ void pkgDepCache::Update(DepIterator D) { // Update the reverse deps @@@ -644,9 -465,7 +641,9 @@@ State = DependencyState(D); // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; RemoveStates(D.ParentPkg()); @@@ -688,7 -507,7 +685,7 @@@ void pkgDepCache::Update(PkgIterator co // DepCache::MarkKeep - Put the package in the keep state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft) +void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) { // Simplifies other routines. if (Pkg.end() == true) @@@ -700,9 -519,6 +697,9 @@@ Pkg.CurrentVer().Downloadable() == false) return; + /** \todo Can this be moved later in the method? */ + ActionGroup group(*this); + /* We changed the soft state all the time so the UI is a bit nicer to use */ StateCache &P = PkgState[Pkg->ID]; @@@ -718,18 -534,8 +715,18 @@@ // We dont even try to keep virtual packages.. if (Pkg->VersionList == 0) return; - - P.Flags &= ~Flag::Auto; + +#if 0 // reseting the autoflag here means we lose the + // auto-mark information if a user selects a package for removal + // but changes his mind then and sets it for keep again + // - this makes sense as default when all Garbage dependencies + // are automatically marked for removal (as aptitude does). + // setting a package for keep then makes it no longer autoinstalled + // for all other use-case this action is rather suprising + if(FromUser && !P.Marked) + P.Flags &= ~Flag::Auto; +#endif + RemoveSizes(Pkg); RemoveStates(Pkg); @@@ -755,8 -561,6 +752,8 @@@ void pkgDepCache::MarkDelete(PkgIterato if (Pkg.end() == true) return; + ActionGroup group(*this); + // Check that it is not already marked for delete StateCache &P = PkgState[Pkg->ID]; P.iFlags &= ~(AutoKept | Purge); @@@ -779,6 -583,7 +776,6 @@@ else P.Mode = ModeDelete; P.InstallVer = 0; - P.Flags &= Flag::Auto; AddStates(Pkg); Update(Pkg); @@@ -789,8 -594,7 +786,8 @@@ // --------------------------------------------------------------------- /* */ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, - unsigned long Depth) + unsigned long Depth, bool FromUser, + bool ForceImportantDeps) { if (Depth > 100) return; @@@ -799,27 -603,26 +796,27 @@@ if (Pkg.end() == true) return; + ActionGroup group(*this); + /* Check that it is not already marked for install and that it can be installed */ StateCache &P = PkgState[Pkg->ID]; P.iFlags &= ~AutoKept; - if (P.InstBroken() == false && (P.Mode == ModeInstall || + if ((P.InstPolicyBroken() == false && P.InstBroken() == false) && + (P.Mode == ModeInstall || P.CandidateVer == (Version *)Pkg.CurrentVer())) { if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) - MarkKeep(Pkg); + MarkKeep(Pkg, false, FromUser); return; } // See if there is even any possible instalation candidate if (P.CandidateVer == 0) return; - // We dont even try to install virtual packages.. if (Pkg->VersionList == 0) return; - /* Target the candidate version and remove the autoflag. We reset the autoflag below if this was called recursively. Otherwise the user should have the ability to de-auto a package by changing its state */ @@@ -828,20 -631,7 +825,20 @@@ P.Mode = ModeInstall; P.InstallVer = P.CandidateVer; - P.Flags &= ~Flag::Auto; + + if(FromUser) + { + // Set it to manual if it's a new install or cancelling the + // removal of a garbage package. + if(P.Status == 2 || (!Pkg.CurrentVer().end() && !P.Marked)) + P.Flags &= ~Flag::Auto; + } + else + { + // Set it to auto if this is a new install. + if(P.Status == 2) + P.Flags |= Flag::Auto; + } if (P.CandidateVer == (Version *)Pkg.CurrentVer()) P.Mode = ModeKeep; @@@ -873,43 -663,10 +870,43 @@@ /* Check if this dep should be consider for install. If it is a user defined important dep and we are installed a new package then - it will be installed. Otherwise we only worry about critical deps */ + it will be installed. Otherwise we only check for important + deps that have changed from the installed version + */ if (IsImportantDep(Start) == false) continue; - if (Pkg->CurrentVer != 0 && Start.IsCritical() == false) + + /* check if any ImportantDep() (but not Critial) where added + * since we installed the package + */ + bool isNewImportantDep = false; + if(!ForceImportantDeps && !Start.IsCritical()) + { + bool found=false; + VerIterator instVer = Pkg.CurrentVer(); + if(!instVer.end()) + { + for (DepIterator D = instVer.DependsList(); D.end() != true; D++) + { + //FIXME: deal better with or-groups(?) + DepIterator LocalStart = D; + + if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg()) + found=true; + } + // this is a new dep if it was not found to be already + // a important dep of the installed pacakge + isNewImportantDep = !found; + } + } + if(isNewImportantDep) + if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) + std::clog << "new important dependency: " + << Start.TargetPkg().Name() << std::endl; + + // skip important deps if the package is already installed + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false + && !isNewImportantDep && !ForceImportantDeps) continue; /* If we are in an or group locate the first or that can @@@ -920,8 -677,7 +917,8 @@@ /* This bit is for processing the possibilty of an install/upgrade fixing the problem */ SPtrArray List = Start.AllTargets(); - if ((DepState[Start->ID] & DepCVer) == DepCVer) + if (Start->Type != Dep::DpkgBreaks && + (DepState[Start->ID] & DepCVer) == DepCVer) { // Right, find the best version to install.. Version **Cur = List; @@@ -952,49 -708,33 +949,49 @@@ } } - if (InstPkg.end() == false) + if (InstPkg.end() == false) { if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) std::clog << "Installing " << InstPkg.Name() << " as dep of " << Pkg.Name() << std::endl; - MarkInstall(InstPkg,true,Depth + 1); - // Set the autoflag, after MarkInstall because MarkInstall unsets it - if (P->CurrentVer == 0) - PkgState[InstPkg->ID].Flags |= Flag::Auto; + // now check if we should consider it a automatic dependency or not + string sec = _config->Find("APT::Never-MarkAuto-Section",""); + if(Pkg.Section() && (string(Pkg.Section()) == sec)) + { + if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) + std::clog << "Setting NOT as auto-installed because its a direct dep of a package in section " << sec << std::endl; + MarkInstall(InstPkg,true,Depth + 1, true, ForceImportantDeps); + } + else + { + // mark automatic dependency + MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps); + // Set the autoflag, after MarkInstall because MarkInstall unsets it + if (P->CurrentVer == 0) + PkgState[InstPkg->ID].Flags |= Flag::Auto; + } } - continue; } - + /* For conflicts we just de-install the package and mark as auto, - Conflicts may not have or groups */ - if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes) + Conflicts may not have or groups. For dpkg's Breaks we try to + upgrade the package. */ + if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes || + Start->Type == Dep::DpkgBreaks) { for (Version **I = List; *I != 0; I++) { VerIterator Ver(*this,*I); PkgIterator Pkg = Ver.ParentPkg(); - - MarkDelete(Pkg); - PkgState[Pkg->ID].Flags |= Flag::Auto; + + if (Start->Type != Dep::DpkgBreaks) + MarkDelete(Pkg); + else + if (PkgState[Pkg->ID].CandidateVer != *I) + MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); } continue; } @@@ -1006,8 -746,6 +1003,8 @@@ /* */ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) { + ActionGroup group(*this); + RemoveSizes(Pkg); RemoveStates(Pkg); @@@ -1026,11 -764,9 +1023,11 @@@ /* */ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) { + ActionGroup group(*this); + pkgCache::PkgIterator Pkg = TargetVer.ParentPkg(); StateCache &P = PkgState[Pkg->ID]; - + RemoveSizes(Pkg); RemoveStates(Pkg); @@@ -1043,18 -779,6 +1040,18 @@@ Update(Pkg); AddSizes(Pkg); } + +void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto) +{ + StateCache &state = PkgState[Pkg->ID]; + + ActionGroup group(*this); + + if(Auto) + state.Flags |= Flag::Auto; + else + state.Flags &= ~Flag::Auto; +} /*}}}*/ // StateCache::Update - Compute the various static display things /*{{{*/ // --------------------------------------------------------------------- @@@ -1137,251 -861,11 +1134,251 @@@ pkgCache::VerIterator pkgDepCache::Poli return Last; } /*}}}*/ + /*}}}*/ + +pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() + : constructedSuccessfully(false) +{ + Configuration::Item const *Opts; + Opts = _config->Tree("APT::NeverAutoRemove"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + + regex_t *p = new regex_t; + if(regcomp(p,Opts->Value.c_str(), + REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) + { + regfree(p); + delete p; + _error->Error("Regex compilation error for APT::NeverAutoRemove"); + return; + } + + rootSetRegexp.push_back(p); + } + } + + constructedSuccessfully = true; +} + +pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + { + regfree(rootSetRegexp[i]); + delete rootSetRegexp[i]; + } +} + + +bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0) + return true; + + return false; +} + +pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() +{ + DefaultRootSetFunc *f = new DefaultRootSetFunc; + if(f->wasConstructedSuccessfully()) + return f; + else + { + delete f; + return NULL; + } +} + +bool pkgDepCache::MarkFollowsRecommends() +{ + return _config->FindB("APT::AutoRemove::RecommendsImportant", true); +} + +bool pkgDepCache::MarkFollowsSuggests() +{ + return _config->FindB("APT::AutoRemove::SuggestsImportant", false); +} + +// the main mark algorithm +bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) +{ + bool follow_recommends; + bool follow_suggests; + + // init the states + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + PkgState[p->ID].Marked = false; + PkgState[p->ID].Garbage = false; + + // debug output + if(_config->FindB("Debug::pkgAutoRemove",false) + && PkgState[p->ID].Flags & Flag::Auto) + std::clog << "AutoDep: " << p.Name() << std::endl; + } + + // init vars + follow_recommends = MarkFollowsRecommends(); + follow_suggests = MarkFollowsSuggests(); + + + + // do the mark part, this is the core bit of the algorithm + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + if(!(PkgState[p->ID].Flags & Flag::Auto) || + (p->Flags & Flag::Essential) || + userFunc.InRootSet(p)) + + { + // the package is installed (and set to keep) + if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) + MarkPackage(p, p.CurrentVer(), + follow_recommends, follow_suggests); + // the package is to be installed + else if(PkgState[p->ID].Install()) + MarkPackage(p, PkgState[p->ID].InstVerIter(*this), + follow_recommends, follow_suggests); + } + } + + return true; +} + +// mark a single package in Mark-and-Sweep +void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests) +{ + pkgDepCache::StateCache &state = PkgState[pkg->ID]; + VerIterator candver = state.CandidateVerIter(*this); + VerIterator instver = state.InstVerIter(*this); + +#if 0 + // If a package was garbage-collected but is now being marked, we + // should re-select it + // For cases when a pkg is set to upgrade and this trigger the + // removal of a no-longer used dependency. if the pkg is set to + // keep again later it will result in broken deps + if(state.Delete() && state.RemoveReason = Unused) + { + if(ver==candver) + mark_install(pkg, false, false, NULL); + else if(ver==pkg.CurrentVer()) + MarkKeep(pkg, false, false); + + instver=state.InstVerIter(*this); + } +#endif + + // Ignore versions other than the InstVer, and ignore packages + // that are already going to be removed or just left uninstalled. + if(!(ver == instver && !instver.end())) + return; + + // if we are marked already we are done + if(state.Marked) + return; + + //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; + state.Marked=true; + + if(!ver.end()) + { + for(DepIterator d = ver.DependsList(); !d.end(); ++d) + { + if(d->Type == Dep::Depends || + d->Type == Dep::PreDepends || + (follow_recommends && + d->Type == Dep::Recommends) || + (follow_suggests && + d->Type == Dep::Suggests)) + { + // Try all versions of this package. + for(VerIterator V = d.TargetPkg().VersionList(); + !V.end(); ++V) + { + if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer())) + { + MarkPackage(V.ParentPkg(), V, + follow_recommends, follow_suggests); + } + } + // Now try virtual packages + for(PrvIterator prv=d.TargetPkg().ProvidesList(); + !prv.end(); ++prv) + { + if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, + d.TargetVer())) + { + MarkPackage(prv.OwnerPkg(), prv.OwnerVer(), + follow_recommends, follow_suggests); + } + } + } + } + } +} + +bool pkgDepCache::Sweep() +{ + // do the sweep + for(PkgIterator p=PkgBegin(); !p.end(); ++p) + { + StateCache &state=PkgState[p->ID]; + + // skip required packages + if (!p.CurrentVer().end() && + (p.CurrentVer()->Priority == pkgCache::State::Required)) + continue; + + // if it is not marked and it is installed, it's garbage + if(!state.Marked && (!p.CurrentVer().end() || state.Install())) + { + state.Garbage=true; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Garbage: " << p.Name() << std::endl; + } + } + + return true; +} + // Policy::IsImportantDep - True if the dependency is important /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) { - return Dep.IsCritical(); + if(Dep.IsCritical()) + return true; + else if(Dep->Type == pkgCache::Dep::Recommends) + { + if ( _config->FindB("APT::Install-Recommends", false)) + return true; + // we suport a special mode to only install-recommends for certain + // sections + // FIXME: this is a meant as a temporarly solution until the + // recommends are cleaned up + string s = _config->Find("APT::Install-Recommends-Section",""); + if(s.size() > 0) + { + const char *sec = Dep.ParentVer().Section(); + if (sec && strcmp(sec, s.c_str()) == 0) + return true; + } + } + else if(Dep->Type == pkgCache::Dep::Suggests) + return _config->FindB("APT::Install-Suggests", false); + + return false; } /*}}}*/ diff --combined apt-pkg/depcache.h index 8f759d345,929fe93c9..84fed7f37 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@@ -1,4 -1,4 +1,4 @@@ -// -*- mode: cpp; mode: fold -*- +// -*- mode: c++; mode: fold -*- // Description /*{{{*/ // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $ /* ###################################################################### @@@ -38,78 -38,13 +38,75 @@@ #ifndef PKGLIB_DEPCACHE_H #define PKGLIB_DEPCACHE_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/depcache.h" - #endif #include #include +#include + +#include + class pkgDepCache : protected pkgCache::Namespace { public: + + /** \brief An arbitrary predicate on packages. */ + class InRootSetFunc + { + public: + virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;}; + virtual ~InRootSetFunc() {}; + }; + + private: + /** \brief Mark a single package and all its unmarked important + * dependencies during mark-and-sweep. + * + * Recursively invokes itself to mark all dependencies of the + * package. + * + * \param pkg The package to mark. + * + * \param ver The version of the package that is to be marked. + * + * \param follow_recommends If \b true, recommendations of the + * package will be recursively marked. + * + * \param follow_suggests If \b true, suggestions of the package + * will be recursively marked. + */ + void MarkPackage(const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests); + + /** \brief Update the Marked field of all packages. + * + * Each package's StateCache::Marked field will be set to \b true + * if and only if it can be reached from the root set. By + * default, the root set consists of the set of manually installed + * or essential packages, but it can be extended using the + * parameter #rootFunc. + * + * \param rootFunc A callback that can be used to add extra + * packages to the root set. + * + * \return \b false if an error occured. + */ + bool MarkRequired(InRootSetFunc &rootFunc); + + /** \brief Set the StateCache::Garbage flag on all packages that + * should be removed. + * + * Packages that were not marked by the last call to #MarkRequired + * are tested to see whether they are actually garbage. If so, + * they are marked as such. + * + * \return \b false if an error occured. + */ + bool Sweep(); + + public: // These flags are used in DepState enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2), @@@ -125,84 -60,6 +122,84 @@@ enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; + + /** \brief Represents an active action group. + * + * An action group is a group of actions that are currently being + * performed. While an active group is active, certain routine + * clean-up actions that would normally be performed after every + * cache operation are delayed until the action group is + * completed. This is necessary primarily to avoid inefficiencies + * when modifying a large number of packages at once. + * + * This class represents an active action group. Creating an + * instance will create an action group; destroying one will + * destroy the corresponding action group. + * + * The following operations are suppressed by this class: + * + * - Keeping the Marked and Garbage flags up to date. + * + * \note This can be used in the future to easily accumulate + * atomic actions for undo or to display "what apt did anyway"; + * e.g., change the counter of how many action groups are active + * to a std::set of pointers to them and use those to store + * information about what happened in a group in the group. + */ + class ActionGroup + { + pkgDepCache &cache; + + bool released; + + /** Action groups are noncopyable. */ + ActionGroup(const ActionGroup &other); + public: + /** \brief Create a new ActionGroup. + * + * \param cache The cache that this ActionGroup should + * manipulate. + * + * As long as this object exists, no automatic cleanup + * operations will be undertaken. + */ + ActionGroup(pkgDepCache &cache); + + /** \brief Clean up the action group before it is destroyed. + * + * If it is destroyed later, no second cleanup wil be run. + */ + void release(); + + /** \brief Destroy the action group. + * + * If this is the last action group, the automatic cache + * cleanup operations will be undertaken. + */ + ~ActionGroup(); + }; + + /** \brief Returns \b true for packages matching a regular + * expression in APT::NeverAutoRemove. + */ + class DefaultRootSetFunc : public InRootSetFunc + { + std::vector rootSetRegexp; + bool constructedSuccessfully; + + public: + DefaultRootSetFunc(); + ~DefaultRootSetFunc(); + + /** \return \b true if the class initialized successfully, \b + * false otherwise. Used to avoid throwing an exception, since + * APT classes generally don't. + */ + bool wasConstructedSuccessfully() const { return constructedSuccessfully; } + + bool InRootSet(const pkgCache::PkgIterator &pkg); + }; + struct StateCache { // Epoch stripped text versions of the two version fields @@@ -219,17 -76,6 +216,17 @@@ unsigned short Flags; unsigned short iFlags; // Internal flags + /** \brief \b true if this package can be reached from the root set. */ + bool Marked; + + /** \brief \b true if this package is unused and should be removed. + * + * This differs from !#Marked, because it is possible that some + * unreachable packages will be protected from becoming + * garbage. + */ + bool Garbage; + // Various tree indicators signed char Status; // -1,0,1,2 unsigned char Mode; // ModeList @@@ -248,9 -94,7 +245,9 @@@ inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;}; inline bool Held() const {return Status != 0 && Keep();}; inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; + inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;}; inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; + inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;}; inline bool Install() const {return Mode == ModeInstall;}; inline VerIterator InstVerIter(pkgCache &Cache) {return VerIterator(Cache,InstallVer);}; @@@ -272,14 -116,6 +269,14 @@@ virtual ~Policy() {}; }; + + private: + /** The number of open "action groups"; certain post-action + * operations are suppressed if this number is > 0. + */ + int group_level; + + friend class ActionGroup; protected: @@@ -294,7 -130,6 +291,7 @@@ unsigned long iDelCount; unsigned long iKeepCount; unsigned long iBrokenCount; + unsigned long iPolicyBrokenCount; unsigned long iBadCount; Policy *delLocalPolicy; // For memory clean up.. @@@ -344,69 -179,16 +341,69 @@@ inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];}; inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];}; - // Manipulators - void MarkKeep(PkgIterator const &Pkg,bool Soft = false); + /** \return A function identifying packages in the root set other + * than manually installed packages and essential packages, or \b + * NULL if an error occurs. + * + * \todo Is this the best place for this function? Perhaps the + * settings for mark-and-sweep should be stored in a single + * external class? + */ + virtual InRootSetFunc *GetRootSetFunc(); + + /** \return \b true if the garbage collector should follow recommendations. + */ + virtual bool MarkFollowsRecommends(); + + /** \return \b true if the garbage collector should follow suggestions. + */ + virtual bool MarkFollowsSuggests(); + + /** \brief Update the Marked and Garbage fields of all packages. + * + * This routine is implicitly invoked after all state manipulators + * and when an ActionGroup is destroyed. It invokes #MarkRequired + * and #Sweep to do its dirty work. + * + * \param rootFunc A predicate that returns \b true for packages + * that should be added to the root set. + */ + bool MarkAndSweep(InRootSetFunc &rootFunc) + { + return MarkRequired(rootFunc) && Sweep(); + } + + bool MarkAndSweep() + { + std::auto_ptr f(GetRootSetFunc()); + if(f.get() != NULL) + return MarkAndSweep(*f.get()); + else + return false; + } + + /** \name State Manipulators + */ + // @{ + void MarkKeep(PkgIterator const &Pkg, bool Soft = false, + bool FromUser = true); void MarkDelete(PkgIterator const &Pkg,bool Purge = false); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, - unsigned long Depth = 0); + unsigned long Depth = 0, bool FromUser = true, + bool ForceImportantDeps = false); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); + + /** Set the "is automatically installed" flag of Pkg. */ + void MarkAuto(const PkgIterator &Pkg, bool Auto); + // @} // This is for debuging void Update(OpProgress *Prog = 0); + + // read persistent states + bool readStateFile(OpProgress *prog); + bool writeStateFile(OpProgress *prog, bool InstalledOnly=false); // Size queries inline double UsrSize() {return iUsrSize;}; @@@ -415,7 -197,6 +412,7 @@@ inline unsigned long KeepCount() {return iKeepCount;}; inline unsigned long InstCount() {return iInstCount;}; inline unsigned long BrokenCount() {return iBrokenCount;}; + inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;}; inline unsigned long BadCount() {return iBadCount;}; bool Init(OpProgress *Prog); diff --combined apt-pkg/indexfile.cc index fad38772b,63f692c1d..2dda2d892 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@@ -8,15 -8,8 +8,11 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/indexfile.h" - #endif - +#include #include #include + +#include /*}}}*/ // Global list of Item supported @@@ -70,63 -63,3 +66,63 @@@ string pkgIndexFile::SourceInfo(pkgSrcR return string(); } /*}}}*/ +// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgIndexFile::TranslationsAvailable() +{ + const string Translation = _config->Find("APT::Acquire::Translation", "environment"); + + if (Translation.compare("none") != 0) + return CheckLanguageCode(LanguageCode().c_str()); + else + return false; +} + /*}}}*/ +// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/ +// --------------------------------------------------------------------- +/* */ +/* common cases: de_DE, de_DE@euro, de_DE.UTF-8, de_DE.UTF-8@euro, + de_DE.ISO8859-1, tig_ER + more in /etc/gdm/locale.conf +*/ + +bool pkgIndexFile::CheckLanguageCode(const char *Lang) +{ + if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_')) + return true; + + if (strcmp(Lang,"C") != 0) + _error->Warning("Wrong language code %s", Lang); + + return false; +} + /*}}}*/ +// IndexFile::LanguageCode - Return the Language Code /*{{{*/ +// --------------------------------------------------------------------- +/* return the language code */ +string pkgIndexFile::LanguageCode() +{ + const string Translation = _config->Find("APT::Acquire::Translation", "environment"); + + if (Translation.compare("environment") == 0) + { + string lang = std::setlocale(LC_MESSAGES,NULL); + + // we have a mapping of the language codes that contains all the language + // codes that need the country code as well + // (like pt_BR, pt_PT, sv_SE, zh_*, en_*) + char *need_full_langcode[] = { "pt","sv","zh","en", NULL }; + for(char **s = need_full_langcode;*s != NULL; s++) + if(lang.find(*s) == 0) + return lang.substr(0,5); + + if(lang.size() > 2) + return lang.substr(0,2); + else + return lang; + } + else + return Translation; +} + /*}}}*/ diff --combined apt-pkg/indexfile.h index d5d1cf57a,f1c0268b8..3cc501629 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@@ -5,11 -5,10 +5,11 @@@ Index File - Abstraction for an index of archive/source file. - There are 3 primary sorts of index files, all represented by this + There are 4 primary sorts of index files, all represented by this class: Binary index files + Binary translation files Bianry index files decribing the local system Source index files @@@ -22,9 -21,6 +22,6 @@@ #ifndef PKGLIB_INDEXFILE_H #define PKGLIB_INDEXFILE_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/indexfile.h" - #endif #include #include @@@ -81,10 -77,6 +78,10 @@@ class pkgIndexFil virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return true;}; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; + static bool TranslationsAvailable(); + static bool CheckLanguageCode(const char *Lang); + static string LanguageCode(); + bool IsTrusted() const { return Trusted; }; pkgIndexFile(bool Trusted): Trusted(Trusted) {}; diff --combined apt-pkg/orderlist.cc index 61d8d914e,7302f02b6..616714e29 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@@ -63,9 -63,6 +63,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/orderlist.h" - #endif #include #include #include @@@ -491,13 -488,11 +488,13 @@@ bool pkgOrderList::VisitProvides(DepIte continue; if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && Cache[Pkg].InstallVer != *I) continue; if ((D->Type == pkgCache::Dep::Conflicts || + D->Type == pkgCache::Dep::DpkgBreaks || D->Type == pkgCache::Dep::Obsoletes) && (Version *)Pkg.CurrentVer() != *I) continue; @@@ -632,7 -627,6 +629,7 @@@ bool pkgOrderList::DepUnPackCrit(DepIte /* Forward critical dependencies MUST be correct before the package can be unpacked. */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && D->Type != pkgCache::Dep::PreDepends) continue; @@@ -671,7 -665,7 +668,7 @@@ } return true; } - /*}}}*/ + // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/ // --------------------------------------------------------------------- /* Critical PreDepends (also configure immediate and essential) strives to @@@ -806,20 -800,9 +803,20 @@@ bool pkgOrderList::DepUnPackDep(DepIter return false; } else + { if (D->Type == pkgCache::Dep::Depends) if (VisitProvides(D,false) == false) return false; + + if (D->Type == pkgCache::Dep::DpkgBreaks) + { + if (CheckDep(D) == true) + continue; + + if (VisitNode(D.TargetPkg()) == false) + return false; + } + } } return true; } @@@ -967,7 -950,6 +964,7 @@@ bool pkgOrderList::CheckDep(DepIterato /* Conflicts requires that all versions are not present, depends just needs one */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes) { /* Try to find something that does not have the after flag set diff --combined apt-pkg/packagemanager.cc index 1e57d6455,8b94e1206..10e2858ed --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@@ -13,10 -13,6 +13,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/packagemanager.h" - #endif - #include #include #include @@@ -95,10 -91,9 +91,10 @@@ bool pkgPackageManager::GetArchives(pkg be downloaded. */ bool pkgPackageManager::FixMissing() { + pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Resolve(&Cache); List->SetFileList(FileNames); - + bool Bad = false; for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { @@@ -107,7 -102,7 +103,7 @@@ // Okay, this file is missing and we need it. Mark it for keep Bad = true; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } // We have to empty the list otherwise it will not have the new changes @@@ -632,11 -627,14 +628,11 @@@ pkgPackageManager::OrderResult pkgPacka // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int status_fd) +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) { - OrderResult Res = OrderInstall(); - if(Debug) - std::clog << "OrderInstall() returned: " << Res << std::endl; - if (Res != Failed) - if (Go(status_fd) == false) - return Failed; - return Res; + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(statusFd); } /*}}}*/ diff --combined apt-pkg/packagemanager.h index 48f53576c,35cdca913..53600fb61 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@@ -23,14 -23,9 +23,11 @@@ #ifndef PKGLIB_PACKAGEMANAGER_H #define PKGLIB_PACKAGEMANAGER_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/packagemanager.h" - #endif #include +#include #include +#include using std::string; @@@ -72,39 -67,13 +69,39 @@@ class pkgPackageManager : protected pkg virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; virtual bool Go(int statusFd=-1) {return true;}; virtual void Reset() {}; - + + // the result of the operation + OrderResult Res; + public: // Main action members bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, pkgRecords *Recs); - OrderResult DoInstall(int statusFd=-1); + + // Do the installation + OrderResult DoInstall(int statusFd=-1); + + // stuff that needs to be done before the fork() of a library that + // uses apt + OrderResult DoInstallPreFork() { + Res = OrderInstall(); + return Res; + }; + + // stuff that needs to be done after the fork + OrderResult DoInstallPostFork(int statusFd=-1) { + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + // if all was fine update the state file + if(Res == Completed) { + Cache.writeStateFile(NULL); + } + return Res; + }; + bool FixMissing(); pkgPackageManager(pkgDepCache *Cache); diff --combined apt-pkg/pkgcache.cc index 93ad56641,5672e60a4..7e3b9d78c --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@@ -20,13 -20,7 +20,8 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/pkgcache.h" - #pragma implementation "apt-pkg/cacheiterators.h" - #endif - #include +#include #include #include #include @@@ -44,7 -38,6 +39,7 @@@ using std::string; + // Cache::Header::Header - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Simply initialize the header */ @@@ -54,7 -47,7 +49,7 @@@ pkgCache::Header::Header( /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ - MajorVersion = 4; + MajorVersion = 6; MinorVersion = 0; Dirty = false; @@@ -62,22 -55,17 +57,22 @@@ PackageSz = sizeof(pkgCache::Package); PackageFileSz = sizeof(pkgCache::PackageFile); VersionSz = sizeof(pkgCache::Version); + DescriptionSz = sizeof(pkgCache::Description); DependencySz = sizeof(pkgCache::Dependency); ProvidesSz = sizeof(pkgCache::Provides); VerFileSz = sizeof(pkgCache::VerFile); + DescFileSz = sizeof(pkgCache::DescFile); PackageCount = 0; VersionCount = 0; + DescriptionCount = 0; DependsCount = 0; PackageFileCount = 0; VerFileCount = 0; + DescFileCount = 0; ProvidesCount = 0; MaxVerFileSize = 0; + MaxDescFileSize = 0; FileList = 0; StringList = 0; @@@ -96,10 -84,8 +91,10 @@@ bool pkgCache::Header::CheckSizes(Heade PackageSz == Against.PackageSz && PackageFileSz == Against.PackageFileSz && VersionSz == Against.VersionSz && + DescriptionSz == Against.DescriptionSz && DependencySz == Against.DependencySz && VerFileSz == Against.VerFileSz && + DescFileSz == Against.DescFileSz && ProvidesSz == Against.ProvidesSz) return true; return false; @@@ -124,10 -110,8 +119,10 @@@ bool pkgCache::ReMap( HeaderP = (Header *)Map.Data(); PkgP = (Package *)Map.Data(); VerFileP = (VerFile *)Map.Data(); + DescFileP = (DescFile *)Map.Data(); PkgFileP = (PackageFile *)Map.Data(); VerP = (Version *)Map.Data(); + DescP = (Description *)Map.Data(); ProvideP = (Provides *)Map.Data(); DepP = (Dependency *)Map.Data(); StringItemP = (StringItem *)Map.Data(); @@@ -228,8 -212,8 +223,8 @@@ const char *pkgCache::DepType(unsigned { const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), _("Recommends"),_("Conflicts"),_("Replaces"), - _("Obsoletes")}; - if (Type < 8) + _("Obsoletes"),_("Breaks")}; + if (Type < sizeof(Types)/sizeof(*Types)) return Types[Type]; return ""; } @@@ -246,11 -230,11 +241,11 @@@ 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() {} /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- @@@ -292,11 -276,10 +287,11 @@@ pkgCache::PkgIterator::OkState pkgCache // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ // --------------------------------------------------------------------- /* Currently critical deps are defined as depends, predepends and - conflicts. */ + 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) @@@ -382,7 -365,6 +377,7 @@@ pkgCache::Version **pkgCache::DepIterat continue; if ((Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::DpkgBreaks || Dep->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.ParentPkg()) continue; @@@ -399,7 -381,6 +394,7 @@@ continue; if ((Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::DpkgBreaks || Dep->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.OwnerPkg()) continue; @@@ -613,20 -594,3 +608,20 @@@ string pkgCache::PkgFileIterator::RelSt return Res; } /*}}}*/ +// VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/ +// --------------------------------------------------------------------- +/* return a DescIter for the current locale or the default if none is + * found + */ +pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const +{ + pkgCache::DescIterator DescDefault = DescriptionList(); + pkgCache::DescIterator Desc = DescDefault; + for (; Desc.end() == false; Desc++) + if (pkgIndexFile::LanguageCode() == Desc.LanguageCode()) + break; + if (Desc.end() == true) Desc = DescDefault; + return Desc; +}; + + /*}}}*/ diff --combined apt-pkg/pkgcache.h index 970759492,8e7fc252c..83b7548a3 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@@ -19,9 -19,6 +19,6 @@@ #ifndef PKGLIB_PKGCACHE_H #define PKGLIB_PKGCACHE_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/pkgcache.h" - #endif #include #include @@@ -38,42 -35,32 +35,42 @@@ class pkgCach struct Package; struct PackageFile; struct Version; + struct Description; struct Provides; struct Dependency; struct StringItem; struct VerFile; + struct DescFile; // Iterators class PkgIterator; class VerIterator; + class DescIterator; class DepIterator; class PrvIterator; class PkgFileIterator; class VerFileIterator; + class DescFileIterator; friend class PkgIterator; friend class VerIterator; + friend class DescInterator; friend class DepIterator; friend class PrvIterator; friend class PkgFileIterator; friend class VerFileIterator; + friend class DescFileIterator; class Namespace; // These are all the constants used in the cache structures + + // WARNING - if you change these lists you must also edit + // the stringification in pkgcache.cc and also consider whether + // the cache file will become incompatible. struct Dep { enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, - Conflicts=5,Replaces=6,Obsoletes=7}; + Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8}; enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, Greater=0x4,Equals=0x5,NotEquals=0x6}; }; @@@ -108,10 -95,8 +105,10 @@@ Header *HeaderP; Package *PkgP; VerFile *VerFileP; + DescFile *DescFileP; PackageFile *PkgFileP; Version *VerP; + Description *DescP; Provides *ProvideP; Dependency *DepP; StringItem *StringItemP; @@@ -163,20 -148,16 +160,20 @@@ struct pkgCache::Heade unsigned short PackageSz; unsigned short PackageFileSz; unsigned short VersionSz; + unsigned short DescriptionSz; unsigned short DependencySz; unsigned short ProvidesSz; unsigned short VerFileSz; + unsigned short DescFileSz; // Structure counts unsigned long PackageCount; unsigned long VersionCount; + unsigned long DescriptionCount; unsigned long DependsCount; unsigned long PackageFileCount; unsigned long VerFileCount; + unsigned long DescFileCount; unsigned long ProvidesCount; // Offsets @@@ -185,11 -166,10 +182,11 @@@ map_ptrloc VerSysName; // StringTable map_ptrloc Architecture; // StringTable unsigned long MaxVerFileSize; + unsigned long MaxDescFileSize; /* Allocation pools, there should be one of these for each structure excluding the header */ - DynamicMMap::Pool Pools[7]; + DynamicMMap::Pool Pools[8]; // Rapid package name lookup map_ptrloc HashTable[2*1048]; @@@ -210,7 -190,7 +207,7 @@@ struct pkgCache::Packag map_ptrloc NextPackage; // Package map_ptrloc RevDepends; // Dependency map_ptrloc ProvidesList; // Provides - + // Install/Remove/Purge etc unsigned char SelectedState; // What unsigned char InstState; // Flags @@@ -249,14 -229,6 +246,14 @@@ struct pkgCache::VerFil unsigned short Size; }; +struct pkgCache::DescFile +{ + map_ptrloc File; // PackageFile + map_ptrloc NextFile; // PkgVerFile + map_ptrloc Offset; // File offset + unsigned short Size; +}; + struct pkgCache::Version { map_ptrloc VerStr; // Stringtable @@@ -266,7 -238,6 +263,7 @@@ // Lists map_ptrloc FileList; // VerFile map_ptrloc NextVer; // Version + map_ptrloc DescriptionList; // Description map_ptrloc DependsList; // Dependency map_ptrloc ParentPkg; // Package map_ptrloc ProvidesList; // Provides @@@ -278,22 -249,6 +275,22 @@@ unsigned char Priority; }; +struct pkgCache::Description +{ + // Language Code store the description translation language code. If + // the value has a 0 lenght then this is readed using the Package + // file else the Translation-CODE are used. + map_ptrloc language_code; // StringTable + map_ptrloc md5sum; // StringTable + + // Linked list + map_ptrloc FileList; // DescFile + map_ptrloc NextDesc; // Description + map_ptrloc ParentPkg; // Package + + unsigned short ID; +}; + struct pkgCache::Dependency { map_ptrloc Version; // Stringtable @@@ -341,13 -296,11 +338,13 @@@ class pkgCache::Namespac typedef pkgCache::PkgIterator PkgIterator; typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::DescIterator DescIterator; typedef pkgCache::DepIterator DepIterator; typedef pkgCache::PrvIterator PrvIterator; typedef pkgCache::PkgFileIterator PkgFileIterator; typedef pkgCache::VerFileIterator VerFileIterator; typedef pkgCache::Version Version; + typedef pkgCache::Description Description; typedef pkgCache::Package Package; typedef pkgCache::Header Header; typedef pkgCache::Dep Dep; diff --combined apt-pkg/pkgcachegen.cc index 8ec6a1719,1c93b32a3..ce9b96980 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@@ -10,10 -10,6 +10,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/pkgcachegen.h" - #endif - #define APT_COMPATIBILITY 986 #include @@@ -26,8 -22,6 +22,8 @@@ #include #include +#include + #include #include @@@ -127,46 -121,16 +123,46 @@@ bool pkgCacheGenerator::MergeList(ListP string Version = List.Version(); if (Version.empty() == true) { + // we first process the package, then the descriptions + // (this has the bonus that we get MMap error when we run out + // of MMap space) if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false) return _error->Error(_("Error occurred while processing %s (UsePackage1)"), PackageName.c_str()); + + // Find the right version to write the description + MD5SumValue CurMd5 = List.Description_md5(); + pkgCache::VerIterator Ver = Pkg.VersionList(); + map_ptrloc *LastVer = &Pkg->VersionList; + + for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) + { + pkgCache::DescIterator Desc = Ver.DescriptionList(); + map_ptrloc *LastDesc = &Ver->DescriptionList; + + for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++) + { + + if (MD5SumValue(Desc.md5()) == CurMd5) + { + // Add new description + *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc); + Desc->ParentPkg = Pkg.Index(); + + if (NewFileDesc(Desc,List) == false) + return _error->Error(_("Error occured while processing %s (NewFileDesc1)"),PackageName.c_str()); + break; + } + } + } + continue; } pkgCache::VerIterator Ver = Pkg.VersionList(); - map_ptrloc *Last = &Pkg->VersionList; + map_ptrloc *LastVer = &Pkg->VersionList; int Res = 1; - for (; Ver.end() == false; Last = &Ver->NextVer, Ver++) + for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) { Res = Cache.VS->CmpVersion(Version,Ver.VerStr()); if (Res >= 0) @@@ -200,7 -164,7 +196,7 @@@ // Skip to the end of the same version set. if (Res == 0) { - for (; Ver.end() == false; Last = &Ver->NextVer, Ver++) + for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) { Res = Cache.VS->CmpVersion(Version,Ver.VerStr()); if (Res != 0) @@@ -209,10 -173,9 +205,10 @@@ } // Add a new version - *Last = NewVersion(Ver,Version,*Last); + *LastVer = NewVersion(Ver,Version,*LastVer); Ver->ParentPkg = Pkg.Index(); Ver->Hash = Hash; + if (List.NewVersion(Ver) == false) return _error->Error(_("Error occurred while processing %s (NewVersion1)"), PackageName.c_str()); @@@ -232,21 -195,6 +228,21 @@@ FoundFileDeps |= List.HasFileDeps(); return true; } + + /* Record the Description data. Description data always exist in + Packages and Translation-* files. */ + pkgCache::DescIterator Desc = Ver.DescriptionList(); + map_ptrloc *LastDesc = &Ver->DescriptionList; + + // Skip to the end of description set + for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++); + + // Add new description + *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc); + Desc->ParentPkg = Pkg.Index(); + + if (NewFileDesc(Desc,List) == false) + return _error->Error(_("Error occured while processing %s (NewFileDesc2)"),PackageName.c_str()); } FoundFileDeps |= List.HasFileDeps(); @@@ -257,9 -205,6 +253,9 @@@ if (Cache.HeaderP->VersionCount >= (1ULL<<(sizeof(Cache.VerP->ID)*8))-1) return _error->Error(_("Wow, you exceeded the number of versions " "this APT is capable of.")); + if (Cache.HeaderP->DescriptionCount >= (1ULL<<(sizeof(Cache.DescP->ID)*8))-1) + return _error->Error(_("Wow, you exceeded the number of descriptions " + "this APT is capable of.")); if (Cache.HeaderP->DependsCount >= (1ULL<<(sizeof(Cache.DepP->ID)*8))-1ULL) return _error->Error(_("Wow, you exceeded the number of dependencies " "this APT is capable of.")); @@@ -322,7 -267,7 +318,7 @@@ bool pkgCacheGenerator::NewPackage(pkgC Pkg = Cache.FindPkg(Name); if (Pkg.end() == false) return true; - + // Get a structure unsigned long Package = Map.Allocate(sizeof(pkgCache::Package)); if (Package == 0) @@@ -400,62 -345,6 +396,62 @@@ unsigned long pkgCacheGenerator::NewVer return Version; } /*}}}*/ +// CacheGenerator::NewFileDesc - Create a new File<->Desc association /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc, + ListParser &List) +{ + if (CurrentFile == 0) + return true; + + // Get a structure + unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile)); + if (DescFile == 0) + return 0; + + pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile); + DF->File = CurrentFile - Cache.PkgFileP; + + // Link it to the end of the list + map_ptrloc *Last = &Desc->FileList; + for (pkgCache::DescFileIterator D = Desc.FileList(); D.end() == false; D++) + Last = &D->NextFile; + + DF->NextFile = *Last; + *Last = DF.Index(); + + DF->Offset = List.Offset(); + DF->Size = List.Size(); + if (Cache.HeaderP->MaxDescFileSize < DF->Size) + Cache.HeaderP->MaxDescFileSize = DF->Size; + Cache.HeaderP->DescFileCount++; + + return true; +} + /*}}}*/ +// CacheGenerator::NewDescription - Create a new Description /*{{{*/ +// --------------------------------------------------------------------- +/* This puts a description structure in the linked list */ +map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, + const string &Lang, const MD5SumValue &md5sum, + map_ptrloc Next) +{ + // Get a structure + map_ptrloc Description = Map.Allocate(sizeof(pkgCache::Description)); + if (Description == 0) + return 0; + + // Fill it in + Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); + Desc->NextDesc = Next; + Desc->ID = Cache.HeaderP->DescriptionCount++; + Desc->language_code = Map.WriteString(Lang); + Desc->md5sum = Map.WriteString(md5sum.Value()); + + return Description; +} + /*}}}*/ // ListParser::NewDepends - Create a dependency element /*{{{*/ // --------------------------------------------------------------------- /* This creates a dependency element in the tree. It is linked to the @@@ -678,10 -567,8 +674,10 @@@ static bool CheckValidity(const string if ((*Start)->Exists() == false) { +#if 0 // mvo: we no longer give a message here (Default Sources spec) _error->WarningE("stat",_("Couldn't stat source package list %s"), (*Start)->Describe().c_str()); +#endif continue; } @@@ -689,7 -576,7 +685,7 @@@ pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache); if (File.end() == true) return false; - + Visited[File->ID] = true; } @@@ -785,7 -672,7 +781,7 @@@ static bool BuildCache(pkgCacheGenerato bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, MMap **OutMap,bool AllowMem) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",12*1024*1024); + unsigned long MapSize = _config->FindI("APT::Cache-Limit",16*1024*1024); vector Files; for (vector::const_iterator i = List.begin(); @@@ -932,7 -819,7 +928,7 @@@ /* */ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",8*1024*1024); + unsigned long MapSize = _config->FindI("APT::Cache-Limit",12*1024*1024); vector Files; unsigned long EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) diff --combined apt-pkg/pkgcachegen.h index fae1a60a6,70616c0a8..a47b097b3 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@@ -19,12 -19,8 +19,9 @@@ #ifndef PKGLIB_PKGCACHEGEN_H #define PKGLIB_PKGCACHEGEN_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/pkgcachegen.h" - #endif #include +#include class pkgSourceList; class OpProgress; @@@ -56,9 -52,7 +53,9 @@@ class pkgCacheGenerato bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Pkg); bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); + bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List); unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next); + map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next); public: @@@ -111,9 -105,6 +108,9 @@@ class pkgCacheGenerator::ListParse virtual string Package() = 0; virtual string Version() = 0; virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; + virtual string Description() = 0; + virtual string DescriptionLanguage() = 0; + virtual MD5SumValue Description_md5() = 0; virtual unsigned short VersionHash() = 0; virtual bool UsePackage(pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) = 0; diff --combined apt-pkg/pkgrecords.cc index 456b5aef4,dc43735a6..d251bee41 --- a/apt-pkg/pkgrecords.cc +++ b/apt-pkg/pkgrecords.cc @@@ -9,9 -9,6 +9,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/pkgrecords.h" - #endif #include #include #include @@@ -23,9 -20,11 +20,9 @@@ // Records::pkgRecords - Constructor /*{{{*/ // --------------------------------------------------------------------- /* This will create the necessary structures to access the status files */ -pkgRecords::pkgRecords(pkgCache &Cache) : Cache(Cache), Files(0) +pkgRecords::pkgRecords(pkgCache &Cache) : Cache(Cache), + Files(Cache.HeaderP->PackageFileCount) { - Files = new Parser *[Cache.HeaderP->PackageFileCount]; - memset(Files,0,sizeof(*Files)*Cache.HeaderP->PackageFileCount); - for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++) { @@@ -47,13 -46,9 +44,13 @@@ /* */ pkgRecords::~pkgRecords() { - for (unsigned I = 0; I != Cache.HeaderP->PackageFileCount; I++) - delete Files[I]; - delete [] Files; + for ( vector::iterator it = Files.begin(); + it != Files.end(); + ++it) + { + delete *it; + } + } /*}}}*/ // Records::Lookup - Get a parser for the package version file /*{{{*/ @@@ -65,12 -60,3 +62,12 @@@ pkgRecords::Parser &pkgRecords::Lookup( return *Files[Ver.File()->ID]; } /*}}}*/ +// Records::Lookup - Get a parser for the package description file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRecords::Parser &pkgRecords::Lookup(pkgCache::DescFileIterator const &Desc) +{ + Files[Desc.File()->ID]->Jump(Desc); + return *Files[Desc.File()->ID]; +} + /*}}}*/ diff --combined apt-pkg/pkgrecords.h index ad3946c1b,d431101fe..bae5284ab --- a/apt-pkg/pkgrecords.h +++ b/apt-pkg/pkgrecords.h @@@ -17,13 -17,9 +17,10 @@@ #ifndef PKGLIB_PKGRECORDS_H #define PKGLIB_PKGRECORDS_H - #ifdef __GNUG__ - #pragma interface "apt-pkg/pkgrecords.h" - #endif #include #include +#include class pkgRecords { @@@ -33,13 -29,12 +30,13 @@@ private: pkgCache &Cache; - Parser **Files; - + std::vectorFiles; + public: // Lookup function Parser &Lookup(pkgCache::VerFileIterator const &Ver); + Parser &Lookup(pkgCache::DescFileIterator const &Desc); // Construct destruct pkgRecords(pkgCache &Cache); @@@ -51,7 -46,6 +48,7 @@@ class pkgRecords::Parse protected: virtual bool Jump(pkgCache::VerFileIterator const &Ver) = 0; + virtual bool Jump(pkgCache::DescFileIterator const &Desc) = 0; public: friend class pkgRecords; diff --combined apt-pkg/policy.cc index 35a50425b,795f1d787..8b083fd44 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@@ -23,9 -23,6 +23,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/policy.h" - #endif #include #include #include @@@ -36,7 -33,6 +33,7 @@@ #include #include +#include /*}}}*/ using namespace std; @@@ -301,13 -297,7 +298,13 @@@ bool ReadPinFile(pkgPolicy &Plcy,strin continue; } - Plcy.CreatePin(Type,Name,string(Word,End),priority); + istringstream s(Name); + string pkg; + while(!s.eof()) + { + s >> pkg; + Plcy.CreatePin(Type, pkg, string(Word,End),priority); + }; } Plcy.InitDefaults(); diff --combined apt-pkg/tagfile.cc index 8700dd17d,85e6abfd7..0ae6950f3 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@@ -11,10 -11,6 +11,6 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ - #ifdef __GNUG__ - #pragma implementation "apt-pkg/tagfile.h" - #endif - #include #include #include @@@ -411,7 -407,6 +407,7 @@@ static const char *iTFRewritePackageOrd "Section", "Installed-Size", "Maintainer", + "Original-Maintainer", "Architecture", "Source", "Version", @@@ -424,7 -419,6 +420,7 @@@ "Recommends", "Suggests", "Conflicts", + "Breaks", "Conffiles", "Filename", "Size", @@@ -441,7 -435,6 +437,7 @@@ static const char *iTFRewriteSourceOrde "Priority", "Section", "Maintainer", + "Original-Maintainer", "Build-Depends", "Build-Depends-Indep", "Build-Conflicts", diff --combined po/apt-all.pot index b55c31ff4,4c354136a..addf713f8 --- a/po/apt-all.pot +++ b/po/apt-all.pot @@@ -7,7 -7,7 +7,7 @@@ msgid " msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2007-04-27 15:16+0200\n" + "POT-Creation-Date: 2006-10-02 15:46+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@@ -1477,16 -1477,16 +1477,16 @@@ msgstr " msgid "Wrong CD-ROM" msgstr "" -#: methods/cdrom.cc:164 +#: methods/cdrom.cc:166 #, c-format msgid "Unable to unmount the CD-ROM in %s, it may still be in use." msgstr "" -#: methods/cdrom.cc:169 +#: methods/cdrom.cc:171 msgid "Disk not found." msgstr "" -#: methods/cdrom.cc:177 methods/file.cc:79 methods/rsh.cc:264 +#: methods/cdrom.cc:179 methods/file.cc:79 methods/rsh.cc:264 msgid "File not found" msgstr "" @@@ -1621,7 -1621,7 +1621,7 @@@ msgstr " msgid "Unable to accept connection" msgstr "" -#: methods/ftp.cc:864 methods/http.cc:958 methods/rsh.cc:303 +#: methods/ftp.cc:864 methods/http.cc:959 methods/rsh.cc:303 msgid "Problem hashing file" msgstr "" @@@ -1752,76 -1752,76 +1752,76 @@@ msgstr " msgid "Read error from %s process" msgstr "" -#: methods/http.cc:376 +#: methods/http.cc:377 msgid "Waiting for headers" msgstr "" -#: methods/http.cc:522 +#: methods/http.cc:523 #, c-format msgid "Got a single header line over %u chars" msgstr "" -#: methods/http.cc:530 +#: methods/http.cc:531 msgid "Bad header line" msgstr "" -#: methods/http.cc:549 methods/http.cc:556 +#: methods/http.cc:550 methods/http.cc:557 msgid "The HTTP server sent an invalid reply header" msgstr "" -#: methods/http.cc:585 +#: methods/http.cc:586 msgid "The HTTP server sent an invalid Content-Length header" msgstr "" -#: methods/http.cc:600 +#: methods/http.cc:601 msgid "The HTTP server sent an invalid Content-Range header" msgstr "" -#: methods/http.cc:602 +#: methods/http.cc:603 msgid "This HTTP server has broken range support" msgstr "" -#: methods/http.cc:626 +#: methods/http.cc:627 msgid "Unknown date format" msgstr "" -#: methods/http.cc:773 +#: methods/http.cc:774 msgid "Select failed" msgstr "" -#: methods/http.cc:778 +#: methods/http.cc:779 msgid "Connection timed out" msgstr "" -#: methods/http.cc:801 +#: methods/http.cc:802 msgid "Error writing to output file" msgstr "" -#: methods/http.cc:832 +#: methods/http.cc:833 msgid "Error writing to file" msgstr "" -#: methods/http.cc:860 +#: methods/http.cc:861 msgid "Error writing to the file" msgstr "" -#: methods/http.cc:874 +#: methods/http.cc:875 msgid "Error reading from server. Remote end closed connection" msgstr "" -#: methods/http.cc:876 +#: methods/http.cc:877 msgid "Error reading from server" msgstr "" -#: methods/http.cc:1107 +#: methods/http.cc:1108 msgid "Bad header data" msgstr "" -#: methods/http.cc:1124 +#: methods/http.cc:1125 msgid "Connection failed" msgstr "" -#: methods/http.cc:1215 +#: methods/http.cc:1216 msgid "Internal error" msgstr "" @@@ -1894,12 -1894,12 +1894,12 @@@ msgstr " msgid "Syntax error %s:%u: Extra junk at end of file" msgstr "" -#: apt-pkg/contrib/progress.cc:154 +#: apt-pkg/contrib/progress.cc:155 #, c-format msgid "%c%s... Error!" msgstr "" -#: apt-pkg/contrib/progress.cc:156 +#: apt-pkg/contrib/progress.cc:157 #, c-format msgid "%c%s... Done" msgstr "" @@@ -2031,84 -2031,84 +2031,84 @@@ msgstr " msgid "Problem syncing the file" msgstr "" - #: apt-pkg/pkgcache.cc:126 + #: apt-pkg/pkgcache.cc:121 msgid "Empty package cache" msgstr "" - #: apt-pkg/pkgcache.cc:132 + #: apt-pkg/pkgcache.cc:127 msgid "The package cache file is corrupted" msgstr "" - #: apt-pkg/pkgcache.cc:137 + #: apt-pkg/pkgcache.cc:132 msgid "The package cache file is an incompatible version" msgstr "" - #: apt-pkg/pkgcache.cc:142 + #: apt-pkg/pkgcache.cc:137 #, c-format msgid "This APT does not support the versioning system '%s'" msgstr "" - #: apt-pkg/pkgcache.cc:147 + #: apt-pkg/pkgcache.cc:142 msgid "The package cache was built for a different architecture" msgstr "" - #: apt-pkg/pkgcache.cc:218 + #: apt-pkg/pkgcache.cc:213 msgid "Depends" msgstr "" - #: apt-pkg/pkgcache.cc:218 + #: apt-pkg/pkgcache.cc:213 msgid "PreDepends" msgstr "" - #: apt-pkg/pkgcache.cc:218 + #: apt-pkg/pkgcache.cc:213 msgid "Suggests" msgstr "" - #: apt-pkg/pkgcache.cc:219 + #: apt-pkg/pkgcache.cc:214 msgid "Recommends" msgstr "" - #: apt-pkg/pkgcache.cc:219 + #: apt-pkg/pkgcache.cc:214 msgid "Conflicts" msgstr "" - #: apt-pkg/pkgcache.cc:219 + #: apt-pkg/pkgcache.cc:214 msgid "Replaces" msgstr "" - #: apt-pkg/pkgcache.cc:220 + #: apt-pkg/pkgcache.cc:215 msgid "Obsoletes" msgstr "" - #: apt-pkg/pkgcache.cc:231 + #: apt-pkg/pkgcache.cc:226 msgid "important" msgstr "" - #: apt-pkg/pkgcache.cc:231 + #: apt-pkg/pkgcache.cc:226 msgid "required" msgstr "" - #: apt-pkg/pkgcache.cc:231 + #: apt-pkg/pkgcache.cc:226 msgid "standard" msgstr "" - #: apt-pkg/pkgcache.cc:232 + #: apt-pkg/pkgcache.cc:227 msgid "optional" msgstr "" - #: apt-pkg/pkgcache.cc:232 + #: apt-pkg/pkgcache.cc:227 msgid "extra" msgstr "" - #: apt-pkg/depcache.cc:61 apt-pkg/depcache.cc:90 + #: apt-pkg/depcache.cc:58 apt-pkg/depcache.cc:87 msgid "Building dependency tree" msgstr "" - #: apt-pkg/depcache.cc:62 + #: apt-pkg/depcache.cc:59 msgid "Candidate versions" msgstr "" - #: apt-pkg/depcache.cc:91 + #: apt-pkg/depcache.cc:88 msgid "Dependency generation" msgstr "" @@@ -2191,13 -2191,13 +2191,13 @@@ msgid " "The package %s needs to be reinstalled, but I can't find an archive for it." msgstr "" -#: apt-pkg/algorithms.cc:1059 +#: apt-pkg/algorithms.cc:1066 msgid "" "Error, pkgProblemResolver::Resolve generated breaks, this may be caused by " "held packages." msgstr "" -#: apt-pkg/algorithms.cc:1061 +#: apt-pkg/algorithms.cc:1068 msgid "Unable to correct problems, you have held broken packages." msgstr "" @@@ -2213,12 -2213,12 +2213,12 @@@ msgstr " #. only show the ETA if it makes sense #. two days -#: apt-pkg/acquire.cc:823 +#: apt-pkg/acquire.cc:830 #, c-format msgid "Retrieving file %li of %li (%s remaining)" msgstr "" -#: apt-pkg/acquire.cc:825 +#: apt-pkg/acquire.cc:832 #, c-format msgid "Retrieving file %li of %li" msgstr "" @@@ -2264,16 -2264,16 +2264,16 @@@ msgstr " msgid "You may want to run apt-get update to correct these problems" msgstr "" -#: apt-pkg/policy.cc:269 +#: apt-pkg/policy.cc:270 msgid "Invalid record in the preferences file, no Package header" msgstr "" -#: apt-pkg/policy.cc:291 +#: apt-pkg/policy.cc:292 #, c-format msgid "Did not understand pin type %s" msgstr "" -#: apt-pkg/policy.cc:299 +#: apt-pkg/policy.cc:300 msgid "No priority (or zero) specified for pin" msgstr "" @@@ -2361,35 -2361,35 +2361,35 @@@ msgstr " msgid "rename failed, %s (%s -> %s)." msgstr "" -#: apt-pkg/acquire-item.cc:236 apt-pkg/acquire-item.cc:945 +#: apt-pkg/acquire-item.cc:243 apt-pkg/acquire-item.cc:952 msgid "MD5Sum mismatch" msgstr "" -#: apt-pkg/acquire-item.cc:640 -msgid "There are no public key available for the following key IDs:\n" +#: apt-pkg/acquire-item.cc:647 +msgid "There is no public key available for the following key IDs:\n" msgstr "" -#: apt-pkg/acquire-item.cc:753 +#: apt-pkg/acquire-item.cc:760 #, c-format msgid "" "I wasn't able to locate a file for the %s package. This might mean you need " "to manually fix this package. (due to missing arch)" msgstr "" -#: apt-pkg/acquire-item.cc:812 +#: apt-pkg/acquire-item.cc:819 #, c-format msgid "" "I wasn't able to locate file for the %s package. This might mean you need to " "manually fix this package." msgstr "" -#: apt-pkg/acquire-item.cc:848 +#: apt-pkg/acquire-item.cc:855 #, c-format msgid "" "The package index files are corrupted. No Filename: field for package %s." msgstr "" -#: apt-pkg/acquire-item.cc:935 +#: apt-pkg/acquire-item.cc:942 msgid "Size mismatch" msgstr "" @@@ -2441,30 -2441,30 +2441,30 @@@ msgstr " msgid "Found %i package indexes, %i source indexes and %i signatures\n" msgstr "" -#: apt-pkg/cdrom.cc:710 +#: apt-pkg/cdrom.cc:712 msgid "That is not a valid name, try again.\n" msgstr "" -#: apt-pkg/cdrom.cc:726 +#: apt-pkg/cdrom.cc:728 #, c-format msgid "" "This disc is called: \n" "'%s'\n" msgstr "" -#: apt-pkg/cdrom.cc:730 +#: apt-pkg/cdrom.cc:732 msgid "Copying package lists..." msgstr "" -#: apt-pkg/cdrom.cc:754 +#: apt-pkg/cdrom.cc:756 msgid "Writing new source list\n" msgstr "" -#: apt-pkg/cdrom.cc:763 +#: apt-pkg/cdrom.cc:765 msgid "Source list entries for this disc are:\n" msgstr "" -#: apt-pkg/cdrom.cc:803 +#: apt-pkg/cdrom.cc:807 msgid "Unmounting CD-ROM..." msgstr ""