X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/fd78974020e23679e9e810cf01dc5c8f3012bb8a..bfc0933abedcd57e0a5bd07e282f3a50ba1fa5b2:/apt-private/private-sources.cc

diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc
index 5f61a23ab..587571760 100644
--- a/apt-private/private-sources.cc
+++ b/apt-private/private-sources.cc
@@ -7,11 +7,14 @@
 #include <apt-pkg/cmndline.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/cachefile.h>
 
 #include <apt-private/private-output.h>
 #include <apt-private/private-sources.h>
 #include <apt-private/private-utils.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stddef.h>
 #include <unistd.h>
 #include <iostream>
@@ -20,17 +23,19 @@
 #include <apti18n.h>
 
 /* 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 sourceslist;
    if (CmdL.FileList[1] != NULL)
    {
@@ -43,31 +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) {
+      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(outs.c_str(), 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)) {
+   if (res == true && file_changed == true)
+   {
       ioprintf(
          std::cout, _("Your '%s' file changed, please run 'apt-get update'."),
          sourceslist.c_str());
    }
-
-   return true;
+   return res;
 }
 									/*}}}*/