From cb6a2b3eaca4353d7f490fb360b98c08d64a2d8c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 14 Jan 2013 07:09:51 +0100 Subject: first iteration that adds support for checksums-{sha512,sha256} --- cmdline/apt-get.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 1bb981b20..68e7f829c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2555,15 +2555,12 @@ bool DoSource(CommandLine &CmdL) if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end()) continue; queued.insert(Last->Index().ArchiveURI(I->Path)); - + // check if we have a file with that md5 sum already localy - if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) + if(!I->Hash.empty() && FileExists(flNotDir(I->Path))) { - FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); - MD5Summation sum; - sum.AddFD(Fd.Fd(), Fd.Size()); - Fd.Close(); - if((string)sum.Result() == I->MD5Hash) + HashString hash_string = HashString(I->Hash); + if(hash_string.VerifyFile(I->Path)) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), flNotDir(I->Path).c_str()); @@ -2572,7 +2569,7 @@ bool DoSource(CommandLine &CmdL) } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->MD5Hash,I->Size, + I->Hash,I->Size, Last->Index().SourceInfo(*Last,*I),Src); } } -- cgit v1.2.3 From 64680d3bf12db6599e93f950546e380e0bd5ddf4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 14 Jan 2013 07:59:52 +0100 Subject: fix skipping of already downloaded files and add some FIXMEs --- cmdline/apt-get.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 68e7f829c..a2a19cd11 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2560,7 +2560,7 @@ bool DoSource(CommandLine &CmdL) if(!I->Hash.empty() && FileExists(flNotDir(I->Path))) { HashString hash_string = HashString(I->Hash); - if(hash_string.VerifyFile(I->Path)) + if(hash_string.VerifyFile(flNotDir(I->Path))) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), flNotDir(I->Path).c_str()); -- cgit v1.2.3 From 2a49601f69e08f06fb2727d869d420daacdd09d5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 23 Apr 2013 08:16:21 +0200 Subject: merge patch from Daniel Hartwig to Show a error message if {,dist-}upgrade is used with additional arguments (closes: #705510) --- cmdline/apt-get.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index eaa50519c..cce80ccfe 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1845,6 +1845,9 @@ bool DoAutomaticRemove(CacheFile &Cache) packages */ bool DoUpgrade(CommandLine &CmdL) { + if (CmdL.FileSize() != 1) + return _error->Error(_("The upgrade command takes no arguments")); + CacheFile Cache; if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) return false; @@ -2178,6 +2181,9 @@ bool DoMarkAuto(CommandLine &CmdL) /* Intelligent upgrader that will install and remove packages at will */ bool DoDistUpgrade(CommandLine &CmdL) { + if (CmdL.FileSize() != 1) + return _error->Error(_("The dist-upgrade command takes no arguments")); + CacheFile Cache; if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) return false; -- cgit v1.2.3 From feab34c5216941ca95aae1a389238a77b662d1de Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Apr 2014 17:59:09 +0200 Subject: add support for apt-get build-dep foo.dsc --- cmdline/apt-get.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index caf69da2a..92384931b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -57,6 +57,9 @@ #include #include +// FIXME: direct include of deb specific header +#include + #include #include #include @@ -1053,12 +1056,23 @@ static bool DoBuildDep(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + pkgSrcRecords::Parser *Last = 0; + vector BuildDeps; + + // support local .dsc files + if (FileExists(*I) && flExtension(*I) == "dsc") + { + // FIXME: add a layer of abstraction + Last = new debDscRecordParser(*I); + Src = *I; + } else { + Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + } if (Last == 0) return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); // Process the build-dependencies - vector BuildDeps; + // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary if (hostArch.empty() == false) { @@ -1071,7 +1085,7 @@ static bool DoBuildDep(CommandLine &CmdL) } else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false) return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str()); - + // Also ensure that build-essential packages are present Configuration::Item const *Opts = _config->Tree("APT::Build-Essential"); if (Opts) -- cgit v1.2.3 From a49e7948029d8219d7cb182fbc1b0adb587691b8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 23 Apr 2014 13:51:48 +0200 Subject: create debIFTypeDscFile type --- cmdline/apt-get.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 92384931b..5418c351b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -57,9 +57,6 @@ #include #include -// FIXME: direct include of deb specific header -#include - #include #include #include @@ -1057,22 +1054,25 @@ static bool DoBuildDep(CommandLine &CmdL) { string Src; pkgSrcRecords::Parser *Last = 0; - vector BuildDeps; - // support local .dsc files - if (FileExists(*I) && flExtension(*I) == "dsc") + // if its a local file (e.g. .dsc) use this + if (FileExists(*I)) { - // FIXME: add a layer of abstraction - Last = new debDscRecordParser(*I); - Src = *I; + // see if we can get a parser for this pkgIndexFile type + string TypeName = flExtension(*I) + " File Source Index"; + pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); + if(Type != NULL) + Last = Type->CreateSrcPkgParser(*I); } else { + // normal case, search the cache for the source file Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); } + if (Last == 0) return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); // Process the build-dependencies - + vector BuildDeps; // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary if (hostArch.empty() == false) { -- cgit v1.2.3 From 77da39b95870498431fc21df65900acc5ce2f7ea Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 25 Apr 2014 09:47:50 +0200 Subject: add support for apt-get build-dep unpacked-source-dir --- cmdline/apt-get.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 5418c351b..6d6ba5ff9 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1055,8 +1055,17 @@ static bool DoBuildDep(CommandLine &CmdL) string Src; pkgSrcRecords::Parser *Last = 0; + // a unpacked debian source tree + if (DirectoryExists(*I)) + { + // FIXME: how can we make this more elegant? + std::string TypeName = "debian/control File Source Index"; + pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); + if(Type != NULL) + Last = Type->CreateSrcPkgParser(*I); + } // if its a local file (e.g. .dsc) use this - if (FileExists(*I)) + else if (FileExists(*I)) { // see if we can get a parser for this pkgIndexFile type string TypeName = flExtension(*I) + " File Source Index"; -- cgit v1.2.3 From 1262d35895c930f3fa49d7b4182cdd7a4a841f74 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 18 Aug 2013 23:27:24 +0200 Subject: use 'best' hash for source authentication Collect all hashes we can get from the source record and put them into a HashStringList so that 'apt-get source' can use it instead of using always the MD5sum. We therefore also deprecate the MD5 struct member in favor of the list. While at it, the parsing of the Files is enhanced so that records which miss "Files" (aka MD5 checksums) are still searched for other checksums as they include just as much data, just not with a nice and catchy name. LP: 1098738 --- cmdline/apt-get.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 1148dbbf3..fc6223989 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -828,19 +828,26 @@ static bool DoSource(CommandLine &CmdL) queued.insert(Last->Index().ArchiveURI(I->Path)); // check if we have a file with that md5 sum already localy - if(!I->Hash.empty() && FileExists(flNotDir(I->Path))) - { - HashString hash_string = HashString(I->Hash); - if(hash_string.VerifyFile(flNotDir(I->Path))) + std::string localFile = flNotDir(I->Path); + if (FileExists(localFile) == true) + if(I->Hashes.VerifyFile(localFile) == true) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), - flNotDir(I->Path).c_str()); + localFile.c_str()); continue; } + + // see if we have a hash (Acquire::ForceHash is the only way to have none) + HashString const * const hs = I->Hashes.find(NULL); + if (hs == NULL && _config->FindB("APT::Get::AllowUnauthenticated",false) == false) + { + ioprintf(c1out, "Skipping download of file '%s' as requested hashsum is not available for authentication\n", + localFile.c_str()); + continue; } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->Hash,I->Size, + hs != NULL ? hs->toStr() : "", I->Size, Last->Index().SourceInfo(*Last,*I),Src); } } -- cgit v1.2.3 From b3501edb7091ca3aa6c2d6d96dc667b8161dd2b9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 19 Aug 2013 00:00:23 +0200 Subject: use HashStringList in the acquire system It is not very extensible to have the supported Hashes hardcoded everywhere and especially if it is part of virtual method names. It is also possible that a method does not support the 'best' hash (yet), so we might end up not being able to verify a file even though we have a common subset of supported hashes. And those are just two of the cases in which it is handy to have a more dynamic selection. The downside is that this is a MAJOR API break, but the HashStringList has a string constructor for compatibility, so with a bit of luck the few frontends playing with the acquire system directly are okay. --- cmdline/apt-get.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index fc6223989..3388351d9 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -838,8 +838,7 @@ static bool DoSource(CommandLine &CmdL) } // see if we have a hash (Acquire::ForceHash is the only way to have none) - HashString const * const hs = I->Hashes.find(NULL); - if (hs == NULL && _config->FindB("APT::Get::AllowUnauthenticated",false) == false) + if (I->Hashes.usable() == false && _config->FindB("APT::Get::AllowUnauthenticated",false) == false) { ioprintf(c1out, "Skipping download of file '%s' as requested hashsum is not available for authentication\n", localFile.c_str()); @@ -847,8 +846,7 @@ static bool DoSource(CommandLine &CmdL) } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - hs != NULL ? hs->toStr() : "", I->Size, - Last->Index().SourceInfo(*Last,*I),Src); + I->Hashes, I->Size, Last->Index().SourceInfo(*Last,*I), Src); } } -- cgit v1.2.3 From 8710a36a01c0cb1648926792c2ad05185535558e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 10 May 2014 11:24:44 +0200 Subject: improve pkgTagSection scanning and parsing Removes the 256 fields limit, deals consistently with spaces littered all over the place and is even a tiny bit faster than before. Even comes with a bunch of new tests to validate these claims. --- cmdline/apt-extracttemplates.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index e4428e051..7be59b9f8 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -103,10 +103,12 @@ bool DebFile::DoItem(Item &I, int &Fd) if (strcmp(I.Name, "control") == 0) { delete [] Control; - Control = new char[I.Size+1]; - Control[I.Size] = 0; + Control = new char[I.Size+3]; + Control[I.Size] = '\n'; + Control[I.Size + 1] = '\n'; + Control[I.Size + 2] = '\0'; Which = IsControl; - ControlLen = I.Size; + ControlLen = I.Size + 3; // make it call the Process method below. this is so evil Fd = -2; } @@ -162,9 +164,10 @@ bool DebFile::Process(Item &/*I*/, const unsigned char *data, bool DebFile::ParseInfo() { if (Control == NULL) return false; - + pkgTagSection Section; - Section.Scan(Control, ControlLen); + if (Section.Scan(Control, ControlLen) == false) + return false; Package = Section.FindS("Package"); Version = GetInstalledVer(Package); -- cgit v1.2.3 From 8f418981337503ff7abedd872f788b51bcdbc886 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Apr 2014 16:07:32 +0200 Subject: show upgradable packages after apt update Closes: 748389 --- cmdline/apt.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'cmdline') diff --git a/cmdline/apt.cc b/cmdline/apt.cc index 4813861a4..8a6f96aea 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -112,6 +112,7 @@ int main(int argc, const char *argv[]) /*{{{*/ _config->CndSet("DPkg::Progress-Fancy", "1"); _config->CndSet("Apt::Color", "1"); _config->CndSet("APT::Get::Upgrade-Allow-New", true); + _config->CndSet("APT::Cmd::Show-Update-Stats", true); // Parse the command line and initialize the package library CommandLine CmdL(Args.data(), _config); -- cgit v1.2.3 From d287a035e07030be13f72265d4d0812086c323f5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sat, 17 May 2014 06:57:47 +0200 Subject: fix screen width detection for apt/apt-get lists 3163087b moved SigWinch(int) from apt-get.cc to private-output.cc without moving #include , making SigWinch a nop. Closes: 748430, 747942 --- cmdline/apt-get.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 566103f8c..0f18b0e7c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From d01d91d397284fb2ab3402dddede1594d2685356 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 May 2014 13:49:52 +0200 Subject: cmdline/apt-extracttemplates.cc: remove unused private var Reported-By: clang -Wall --- cmdline/apt-extracttemplates.cc | 2 +- cmdline/apt-extracttemplates.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index e4428e051..6dd53b78d 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -52,7 +52,7 @@ pkgCache *DebFile::Cache = 0; // --------------------------------------------------------------------- /* */ DebFile::DebFile(const char *debfile) - : File(debfile, FileFd::ReadOnly), Size(0), Control(NULL), ControlLen(0), + : File(debfile, FileFd::ReadOnly), Control(NULL), ControlLen(0), DepOp(0), PreDepOp(0), Config(0), Template(0), Which(None) { } diff --git a/cmdline/apt-extracttemplates.h b/cmdline/apt-extracttemplates.h index 9cc3f5f25..6d2870a02 100644 --- a/cmdline/apt-extracttemplates.h +++ b/cmdline/apt-extracttemplates.h @@ -20,7 +20,6 @@ class pkgCache; class DebFile : public pkgDirStream { FileFd File; - unsigned long Size; char *Control; unsigned long ControlLen; -- cgit v1.2.3 From a93a32b5cda4f2a0572365a8b919329ea6af2c66 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 29 May 2014 10:22:09 +0200 Subject: add hashtable stats --- cmdline/apt-cache.cc | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 84b775390..a620740e1 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -373,7 +373,63 @@ static bool Stats(CommandLine &) Cache->Head().VerFileCount*Cache->Head().VerFileSz + Cache->Head().ProvidesCount*Cache->Head().ProvidesSz; cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; - + + // get the hash collisions average + long NumBuckets = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc); + long UsedBuckets = 0; + long UnusedBuckets = 0; + long LongestBucket = 0; + long ShortestBucket = NumBuckets; + for (unsigned int i=0; i < NumBuckets; ++i) + { + pkgCache::Package *Pkg = Cache->PkgP + Cache->HeaderP->PkgHashTable[i]; + if(Pkg == 0 || Pkg == Cache->PkgP) + { + UnusedBuckets++; + continue; + } + long ThisBucketSize = 0; + for (; Pkg != Cache->PkgP; Pkg = Cache->PkgP + Pkg->NextPackage) + ThisBucketSize++; + LongestBucket = std::max(ThisBucketSize, LongestBucket); + ShortestBucket = std::min(ThisBucketSize, ShortestBucket); + UsedBuckets += ThisBucketSize; + } + cout << _("Pkg Hashtable stats:") << endl; + cout << _("Number of buckets: ") << SizeToStr(NumBuckets) << endl; + cout << _("Unused buckets: ") << SizeToStr(UnusedBuckets) << endl; + cout << _("Used buckets: ") << UsedBuckets << endl; + cout << _("Average num entries per bucket : ") << UsedBuckets/(double)NumBuckets << endl; + cout << _("Longest / Shortest bucket: ") << LongestBucket << " / " << ShortestBucket << endl; + + // get the hash collisions average + NumBuckets = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc); + UsedBuckets = 0; + UnusedBuckets = 0; + LongestBucket = 0; + ShortestBucket = NumBuckets; + for (unsigned int i=0; i < NumBuckets; ++i) + { + pkgCache::Group *Grp = Cache->GrpP + Cache->HeaderP->GrpHashTable[i]; + if(Grp == 0 || Grp == Cache->GrpP) + { + UnusedBuckets++; + continue; + } + long ThisBucketSize = 0; + for (; Grp != Cache->GrpP; Grp = Cache->GrpP + Grp->Next) + ThisBucketSize++; + LongestBucket = std::max(ThisBucketSize, LongestBucket); + ShortestBucket = std::min(ThisBucketSize, ShortestBucket); + UsedBuckets += ThisBucketSize; + } + cout << _("Grp Hashtable stats:") << endl; + cout << _("Number of buckets: ") << SizeToStr(NumBuckets) << endl; + cout << _("Unused buckets: ") << SizeToStr(UnusedBuckets) << endl; + cout << _("Used buckets: ") << UsedBuckets << endl; + cout << _("Average num entries per bucket : ") << UsedBuckets/(double)NumBuckets << endl; + cout << _("Longest / Shortest bucket: ") << LongestBucket << " / " << ShortestBucket << endl; + return true; } /*}}}*/ -- cgit v1.2.3 From 387fb4aea8415d09e177195841fbefb39bf5521b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 May 2014 13:49:52 +0200 Subject: cmdline/apt-extracttemplates.cc: remove unused private var Reported-By: clang -Wall --- cmdline/apt-extracttemplates.cc | 2 +- cmdline/apt-extracttemplates.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 7be59b9f8..0d568106f 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -52,7 +52,7 @@ pkgCache *DebFile::Cache = 0; // --------------------------------------------------------------------- /* */ DebFile::DebFile(const char *debfile) - : File(debfile, FileFd::ReadOnly), Size(0), Control(NULL), ControlLen(0), + : File(debfile, FileFd::ReadOnly), Control(NULL), ControlLen(0), DepOp(0), PreDepOp(0), Config(0), Template(0), Which(None) { } diff --git a/cmdline/apt-extracttemplates.h b/cmdline/apt-extracttemplates.h index 9cc3f5f25..6d2870a02 100644 --- a/cmdline/apt-extracttemplates.h +++ b/cmdline/apt-extracttemplates.h @@ -20,7 +20,6 @@ class pkgCache; class DebFile : public pkgDirStream { FileFd File; - unsigned long Size; char *Control; unsigned long ControlLen; -- cgit v1.2.3 From 81b3540d26b4f47785e6678e22d1312b8cd6d704 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 30 May 2014 16:52:19 +0200 Subject: print error stack on failure of 'apt' solver Git-Dch: ignore --- cmdline/apt-internal-solver.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index b85c07c33..e4cdf6381 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include /*}}}*/ @@ -56,6 +57,12 @@ static bool ShowHelp(CommandLine &) { return true; } /*}}}*/ +APT_NORETURN static void DIE(std::string const &message) { /*{{{*/ + std::cerr << "ERROR: " << message << std::endl; + _error->DumpErrors(std::cerr); + exit(EXIT_FAILURE); +} + /*}}}*/ int main(int argc,const char *argv[]) /*{{{*/ { CommandLine::Args Args[] = { @@ -115,34 +122,29 @@ int main(int argc,const char *argv[]) /*{{{*/ EDSP::WriteProgress(0, "Start up solver…", output); - if (pkgInitSystem(*_config,_system) == false) { - std::cerr << "System could not be initialized!" << std::endl; - return 1; - } + if (pkgInitSystem(*_config,_system) == false) + DIE("System could not be initialized!"); EDSP::WriteProgress(1, "Read request…", output); if (WaitFd(input, false, 5) == false) - std::cerr << "WAIT timed out in the resolver" << std::endl; + DIE("WAIT timed out in the resolver"); std::list install, remove; bool upgrade, distUpgrade, autoRemove; - if (EDSP::ReadRequest(input, install, remove, upgrade, distUpgrade, autoRemove) == false) { - std::cerr << "Parsing the request failed!" << std::endl; - return 2; - } + if (EDSP::ReadRequest(input, install, remove, upgrade, distUpgrade, autoRemove) == false) + DIE("Parsing the request failed!"); EDSP::WriteProgress(5, "Read scenario…", output); pkgCacheFile CacheFile; - CacheFile.Open(NULL, false); + if (CacheFile.Open(NULL, false) == false) + DIE("Failed to open CacheFile!"); EDSP::WriteProgress(50, "Apply request on scenario…", output); - if (EDSP::ApplyRequest(install, remove, CacheFile) == false) { - std::cerr << "Failed to apply request to depcache!" << std::endl; - return 3; - } + if (EDSP::ApplyRequest(install, remove, CacheFile) == false) + DIE("Failed to apply request to depcache!"); pkgProblemResolver Fix(CacheFile); for (std::list::const_iterator i = remove.begin(); @@ -183,10 +185,8 @@ int main(int argc,const char *argv[]) /*{{{*/ EDSP::WriteProgress(95, "Write solution…", output); - if (EDSP::WriteSolution(CacheFile, output) == false) { - std::cerr << "Failed to output the solution!" << std::endl; - return 4; - } + if (EDSP::WriteSolution(CacheFile, output) == false) + DIE("Failed to output the solution!"); EDSP::WriteProgress(100, "Done", output); -- cgit v1.2.3 From a3f1d60cb75ab83f63a52a43c056a4752c8fdeb2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 30 May 2014 14:47:56 +0200 Subject: Show unauthenticated warning for source packages as well This will show the same unauthenticated warning for source packages as for binary packages and will not download a source package if it is unauthenticated. This can be overridden with --allow-unauthenticated Closes: #749795 --- cmdline/apt-get.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0f18b0e7c..a58386eb0 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -755,6 +756,7 @@ static bool DoSource(CommandLine &CmdL) // Load the requestd sources into the fetcher unsigned J = 0; + std::string UntrustedList; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; @@ -763,6 +765,9 @@ static bool DoSource(CommandLine &CmdL) if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); } + + if (Last->Index().IsTrusted() == false) + UntrustedList += Src + " "; string srec = Last->AsStr(); string::size_type pos = srec.find("\nVcs-"); @@ -846,6 +851,10 @@ static bool DoSource(CommandLine &CmdL) Last->Index().SourceInfo(*Last,*I),Src); } } + + // check authentication status of the source as well + if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) + return false; // Display statistics unsigned long long FetchBytes = Fetcher.FetchNeeded(); -- cgit v1.2.3 From 0dd2cbc08aefb73421d5aa31bc62184181a28c32 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 6 Jun 2014 11:24:44 +0200 Subject: cmdline/apt-helper.cc: use less generic description/short-description --- cmdline/apt-helper.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index 2c1107d90..b0edafcbd 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -43,7 +43,8 @@ static bool DoDownloadFile(CommandLine &CmdL) std::string hash; if (CmdL.FileSize() > 3) hash = CmdL.FileList[3]; - new pkgAcqFile(&Fetcher, download_uri, hash, 0, "desc", "short-desc", + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, "dest-dir-ignored", targetfile); Fetcher.Run(); bool Failed = false; -- cgit v1.2.3 From 4dde2b4285fc6288e44e915a0d7bc0faac114a2e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 10 Jun 2014 14:12:12 +0200 Subject: support Acquire::GzipIndexes in dumpavail Closes: 742835 --- cmdline/apt-cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 84b775390..1414617eb 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -507,7 +507,7 @@ static bool DumpAvail(CommandLine &) break; } - FileFd PkgF(File.FileName(),FileFd::ReadOnly); + FileFd PkgF(File.FileName(),FileFd::ReadOnly, FileFd::Extension); if (_error->PendingError() == true) break; -- cgit v1.2.3 From fc1a78d8e9b958f3d65fe1c03494d785314f9816 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 11 Jun 2014 15:31:38 +0200 Subject: DropPrivs in the solvers (just to be on the safe side) --- cmdline/apt-dump-solver.cc | 2 ++ cmdline/apt-internal-solver.cc | 3 +++ 2 files changed, 5 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-dump-solver.cc b/cmdline/apt-dump-solver.cc index 04e13bde9..424764b3c 100644 --- a/cmdline/apt-dump-solver.cc +++ b/cmdline/apt-dump-solver.cc @@ -40,6 +40,8 @@ int main(int argc,const char *argv[]) /*{{{*/ ShowHelp(); return 0; } + // we really don't need anything + DropPrivs(); FILE* input = fdopen(STDIN_FILENO, "r"); FILE* output = fopen("/tmp/dump.edsp", "w"); diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index e4cdf6381..0cac12da2 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -74,6 +74,9 @@ int main(int argc,const char *argv[]) /*{{{*/ {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; + // we really don't need anything + DropPrivs(); + CommandLine CmdL(Args,_config); if (pkgInitConfig(*_config) == false || CmdL.Parse(argc,argv) == false) { -- cgit v1.2.3 From eceb418be84f6271c10e374281c1a8379647679b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Jun 2014 08:51:59 +0200 Subject: improve formating of the hash stats --- cmdline/apt-cache.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index a620740e1..072cf4ef7 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -374,7 +374,7 @@ static bool Stats(CommandLine &) Cache->Head().ProvidesCount*Cache->Head().ProvidesSz; cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; - // get the hash collisions average + // hashtable stats for the PkgHashTable long NumBuckets = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc); long UsedBuckets = 0; long UnusedBuckets = 0; @@ -395,14 +395,14 @@ static bool Stats(CommandLine &) ShortestBucket = std::min(ThisBucketSize, ShortestBucket); UsedBuckets += ThisBucketSize; } - cout << _("Pkg Hashtable stats:") << endl; - cout << _("Number of buckets: ") << SizeToStr(NumBuckets) << endl; - cout << _("Unused buckets: ") << SizeToStr(UnusedBuckets) << endl; - cout << _("Used buckets: ") << UsedBuckets << endl; - cout << _("Average num entries per bucket : ") << UsedBuckets/(double)NumBuckets << endl; - cout << _("Longest / Shortest bucket: ") << LongestBucket << " / " << ShortestBucket << endl; - - // get the hash collisions average + cout << "Total PkgHashTable buckets: " << SizeToStr(NumBuckets) << std::endl; + cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; + cout << " Used: " << UsedBuckets << std::endl; + cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; + cout << " Longest: " << LongestBucket << std::endl; + cout << " Shortest: " << ShortestBucket << std::endl; + + // hashtable stats for the GrpHashTable NumBuckets = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc); UsedBuckets = 0; UnusedBuckets = 0; @@ -423,12 +423,12 @@ static bool Stats(CommandLine &) ShortestBucket = std::min(ThisBucketSize, ShortestBucket); UsedBuckets += ThisBucketSize; } - cout << _("Grp Hashtable stats:") << endl; - cout << _("Number of buckets: ") << SizeToStr(NumBuckets) << endl; - cout << _("Unused buckets: ") << SizeToStr(UnusedBuckets) << endl; - cout << _("Used buckets: ") << UsedBuckets << endl; - cout << _("Average num entries per bucket : ") << UsedBuckets/(double)NumBuckets << endl; - cout << _("Longest / Shortest bucket: ") << LongestBucket << " / " << ShortestBucket << endl; + cout << "Total GrpHashTable buckets: " << SizeToStr(NumBuckets) << std::endl; + cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; + cout << " Used: " << UsedBuckets << std::endl; + cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; + cout << " Longest: " << LongestBucket << std::endl; + cout << " Shortest: " << ShortestBucket << std::endl; return true; } -- cgit v1.2.3 From 637c3b232223c17827a8842cb1c24655469329ba Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Jun 2014 09:36:48 +0200 Subject: Provide ShowHashTableStats function --- cmdline/apt-cache.cc | 98 +++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 55 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 072cf4ef7..35e9cc3a8 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -264,6 +264,44 @@ static bool DumpPackage(CommandLine &CmdL) return true; } /*}}}*/ +// ShowHashTableStats - Show stats about a hashtable /*{{{*/ +// --------------------------------------------------------------------- +/* */ +template +static void ShowHashTableStats(std::string Type, + T *StartP, + map_ptrloc *Hashtable, + unsigned long Size) +{ + // hashtable stats for the HashTable + long NumBuckets = Size; + long UsedBuckets = 0; + long UnusedBuckets = 0; + long LongestBucket = 0; + long ShortestBucket = NumBuckets; + for (unsigned int i=0; i < NumBuckets; ++i) + { + T *P = StartP + Hashtable[i]; + if(P == 0 || P == StartP) + { + UnusedBuckets++; + continue; + } + long ThisBucketSize = 0; + for (; P != StartP; P = StartP + P->Next) + ThisBucketSize++; + LongestBucket = std::max(ThisBucketSize, LongestBucket); + ShortestBucket = std::min(ThisBucketSize, ShortestBucket); + UsedBuckets += ThisBucketSize; + } + cout << "Total buckets " << Type << ": " << SizeToStr(NumBuckets) << std::endl; + cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; + cout << " Used: " << UsedBuckets << std::endl; + cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; + cout << " Longest: " << LongestBucket << std::endl; + cout << " Shortest: " << ShortestBucket << std::endl; +} + /*}}}*/ // Stats - Dump some nice statistics /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -374,61 +412,11 @@ static bool Stats(CommandLine &) Cache->Head().ProvidesCount*Cache->Head().ProvidesSz; cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; - // hashtable stats for the PkgHashTable - long NumBuckets = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc); - long UsedBuckets = 0; - long UnusedBuckets = 0; - long LongestBucket = 0; - long ShortestBucket = NumBuckets; - for (unsigned int i=0; i < NumBuckets; ++i) - { - pkgCache::Package *Pkg = Cache->PkgP + Cache->HeaderP->PkgHashTable[i]; - if(Pkg == 0 || Pkg == Cache->PkgP) - { - UnusedBuckets++; - continue; - } - long ThisBucketSize = 0; - for (; Pkg != Cache->PkgP; Pkg = Cache->PkgP + Pkg->NextPackage) - ThisBucketSize++; - LongestBucket = std::max(ThisBucketSize, LongestBucket); - ShortestBucket = std::min(ThisBucketSize, ShortestBucket); - UsedBuckets += ThisBucketSize; - } - cout << "Total PkgHashTable buckets: " << SizeToStr(NumBuckets) << std::endl; - cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; - cout << " Used: " << UsedBuckets << std::endl; - cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; - cout << " Longest: " << LongestBucket << std::endl; - cout << " Shortest: " << ShortestBucket << std::endl; - - // hashtable stats for the GrpHashTable - NumBuckets = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc); - UsedBuckets = 0; - UnusedBuckets = 0; - LongestBucket = 0; - ShortestBucket = NumBuckets; - for (unsigned int i=0; i < NumBuckets; ++i) - { - pkgCache::Group *Grp = Cache->GrpP + Cache->HeaderP->GrpHashTable[i]; - if(Grp == 0 || Grp == Cache->GrpP) - { - UnusedBuckets++; - continue; - } - long ThisBucketSize = 0; - for (; Grp != Cache->GrpP; Grp = Cache->GrpP + Grp->Next) - ThisBucketSize++; - LongestBucket = std::max(ThisBucketSize, LongestBucket); - ShortestBucket = std::min(ThisBucketSize, ShortestBucket); - UsedBuckets += ThisBucketSize; - } - cout << "Total GrpHashTable buckets: " << SizeToStr(NumBuckets) << std::endl; - cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; - cout << " Used: " << UsedBuckets << std::endl; - cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; - cout << " Longest: " << LongestBucket << std::endl; - cout << " Shortest: " << ShortestBucket << std::endl; + // hashtable stats + int HashTableSize = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc); + ShowHashTableStats("PkgHashTable", Cache->PkgP, Cache->HeaderP->PkgHashTable, HashTableSize); + HashTableSize = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc); + ShowHashTableStats("GrpHashTable", Cache->GrpP, Cache->HeaderP->GrpHashTable, HashTableSize); return true; } -- cgit v1.2.3 From d39d7f885d61bfe296c131c83bdc042a2ab6b0d7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 17:45:33 +0200 Subject: show our broken packages message in 'apt' solver --- cmdline/apt-internal-solver.cc | 24 ++++++++++++++---------- cmdline/makefile | 20 ++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index e4cdf6381..5fda7b6a0 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -24,9 +24,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -168,18 +170,20 @@ int main(int argc,const char *argv[]) /*{{{*/ EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output); + std::string failure; if (upgrade == true) { - if (pkgAllUpgrade(CacheFile) == false) { - EDSP::WriteError("ERR_UNSOLVABLE_UPGRADE", "An upgrade error occurred", output); - return 0; - } + if (pkgAllUpgrade(CacheFile) == false) + failure = "ERR_UNSOLVABLE_UPGRADE"; } else if (distUpgrade == true) { - if (pkgDistUpgrade(CacheFile) == false) { - EDSP::WriteError("ERR_UNSOLVABLE_DIST_UPGRADE", "An dist-upgrade error occurred", output); - return 0; - } - } else if (Fix.Resolve() == false) { - EDSP::WriteError("ERR_UNSOLVABLE", "An error occurred", output); + if (pkgDistUpgrade(CacheFile) == false) + failure = "ERR_UNSOLVABLE_DIST_UPGRADE"; + } else if (Fix.Resolve() == false) + failure = "ERR_UNSOLVABLE"; + + if (failure.empty() == false) { + std::ostringstream broken; + ShowBroken(broken, CacheFile, false); + EDSP::WriteError(failure.c_str(), broken.str(), output); return 0; } diff --git a/cmdline/makefile b/cmdline/makefile index c4a249cd6..b7c35ddd1 100644 --- a/cmdline/makefile +++ b/cmdline/makefile @@ -8,49 +8,49 @@ include ../buildlib/defaults.mak # The apt program PROGRAM=apt SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt.cc include $(PROGRAM_H) # The apt-cache program PROGRAM=apt-cache SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-cache.cc include $(PROGRAM_H) # The apt-get program PROGRAM=apt-get SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-get.cc include $(PROGRAM_H) # The apt-config program PROGRAM=apt-config SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-config.cc include $(PROGRAM_H) # The apt-cdrom program PROGRAM=apt-cdrom SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-cdrom.cc include $(PROGRAM_H) # The apt-mark program PROGRAM=apt-mark SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-mark.cc include $(PROGRAM_H) # The apt-helper PROGRAM=apt-helper SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-helper.cc include $(PROGRAM_H) @@ -75,14 +75,14 @@ include $(PROGRAM_H) # The apt-extracttemplates program PROGRAM=apt-extracttemplates SLIBS = -lapt-pkg -lapt-inst $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-inst/makefile SOURCE = apt-extracttemplates.cc include $(PROGRAM_H) # The internal solver acting as an external PROGRAM=apt-internal-solver -SLIBS = -lapt-pkg $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-internal-solver.cc include $(PROGRAM_H) -- cgit v1.2.3 From 4ad8619bb1f0bf777d17c568bb7a6cf7f30aac34 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 12 Jun 2014 12:22:45 +0200 Subject: cleanup datatypes mix used in binary cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had a wild mixture of (unsigned) int, long and long long here without much sense, so this commit adds a few typedefs to get some sense in the typesystem and ensures that a ID isn't sometimes computed as int, stored as long and compared with a long long… as this could potentially bite us later on as the size of the archive only increases over time. --- cmdline/apt-cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 2ed1bf5d4..620cb6c01 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1275,7 +1275,7 @@ static bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V) struct ExDescFile { pkgCache::DescFile *Df; - map_ptrloc ID; + map_id_t ID; }; // Search - Perform a search /*{{{*/ -- cgit v1.2.3 From ac2c559b33db7a2dbec3a95760ee2497baf7017a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 13 Jun 2014 09:10:11 +0200 Subject: correct 'apt-cache stats' to include more It still doesn't reflect the size the cache has on the disk compared to what is given as total size (90 vs 103 MB), but by counting all structs in we are at least a bit closer to the reality. Git-Dch: ignore --- cmdline/apt-cache.cc | 56 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 620cb6c01..88a323280 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -270,34 +270,36 @@ static bool DumpPackage(CommandLine &CmdL) template static void ShowHashTableStats(std::string Type, T *StartP, - map_ptrloc *Hashtable, + map_pointer_t *Hashtable, unsigned long Size) { // hashtable stats for the HashTable - long NumBuckets = Size; - long UsedBuckets = 0; - long UnusedBuckets = 0; - long LongestBucket = 0; - long ShortestBucket = NumBuckets; + unsigned long NumBuckets = Size; + unsigned long UsedBuckets = 0; + unsigned long UnusedBuckets = 0; + unsigned long LongestBucket = 0; + unsigned long ShortestBucket = NumBuckets; + unsigned long Entries = 0; for (unsigned int i=0; i < NumBuckets; ++i) { T *P = StartP + Hashtable[i]; if(P == 0 || P == StartP) { - UnusedBuckets++; + ++UnusedBuckets; continue; } - long ThisBucketSize = 0; + ++UsedBuckets; + unsigned long ThisBucketSize = 0; for (; P != StartP; P = StartP + P->Next) - ThisBucketSize++; + ++ThisBucketSize; + Entries += ThisBucketSize; LongestBucket = std::max(ThisBucketSize, LongestBucket); ShortestBucket = std::min(ThisBucketSize, ShortestBucket); - UsedBuckets += ThisBucketSize; } - cout << "Total buckets " << Type << ": " << SizeToStr(NumBuckets) << std::endl; - cout << " Unused: " << SizeToStr(UnusedBuckets) << std::endl; + cout << "Total buckets in " << Type << ": " << NumBuckets << std::endl; + cout << " Unused: " << UnusedBuckets << std::endl; cout << " Used: " << UsedBuckets << std::endl; - cout << " Average entries: " << UsedBuckets/(double)NumBuckets << std::endl; + cout << " Average entries: " << Entries/(double)NumBuckets << std::endl; cout << " Longest: " << LongestBucket << std::endl; cout << " Shortest: " << ShortestBucket << std::endl; } @@ -398,25 +400,31 @@ static bool Stats(CommandLine &) } } cout << _("Total dependency version space: ") << SizeToStr(DepVerSize) << endl; - + unsigned long Slack = 0; for (int I = 0; I != 7; I++) Slack += Cache->Head().Pools[I].ItemSize*Cache->Head().Pools[I].Count; cout << _("Total slack space: ") << SizeToStr(Slack) << endl; - + unsigned long Total = 0; - Total = Slack + Size + Cache->Head().DependsCount*Cache->Head().DependencySz + - Cache->Head().VersionCount*Cache->Head().VersionSz + - Cache->Head().PackageCount*Cache->Head().PackageSz + - Cache->Head().VerFileCount*Cache->Head().VerFileSz + - Cache->Head().ProvidesCount*Cache->Head().ProvidesSz; +#define APT_CACHESIZE(X,Y) (Cache->Head().X * Cache->Head().Y) + Total = Slack + Size + + APT_CACHESIZE(GroupCount, GroupSz) + + APT_CACHESIZE(PackageCount, PackageSz) + + APT_CACHESIZE(VersionCount, VersionSz) + + APT_CACHESIZE(DescriptionCount, DescriptionSz) + + APT_CACHESIZE(DependsCount, DependencySz) + + APT_CACHESIZE(PackageFileCount, PackageFileSz) + + APT_CACHESIZE(VerFileCount, VerFileSz) + + APT_CACHESIZE(DescFileCount, DescFileSz) + + APT_CACHESIZE(ProvidesCount, ProvidesSz) + + (2 * Cache->Head().HashTableSize * sizeof(map_id_t)); cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; +#undef APT_CACHESIZE // hashtable stats - int HashTableSize = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc); - ShowHashTableStats("PkgHashTable", Cache->PkgP, Cache->HeaderP->PkgHashTable, HashTableSize); - HashTableSize = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc); - ShowHashTableStats("GrpHashTable", Cache->GrpP, Cache->HeaderP->GrpHashTable, HashTableSize); + ShowHashTableStats("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTable(), Cache->Head().HashTableSize); + ShowHashTableStats("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTable(), Cache->Head().HashTableSize); return true; } -- cgit v1.2.3 From 3621b1c70f532c61ccfee6a65c413ee573ed4900 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 2 Jul 2014 03:10:21 +0200 Subject: Fix ar and tar code to be LFS-safe This is an ABI break. Closes: #742882 --- cmdline/apt-extracttemplates.cc | 2 +- cmdline/apt-extracttemplates.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 0d568106f..f95b9e5ba 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -140,7 +140,7 @@ bool DebFile::DoItem(Item &I, int &Fd) // --------------------------------------------------------------------- /* */ bool DebFile::Process(Item &/*I*/, const unsigned char *data, - unsigned long size, unsigned long pos) + unsigned long long size, unsigned long long pos) { switch (Which) { diff --git a/cmdline/apt-extracttemplates.h b/cmdline/apt-extracttemplates.h index 6d2870a02..829cdae75 100644 --- a/cmdline/apt-extracttemplates.h +++ b/cmdline/apt-extracttemplates.h @@ -28,7 +28,7 @@ public: ~DebFile(); bool DoItem(Item &I, int &fd); bool Process(pkgDirStream::Item &I, const unsigned char *data, - unsigned long size, unsigned long pos); + unsigned long long size, unsigned long long pos); bool Go(); bool ParseInfo(); -- cgit v1.2.3 From a5bb5e1e747ceb7b5a9defb6b1a8d9282a6e0957 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 8 Jul 2014 15:11:14 +0200 Subject: Only allow "apt-get build-dep path" when path starts with ./ or / This avoid the subtle problem that someone might have a directory with the same package name as the build-depends he/she is trying to fetch. Also print a note that the specific file/dir is used. --- cmdline/apt-get.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index bd866bc8c..cdbfa4708 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1065,9 +1065,12 @@ static bool DoBuildDep(CommandLine &CmdL) string Src; pkgSrcRecords::Parser *Last = 0; - // a unpacked debian source tree - if (DirectoryExists(*I)) + // an unpacked debian source tree + using APT::String::Startswith; + if ((Startswith(*I, "./") || Startswith(*I, "/")) && + DirectoryExists(*I)) { + ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), *I); // FIXME: how can we make this more elegant? std::string TypeName = "debian/control File Source Index"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); @@ -1077,6 +1080,8 @@ static bool DoBuildDep(CommandLine &CmdL) // if its a local file (e.g. .dsc) use this else if (FileExists(*I)) { + ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), *I); + // see if we can get a parser for this pkgIndexFile type string TypeName = flExtension(*I) + " File Source Index"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); -- cgit v1.2.3 From c53cf70da31a3c59675af8c5425b54433793dc8d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 16 Aug 2014 13:29:10 +0200 Subject: add dpkg::source-options for dpkg-source invocation dpkg-source can be told to enforce signature checks with --require-valid-signature, but while this isn't feasible as default for Debian itself at the moment, a local admin should be able to use it. This commit also fixes the size limit on the construction of the command being called for dpkg-source and dpkg-buildpackage. Closes: 757534 --- cmdline/apt-get.cc | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a58386eb0..845d67d2b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -953,18 +953,19 @@ static bool DoSource(CommandLine &CmdL) else { // Call dpkg-source - char S[500]; - snprintf(S,sizeof(S),"%s -x %s", + std::string const sourceopts = _config->Find("DPkg::Source-Options", "-x"); + std::string S; + strprintf(S, "%s %s %s", _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), - Dsc[I].Dsc.c_str()); - if (system(S) != 0) + sourceopts.c_str(), Dsc[I].Dsc.c_str()); + if (system(S.c_str()) != 0) { - fprintf(stderr,_("Unpack command '%s' failed.\n"),S); - fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n")); + fprintf(stderr, _("Unpack command '%s' failed.\n"), S.c_str()); + fprintf(stderr, _("Check if the 'dpkg-dev' package is installed.\n")); _exit(1); - } + } } - + // Try to compile it with dpkg-buildpackage if (_config->FindB("APT::Get::Compile",false) == true) { @@ -980,20 +981,20 @@ static bool DoSource(CommandLine &CmdL) buildopts.append(_config->Find("DPkg::Build-Options","-b -uc")); // Call dpkg-buildpackage - char S[500]; - snprintf(S,sizeof(S),"cd %s && %s %s", + std::string S; + strprintf(S, "cd %s && %s %s", Dir.c_str(), _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), buildopts.c_str()); - - if (system(S) != 0) + + if (system(S.c_str()) != 0) { - fprintf(stderr,_("Build command '%s' failed.\n"),S); + fprintf(stderr, _("Build command '%s' failed.\n"), S.c_str()); _exit(1); - } - } + } + } } - + _exit(0); } -- cgit v1.2.3 From c6ee61eab54edf6cc3fbe118d304d72a860e1451 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 Sep 2014 15:50:19 +0200 Subject: Make Proxy-Auto-Detect check for each host When doing Acquire::http{,s}::Proxy-Auto-Detect, run the auto-detect command for each host instead of only once. This should make using "proxy" from libproxy-tools feasible which can then be used for PAC style or other proxy configurations. Closes: #759264 --- cmdline/apt-helper.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index b0edafcbd..dd43ea1bc 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,19 @@ #include /*}}}*/ +static bool DoAutoDetectProxy(CommandLine &CmdL) +{ + if (CmdL.FileSize() != 2) + return _error->Error(_("Need one URL as argument")); + URI ServerURL(CmdL.FileList[1]); + AutoDetectProxy(ServerURL); + std::string SpecificProxy = _config->Find("Acquire::"+ServerURL.Access+"::Proxy::" + ServerURL.Host); + ioprintf(std::cout, "Using proxy '%s' for URL '%s'\n", + SpecificProxy.c_str(), std::string(ServerURL).c_str()); + + return true; +} + static bool DoDownloadFile(CommandLine &CmdL) { if (CmdL.FileSize() <= 2) @@ -70,6 +84,7 @@ static bool ShowHelp(CommandLine &) "\n" "Commands:\n" " download-file - download the given uri to the target-path\n" + " auto-detect-proxy - detect proxy using apt.conf\n" "\n" " This APT helper has Super Meep Powers.\n"); return true; @@ -80,6 +95,7 @@ int main(int argc,const char *argv[]) /*{{{*/ { CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp}, {"download-file", &DoDownloadFile}, + {"auto-detect-proxy", &DoAutoDetectProxy}, {0,0}}; std::vector Args = getCommandArgs( -- cgit v1.2.3 From 097248092ea4ff4543dfb17deb4e0d31dd697c71 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 Sep 2014 17:06:52 +0200 Subject: Use heap to allocate PatternMatch to avoid potential stack overflow When apt-cache search with many args (> 130) is given the allocation of PatternMatch on the stack may fail resulting in a segmentation fault. By using the heap the max size is much bigger and we also get a bad_alloc expection instead of a segfault (which we can catch *if* this ever becomes a pratical problem). No test for the crash as its not reproducable with the MALLOC_ settings in framework. Closes: 759612 --- cmdline/apt-cache.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 1414617eb..ac0d48a36 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1278,8 +1278,8 @@ static bool Search(CommandLine &CmdL) ExDescFile *DFList = new ExDescFile[descCount]; memset(DFList,0,sizeof(*DFList) * descCount); - bool PatternMatch[descCount * NumPatterns]; - memset(PatternMatch,false,sizeof(PatternMatch)); + bool *PatternMatch = new bool[descCount * NumPatterns]; + memset(PatternMatch,false,sizeof(*PatternMatch) * descCount * NumPatterns); // Map versions that we want to write out onto the VerList array. for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G) @@ -1389,6 +1389,7 @@ static bool Search(CommandLine &CmdL) } delete [] DFList; + delete [] PatternMatch; for (unsigned I = 0; I != NumPatterns; I++) regfree(&Patterns[I]); if (ferror(stdout)) -- cgit v1.2.3 From b0f4b486e6850c5f98520ccf19da71d0ed748ae4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 21 Sep 2014 10:18:03 +0200 Subject: generalize Acquire::GzipIndex --- cmdline/apt-get.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 845d67d2b..2e283da5a 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -665,7 +665,7 @@ static bool DoDownload(CommandLine &CmdL) { pkgAcquire::UriIterator I = Fetcher.UriBegin(); for (; I != Fetcher.UriEnd(); ++I) - cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; return true; } -- cgit v1.2.3 From a3a91fd7bab34983a008854728baf26034d4033e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 20:28:54 +0200 Subject: count strings more accurately for stats So far, only the few strings stored in stringitems were counted, but many more strings are directly inserted into the cache. We account for this now by identifying all these different strings and measure their length. We are still not at the correct size of the cache in 'stats' this way, but we are now again a bit closer. Git-Dch: Ignore --- cmdline/apt-cache.cc | 53 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 1447feb81..4030ce4e6 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -375,31 +375,56 @@ static bool Stats(CommandLine &) SizeToStr(Cache->Head().DescFileCount*Cache->Head().DescFileSz) << ')' << endl; cout << _("Total Provides mappings: ") << Cache->Head().ProvidesCount << " (" << SizeToStr(Cache->Head().ProvidesCount*Cache->Head().ProvidesSz) << ')' << endl; - - // String list stats - unsigned long Size = 0; - unsigned long Count = 0; - for (pkgCache::StringItem *I = Cache->StringItemP + Cache->Head().StringList; - I!= Cache->StringItemP; I = Cache->StringItemP + I->NextItem) - { - Count++; - Size += strlen(Cache->StrP + I->String) + 1; - } - cout << _("Total globbed strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl; - unsigned long DepVerSize = 0; + // String list stats + std::set stritems; + for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G) + stritems.insert(G->Name); for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P) { + stritems.insert(P->Arch); for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) { + if (V->VerStr != 0) + stritems.insert(V->VerStr); + if (V->Section != 0) + stritems.insert(V->Section); for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D) { if (D->Version != 0) - DepVerSize += strlen(D.TargetVer()) + 1; + stritems.insert(D->Version); + } + for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D) + { + stritems.insert(D->md5sum); + stritems.insert(D->language_code); } } + for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; ++Prv) + { + if (Prv->ProvideVersion != 0) + stritems.insert(Prv->ProvideVersion); + } } - cout << _("Total dependency version space: ") << SizeToStr(DepVerSize) << endl; + for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) + { + stritems.insert(F->FileName); + stritems.insert(F->Archive); + stritems.insert(F->Codename); + stritems.insert(F->Component); + stritems.insert(F->Version); + stritems.insert(F->Origin); + stritems.insert(F->Label); + stritems.insert(F->Architecture); + stritems.insert(F->Site); + stritems.insert(F->IndexType); + } + unsigned long Size = 0; + for (std::set::const_iterator i = stritems.begin(); i != stritems.end(); ++i) + Size += strlen(Cache->StrP + *i) + 1; + + cout << _("Total globbed strings: ") << stritems.size() << " (" << SizeToStr(Size) << ')' << endl; + stritems.clear(); unsigned long Slack = 0; for (int I = 0; I != 7; I++) -- cgit v1.2.3 From 67caa2e6538f13ff7a0d77e98ad6c58af998376d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 17 Aug 2014 13:27:59 +0200 Subject: mark pkg(All|Dist)Upgrade as deprecated The comment above their definition marks them already as such, so this is only a formalisation of the deprecation and fixes the occurances we have in our own code together with removing a magic number. Git-Dch: Ignore --- cmdline/apt-get.cc | 2 +- cmdline/apt-internal-solver.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d6cd94f72..aed1beb4d 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -540,7 +540,7 @@ static bool DoDSelectUpgrade(CommandLine &) } // Now upgrade everything - if (pkgAllUpgrade(Cache) == false) + if (APT::Upgrade::Upgrade(Cache, APT::Upgrade::FORBID_REMOVE_PACKAGES | APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES) == false) { ShowBroken(c1out,Cache,false); return _error->Error(_("Internal error, problem resolver broke stuff")); diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index c24a96cdf..0f2ec6283 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -175,10 +175,10 @@ int main(int argc,const char *argv[]) /*{{{*/ std::string failure; if (upgrade == true) { - if (pkgAllUpgrade(CacheFile) == false) + if (APT::Upgrade::Upgrade(CacheFile, APT::Upgrade::FORBID_REMOVE_PACKAGES | APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES) == false) failure = "ERR_UNSOLVABLE_UPGRADE"; } else if (distUpgrade == true) { - if (pkgDistUpgrade(CacheFile) == false) + if (APT::Upgrade::Upgrade(CacheFile, APT::Upgrade::ALLOW_EVERYTHING) == false) failure = "ERR_UNSOLVABLE_DIST_UPGRADE"; } else if (Fix.Resolve() == false) failure = "ERR_UNSOLVABLE"; -- cgit v1.2.3 From fdba4d53d6b9b594531c34792798f4044a25157e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Sep 2014 18:16:16 +0200 Subject: rework cachesets API to allow future extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The introduction of Fnmatch showed that each new selector would require multiple new virtual methods in the CacheSetHelper to work correctly, which isn't that great. We now flip to a single virtual method which handles all cases separated by an enum – as new enum values can be added without an ABI break. Great care was taken to make old code work with the new way of organisation, which means in return that you might be bombarded with deprecation warnings now if you don't adapt, but code should still compile and work as before as can be seen in apt itself with this commit. Git-Dch: Ignore --- cmdline/apt-cache.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 4030ce4e6..bd10a41ef 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -838,9 +838,9 @@ static bool XVcg(CommandLine &CmdL) // Load the list of packages from the command line into the show list APT::CacheSetHelper helper(true, GlobalError::NOTICE); - std::list mods; - mods.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); - mods.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); + std::list mods; + mods.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); + mods.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); std::map pkgsets = APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper); @@ -1050,9 +1050,9 @@ static bool Dotty(CommandLine &CmdL) // Load the list of packages from the command line into the show list APT::CacheSetHelper helper(true, GlobalError::NOTICE); - std::list mods; - mods.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); - mods.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); + std::list mods; + mods.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); + mods.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); std::map pkgsets = APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper); -- cgit v1.2.3 From e6f0c9bca4b052d20a2e48ce9715b89e187b671a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Sep 2014 19:02:05 +0200 Subject: adapt to the new CacheSetHelper API Git-Dch: Ignore --- cmdline/apt-cache.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index bd10a41ef..5a5dde088 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -191,7 +191,7 @@ static bool UnMet(CommandLine &CmdL) { CacheSetHelperVirtuals helper(true, GlobalError::NOTICE); APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, - APT::VersionList::CANDIDATE, helper); + APT::CacheSetHelper::CANDIDATE, helper); for (APT::VersionList::iterator V = verset.begin(); V != verset.end(); ++V) if (ShowUnMet(V, Important) == false) return false; @@ -656,7 +656,7 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends) return false; CacheSetHelperVirtuals helper(false); - APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper); + APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true && helper.virtualPkgs.empty() == true) return _error->Error(_("No packages found")); std::vector Shown(Cache->Head().PackageCount); @@ -724,7 +724,7 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends) if (Recurse == true && Shown[Trg->ID] == false) { Shown[Trg->ID] = true; - verset.insert(APT::VersionSet::FromPackage(CacheFile, Trg, APT::VersionSet::CANDIDATE, helper)); + verset.insert(APT::VersionSet::FromPackage(CacheFile, Trg, APT::CacheSetHelper::CANDIDATE, helper)); } } @@ -743,7 +743,7 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends) if (Recurse == true && Shown[V.ParentPkg()->ID] == false) { Shown[V.ParentPkg()->ID] = true; - verset.insert(APT::VersionSet::FromPackage(CacheFile, V.ParentPkg(), APT::VersionSet::CANDIDATE, helper)); + verset.insert(APT::VersionSet::FromPackage(CacheFile, V.ParentPkg(), APT::CacheSetHelper::CANDIDATE, helper)); } } @@ -1506,8 +1506,8 @@ static bool ShowPackage(CommandLine &CmdL) { pkgCacheFile CacheFile; CacheSetHelperVirtuals helper(true, GlobalError::NOTICE); - APT::VersionList::Version const select = _config->FindB("APT::Cache::AllVersions", true) ? - APT::VersionList::ALL : APT::VersionList::CANDIDATE; + APT::CacheSetHelper::VerSelector const select = _config->FindB("APT::Cache::AllVersions", true) ? + APT::CacheSetHelper::ALL : APT::CacheSetHelper::CANDIDATE; APT::VersionList const verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper); for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver) if (DisplayRecord(CacheFile, Ver) == false) -- cgit v1.2.3 From 3e032cda2d3558c076a559697e664546da56c243 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 15:02:39 +0100 Subject: remove leftover debug output from multikey softlink Git-Dch: Ignore --- cmdline/apt-key.in | 1 - 1 file changed, 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 0774cf4b7..59b69b89c 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -198,7 +198,6 @@ remove_key_from_keyring() { REALTARGET="$(readlink -f "$1")" mv -f "$1" "${1}.dpkg-tmp" cp -a "$REALTARGET" "$1" - ls "$(dirname $1)" fi # delete the key from the keyring $GPG --batch --delete-key --yes "$2" -- cgit v1.2.3 From 3d0def059874a6e63566ce13579de296ccd26932 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 16:43:19 +0100 Subject: add a (hidden) --quiet option for apt-key --- cmdline/apt-key.in | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 59b69b89c..d50ad40ac 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -39,6 +39,8 @@ ARCHIVE_KEYRING_URI='&keyring-uri;' eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) TMP_KEYRING=${APT_DIR}/var/lib/apt/keyrings/maybe-import-keyring.gpg +aptkey_echo() { echo "$@"; } + requires_root() { if [ "$(id -u)" -ne 0 ]; then echo >&1 "ERROR: This command can only be used by root." @@ -142,7 +144,7 @@ net_update() { fi new_mtime=$(stat -c %Y $keyring) if [ $new_mtime -ne $old_mtime ]; then - echo "Checking for new archive signing keys now" + aptkey_echo "Checking for new archive signing keys now" add_keys_with_verify_against_master_keyring $keyring $MASTER_KEYRING fi } @@ -227,7 +229,7 @@ remove_key() { done fi fi - echo "OK" + aptkey_echo "OK" } @@ -267,6 +269,10 @@ while [ -n "$1" ]; do requires_root() { true; } shift ;; + --quiet) + aptkey_echo() { true; } + shift + ;; --*) echo >&2 "Unknown option: $1" usage @@ -316,7 +322,7 @@ case "$command" in requires_root init_keyring "$TRUSTEDFILE" $GPG --quiet --batch --import "$1" - echo "OK" + aptkey_echo "OK" ;; del|rm|remove) init_keyring "$TRUSTEDFILE" @@ -348,7 +354,7 @@ case "$command" in ;; adv*) init_keyring "$TRUSTEDFILE" - echo "Executing: $GPG $*" + aptkey_echo "Executing: $GPG $*" $GPG $* ;; help) -- cgit v1.2.3 From 84b286f65c55e21b4734a17474f1cba464cbbd9c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 16:44:49 +0100 Subject: all errors should be printed to stderr Git-Dch: Ignore --- cmdline/apt-key.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index d50ad40ac..e592925d6 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -43,7 +43,7 @@ aptkey_echo() { echo "$@"; } requires_root() { if [ "$(id -u)" -ne 0 ]; then - echo >&1 "ERROR: This command can only be used by root." + echo >&2 "ERROR: This command can only be used by root." exit 1 fi } @@ -63,11 +63,11 @@ add_keys_with_verify_against_master_keyring() { MASTER=$2 if [ ! -f "$ADD_KEYRING" ]; then - echo "ERROR: '$ADD_KEYRING' not found" + echo >&2 "ERROR: '$ADD_KEYRING' not found" return - fi + fi if [ ! -f "$MASTER" ]; then - echo "ERROR: '$MASTER' not found" + echo >&2 "ERROR: '$MASTER' not found" return fi @@ -175,7 +175,7 @@ update() { fi done else - echo "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" >&2 + echo >&2 "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" fi } -- cgit v1.2.3 From 9fda3be1ae000e81e15dc8840271946e140765c9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:14:52 +0100 Subject: only create new trusted.gpg if directory is writeable --- cmdline/apt-key.in | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index e592925d6..66e26ef0c 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -48,16 +48,6 @@ requires_root() { fi } -# gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. -init_keyring() { - for path; do - if ! [ -e "$path" ]; then - touch -- "$path" - chmod 0644 -- "$path" - fi - done -} - add_keys_with_verify_against_master_keyring() { ADD_KEYRING=$1 MASTER=$2 @@ -311,49 +301,50 @@ if [ -z "$command" ]; then fi shift -if [ "$command" != "help" ] && ! which gpg >/dev/null 2>&1; then - echo >&2 "Warning: gnupg does not seem to be installed." - echo >&2 "Warning: apt-key requires gnupg for most operations." - echo >&2 +if [ "$command" != "help" ]; then + if ! which gpg >/dev/null 2>&1; then + echo >&2 "Warning: gnupg does not seem to be installed." + echo >&2 "Warning: apt-key requires gnupg for most operations." + echo >&2 + fi + + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. + if ! [ -e "$TRUSTEDFILE" ]; then + if [ -w "$(dirname "$TRUSTEDFILE")" ]; then + touch -- "$TRUSTEDFILE" + chmod 0644 -- "$TRUSTEDFILE" + fi + fi fi case "$command" in add) requires_root - init_keyring "$TRUSTEDFILE" $GPG --quiet --batch --import "$1" aptkey_echo "OK" ;; del|rm|remove) - init_keyring "$TRUSTEDFILE" remove_key "$1" ;; update) - init_keyring "$TRUSTEDFILE" update ;; net-update) - init_keyring "$TRUSTEDFILE" net_update ;; list) - init_keyring "$TRUSTEDFILE" $GPG --batch --list-keys ;; finger*) - init_keyring "$TRUSTEDFILE" $GPG --batch --fingerprint ;; export) - init_keyring "$TRUSTEDFILE" $GPG --armor --export "$1" ;; exportall) - init_keyring "$TRUSTEDFILE" $GPG --armor --export ;; adv*) - init_keyring "$TRUSTEDFILE" aptkey_echo "Executing: $GPG $*" $GPG $* ;; -- cgit v1.2.3 From 4f51a496d56807c73586220dd736173d7783c8b3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:24:56 +0100 Subject: support (multiple) arguments properly in apt-key --- cmdline/apt-key.in | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 66e26ef0c..ab62d4c8f 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -202,24 +202,27 @@ remove_key_from_keyring() { remove_key() { requires_root - # if a --keyring was given, just remove from there - if [ -n "$FORCED_KEYRING" ]; then - remove_key_from_keyring "$FORCED_KEYRING" "$1" - else - # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - remove_key_from_keyring "$TRUSTEDFILE" "$1" - TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) - if [ -d "$TRUSTEDPARTS" ]; then - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - remove_key_from_keyring "$trusted" "$1" - done + while [ -n "$1" ]; do + # if a --keyring was given, just remove from there + if [ -n "$FORCED_KEYRING" ]; then + remove_key_from_keyring "$FORCED_KEYRING" "$1" + else + # otherwise all known keyrings are up for inspection + local TRUSTEDFILE="/etc/apt/trusted.gpg" + eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) + eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) + remove_key_from_keyring "$TRUSTEDFILE" "$1" + TRUSTEDPARTS="/etc/apt/trusted.gpg.d" + eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) + if [ -d "$TRUSTEDPARTS" ]; then + for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do + remove_key_from_keyring "$trusted" "$1" + done + fi fi - fi - aptkey_echo "OK" + aptkey_echo "OK" + shift + done } @@ -320,11 +323,11 @@ fi case "$command" in add) requires_root - $GPG --quiet --batch --import "$1" + $GPG --quiet --batch --import "$@" aptkey_echo "OK" ;; del|rm|remove) - remove_key "$1" + remove_key "$@" ;; update) update @@ -333,20 +336,17 @@ case "$command" in net_update ;; list) - $GPG --batch --list-keys + $GPG --batch --list-keys "$@" ;; finger*) - $GPG --batch --fingerprint - ;; - export) - $GPG --armor --export "$1" + $GPG --batch --fingerprint "$@" ;; - exportall) - $GPG --armor --export + export|exportall) + $GPG --armor --export "$@" ;; adv*) aptkey_echo "Executing: $GPG $*" - $GPG $* + $GPG "$@" ;; help) usage -- cgit v1.2.3 From 08cfcd73f517e909823c100143c4938b9997343e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:41:35 +0100 Subject: set a primary-keyring only if we have access to it --- cmdline/apt-key.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index ab62d4c8f..9da5fceb8 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -281,8 +281,8 @@ if [ -z "$TRUSTEDFILE" ]; then eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) if [ -r "$TRUSTEDFILE" ]; then GPG="$GPG --keyring $TRUSTEDFILE" + GPG="$GPG --primary-keyring $TRUSTEDFILE" fi - GPG="$GPG --primary-keyring $TRUSTEDFILE" TRUSTEDPARTS="/etc/apt/trusted.gpg.d" eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) if [ -d "$TRUSTEDPARTS" ]; then @@ -316,6 +316,8 @@ if [ "$command" != "help" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then touch -- "$TRUSTEDFILE" chmod 0644 -- "$TRUSTEDFILE" + GPG="$GPG --keyring $TRUSTEDFILE" + GPG="$GPG --primary-keyring $TRUSTEDFILE" fi fi fi -- cgit v1.2.3 From 4b30c1dc053278a6b9bdb50f0d91b3f934e8613d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 18:24:43 +0100 Subject: refactor key removal code to reuse it in next step Git-Dch: Ignore --- cmdline/apt-key.in | 103 ++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 48 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9da5fceb8..9adbd6443 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -170,62 +170,69 @@ update() { } remove_key_from_keyring() { - local GPG="$GPG_CMD --keyring $1" - # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then - return - fi - if [ ! -w "$1" ]; then - echo >&2 "Key ${2} is in keyring ${1}, but can't be removed as it is read only." - return - fi - # check if it is the only key in the keyring and if so remove the keyring altogether - if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then - mv -f "$1" "${1}~" # behave like gpg - return - fi - # we can't just modify pointed to files as these might be in /usr or something - local REALTARGET - if [ -L "$1" ]; then - REALTARGET="$(readlink -f "$1")" - mv -f "$1" "${1}.dpkg-tmp" - cp -a "$REALTARGET" "$1" - fi - # delete the key from the keyring - $GPG --batch --delete-key --yes "$2" - if [ -n "$REALTARGET" ]; then - # the real backup is the old link, not the copy we made - mv -f "${1}.dpkg-tmp" "${1}~" - fi + local KEYRINGFILE="$1" + shift + local GPG="$GPG_CMD --keyring $KEYRINGFILE" + while [ -n "$1" ]; do + local KEY="$1" + shift + # check if the key is in this keyring: the key id is in the 5 column at the end + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+${KEY}:"; then + continue + fi + if [ ! -w "$KEYRINGFILE" ]; then + echo >&2 "Key ${KEY} is in keyring ${KEYRINGFILE}, but can't be removed as it is read only." + continue + fi + # check if it is the only key in the keyring and if so remove the keyring altogether + if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then + mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg + return + fi + # we can't just modify pointed to files as these might be in /usr or something + local REALTARGET + if [ -L "$KEYRINGFILE" ]; then + REALTARGET="$(readlink -f "$KEYRINGFILE")" + mv -f "$KEYRINGFILE" "${KEYRINGFILE}.dpkg-tmp" + cp -a "$REALTARGET" "$KEYRINGFILE" + fi + # delete the key from the keyring + $GPG --batch --delete-key --yes "$KEY" + if [ -n "$REALTARGET" ]; then + # the real backup is the old link, not the copy we made + mv -f "${KEYRINGFILE}.dpkg-tmp" "${KEYRINGFILE}~" + fi + done } remove_key() { requires_root + foreach_keyring_do 'remove_key_from_keyring' "$@" + aptkey_echo "OK" + } - while [ -n "$1" ]; do - # if a --keyring was given, just remove from there - if [ -n "$FORCED_KEYRING" ]; then - remove_key_from_keyring "$FORCED_KEYRING" "$1" - else - # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - remove_key_from_keyring "$TRUSTEDFILE" "$1" - TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) - if [ -d "$TRUSTEDPARTS" ]; then - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - remove_key_from_keyring "$trusted" "$1" - done - fi +foreach_keyring_do() { + local ACTION="$1" + shift + # if a --keyring was given, just remove from there + if [ -n "$FORCED_KEYRING" ]; then + $ACTION "$FORCED_KEYRING" "$@" + else + # otherwise all known keyrings are up for inspection + local TRUSTEDFILE="/etc/apt/trusted.gpg" + eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) + eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) + $ACTION "$TRUSTEDFILE" "$@" + local TRUSTEDPARTS="/etc/apt/trusted.gpg.d" + eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) + if [ -d "$TRUSTEDPARTS" ]; then + for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do + $ACTION "$trusted" "$@" + done fi - aptkey_echo "OK" - shift - done + fi } - usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" echo -- cgit v1.2.3 From 5beb682d2de2003e1c022cb298d6c2ec0cf91c0d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 22:40:52 +0100 Subject: merge fragment keyrings in apt-key to avoid hitting gpg limits gnupg has a hardlimit of 40 (at the moment) keyrings per invocation, which can be exceeded with (many) repositories. That is rather misfortune as the longrun goal was to drop gnupg dependency at some point in the future, but this can now be considered missed and dropped. It also means that 'apt-key adv' commands might not have the behaviour one would expect it to have as it mainly operates on a big temporary keyring, so commands modifying keys will break. Doing this was never a good idea anyway through, so lets just hope nothing break too badly. Closes: 733028 --- cmdline/apt-key.in | 134 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 57 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9adbd6443..9d8e60ec0 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -23,7 +23,6 @@ GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" $GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 # tell gpg that it shouldn't try to maintain a trustdb file GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" - GPG="$GPG_CMD" APT_DIR="/" @@ -113,7 +112,6 @@ net_update() { echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set" exit 1 fi - requires_root # in theory we would need to depend on wget for this, but this feature # isn't useable in debian anyway as we have no keyring uri nor a master key if ! which wget >/dev/null 2>&1; then @@ -145,7 +143,6 @@ update() { echo >&2 "Is the &keyring-package; package installed?" exit 1 fi - requires_root # add new keys from the package; @@ -158,11 +155,8 @@ update() { if [ -r "$REMOVED_KEYS" ]; then # remove no-longer supported/used keys - keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5` - for key in $keys; do - if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then - $GPG --quiet --batch --delete-key --yes ${key} - fi + $GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5 | while read key; do + foreach_keyring_do 'remove_key_from_keyring' "$key" done else echo >&2 "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" @@ -172,12 +166,17 @@ update() { remove_key_from_keyring() { local KEYRINGFILE="$1" shift + # non-existent keyrings have by definition no keys + if [ ! -e "$KEYRINGFILE" ]; then + return + fi + local GPG="$GPG_CMD --keyring $KEYRINGFILE" while [ -n "$1" ]; do local KEY="$1" shift # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+${KEY}:"; then + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*${KEY}:"; then continue fi if [ ! -w "$KEYRINGFILE" ]; then @@ -205,12 +204,6 @@ remove_key_from_keyring() { done } -remove_key() { - requires_root - foreach_keyring_do 'remove_key_from_keyring' "$@" - aptkey_echo "OK" - } - foreach_keyring_do() { local ACTION="$1" shift @@ -219,20 +212,62 @@ foreach_keyring_do() { $ACTION "$FORCED_KEYRING" "$@" else # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - $ACTION "$TRUSTEDFILE" "$@" + if [ -s "$TRUSTEDFILE" ]; then + $ACTION "$TRUSTEDFILE" "$@" + fi local TRUSTEDPARTS="/etc/apt/trusted.gpg.d" eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) if [ -d "$TRUSTEDPARTS" ]; then + # strip / suffix as gpg will double-slash in that case (#665411) + local STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}" + if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then + TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS" + fi for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - $ACTION "$trusted" "$@" + if [ -s "$trusted" ]; then + $ACTION "$trusted" "$@" + fi done fi fi } +list_keys_from_keyring() { + local KEYRINGFILE="$1" + shift + # don't show the error message if this keyring doesn't include the key + $GPG_CMD --keyring "$KEYRINGFILE" --batch --list-keys "$@" 2>/dev/null || true +} + +fingerprint_keys_from_keyring() { + local KEYRINGFILE="$1" + shift + # don't show the error message if this keyring doesn't include the fingerprint + $GPG_CMD --keyring "$KEYRINGFILE" --batch --fingerprint "$@" 2>/dev/null || true +} + +import_keys_from_keyring() { + local IMPORT="$1" + local KEYRINGFILE="$2" + $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" >/dev/null 2>&1 +} + +setup_merged_keyring() { + local TRUSTEDFILE_BAK="$TRUSTEDFILE" + TRUSTEDFILE='/dev/null' + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" + TRUSTEDFILE="$TRUSTEDFILE_BAK" + # mark it as non-writeable so users get errors if gnupg tries to modify it + if [ -s "${GPGHOMEDIR}/trusted.gpg" ]; then + chmod -w "${GPGHOMEDIR}/trusted.gpg" + GPG="$GPG --keyring ${GPGHOMEDIR}/trusted.gpg" + fi + if [ -r "$TRUSTEDFILE" ]; then + GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" + fi +} + + usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" echo @@ -257,12 +292,6 @@ while [ -n "$1" ]; do shift TRUSTEDFILE="$1" FORCED_KEYRING="$1" - if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then - GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" - else - echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable" - exit 1 - fi shift ;; --fakeroot) @@ -286,22 +315,6 @@ if [ -z "$TRUSTEDFILE" ]; then TRUSTEDFILE="/etc/apt/trusted.gpg" eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - if [ -r "$TRUSTEDFILE" ]; then - GPG="$GPG --keyring $TRUSTEDFILE" - GPG="$GPG --primary-keyring $TRUSTEDFILE" - fi - TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) - if [ -d "$TRUSTEDPARTS" ]; then - # strip / suffix as gpg will double-slash in that case (#665411) - STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}" - if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then - TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS" - fi - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - GPG="$GPG --keyring $trusted" - done - fi fi command="$1" @@ -323,40 +336,47 @@ if [ "$command" != "help" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then touch -- "$TRUSTEDFILE" chmod 0644 -- "$TRUSTEDFILE" - GPG="$GPG --keyring $TRUSTEDFILE" - GPG="$GPG --primary-keyring $TRUSTEDFILE" fi fi fi case "$command" in add) - requires_root - $GPG --quiet --batch --import "$@" - aptkey_echo "OK" + requires_root + setup_merged_keyring + $GPG --quiet --batch --import "$@" + aptkey_echo "OK" ;; del|rm|remove) - remove_key "$@" + requires_root + foreach_keyring_do 'remove_key_from_keyring' "$@" + aptkey_echo "OK" ;; update) + requires_root + setup_merged_keyring update ;; net-update) + requires_root + setup_merged_keyring net_update ;; list) - $GPG --batch --list-keys "$@" - ;; + foreach_keyring_do 'list_keys_from_keyring' "$@" + ;; finger*) - $GPG --batch --fingerprint "$@" - ;; + foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" + ;; export|exportall) - $GPG --armor --export "$@" - ;; + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" + $GPG_CMD --keyring "${GPGHOMEDIR}/trusted.gpg" --armor --export "$@" + ;; adv*) - aptkey_echo "Executing: $GPG $*" - $GPG "$@" - ;; + setup_merged_keyring + aptkey_echo "Executing: $GPG $*" + $GPG "$@" + ;; help) usage ;; -- cgit v1.2.3 From 059911800900a42c4246f1e209b51656055215b2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 17:37:00 +0100 Subject: delay gnupg setup in apt-key until it is needed 'apt-key help' and incorrect usage do not need a functioning gnupg setup, as well as we shouldn't try to setup gnupg before we actually test if it is available (and print a message if it is not). --- cmdline/apt-key.in | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9d8e60ec0..b8fdfe121 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -3,28 +3,6 @@ set -e unset GREP_OPTIONS -GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" - -# gpg needs (in different versions more or less) files to function correctly, -# so we give it its own homedir and generate some valid content for it -GPGHOMEDIR="$(mktemp -d)" -CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" -trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM -chmod 700 "$GPGHOMEDIR" -# We don't use a secret keyring, of course, but gpg panics and -# implodes if there isn't one available - and writeable for imports -SECRETKEYRING="${GPGHOMEDIR}/secring.gpg" -touch $SECRETKEYRING -GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" -# create the trustdb with an (empty) dummy keyring -# older gpgs required it, newer gpgs even warn that it isn't needed, -# but require it nonetheless for some commands, so we just play safe -# here for the foreseeable future and create a dummy one -$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 -# tell gpg that it shouldn't try to maintain a trustdb file -GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" -GPG="$GPG_CMD" - APT_DIR="/" eval $(apt-config shell APT_DIR Dir) @@ -331,6 +309,28 @@ if [ "$command" != "help" ]; then echo >&2 fi + GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" + + # gpg needs (in different versions more or less) files to function correctly, + # so we give it its own homedir and generate some valid content for it + GPGHOMEDIR="$(mktemp -d)" + CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" + trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM + chmod 700 "$GPGHOMEDIR" + # We don't use a secret keyring, of course, but gpg panics and + # implodes if there isn't one available - and writeable for imports + SECRETKEYRING="${GPGHOMEDIR}/secring.gpg" + touch $SECRETKEYRING + GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" + # create the trustdb with an (empty) dummy keyring + # older gpgs required it, newer gpgs even warn that it isn't needed, + # but require it nonetheless for some commands, so we just play safe + # here for the foreseeable future and create a dummy one + $GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 + # tell gpg that it shouldn't try to maintain a trustdb file + GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" + GPG="$GPG_CMD" + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. if ! [ -e "$TRUSTEDFILE" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then -- cgit v1.2.3 From 93d0d08cdd6854f9bfb779c13b5b78cd6ed263aa Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 18:28:50 +0100 Subject: support gnupg2 as drop-in replacement for gnupg If both are available APT will still prefer gpg over gpg2 as it is a bit more lightweight, but it shouldn't be a problem to use one or the other (at least at the moment, who knows what will happen in the future). --- cmdline/apt-key.in | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index b8fdfe121..12aee9750 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -303,13 +303,22 @@ fi shift if [ "$command" != "help" ]; then - if ! which gpg >/dev/null 2>&1; then - echo >&2 "Warning: gnupg does not seem to be installed." - echo >&2 "Warning: apt-key requires gnupg for most operations." + eval $(apt-config shell GPG_EXE Apt::Key::gpgcommand) + + if [ -n "$GPG_EXE" ] && which "$GPG_EXE" >/dev/null 2>&1; then + true + elif which gpg >/dev/null 2>&1; then + GPG_EXE="gpg" + elif which gpg2 >/dev/null 2>&1; then + GPG_EXE="gpg2" + else + echo >&2 "Error: gnupg or gnupg2 do not seem to be installed," + echo >&2 "Error: but apt-key requires gnupg or gnupg2 for operation." echo >&2 + exit 255 fi - GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" + GPG_CMD="$GPG_EXE --ignore-time-conflict --no-options --no-default-keyring" # gpg needs (in different versions more or less) files to function correctly, # so we give it its own homedir and generate some valid content for it -- cgit v1.2.3 From 0740a31033739ba30e7cb6754111f968167cbbf5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 19:14:13 +0100 Subject: respect --keyring also in merged keyring commands Git-Dch: Ignore --- cmdline/apt-key.in | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 12aee9750..c54b608e1 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -231,14 +231,16 @@ import_keys_from_keyring() { } setup_merged_keyring() { - local TRUSTEDFILE_BAK="$TRUSTEDFILE" - TRUSTEDFILE='/dev/null' - foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" - TRUSTEDFILE="$TRUSTEDFILE_BAK" - # mark it as non-writeable so users get errors if gnupg tries to modify it - if [ -s "${GPGHOMEDIR}/trusted.gpg" ]; then - chmod -w "${GPGHOMEDIR}/trusted.gpg" - GPG="$GPG --keyring ${GPGHOMEDIR}/trusted.gpg" + if [ -z "$FORCED_KEYRING" ]; then + local TRUSTEDFILE_BAK="$TRUSTEDFILE" + TRUSTEDFILE='/dev/null' + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" + TRUSTEDFILE="$TRUSTEDFILE_BAK" + # mark it as non-writeable so users get errors if gnupg tries to modify it + if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then + chmod -w "${GPGHOMEDIR}/pubring.gpg" + GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + fi fi if [ -r "$TRUSTEDFILE" ]; then GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" -- cgit v1.2.3 From 38005d8b24bb81f4862d2c2a228e4a49a2af4ccd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 16:59:46 +0100 Subject: add a test for apt-key export{,all} Git-Dch: Ignore --- cmdline/apt-key.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index c54b608e1..a3f8dde3a 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -380,8 +380,8 @@ case "$command" in foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" ;; export|exportall) - foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" - $GPG_CMD --keyring "${GPGHOMEDIR}/trusted.gpg" --armor --export "$@" + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" + $GPG_CMD --keyring "${GPGHOMEDIR}/pubring.gpg" --armor --export "$@" ;; adv*) setup_merged_keyring -- cgit v1.2.3 From ba72845c07b2682f251dc7661869d20095260f8f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 17:04:53 +0100 Subject: allow to specify fingerprints in 'apt-key del' --- cmdline/apt-key.in | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index a3f8dde3a..74ca4d135 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -25,6 +25,19 @@ requires_root() { fi } +get_fingerprints_of_keyring() { + $GPG_CMD --keyring "$1" --with-colons --fingerprint | while read publine; do + # search for a public key + if [ "${publine%%:*}" != 'pub' ]; then continue; fi + # search for the associated fingerprint (should be the very next line) + while read fprline; do + if [ "${fprline%%:*}" = 'sub' ]; then break; # should never happen + elif [ "${fprline%%:*}" != 'fpr' ]; then continue; fi + echo "$fprline" | cut -d':' -f 10 + done + done +} + add_keys_with_verify_against_master_keyring() { ADD_KEYRING=$1 MASTER=$2 @@ -42,7 +55,7 @@ add_keys_with_verify_against_master_keyring() { # is honored. so: # all keys that are exported must have a valid signature # from a key in the $distro-master-keyring - add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^pub | cut -d: -f5` + add_keys="$(get_fingerprints_of_keyring "$ADD_KEYRING")" all_add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5` master_keys=`$GPG_CMD --keyring $MASTER --with-colons --list-keys | grep ^pub | cut -d: -f5` @@ -133,7 +146,7 @@ update() { if [ -r "$REMOVED_KEYS" ]; then # remove no-longer supported/used keys - $GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5 | while read key; do + get_fingerprints_of_keyring "$REMOVED_KEYS" | while read key; do foreach_keyring_do 'remove_key_from_keyring' "$key" done else @@ -154,7 +167,7 @@ remove_key_from_keyring() { local KEY="$1" shift # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*${KEY}:"; then + if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -q "^[0-9A-F]*${KEY}$"; then continue fi if [ ! -w "$KEYRINGFILE" ]; then @@ -162,7 +175,7 @@ remove_key_from_keyring() { continue fi # check if it is the only key in the keyring and if so remove the keyring altogether - if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then + if [ '1' = "$(get_fingerprints_of_keyring "$KEYRINGFILE" | wc -l)" ]; then mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg return fi -- cgit v1.2.3 From bd7fb5aa31f58917e8630f2981e78d190d465198 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 18:26:44 +0100 Subject: add --secret-keyring option for apt-key For some advanced usecases it might be handy to specify the secret keyring to be used (e.g. as it is used in the testcases), but specifying it via a normal option for gnupg might not be available forever: http://lists.gnupg.org/pipermail/gnupg-users/2013-August/047180.html Git-Dch: Ignore --- cmdline/apt-key.in | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 74ca4d135..36824b6ec 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -287,6 +287,11 @@ while [ -n "$1" ]; do FORCED_KEYRING="$1" shift ;; + --secret-keyring) + shift + FORCED_SECRET_KEYRING="$1" + shift + ;; --fakeroot) requires_root() { true; } shift @@ -355,6 +360,12 @@ if [ "$command" != "help" ]; then GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" GPG="$GPG_CMD" + # for advanced operations, we might really need a secret keyring after all + if [ -n "$FORCED_SECRET_KEYRING" ] && [ -r "$FORCED_SECRET_KEYRING" ]; then + rm -f "$SECRETKEYRING" + cp -a "$FORCED_SECRET_KEYRING" "$SECRETKEYRING" + fi + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. if ! [ -e "$TRUSTEDFILE" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then -- cgit v1.2.3 From 0dae96a2b5e8ecd80a1b6e44961f1692ad4aec15 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 22:07:16 +0100 Subject: use only one --keyring in gpg interactions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were down to at most two keyrings before, but gnupg upstream plans dropping support for multiple keyrings in the longrun, so with a single keyring we hope to be future proof – and 'apt-key adv' isn't a problem anymore as every change to the keys is merged back, so we have now the same behavior as before, but support an unlimited amount of trusted.gpg.d keyrings. --- cmdline/apt-key.in | 105 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 28 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 36824b6ec..9259fac0d 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -14,7 +14,6 @@ REMOVED_KEYS='&keyring-removed-filename;' eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys) ARCHIVE_KEYRING_URI='&keyring-uri;' eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) -TMP_KEYRING=${APT_DIR}/var/lib/apt/keyrings/maybe-import-keyring.gpg aptkey_echo() { echo "$@"; } @@ -68,24 +67,28 @@ add_keys_with_verify_against_master_keyring() { fi done done - + for add_key in $add_keys; do # export the add keyring one-by-one - rm -f $TMP_KEYRING - $GPG_CMD --keyring $ADD_KEYRING --output $TMP_KEYRING --export $add_key - # check if signed with the master key and only add in this case - ADDED=0 + local TMP_KEYRING="${GPGHOMEDIR}/tmp-keyring.gpg" + $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --output "$TMP_KEYRING" --export "$add_key" + if ! $GPG_CMD --batch --yes --keyring "$TMP_KEYRING" --import "$MASTER" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi + # check if signed with the master key and only add in this case + ADDED=0 for master_key in $master_keys; do - if $GPG_CMD --keyring $MASTER --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then - $GPG --import $TMP_KEYRING + if $GPG_CMD --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then + $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --export "$add_key" | $GPG --batch --yes --import ADDED=1 fi done if [ $ADDED = 0 ]; then echo >&2 "Key '$add_key' not added. It is not signed with a master key" fi + rm -f "${TMP_KEYRING}" done - rm -f $TMP_KEYRING } # update the current archive signing keyring from a network URI @@ -240,26 +243,75 @@ fingerprint_keys_from_keyring() { import_keys_from_keyring() { local IMPORT="$1" local KEYRINGFILE="$2" - $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" >/dev/null 2>&1 + if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi +} + +merge_keys_into_keyrings() { + local KEYRINGFILE="$1" + local IMPORT="$2" + if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import --import-options 'merge-only' "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi +} + +merge_back_changes() { + if [ -n "$FORCED_KEYRING" ]; then + # if the keyring was forced merge is already done + return + fi + if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then + # merge all updated keys + foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg" + fi + # no look for keys which were added or removed + get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst" + get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst" + #echo >&2 "MERGE BACK" + sort "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" | uniq --unique | while read key; do + if grep -q "^${key}$" "${GPGHOMEDIR}/pubring.orig.keylst"; then + # key isn't part of new keyring, so remove + foreach_keyring_do 'remove_key_from_keyring' "$key" + elif grep -q "^${key}$" "${GPGHOMEDIR}/pubring.keylst"; then + # key is part of new keyring, so we need to import it + create_new_keyring "$TRUSTEDFILE" + if ! $GPG --batch --yes --export "$key" | $GPG_CMD --keyring "$TRUSTEDFILE" --batch --yes --import > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi + else + echo >&2 "Errror: Key ${key} (dis)appeared out of nowhere" + fi + done } setup_merged_keyring() { if [ -z "$FORCED_KEYRING" ]; then - local TRUSTEDFILE_BAK="$TRUSTEDFILE" - TRUSTEDFILE='/dev/null' foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" - TRUSTEDFILE="$TRUSTEDFILE_BAK" - # mark it as non-writeable so users get errors if gnupg tries to modify it - if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then - chmod -w "${GPGHOMEDIR}/pubring.gpg" - GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + if [ -r "${GPGHOMEDIR}/pubring.gpg" ]; then + cp -a "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg" + else + touch "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg" fi - fi - if [ -r "$TRUSTEDFILE" ]; then - GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" + GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + else + GPG="$GPG --keyring $TRUSTEDFILE" + create_new_keyring "$TRUSTEDFILE" fi } +create_new_keyring() { + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. + if ! [ -e "$TRUSTEDFILE" ]; then + if [ -w "$(dirname "$TRUSTEDFILE")" ]; then + touch -- "$TRUSTEDFILE" + chmod 0644 -- "$TRUSTEDFILE" + fi + fi +} usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" @@ -365,14 +417,6 @@ if [ "$command" != "help" ]; then rm -f "$SECRETKEYRING" cp -a "$FORCED_SECRET_KEYRING" "$SECRETKEYRING" fi - - # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. - if ! [ -e "$TRUSTEDFILE" ]; then - if [ -w "$(dirname "$TRUSTEDFILE")" ]; then - touch -- "$TRUSTEDFILE" - chmod 0644 -- "$TRUSTEDFILE" - fi - fi fi case "$command" in @@ -380,22 +424,26 @@ case "$command" in requires_root setup_merged_keyring $GPG --quiet --batch --import "$@" + merge_back_changes aptkey_echo "OK" ;; del|rm|remove) requires_root foreach_keyring_do 'remove_key_from_keyring' "$@" + merge_back_changes aptkey_echo "OK" ;; update) requires_root setup_merged_keyring update + merge_back_changes ;; net-update) requires_root setup_merged_keyring net_update + merge_back_changes ;; list) foreach_keyring_do 'list_keys_from_keyring' "$@" @@ -411,6 +459,7 @@ case "$command" in setup_merged_keyring aptkey_echo "Executing: $GPG $*" $GPG "$@" + merge_back_changes ;; help) usage -- cgit v1.2.3 From 33a2267214eed2a11281c9f93b8cf10b4c436d94 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 17:56:28 +0100 Subject: add --readonly option for apt-key adv Some advanced commands can be executed without the keyring being modified like --verify, so this adds an option to disable the mergeback and uses it for our gpg calling code. Git-Dch: Ignore --- cmdline/apt-key.in | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9259fac0d..21d692631 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -337,20 +337,19 @@ while [ -n "$1" ]; do shift TRUSTEDFILE="$1" FORCED_KEYRING="$1" - shift ;; --secret-keyring) shift FORCED_SECRET_KEYRING="$1" - shift + ;; + --readonly) + merge_back_changes() { true; } ;; --fakeroot) requires_root() { true; } - shift ;; --quiet) aptkey_echo() { true; } - shift ;; --*) echo >&2 "Unknown option: $1" @@ -359,6 +358,7 @@ while [ -n "$1" ]; do *) break;; esac + shift done if [ -z "$TRUSTEDFILE" ]; then @@ -430,7 +430,6 @@ case "$command" in del|rm|remove) requires_root foreach_keyring_do 'remove_key_from_keyring' "$@" - merge_back_changes aptkey_echo "OK" ;; update) -- cgit v1.2.3 From 0b94a7bc2ebb42453d9e22dc58dde76b9261de50 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 18:43:55 +0100 Subject: miscellaneous small cleanups in apt-key Git-Dch: Ignore --- cmdline/apt-key.in | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 21d692631..a9a729cce 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -166,9 +166,7 @@ remove_key_from_keyring() { fi local GPG="$GPG_CMD --keyring $KEYRINGFILE" - while [ -n "$1" ]; do - local KEY="$1" - shift + for KEY in "$@"; do # check if the key is in this keyring: the key id is in the 5 column at the end if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -q "^[0-9A-F]*${KEY}$"; then continue @@ -226,18 +224,11 @@ foreach_keyring_do() { fi } -list_keys_from_keyring() { +run_cmd_on_keyring() { local KEYRINGFILE="$1" shift - # don't show the error message if this keyring doesn't include the key - $GPG_CMD --keyring "$KEYRINGFILE" --batch --list-keys "$@" 2>/dev/null || true -} - -fingerprint_keys_from_keyring() { - local KEYRINGFILE="$1" - shift - # don't show the error message if this keyring doesn't include the fingerprint - $GPG_CMD --keyring "$KEYRINGFILE" --batch --fingerprint "$@" 2>/dev/null || true + # fingerprint and co will fail if key isn't in this keyring + $GPG_CMD --keyring "$KEYRINGFILE" --batch "$@" 2>/dev/null || true } import_keys_from_keyring() { @@ -267,10 +258,9 @@ merge_back_changes() { # merge all updated keys foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg" fi - # no look for keys which were added or removed + # look for keys which were added or removed get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst" get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst" - #echo >&2 "MERGE BACK" sort "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" | uniq --unique | while read key; do if grep -q "^${key}$" "${GPGHOMEDIR}/pubring.orig.keylst"; then # key isn't part of new keyring, so remove @@ -445,10 +435,10 @@ case "$command" in merge_back_changes ;; list) - foreach_keyring_do 'list_keys_from_keyring' "$@" + foreach_keyring_do 'run_cmd_on_keyring' --list-keys "$@" ;; finger*) - foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" + foreach_keyring_do 'run_cmd_on_keyring' --fingerprint "$@" ;; export|exportall) foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" -- cgit v1.2.3 From c46a36adaf51fc28464ea1a0e826c754ee60672b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 14 Apr 2014 18:24:17 +0200 Subject: add and use 'apt-key verify' which prefers gpgv over gpg gnupg/gnupg2 can do verify just fine of course, so we don't need to use gpgv here, but it is what we always used in the past, so there might be scripts expecting a certain output and more importantly the output of apt-cdrom contains messages from gpg and even with all the settings we activate to prevent it, it still shows (in some versions) a quiet scary: "gpg: WARNING: Using untrusted key!" message. Keeping the use of gpgv is the simplest way to prevent it. We are increasing also the "Breaks: apt" version from libapt as it requires a newer apt-key than might be installed in partial upgrades. --- cmdline/apt-key.in | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index a9a729cce..83a7a31b9 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -450,6 +450,14 @@ case "$command" in $GPG "$@" merge_back_changes ;; + verify) + setup_merged_keyring + if which gpgv >/dev/null 2>&1; then + gpgv --homedir "${GPGHOMEDIR}" --keyring "${GPGHOMEDIR}/pubring.gpg" --ignore-time-conflict "$@" + else + $GPG --verify "$@" + fi + ;; help) usage ;; -- cgit v1.2.3 From a221efc331693f8905da870141756c892911c433 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 19:34:40 +0200 Subject: store source name and version in binary cache Accessing the package records to acquire this information is pretty costly, so that information wasn't used so far in many places. The most noticeable user by far is EDSP at the moment, but there are ideas to change that which this commit tries to enable. --- cmdline/apt-cache.cc | 2 ++ cmdline/apt-get.cc | 64 ++++++++++++++++++---------------------------------- 2 files changed, 24 insertions(+), 42 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 5a5dde088..0f4f7e1ce 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -389,6 +389,8 @@ static bool Stats(CommandLine &) stritems.insert(V->VerStr); if (V->Section != 0) stritems.insert(V->Section); + stritems.insert(V->SourcePkgName); + stritems.insert(V->SourceVerStr); for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D) { if (D->Version != 0) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index aed1beb4d..a5cafc39d 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -195,7 +195,7 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ -static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, +static pkgSrcRecords::Parser *FindSrc(const char *Name, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { @@ -303,16 +303,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { - pkgRecords::Parser &Parse = Recs.Lookup(VF); - Src = Parse.SourcePkg(); - // no SourcePkg name, so it is the "binary" name - if (Src.empty() == true) - Src = TmpSrc; + Src = Ver.SourcePkgName(); // the Version we have is possibly fuzzy or includes binUploads, - // so we use the Version of the SourcePkg (empty if same as package) - VerTag = Parse.SourceVer(); - if (VerTag.empty() == true) - VerTag = Ver.VerStr(); + // so we use the Version of the SourcePkg + VerTag = Ver.SourceVerStr(); break; } } @@ -343,10 +337,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); + if (strcmp(Ver.SourcePkgName(),Ver.ParentPkg().Name()) != 0) + Src = Ver.SourcePkgName(); + if (VerTag.empty() == true && strcmp(Ver.SourceVerStr(),Ver.VerStr()) != 0) + VerTag = Ver.SourceVerStr(); } } } @@ -731,7 +725,6 @@ static bool DoSource(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -760,7 +753,7 @@ static bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,SrcRecs,Src,Cache); if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); @@ -1037,7 +1030,6 @@ static bool DoBuildDep(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -1090,7 +1082,7 @@ static bool DoBuildDep(CommandLine &CmdL) Last = Type->CreateSrcPkgParser(*I); } else { // normal case, search the cache for the source file - Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + Last = FindSrc(*I,SrcRecs,Src,Cache); } if (Last == 0) @@ -1441,21 +1433,15 @@ static bool DoBuildDep(CommandLine &CmdL) * pool/ next to the deb itself) * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" */ -static string GetChangelogPath(CacheFile &Cache, - pkgCache::PkgIterator Pkg, +static string GetChangelogPath(CacheFile &Cache, pkgCache::VerIterator Ver) { - string path; - pkgRecords Recs(Cache); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); - string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); - string ver = Ver.VerStr(); - // if there is a source version it always wins - if (rec.SourceVer() != "") - ver = rec.SourceVer(); - path = flNotFile(rec.FileName()); - path += srcpkg + "_" + StripEpoch(ver); + string path = flNotFile(rec.FileName()); + path.append(Ver.SourcePkgName()); + path.append("_"); + path.append(StripEpoch(Ver.SourceVerStr())); return path; } /*}}}*/ @@ -1469,7 +1455,6 @@ static string GetChangelogPath(CacheFile &Cache, * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog */ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, - pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver, string &out_uri) { @@ -1484,7 +1469,7 @@ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, return false; // get archive uri for the binary deb - string path_without_dot_changelog = GetChangelogPath(Cache, Pkg, Ver); + string path_without_dot_changelog = GetChangelogPath(Cache, Ver); out_uri = index->ArchiveURI(path_without_dot_changelog + ".changelog"); // now strip away the filename and add srcpkg_srcver.changelog @@ -1502,25 +1487,20 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, * GuessThirdPartyChangelogUri for details how) */ { - string path; - string descr; - string server; - string changelog_uri; - - // data structures we need - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - // make the server root configurable - server = _config->Find("Apt::Changelogs::Server", + string const server = _config->Find("Apt::Changelogs::Server", "http://packages.debian.org/changelogs"); - path = GetChangelogPath(CacheFile, Pkg, Ver); + string const path = GetChangelogPath(CacheFile, Ver); + string changelog_uri; strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); if (_config->FindB("APT::Get::Print-URIs", false) == true) { std::cout << '\'' << changelog_uri << '\'' << std::endl; return true; } + pkgCache::PkgIterator const Pkg = Ver.ParentPkg(); + string descr; strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); // queue it new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); @@ -1531,7 +1511,7 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, if (!FileExists(targetfile)) { string third_party_uri; - if (GuessThirdPartyChangelogUri(CacheFile, Pkg, Ver, third_party_uri)) + if (GuessThirdPartyChangelogUri(CacheFile, Ver, third_party_uri)) { strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str()); new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); -- cgit v1.2.3 From 43acd01979039b248cb7f033b82e36d778d0ebec Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 27 Sep 2014 19:45:30 +0200 Subject: allow fetcher setup without directory creation apt-get download and changelog as well as apt-helper reuse the acquire system for their own proposes without requiring the directories the fetcher wants to create, which is a problem if you run them as non-root and the directories do not exist as it greets you with: E: Archives directory /var/cache/apt/archives/partial is missing. - Acquire (13: Permission denied) Closes: 762898 --- cmdline/apt-get.cc | 9 +++++---- cmdline/apt-helper.cc | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a5cafc39d..6d03c7eec 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -626,14 +626,14 @@ static bool DoDownload(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0)); pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat) == false) + if (Fetcher.Setup(&Stat, "", false) == false) return false; pkgRecords Recs(Cache); @@ -1536,7 +1536,7 @@ static bool DoChangelog(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; pkgAcquire Fetcher; @@ -1551,7 +1551,8 @@ static bool DoChangelog(CommandLine &CmdL) } AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); + if (Fetcher.Setup(&Stat, "",false) == false) + return false; bool const downOnly = _config->FindB("APT::Get::Download-Only", false); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index dd43ea1bc..b89df61d6 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -51,7 +51,8 @@ static bool DoDownloadFile(CommandLine &CmdL) pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); + if (Fetcher.Setup(&Stat, "", false) == false) + return false; std::string download_uri = CmdL.FileList[1]; std::string targetfile = CmdL.FileList[2]; std::string hash; -- cgit v1.2.3 From 20e6965ad6388b964b59b89c31ff8b81cbcb8f8c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 27 Sep 2014 20:09:44 +0200 Subject: cleanup partial directory of lists in apt-get clean Not really the intended usecase for apt-get clean, but users expect it to help them in recovery and it can't really hurt as this directory should be empty if everything was fine and proper anyway. Closes: #762889 --- cmdline/apt-get.cc | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 6d03c7eec..c8c3ca56b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -549,30 +549,44 @@ static bool DoDSelectUpgrade(CommandLine &) static bool DoClean(CommandLine &) { std::string const archivedir = _config->FindDir("Dir::Cache::archives"); - std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache"); - std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache"); + std::string const listsdir = _config->FindDir("Dir::state::lists"); if (_config->FindB("APT::Get::Simulate") == true) { + std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache"); + std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache"); cout << "Del " << archivedir << "* " << archivedir << "partial/*"<< endl + << "Del " << listsdir << "partial/*" << endl << "Del " << pkgcache << " " << srcpkgcache << endl; return true; } - + + bool const NoLocking = _config->FindB("Debug::NoLocking",false); // Lock the archive directory FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) + if (NoLocking == false) { int lock_fd = GetLock(archivedir + "lock"); if (lock_fd < 0) - return _error->Error(_("Unable to lock the download directory")); + return _error->Error(_("Unable to lock directory %s"), archivedir.c_str()); Lock.Fd(lock_fd); } - + pkgAcquire Fetcher; Fetcher.Clean(archivedir); Fetcher.Clean(archivedir + "partial/"); + if (NoLocking == false) + { + Lock.Close(); + int lock_fd = GetLock(listsdir + "lock"); + if (lock_fd < 0) + return _error->Error(_("Unable to lock directory %s"), listsdir.c_str()); + Lock.Fd(lock_fd); + } + + Fetcher.Clean(listsdir + "partial/"); + pkgCacheFile::RemoveCaches(); return true; -- cgit v1.2.3 From 7ffac4c10144a8458fec6de03c58f3b49d081e5c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 29 Sep 2014 11:43:37 +0200 Subject: Test if TMPDIR is a directory in apt-key and if not unset it This prevents a failure in mktemp -d - it will blindly trust TMPDIR and not use something else if the dir is not there. --- cmdline/apt-key.in | 3 +++ 1 file changed, 3 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 83a7a31b9..7a3852ee8 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -384,6 +384,9 @@ if [ "$command" != "help" ]; then # gpg needs (in different versions more or less) files to function correctly, # so we give it its own homedir and generate some valid content for it + if [ ! -d "$TMPDIR" ]; then + unset TMPDIR + fi GPGHOMEDIR="$(mktemp -d)" CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM -- cgit v1.2.3 From 4c370aad7539b7e3bc0028aa538f34b95a526cff Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 2 Oct 2014 17:48:13 +0200 Subject: apt-get: Create the temporary downloaded changelog inside tmpdir The code is creating a secure temporary directory, but then creates the changelog alongside the tmpdir in the same base directory. This defeats the secure tmpdir creation, making the filename predictable. Inject a '/' between the tmpdir and the changelog filename. --- cmdline/apt-get.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 2e283da5a..cfa79339b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1563,7 +1563,7 @@ static bool DoChangelog(CommandLine &CmdL) { string changelogfile; if (downOnly == false) - changelogfile.append(tmpname).append("changelog"); + changelogfile.append(tmpname).append("/changelog"); else changelogfile.append(Ver.ParentPkg().Name()).append(".changelog"); if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false) -- cgit v1.2.3 From 339bc464875616d214cc3b73f5d41ced10c820b9 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 2 Oct 2014 17:48:13 +0200 Subject: apt-get: Create the temporary downloaded changelog inside tmpdir The code is creating a secure temporary directory, but then creates the changelog alongside the tmpdir in the same base directory. This defeats the secure tmpdir creation, making the filename predictable. Inject a '/' between the tmpdir and the changelog filename. --- cmdline/apt-get.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0cea05cb3..13a85d34b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1588,7 +1588,7 @@ static bool DoChangelog(CommandLine &CmdL) { string changelogfile; if (downOnly == false) - changelogfile.append(tmpname).append("changelog"); + changelogfile.append(tmpname).append("/changelog"); else changelogfile.append(Ver.ParentPkg().Name()).append(".changelog"); if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false) -- cgit v1.2.3 From 04a54261afd1c99686109f102afc83346c01c930 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 6 Oct 2014 11:15:03 +0200 Subject: ensure partial dirs are 0700 and owned by _apt:root Reworks the API involved in creating and setting up the fetcher to be a bit more pleasent to look at and work with as e.g. an empty string for no lock isn't very nice. With the lock we can also stop creating all our partial directories "just in case". This way we can also be a bit more aggressive with the partial directory itself as with a lock, we know we will gone need it. --- cmdline/apt-get.cc | 18 ++++-------------- cmdline/apt-helper.cc | 6 ++---- 2 files changed, 6 insertions(+), 18 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0cea05cb3..15696e19f 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -646,9 +646,7 @@ static bool DoDownload(CommandLine &CmdL) return false; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0)); - pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat, "", false) == false) - return false; + pkgAcquire Fetcher(&Stat); pkgRecords Recs(Cache); pkgSourceList *SrcList = Cache.GetSourceList(); @@ -744,9 +742,8 @@ static bool DoSource(CommandLine &CmdL) return false; // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher; - Fetcher.SetLog(&Stat); + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); SPtrArray Dsc = new DscFile[CmdL.FileSize()]; @@ -1048,12 +1045,6 @@ static bool DoBuildDep(CommandLine &CmdL) if (_error->PendingError() == true) return false; - // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat) == false) - return false; - bool StripMultiArch; string hostArch = _config->Find("APT::Get::Host-Architecture"); if (hostArch.empty() == false) @@ -1565,8 +1556,7 @@ static bool DoChangelog(CommandLine &CmdL) } AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - if (Fetcher.Setup(&Stat, "",false) == false) - return false; + Fetcher.SetLog(&Stat); bool const downOnly = _config->FindB("APT::Get::Download-Only", false); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index b89df61d6..c240008aa 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -48,11 +48,9 @@ static bool DoDownloadFile(CommandLine &CmdL) if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); - - pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - if (Fetcher.Setup(&Stat, "", false) == false) - return false; + pkgAcquire Fetcher(&Stat); + std::string download_uri = CmdL.FileList[1]; std::string targetfile = CmdL.FileList[2]; std::string hash; -- cgit v1.2.3 From 373fa2b4b2caae977c41b2c10ea27e41308a05c3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 7 Oct 2014 13:30:27 +0200 Subject: Rename DropPrivs() to DropPrivileges() Git-Dch: ignore --- cmdline/apt-dump-solver.cc | 2 +- cmdline/apt-internal-solver.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-dump-solver.cc b/cmdline/apt-dump-solver.cc index 424764b3c..f765234c5 100644 --- a/cmdline/apt-dump-solver.cc +++ b/cmdline/apt-dump-solver.cc @@ -41,7 +41,7 @@ int main(int argc,const char *argv[]) /*{{{*/ return 0; } // we really don't need anything - DropPrivs(); + DropPrivileges(); FILE* input = fdopen(STDIN_FILENO, "r"); FILE* output = fopen("/tmp/dump.edsp", "w"); diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index 0f2ec6283..92a4429e5 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -77,7 +77,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {0,0,0,0}}; // we really don't need anything - DropPrivs(); + DropPrivileges(); CommandLine CmdL(Args,_config); if (pkgInitConfig(*_config) == false || -- cgit v1.2.3 From 460601d53039b1d1b5688a8cd58bae10fb746f57 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 15 Oct 2014 02:43:44 +0200 Subject: don't drop privileges if _apt has not enough rights MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Privilege dropping breaks download/source/changelog commands as they require the _apt user to have write permissions in the current directory, which is e.g. the case in /tmp, but not in /root, so we disable the privilege dropping if we deal with such a directory based on idea and code by Michael Vogt. The alternative would be to download always to a temp directory and move it then done, but this breaks partial file support. To resolve this, we could move to one of our partial/ directories, but this would require a lock which would block root from using two of these commands in parallel. As both seems unacceptable we instead let the user choose what to do: Either a directory is setupped for _apt, downloading as root is accepted or – which is potentially even better – an unprivileged user is used for the commands. --- cmdline/apt-get.cc | 19 ++++++++++++++----- cmdline/apt-helper.cc | 5 ++++- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 8448638db..8c0c50f83 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -676,6 +676,9 @@ static bool DoDownload(CommandLine &CmdL) return true; } + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + if (_error->PendingError() == true || CheckAuth(Fetcher, false) == false) return false; @@ -858,10 +861,6 @@ static bool DoSource(CommandLine &CmdL) } } - // check authentication status of the source as well - if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) - return false; - // Display statistics unsigned long long FetchBytes = Fetcher.FetchNeeded(); unsigned long long FetchPBytes = Fetcher.PartialPresent(); @@ -908,7 +907,7 @@ static bool DoSource(CommandLine &CmdL) ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); return true; } - + // Just print out the uris an exit if the --print-uris flag was used if (_config->FindB("APT::Get::Print-URIs") == true) { @@ -919,6 +918,13 @@ static bool DoSource(CommandLine &CmdL) return true; } + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + + // check authentication status of the source as well + if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) + return false; + // Run it bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) @@ -1510,6 +1516,9 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, // queue it new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + // try downloading it, if that fails, try third-party-changelogs location // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? Fetcher.Run(); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index c240008aa..27abb2013 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -59,7 +59,10 @@ static bool DoDownloadFile(CommandLine &CmdL) // we use download_uri as descr and targetfile as short-descr new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, "dest-dir-ignored", targetfile); - Fetcher.Run(); + + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || FileExists(targetfile) == false) -- cgit v1.2.3 From 9c81f8de38df940559d13a3ea9591d63cbe970bb Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 15 Oct 2014 04:18:07 +0200 Subject: check for available space, excluding root reserved blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are checking the space requirements for ages, but the check uses the free blocks count, which includes the blocks reserved for usage by root. Now that we use an unprivileged user it has no access to these blocks anymore – and more importantly these blocks are a reserve, they shouldn't be used by apt without special encouragement by the user as it would be bad to have dpkg run out of diskspace and maintainerscripts like man-db skip certain actions if not enough space is available freely. --- cmdline/apt-get.cc | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 8c0c50f83..e176a3350 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -78,8 +78,6 @@ #include #include #include -#include -#include #include #include #include @@ -866,29 +864,9 @@ static bool DoSource(CommandLine &CmdL) unsigned long long FetchPBytes = Fetcher.PartialPresent(); unsigned long long DebBytes = Fetcher.TotalNeeded(); - // Check for enough free space - struct statvfs Buf; - string OutputDir = "."; - if (statvfs(OutputDir.c_str(),&Buf) != 0) { - if (errno == EOVERFLOW) - return _error->WarningE("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - else - return _error->Errno("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) - { - struct statfs Stat; - if (statfs(OutputDir.c_str(),&Stat) != 0 -#if HAVE_STRUCT_STATFS_F_TYPE - || unsigned(Stat.f_type) != RAMFS_MAGIC -#endif - ) { - return _error->Error(_("You don't have enough free space in %s"), - OutputDir.c_str()); - } - } - + if (CheckFreeSpaceBeforeDownload(".", (FetchBytes - FetchPBytes)) == false) + return false; + // Number of bytes if (DebBytes != FetchBytes) //TRANSLATOR: The required space between number and unit is already included -- cgit v1.2.3 From 0d303f1764645284b33924c9be8bf29f0a32ca5c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 20 Oct 2014 12:00:46 +0200 Subject: test if TMPDIR is accessible before using Private temporary directories as created by e.g. libpam-tmpdir are nice, but they are also very effective in preventing our priviledge dropping to work as TMPDIR will be set to a directory only root has access to, so working with it as _apt will fail. We circumvent this by extending our check for a usable TMPDIR setting by checking access rights. Closes: 765951 --- cmdline/apt-key.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 7a3852ee8..cf0b9a96f 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -384,8 +384,12 @@ if [ "$command" != "help" ]; then # gpg needs (in different versions more or less) files to function correctly, # so we give it its own homedir and generate some valid content for it - if [ ! -d "$TMPDIR" ]; then - unset TMPDIR + if [ -n "$TMPDIR" ]; then + # tmpdir is a directory and current user has rwx access to it + # same tests as in apt-pkg/contrib/fileutl.cc GetTempDir() + if [ ! -d "$TMPDIR" ] || [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] || [ ! -x "$TMPDIR" ]; then + unset TMPDIR + fi fi GPGHOMEDIR="$(mktemp -d)" CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" -- cgit v1.2.3 From 03aa08472dcd689572a46ce6efdb1dccf6136334 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 23 Oct 2014 01:28:05 +0200 Subject: chown finished partial files earlier partial files are chowned by the Item baseclass to let the methods work with them. Now, this baseclass is also responsible for chowning the files back to root instead of having various deeper levels do this. The consequence is that all overloaded Failed() methods now call the Item::Failed base as their first step. The same is done for Done(). The effect is that even in partial files usually don't belong to _apt anymore, helping sneakernets and reducing possibilities of a bad method modifying files not belonging to them. The change is supported by the framework not only supporting being run as root, but with proper permission management, too, so that privilege dropping can be tested with them. --- cmdline/apt-get.cc | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index e176a3350..b6786faf8 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -80,6 +80,9 @@ #include #include #include +#include +#include + #include #include #include @@ -659,6 +662,8 @@ static bool DoDownload(CommandLine &CmdL) Ver != verset.end(); ++Ver, ++i) { pkgAcquire::Item *I = new pkgAcqArchive(&Fetcher, SrcList, &Recs, *Ver, storefile[i]); + if (storefile[i].empty()) + continue; std::string const filename = cwd + flNotDir(storefile[i]); storefile[i].assign(filename); I->DestFile.assign(filename); @@ -1481,7 +1486,10 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, "http://packages.debian.org/changelogs"); string const path = GetChangelogPath(CacheFile, Ver); string changelog_uri; - strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); + if (APT::String::Endswith(server, "/") == true) + strprintf(changelog_uri, "%s%s/changelog", server.c_str(), path.c_str()); + else + strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); if (_config->FindB("APT::Get::Print-URIs", false) == true) { std::cout << '\'' << changelog_uri << '\'' << std::endl; @@ -1492,7 +1500,7 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, string descr; strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); // queue it - new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); + pkgAcquire::Item const * itm = new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); // Disable drop-privs if "_apt" can not write to the target dir CheckDropPrivsMustBeDisabled(Fetcher); @@ -1500,18 +1508,18 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, // try downloading it, if that fails, try third-party-changelogs location // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? Fetcher.Run(); - if (!FileExists(targetfile)) + if (itm->Status != pkgAcquire::Item::StatDone) { string third_party_uri; if (GuessThirdPartyChangelogUri(CacheFile, Ver, third_party_uri)) { strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str()); - new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); + itm = new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); Fetcher.Run(); } } - if (FileExists(targetfile)) + if (itm->Status == pkgAcquire::Item::StatDone) return true; // error @@ -1557,6 +1565,19 @@ static bool DoChangelog(CommandLine &CmdL) tmpdir = mkdtemp(tmpname); if (tmpdir == NULL) return _error->Errno("mkdtemp", "mkdtemp failed"); + + std::string const SandboxUser = _config->Find("APT::Sandbox::User"); + if (getuid() == 0 && SandboxUser.empty() == false) // if we aren't root, we can't chown, so don't try it + { + struct passwd const * const pw = getpwnam(SandboxUser.c_str()); + struct group const * const gr = getgrnam("root"); + if (pw != NULL && gr != NULL) + { + // chown the tmp dir directory we use to the sandbox user + if(chown(tmpdir, pw->pw_uid, gr->gr_gid) != 0) + _error->WarningE("DoChangelog", "chown to %s:%s of directory %s failed", SandboxUser.c_str(), "root", tmpdir); + } + } } for (APT::VersionList::const_iterator Ver = verset.begin(); @@ -1572,7 +1593,7 @@ static bool DoChangelog(CommandLine &CmdL) { DisplayFileInPager(changelogfile); // cleanup temp file - unlink(changelogfile.c_str()); + unlink(changelogfile.c_str()); } } // clenaup tmp dir -- cgit v1.2.3 From f105aaba433f5a8b9c4326dd0d704501bf07d1e5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Nov 2014 12:53:59 +0100 Subject: better non-virtual metaIndex.LocalFileName() implementation We can't add a new virtual method without breaking the ABI, but we can freely add new methods, so for older ABIs we just implement this method with a dynamic_cast, so that clients can be more ignorant about the API here and especially don't need to pull a very dirty trick by assuming internal knowledge (like apt-get did here). --- cmdline/apt-get.cc | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index b6786faf8..e9e38debc 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -136,28 +136,6 @@ static bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return true; } /*}}}*/ - - -// helper that can go wit hthe next ABI break -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) -static std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) -{ - // FIXME: this cast is the horror, the horror - debReleaseIndex *r = (debReleaseIndex*)metaindex; - - // see if we have a InRelease file - std::string PathInRelease = r->MetaIndexFile("InRelease"); - if (FileExists(PathInRelease)) - return PathInRelease; - - // and if not return the normal one - if (FileExists(PathInRelease)) - return r->MetaIndexFile("Release"); - - return ""; -} -#endif - // GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -176,12 +154,8 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, { if (&CurrentIndexFile == (*IF)) { -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) - std::string path = MetaIndexFileNameOnDisk(*S); -#else - std::string path = (*S)->LocalFileName(); -#endif - if (path != "") + std::string const path = (*S)->LocalFileName(); + if (path != "") { indexRecords records; records.Load(path); -- cgit v1.2.3 From 765190e493645e13b5651625d87fd9c8db910a85 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 16:45:18 +0100 Subject: guard ABI changes for SourcePkg/Ver in pkgCache Git-Dch: Ignore --- cmdline/apt-cache.cc | 2 ++ cmdline/apt-get.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 0f4f7e1ce..1bd75dfba 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -389,8 +389,10 @@ static bool Stats(CommandLine &) stritems.insert(V->VerStr); if (V->Section != 0) stritems.insert(V->Section); +#if APT_PKG_ABI >= 413 stritems.insert(V->SourcePkgName); stritems.insert(V->SourceVerStr); +#endif for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D) { if (D->Version != 0) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index e9e38debc..eca4a723b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -170,7 +170,11 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ +#if APT_PKG_ABI >= 413 static pkgSrcRecords::Parser *FindSrc(const char *Name, +#else +static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, +#endif pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { @@ -278,10 +282,21 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name, (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { - Src = Ver.SourcePkgName(); // the Version we have is possibly fuzzy or includes binUploads, - // so we use the Version of the SourcePkg + // so we use the Version of the SourcePkg (empty if same as package) +#if APT_PKG_ABI >= 413 + Src = Ver.SourcePkgName(); VerTag = Ver.SourceVerStr(); +#else + pkgRecords::Parser &Parse = Recs.Lookup(VF); + Src = Parse.SourcePkg(); + // no SourcePkg name, so it is the "binary" name + if (Src.empty() == true) + Src = TmpSrc; + VerTag = Parse.SourceVer(); + if (VerTag.empty() == true) + VerTag = Ver.VerStr(); +#endif break; } } @@ -312,10 +327,17 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name, pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { +#if APT_PKG_ABI >= 413 if (strcmp(Ver.SourcePkgName(),Ver.ParentPkg().Name()) != 0) Src = Ver.SourcePkgName(); if (VerTag.empty() == true && strcmp(Ver.SourceVerStr(),Ver.VerStr()) != 0) VerTag = Ver.SourceVerStr(); +#else + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + Src = Parse.SourcePkg(); + if (VerTag.empty() == true) + VerTag = Parse.SourceVer(); +#endif } } } @@ -717,6 +739,9 @@ static bool DoSource(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers +#if APT_PKG_ABI < 413 + pkgRecords Recs(Cache); +#endif pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -744,8 +769,11 @@ static bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; +#if APT_PKG_ABI >= 413 pkgSrcRecords::Parser *Last = FindSrc(*I,SrcRecs,Src,Cache); - +#else + pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); +#endif if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); } @@ -1004,6 +1032,9 @@ static bool DoBuildDep(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers +#if APT_PKG_ABI < 413 + pkgRecords Recs(Cache); +#endif pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -1050,7 +1081,11 @@ static bool DoBuildDep(CommandLine &CmdL) Last = Type->CreateSrcPkgParser(*I); } else { // normal case, search the cache for the source file - Last = FindSrc(*I,SrcRecs,Src,Cache); +#if APT_PKG_ABI >= 413 + Last = FindSrc(*I,SrcRecs,Src,Cache); +#else + Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); +#endif } if (Last == 0) @@ -1407,9 +1442,18 @@ static string GetChangelogPath(CacheFile &Cache, pkgRecords Recs(Cache); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); string path = flNotFile(rec.FileName()); +#if APT_PKG_ABI >= 413 path.append(Ver.SourcePkgName()); path.append("_"); path.append(StripEpoch(Ver.SourceVerStr())); +#else + string srcpkg = rec.SourcePkg().empty() ? Ver.ParentPkg().Name() : rec.SourcePkg(); + string ver = Ver.VerStr(); + // if there is a source version it always wins + if (rec.SourceVer() != "") + ver = rec.SourceVer(); + path += srcpkg + "_" + StripEpoch(ver); +#endif return path; } /*}}}*/ -- cgit v1.2.3 From 32ab4bd05cb298f6bf1f9574f5b20570beaae429 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 19:18:21 +0100 Subject: guard pkg/grp hashtable creation changes The change itself is no problem ABI wise, but the remove of the old undynamic hashtables is, so we bring it back for older abis and happily use the now available free space to backport more recent additions like the dynamic hashtable itself. Git-Dch: Ignore --- cmdline/apt-cache.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 1bd75dfba..9bac45029 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -267,11 +267,14 @@ static bool DumpPackage(CommandLine &CmdL) // ShowHashTableStats - Show stats about a hashtable /*{{{*/ // --------------------------------------------------------------------- /* */ +static map_pointer_t PackageNext(pkgCache::Package const * const P) { return P->NextPackage; } +static map_pointer_t GroupNext(pkgCache::Group const * const G) { return G->Next; } template static void ShowHashTableStats(std::string Type, T *StartP, map_pointer_t *Hashtable, - unsigned long Size) + unsigned long Size, + map_pointer_t(*Next)(T const * const)) { // hashtable stats for the HashTable unsigned long NumBuckets = Size; @@ -290,7 +293,7 @@ static void ShowHashTableStats(std::string Type, } ++UsedBuckets; unsigned long ThisBucketSize = 0; - for (; P != StartP; P = StartP + P->Next) + for (; P != StartP; P = StartP + Next(P)) ++ThisBucketSize; Entries += ThisBucketSize; LongestBucket = std::max(ThisBucketSize, LongestBucket); @@ -447,13 +450,13 @@ static bool Stats(CommandLine &) APT_CACHESIZE(VerFileCount, VerFileSz) + APT_CACHESIZE(DescFileCount, DescFileSz) + APT_CACHESIZE(ProvidesCount, ProvidesSz) + - (2 * Cache->Head().HashTableSize * sizeof(map_id_t)); + (2 * Cache->Head().GetHashTableSize() * sizeof(map_id_t)); cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; #undef APT_CACHESIZE // hashtable stats - ShowHashTableStats("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTable(), Cache->Head().HashTableSize); - ShowHashTableStats("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTable(), Cache->Head().HashTableSize); + ShowHashTableStats("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTableP(), Cache->Head().GetHashTableSize(), PackageNext); + ShowHashTableStats("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTableP(), Cache->Head().GetHashTableSize(), GroupNext); return true; } -- cgit v1.2.3 From ad7e0941b376d792911f240377094a2e78ca8756 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 8 Nov 2014 18:14:46 +0100 Subject: streamline display of --help in all tools By convention, if I run a tool with --help or --version I expect it to exit successfully with the usage, while if I do call it wrong (like without any parameters) I expect the usage message shown with a non-zero exit. --- cmdline/apt-cache.cc | 18 ++---------------- cmdline/apt-cdrom.cc | 15 ++------------- cmdline/apt-config.cc | 15 ++------------- cmdline/apt-extracttemplates.cc | 32 ++++++++++++-------------------- cmdline/apt-get.cc | 22 ++-------------------- cmdline/apt-helper.cc | 21 ++------------------- cmdline/apt-internal-solver.cc | 17 ++++------------- cmdline/apt-mark.cc | 22 ++-------------------- cmdline/apt-sortpkgs.cc | 24 ++++++++---------------- cmdline/apt.cc | 20 +++----------------- cmdline/makefile | 8 ++++---- 11 files changed, 43 insertions(+), 171 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 9bac45029..12ed4f719 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1896,23 +1896,9 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); - // See if the help should be shown - if (_config->FindB("help") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } - // Deal with stdout not being a tty if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 53efe65b8..8ac73fd7e 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -249,19 +249,8 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || _config->FindB("version") == true || - CmdL.FileSize() == 0) - return ShowHelp(CmdL); + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); // Deal with stdout not being a tty if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc index 40ba468eb..e0b8a624e 100644 --- a/cmdline/apt-config.cc +++ b/cmdline/apt-config.cc @@ -115,19 +115,8 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - CmdL.FileSize() == 0) - return ShowHelp(CmdL); + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); std::vector const langs = APT::Configuration::getLanguages(true); _config->Clear("Acquire::Languages"); diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index f95b9e5ba..5211ee027 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -33,6 +33,8 @@ #include #include +#include + #include #include #include @@ -215,15 +217,15 @@ bool DebFile::ParseInfo() // ShowHelp - show a short help text /*{{{*/ // --------------------------------------------------------------------- /* */ -static int ShowHelp(void) +static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, + ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, COMMON_ARCH,__DATE__,__TIME__); - if (_config->FindB("version") == true) - return 0; + if (_config->FindB("version") == true) + return true; - cout << + cout << _("Usage: apt-extracttemplates file1 [file2 ...]\n" "\n" "apt-extracttemplates is a tool to extract config and template info\n" @@ -234,7 +236,7 @@ static int ShowHelp(void) " -t Set the temp dir\n" " -c=? Read this configuration file\n" " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"); - return 0; + return true; } /*}}}*/ // WriteFile - write the contents of the passed string to a file /*{{{*/ @@ -356,20 +358,10 @@ int main(int argc, const char **argv) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args,_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - CmdL.FileSize() == 0) - return ShowHelp(); - + CommandLine::Dispatch Cmds[] = {{NULL, NULL}}; + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args, &_config, &_system, argc, argv, ShowHelp); + Go(CmdL); // Print any errors or warnings found during operation diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index eca4a723b..a9053bdfd 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1746,26 +1746,8 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - if (_config->FindB("version") == true) - ShowHelp(CmdL); - - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); // see if we are in simulate mode CheckSimulateMode(CmdL); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index 27abb2013..1b832f165 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -108,25 +108,8 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - if (_config->FindB("version") == true) - ShowHelp(CmdL); - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); InitOutput(); diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index 92a4429e5..4fabeb02f 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -24,7 +24,9 @@ #include #include #include + #include +#include #include #include @@ -79,19 +81,8 @@ int main(int argc,const char *argv[]) /*{{{*/ // we really don't need anything DropPrivileges(); - CommandLine CmdL(Args,_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false) { - _error->DumpErrors(); - return 2; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true) { - ShowHelp(CmdL); - return 1; - } + CommandLine CmdL; + ParseCommandLine(CmdL, NULL, Args, &_config, NULL, argc, argv, ShowHelp); if (CmdL.FileList[0] != 0 && strcmp(CmdL.FileList[0], "scenario") == 0) { diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index ed348358a..487f3d8a1 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -441,26 +441,8 @@ int main(int argc,const char *argv[]) /*{{{*/ setlocale(LC_ALL,""); textdomain(PACKAGE); - // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(),_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - if (_config->FindB("version") == true) - ShowHelp(CmdL); - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); // Deal with stdout not being a tty if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) diff --git a/cmdline/apt-sortpkgs.cc b/cmdline/apt-sortpkgs.cc index c2b11890a..9b66ad4db 100644 --- a/cmdline/apt-sortpkgs.cc +++ b/cmdline/apt-sortpkgs.cc @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -142,12 +144,12 @@ static bool DoIt(string InFile) // ShowHelp - Show the help text /*{{{*/ // --------------------------------------------------------------------- /* */ -static int ShowHelp() +static bool ShowHelp(CommandLine &) { ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, COMMON_ARCH,__DATE__,__TIME__); if (_config->FindB("version") == true) - return 0; + return true; cout << _("Usage: apt-sortpkgs [options] file1 [file2 ...]\n" @@ -161,7 +163,7 @@ static int ShowHelp() " -c=? Read this configuration file\n" " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"); - return 0; + return true; } /*}}}*/ int main(int argc,const char *argv[]) /*{{{*/ @@ -179,19 +181,9 @@ int main(int argc,const char *argv[]) /*{{{*/ textdomain(PACKAGE); // Parse the command line and initialize the package library - CommandLine CmdL(Args,_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - CmdL.FileSize() == 0) - return ShowHelp(); + CommandLine::Dispatch Cmds[] = {{NULL, NULL}}; + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args, &_config, &_system, argc, argv, ShowHelp); // Match the operation for (unsigned int I = 0; I != CmdL.FileSize(); I++) diff --git a/cmdline/apt.cc b/cmdline/apt.cc index 2cfdf8e8e..056cd213f 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -119,15 +119,10 @@ int main(int argc, const char *argv[]) /*{{{*/ _config->CndSet("APT::Cmd::Show-Update-Stats", true); // Parse the command line and initialize the package library - CommandLine CmdL(Args.data(), _config); - if (CmdL.Parse(argc, argv) == false || - pkgInitSystem(*_config, _system) == false) - { - _error->DumpErrors(); - return 100; - } + CommandLine CmdL; + ParseCommandLine(CmdL, Cmds, Args.data(), NULL, &_system, argc, argv, ShowHelp); - if(!isatty(STDOUT_FILENO) && + if(!isatty(STDOUT_FILENO) && _config->FindB("Apt::Cmd::Disable-Script-Warning", false) == false) { std::cerr << std::endl @@ -138,15 +133,6 @@ int main(int argc, const char *argv[]) /*{{{*/ << std::endl; } - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } - // see if we are in simulate mode CheckSimulateMode(CmdL); diff --git a/cmdline/makefile b/cmdline/makefile index b7c35ddd1..816038c3b 100644 --- a/cmdline/makefile +++ b/cmdline/makefile @@ -67,15 +67,15 @@ APT_DOMAIN:=apt-utils # The apt-sortpkgs program PROGRAM=apt-sortpkgs -SLIBS = -lapt-pkg $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-sortpkgs.cc include $(PROGRAM_H) # The apt-extracttemplates program PROGRAM=apt-extracttemplates -SLIBS = -lapt-pkg -lapt-inst $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile apt-inst/makefile +SLIBS = -lapt-pkg -lapt-inst -lapt-private $(INTLLIBS) +LIB_MAKES = apt-pkg/makefile apt-inst/makefile apt-private/makefile SOURCE = apt-extracttemplates.cc include $(PROGRAM_H) -- cgit v1.2.3 From d9e518c6f7dc0ad464495b586d1b8e115d54d41a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 8 Nov 2014 20:44:44 +0100 Subject: use the same code to detect quiet setting in all tools Git-Dch: Ignore --- cmdline/apt-cache.cc | 4 +--- cmdline/apt-cdrom.cc | 7 +++---- cmdline/apt-mark.cc | 18 ++---------------- 3 files changed, 6 insertions(+), 23 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 12ed4f719..342ad1858 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1899,9 +1899,7 @@ int main(int argc,const char *argv[]) /*{{{*/ CommandLine CmdL; ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); - // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) - _config->Set("quiet","1"); + InitOutput(); if (_config->Exists("APT::Cache::Generate") == true) _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true)); diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 8ac73fd7e..327039e00 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -31,6 +31,7 @@ #include #include +#include #include /*}}}*/ @@ -252,10 +253,8 @@ int main(int argc,const char *argv[]) /*{{{*/ CommandLine CmdL; ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); - // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) - _config->Set("quiet","1"); - + InitOutput(); + // Match the operation bool returned = CmdL.DispatchArg(Cmds); diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index 487f3d8a1..2702dbbd3 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -41,10 +42,6 @@ /*}}}*/ using namespace std; -ostream c0out(0); -ostream c1out(0); -ostream c2out(0); -ofstream devnull("/dev/null"); /* DoAuto - mark packages as automatically/manually installed {{{*/ static bool DoAuto(CommandLine &CmdL) { @@ -444,18 +441,7 @@ int main(int argc,const char *argv[]) /*{{{*/ CommandLine CmdL; ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); - // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) - _config->Set("quiet","1"); - - // Setup the output streams - c0out.rdbuf(cout.rdbuf()); - c1out.rdbuf(cout.rdbuf()); - c2out.rdbuf(cout.rdbuf()); - if (_config->FindI("quiet",0) > 0) - c0out.rdbuf(devnull.rdbuf()); - if (_config->FindI("quiet",0) > 1) - c1out.rdbuf(devnull.rdbuf()); + InitOutput(); // Match the operation CmdL.DispatchArg(Cmds); -- cgit v1.2.3 From 374f8492e6f109e8427816a8f513e5e8feda9049 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Nov 2014 15:40:19 +0100 Subject: allow uninstalled packages to be put on hold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dpkg wants to know about a package before it can be put on hold, so we have to at least hint about its existance in the available file it "maintaince" to know about such stuff. The simple thing would probably be to just feed all Packages files into dpkg as well, but what would be the point really? Exactly, so we take a shortcut here and just create dummies in the available file if we need to which isn't going to be that common as usually you are holding packages back and not off. Who would have thought that a simple feature like setting a package on hold requires more than 200 lines of code… at least with the testcase it is now explicitly tested code. --- cmdline/apt-mark.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index 2702dbbd3..860982f9e 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -275,10 +275,64 @@ static bool DoHold(CommandLine &CmdL) } Args.erase(Args.begin() + BaseArgs, Args.end()); - Args.push_back("--set-selections"); + Args.push_back("--merge-avail"); + Args.push_back("-"); Args.push_back(NULL); int external[2] = {-1, -1}; + if (pipe(external) != 0) + return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --merge-avail"); + + pid_t dpkgMergeAvail = ExecFork(); + if (dpkgMergeAvail == 0) + { + close(external[1]); + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0) + _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --merge-avail", chrootDir.c_str()); + dup2(external[0], STDIN_FILENO); + int const nullfd = open("/dev/null", O_RDONLY); + dup2(nullfd, STDOUT_FILENO); + execvp(Args[0], (char**) &Args[0]); + _error->WarningE("dpkgGo", "Can't get dpkg --merge-avail running!"); + _exit(2); + } + + FILE* dpkg = fdopen(external[1], "w"); + for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + { + if (Pkg->CurrentVer != 0) + continue; + char const * Arch; + if (Pkg->VersionList != 0) + Arch = Pkg.VersionList().Arch(); + else + Arch = Pkg.Arch(); + fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example \n" + "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", Pkg.Name(), Arch); + } + fclose(dpkg); + + if (dpkgMergeAvail > 0) + { + int Status = 0; + while (waitpid(dpkgMergeAvail, &Status, 0) != dpkgMergeAvail) + { + if (errno == EINTR) + continue; + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --merge-avail"); + break; + } + if (WIFEXITED(Status) == false || WEXITSTATUS(Status) != 0) + return _error->Error(_("Executing dpkg failed. Are you root?")); + } + + Args.erase(Args.begin() + BaseArgs, Args.end()); + Args.push_back("--set-selections"); + Args.push_back(NULL); + + external[0] = -1; + external[1] = -1; if (pipe(external) != 0) return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --set-selections"); @@ -289,16 +343,13 @@ static bool DoHold(CommandLine &CmdL) std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0) _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --set-selections", chrootDir.c_str()); - int const nullfd = open("/dev/null", O_RDONLY); dup2(external[0], STDIN_FILENO); - dup2(nullfd, STDOUT_FILENO); - dup2(nullfd, STDERR_FILENO); execvp(Args[0], (char**) &Args[0]); - _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); + _error->WarningE("dpkgGo", "Can't get dpkg --set-selections running!"); _exit(2); } - FILE* dpkg = fdopen(external[1], "w"); + dpkg = fdopen(external[1], "w"); for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) { if (dpkgMultiArch == false) -- cgit v1.2.3 From 7e04a6bf23d857db60afd2ec3d0f4a8271b1c597 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Nov 2014 19:04:54 +0100 Subject: use pkgAcquire::GetLock instead of own code Do the same with less code in apt-get. This especially ensures that the lock file (and the parent directories) exist before we are trying to lock. It also means that clean now creates the directories if they are missing so we returned to a proper clean state now. Git-Dch: Ignore --- cmdline/apt-get.cc | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a9053bdfd..eab792264 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -558,30 +558,12 @@ static bool DoClean(CommandLine &) return true; } - bool const NoLocking = _config->FindB("Debug::NoLocking",false); - // Lock the archive directory - FileFd Lock; - if (NoLocking == false) - { - int lock_fd = GetLock(archivedir + "lock"); - if (lock_fd < 0) - return _error->Error(_("Unable to lock directory %s"), archivedir.c_str()); - Lock.Fd(lock_fd); - } - pkgAcquire Fetcher; + Fetcher.GetLock(archivedir); Fetcher.Clean(archivedir); Fetcher.Clean(archivedir + "partial/"); - if (NoLocking == false) - { - Lock.Close(); - int lock_fd = GetLock(listsdir + "lock"); - if (lock_fd < 0) - return _error->Error(_("Unable to lock directory %s"), listsdir.c_str()); - Lock.Fd(lock_fd); - } - + Fetcher.GetLock(listsdir); Fetcher.Clean(listsdir + "partial/"); pkgCacheFile::RemoveCaches(); -- cgit v1.2.3 From 3a2b39ee602dd5a98b8fdaee2f1c8e0b13a276e2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 18 Aug 2013 23:27:24 +0200 Subject: use 'best' hash for source authentication Collect all hashes we can get from the source record and put them into a HashStringList so that 'apt-get source' can use it instead of using always the MD5sum. We therefore also deprecate the MD5 struct member in favor of the list. While at it, the parsing of the Files is enhanced so that records which miss "Files" (aka MD5 checksums) are still searched for other checksums as they include just as much data, just not with a nice and catchy name. This is a cherry-pick of 1262d35 with some dirty tricks to preserve ABI. LP: 1098738 --- cmdline/apt-get.cc | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index cfa79339b..a28537712 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -797,13 +797,13 @@ static bool DoSource(CommandLine &CmdL) } // Back track - vector Lst; - if (Last->Files(Lst) == false) { + vector Lst; + if (Last->Files2(Lst) == false) { return false; } // Load them into the fetcher - for (vector::const_iterator I = Lst.begin(); + for (vector::const_iterator I = Lst.begin(); I != Lst.end(); ++I) { // Try to guess what sort of file it is we are getting. @@ -832,22 +832,26 @@ static bool DoSource(CommandLine &CmdL) queued.insert(Last->Index().ArchiveURI(I->Path)); // check if we have a file with that md5 sum already localy - if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) - { - FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); - MD5Summation sum; - sum.AddFD(Fd.Fd(), Fd.Size()); - Fd.Close(); - if((string)sum.Result() == I->MD5Hash) + std::string localFile = flNotDir(I->Path); + if (FileExists(localFile) == true) + if(I->Hashes.VerifyFile(localFile) == true) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), - flNotDir(I->Path).c_str()); + localFile.c_str()); continue; } + + // see if we have a hash (Acquire::ForceHash is the only way to have none) + HashString const * const hs = I->Hashes.find(NULL); + if (hs == NULL && _config->FindB("APT::Get::AllowUnauthenticated",false) == false) + { + ioprintf(c1out, "Skipping download of file '%s' as requested hashsum is not available for authentication\n", + localFile.c_str()); + continue; } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->MD5Hash,I->Size, + hs != NULL ? hs->toStr() : "", I->FileSize, Last->Index().SourceInfo(*Last,*I),Src); } } -- cgit v1.2.3 From 081c9d442a6d39fb9bc419fe3ce697cc791cb844 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Nov 2014 21:38:53 +0100 Subject: various small additional tests and testcases Usually they don't provide a lot in terms of what they test, but they help in covering many lines from strictly anecdotal commands (stats, moo) and error messages, so that stuff which really needs to be tested, but isn't is better visible in coverage reports. Git-Dch: Ignore --- cmdline/apt-cache.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 342ad1858..a5024c581 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -116,7 +116,7 @@ static bool ShowUnMet(pkgCache::VerIterator const &V, bool const Important) continue; // Skip conflicts and replaces - if (End.IsNegative() == true) + if (End.IsNegative() == true || End->Type == pkgCache::Dep::Replaces) continue; // Verify the or group @@ -133,7 +133,7 @@ static bool ShowUnMet(pkgCache::VerIterator const &V, bool const Important) break; } delete [] VList; - + if (Start == End) break; ++Start; -- cgit v1.2.3 From 1d838084dc775c0a4184edb4f3b9138903ac27fb Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 18 Nov 2014 13:41:18 +0100 Subject: use dpkg --merge-avail only if needed in apt-mark Only "recent" versions of dpkg support stdin for merge instead of a file, so as a quick fix we delay calling it until we really need it which fixes most of the problem already. Checking for a specific dpkg version here is deemed too much work, just like using a temporary file here and depends a too high requirement for this minor usecase. After all, it didn't work at all before, so we break nobody here and can fix it if someone complains (with a patch). --- cmdline/apt-mark.cc | 100 +++++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 45 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index 860982f9e..8974397c9 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -274,65 +274,75 @@ static bool DoHold(CommandLine &CmdL) return true; } - Args.erase(Args.begin() + BaseArgs, Args.end()); - Args.push_back("--merge-avail"); - Args.push_back("-"); - Args.push_back(NULL); - - int external[2] = {-1, -1}; - if (pipe(external) != 0) - return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --merge-avail"); - - pid_t dpkgMergeAvail = ExecFork(); - if (dpkgMergeAvail == 0) - { - close(external[1]); - std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); - if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0) - _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --merge-avail", chrootDir.c_str()); - dup2(external[0], STDIN_FILENO); - int const nullfd = open("/dev/null", O_RDONLY); - dup2(nullfd, STDOUT_FILENO); - execvp(Args[0], (char**) &Args[0]); - _error->WarningE("dpkgGo", "Can't get dpkg --merge-avail running!"); - _exit(2); - } - - FILE* dpkg = fdopen(external[1], "w"); + APT::PackageList keepoffset; for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) { if (Pkg->CurrentVer != 0) continue; - char const * Arch; - if (Pkg->VersionList != 0) - Arch = Pkg.VersionList().Arch(); - else - Arch = Pkg.Arch(); - fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example \n" - "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", Pkg.Name(), Arch); + keepoffset.insert(Pkg); } - fclose(dpkg); - if (dpkgMergeAvail > 0) + if (keepoffset.empty() == false) { - int Status = 0; - while (waitpid(dpkgMergeAvail, &Status, 0) != dpkgMergeAvail) + Args.erase(Args.begin() + BaseArgs, Args.end()); + Args.push_back("--merge-avail"); + // FIXME: supported only since 1.17.7 in dpkg + Args.push_back("-"); + Args.push_back(NULL); + + int external[2] = {-1, -1}; + if (pipe(external) != 0) + return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --merge-avail"); + + pid_t dpkgMergeAvail = ExecFork(); + if (dpkgMergeAvail == 0) { - if (errno == EINTR) - continue; - _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --merge-avail"); - break; + close(external[1]); + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0) + _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --merge-avail", chrootDir.c_str()); + dup2(external[0], STDIN_FILENO); + int const nullfd = open("/dev/null", O_RDONLY); + dup2(nullfd, STDOUT_FILENO); + execvp(Args[0], (char**) &Args[0]); + _error->WarningE("dpkgGo", "Can't get dpkg --merge-avail running!"); + _exit(2); + } + + FILE* dpkg = fdopen(external[1], "w"); + for (APT::PackageList::iterator Pkg = keepoffset.begin(); Pkg != keepoffset.end(); ++Pkg) + { + char const * Arch; + if (Pkg->VersionList != 0) + Arch = Pkg.VersionList().Arch(); + else + Arch = Pkg.Arch(); + fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example \n" + "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", Pkg.Name(), Arch); + } + fclose(dpkg); + keepoffset.clear(); + + if (dpkgMergeAvail > 0) + { + int Status = 0; + while (waitpid(dpkgMergeAvail, &Status, 0) != dpkgMergeAvail) + { + if (errno == EINTR) + continue; + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --merge-avail"); + break; + } + if (WIFEXITED(Status) == false || WEXITSTATUS(Status) != 0) + return _error->Error(_("Executing dpkg failed. Are you root?")); } - if (WIFEXITED(Status) == false || WEXITSTATUS(Status) != 0) - return _error->Error(_("Executing dpkg failed. Are you root?")); } Args.erase(Args.begin() + BaseArgs, Args.end()); Args.push_back("--set-selections"); Args.push_back(NULL); - external[0] = -1; - external[1] = -1; + int external[2] = {-1, -1}; if (pipe(external) != 0) return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --set-selections"); @@ -349,7 +359,7 @@ static bool DoHold(CommandLine &CmdL) _exit(2); } - dpkg = fdopen(external[1], "w"); + FILE* dpkg = fdopen(external[1], "w"); for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) { if (dpkgMultiArch == false) -- cgit v1.2.3 From 69d8b8537af1dd52db5f2e0e785bdce3e52fdf8d Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 28 Nov 2014 14:21:06 +0100 Subject: support long keyids in "apt-key del" instead of ignoring them apt-key given a long keyid reports just "OK" all the time, but doesn't delete the mentioned key as it doesn't find the key. Note: In debian/experimental this was closed with 29f1b977100aeb6d6ebd38923eeb7a623e264ffe which just added the testcase as the rewrite of apt-key had fixed this as well. Closes: 754436 --- cmdline/apt-key.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 0774cf4b7..b4e071000 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -180,7 +180,7 @@ update() { remove_key_from_keyring() { local GPG="$GPG_CMD --keyring $1" # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*$2:"; then return fi if [ ! -w "$1" ]; then -- cgit v1.2.3 From ed793a19ec00b83254029509bc516e3ba911c75a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 Nov 2014 17:59:52 +0100 Subject: dispose http(s) 416 error page as non-content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real webservers (like apache) actually send an error page with a 416 response, but our client didn't expect it leaving the page on the socket to be parsed as response for the next request (http) or as file content (https), which isn't what we want at all… Symptom is a "Bad header line" as html usually doesn't parse that well to an http-header. This manifests itself e.g. if we have a complete file (or larger) in partial/ which isn't discarded by If-Range as the server doesn't support it (or it is just newer, think: mirror rotation). It is a sort-of regression of 78c72d0ce22e00b194251445aae306df357d5c1a, which removed the filesize - 1 trick, but this had its own problems… To properly test this our webserver gains the ability to reply with transfer-encoding: chunked as most real webservers will use it to send the dynamically generated error pages. Closes: 768797 --- cmdline/apt-helper.cc | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index 1b832f165..a05ae90a2 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -51,22 +51,33 @@ static bool DoDownloadFile(CommandLine &CmdL) AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); - std::string download_uri = CmdL.FileList[1]; - std::string targetfile = CmdL.FileList[2]; - std::string hash; - if (CmdL.FileSize() > 3) - hash = CmdL.FileList[3]; - // we use download_uri as descr and targetfile as short-descr - new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, - "dest-dir-ignored", targetfile); + size_t fileind = 0; + std::vector targetfiles; + while (fileind + 2 <= CmdL.FileSize()) + { + std::string download_uri = CmdL.FileList[fileind + 1]; + std::string targetfile = CmdL.FileList[fileind + 2]; + std::string hash; + if (CmdL.FileSize() > fileind + 3) + hash = CmdL.FileList[fileind + 3]; + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, + "dest-dir-ignored", targetfile); + targetfiles.push_back(targetfile); + fileind += 3; + } // Disable drop-privs if "_apt" can not write to the target dir CheckDropPrivsMustBeDisabled(Fetcher); bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || - FileExists(targetfile) == false) + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return _error->Error(_("Download Failed")); + if (targetfiles.empty() == false) + for (std::vector::const_iterator f = targetfiles.begin(); f != targetfiles.end(); ++f) + if (FileExists(*f) == false) + return _error->Error(_("Download Failed")); + return true; } -- cgit v1.2.3 From 92e8c1ff287ab829de825e00cdf94744e699ff97 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 Nov 2014 17:59:52 +0100 Subject: dispose http(s) 416 error page as non-content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real webservers (like apache) actually send an error page with a 416 response, but our client didn't expect it leaving the page on the socket to be parsed as response for the next request (http) or as file content (https), which isn't what we want at all… Symptom is a "Bad header line" as html usually doesn't parse that well to an http-header. This manifests itself e.g. if we have a complete file (or larger) in partial/ which isn't discarded by If-Range as the server doesn't support it (or it is just newer, think: mirror rotation). It is a sort-of regression of 78c72d0ce22e00b194251445aae306df357d5c1a, which removed the filesize - 1 trick, but this had its own problems… To properly test this our webserver gains the ability to reply with transfer-encoding: chunked as most real webservers will use it to send the dynamically generated error pages. (The tests and their binary helpers had to be slightly modified to apply, but the patch to fix the issue itself is unchanged.) Closes: 768797 --- cmdline/apt-helper.cc | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index dd43ea1bc..63f70983c 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -48,23 +48,34 @@ static bool DoDownloadFile(CommandLine &CmdL) if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); - pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); Fetcher.Setup(&Stat); - std::string download_uri = CmdL.FileList[1]; - std::string targetfile = CmdL.FileList[2]; - std::string hash; - if (CmdL.FileSize() > 3) - hash = CmdL.FileList[3]; - // we use download_uri as descr and targetfile as short-descr - new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, - "dest-dir-ignored", targetfile); - Fetcher.Run(); + + size_t fileind = 0; + std::vector targetfiles; + while (fileind + 2 <= CmdL.FileSize()) + { + std::string download_uri = CmdL.FileList[fileind + 1]; + std::string targetfile = CmdL.FileList[fileind + 2]; + std::string hash; + if (CmdL.FileSize() > fileind + 3) + hash = CmdL.FileList[fileind + 3]; + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, + "dest-dir-ignored", targetfile); + targetfiles.push_back(targetfile); + fileind += 3; + } + bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || - FileExists(targetfile) == false) + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return _error->Error(_("Download Failed")); + if (targetfiles.empty() == false) + for (std::vector::const_iterator f = targetfiles.begin(); f != targetfiles.end(); ++f) + if (FileExists(*f) == false) + return _error->Error(_("Download Failed")); + return true; } -- cgit v1.2.3 From 3bf4c93ac241e270c374d1a49be11fb4d673abc1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 9 Mar 2015 16:00:23 +0100 Subject: (error) Same iterator is used with different containers cppcheck reports this error, its not really a problem for us as the API can actually deal with it via implicit conversion, but being explicit can't hurt and the less reported errors the better. Git-Dch: Ignore --- cmdline/apt-mark.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index 8974397c9..47777009b 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -279,7 +279,7 @@ static bool DoHold(CommandLine &CmdL) { if (Pkg->CurrentVer != 0) continue; - keepoffset.insert(Pkg); + keepoffset.insert(*Pkg); } if (keepoffset.empty() == false) -- cgit v1.2.3 From 249aec3b7397662a678ea0014f94392085477b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= Date: Tue, 10 Mar 2015 10:09:44 +0100 Subject: stop displaying time of build in online help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As part of the “reproducible builds” effort [1], we have noticed that apt could not be built reproducibly. One issue is that it uses the __DATE__ and __TIME__ macros of the C preprocessor to display the time of build in the online help. We believe this information not to be really useful to users as they can always look at the package data and metadata to figure it out. The attached patch simply removes this information. All non-documentation packages can then be built reproducibly with our current experimental framework. [David: changed the string slightly to be untranslateable as well] Closes: 774342 --- cmdline/apt-cache.cc | 5 ++--- cmdline/apt-cdrom.cc | 4 ++-- cmdline/apt-config.cc | 5 ++--- cmdline/apt-dump-solver.cc | 3 +-- cmdline/apt-extracttemplates.cc | 3 +-- cmdline/apt-get.cc | 9 ++++----- cmdline/apt-helper.cc | 3 +-- cmdline/apt-internal-solver.cc | 3 +-- cmdline/apt-mark.cc | 3 +-- cmdline/apt-sortpkgs.cc | 3 +-- cmdline/apt.cc | 3 +-- 11 files changed, 17 insertions(+), 27 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index a5024c581..e2cf7e8b7 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1824,9 +1824,8 @@ static bool GenCaches(CommandLine &) /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); - + ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); + if (_config->FindB("version") == true) return true; diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 327039e00..d95c169cd 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -205,8 +205,8 @@ static bool DoIdent(CommandLine &) // ShowHelp - Show the help screen /*{{{*/ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); + if (_config->FindB("version") == true) return true; diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc index e0b8a624e..4479b84a7 100644 --- a/cmdline/apt-config.cc +++ b/cmdline/apt-config.cc @@ -80,11 +80,10 @@ static bool DoDump(CommandLine &CmdL) /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); if (_config->FindB("version") == true) return true; - + cout << _("Usage: apt-config [options] command\n" "\n" diff --git a/cmdline/apt-dump-solver.cc b/cmdline/apt-dump-solver.cc index f765234c5..4729eac55 100644 --- a/cmdline/apt-dump-solver.cc +++ b/cmdline/apt-dump-solver.cc @@ -21,9 +21,8 @@ // --------------------------------------------------------------------- /* */ static bool ShowHelp() { - + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); std::cout << - PACKAGE " " PACKAGE_VERSION " for " COMMON_ARCH " compiled on " __DATE__ " " __TIME__ << std::endl << "Usage: apt-dump-resolver\n" "\n" "apt-dump-resolver is a dummy solver who just dumps its input to the\n" diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 5211ee027..3e4f89286 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -219,8 +219,7 @@ bool DebFile::ParseInfo() /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); if (_config->FindB("version") == true) return true; diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 33bbdd861..a0d78257c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1607,13 +1607,12 @@ static bool DoChangelog(CommandLine &CmdL) /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); - + ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); + if (_config->FindB("version") == true) { cout << _("Supported modules:") << endl; - + for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++) { pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I]; @@ -1622,7 +1621,7 @@ static bool ShowHelp(CommandLine &) else cout << ' '; cout << "Ver: " << VS->Label << endl; - + /* Print out all the packaging systems that will work with this VS */ for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++) diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index a05ae90a2..65db857ad 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -83,8 +83,7 @@ static bool DoDownloadFile(CommandLine &CmdL) static bool ShowHelp(CommandLine &) { - ioprintf(std::cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); if (_config->FindB("version") == true) return true; diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index 4fabeb02f..939061b93 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -44,8 +44,7 @@ // --------------------------------------------------------------------- /* */ static bool ShowHelp(CommandLine &) { - ioprintf(std::cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); std::cout << _("Usage: apt-internal-solver\n" diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index 47777009b..de1c80309 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -443,8 +443,7 @@ static bool ShowHold(CommandLine &CmdL) /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); cout << _("Usage: apt-mark [options] {auto|manual} pkg1 [pkg2 ...]\n" diff --git a/cmdline/apt-sortpkgs.cc b/cmdline/apt-sortpkgs.cc index 9b66ad4db..971900e4f 100644 --- a/cmdline/apt-sortpkgs.cc +++ b/cmdline/apt-sortpkgs.cc @@ -146,8 +146,7 @@ static bool DoIt(string InFile) /* */ static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); if (_config->FindB("version") == true) return true; diff --git a/cmdline/apt.cc b/cmdline/apt.cc index 056cd213f..2f7eddb61 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -39,8 +39,7 @@ static bool ShowHelp(CommandLine &) { - ioprintf(c1out,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, - COMMON_ARCH,__DATE__,__TIME__); + ioprintf(c1out, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); // FIXME: generate from CommandLine c1out << -- cgit v1.2.3 From d5cf8851753dde4f45bfd3b48fcdf34247a8752a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 7 Apr 2015 22:34:34 +0200 Subject: keyids in "apt-key del" should be case-insensitive gnupg is case-insensitive about keyids, so back then apt-key called it directly any keyid was accepted, but now that we work more with the keyid ourself we regressed to require uppercase keyids by accident. This is also inconsistent with other apt-key commands which still use gnupg directly. A single case-insensitive grep and we are fine again. Closes: 781696 --- cmdline/apt-key.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index b4e071000..1da311d35 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -180,7 +180,7 @@ update() { remove_key_from_keyring() { local GPG="$GPG_CMD --keyring $1" # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*$2:"; then + if ! $GPG --with-colons --list-keys 2>&1 | grep -iq "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*$2:"; then return fi if [ ! -w "$1" ]; then -- cgit v1.2.3 From dfad5beea77d75983f6ff8a1b8296b74dd48203e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 15 Mar 2015 22:34:54 +0100 Subject: add a simple unit test for acquire progress This isn't testing much of the 'complex' parts, but its better than nothing for now. Git-Dch: Ignore --- cmdline/apt-get.cc | 6 +++--- cmdline/apt-helper.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a0d78257c..1a4f4c5a8 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -624,7 +624,7 @@ static bool DoDownload(CommandLine &CmdL) if (verset.empty() == true) return false; - AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0)); + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); pkgRecords Recs(Cache); @@ -729,7 +729,7 @@ static bool DoSource(CommandLine &CmdL) return false; // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); SPtrArray Dsc = new DscFile[CmdL.FileSize()]; @@ -1550,7 +1550,7 @@ static bool DoChangelog(CommandLine &CmdL) return Success; } - AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); Fetcher.SetLog(&Stat); bool const downOnly = _config->FindB("APT::Get::Download-Only", false); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index 65db857ad..a97fc903f 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -48,7 +48,7 @@ static bool DoDownloadFile(CommandLine &CmdL) if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); - AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); size_t fileind = 0; -- cgit v1.2.3 From 353c135e45d3b76dbecc1ba1b2bd9266601181ee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 9 May 2015 15:10:55 +0200 Subject: drop incorrect parameter implicitely converted to bool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The helper expects to be told if it should generate messages, not where these messages should be printed – as it isn't printing such messages, but puts them in _error. apt-get uses in other methods a helper specialisation which does also print stuff to a stream through, so this is likely a copy&paste error. Git-Dch: Ignore --- cmdline/apt-get.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 1a4f4c5a8..c1f78523c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -617,7 +617,7 @@ static bool DoDownload(CommandLine &CmdL) if (Cache.ReadOnlyOpen() == false) return false; - APT::CacheSetHelper helper(c0out); + APT::CacheSetHelper helper; APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); @@ -1534,7 +1534,7 @@ static bool DoChangelog(CommandLine &CmdL) if (Cache.ReadOnlyOpen() == false) return false; - APT::CacheSetHelper helper(c0out); + APT::CacheSetHelper helper; APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) -- cgit v1.2.3 From 88593886a42025d51d76051da5929b044e42efee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 11 May 2015 15:08:08 +0200 Subject: rewrite all TFRewrite instances to use the new pkgTagSection::Write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it is mostly busywork to rewrite all instances it actually fixes bugs as the data storage used by the new method is std::string rather than a char*, the later mostly created by c_str() from a std::string which the caller has to ensure keeps in scope – something apt-ftparchive actually didn't ensure and relied on copy-on-write behavior instead which c++11 forbids and hence the new default gcc abi doesn't use it. --- cmdline/apt-cache.cc | 21 ++++++++++++--------- cmdline/apt-sortpkgs.cc | 14 +++++++------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index e2cf7e8b7..690b03bcc 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -580,6 +580,12 @@ static bool DumpAvail(CommandLine &) LocalitySort(VFList,Count,sizeof(*VFList)); + std::vector RW; + RW.push_back(pkgTagSection::Tag::Remove("Status")); + RW.push_back(pkgTagSection::Tag::Remove("Config-Version")); + FileFd stdoutfd; + stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false); + // Iterate over all the package files and write them out. char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10]; for (pkgCache::VerFile **J = VFList; *J != 0;) @@ -620,35 +626,32 @@ static bool DumpAvail(CommandLine &) if (PkgF.Read(Buffer,VF.Size + Jitter) == false) break; Buffer[VF.Size + Jitter] = '\n'; - + // See above.. if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource) { pkgTagSection Tags; - TFRewriteData RW[] = {{"Status", NULL, NULL},{"Config-Version", NULL, NULL},{NULL, NULL, NULL}}; - const char *Zero = 0; if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false || - TFRewrite(stdout,Tags,&Zero,RW) == false) + Tags.Write(stdoutfd, NULL, RW) == false || + stdoutfd.Write("\n", 1) == false) { _error->Error("Internal Error, Unable to parse a package record"); break; } - fputc('\n',stdout); } else { - if (fwrite(Buffer+Jitter,VF.Size+1,1,stdout) != 1) + if (stdoutfd.Write(Buffer + Jitter, VF.Size + 1) == false) break; } - + Pos = VF.Offset + VF.Size; } - fflush(stdout); if (_error->PendingError() == true) break; } - + delete [] Buffer; delete [] VFList; return !_error->PendingError(); diff --git a/cmdline/apt-sortpkgs.cc b/cmdline/apt-sortpkgs.cc index 971900e4f..12ef8dda0 100644 --- a/cmdline/apt-sortpkgs.cc +++ b/cmdline/apt-sortpkgs.cc @@ -108,8 +108,10 @@ static bool DoIt(string InFile) const char **Order = TFRewritePackageOrder; if (Source == true) Order = TFRewriteSourceOrder; - + // Emit + FileFd stdoutfd; + stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false); unsigned char *Buffer = new unsigned char[Largest+1]; for (vector::iterator I = List.begin(); I != List.end(); ++I) { @@ -119,8 +121,8 @@ static bool DoIt(string InFile) delete [] Buffer; return false; } - - Buffer[I->Length] = '\n'; + + Buffer[I->Length] = '\n'; if (Section.Scan((char *)Buffer,I->Length+1) == false) { delete [] Buffer; @@ -128,15 +130,13 @@ static bool DoIt(string InFile) } // Sort the section - if (TFRewrite(stdout,Section,Order,0) == false) + if (Section.Write(stdoutfd, Order) == false || stdoutfd.Write("\n", 1) == false) { delete [] Buffer; return _error->Error("Internal error, failed to sort fields"); } - - fputc('\n',stdout); } - + delete [] Buffer; return true; } -- cgit v1.2.3