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