summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cachefile.cc96
-rw-r--r--apt-pkg/cachefile.h48
-rw-r--r--apt-pkg/contrib/mmap.cc67
-rw-r--r--apt-pkg/contrib/mmap.h15
-rw-r--r--apt-pkg/deb/dpkginit.cc6
-rw-r--r--apt-pkg/makefile4
-rw-r--r--apt-pkg/pkgcachegen.cc242
-rw-r--r--apt-pkg/pkgcachegen.h4
-rw-r--r--cmdline/apt-get.cc84
9 files changed, 421 insertions, 145 deletions
diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
new file mode 100644
index 000000000..285eb310f
--- /dev/null
+++ b/apt-pkg/cachefile.cc
@@ -0,0 +1,96 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: cachefile.cc,v 1.1 1999/04/18 06:36:36 jgg Exp $
+/* ######################################################################
+
+ CacheFile - Simple wrapper class for opening, generating and whatnot
+
+ This class implements a simple 2 line mechanism to open various sorts
+ of caches. It can operate as root, as not root, show progress and so on,
+ it transparently handles everything necessary.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/cachefile.h"
+#endif
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/configuration.h>
+ /*}}}*/
+
+// CacheFile::CacheFile - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCacheFile::pkgCacheFile() : Map(0), Cache(0), Lock()
+{
+}
+ /*}}}*/
+// CacheFile::~CacheFile - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCacheFile::~pkgCacheFile()
+{
+ delete Cache;
+ delete Map;
+ delete Lock;
+}
+ /*}}}*/
+// CacheFile::Open - Open the cache files, creating if necessary /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
+{
+ if (WithLock == true)
+ Lock = new pkgDpkgLock;
+
+ if (_error->PendingError() == true)
+ return false;
+
+ // Read the source list
+ pkgSourceList List;
+ if (List.ReadMainList() == false)
+ return _error->Error("The list of sources could not be read.");
+
+ /* Build all of the caches, using the cache files if we are locking
+ (ie as root) */
+ if (WithLock == true)
+ {
+ pkgMakeStatusCache(List,Progress);
+ Progress.Done();
+ if (_error->PendingError() == true)
+ return _error->Error("The package lists or status file could not be parsed or opened.");
+ if (_error->empty() == false)
+ _error->Warning("You may want to run apt-get update to correct theses missing files");
+
+ // Open the cache file
+ FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ return false;
+
+ Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+ if (_error->PendingError() == true)
+ return false;
+ }
+ else
+ {
+ Map = pkgMakeStatusCacheMem(List,Progress);
+ Progress.Done();
+ if (Map == 0)
+ return false;
+ }
+
+ // Create the dependency cache
+ Cache = new pkgDepCache(*Map,Progress);
+ if (_error->PendingError() == true)
+ return false;
+
+ Progress.Done();
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h
new file mode 100644
index 000000000..23bd4008b
--- /dev/null
+++ b/apt-pkg/cachefile.h
@@ -0,0 +1,48 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: cachefile.h,v 1.1 1999/04/18 06:36:36 jgg Exp $
+/* ######################################################################
+
+ CacheFile - Simple wrapper class for opening, generating and whatnot
+
+ This class implements a simple 2 line mechanism to open various sorts
+ of caches. It can operate as root, as not root, show progress and so on,
+ it transparently handles everything necessary.
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef PKGLIB_CACHEFILE_H
+#define PKGLIB_CACHEFILE_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/cachefile.h"
+#endif
+
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/dpkginit.h>
+
+class pkgCacheFile
+{
+ protected:
+
+ MMap *Map;
+ pkgDepCache *Cache;
+ pkgDpkgLock *Lock;
+
+ public:
+
+ // We look pretty much exactly like a pointer to a dep cache
+ inline operator pkgDepCache &() {return *Cache;};
+ inline pkgDepCache *operator ->() {return Cache;};
+ inline pkgDepCache &operator *() {return *Cache;};
+
+ // Release the dpkg status lock
+ inline void ReleaseLock() {Lock->Close();};
+
+ bool Open(OpProgress &Progress,bool WithLock = true);
+
+ pkgCacheFile();
+ ~pkgCacheFile();
+};
+
+#endif
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 7a5065ffb..098c61ca6 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: mmap.cc,v 1.14 1999/03/18 04:32:46 jgg Exp $
+// $Id: mmap.cc,v 1.15 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -38,11 +38,19 @@
// MMap::MMap - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0),
+MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
Base(0)
{
if ((Flags & NoImmMap) != NoImmMap)
- Map();
+ Map(F);
+}
+ /*}}}*/
+// MMap::MMap - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
+ Base(0)
+{
}
/*}}}*/
// MMap::~MMap - Destructor /*{{{*/
@@ -50,13 +58,13 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0),
/* */
MMap::~MMap()
{
- Close(true);
+ Close();
}
/*}}}*/
// MMap::Map - Perform the mapping /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool MMap::Map()
+bool MMap::Map(FileFd &Fd)
{
iSize = Fd.Size();
@@ -82,11 +90,11 @@ bool MMap::Map()
// MMap::Close - Close the map /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool MMap::Close(bool DoClose, bool DoSync)
+bool MMap::Close(bool DoSync)
{
- if (Fd.IsOpen() == false)
+ if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0)
return true;
-
+
if (DoSync == true)
Sync();
@@ -94,8 +102,6 @@ bool MMap::Close(bool DoClose, bool DoSync)
_error->Warning("Unable to munmap");
iSize = 0;
- if (DoClose == true)
- Fd.Close();
return true;
}
/*}}}*/
@@ -105,6 +111,9 @@ bool MMap::Close(bool DoClose, bool DoSync)
not return till all IO is complete */
bool MMap::Sync()
{
+ if ((Flags & UnMapped) == UnMapped)
+ return true;
+
#ifdef _POSIX_SYNCHRONIZED_IO
if ((Flags & ReadOnly) != ReadOnly)
if (msync((char *)Base,iSize,MS_SYNC) != 0)
@@ -118,6 +127,9 @@ bool MMap::Sync()
/* */
bool MMap::Sync(unsigned long Start,unsigned long Stop)
{
+ if ((Flags & UnMapped) == UnMapped)
+ return true;
+
#ifdef _POSIX_SYNCHRONIZED_IO
unsigned long PSize = sysconf(_SC_PAGESIZE);
if ((Flags & ReadOnly) != ReadOnly)
@@ -132,30 +144,49 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
// ---------------------------------------------------------------------
/* */
DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
- MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace)
+ MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
{
if (_error->PendingError() == true)
return;
- unsigned long EndOfFile = Fd.Size();
- Fd.Seek(WorkSpace);
+ unsigned long EndOfFile = Fd->Size();
+ Fd->Seek(WorkSpace);
char C = 0;
- Fd.Write(&C,sizeof(C));
- Map();
+ Fd->Write(&C,sizeof(C));
+ Map(F);
iSize = EndOfFile;
}
/*}}}*/
+// DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/
+// ---------------------------------------------------------------------
+/* This is just a fancy malloc really.. */
+DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
+ MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
+{
+ if (_error->PendingError() == true)
+ return;
+
+ Base = new unsigned char[WorkSpace];
+ iSize = 0;
+}
+ /*}}}*/
// DynamicMMap::~DynamicMMap - Destructor /*{{{*/
// ---------------------------------------------------------------------
/* We truncate the file to the size of the memory data set */
DynamicMMap::~DynamicMMap()
{
+ if (Fd == 0)
+ {
+ delete [] (unsigned char *)Base;
+ return;
+ }
+
unsigned long EndOfFile = iSize;
Sync();
iSize = WorkSpace;
- Close(false,false);
- ftruncate(Fd.Fd(),EndOfFile);
- Fd.Close();
+ Close(false);
+ ftruncate(Fd->Fd(),EndOfFile);
+ Fd->Close();
}
/*}}}*/
// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index 3cb6c6468..0c11d3202 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: mmap.h,v 1.8 1999/01/18 06:20:08 jgg Exp $
+// $Id: mmap.h,v 1.9 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -36,17 +36,17 @@ class MMap
{
protected:
- FileFd &Fd;
- unsigned long Flags;
+ unsigned long Flags;
unsigned long iSize;
void *Base;
- bool Map();
- bool Close(bool DoClose = true,bool DoSync = true);
+ bool Map(FileFd &Fd);
+ bool Close(bool DoSync = true);
public:
- enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)};
+ enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2),
+ UnMapped = (1<<3)};
// Simple accessors
inline operator void *() {return Base;};
@@ -58,6 +58,7 @@ class MMap
bool Sync(unsigned long Start,unsigned long Stop);
MMap(FileFd &F,unsigned long Flags);
+ MMap(unsigned long Flags);
virtual ~MMap();
};
@@ -75,6 +76,7 @@ class DynamicMMap : public MMap
protected:
+ FileFd *Fd;
unsigned long WorkSpace;
Pool *Pools;
unsigned int PoolCount;
@@ -89,6 +91,7 @@ class DynamicMMap : public MMap
void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;};
DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
+ DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
virtual ~DynamicMMap();
};
diff --git a/apt-pkg/deb/dpkginit.cc b/apt-pkg/deb/dpkginit.cc
index 095156d0d..518d18f59 100644
--- a/apt-pkg/deb/dpkginit.cc
+++ b/apt-pkg/deb/dpkginit.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: dpkginit.cc,v 1.1 1998/11/23 07:03:10 jgg Exp $
+// $Id: dpkginit.cc,v 1.2 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
DPKG init - Initialize the dpkg stuff
@@ -54,8 +54,8 @@ bool pkgDpkgLock::GetLock()
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());
+ return _error->Error("Unable to lock the administration directory, "
+ "are you root?");
// Check for updates.. (dirty)
string File = AdminDir + "updates/";
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index 14ed1dea5..80bfbdcf3 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -25,7 +25,7 @@ SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \
orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \
pkgrecords.cc algorithms.cc acquire.cc acquire-item.cc \
acquire-worker.cc acquire-method.cc init.cc clean.cc \
- srcrecords.cc
+ srcrecords.cc cachefile.cc
# Source code for the debian specific components
SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc deb/dpkginit.cc \
@@ -38,7 +38,7 @@ HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.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 dpkginit.h cdromutl.h strutl.h clean.h srcrecords.h \
- debsrcrecords.h
+ debsrcrecords.h cachefile.h
HEADERS := $(addprefix apt-pkg/,$(HEADERS))
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index d7e830df5..ee65c94d1 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcachegen.cc,v 1.34 1999/04/04 01:33:09 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.35 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
@@ -618,6 +618,70 @@ static bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen,
return true;
}
/*}}}*/
+// GenerateSrcCache - Write the source package lists to the map /*{{{*/
+// ---------------------------------------------------------------------
+/* This puts the source package cache into the given generator. */
+bool pkgGenerateSrcCache(pkgSourceList &List,OpProgress &Progress,
+ pkgCacheGenerator &Gen,
+ unsigned long &CurrentSize,unsigned long TotalSize)
+{
+ string ListDir = _config->FindDir("Dir::State::lists");
+
+ // Prepare the progress indicator
+ TotalSize = 0;
+ struct stat Buf;
+ for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
+ {
+ string File = ListDir + URItoFileName(I->PackagesURI());
+ if (stat(File.c_str(),&Buf) != 0)
+ continue;
+ TotalSize += Buf.st_size;
+ }
+
+ if (pkgAddSourcesSize(TotalSize) == false)
+ return false;
+
+ // Generate the pkg source cache
+ CurrentSize = 0;
+ for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
+ {
+ // Only cache deb source types.
+ if (I->Type != pkgSourceList::Item::Deb)
+ continue;
+
+ string File = ListDir + URItoFileName(I->PackagesURI());
+
+ if (FileExists(File) == false)
+ continue;
+
+ FileFd Pkg(File,FileFd::ReadOnly);
+ debListParser Parser(Pkg);
+ Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists");
+ if (_error->PendingError() == true)
+ return _error->Error("Problem opening %s",File.c_str());
+ CurrentSize += Pkg.Size();
+
+ Progress.SubProgress(0,I->PackagesInfo());
+ if (Gen.SelectFile(File) == false)
+ return _error->Error("Problem with SelectFile %s",File.c_str());
+
+ if (Gen.MergeList(Parser) == false)
+ return _error->Error("Problem with MergeList %s",File.c_str());
+
+ // Check the release file
+ string RFile = ListDir + URItoFileName(I->ReleaseURI());
+ if (FileExists(RFile) == true)
+ {
+ FileFd Rel(RFile,FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ return false;
+ Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel);
+ }
+ }
+
+ return true;
+}
+ /*}}}*/
// MakeStatusCache - Generates a cache that includes the status files /*{{{*/
// ---------------------------------------------------------------------
/* This copies the package source cache and then merges the status and
@@ -634,67 +698,18 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress)
if (SrcOk == false)
{
string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
- string ListDir = _config->FindDir("Dir::State::lists");
FileFd SCacheF(SCacheFile,FileFd::WriteEmpty);
FileFd CacheF(CacheFile,FileFd::WriteEmpty);
DynamicMMap Map(CacheF,MMap::Public);
if (_error->PendingError() == true)
return false;
-
+
pkgCacheGenerator Gen(Map,Progress);
-
- // Prepare the progress indicator
+ unsigned long CurrentSize = 0;
unsigned long TotalSize = 0;
- struct stat Buf;
- for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
- {
- string File = ListDir + URItoFileName(I->PackagesURI());
- if (stat(File.c_str(),&Buf) != 0)
- continue;
- TotalSize += Buf.st_size;
- }
-
- if (pkgAddSourcesSize(TotalSize) == false)
+ if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false)
return false;
- // Generate the pkg source cache
- unsigned long CurrentSize = 0;
- for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
- {
- // Only cache deb source types.
- if (I->Type != pkgSourceList::Item::Deb)
- continue;
-
- string File = ListDir + URItoFileName(I->PackagesURI());
-
- if (FileExists(File) == false)
- continue;
-
- FileFd Pkg(File,FileFd::ReadOnly);
- debListParser Parser(Pkg);
- Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists");
- if (_error->PendingError() == true)
- return _error->Error("Problem opening %s",File.c_str());
- CurrentSize += Pkg.Size();
-
- Progress.SubProgress(0,I->PackagesInfo());
- if (Gen.SelectFile(File) == false)
- return _error->Error("Problem with SelectFile %s",File.c_str());
-
- if (Gen.MergeList(Parser) == false)
- return _error->Error("Problem with MergeList %s",File.c_str());
-
- // Check the release file
- string RFile = ListDir + URItoFileName(I->ReleaseURI());
- if (FileExists(RFile) == true)
- {
- FileFd Rel(RFile,FileFd::ReadOnly);
- if (_error->PendingError() == true)
- return false;
- Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel);
- }
- }
-
// Write the src cache
Gen.GetCache().HeaderP->Dirty = false;
if (SCacheF.Write(Map.Data(),Map.Size()) == false)
@@ -736,3 +751,124 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress)
return pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize);
}
/*}}}*/
+// MakeStatusCacheMem - Returns a map for the status cache /*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a map object for the status cache. If the process has write
+ access to the caches then it is the same as MakeStatusCache, otherwise it
+ creates a memory block and puts the cache in there. */
+MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress)
+{
+ /* If the cache file is writeable this is just a wrapper for
+ MakeStatusCache */
+ string CacheFile = _config->FindFile("Dir::Cache::pkgcache");
+ bool Writeable = access(CacheFile.c_str(),W_OK) == 0;
+ if (Writeable == true)
+ {
+ if (pkgMakeStatusCache(List,Progress) == false)
+ return 0;
+
+ // Open the cache file
+ FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ return 0;
+
+ MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+ if (_error->PendingError() == true)
+ {
+ delete Map;
+ return 0;
+ }
+ return Map;
+ }
+
+ // Mostly from MakeStatusCache..
+ Progress.OverallProgress(0,1,1,"Reading Package Lists");
+
+ bool SrcOk = pkgSrcCacheCheck(List);
+ bool PkgOk = SrcOk && pkgPkgCacheCheck(CacheFile);
+
+ // Rebuild the source and package caches
+ if (SrcOk == false)
+ {
+ DynamicMMap *Map = new DynamicMMap(MMap::Public);
+ if (_error->PendingError() == true)
+ {
+ delete Map;
+ return 0;
+ }
+
+ pkgCacheGenerator Gen(*Map,Progress);
+ unsigned long CurrentSize = 0;
+ unsigned long TotalSize = 0;
+ if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ // Merge in the source caches
+ if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ return Map;
+ }
+
+ if (PkgOk == true)
+ {
+ Progress.OverallProgress(1,1,1,"Reading Package Lists");
+
+ // Open the cache file
+ FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ return 0;
+
+ MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+ if (_error->PendingError() == true)
+ {
+ delete Map;
+ return 0;
+ }
+ return Map;
+ }
+
+ // We use the source cache to generate the package cache
+ string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
+ FileFd SCacheF(SCacheFile,FileFd::ReadOnly);
+ DynamicMMap *Map = new DynamicMMap(MMap::Public);
+ if (_error->PendingError() == true)
+ {
+ delete Map;
+ return 0;
+ }
+
+ // Preload the map with the source cache
+ if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()),
+ SCacheF.Size()) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ pkgCacheGenerator Gen(*Map,Progress);
+
+ // Compute the progress
+ unsigned long TotalSize = 0;
+ if (pkgAddSourcesSize(TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ unsigned long CurrentSize = 0;
+ if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ return Map;
+}
+ /*}}}*/
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 8ffb277c6..66a991371 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcachegen.h,v 1.12 1999/02/23 06:46:24 jgg Exp $
+// $Id: pkgcachegen.h,v 1.13 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
@@ -28,6 +28,7 @@
class pkgSourceList;
class OpProgress;
+class MMap;
class pkgCacheGenerator
{
@@ -71,6 +72,7 @@ class pkgCacheGenerator
bool pkgSrcCacheCheck(pkgSourceList &List);
bool pkgPkgCacheCheck(string CacheFile);
bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress);
+MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress);
// This is the abstract package list parser class.
class pkgCacheGenerator::ListParser
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index a2c013206..07ba19f18 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: apt-get.cc,v 1.51 1999/04/12 02:25:25 jgg Exp $
+// $Id: apt-get.cc,v 1.52 1999/04/18 06:36:36 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
@@ -30,15 +30,14 @@
#include <apt-pkg/init.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/sourcelist.h>
-#include <apt-pkg/pkgcachegen.h>
#include <apt-pkg/algorithms.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/dpkgpm.h>
-#include <apt-pkg/dpkginit.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/clean.h>
#include <apt-pkg/srcrecords.h>
#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
#include <config.h>
@@ -372,70 +371,27 @@ void Stats(ostream &out,pkgDepCache &Dep)
// class CacheFile - Cover class for some dependency cache functions /*{{{*/
// ---------------------------------------------------------------------
/* */
-class CacheFile
+class CacheFile : public pkgCacheFile
{
public:
- FileFd *File;
- MMap *Map;
- pkgDepCache *Cache;
- pkgDpkgLock Lock;
-
- inline operator pkgDepCache &() {return *Cache;};
- inline pkgDepCache *operator ->() {return Cache;};
- inline pkgDepCache &operator *() {return *Cache;};
-
- bool Open(bool AllowBroken = false);
- CacheFile() : File(0), Map(0), Cache(0) {};
- ~CacheFile()
+ bool CheckDeps(bool AllowBroken = false);
+ bool Open(bool WithLock = true)
{
- delete Cache;
- delete Map;
- delete File;
- }
+ OpTextProgress Prog(*_config);
+ return pkgCacheFile::Open(Prog,WithLock);
+ };
};
/*}}}*/
// CacheFile::Open - Open the cache file /*{{{*/
// ---------------------------------------------------------------------
/* This routine generates the caches and then opens the dependency cache
and verifies that the system is OK. */
-bool CacheFile::Open(bool AllowBroken)
+bool CacheFile::CheckDeps(bool AllowBroken)
{
if (_error->PendingError() == true)
return false;
-
- // Create a progress class
- OpTextProgress Progress(*_config);
-
- // Read the source list
- pkgSourceList List;
- if (List.ReadMainList() == false)
- return _error->Error("The list of sources could not be read.");
-
- // Build all of the caches
- pkgMakeStatusCache(List,Progress);
- if (_error->PendingError() == true)
- return _error->Error("The package lists or status file could not be parsed or opened.");
- if (_error->empty() == false)
- _error->Warning("You may want to run apt-get update to correct theses missing files");
-
- Progress.Done();
-
- // Open the cache file
- File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
- if (_error->PendingError() == true)
- return false;
-
- Map = new MMap(*File,MMap::Public | MMap::ReadOnly);
- if (_error->PendingError() == true)
- return false;
-
- Cache = new pkgDepCache(*Map,Progress);
- if (_error->PendingError() == true)
- return false;
- Progress.Done();
-
// Check that the system is OK
if (Cache->DelCount() != 0 || Cache->InstCount() != 0)
return _error->Error("Internal Error, non-zero counts");
@@ -676,7 +632,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey =
return _error->Error("Aborting Install.");
}
- Cache.Lock.Close();
+ Cache.ReleaseLock();
return PM.DoInstall();
}
/*}}}*/
@@ -724,7 +680,7 @@ bool DoUpdate(CommandLine &)
// Prepare the cache.
CacheFile Cache;
- if (Cache.Open() == false)
+ if (Cache.Open() == false || Cache.CheckDeps() == false)
return false;
return true;
@@ -737,7 +693,7 @@ bool DoUpdate(CommandLine &)
bool DoUpgrade(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open() == false)
+ if (Cache.Open() == false || Cache.CheckDeps() == false)
return false;
// Do the upgrade
@@ -756,7 +712,7 @@ bool DoUpgrade(CommandLine &CmdL)
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open(CmdL.FileSize() != 1) == false)
+ if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false)
return false;
// Enter the special broken fixing mode if the user specified arguments
@@ -949,7 +905,7 @@ bool DoInstall(CommandLine &CmdL)
bool DoDistUpgrade(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open() == false)
+ if (Cache.Open() == false || Cache.CheckDeps() == false)
return false;
c0out << "Calculating Upgrade... " << flush;
@@ -971,7 +927,7 @@ bool DoDistUpgrade(CommandLine &CmdL)
bool DoDSelectUpgrade(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open() == false)
+ if (Cache.Open() == false || Cache.CheckDeps() == false)
return false;
// Install everything with the install flag set
@@ -1066,7 +1022,7 @@ class LogCleaner : public pkgArchiveCleaner
bool DoAutoClean(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open(true) == false)
+ if (Cache.Open() == false)
return false;
LogCleaner Cleaner;
@@ -1083,19 +1039,23 @@ bool DoCheck(CommandLine &CmdL)
{
CacheFile Cache;
Cache.Open();
+ Cache.CheckDeps();
return true;
}
/*}}}*/
// DoSource - Fetch a source archive /*{{{*/
// ---------------------------------------------------------------------
-/* */
+/* Fetch souce packages */
bool DoSource(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open(true) == false)
+ if (Cache.Open(false) == false)
return false;
+ if (CmdL.FileSize() <= 1)
+ return _error->Error("Must specify at least one package to fetch source for");
+
// Read the source list
pkgSourceList List;
if (List.ReadMainList() == false)