// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: packagemanager.cc,v 1.1 1998/07/07 04:17:01 jgg Exp $
+// $Id: packagemanager.cc,v 1.14 1999/02/21 08:38:53 jgg Exp $
/* ######################################################################
Package Manager - Abstacts the package manager
/*}}}*/
// Include Files /*{{{*/
#ifdef __GNUG__
-#pragma implementation "pkglib/packagemanager.h"
+#pragma implementation "apt-pkg/packagemanager.h"
#endif
-#include <pkglib/packagemanager.h>
-#include <pkglib/orderlist.h>
-#include <pkglib/depcache.h>
-#include <pkglib/sourcelist.h>
-#include <pkglib/aquire.h>
-#include <pkglib/controlcache.h>
-#include <pkglib/error.h>
-#include <options.h>
+#include <apt-pkg/packagemanager.h>
+#include <apt-pkg/orderlist.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/configuration.h>
/*}}}*/
// PM::PackageManager - Constructor /*{{{*/
{
FileNames = new string[Cache.Head().PackageCount];
List = 0;
+ Debug = _config->FindB("Debug::pkgPackageManager",false);
}
/*}}}*/
// PM::PackageManager - Destructor /*{{{*/
delete [] FileNames;
}
/*}}}*/
-// PM::GetArchives - Puts the install archives in the aquire list /*{{{*/
+// PM::GetArchives - Queue the archives for download /*{{{*/
// ---------------------------------------------------------------------
-/* The Source list is used to convert the packages to install into
- URNs which are then passed to Aquire to convert to FileNames. */
-bool pkgPackageManager::GetArchives(pkgSourceList &List,pkgAquire &Engine)
+/* */
+bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
+ pkgRecords *Recs)
{
- pkgControlCache CCache(Cache);
- if (_error->PendingError() == true)
+ if (CreateOrderList() == false)
return false;
+
+ if (List->OrderUnpack() == false)
+ return _error->Error("Internal ordering error");
- Engine.OutputDir(PKG_DEB_CA_ARCHIVES);
- pkgCache::PkgIterator I = Cache.PkgBegin();
- for (;I.end() != true; I++)
+ for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
{
- // Not interesting
- if ((Cache[I].InstallVer == (pkgCache::Version *)I.CurrentVer() &&
- I.State() != pkgCache::PkgIterator::NeedsUnpack) ||
- Cache[I].Delete() == true)
- continue;
-
- // Cross match with the source list.
- pkgSourceList::const_iterator Dist = List.MatchPkgFile(Cache[I].InstVerIter(Cache));
- if (Dist == List.end())
- {
- _error->Warning("Couldn't locate an archive source for package %s",I.Name());
- continue;
- }
+ PkgIterator Pkg(Cache,*I);
- // Read in the info record
- pkgSPkgCtrlInfo Inf = CCache[Cache[I].InstVerIter(Cache)];
- if (Inf.isNull() == true)
- {
- _error->Warning("Couldn't locate info for package %s",I.Name());
+ // Skip packages to erase
+ if (Cache[Pkg].Delete() == true)
continue;
- }
- // Isolate the filename
- string File = Inf->Find("Filename")->Value();
- if (File.empty() == true)
- {
- _error->Warning("Couldn't locate an archive for package %s",I.Name());
+ // Skip Packages that need configure only.
+ if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
+ Cache[Pkg].Keep() == true)
continue;
- }
-
- // Generate the get request.
- string URI = Dist->ArchiveURI(File);
-
- // Output file
- unsigned int Pos = File.rfind('/');
- if (Pos == File.length())
- return _error->Error("Malformed file line in package %s",I.Name());
-
- // Null pos isnt used in present package files
- if (Pos == string::npos)
- Pos = 0;
- else
- Pos++;
- if (Engine.Get(URI,string(File,Pos),
- Dist->ArchiveInfo(Cache[I].InstVerIter(Cache)),
- Cache[I].InstVerIter(Cache)->Size,
- Inf->Find("MD5sum")->Value(),
- &FileNames[I->ID]) == false)
- return false;
+ new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
+ FileNames[Pkg->ID]);
}
return true;
be downloaded. */
bool pkgPackageManager::FixMissing()
{
- unsigned char *Touch = new unsigned char[Cache.Head().PackageCount];
+ pkgProblemResolver Resolve(Cache);
+
+ bool Bad = false;
for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
- // Create the status list that ResolveConflicts needs
- if ((Cache[I].DepState & pkgDepCache::DepNowMin) == pkgDepCache::DepNowMin)
- Touch[I->ID] = (1 << 0) | (1 << 1);
- else
- Touch[I->ID] = 1 << 1;
-
+ // These don't need files
if (Cache[I].Keep() == true)
continue;
- if (FileNames[I->ID].empty() == false || Cache[I].Delete() == true)
+ if (Cache[I].Delete() == true)
+ continue;
+
+ // We have a filename
+ if (FileNames[I->ID].empty() == false)
+ continue;
+
+ // Skip Packages that need configure only.
+ if (I.State() == pkgCache::PkgIterator::NeedsConfigure &&
+ Cache[I].Keep() == true)
continue;
+
+ // Okay, this file is missing and we need it. Mark it for keep
+ Bad = true;
Cache.MarkKeep(I);
}
+ if (Bad == false)
+ return true;
+
// Now downgrade everything that is broken
- Cache.ResolveConflicts(Touch);
- delete [] Touch;
-
- return Cache.BrokenCount() == 0;
+ return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
}
/*}}}*/
+// PM::CreateOrderList - Create the ordering class /*{{{*/
+// ---------------------------------------------------------------------
+/* This populates the ordering list with all the packages that are
+ going to change. */
+bool pkgPackageManager::CreateOrderList()
+{
+ delete List;
+ List = new pkgOrderList(Cache);
+
+ bool NoImmConfigure = _config->FindB("APT::Immediate-Configure",false);
+
+ // Generate the list of affected packages and sort it
+ for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ // Mark the package and its dependends for immediate configuration
+ if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
+ (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) &&
+ NoImmConfigure == false)
+ {
+ 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++)
+ if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
+ List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
+ }
+
+ // Not interesting
+ if ((Cache[I].Keep() == true ||
+ Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
+ I.State() == pkgCache::PkgIterator::NeedsNothing)
+ continue;
+
+ // Append it to the list
+ List->push_back(I);
+ }
+
+ return true;
+}
+ /*}}}*/
// PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
// ---------------------------------------------------------------------
/* The restriction on provides is to eliminate the case when provides
{
for (;D.end() == false; D++)
{
- if (D->Type != pkgDEP_Conflicts)
+ if (D->Type != pkgCache::Dep::Conflicts)
continue;
if (D.ParentPkg() == Pkg)
bool Bad = false;
for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
{
- if (D->Type != pkgDEP_Depends && D->Type != pkgDEP_PreDepends)
+ if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
{
D++;
continue;
Bad = true;
for (bool LastOR = true; D.end() == false && LastOR == true; D++)
{
- LastOR = (D->CompareOp & pkgOP_OR) == pkgOP_OR;
+ LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
if (Bad == false)
continue;
return _error->Error("Internal Error, Could not perform immediate configuraton");
return true;
}
-
+
/* See if this packages install version has any predependencies
that are not met by 'now' packages. */
for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
D.end() == false; D++)
{
- if (D->Type == pkgDEP_PreDepends)
+ if (D->Type == pkgCache::Dep::PreDepends)
{
// Look for possible ok targets.
Version **VList = D.AllTargets();
continue;
}
- if (D->Type == pkgDEP_Conflicts)
+ if (D->Type == pkgCache::Dep::Conflicts)
{
/* Look for conflicts. Two packages that are both in the install
state cannot conflict so we don't check.. */
/* */
bool pkgPackageManager::OrderInstall()
{
- delete List;
- List = new pkgOrderList(Cache);
+ if (CreateOrderList() == false)
+ return false;
- // Generate the list of affected packages and sort it
- for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
- {
- // Consider all depends
- if ((I->Flags & pkgFLAG_Essential) == pkgFLAG_Essential)
- {
- List->Flag(I,pkgOrderList::Immediate);
- if (Cache[I].InstallVer != 0)
- for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
- D.end() == false; D++)
- if (D->Type == pkgDEP_Depends || D->Type == pkgDEP_PreDepends)
- List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
- if (I->CurrentVer != 0)
- for (DepIterator D = I.CurrentVer().DependsList();
- D.end() == false; D++)
- if (D->Type == pkgDEP_Depends || D->Type == pkgDEP_PreDepends)
- List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
- }
-
- // Not interesting
- if ((Cache[I].Keep() == true ||
- Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
- I.State() == pkgCache::PkgIterator::NeedsNothing)
- continue;
-
- // Append it to the list
- List->push_back(I);
-
- if ((I->Flags & pkgFLAG_ImmediateConf) == pkgFLAG_ImmediateConf)
- List->Flag(I,pkgOrderList::Immediate);
- }
+ if (Debug == true)
+ clog << "Begining to order" << endl;
if (List->OrderUnpack() == false)
return _error->Error("Internal ordering error");
+ if (Debug == true)
+ clog << "Done ordering" << endl;
+
for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
{
PkgIterator Pkg(Cache,*I);