// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: algorithms.cc,v 1.11 1998/11/14 07:20:06 jgg Exp $
+// $Id: algorithms.cc,v 1.12 1998/11/23 07:02:58 jgg Exp $
/* ######################################################################
Algorithms - A set of misc algorithms
{
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
+ // Only choice for a ReInstReq package is to reinstall
+ if (I->InstState == pkgCache::State::ReInstReq ||
+ I->InstState == pkgCache::State::HoldReInstReq)
+ {
+ Cache.MarkKeep(I);
+ continue;
+ }
+
switch (I->CurrentState)
{
// This means installation failed somehow
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.cc,v 1.13 1998/10/26 07:11:49 jgg Exp $
+// $Id: fileutl.cc,v 1.14 1998/11/23 07:03:06 jgg Exp $
/* ######################################################################
File Utilities
return string(File,Res,Res - File.length());
}
/*}}}*/
+// flNotFile - Strip the file from the directory name /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string flNotFile(string File)
+{
+ string::size_type Res = File.rfind('/');
+ if (Res == string::npos)
+ return File;
+ Res++;
+ return string(File,0,Res);
+}
+ /*}}}*/
// SetCloseExec - Set the close on exec flag /*{{{*/
// ---------------------------------------------------------------------
/* */
case WriteAny:
iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms);
- break;
-
- // Dont use this in public directories
- case LockEmpty:
- iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms);
- break;
+ break;
}
if (iFd < 0)
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.h,v 1.8 1998/10/26 07:11:50 jgg Exp $
+// $Id: fileutl.h,v 1.9 1998/11/23 07:03:07 jgg Exp $
/* ######################################################################
File Utilities
string FileName;
public:
- enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,LockEmpty};
+ enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny};
bool Read(void *To,unsigned long Size);
bool Write(void *From,unsigned long Size);
// File string manipulators
string flNotDir(string File);
+string flNotFile(string File);
#endif
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: mmap.cc,v 1.9 1998/11/12 03:14:39 jgg Exp $
+// $Id: mmap.cc,v 1.10 1998/11/23 07:03:08 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace)
{
+ if (_error->PendingError() == true)
+ return;
+
unsigned long EndOfFile = Fd.Size();
Fd.Seek(WorkSpace);
char C = 0;
--- /dev/null
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: dpkginit.cc,v 1.1 1998/11/23 07:03:10 jgg Exp $
+/* ######################################################################
+
+ DPKG init - Initialize the dpkg stuff
+
+ ##################################################################### */
+ /*}}}*/
+// 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()
+{
+ LockFD = -1;
+ GetLock();
+}
+ /*}}}*/
+// 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()
+{
+ // 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->Errno("Open","Unable to lock the administration directory "
+ "%s, are you root?",AdminDir.c_str());
+
+ // Check for updates.. (dirty)
+ string File = AdminDir + "updates/";
+ DIR *DirP = opendir(File.c_str());
+ if (DirP != 0)
+ {
+ /* 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);
+
+ // Woops, we have to run dpkg to rewrite the status file
+ if (Damaged == 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;
+}
+ /*}}}*/
--- /dev/null
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: dpkginit.h,v 1.1 1998/11/23 07:03:11 jgg Exp $
+/* ######################################################################
+
+ DPKG init - Initialize the dpkg stuff
+
+ This basically gets a lock in /var/lib/dpkg and checks the updates
+ directory
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef PKGLIB_DPKGINIT_H
+#define PKGLIB_DPKGINIT_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/dpkginit.h"
+#endif
+
+class pkgDpkgLock
+{
+ int LockFD;
+
+ public:
+
+ bool GetLock();
+ void Close();
+
+ pkgDpkgLock();
+ ~pkgDpkgLock();
+};
+
+#endif
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: dpkgpm.cc,v 1.2 1998/11/22 03:20:35 jgg Exp $
+// $Id: dpkgpm.cc,v 1.3 1998/11/23 07:03:11 jgg Exp $
/* ######################################################################
DPKG Package Manager - Provide an interface to dpkg
// This is the child
if (Child == 0)
{
+ signal(SIGPIPE,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGWINCH,SIG_DFL);
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: dpkgpm.h,v 1.1 1998/11/13 04:23:39 jgg Exp $
+// $Id: dpkgpm.h,v 1.2 1998/11/23 07:03:12 jgg Exp $
/* ######################################################################
DPKG Package Manager - Provide an interface to dpkg
##################################################################### */
/*}}}*/
-// Header section: pkglib
#ifndef PKGLIB_DPKGPM_H
#define PKGLIB_DPKGPM_H
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: depcache.cc,v 1.6 1998/11/23 01:45:58 jgg Exp $
+// $Id: depcache.cc,v 1.7 1998/11/23 07:02:59 jgg Exp $
/* ######################################################################
Dependency Cache - Caches Dependency information.
{
iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize;
iDownloadSize += Mult*P.InstVerIter(*this)->Size;
+ return;
}
// Upgrading
iUsrSize += Mult*((signed)P.InstVerIter(*this)->InstalledSize -
(signed)Pkg.CurrentVer()->InstalledSize);
iDownloadSize += Mult*P.InstVerIter(*this)->Size;
+ return;
+ }
+
+ // Reinstall
+ if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack)
+ {
+ iDownloadSize += Mult*P.InstVerIter(*this)->Size;
+ return;
}
// Removing
if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
+ {
iUsrSize -= Mult*Pkg.CurrentVer()->InstalledSize;
+ return;
+ }
}
/*}}}*/
// DepCache::AddStates - Add the package to the state counter /*{{{*/
acquire-worker.cc acquire-method.cc init.cc templates.cc
# Source code for the debian specific components
-SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc
+SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc deb/dpkginit.cc
# Public apt-pkg header files
HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \
packagemanager.h tagfile.h deblistparser.h init.h pkgcache.h \
version.h progress.h pkgrecords.h debrecords.h cmndline.h \
acquire.h acquire-worker.h acquire-item.h acquire-method.h md5.h \
- dpkgpm.h
+ dpkgpm.h dpkginit.h
HEADERS := $(addprefix apt-pkg/,$(HEADERS))
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: packagemanager.cc,v 1.7 1998/11/22 23:37:05 jgg Exp $
+// $Id: packagemanager.cc,v 1.8 1998/11/23 07:03:01 jgg Exp $
/* ######################################################################
Package Manager - Abstacts the package manager
// Skip packages to erase
if (Cache[Pkg].Delete() == true)
continue;
+
+ // Skip Packages that need configure only.
+ if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure)
+ continue;
new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
FileNames[Pkg->ID]);
// Generate the list of affected packages and sort it
for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
- // Consider all depends
+ // Mark the package for immediate configuration
if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
{
List->Flag(I,pkgOrderList::Immediate);
+
+ // Look for other packages to make immediate configurea
if (Cache[I].InstallVer != 0)
for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
D.end() == false; D++)
if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
+
+ // And again with the current version.
if (I->CurrentVer != 0)
for (DepIterator D = I.CurrentVer().DependsList();
D.end() == false; D++)
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcache.cc,v 1.16 1998/11/14 07:20:09 jgg Exp $
+// $Id: pkgcache.cc,v 1.17 1998/11/23 07:03:05 jgg Exp $
/* ######################################################################
Package Cache - Accessor code for the cache
// ---------------------------------------------------------------------
/* By this we mean if it is either cleanly installed or cleanly removed. */
pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
-{
+{
if (Pkg->InstState == pkgCache::State::ReInstReq ||
Pkg->InstState == pkgCache::State::HoldReInstReq)
return NeedsUnpack;
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: apt-get.cc,v 1.17 1998/11/23 01:45:59 jgg Exp $
+// $Id: apt-get.cc,v 1.18 1998/11/23 07:03:13 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
#include <apt-pkg/algorithms.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/dpkgpm.h>
+#include <apt-pkg/dpkginit.h>
#include <strutl.h>
#include <config.h>
FileFd *File;
MMap *Map;
pkgDepCache *Cache;
+ pkgDpkgLock Lock;
inline operator pkgDepCache &() {return *Cache;};
inline pkgDepCache *operator ->() {return Cache;};
and verifies that the system is OK. */
bool CacheFile::Open()
{
+ if (_error->PendingError() == true)
+ return false;
+
// Create a progress class
OpTextProgress Progress(*_config);
// ---------------------------------------------------------------------
/* This displays the informative messages describing what is going to
happen and then calls the download routines */
-bool InstallPackages(pkgDepCache &Cache,bool ShwKept,bool Ask = true)
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true)
{
// Show all the various warning indicators
ShowDel(c1out,Cache);
Stats(c1out,Cache);
// Sanity check
- if (Cache.BrokenCount() != 0)
+ if (Cache->BrokenCount() != 0)
{
ShowBroken(c1out,Cache);
return _error->Error("Internal Error, InstallPackages was called with broken packages!");
}
- if (Cache.DelCount() == 0 && Cache.InstCount() == 0 &&
- Cache.BadCount() == 0)
+ if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ Cache->BadCount() == 0)
return true;
// Run the simulator ..
// Create the text record parser
pkgRecords Recs(Cache);
+
+ // Lock the archive directory
+ if (_config->FindB("Debug::NoLocking",false) == false)
+ {
+ FileFd Lock(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+ if (_error->PendingError() == true)
+ return _error->Error("Unable to lock the download directory");
+ }
// Create the download object
AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
// Display statistics
unsigned long FetchBytes = Fetcher.FetchNeeded();
unsigned long DebBytes = Fetcher.TotalNeeded();
- if (DebBytes != Cache.DebSize())
+ if (DebBytes != Cache->DebSize())
+ {
+ c0out << DebBytes << ',' << Cache->DebSize() << endl;
c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
-
+ }
+
// Number of bytes
c1out << "Need to get ";
if (DebBytes != FetchBytes)
c1out << " of archives. After unpacking ";
// Size delta
- if (Cache.UsrSize() >= 0)
- c1out << SizeToStr(Cache.UsrSize()) << " will be used." << endl;
+ if (Cache->UsrSize() >= 0)
+ c1out << SizeToStr(Cache->UsrSize()) << " will be used." << endl;
else
- c1out << SizeToStr(-1*Cache.UsrSize()) << " will be freed." << endl;
+ c1out << SizeToStr(-1*Cache->UsrSize()) << " will be freed." << endl;
if (_error->PendingError() == true)
return false;
return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
// Try to deal with missing package files
-/* if (PM.FixMissing() == false)
+ if (PM.FixMissing() == false)
{
cerr << "Unable to correct missing packages." << endl;
return _error->Error("Aborting Install.");
- }*/
+ }
+ Cache.Lock.Close();
return PM.DoInstall();
}
/*}}}*/
if (List.ReadMainList() == false)
return false;
+ // Lock the list directory
+ if (_config->FindB("Debug::NoLocking",false) == false)
+ {
+ FileFd Lock(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
+ if (_error->PendingError() == true)
+ return _error->Error("Unable to lock the list directory");
+ }
+
// Create the download object
AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
pkgAcquire Fetcher(&Stat);