]>
Commit | Line | Data |
---|---|---|
b2e465d6 AL |
1 | // -*- mode: cpp; mode: fold -*- |
2 | // Description /*{{{*/ | |
efef4fd3 | 3 | // $Id: debsystem.cc,v 1.4 2004/01/26 17:01:53 mdz Exp $ |
b2e465d6 AL |
4 | /* ###################################################################### |
5 | ||
6 | System - Abstraction for running on different systems. | |
7 | ||
8 | Basic general structure.. | |
9 | ||
10 | ##################################################################### */ | |
11 | /*}}}*/ | |
12 | // Include Files /*{{{*/ | |
b2e465d6 AL |
13 | #include <apt-pkg/debsystem.h> |
14 | #include <apt-pkg/debversion.h> | |
15 | #include <apt-pkg/debindexfile.h> | |
16 | #include <apt-pkg/dpkgpm.h> | |
17 | #include <apt-pkg/configuration.h> | |
18 | #include <apt-pkg/error.h> | |
19 | #include <apt-pkg/fileutl.h> | |
f0bb6493 | 20 | #include <apti18n.h> |
b2e465d6 AL |
21 | #include <sys/types.h> |
22 | #include <unistd.h> | |
23 | #include <dirent.h> | |
24 | #include <errno.h> | |
25 | /*}}}*/ | |
26 | ||
27 | debSystem debSys; | |
28 | ||
b8f90d97 MV |
29 | class debSystemPrivate { |
30 | public: | |
31 | debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0) | |
32 | { | |
33 | } | |
34 | // For locking support | |
35 | int LockFD; | |
36 | unsigned LockCount; | |
37 | ||
38 | debStatusIndex *StatusFile; | |
39 | }; | |
40 | ||
b2e465d6 AL |
41 | // System::debSystem - Constructor /*{{{*/ |
42 | // --------------------------------------------------------------------- | |
43 | /* */ | |
44 | debSystem::debSystem() | |
45 | { | |
b8f90d97 | 46 | d = new debSystemPrivate(); |
b2e465d6 AL |
47 | Label = "Debian dpkg interface"; |
48 | VS = &debVS; | |
49 | } | |
50 | /*}}}*/ | |
af87ab54 AL |
51 | // System::~debSystem - Destructor /*{{{*/ |
52 | // --------------------------------------------------------------------- | |
53 | /* */ | |
54 | debSystem::~debSystem() | |
55 | { | |
b8f90d97 MV |
56 | delete d->StatusFile; |
57 | delete d; | |
af87ab54 AL |
58 | } |
59 | /*}}}*/ | |
b2e465d6 AL |
60 | // System::Lock - Get the lock /*{{{*/ |
61 | // --------------------------------------------------------------------- | |
62 | /* This mirrors the operations dpkg does when it starts up. Note the | |
63 | checking of the updates directory. */ | |
64 | bool debSystem::Lock() | |
65 | { | |
66 | // Disable file locking | |
b8f90d97 | 67 | if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 1) |
b2e465d6 | 68 | { |
b8f90d97 | 69 | d->LockCount++; |
b2e465d6 AL |
70 | return true; |
71 | } | |
72 | ||
73 | // Create the lockfile | |
74 | string AdminDir = flNotFile(_config->Find("Dir::State::status")); | |
b8f90d97 MV |
75 | d->LockFD = GetLock(AdminDir + "lock"); |
76 | if (d->LockFD == -1) | |
b2e465d6 AL |
77 | { |
78 | if (errno == EACCES || errno == EAGAIN) | |
f23153d0 MV |
79 | return _error->Error(_("Unable to lock the administration directory (%s), " |
80 | "is another process using it?"),AdminDir.c_str()); | |
b2e465d6 | 81 | else |
f23153d0 MV |
82 | return _error->Error(_("Unable to lock the administration directory (%s), " |
83 | "are you root?"),AdminDir.c_str()); | |
b2e465d6 AL |
84 | } |
85 | ||
86 | // See if we need to abort with a dirty journal | |
87 | if (CheckUpdates() == true) | |
88 | { | |
b8f90d97 MV |
89 | close(d->LockFD); |
90 | d->LockFD = -1; | |
23c5897c MV |
91 | const char *cmd; |
92 | if (getenv("SUDO_USER") != NULL) | |
93 | cmd = "sudo dpkg --configure -a"; | |
94 | else | |
95 | cmd = "dpkg --configure -a"; | |
96 | // TRANSLATORS: the %s contains the recovery command, usually | |
97 | // dpkg --configure -a | |
f23153d0 | 98 | return _error->Error(_("dpkg was interrupted, you must manually " |
23c5897c | 99 | "run '%s' to correct the problem. "), cmd); |
b2e465d6 AL |
100 | } |
101 | ||
b8f90d97 | 102 | d->LockCount++; |
b2e465d6 AL |
103 | |
104 | return true; | |
105 | } | |
106 | /*}}}*/ | |
107 | // System::UnLock - Drop a lock /*{{{*/ | |
108 | // --------------------------------------------------------------------- | |
109 | /* */ | |
110 | bool debSystem::UnLock(bool NoErrors) | |
111 | { | |
b8f90d97 | 112 | if (d->LockCount == 0 && NoErrors == true) |
b2e465d6 AL |
113 | return false; |
114 | ||
b8f90d97 | 115 | if (d->LockCount < 1) |
09fab244 | 116 | return _error->Error(_("Not locked")); |
b8f90d97 | 117 | if (--d->LockCount == 0) |
b2e465d6 | 118 | { |
b8f90d97 MV |
119 | close(d->LockFD); |
120 | d->LockCount = 0; | |
b2e465d6 AL |
121 | } |
122 | ||
123 | return true; | |
124 | } | |
125 | /*}}}*/ | |
126 | // System::CheckUpdates - Check if the updates dir is dirty /*{{{*/ | |
127 | // --------------------------------------------------------------------- | |
128 | /* This does a check of the updates directory (dpkg journal) to see if it has | |
129 | any entries in it. */ | |
130 | bool debSystem::CheckUpdates() | |
131 | { | |
132 | // Check for updates.. (dirty) | |
133 | string File = flNotFile(_config->Find("Dir::State::status")) + "updates/"; | |
134 | DIR *DirP = opendir(File.c_str()); | |
135 | if (DirP == 0) | |
136 | return false; | |
137 | ||
138 | /* We ignore any files that are not all digits, this skips .,.. and | |
139 | some tmp files dpkg will leave behind.. */ | |
140 | bool Damaged = false; | |
141 | for (struct dirent *Ent = readdir(DirP); Ent != 0; Ent = readdir(DirP)) | |
142 | { | |
143 | Damaged = true; | |
144 | for (unsigned int I = 0; Ent->d_name[I] != 0; I++) | |
145 | { | |
146 | // Check if its not a digit.. | |
147 | if (isdigit(Ent->d_name[I]) == 0) | |
148 | { | |
149 | Damaged = false; | |
150 | break; | |
151 | } | |
152 | } | |
153 | if (Damaged == true) | |
154 | break; | |
155 | } | |
156 | closedir(DirP); | |
157 | ||
158 | return Damaged; | |
159 | } | |
160 | /*}}}*/ | |
161 | // System::CreatePM - Create the underlying package manager /*{{{*/ | |
162 | // --------------------------------------------------------------------- | |
163 | /* */ | |
164 | pkgPackageManager *debSystem::CreatePM(pkgDepCache *Cache) const | |
165 | { | |
166 | return new pkgDPkgPM(Cache); | |
167 | } | |
168 | /*}}}*/ | |
169 | // System::Initialize - Setup the configuration space.. /*{{{*/ | |
170 | // --------------------------------------------------------------------- | |
171 | /* These are the Debian specific configuration variables.. */ | |
172 | bool debSystem::Initialize(Configuration &Cnf) | |
173 | { | |
174 | /* These really should be jammed into a generic 'Local Database' engine | |
175 | which is yet to be determined. The functions in pkgcachegen should | |
176 | be the only users of these */ | |
940ff5d6 | 177 | Cnf.CndSet("Dir::State::extended_states", "extended_states"); |
c988fe21 | 178 | Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status"); |
b2e465d6 | 179 | Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg"); |
13e8426f | 180 | |
b8f90d97 MV |
181 | if (d->StatusFile) { |
182 | delete d->StatusFile; | |
183 | d->StatusFile = 0; | |
13e8426f MV |
184 | } |
185 | ||
b2e465d6 AL |
186 | return true; |
187 | } | |
188 | /*}}}*/ | |
189 | // System::ArchiveSupported - Is a file format supported /*{{{*/ | |
190 | // --------------------------------------------------------------------- | |
191 | /* The standard name for a deb is 'deb'.. There are no seperate versions | |
192 | of .deb to worry about.. */ | |
193 | bool debSystem::ArchiveSupported(const char *Type) | |
194 | { | |
195 | if (strcmp(Type,"deb") == 0) | |
196 | return true; | |
197 | return false; | |
198 | } | |
199 | /*}}}*/ | |
200 | // System::Score - Determine how 'Debiany' this sys is.. /*{{{*/ | |
201 | // --------------------------------------------------------------------- | |
202 | /* We check some files that are sure tell signs of this being a Debian | |
203 | System.. */ | |
204 | signed debSystem::Score(Configuration const &Cnf) | |
205 | { | |
206 | signed Score = 0; | |
207 | if (FileExists(Cnf.FindFile("Dir::State::status","/var/lib/dpkg/status")) == true) | |
208 | Score += 10; | |
209 | if (FileExists(Cnf.FindFile("Dir::Bin::dpkg","/usr/bin/dpkg")) == true) | |
210 | Score += 10; | |
211 | if (FileExists("/etc/debian_version") == true) | |
212 | Score += 10; | |
213 | return Score; | |
214 | } | |
215 | /*}}}*/ | |
216 | // System::AddStatusFiles - Register the status files /*{{{*/ | |
217 | // --------------------------------------------------------------------- | |
218 | /* */ | |
219 | bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List) | |
220 | { | |
b8f90d97 MV |
221 | if (d->StatusFile == 0) |
222 | d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status")); | |
223 | List.push_back(d->StatusFile); | |
b2e465d6 AL |
224 | return true; |
225 | } | |
226 | /*}}}*/ | |
af87ab54 AL |
227 | // System::FindIndex - Get an index file for status files /*{{{*/ |
228 | // --------------------------------------------------------------------- | |
229 | /* */ | |
230 | bool debSystem::FindIndex(pkgCache::PkgFileIterator File, | |
231 | pkgIndexFile *&Found) const | |
232 | { | |
b8f90d97 | 233 | if (d->StatusFile == 0) |
af87ab54 | 234 | return false; |
b8f90d97 | 235 | if (d->StatusFile->FindInCache(*File.Cache()) == File) |
af87ab54 | 236 | { |
b8f90d97 | 237 | Found = d->StatusFile; |
af87ab54 AL |
238 | return true; |
239 | } | |
240 | ||
241 | return false; | |
242 | } | |
243 | /*}}}*/ |