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