]>
git.saurik.com Git - apt.git/blob - apt-pkg/packagemanager.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: packagemanager.cc,v 1.5 1998/11/13 04:23:30 jgg Exp $
4 /* ######################################################################
6 Package Manager - Abstacts the package manager
8 More work is needed in the area of transitioning provides, ie exim
9 replacing smail. This can cause interesing side effects.
11 Other cases involving conflicts+replaces should be tested.
13 ##################################################################### */
15 // Include Files /*{{{*/
17 #pragma implementation "apt-pkg/packagemanager.h"
19 #include <apt-pkg/packagemanager.h>
20 #include <apt-pkg/orderlist.h>
21 #include <apt-pkg/depcache.h>
22 #include <apt-pkg/error.h>
23 #include <apt-pkg/version.h>
24 #include <apt-pkg/acquire-item.h>
27 // PM::PackageManager - Constructor /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgPackageManager::pkgPackageManager(pkgDepCache
&Cache
) : Cache(Cache
)
32 FileNames
= new string
[Cache
.Head().PackageCount
];
36 // PM::PackageManager - Destructor /*{{{*/
37 // ---------------------------------------------------------------------
39 pkgPackageManager::~pkgPackageManager()
45 // PM::GetArchives - Queue the archives for download /*{{{*/
46 // ---------------------------------------------------------------------
48 bool pkgPackageManager::GetArchives(pkgAcquire
*Owner
,pkgSourceList
*Sources
,
51 pkgCache::PkgIterator I
= Cache
.PkgBegin();
52 for (;I
.end() != true; I
++)
55 if ((Cache
[I
].InstallVer
== (pkgCache::Version
*)I
.CurrentVer() &&
56 I
.State() != pkgCache::PkgIterator::NeedsUnpack
) ||
57 Cache
[I
].Delete() == true)
60 new pkgAcqArchive(Owner
,Sources
,Recs
,Cache
[I
].InstVerIter(Cache
));
65 // PM::FixMissing - Keep all missing packages /*{{{*/
66 // ---------------------------------------------------------------------
67 /* This is called to correct the installation when packages could not
69 bool pkgPackageManager::FixMissing()
71 unsigned char *Touch
= new unsigned char[Cache
.Head().PackageCount
];
72 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
74 // Create the status list that ResolveConflicts needs
75 if ((Cache
[I
].DepState
& pkgDepCache::DepNowMin
) == pkgDepCache::DepNowMin
)
76 Touch
[I
->ID
] = (1 << 0) | (1 << 1);
78 Touch
[I
->ID
] = 1 << 1;
80 if (Cache
[I
].Keep() == true)
82 if (FileNames
[I
->ID
].empty() == false || Cache
[I
].Delete() == true)
87 // Now downgrade everything that is broken
88 // Cache.ResolveConflicts(Touch);
91 return Cache
.BrokenCount() == 0;
95 // PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
96 // ---------------------------------------------------------------------
97 /* The restriction on provides is to eliminate the case when provides
98 are transitioning between valid states [ie exim to smail] */
99 bool pkgPackageManager::DepAlwaysTrue(DepIterator D
)
101 if (D
.TargetPkg()->ProvidesList
!= 0)
104 if ((Cache
[D
] & pkgDepCache::DepInstall
) != 0 &&
105 (Cache
[D
] & pkgDepCache::DepNow
) != 0)
110 // PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
111 // ---------------------------------------------------------------------
112 /* This looks over the reverses for a conflicts line that needs early
114 bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg
,DepIterator D
,
117 for (;D
.end() == false; D
++)
119 if (D
->Type
!= pkgCache::Dep::Conflicts
)
122 if (D
.ParentPkg() == Pkg
)
125 if (pkgCheckDep(D
.TargetVer(),Ver
,D
->CompareOp
) == false)
128 if (List
->IsNow(Pkg
) == false)
131 if (EarlyRemove(D
.ParentPkg()) == false)
137 // PM::ConfigureAll - Run the all out configuration /*{{{*/
138 // ---------------------------------------------------------------------
139 /* This configures every package. It is assumed they are all unpacked and
140 that the final configuration is valid. */
141 bool pkgPackageManager::ConfigureAll()
143 pkgOrderList
OList(Cache
);
145 // Populate the order list
146 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
147 if (List
->IsFlag(pkgCache::PkgIterator(Cache
,*I
),
148 pkgOrderList::UnPacked
) == true)
151 if (OList
.OrderConfigure() == false)
154 // Perform the configuring
155 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); I
++)
157 PkgIterator
Pkg(Cache
,*I
);
159 if (Configure(Pkg
) == false)
162 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
168 // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
169 // ---------------------------------------------------------------------
170 /* This routine scheduals the configuration of the given package and all
171 of it's dependents. */
172 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg
)
174 pkgOrderList
OList(Cache
);
176 if (DepAdd(OList
,Pkg
) == false)
179 if (OList
.OrderConfigure() == false)
182 // Perform the configuring
183 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); I
++)
185 PkgIterator
Pkg(Cache
,*I
);
187 if (Configure(Pkg
) == false)
190 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
194 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == false)
195 return _error
->Error("Internal error, could not immediate configure %s",Pkg
.Name());
200 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
201 // ---------------------------------------------------------------------
202 /* This recursively adds all dependents to the order list */
203 bool pkgPackageManager::DepAdd(pkgOrderList
&OList
,PkgIterator Pkg
,int Depth
)
205 if (OList
.IsFlag(Pkg
,pkgOrderList::Added
) == true)
207 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
209 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == false)
213 // Put the package on the list
214 OList
.push_back(Pkg
);
215 OList
.Flag(Pkg
,pkgOrderList::Added
);
218 // Check the dependencies to see if they are all satisfied.
220 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
222 if (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
)
230 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
232 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
237 Version
**VList
= D
.AllTargets();
238 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
240 VerIterator
Ver(Cache
,*I
);
241 PkgIterator Pkg
= Ver
.ParentPkg();
243 // See if the current version is ok
244 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
245 Pkg
.State() == PkgIterator::NeedsNothing
)
251 // Not the install version
252 if (Cache
[Pkg
].InstallVer
!= *I
||
253 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
255 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == true)
256 Bad
= !DepAdd(OList
,Pkg
,Depth
);
257 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
265 OList
.Flag(Pkg
,0,pkgOrderList::Added
);
276 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
277 // ---------------------------------------------------------------------
278 /* This is called to deal with conflicts arising from unpacking */
279 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg
)
281 if (List
->IsNow(Pkg
) == false)
284 // Already removed it
285 if (List
->IsFlag(Pkg
,pkgOrderList::Removed
) == true)
288 // Woops, it will not be re-installed!
289 if (List
->IsFlag(Pkg
,pkgOrderList::InList
) == false)
292 bool Res
= SmartRemove(Pkg
);
293 if (Cache
[Pkg
].Delete() == false)
294 List
->Flag(Pkg
,pkgOrderList::Removed
,pkgOrderList::States
);
299 // PM::SmartRemove - Removal Helper /*{{{*/
300 // ---------------------------------------------------------------------
302 bool pkgPackageManager::SmartRemove(PkgIterator Pkg
)
304 if (List
->IsNow(Pkg
) == false)
307 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
311 // PM::SmartUnPack - Install helper /*{{{*/
312 // ---------------------------------------------------------------------
313 /* This performs the task of handling pre-depends. */
314 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg
)
316 // Check if it is already unpacked
317 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
318 Cache
[Pkg
].Keep() == true)
320 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
321 if (List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
322 if (SmartConfigure(Pkg
) == false)
323 return _error
->Error("Internal Error, Could not perform immediate configuraton");
327 /* See if this packages install version has any predependencies
328 that are not met by 'now' packages. */
329 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
330 D
.end() == false; D
++)
332 if (D
->Type
== pkgCache::Dep::PreDepends
)
334 // Look for possible ok targets.
335 Version
**VList
= D
.AllTargets();
337 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
339 VerIterator
Ver(Cache
,*I
);
340 PkgIterator Pkg
= Ver
.ParentPkg();
342 // See if the current version is ok
343 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
344 Pkg
.State() == PkgIterator::NeedsNothing
)
351 // Look for something that could be configured.
352 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
354 VerIterator
Ver(Cache
,*I
);
355 PkgIterator Pkg
= Ver
.ParentPkg();
357 // Not the install version
358 if (Cache
[Pkg
].InstallVer
!= *I
||
359 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
362 Bad
= !SmartConfigure(Pkg
);
368 return _error
->Error("Internal Error, Couldn't configure a pre-depend");
373 if (D
->Type
== pkgCache::Dep::Conflicts
)
375 /* Look for conflicts. Two packages that are both in the install
376 state cannot conflict so we don't check.. */
377 Version
**VList
= D
.AllTargets();
378 for (Version
**I
= VList
; *I
!= 0; I
++)
380 VerIterator
Ver(Cache
,*I
);
381 PkgIterator Pkg
= Ver
.ParentPkg();
383 // See if the current version is conflicting
384 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true)
386 if (EarlyRemove(Pkg
) == false)
387 return _error
->Error("Internal Error, Could not early remove %s",Pkg
.Name());
394 // Check for reverse conflicts.
395 CheckRConflicts(Pkg
,Pkg
.RevDependsList(),
396 Cache
[Pkg
].InstVerIter(Cache
).VerStr());
397 for (PrvIterator P
= Cache
[Pkg
].InstVerIter(Cache
).ProvidesList();
398 P
.end() == false; P
++)
399 CheckRConflicts(Pkg
,P
.ParentPkg().RevDependsList(),P
.ProvideVersion());
401 if (Install(Pkg
,FileNames
[Pkg
->ID
]) == false)
404 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
406 // Perform immedate configuration of the package.
407 if (List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
408 if (SmartConfigure(Pkg
) == false)
409 return _error
->Error("Internal Error, Could not perform immediate configuraton");
414 // PM::OrderInstall - Installation ordering routine /*{{{*/
415 // ---------------------------------------------------------------------
417 bool pkgPackageManager::OrderInstall()
420 List
= new pkgOrderList(Cache
);
422 // Generate the list of affected packages and sort it
423 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
425 // Consider all depends
426 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
428 List
->Flag(I
,pkgOrderList::Immediate
);
429 if (Cache
[I
].InstallVer
!= 0)
430 for (DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
431 D
.end() == false; D
++)
432 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
433 List
->Flag(D
.TargetPkg(),pkgOrderList::Immediate
);
434 if (I
->CurrentVer
!= 0)
435 for (DepIterator D
= I
.CurrentVer().DependsList();
436 D
.end() == false; D
++)
437 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
438 List
->Flag(D
.TargetPkg(),pkgOrderList::Immediate
);
442 if ((Cache
[I
].Keep() == true ||
443 Cache
[I
].InstVerIter(Cache
) == I
.CurrentVer()) &&
444 I
.State() == pkgCache::PkgIterator::NeedsNothing
)
447 // Append it to the list
450 if ((I
->Flags
& pkgCache::Flag::ImmediateConf
) == pkgCache::Flag::ImmediateConf
)
451 List
->Flag(I
,pkgOrderList::Immediate
);
454 if (List
->OrderUnpack() == false)
455 return _error
->Error("Internal ordering error");
457 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
459 PkgIterator
Pkg(Cache
,*I
);
462 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
)
463 return _error
->Error("Internal Error, trying to manipulate a kept package");
465 // Perform a delete or an install
466 if (Cache
[Pkg
].Delete() == true)
468 if (SmartRemove(Pkg
) == false)
472 if (SmartUnPack(Pkg
) == false)
476 // Final run through the configure phase
477 if (ConfigureAll() == false)
481 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
482 if (List
->IsFlag(*I
,pkgOrderList::Configured
) == false)
483 return _error
->Error("Internal error, packages left unconfigured. %s",
484 PkgIterator(Cache
,*I
).Name());
489 // PM::DoInstall - Does the installation /*{{{*/
490 // ---------------------------------------------------------------------
491 /* This uses the filenames in FileNames and the information in the
492 DepCache to perform the installation of packages.*/
493 bool pkgPackageManager::DoInstall()
495 return OrderInstall() && Go();