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 From 8881b11eacd735148d087c8c0f53827cb537b582 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 11 Jun 2015 16:40:45 +0200 Subject: implement 'apt-get files' to access index targets Downloading additional files is only half the job. We still need a way to allow external tools to know where the files are they requested for download given that we don't want them to choose their own location. 'apt-get files' is our answer to this showing by default in a deb822 format information about each IndexTarget with the potential to filter the records based on lines and an option to change the output format. The command serves also as an example on how to get to this information via libapt. --- cmdline/apt-get.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index c1f78523c..0fff2db58 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -1602,6 +1603,91 @@ static bool DoChangelog(CommandLine &CmdL) return true; } /*}}}*/ +// DoFiles - Lists all IndexTargets /*{{{*/ +static std::string format_key(std::string key) +{ + // deb822 is case-insensitive, but the human eye prefers candy + std::transform(key.begin(), key.end(), key.begin(), ::tolower); + key[0] = ::toupper(key[0]); + size_t found = key.find("_uri"); + if (found != std::string::npos) + key.replace(found, 4, "-URI"); + while ((found = key.find('_')) != std::string::npos) + { + key[found] = '-'; + key[found + 1] = ::toupper(key[found + 1]); + } + return key; +} +static bool DoFiles(CommandLine &CmdL) +{ + pkgCacheFile CacheFile; + pkgSourceList *SrcList = CacheFile.GetSourceList(); + + if (SrcList == NULL) + return false; + + std::string const Format = _config->Find("APT::Get::Files::Format"); + bool Filtered = CmdL.FileSize() > 1; + for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S) + { + std::vector const targets = (*S)->GetIndexTargets(); + std::map AddOptions; + AddOptions.insert(std::make_pair("TRUSTED", ((*S)->IsTrusted() ? "yes" : "no"))); + + for (std::vector::const_iterator T = targets.begin(); T != targets.end(); ++T) + { + std::ostringstream stanza; + if (Filtered || Format.empty()) + { + stanza << "MetaKey: " << T->MetaKey << "\n" + << "ShortDesc: " << T->ShortDesc << "\n" + << "Description: " << T->Description << "\n" + << "URI: " << T->URI << "\n" + << "Filename: " << T->Option(IndexTarget::FILENAME) << "\n" + << "Optional: " << (T->IsOptional ? "yes" : "no") << "\n"; + for (std::map::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O) + stanza << format_key(O->first) << ": " << O->second << "\n"; + for (std::map::const_iterator O = T->Options.begin(); O != T->Options.end(); ++O) + stanza << format_key(O->first) << ": " << O->second << "\n"; + stanza << "\n"; + + if (Filtered) + { + // that is a bit crude, but good enough for now + bool found = true; + std::string haystack = std::string("\n") + stanza.str() + "\n"; + std::transform(haystack.begin(), haystack.end(), haystack.begin(), ::tolower); + size_t const filesize = CmdL.FileSize() - 1; + for (size_t i = 0; i != filesize; ++i) + { + std::string needle = std::string("\n") + CmdL.FileList[i + 1] + "\n"; + std::transform(needle.begin(), needle.end(), needle.begin(), ::tolower); + if (haystack.find(needle) != std::string::npos) + continue; + found = false; + break; + } + if (found == false) + continue; + } + } + + if (Format.empty()) + cout << stanza.str(); + else + { + std::string out = T->Format(Format); + for (std::map::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O) + out = SubstVar(out, std::string("$(") + O->first + ")", O->second); + cout << out << std::endl; + } + } + } + + return true; +} + /*}}}*/ // ShowHelp - Show a help screen /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1716,6 +1802,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {"source",&DoSource}, {"download",&DoDownload}, {"changelog",&DoChangelog}, + {"files",&DoFiles}, {"moo",&DoMoo}, {"help",&ShowHelp}, {0,0}}; -- cgit v1.2.3 From b07aeb1a6e24825e534167a737043441e871de9f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Jun 2015 02:08:53 +0200 Subject: store Release files data in the Cache We used to read the Release file for each Packages file and store the data in the PackageFile struct even through potentially many Packages (and Translation-*) files could use the same data. The point of the exercise isn't the duplicated data through. Having the Release files as first-class citizens in the Cache allows us to properly track their state as well as allows us to use the information also for files which aren't in the cache, but where we know to which Release file they belong (Sources are an example for this). This modifies the pkgCache structs, especially the PackagesFile struct which depending on how libapt users access the data in these structs can mean huge breakage or no visible change. As a single data point: aptitude seems to be fine with this. Even if there is breakage it is trivial to fix in a backportable way while avoiding breakage for everyone would be a huge pain for us. Note that not all PackageFile structs have a corresponding ReleaseFile. In particular the dpkg/status file as well as *.deb files have not. As these have only a Archive property need, the Component property takes over this duty and the ReleaseFile remains zero. This is also the reason why it isn't needed nor particularily recommended to change from PackagesFile to ReleaseFile blindly. Sticking with the earlier is usually the better option. --- cmdline/apt-cache.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 690b03bcc..3b8ebc96d 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -413,17 +413,21 @@ static bool Stats(CommandLine &) stritems.insert(Prv->ProvideVersion); } } - for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) + for (pkgCache::RlsFileIterator F = Cache->RlsFileBegin(); F != Cache->RlsFileEnd(); ++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); + } + for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) + { + stritems.insert(F->FileName); + stritems.insert(F->Architecture); + stritems.insert(F->Component); stritems.insert(F->IndexType); } unsigned long Size = 0; @@ -446,6 +450,7 @@ static bool Stats(CommandLine &) APT_CACHESIZE(VersionCount, VersionSz) + APT_CACHESIZE(DescriptionCount, DescriptionSz) + APT_CACHESIZE(DependsCount, DependencySz) + + APT_CACHESIZE(ReleaseFileCount, ReleaseFileSz) + APT_CACHESIZE(PackageFileCount, PackageFileSz) + APT_CACHESIZE(VerFileCount, VerFileSz) + APT_CACHESIZE(DescFileCount, DescFileSz) + -- cgit v1.2.3 From 3fd89e62e985c89b1f9a545ab72c20987b756aff Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Jun 2015 12:06:29 +0200 Subject: implement default apt-get file --release-info mode Selecting targets based on the Release they belong to isn't to unrealistic. In fact, it is assumed to be the most used case so it is made the default especially as this allows to bundle another thing we have to be careful with: Filenames and only showing targets we have acquired. Closes: 752702 --- cmdline/apt-get.cc | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0fff2db58..a4cd3c377 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1628,15 +1628,34 @@ static bool DoFiles(CommandLine &CmdL) return false; std::string const Format = _config->Find("APT::Get::Files::Format"); + bool const ReleaseInfo = _config->FindB("APT::Get::Files::ReleaseInfo", true); bool Filtered = CmdL.FileSize() > 1; for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S) { std::vector const targets = (*S)->GetIndexTargets(); std::map AddOptions; - AddOptions.insert(std::make_pair("TRUSTED", ((*S)->IsTrusted() ? "yes" : "no"))); + if (ReleaseInfo) + { + AddOptions.insert(std::make_pair("TRUSTED", ((*S)->IsTrusted() ? "yes" : "no"))); + pkgCache &Cache = *CacheFile.GetPkgCache(); + pkgCache::RlsFileIterator const RlsFile = (*S)->FindInCache(Cache, false); + if (RlsFile.end()) + continue; +#define APT_RELEASE(X,Y) if (RlsFile.Y() != NULL) AddOptions.insert(std::make_pair(X, RlsFile.Y())) + APT_RELEASE("CODENAME", Codename); + APT_RELEASE("SUITE", Archive); + APT_RELEASE("VERSION", Version); + APT_RELEASE("ORIGIN", Origin); + APT_RELEASE("LABEL", Label); +#undef APT_RELEASE + } for (std::vector::const_iterator T = targets.begin(); T != targets.end(); ++T) { + std::string filename = T->Option(ReleaseInfo ? IndexTarget::EXISTING_FILENAME : IndexTarget::FILENAME); + if (filename.empty()) + continue; + std::ostringstream stanza; if (Filtered || Format.empty()) { @@ -1644,7 +1663,7 @@ static bool DoFiles(CommandLine &CmdL) << "ShortDesc: " << T->ShortDesc << "\n" << "Description: " << T->Description << "\n" << "URI: " << T->URI << "\n" - << "Filename: " << T->Option(IndexTarget::FILENAME) << "\n" + << "Filename: " << filename << "\n" << "Optional: " << (T->IsOptional ? "yes" : "no") << "\n"; for (std::map::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O) stanza << format_key(O->first) << ": " << O->second << "\n"; @@ -1677,7 +1696,8 @@ static bool DoFiles(CommandLine &CmdL) cout << stanza.str(); else { - std::string out = T->Format(Format); + std::string out = SubstVar(Format, "$(FILENAME)", filename); + out = T->Format(out); for (std::map::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O) out = SubstVar(out, std::string("$(") + O->first + ")", O->second); cout << out << std::endl; -- cgit v1.2.3 From d2cb5b153fb13d587b1ff632cab34ce0c403326e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Jun 2015 15:48:00 +0200 Subject: hide Translation-* in 'apt-cache policy' output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation-* files are internally handled as PackageFiles which isn't super nice, but giving them their own struct is a bit overkill so let it be for the moment. They always appeared in the policy output because of this through and now that they are properly linked to a ReleaseFile they even display all the pinning information on them, but they don't contain any packages which could be pinned… No problem, but useless and potentially confusing output. Adding a 'NoPackages' flag which can be set on those files and be used in applications seems like a simple way to fix this display issue. --- cmdline/apt-cache.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 3b8ebc96d..c2f6dbd5c 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1638,6 +1638,8 @@ static bool Policy(CommandLine &CmdL) cout << _("Package files:") << endl; for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F) { + if (F.Flagged(pkgCache::Flag::NoPackages)) + continue; // Locate the associated index files so we can derive a description pkgIndexFile *Indx; if (SrcList->FindIndex(F,Indx) == false && -- cgit v1.2.3 From d56e2917f27a722b54685de13aeb1bb7592fc61b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Jun 2015 11:13:45 +0200 Subject: provide a public interface for acquiring changelogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provided is a specialized acquire item which given a version can figure out the correct URI to try by itself and if not provides an error message alongside with static methods to get just the URI it would try to download if it should just be displayed or similar such. The URI is constructed as follows: Release files can provide an URI template in the "Changelogs" field, otherwise we lookup a configuration item based on the "Label" or "Origin" of the Release file to get a (hopefully known) default value for now. This template should contain the string CHANGEPATH which is replaced with the information about the version we want the changelog for (e.g. main/a/apt/apt_1.1). This middleway was choosen as this path part was consistent over the three known implementations (+1 defunct), while the rest of the URI varies widely between them. The benefit of this construct is that it is now easy to get changelogs for Debian packages on Ubuntu and vice versa – even at the moment where the Changelogs field is present nowhere. Strictly better than what apt-get had before as it would even fail to get changelogs from security… Now it will notice that security identifies as Origin: Debian and pick this setting (assuming again that no Changelogs field exists). If on the other hand security would ship its changelogs in a different location we could set it via the Label option overruling Origin. Closes: 687147, 739854, 784027, 787190 --- cmdline/apt-get.cc | 204 ++++++++++------------------------------------------- 1 file changed, 39 insertions(+), 165 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a4cd3c377..184b51d23 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1410,196 +1410,70 @@ static bool DoBuildDep(CommandLine &CmdL) return true; } /*}}}*/ -// GetChangelogPath - return a path pointing to a changelog file or dir /*{{{*/ -// --------------------------------------------------------------------- -/* This returns a "path" string for the changelog url construction. - * Please note that its not complete, it either needs a "/changelog" - * appended (for the packages.debian.org/changelogs site) or a - * ".changelog" (for third party sites that store the changelog in the - * pool/ next to the deb itself) - * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" - */ -static string GetChangelogPath(CacheFile &Cache, - pkgCache::VerIterator Ver) -{ - 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; -} - /*}}}*/ -// GuessThirdPartyChangelogUri - return url /*{{{*/ -// --------------------------------------------------------------------- -/* Contruct a changelog file path for third party sites that do not use - * packages.debian.org/changelogs - * This simply uses the ArchiveURI() of the source pkg and looks for - * a .changelog file there, Example for "mediabuntu": - * apt-get changelog mplayer-doc: - * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog - */ -static bool GuessThirdPartyChangelogUri(CacheFile &Cache, - pkgCache::VerIterator Ver, - string &out_uri) -{ - // get the binary deb server path - pkgCache::VerFileIterator Vf = Ver.FileList(); - if (Vf.end() == true) - return false; - pkgCache::PkgFileIterator F = Vf.File(); - pkgIndexFile *index; - pkgSourceList *SrcList = Cache.GetSourceList(); - if(SrcList->FindIndex(F, index) == false) - return false; - - // get archive uri for the binary deb - 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 - return true; -} - /*}}}*/ -// DownloadChangelog - Download the changelog /*{{{*/ -// --------------------------------------------------------------------- -static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, - pkgCache::VerIterator Ver, string targetfile) -/* Download a changelog file for the given package version to - * targetfile. This will first try the server from Apt::Changelogs::Server - * (http://packages.debian.org/changelogs by default) and if that gives - * a 404 tries to get it from the archive directly (see - * GuessThirdPartyChangelogUri for details how) - */ -{ - // make the server root configurable - string const server = _config->Find("Apt::Changelogs::Server", - "http://packages.debian.org/changelogs"); - string const path = GetChangelogPath(CacheFile, Ver); - string changelog_uri; - 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; - return true; - } - pkgCache::PkgIterator const Pkg = Ver.ParentPkg(); - - string descr; - strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); - // queue it - 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); - - // 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 (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()); - itm = new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); - Fetcher.Run(); - } - } - - if (itm->Status == pkgAcquire::Item::StatDone) - return true; - - // error - return _error->Error("changelog download failed"); -} - /*}}}*/ // DoChangelog - Get changelog from the command line /*{{{*/ -// --------------------------------------------------------------------- static bool DoChangelog(CommandLine &CmdL) { CacheFile Cache; if (Cache.ReadOnlyOpen() == false) return false; - + APT::CacheSetHelper helper; APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; pkgAcquire Fetcher; + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); + Fetcher.SetLog(&Stat); - if (_config->FindB("APT::Get::Print-URIs", false) == true) + bool const downOnly = _config->FindB("APT::Get::Download-Only", false); + bool const printOnly = _config->FindB("APT::Get::Print-URIs", false); + + for (APT::VersionList::const_iterator Ver = verset.begin(); + Ver != verset.end(); + ++Ver) { - bool Success = true; - for (APT::VersionList::const_iterator Ver = verset.begin(); - Ver != verset.end(); ++Ver) - Success &= DownloadChangelog(Cache, Fetcher, Ver, ""); - return Success; + if (printOnly) + new pkgAcqChangelog(&Fetcher, Ver, "/dev/null"); + else if (downOnly) + new pkgAcqChangelog(&Fetcher, Ver, "."); + else + new pkgAcqChangelog(&Fetcher, Ver); } - AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); - Fetcher.SetLog(&Stat); + if (printOnly == false) + { + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + if (_error->PendingError() == true) + return false; - bool const downOnly = _config->FindB("APT::Get::Download-Only", false); + bool Failed = false; + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) + return false; + } - char tmpname[100]; - const char* tmpdir = NULL; - if (downOnly == false) + if (downOnly == false || printOnly == true) { - std::string systemTemp = GetTempDir(); - snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", - systemTemp.c_str()); - 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 + bool Failed = false; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I) { - struct passwd const * const pw = getpwnam(SandboxUser.c_str()); - struct group const * const gr = getgrnam("root"); - if (pw != NULL && gr != NULL) + if (printOnly) { - // 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); + if ((*I)->ErrorText.empty() == false) + { + Failed = true; + _error->Error("%s", (*I)->ErrorText.c_str()); + } + else + cout << '\'' << (*I)->DescURI() << "' " << flNotDir((*I)->DestFile) << std::endl; } + else + DisplayFileInPager((*I)->DestFile); } + return Failed == false; } - for (APT::VersionList::const_iterator Ver = verset.begin(); - Ver != verset.end(); - ++Ver) - { - string changelogfile; - if (downOnly == false) - changelogfile.append(tmpname).append("/changelog"); - else - changelogfile.append(Ver.ParentPkg().Name()).append(".changelog"); - if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false) - { - DisplayFileInPager(changelogfile); - // cleanup temp file - unlink(changelogfile.c_str()); - } - } - // clenaup tmp dir - if (tmpdir != NULL) - rmdir(tmpdir); return true; } /*}}}*/ -- cgit v1.2.3