- // Quickly check if the existing package cache is ok
- bool Bad = false;
- while (Bad == false)
- {
- if (FileExists(PKG_DEB_CA_PKGCACHE) == false)
- break;
-
- /* We check the dates of the two caches. This takes care of most things
- quickly and easially */
- struct stat Src;
- struct stat Pkg;
- if (stat(PKG_DEB_CA_PKGCACHE,&Pkg) != 0 ||
- stat(PKG_DEB_CA_SRCCACHE,&Src) != 0)
- break;
- if (difftime(Src.st_mtime,Pkg.st_mtime) > 0)
- break;
-
- pkgCache Cache(PKG_DEB_CA_PKGCACHE,true,true);
- if (_error->PendingError() == true)
- {
- _error->Discard();
- break;
- }
-
- for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
- {
- if (F.IsOk() == false)
- {
- Bad = true;
- break;
- }
- }
-
- if (Bad == false)
- return true;
- }
-
- // Check the integrity of the source cache.
- {
- pkgCache Cache(PKG_DEB_CA_SRCCACHE,true,true);
- if (_error->PendingError() == true)
- return false;
- }
-
- // Sub scope so that merge destructs before we rename the file...
- string Cache = PKG_DEB_CA_PKGCACHE ".new";
- {
- if (CopyFile(PKG_DEB_CA_SRCCACHE,Cache) == false)
- return false;
-
- pkgCache::MergeState Merge(Cache);
- if (_error->PendingError() == true)
- return false;
-
- // Merge in the user status file
- if (FileExists(PKG_DEB_ST_USERSTATUS) == true)
- if (Merge.MergePackageFile(PKG_DEB_ST_USERSTATUS,"status","0",
- pkgFLAG_NotSource) == false)
- return false;
-
- // Merge in the extra status file
- if (FileExists(PKG_DEB_ST_XSTATUS) == true)
- if (Merge.MergePackageFile(PKG_DEB_ST_XSTATUS,"status","0",
- pkgFLAG_NotSource) == false)
- return false;
-
- // Merge in the status file
- if (Merge.MergePackageFile("/var/lib/dpkg/status","status","0",
- pkgFLAG_NotSource) == false)
- return false;
- }
-
- if (rename(Cache.c_str(),PKG_DEB_CA_PKGCACHE) != 0)
- return false;
-
- return true;