summaryrefslogtreecommitdiffstats
path: root/apt-private/private-sources.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--apt-private/private-sources.cc105
1 files changed, 105 insertions, 0 deletions
diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc
new file mode 100644
index 0000000..a7d003f
--- /dev/null
+++ b/apt-private/private-sources.cc
@@ -0,0 +1,105 @@
+#include <config.h>
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/hashes.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/strutl.h>
+
+#include <apt-private/private-output.h>
+#include <apt-private/private-sources.h>
+#include <apt-private/private-utils.h>
+
+#include <cstddef>
+#include <iostream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <apti18n.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 /*{{{*/
+class APT_HIDDEN ScopedGetLock {
+public:
+ int fd;
+ explicit ScopedGetLock(std::string const &filename) : fd(GetLock(filename)) {}
+ ~ScopedGetLock() { close(fd); }
+};
+bool EditSources(CommandLine &CmdL)
+{
+ std::string sourceslist;
+ if (CmdL.FileList[1] != NULL)
+ {
+ 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);
+ else
+ {
+ FileFd filefd;
+ if (filefd.Open(sourceslist, FileFd::Create | FileFd::WriteOnly, FileFd::None, 0644) == false)
+ return false;
+ }
+
+ ScopedGetLock lock(sourceslist);
+ if (lock.fd < 0)
+ return false;
+
+ bool res;
+ bool file_changed = false;
+ do {
+ 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?
+ if (YnPrompt(outs.c_str(), true) == false)
+ {
+ if (res == false && _error->PendingError() == false)
+ {
+ CacheFile.Close();
+ pkgCacheFile::RemoveCaches();
+ res = CacheFile.BuildCaches(nullptr);
+ }
+ break;
+ }
+ }
+ } while (res == false);
+
+ if (res == true && file_changed == true)
+ {
+ ioprintf(
+ std::cout, _("Your '%s' file changed, please run 'apt-get update'.\n"),
+ sourceslist.c_str());
+ }
+ return res;
+}
+ /*}}}*/