]> git.saurik.com Git - apt.git/blobdiff - apt-private/private-sources.cc
support dpkg debug mode in APT::StateChanges
[apt.git] / apt-private / private-sources.cc
index eb9c5b971e9d9d72f765e101937104f7ecb70cd1..587571760f6f339b26b72e5c95d31242da4130a9 100644 (file)
+#include <config.h>
 
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/sourcelist.h>
+#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>
+#include <string>
+
 #include <apti18n.h>
 
-#include "private-output.h"
-#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                                        /*{{{*/
-// ---------------------------------------------------------------------
+// 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;
-
-   // 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];
+      if (!APT::String::Endswith(sourceslist, ".list"))
+         sourceslist += ".list";
+   } else {
+      sourceslist = _config->FindFile("Dir::Etc::sourcelist");
+   }
    HashString before;
-   before.FromFile(sourceslist);
+   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 {
-      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);
+      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;
+        }
       }
-      _error->RevertToStack();
    } while (res == false);
 
-   if (!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;
 }
                                                                        /*}}}*/