You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
7.2 KiB
255 lines
7.2 KiB
// -*- mode: cpp; mode: fold -*-
|
|
// Description /*{{{*/
|
|
// $Id: debsystem.cc,v 1.4 2004/01/26 17:01:53 mdz Exp $
|
|
/* ######################################################################
|
|
|
|
System - Abstraction for running on different systems.
|
|
|
|
Basic general structure..
|
|
|
|
##################################################################### */
|
|
/*}}}*/
|
|
// Include Files /*{{{*/
|
|
#include <config.h>
|
|
|
|
#include <apt-pkg/debsystem.h>
|
|
#include <apt-pkg/debversion.h>
|
|
#include <apt-pkg/debindexfile.h>
|
|
#include <apt-pkg/dpkgpm.h>
|
|
#include <apt-pkg/configuration.h>
|
|
#include <apt-pkg/error.h>
|
|
#include <apt-pkg/fileutl.h>
|
|
#include <apt-pkg/pkgcache.h>
|
|
#include <apt-pkg/cacheiterators.h>
|
|
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
|
|
#include <apti18n.h>
|
|
/*}}}*/
|
|
|
|
using std::string;
|
|
|
|
debSystem debSys;
|
|
|
|
class debSystemPrivate {
|
|
public:
|
|
debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0)
|
|
{
|
|
}
|
|
// For locking support
|
|
int LockFD;
|
|
unsigned LockCount;
|
|
|
|
debStatusIndex *StatusFile;
|
|
};
|
|
|
|
// System::debSystem - Constructor /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
debSystem::debSystem()
|
|
{
|
|
d = new debSystemPrivate();
|
|
Label = "Debian dpkg interface";
|
|
VS = &debVS;
|
|
}
|
|
/*}}}*/
|
|
// System::~debSystem - Destructor /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
debSystem::~debSystem()
|
|
{
|
|
delete d->StatusFile;
|
|
delete d;
|
|
}
|
|
/*}}}*/
|
|
// System::Lock - Get the lock /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* This mirrors the operations dpkg does when it starts up. Note the
|
|
checking of the updates directory. */
|
|
bool debSystem::Lock()
|
|
{
|
|
// Disable file locking
|
|
if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 1)
|
|
{
|
|
d->LockCount++;
|
|
return true;
|
|
}
|
|
|
|
// Create the lockfile
|
|
string AdminDir = flNotFile(_config->Find("Dir::State::status"));
|
|
d->LockFD = GetLock(AdminDir + "lock");
|
|
if (d->LockFD == -1)
|
|
{
|
|
if (errno == EACCES || errno == EAGAIN)
|
|
return _error->Error(_("Unable to lock the administration directory (%s), "
|
|
"is another process using it?"),AdminDir.c_str());
|
|
else
|
|
return _error->Error(_("Unable to lock the administration directory (%s), "
|
|
"are you root?"),AdminDir.c_str());
|
|
}
|
|
|
|
// See if we need to abort with a dirty journal
|
|
if (CheckUpdates() == true)
|
|
{
|
|
close(d->LockFD);
|
|
d->LockFD = -1;
|
|
const char *cmd;
|
|
if (getenv("SUDO_USER") != NULL)
|
|
cmd = "sudo dpkg --configure -a";
|
|
else
|
|
cmd = "dpkg --configure -a";
|
|
// TRANSLATORS: the %s contains the recovery command, usually
|
|
// dpkg --configure -a
|
|
return _error->Error(_("dpkg was interrupted, you must manually "
|
|
"run '%s' to correct the problem. "), cmd);
|
|
}
|
|
|
|
d->LockCount++;
|
|
|
|
return true;
|
|
}
|
|
/*}}}*/
|
|
// System::UnLock - Drop a lock /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
bool debSystem::UnLock(bool NoErrors)
|
|
{
|
|
if (d->LockCount == 0 && NoErrors == true)
|
|
return false;
|
|
|
|
if (d->LockCount < 1)
|
|
return _error->Error(_("Not locked"));
|
|
if (--d->LockCount == 0)
|
|
{
|
|
close(d->LockFD);
|
|
d->LockCount = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
/*}}}*/
|
|
// System::CheckUpdates - Check if the updates dir is dirty /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* This does a check of the updates directory (dpkg journal) to see if it has
|
|
any entries in it. */
|
|
bool debSystem::CheckUpdates()
|
|
{
|
|
// Check for updates.. (dirty)
|
|
string File = flNotFile(_config->Find("Dir::State::status")) + "updates/";
|
|
DIR *DirP = opendir(File.c_str());
|
|
if (DirP == 0)
|
|
return false;
|
|
|
|
/* We ignore any files that are not all digits, this skips .,.. and
|
|
some tmp files dpkg will leave behind.. */
|
|
bool Damaged = false;
|
|
for (struct dirent *Ent = readdir(DirP); Ent != 0; Ent = readdir(DirP))
|
|
{
|
|
Damaged = true;
|
|
for (unsigned int I = 0; Ent->d_name[I] != 0; I++)
|
|
{
|
|
// Check if its not a digit..
|
|
if (isdigit(Ent->d_name[I]) == 0)
|
|
{
|
|
Damaged = false;
|
|
break;
|
|
}
|
|
}
|
|
if (Damaged == true)
|
|
break;
|
|
}
|
|
closedir(DirP);
|
|
|
|
return Damaged;
|
|
}
|
|
/*}}}*/
|
|
// System::CreatePM - Create the underlying package manager /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
pkgPackageManager *debSystem::CreatePM(pkgDepCache *Cache) const
|
|
{
|
|
return new pkgDPkgPM(Cache);
|
|
}
|
|
/*}}}*/
|
|
// System::Initialize - Setup the configuration space.. /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* These are the Debian specific configuration variables.. */
|
|
bool debSystem::Initialize(Configuration &Cnf)
|
|
{
|
|
/* These really should be jammed into a generic 'Local Database' engine
|
|
which is yet to be determined. The functions in pkgcachegen should
|
|
be the only users of these */
|
|
Cnf.CndSet("Dir::State::extended_states", "extended_states");
|
|
Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status");
|
|
Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
|
|
|
|
if (d->StatusFile) {
|
|
delete d->StatusFile;
|
|
d->StatusFile = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
/*}}}*/
|
|
// System::ArchiveSupported - Is a file format supported /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* The standard name for a deb is 'deb'.. There are no separate versions
|
|
of .deb to worry about.. */
|
|
APT_PURE bool debSystem::ArchiveSupported(const char *Type)
|
|
{
|
|
if (strcmp(Type,"deb") == 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
/*}}}*/
|
|
// System::Score - Determine how 'Debiany' this sys is.. /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* We check some files that are sure tell signs of this being a Debian
|
|
System.. */
|
|
signed debSystem::Score(Configuration const &Cnf)
|
|
{
|
|
signed Score = 0;
|
|
if (FileExists(Cnf.FindFile("Dir::State::status","/var/lib/dpkg/status")) == true)
|
|
Score += 10;
|
|
if (FileExists(Cnf.FindFile("Dir::Bin::dpkg","/usr/bin/dpkg")) == true)
|
|
Score += 10;
|
|
if (FileExists("/etc/debian_version") == true)
|
|
Score += 10;
|
|
return Score;
|
|
}
|
|
/*}}}*/
|
|
// System::AddStatusFiles - Register the status files /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
bool debSystem::AddStatusFiles(std::vector<pkgIndexFile *> &List)
|
|
{
|
|
if (d->StatusFile == 0)
|
|
d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status"));
|
|
List.push_back(d->StatusFile);
|
|
return true;
|
|
}
|
|
/*}}}*/
|
|
// System::FindIndex - Get an index file for status files /*{{{*/
|
|
// ---------------------------------------------------------------------
|
|
/* */
|
|
bool debSystem::FindIndex(pkgCache::PkgFileIterator File,
|
|
pkgIndexFile *&Found) const
|
|
{
|
|
if (d->StatusFile == 0)
|
|
return false;
|
|
if (d->StatusFile->FindInCache(*File.Cache()) == File)
|
|
{
|
|
Found = d->StatusFile;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
/*}}}*/
|
|
|