// -*- mode: cpp; mode: fold -*- // Description /*{{{*/ // $Id: dpkginit.cc,v 1.5 1999/08/03 05:21:19 jgg Exp $ /* ###################################################################### DPKG init - Initialize the dpkg stuff This class provides the locking mechanism used by dpkg for its database area. It does the proper consistency checks and acquires the correct kind of lock. ##################################################################### */ /*}}}*/ // Includes /*{{{*/ #ifdef __GNUG__ #pragma implementation "apt-pkg/dpkginit.h" #endif #include <apt-pkg/dpkginit.h> #include <apt-pkg/error.h> #include <apt-pkg/configuration.h> #include <apt-pkg/fileutl.h> #include <sys/types.h> #include <unistd.h> #include <dirent.h> /*}}}*/ // DpkgLock::pkgDpkgLock - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ pkgDpkgLock::pkgDpkgLock(bool WithUpdates) { LockFD = -1; GetLock(WithUpdates); } /*}}}*/ // DpkgLock::~pkgDpkgLock - Destructor /*{{{*/ // --------------------------------------------------------------------- /* */ pkgDpkgLock::~pkgDpkgLock() { Close(); } /*}}}*/ // DpkgLock::GetLock - Get the lock /*{{{*/ // --------------------------------------------------------------------- /* This mirrors the operations dpkg does when it starts up. Note the checking of the updates directory. */ bool pkgDpkgLock::GetLock(bool WithUpdates) { // Disable file locking if (_config->FindB("Debug::NoLocking",false) == true) return true; Close(); // Create the lockfile string AdminDir = flNotFile(_config->Find("Dir::State::status")); LockFD = ::GetLock(AdminDir + "lock"); if (LockFD == -1) return _error->Error("Unable to lock the administration directory, " "are you root?"); // See if we need to abort with a dirty journal if (WithUpdates == true && CheckUpdates() == true) { Close(); return _error->Error("dpkg was interrupted, you must manually " "run 'dpkg --configure -a' to correct the problem. "); } return true; } /*}}}*/ // DpkgLock::Close - Close the lock /*{{{*/ // --------------------------------------------------------------------- /* */ void pkgDpkgLock::Close() { close(LockFD); LockFD = -1; } /*}}}*/ // DpkgLock::CheckUpdates - Check if the updates dir is dirty /*{{{*/ // --------------------------------------------------------------------- /* This does a check of the updates directory to see if it has any entries in it. */ bool pkgDpkgLock::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; } /*}}}*/