+// 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)
+{
+ unsigned long MapSize = _config->FindI("APT::Cache-Limit",4*1024*1024);
+
+ /* 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) ||
+ (errno == ENOENT);
+
+ 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,MapSize);
+ 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,MapSize);
+ 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 (pkgAddStatusSize(TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ unsigned long CurrentSize = 0;
+ if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false)
+ {
+ delete Map;
+ return 0;
+ }
+
+ return Map;
+}
+ /*}}}*/