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