releasing version 0.8.16~exp3
[ntk/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 /*{{{*/
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
27debSystem debSys;
28
b8f90d97
MV
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
b2e465d6
AL
41// System::debSystem - Constructor /*{{{*/
42// ---------------------------------------------------------------------
43/* */
44debSystem::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/* */
54debSystem::~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. */
64bool 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/* */
110bool 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. */
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 */
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.. */
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{
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/* */
230bool 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 /*}}}*/