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