From cfacba5230f2e6bb88a1949505843ac22ed342d5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 25 Nov 2013 08:36:57 +0100 Subject: add basic "edit-sources" command --- apt-private/makefile | 2 +- apt-private/private-utils.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++ apt-private/private-utils.h | 11 ++++++++++ cmdline/apt-get.cc | 19 +---------------- cmdline/apt.cc | 24 +++++++++++++++++++++ 5 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 apt-private/private-utils.cc create mode 100644 apt-private/private-utils.h diff --git a/apt-private/makefile b/apt-private/makefile index 1d179f0b2..b3d764097 100644 --- a/apt-private/makefile +++ b/apt-private/makefile @@ -17,7 +17,7 @@ MAJOR=0.0 MINOR=0 SLIBS=$(PTHREADLIB) -lapt-pkg -PRIVATES=list install download output cachefile cacheset update upgrade cmndline moo search show main +PRIVATES=list install download output cachefile cacheset update upgrade cmndline moo search show main utils SOURCE += $(foreach private, $(PRIVATES), private-$(private).cc) HEADERS += $(foreach private, $(PRIVATES), private-$(private).h) diff --git a/apt-private/private-utils.cc b/apt-private/private-utils.cc new file mode 100644 index 000000000..813f19329 --- /dev/null +++ b/apt-private/private-utils.cc @@ -0,0 +1,50 @@ +#include + +#include +#include +#include "private-utils.h" + + +// DisplayFileInPager - Display File with pager /*{{{*/ +void DisplayFileInPager(std::string filename) +{ + std::string pager = _config->Find("Dir::Bin::Pager", + "/usr/bin/sensible-pager"); + + pid_t Process = ExecFork(); + if (Process == 0) + { + const char *Args[3]; + Args[0] = pager.c_str(); + Args[1] = filename.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for the subprocess + ExecWait(Process, "sensible-pager", false); +} + /*}}}*/ + +// EditFileInSensibleEditor - Edit File with editor /*{{{*/ +void EditFileInSensibleEditor(std::string filename) +{ + std::string editor = _config->Find("Dir::Bin::Editor", + "/usr/bin/sensible-editor"); + + pid_t Process = ExecFork(); + if (Process == 0) + { + const char *Args[3]; + Args[0] = editor.c_str(); + Args[1] = filename.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for the subprocess + ExecWait(Process, "sensible-editor", false); +} + /*}}}*/ diff --git a/apt-private/private-utils.h b/apt-private/private-utils.h new file mode 100644 index 000000000..258dd06a8 --- /dev/null +++ b/apt-private/private-utils.h @@ -0,0 +1,11 @@ +#ifndef APT_PRIVATE_UTILS_H +#define APT_PRIVATE_UTILS_H + +#include + +void DisplayFileInPager(std::string filename); +void EditFileInSensibleEditor(std::string filename); + + + +#endif diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 15373b050..912b2d609 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -59,6 +59,7 @@ #include #include #include +#include #include @@ -1378,24 +1379,6 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, return _error->Error("changelog download failed"); } /*}}}*/ -// DisplayFileInPager - Display File with pager /*{{{*/ -void DisplayFileInPager(string filename) -{ - pid_t Process = ExecFork(); - if (Process == 0) - { - const char *Args[3]; - Args[0] = "/usr/bin/sensible-pager"; - Args[1] = filename.c_str(); - Args[2] = 0; - execvp(Args[0],(char **)Args); - exit(100); - } - - // Wait for the subprocess - ExecWait(Process, "sensible-pager", false); -} - /*}}}*/ // DoChangelog - Get changelog from the command line /*{{{*/ // --------------------------------------------------------------------- bool DoChangelog(CommandLine &CmdL) diff --git a/cmdline/apt.cc b/cmdline/apt.cc index e30967ec2..ef31d0029 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -54,8 +54,28 @@ #include #include #include +#include /*}}}*/ +// EditSource - EditSourcesList /*{{{*/ +// --------------------------------------------------------------------- +bool EditSources(CommandLine &CmdL) +{ + // FIXME: suport CmdL.FileList to specify sources.list.d files + + std::string sourceslist = _config->FindFile("Dir::Etc::sourcelist"); + + // FIXME: take hash before, + // when changed display message to apt update + // do syntax check after save (like visudo) + + EditFileInSensibleEditor(sourceslist); + + return true; +} + /*}}}*/ + + bool ShowHelp(CommandLine &CmdL) { ioprintf(c1out,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, @@ -74,6 +94,8 @@ bool ShowHelp(CommandLine &CmdL) " update - update list of available packages\n" " install - install packages\n" " upgrade - upgrade the systems packages\n" + "\n" + " edit-sources - edit the source information file\n" ); return true; @@ -89,6 +111,8 @@ int main(int argc, const char *argv[]) /*{{{*/ {"remove", &DoInstall}, {"update",&DoUpdate}, {"upgrade",&DoUpgradeWithAllowNewPackages}, + // misc + {"edit-sources",&EditSources}, // helper {"moo",&DoMoo}, {"help",&ShowHelp}, -- cgit v1.2.3 From d2524a53bbd219ee6d069006fd243a5bcda0245b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 26 Nov 2013 09:22:40 +0100 Subject: add syntax check for sources.list --- cmdline/apt.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/cmdline/apt.cc b/cmdline/apt.cc index ef31d0029..38610e731 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -67,9 +67,22 @@ bool EditSources(CommandLine &CmdL) // FIXME: take hash before, // when changed display message to apt update - // do syntax check after save (like visudo) - - EditFileInSensibleEditor(sourceslist); + bool res; + pkgSourceList sl; + + do { + EditFileInSensibleEditor(sourceslist); + _error->PushToStack(); + res = sl.Read(sourceslist); + if (!res) { + std::string outs; + strprintf(outs, _("Failed to parse %s. Edit again? "), + sourceslist.c_str()); + std::cout << outs; + res = !YnPrompt(true); + } + _error->RevertToStack(); + } while (res == false); return true; } -- cgit v1.2.3 From e6645b9fb9ba3a7ff7b6663af3f5e1bcb6f23d78 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 26 Nov 2013 10:32:21 +0100 Subject: add check when sources.list changed --- apt-pkg/contrib/hashes.cc | 25 +++++++++++++++++++++---- apt-pkg/contrib/hashes.h | 9 ++++++++- cmdline/apt.cc | 20 ++++++++++++++------ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index e1a431823..b4c768db9 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -54,6 +54,26 @@ HashString::HashString(std::string StringedHash) /*{{{*/ } /*}}}*/ bool HashString::VerifyFile(std::string filename) const /*{{{*/ +{ + std::string fileHash = GetHashForFile(filename); + + if(_config->FindB("Debug::Hashes",false) == true) + std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl; + + return (fileHash == Hash); +} + /*}}}*/ +bool HashString::FromFile(std::string filename) /*{{{*/ +{ + // pick the strongest hash + if (Type == "") + Type = _SupportedHashes[0]; + + Hash = GetHashForFile(filename); + return true; +} + /*}}}*/ +std::string HashString::GetHashForFile(std::string filename) const /*{{{*/ { std::string fileHash; @@ -84,10 +104,7 @@ bool HashString::VerifyFile(std::string filename) const /*{{{*/ } Fd.Close(); - if(_config->FindB("Debug::Hashes",false) == true) - std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl; - - return (fileHash == Hash); + return fileHash; } /*}}}*/ const char** HashString::SupportedHashes() diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 0c0b6c6a7..0a8bcd259 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -36,7 +36,10 @@ class HashString protected: std::string Type; std::string Hash; - static const char * _SupportedHashes[10]; + static const char* _SupportedHashes[10]; + + // internal helper + std::string GetHashForFile(std::string filename) const; public: HashString(std::string Type, std::string Hash); @@ -49,6 +52,10 @@ class HashString // verify the given filename against the currently loaded hash bool VerifyFile(std::string filename) const; + // generate a hash string from the given filename + bool FromFile(std::string filename); + + // helper std::string toStr() const; // convert to str as "type:hash" bool empty() const; diff --git a/cmdline/apt.cc b/cmdline/apt.cc index 38610e731..47187fac2 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -61,21 +62,21 @@ // --------------------------------------------------------------------- bool EditSources(CommandLine &CmdL) { - // FIXME: suport CmdL.FileList to specify sources.list.d files + bool res; + pkgSourceList sl; + std::string outs; + // FIXME: suport CmdL.FileList to specify sources.list.d files std::string sourceslist = _config->FindFile("Dir::Etc::sourcelist"); - // FIXME: take hash before, - // when changed display message to apt update - bool res; - pkgSourceList sl; + HashString before; + before.FromFile(sourceslist); do { EditFileInSensibleEditor(sourceslist); _error->PushToStack(); res = sl.Read(sourceslist); if (!res) { - std::string outs; strprintf(outs, _("Failed to parse %s. Edit again? "), sourceslist.c_str()); std::cout << outs; @@ -84,6 +85,13 @@ bool EditSources(CommandLine &CmdL) _error->RevertToStack(); } while (res == false); + if (!before.VerifyFile(sourceslist)) { + strprintf( + outs, _("Your '%s' file changed, please run 'apt-get update'."), + sourceslist.c_str()); + std::cout << outs << std::endl; + } + return true; } /*}}}*/ -- cgit v1.2.3 From 9e6b13f3751f8a1287ff79861980afb7792a5f9e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 28 Nov 2013 12:15:47 +0100 Subject: move EditSources into its own file --- apt-private/makefile | 2 +- apt-private/private-sources.cc | 45 ++++++++++++++++++++++++++++++++++++++++++ apt-private/private-sources.h | 3 +++ cmdline/apt.cc | 38 +---------------------------------- 4 files changed, 50 insertions(+), 38 deletions(-) create mode 100644 apt-private/private-sources.cc create mode 100644 apt-private/private-sources.h diff --git a/apt-private/makefile b/apt-private/makefile index b3d764097..728890b9b 100644 --- a/apt-private/makefile +++ b/apt-private/makefile @@ -17,7 +17,7 @@ MAJOR=0.0 MINOR=0 SLIBS=$(PTHREADLIB) -lapt-pkg -PRIVATES=list install download output cachefile cacheset update upgrade cmndline moo search show main utils +PRIVATES=list install download output cachefile cacheset update upgrade cmndline moo search show main utils sources SOURCE += $(foreach private, $(PRIVATES), private-$(private).cc) HEADERS += $(foreach private, $(PRIVATES), private-$(private).h) diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc new file mode 100644 index 000000000..eb9c5b971 --- /dev/null +++ b/apt-private/private-sources.cc @@ -0,0 +1,45 @@ + +#include +#include + +#include "private-output.h" +#include "private-sources.h" +#include "private-utils.h" + +// EditSource - EditSourcesList /*{{{*/ +// --------------------------------------------------------------------- +bool EditSources(CommandLine &CmdL) +{ + bool res; + pkgSourceList sl; + std::string outs; + + // FIXME: suport CmdL.FileList to specify sources.list.d files + std::string sourceslist = _config->FindFile("Dir::Etc::sourcelist"); + + HashString before; + before.FromFile(sourceslist); + + do { + EditFileInSensibleEditor(sourceslist); + _error->PushToStack(); + res = sl.Read(sourceslist); + if (!res) { + strprintf(outs, _("Failed to parse %s. Edit again? "), + sourceslist.c_str()); + std::cout << outs; + res = !YnPrompt(true); + } + _error->RevertToStack(); + } while (res == false); + + if (!before.VerifyFile(sourceslist)) { + strprintf( + outs, _("Your '%s' file changed, please run 'apt-get update'."), + sourceslist.c_str()); + std::cout << outs << std::endl; + } + + return true; +} + /*}}}*/ diff --git a/apt-private/private-sources.h b/apt-private/private-sources.h new file mode 100644 index 000000000..b394622be --- /dev/null +++ b/apt-private/private-sources.h @@ -0,0 +1,3 @@ +#include + +bool EditSources(CommandLine &CmdL); diff --git a/cmdline/apt.cc b/cmdline/apt.cc index 47187fac2..4bcae0aba 100644 --- a/cmdline/apt.cc +++ b/cmdline/apt.cc @@ -56,45 +56,9 @@ #include #include #include +#include /*}}}*/ -// EditSource - EditSourcesList /*{{{*/ -// --------------------------------------------------------------------- -bool EditSources(CommandLine &CmdL) -{ - bool res; - pkgSourceList sl; - std::string outs; - - // FIXME: suport CmdL.FileList to specify sources.list.d files - std::string sourceslist = _config->FindFile("Dir::Etc::sourcelist"); - - HashString before; - before.FromFile(sourceslist); - - do { - EditFileInSensibleEditor(sourceslist); - _error->PushToStack(); - res = sl.Read(sourceslist); - if (!res) { - strprintf(outs, _("Failed to parse %s. Edit again? "), - sourceslist.c_str()); - std::cout << outs; - res = !YnPrompt(true); - } - _error->RevertToStack(); - } while (res == false); - - if (!before.VerifyFile(sourceslist)) { - strprintf( - outs, _("Your '%s' file changed, please run 'apt-get update'."), - sourceslist.c_str()); - std::cout << outs << std::endl; - } - - return true; -} - /*}}}*/ bool ShowHelp(CommandLine &CmdL) -- cgit v1.2.3 From a8f671c17a7f34e80a49bf367bceaa009551b066 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 08:17:44 +0100 Subject: add support for "apt edit-source foo" sources.list.d component editing --- apt-private/private-sources.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc index eb9c5b971..37b0534bd 100644 --- a/apt-private/private-sources.cc +++ b/apt-private/private-sources.cc @@ -6,6 +6,11 @@ #include "private-sources.h" #include "private-utils.h" +/* Interface discussion with donkult (for the future): + apt [add-{archive,release,component}|edit|change-release|disable]-sources + and be clever and work out stuff from the Release file +*/ + // EditSource - EditSourcesList /*{{{*/ // --------------------------------------------------------------------- bool EditSources(CommandLine &CmdL) @@ -14,17 +19,22 @@ bool EditSources(CommandLine &CmdL) pkgSourceList sl; std::string outs; - // FIXME: suport CmdL.FileList to specify sources.list.d files - std::string sourceslist = _config->FindFile("Dir::Etc::sourcelist"); + std::string sourceslist; + if (CmdL.FileList[1] != NULL) + sourceslist = _config->FindDir("Dir::Etc::sourceparts") + CmdL.FileList[1] + ".list"; + else + sourceslist = _config->FindFile("Dir::Etc::sourcelist"); HashString before; - before.FromFile(sourceslist); + if (FileExists(sourceslist)) + before.FromFile(sourceslist); do { EditFileInSensibleEditor(sourceslist); _error->PushToStack(); res = sl.Read(sourceslist); if (!res) { + _error->DumpErrors(); strprintf(outs, _("Failed to parse %s. Edit again? "), sourceslist.c_str()); std::cout << outs; @@ -33,7 +43,7 @@ bool EditSources(CommandLine &CmdL) _error->RevertToStack(); } while (res == false); - if (!before.VerifyFile(sourceslist)) { + if (FileExists(sourceslist) && !before.VerifyFile(sourceslist)) { strprintf( outs, _("Your '%s' file changed, please run 'apt-get update'."), sourceslist.c_str()); -- cgit v1.2.3 From cf993341c2067ee091cfd51e5da0e237babce171 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 08:35:05 +0100 Subject: add "APT::String::Endswith" and automatic adding of ".list" in apt edit-source --- apt-pkg/contrib/strutl.cc | 8 ++++++++ apt-pkg/contrib/strutl.h | 1 + apt-private/private-sources.cc | 10 +++++++--- test/libapt/strutil_test.cc | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 9f794927d..962112854 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -49,6 +49,14 @@ std::string Strip(const std::string &s) size_t end = s.find_last_not_of(" \t\n"); return s.substr(start, end-start+1); } + +bool Endswith(const std::string &s, const std::string &end) +{ + if (end.size() > s.size()) + return false; + return (s.substr(s.size() - end.size(), s.size()) == end); +} + } } /*}}}*/ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index c8fc317c0..8d746f10e 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -36,6 +36,7 @@ using std::ostream; namespace APT { namespace String { std::string Strip(const std::string &s); + bool Endswith(const std::string &s, const std::string &ending); }; }; diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc index 37b0534bd..65706e785 100644 --- a/apt-private/private-sources.cc +++ b/apt-private/private-sources.cc @@ -21,10 +21,13 @@ bool EditSources(CommandLine &CmdL) std::string sourceslist; if (CmdL.FileList[1] != NULL) - sourceslist = _config->FindDir("Dir::Etc::sourceparts") + CmdL.FileList[1] + ".list"; - else + { + sourceslist = _config->FindDir("Dir::Etc::sourceparts") + CmdL.FileList[1]; + if (!APT::String::Endswith(sourceslist, ".list")) + sourceslist += ".list"; + } else { sourceslist = _config->FindFile("Dir::Etc::sourcelist"); - + } HashString before; if (FileExists(sourceslist)) before.FromFile(sourceslist); @@ -38,6 +41,7 @@ bool EditSources(CommandLine &CmdL) strprintf(outs, _("Failed to parse %s. Edit again? "), sourceslist.c_str()); std::cout << outs; + // FIXME: should we add a "restore previous" option here? res = !YnPrompt(true); } _error->RevertToStack(); diff --git a/test/libapt/strutil_test.cc b/test/libapt/strutil_test.cc index 110a20d27..8215654d0 100644 --- a/test/libapt/strutil_test.cc +++ b/test/libapt/strutil_test.cc @@ -69,5 +69,23 @@ int main(int argc,char *argv[]) result = StringSplit(input, ""); equals(result.size(), 0); + // endswith + bool b; + input = "abcd"; + b = APT::String::Endswith(input, "d"); + equals(b, true); + + b = APT::String::Endswith(input, "cd"); + equals(b, true); + + b = APT::String::Endswith(input, "abcd"); + equals(b, true); + + b = APT::String::Endswith(input, "x"); + equals(b, false); + + b = APT::String::Endswith(input, "abcndefg"); + equals(b, false); + return 0; } -- cgit v1.2.3