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