]> git.saurik.com Git - apt.git/blame_incremental - apt-pkg/deb/debsystem.cc
move implementation of checksums around by abstracting even more
[apt.git] / apt-pkg / deb / debsystem.cc
... / ...
CommitLineData
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 <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>
20#include <apti18n.h>
21#include <sys/types.h>
22#include <unistd.h>
23#include <dirent.h>
24#include <errno.h>
25 /*}}}*/
26
27debSystem debSys;
28
29class debSystemPrivate {
30public:
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
41// System::debSystem - Constructor /*{{{*/
42// ---------------------------------------------------------------------
43/* */
44debSystem::debSystem()
45{
46 d = new debSystemPrivate();
47 Label = "Debian dpkg interface";
48 VS = &debVS;
49}
50 /*}}}*/
51// System::~debSystem - Destructor /*{{{*/
52// ---------------------------------------------------------------------
53/* */
54debSystem::~debSystem()
55{
56 delete d->StatusFile;
57 delete d;
58}
59 /*}}}*/
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. */
64bool debSystem::Lock()
65{
66 // Disable file locking
67 if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 1)
68 {
69 d->LockCount++;
70 return true;
71 }
72
73 // Create the lockfile
74 string AdminDir = flNotFile(_config->Find("Dir::State::status"));
75 d->LockFD = GetLock(AdminDir + "lock");
76 if (d->LockFD == -1)
77 {
78 if (errno == EACCES || errno == EAGAIN)
79 return _error->Error(_("Unable to lock the administration directory (%s), "
80 "is another process using it?"),AdminDir.c_str());
81 else
82 return _error->Error(_("Unable to lock the administration directory (%s), "
83 "are you root?"),AdminDir.c_str());
84 }
85
86 // See if we need to abort with a dirty journal
87 if (CheckUpdates() == true)
88 {
89 close(d->LockFD);
90 d->LockFD = -1;
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
98 return _error->Error(_("dpkg was interrupted, you must manually "
99 "run '%s' to correct the problem. "), cmd);
100 }
101
102 d->LockCount++;
103
104 return true;
105}
106 /*}}}*/
107// System::UnLock - Drop a lock /*{{{*/
108// ---------------------------------------------------------------------
109/* */
110bool debSystem::UnLock(bool NoErrors)
111{
112 if (d->LockCount == 0 && NoErrors == true)
113 return false;
114
115 if (d->LockCount < 1)
116 return _error->Error(_("Not locked"));
117 if (--d->LockCount == 0)
118 {
119 close(d->LockFD);
120 d->LockCount = 0;
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. */
130bool 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/* */
164pkgPackageManager *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.. */
172bool 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 */
177 Cnf.CndSet("Dir::State::extended_states", "extended_states");
178 Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status");
179 Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
180
181 if (d->StatusFile) {
182 delete d->StatusFile;
183 d->StatusFile = 0;
184 }
185
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.. */
193bool 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.. */
204signed 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/* */
219bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List)
220{
221 if (d->StatusFile == 0)
222 d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status"));
223 List.push_back(d->StatusFile);
224 return true;
225}
226 /*}}}*/
227// System::FindIndex - Get an index file for status files /*{{{*/
228// ---------------------------------------------------------------------
229/* */
230bool debSystem::FindIndex(pkgCache::PkgFileIterator File,
231 pkgIndexFile *&Found) const
232{
233 if (d->StatusFile == 0)
234 return false;
235 if (d->StatusFile->FindInCache(*File.Cache()) == File)
236 {
237 Found = d->StatusFile;
238 return true;
239 }
240
241 return false;
242}
243 /*}}}*/