X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/f744c64c591cec9e5aa489a9af55e1ed6d1871d1..1e33fb4ac68db5c2630de72d222d9dc10eb93272:/apt-private/private-sources.cc?ds=sidebyside diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc index 41cf6b313..587571760 100644 --- a/apt-private/private-sources.cc +++ b/apt-private/private-sources.cc @@ -1,24 +1,41 @@ +#include #include -#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include -#include "private-output.h" -#include "private-sources.h" -#include "private-utils.h" +#include +#include +#include +#include +#include +#include + +#include /* Interface discussion with donkult (for the future): - apt [add-{archive,release,component}|edit|change-release|disable]-sources + apt [add-{archive,release,component}|edit|change-release|disable]-sources and be clever and work out stuff from the Release file */ -// EditSource - EditSourcesList /*{{{*/ -// --------------------------------------------------------------------- +// EditSource - EditSourcesList /*{{{*/ +class APT_HIDDEN ScopedGetLock { +public: + int fd; + ScopedGetLock(std::string const &filename) : fd(GetLock(filename)) {} + ~ScopedGetLock() { close(fd); } +}; bool EditSources(CommandLine &CmdL) { - bool res; - pkgSourceList sl; - std::string outs; - std::string sourceslist; if (CmdL.FileList[1] != NULL) { @@ -31,34 +48,58 @@ bool EditSources(CommandLine &CmdL) HashString before; if (FileExists(sourceslist)) before.FromFile(sourceslist); + else + { + FileFd filefd; + if (filefd.Open(sourceslist, FileFd::Create | FileFd::WriteOnly, FileFd::None, 0644) == false) + return false; + } - int lockfd = GetLock(sourceslist); - if (lockfd < 0) + ScopedGetLock lock(sourceslist); + if (lock.fd < 0) return false; - + + bool res; + bool file_changed = false; 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; + if (EditFileInSensibleEditor(sourceslist) == false) + return false; + if (before.empty()) + { + struct stat St; + if (stat(sourceslist.c_str(), &St) == 0 && St.st_size == 0) + RemoveFile("edit-sources", sourceslist); + } + else if (FileExists(sourceslist) && !before.VerifyFile(sourceslist)) + { + file_changed = true; + pkgCacheFile::RemoveCaches(); + } + pkgCacheFile CacheFile; + res = CacheFile.BuildCaches(nullptr); + if (res == false || _error->empty(GlobalError::WARNING) == false) { + std::string outs; + strprintf(outs, _("Failed to parse %s. Edit again? "), sourceslist.c_str()); // FIXME: should we add a "restore previous" option here? - res = !YnPrompt(true); + if (YnPrompt(outs.c_str(), true) == false) + { + if (res == false && _error->PendingError() == false) + { + CacheFile.Close(); + pkgCacheFile::RemoveCaches(); + res = CacheFile.BuildCaches(nullptr); + } + break; + } } - _error->RevertToStack(); } while (res == false); - close(lockfd); - if (FileExists(sourceslist) && !before.VerifyFile(sourceslist)) { - strprintf( - outs, _("Your '%s' file changed, please run 'apt-get update'."), + if (res == true && file_changed == true) + { + ioprintf( + std::cout, _("Your '%s' file changed, please run 'apt-get update'."), sourceslist.c_str()); - std::cout << outs << std::endl; } - - return true; + return res; } /*}}}*/