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