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