private-sources.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <config.h>
  2. #include <apt-pkg/hashes.h>
  3. #include <apt-pkg/strutl.h>
  4. #include <apt-pkg/configuration.h>
  5. #include <apt-pkg/sourcelist.h>
  6. #include <apt-pkg/cmndline.h>
  7. #include <apt-pkg/error.h>
  8. #include <apt-pkg/fileutl.h>
  9. #include <apt-pkg/cachefile.h>
  10. #include <apt-private/private-output.h>
  11. #include <apt-private/private-sources.h>
  12. #include <apt-private/private-utils.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <stddef.h>
  16. #include <unistd.h>
  17. #include <iostream>
  18. #include <string>
  19. #include <apti18n.h>
  20. /* Interface discussion with donkult (for the future):
  21. apt [add-{archive,release,component}|edit|change-release|disable]-sources
  22. and be clever and work out stuff from the Release file
  23. */
  24. // EditSource - EditSourcesList /*{{{*/
  25. class APT_HIDDEN ScopedGetLock {
  26. public:
  27. int fd;
  28. ScopedGetLock(std::string const &filename) : fd(GetLock(filename)) {}
  29. ~ScopedGetLock() { close(fd); }
  30. };
  31. bool EditSources(CommandLine &CmdL)
  32. {
  33. std::string sourceslist;
  34. if (CmdL.FileList[1] != NULL)
  35. {
  36. sourceslist = _config->FindDir("Dir::Etc::sourceparts") + CmdL.FileList[1];
  37. if (!APT::String::Endswith(sourceslist, ".list"))
  38. sourceslist += ".list";
  39. } else {
  40. sourceslist = _config->FindFile("Dir::Etc::sourcelist");
  41. }
  42. HashString before;
  43. if (FileExists(sourceslist))
  44. before.FromFile(sourceslist);
  45. else
  46. {
  47. FileFd filefd;
  48. if (filefd.Open(sourceslist, FileFd::Create | FileFd::WriteOnly, FileFd::None, 0644) == false)
  49. return false;
  50. }
  51. ScopedGetLock lock(sourceslist);
  52. if (lock.fd < 0)
  53. return false;
  54. bool res;
  55. bool file_changed = false;
  56. do {
  57. if (EditFileInSensibleEditor(sourceslist) == false)
  58. return false;
  59. if (before.empty())
  60. {
  61. struct stat St;
  62. if (stat(sourceslist.c_str(), &St) == 0 && St.st_size == 0)
  63. RemoveFile("edit-sources", sourceslist);
  64. }
  65. else if (FileExists(sourceslist) && !before.VerifyFile(sourceslist))
  66. {
  67. file_changed = true;
  68. pkgCacheFile::RemoveCaches();
  69. }
  70. pkgCacheFile CacheFile;
  71. res = CacheFile.BuildCaches(nullptr);
  72. if (res == false || _error->empty(GlobalError::WARNING) == false) {
  73. std::string outs;
  74. strprintf(outs, _("Failed to parse %s. Edit again? "), sourceslist.c_str());
  75. // FIXME: should we add a "restore previous" option here?
  76. if (YnPrompt(outs.c_str(), true) == false)
  77. {
  78. if (res == false && _error->PendingError() == false)
  79. {
  80. CacheFile.Close();
  81. pkgCacheFile::RemoveCaches();
  82. res = CacheFile.BuildCaches(nullptr);
  83. }
  84. break;
  85. }
  86. }
  87. } while (res == false);
  88. if (res == true && file_changed == true)
  89. {
  90. ioprintf(
  91. std::cout, _("Your '%s' file changed, please run 'apt-get update'."),
  92. sourceslist.c_str());
  93. }
  94. return res;
  95. }
  96. /*}}}*/