1 // -*- mode: cpp; mode: fold -*-
3 // $Id: debsystem.cc,v 1.4 2004/01/26 17:01:53 mdz Exp $
4 /* ######################################################################
6 System - Abstraction for running on different systems.
8 Basic general structure..
10 ##################################################################### */
12 // Include Files /*{{{*/
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>
22 #include <apt-pkg/pkgcache.h>
23 #include <apt-pkg/cacheiterators.h>
41 class APT_HIDDEN debSystemPrivate
{
43 debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0)
46 // For locking support
50 debStatusIndex
*StatusFile
;
53 // System::debSystem - Constructor /*{{{*/
54 // ---------------------------------------------------------------------
56 debSystem::debSystem() : pkgSystem("Debian dpkg interface", &debVS
), d(new debSystemPrivate())
60 // System::~debSystem - Destructor /*{{{*/
61 // ---------------------------------------------------------------------
63 debSystem::~debSystem()
69 // System::Lock - Get the lock /*{{{*/
70 // ---------------------------------------------------------------------
71 /* This mirrors the operations dpkg does when it starts up. Note the
72 checking of the updates directory. */
73 bool debSystem::Lock()
75 // Disable file locking
76 if (_config
->FindB("Debug::NoLocking",false) == true || d
->LockCount
> 1)
82 // Create the lockfile
83 string AdminDir
= flNotFile(_config
->Find("Dir::State::status"));
84 d
->LockFD
= GetLock(AdminDir
+ "lock");
87 if (errno
== EACCES
|| errno
== EAGAIN
)
88 return _error
->Error(_("Unable to lock the administration directory (%s), "
89 "is another process using it?"),AdminDir
.c_str());
91 return _error
->Error(_("Unable to lock the administration directory (%s), "
92 "are you root?"),AdminDir
.c_str());
95 // See if we need to abort with a dirty journal
96 if (CheckUpdates() == true)
101 if (getenv("SUDO_USER") != NULL
)
102 cmd
= "sudo dpkg --configure -a";
104 cmd
= "dpkg --configure -a";
105 // TRANSLATORS: the %s contains the recovery command, usually
106 // dpkg --configure -a
107 return _error
->Error(_("dpkg was interrupted, you must manually "
108 "run '%s' to correct the problem. "), cmd
);
116 // System::UnLock - Drop a lock /*{{{*/
117 // ---------------------------------------------------------------------
119 bool debSystem::UnLock(bool NoErrors
)
121 if (d
->LockCount
== 0 && NoErrors
== true)
124 if (d
->LockCount
< 1)
125 return _error
->Error(_("Not locked"));
126 if (--d
->LockCount
== 0)
135 // System::CheckUpdates - Check if the updates dir is dirty /*{{{*/
136 // ---------------------------------------------------------------------
137 /* This does a check of the updates directory (dpkg journal) to see if it has
138 any entries in it. */
139 bool debSystem::CheckUpdates()
141 // Check for updates.. (dirty)
142 string File
= flNotFile(_config
->Find("Dir::State::status")) + "updates/";
143 DIR *DirP
= opendir(File
.c_str());
147 /* We ignore any files that are not all digits, this skips .,.. and
148 some tmp files dpkg will leave behind.. */
149 bool Damaged
= false;
150 for (struct dirent
*Ent
= readdir(DirP
); Ent
!= 0; Ent
= readdir(DirP
))
153 for (unsigned int I
= 0; Ent
->d_name
[I
] != 0; I
++)
155 // Check if its not a digit..
156 if (isdigit(Ent
->d_name
[I
]) == 0)
170 // System::CreatePM - Create the underlying package manager /*{{{*/
171 // ---------------------------------------------------------------------
173 pkgPackageManager
*debSystem::CreatePM(pkgDepCache
*Cache
) const
175 return new pkgDPkgPM(Cache
);
178 // System::Initialize - Setup the configuration space.. /*{{{*/
179 // ---------------------------------------------------------------------
180 /* These are the Debian specific configuration variables.. */
181 bool debSystem::Initialize(Configuration
&Cnf
)
183 /* These really should be jammed into a generic 'Local Database' engine
184 which is yet to be determined. The functions in pkgcachegen should
185 be the only users of these */
186 Cnf
.CndSet("Dir::State::extended_states", "extended_states");
187 Cnf
.CndSet("Dir::State::status","/var/lib/dpkg/status");
188 Cnf
.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
191 delete d
->StatusFile
;
198 // System::ArchiveSupported - Is a file format supported /*{{{*/
199 // ---------------------------------------------------------------------
200 /* The standard name for a deb is 'deb'.. There are no separate versions
201 of .deb to worry about.. */
202 APT_PURE
bool debSystem::ArchiveSupported(const char *Type
)
204 if (strcmp(Type
,"deb") == 0)
209 // System::Score - Determine how 'Debiany' this sys is.. /*{{{*/
210 // ---------------------------------------------------------------------
211 /* We check some files that are sure tell signs of this being a Debian
213 signed debSystem::Score(Configuration
const &Cnf
)
216 if (FileExists(Cnf
.FindFile("Dir::State::status","/var/lib/dpkg/status")) == true)
218 if (FileExists(Cnf
.FindFile("Dir::Bin::dpkg","/usr/bin/dpkg")) == true)
220 if (FileExists("/etc/debian_version") == true)
225 // System::AddStatusFiles - Register the status files /*{{{*/
226 // ---------------------------------------------------------------------
228 bool debSystem::AddStatusFiles(std::vector
<pkgIndexFile
*> &List
)
230 if (d
->StatusFile
== 0)
231 d
->StatusFile
= new debStatusIndex(_config
->FindFile("Dir::State::status"));
232 List
.push_back(d
->StatusFile
);
236 // System::FindIndex - Get an index file for status files /*{{{*/
237 // ---------------------------------------------------------------------
239 bool debSystem::FindIndex(pkgCache::PkgFileIterator File
,
240 pkgIndexFile
*&Found
) const
242 if (d
->StatusFile
== 0)
244 if (d
->StatusFile
->FindInCache(*File
.Cache()) == File
)
246 Found
= d
->StatusFile
;