]> git.saurik.com Git - apt.git/blobdiff - apt-private/private-sources.cc
fail instead of segfault on unreadable config files
[apt.git] / apt-private / private-sources.cc
index 37b0534bda63d63334644df67ad46583ee28b9b3..5f61a23abff1a74234a7374c2bbc93cf685be8a0 100644 (file)
@@ -1,10 +1,23 @@
+#include <config.h>
 
 #include <apt-pkg/hashes.h>
-#include <apti18n.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-private/private-output.h>
+#include <apt-private/private-sources.h>
+#include <apt-private/private-utils.h>
 
-#include "private-output.h"
-#include "private-sources.h"
-#include "private-utils.h"
+#include <stddef.h>
+#include <unistd.h>
+#include <iostream>
+#include <string>
+
+#include <apti18n.h>
 
 /* Interface discussion with donkult (for the future):
   apt [add-{archive,release,component}|edit|change-release|disable]-sources 
@@ -17,37 +30,42 @@ bool EditSources(CommandLine &CmdL)
 {
    bool res;
    pkgSourceList sl;
-   std::string outs;
 
    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);
 
+   int lockfd = GetLock(sourceslist);
+   if (lockfd < 0)
+      return 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;
-         res = !YnPrompt(true);
+        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);
       }
       _error->RevertToStack();
    } while (res == false);
+   close(lockfd);
 
    if (FileExists(sourceslist) && !before.VerifyFile(sourceslist)) {
-      strprintf(
-         outs, _("Your '%s' file changed, please run 'apt-get update'."),
+      ioprintf(
+         std::cout, _("Your '%s' file changed, please run 'apt-get update'."),
          sourceslist.c_str());
-      std::cout << outs << std::endl;
    }
 
    return true;