]> git.saurik.com Git - apt.git/blame - apt-pkg/packagemanager.cc
Added a APT::Immediate-Configure-All option to enable imediate configuration for...
[apt.git] / apt-pkg / packagemanager.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b9c0654c 3// $Id: packagemanager.cc,v 1.30 2003/04/27 03:04:15 doogie Exp $
6c139d6e
AL
4/* ######################################################################
5
6 Package Manager - Abstacts the package manager
7
8 More work is needed in the area of transitioning provides, ie exim
9 replacing smail. This can cause interesing side effects.
10
11 Other cases involving conflicts+replaces should be tested.
12
13 ##################################################################### */
14 /*}}}*/
15// Include Files /*{{{*/
094a497d
AL
16#include <apt-pkg/packagemanager.h>
17#include <apt-pkg/orderlist.h>
18#include <apt-pkg/depcache.h>
19#include <apt-pkg/error.h>
20#include <apt-pkg/version.h>
03e39e59 21#include <apt-pkg/acquire-item.h>
30e1eab5
AL
22#include <apt-pkg/algorithms.h>
23#include <apt-pkg/configuration.h>
b2e465d6
AL
24#include <apt-pkg/sptr.h>
25
26#include <apti18n.h>
5819a761 27#include <iostream>
1d6386f3 28#include <fcntl.h>
92fcbfc1 29 /*}}}*/
5819a761
AL
30using namespace std;
31
6c139d6e
AL
32// PM::PackageManager - Constructor /*{{{*/
33// ---------------------------------------------------------------------
34/* */
b2e465d6 35pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache)
6c139d6e
AL
36{
37 FileNames = new string[Cache.Head().PackageCount];
38 List = 0;
30e1eab5 39 Debug = _config->FindB("Debug::pkgPackageManager",false);
6c139d6e
AL
40}
41 /*}}}*/
42// PM::PackageManager - Destructor /*{{{*/
43// ---------------------------------------------------------------------
44/* */
45pkgPackageManager::~pkgPackageManager()
46{
47 delete List;
48 delete [] FileNames;
49}
50 /*}}}*/
03e39e59
AL
51// PM::GetArchives - Queue the archives for download /*{{{*/
52// ---------------------------------------------------------------------
53/* */
54bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
55 pkgRecords *Recs)
56{
7a1b1f8b
AL
57 if (CreateOrderList() == false)
58 return false;
59
5e312de7
DK
60 bool const ordering =
61 _config->FindB("PackageManager::UnpackAll",true) ?
62 List->OrderUnpack() : List->OrderCritical();
63 if (ordering == false)
7a1b1f8b
AL
64 return _error->Error("Internal ordering error");
65
66 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
67 {
68 PkgIterator Pkg(Cache,*I);
281daf46
AL
69 FileNames[Pkg->ID] = string();
70
7a1b1f8b
AL
71 // Skip packages to erase
72 if (Cache[Pkg].Delete() == true)
03e39e59 73 continue;
d38b7b3d
AL
74
75 // Skip Packages that need configure only.
9dbb421f
AL
76 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
77 Cache[Pkg].Keep() == true)
d38b7b3d 78 continue;
281daf46
AL
79
80 // Skip already processed packages
81 if (List->IsNow(Pkg) == false)
82 continue;
803ea2a8 83
7a1b1f8b
AL
84 new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
85 FileNames[Pkg->ID]);
03e39e59 86 }
7a1b1f8b 87
03e39e59
AL
88 return true;
89}
90 /*}}}*/
6c139d6e
AL
91// PM::FixMissing - Keep all missing packages /*{{{*/
92// ---------------------------------------------------------------------
93/* This is called to correct the installation when packages could not
94 be downloaded. */
95bool pkgPackageManager::FixMissing()
bdae53f1 96{
e6756cde 97 pkgDepCache::ActionGroup group(Cache);
b2e465d6 98 pkgProblemResolver Resolve(&Cache);
2fd65468 99 List->SetFileList(FileNames);
e6756cde 100
9dbb421f 101 bool Bad = false;
6c139d6e
AL
102 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
103 {
2fd65468 104 if (List->IsMissing(I) == false)
9dbb421f 105 continue;
2fd65468 106
9dbb421f
AL
107 // Okay, this file is missing and we need it. Mark it for keep
108 Bad = true;
74a05226 109 Cache.MarkKeep(I, false, false);
6c139d6e 110 }
bdae53f1
AL
111
112 // We have to empty the list otherwise it will not have the new changes
113 delete List;
114 List = 0;
6c139d6e 115
9dbb421f
AL
116 if (Bad == false)
117 return true;
118
6c139d6e 119 // Now downgrade everything that is broken
30e1eab5 120 return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
6c139d6e
AL
121}
122 /*}}}*/
3a6d37fd
MV
123// PM::ImmediateAdd - Add the immediate flag recursivly /*{{{*/
124// ---------------------------------------------------------------------
125/* This adds the immediate flag to the pkg and recursively to the
126 dependendies
127 */
d183f850 128void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned const int &Depth)
3a6d37fd
MV
129{
130 DepIterator D;
131
132 if(UseInstallVer)
133 {
134 if(Cache[I].InstallVer == 0)
135 return;
136 D = Cache[I].InstVerIter(Cache).DependsList();
137 } else {
138 if (I->CurrentVer == 0)
139 return;
140 D = I.CurrentVer().DependsList();
141 }
142
143 for ( /* nothing */ ; D.end() == false; D++)
144 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
145 {
146 if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
147 {
148 if(Debug)
d183f850 149 clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl;
3a6d37fd 150 List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
d183f850 151 ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
3a6d37fd
MV
152 }
153 }
154 return;
155}
156 /*}}}*/
7a1b1f8b
AL
157// PM::CreateOrderList - Create the ordering class /*{{{*/
158// ---------------------------------------------------------------------
159/* This populates the ordering list with all the packages that are
160 going to change. */
161bool pkgPackageManager::CreateOrderList()
162{
281daf46
AL
163 if (List != 0)
164 return true;
165
7a1b1f8b 166 delete List;
b2e465d6 167 List = new pkgOrderList(&Cache);
7a1b1f8b 168
5e312de7 169 static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
a6c8798a
CB
170 ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",true);
171
172 if (Debug && ImmConfigureAll)
173 clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl;
079cc404 174
7a1b1f8b
AL
175 // Generate the list of affected packages and sort it
176 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
177 {
e7b470ee
AL
178 // Ignore no-version packages
179 if (I->VersionList == 0)
180 continue;
181
138d4b3d 182 // Mark the package and its dependends for immediate configuration
a6c8798a 183 if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
138d4b3d 184 (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) &&
a6c8798a 185 NoImmConfigure == false) || ImmConfigureAll)
7a1b1f8b 186 {
a6c8798a 187 if(Debug && !ImmConfigureAll)
3a6d37fd 188 clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl;
7a1b1f8b 189 List->Flag(I,pkgOrderList::Immediate);
a6c8798a
CB
190
191 if (!ImmConfigureAll) {
192 continue;
3a6d37fd 193
a6c8798a
CB
194 // Look for other install packages to make immediate configurea
195 ImmediateAdd(I, true);
d38b7b3d 196
a6c8798a
CB
197 // And again with the current version.
198 ImmediateAdd(I, false);
199 }
7a1b1f8b
AL
200 }
201
202 // Not interesting
203 if ((Cache[I].Keep() == true ||
204 Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
d556d1a1 205 I.State() == pkgCache::PkgIterator::NeedsNothing &&
d0c59649 206 (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
d556d1a1
AL
207 (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
208 (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
7a1b1f8b
AL
209 continue;
210
211 // Append it to the list
138d4b3d 212 List->push_back(I);
7a1b1f8b
AL
213 }
214
215 return true;
216}
217 /*}}}*/
6c139d6e
AL
218// PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
219// ---------------------------------------------------------------------
220/* The restriction on provides is to eliminate the case when provides
221 are transitioning between valid states [ie exim to smail] */
222bool pkgPackageManager::DepAlwaysTrue(DepIterator D)
223{
224 if (D.TargetPkg()->ProvidesList != 0)
225 return false;
226
227 if ((Cache[D] & pkgDepCache::DepInstall) != 0 &&
228 (Cache[D] & pkgDepCache::DepNow) != 0)
229 return true;
230 return false;
231}
232 /*}}}*/
233// PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
234// ---------------------------------------------------------------------
235/* This looks over the reverses for a conflicts line that needs early
236 removal. */
237bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
238 const char *Ver)
239{
240 for (;D.end() == false; D++)
241 {
b2e465d6
AL
242 if (D->Type != pkgCache::Dep::Conflicts &&
243 D->Type != pkgCache::Dep::Obsoletes)
6c139d6e 244 continue;
5af32db6
AL
245
246 // The package hasnt been changed
247 if (List->IsNow(Pkg) == false)
248 continue;
6c139d6e 249
5af32db6
AL
250 // Ignore self conflicts, ignore conflicts from irrelevent versions
251 if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
6c139d6e
AL
252 continue;
253
b2e465d6 254 if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
6c139d6e 255 continue;
b2e465d6 256
6c139d6e 257 if (EarlyRemove(D.ParentPkg()) == false)
5af32db6
AL
258 return _error->Error("Reverse conflicts early remove for package '%s' failed",
259 Pkg.Name());
260 }
6c139d6e
AL
261 return true;
262}
263 /*}}}*/
264// PM::ConfigureAll - Run the all out configuration /*{{{*/
265// ---------------------------------------------------------------------
266/* This configures every package. It is assumed they are all unpacked and
267 that the final configuration is valid. */
268bool pkgPackageManager::ConfigureAll()
269{
b2e465d6 270 pkgOrderList OList(&Cache);
6c139d6e
AL
271
272 // Populate the order list
273 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
274 if (List->IsFlag(pkgCache::PkgIterator(Cache,*I),
275 pkgOrderList::UnPacked) == true)
276 OList.push_back(*I);
277
278 if (OList.OrderConfigure() == false)
279 return false;
5e312de7
DK
280
281 std::string const conf = _config->Find("PackageManager::Configure","all");
282 bool const ConfigurePkgs = (conf == "all");
283
6c139d6e
AL
284 // Perform the configuring
285 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
286 {
287 PkgIterator Pkg(Cache,*I);
803ea2a8 288
4e9ccfb2 289 if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false)
6c139d6e
AL
290 return false;
291
292 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
293 }
294
295 return true;
296}
297 /*}}}*/
298// PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
299// ---------------------------------------------------------------------
300/* This routine scheduals the configuration of the given package and all
301 of it's dependents. */
302bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
303{
0eacf067
MV
304 if (Debug == true)
305 clog << "SmartConfigure " << Pkg.Name() << endl;
306
b2e465d6 307 pkgOrderList OList(&Cache);
6c139d6e
AL
308
309 if (DepAdd(OList,Pkg) == false)
310 return false;
5e312de7
DK
311
312 static std::string const conf = _config->Find("PackageManager::Configure","all");
313 static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
314
315 if (ConfigurePkgs == true)
316 if (OList.OrderConfigure() == false)
317 return false;
318
6c139d6e
AL
319 // Perform the configuring
320 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
321 {
322 PkgIterator Pkg(Cache,*I);
323
4e9ccfb2 324 if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false)
6c139d6e
AL
325 return false;
326
327 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
328 }
329
d77b985a
DK
330 if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same)
331 for (PkgIterator P = Pkg.Group().PackageList();
332 P.end() == false; P = Pkg.Group().NextPkg(P))
333 {
334 if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true ||
335 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
336 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
337 continue;
338 SmartConfigure(P);
339 }
340
6c139d6e
AL
341 // Sanity Check
342 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
be2db981 343 return _error->Error(_("Could not perform immediate configuration on '%s'. "
20382bad
DK
344 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
345
6c139d6e 346 return true;
4264ebeb
CB
347}
348
349// PM::VerifyConfigure - Check configuration of dependancies /*{{{*/
350// ---------------------------------------------------------------------
351/* This routine checks that all a packages dependancies have been
352 configured, before it is going to be configured. If this gives a warning
353 on a virtual package, it means that the package thats providing it is not
354 configured*/
355bool pkgPackageManager::VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList)
356{
357 // If this is true at the end, then the package should not be configured
358 bool error=true;
359 // This holds the the OR status of the previous dependancy
360 bool previousOr=false;
361
362 // First iterate through the dependancies of Pkg
363 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++)
364 {
365
366 /* If the dependancy is of type Depends or PreDepends, we need to check it, but only if it is going to be
367 configured at some point */
368 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) {
369
370 /* If the previous package and this package are OR dependancies, and the previous package satisfied the dependancy
371 then skip this dependancy as it is not relevent, this will repeat for the next package if the situation is the
372 same */
373 if (previousOr && !error) { // As error has not been reset, this refers to the previous dependancy
374 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
375 continue;
376 }
377
378 // Reset error
379 error = true;
380
381 // Check thorugh all possible versions of this dependancy (D)
382 SPtrArray<Version *> VList = D.AllTargets();
383 for (Version **I = VList; *I != 0; I++)
384 {
385 VerIterator DepVer(Cache,*I);
386 PkgIterator DepPkg = DepVer.ParentPkg();
387 VerIterator DepInstallVer(Cache,Cache[DepPkg].InstallVer);
388
389 if (DepPkg.CurrentVer() == DepVer && !List->IsFlag(DepPkg,pkgOrderList::UnPacked)) {
4264ebeb
CB
390 error=false;
391 break;
392 }
393
394 if (Cache[DepPkg].InstallVer == DepVer &&
395 (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) {
4264ebeb
CB
396 error=false;
397 break;
398 }
399 }
400
401 /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR
402 the next one might */
403 if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
404 _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name());
405 return false;
406 /* If the previous package is a OR but not this package, but there is still an error then fail as it will not
407 be satisfied */
408 } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
409 _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name());
410 return false;
411 }
412
413 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
414 } else {
415 previousOr=false;
416 }
417 }
418 return true;
419}
420
421// PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/
422// ---------------------------------------------------------------------
423/* This routine verifies if a package can be configured and if so
424 configures it */
425bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList)
426{
4e9ccfb2 427 if (VerifyConfigure(Pkg, OList))
4264ebeb
CB
428 return Configure(Pkg);
429 else
430 return false;
431
6c139d6e
AL
432}
433 /*}}}*/
434// PM::DepAdd - Add all dependents to the oder list /*{{{*/
435// ---------------------------------------------------------------------
436/* This recursively adds all dependents to the order list */
437bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth)
438{
439 if (OList.IsFlag(Pkg,pkgOrderList::Added) == true)
440 return true;
441 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
442 return true;
443 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
444 return false;
131418cf
MV
445
446 if (Debug)
447 std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl;
b2e465d6 448
6c139d6e
AL
449 // Put the package on the list
450 OList.push_back(Pkg);
451 OList.Flag(Pkg,pkgOrderList::Added);
452 Depth++;
453
454 // Check the dependencies to see if they are all satisfied.
455 bool Bad = false;
456 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
457 {
b50b2c97 458 if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
6c139d6e
AL
459 {
460 D++;
461 continue;
462 }
463
464 // Grok or groups
465 Bad = true;
466 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
467 {
b50b2c97 468 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
6c139d6e
AL
469
470 if (Bad == false)
471 continue;
472
b2e465d6 473 SPtrArray<Version *> VList = D.AllTargets();
6c139d6e
AL
474 for (Version **I = VList; *I != 0 && Bad == true; I++)
475 {
476 VerIterator Ver(Cache,*I);
477 PkgIterator Pkg = Ver.ParentPkg();
a6c8798a
CB
478 VerIterator InstallVer(Cache,Cache[Pkg].InstallVer);
479
480 if (Debug) {
481 if (Ver==0) {
482 cout << OutputInDepth(Depth) << "Checking if the dependancy on " << Ver << " of " << Pkg.Name() << " is satisfied" << endl;
483 } else {
484 cout << OutputInDepth(Depth) << "Checking if the dependancy on " << Ver.VerStr() << " of " << Pkg.Name() << " is satisfied" << endl;
485 }
486 }
487 if (Debug) {
488 if (Pkg.CurrentVer()==0) {
489 cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl;
490 } else {
491 cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl;
492 }
493 }
494
495 if (Debug) {
496 if (InstallVer==0) {
497 cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer << endl;
498 } else {
499 cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer.VerStr() << endl;
500 }
501 }
502 if (Debug)
503 cout << OutputInDepth(Depth) << " Keep " << Cache[Pkg].Keep() << " Unpacked " << List->IsFlag(Pkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(Pkg,pkgOrderList::Configured) << endl;
504
6c139d6e 505 // See if the current version is ok
55c04aa4 506 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
6c139d6e
AL
507 Pkg.State() == PkgIterator::NeedsNothing)
508 {
509 Bad = false;
510 continue;
511 }
a6c8798a
CB
512
513 // Keep() , if upgradable, is the package left at the install version
d8a98270 514
6c139d6e
AL
515 // Not the install version
516 if (Cache[Pkg].InstallVer != *I ||
d8a98270
CB
517 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing &&
518 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
6c139d6e 519 continue;
b2e465d6 520
6c139d6e
AL
521 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true)
522 Bad = !DepAdd(OList,Pkg,Depth);
523 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
524 Bad = false;
525 }
6c139d6e
AL
526 }
527
528 if (Bad == true)
529 {
131418cf
MV
530 if (Debug)
531 std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl;
6c139d6e
AL
532 OList.Flag(Pkg,0,pkgOrderList::Added);
533 OList.pop_back();
534 Depth--;
535 return false;
536 }
537 }
538
539 Depth--;
540 return true;
541}
542 /*}}}*/
543// PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
544// ---------------------------------------------------------------------
545/* This is called to deal with conflicts arising from unpacking */
546bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
547{
548 if (List->IsNow(Pkg) == false)
549 return true;
550
551 // Already removed it
552 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
553 return true;
554
555 // Woops, it will not be re-installed!
556 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
557 return false;
9d4c8f67
AL
558
559 // Essential packages get special treatment
5af32db6 560 bool IsEssential = false;
9d4c8f67 561 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
5af32db6
AL
562 IsEssential = true;
563
564 /* Check for packages that are the dependents of essential packages and
565 promote them too */
566 if (Pkg->CurrentVer != 0)
567 {
568 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
569 IsEssential == false; D++)
570 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
571 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
572 IsEssential = true;
573 }
574
575 if (IsEssential == true)
9d4c8f67
AL
576 {
577 if (_config->FindB("APT::Force-LoopBreak",false) == false)
b2e465d6
AL
578 return _error->Error(_("This installation run will require temporarily "
579 "removing the essential package %s due to a "
580 "Conflicts/Pre-Depends loop. This is often bad, "
581 "but if you really want to do it, activate the "
582 "APT::Force-LoopBreak option."),Pkg.Name());
9d4c8f67 583 }
6c139d6e
AL
584
585 bool Res = SmartRemove(Pkg);
586 if (Cache[Pkg].Delete() == false)
587 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
588
589 return Res;
590}
591 /*}}}*/
592// PM::SmartRemove - Removal Helper /*{{{*/
593// ---------------------------------------------------------------------
594/* */
595bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
596{
597 if (List->IsNow(Pkg) == false)
598 return true;
599
600 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
803ea2a8 601
28166356 602 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
803ea2a8 603 return true;
6c139d6e
AL
604}
605 /*}}}*/
606// PM::SmartUnPack - Install helper /*{{{*/
607// ---------------------------------------------------------------------
608/* This performs the task of handling pre-depends. */
609bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
d77b985a
DK
610{
611 return SmartUnPack(Pkg, true);
612}
613bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate)
6c139d6e 614{
cfcdf7fe
CB
615 if (Debug == true)
616 clog << "SmartUnPack " << Pkg.Name() << endl;
617
6c139d6e
AL
618 // Check if it is already unpacked
619 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
620 Cache[Pkg].Keep() == true)
621 {
622 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
d77b985a
DK
623 if (Immediate == true &&
624 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
6c139d6e 625 if (SmartConfigure(Pkg) == false)
be2db981 626 return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'. "
f66a64c2 627 "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
6c139d6e
AL
628 return true;
629 }
a6c8798a 630
d77b985a
DK
631 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
632
6c139d6e
AL
633 /* See if this packages install version has any predependencies
634 that are not met by 'now' packages. */
d77b985a 635 for (DepIterator D = instVer.DependsList();
421c8d10 636 D.end() == false; )
6c139d6e 637 {
421c8d10
AL
638 // Compute a single dependency element (glob or)
639 pkgCache::DepIterator Start;
640 pkgCache::DepIterator End;
641 D.GlobOr(Start,End);
642
643 while (End->Type == pkgCache::Dep::PreDepends)
6c139d6e 644 {
f4945db3
MV
645 if (Debug == true)
646 clog << "PreDepends order for " << Pkg.Name() << std::endl;
647
6c139d6e 648 // Look for possible ok targets.
b2e465d6 649 SPtrArray<Version *> VList = Start.AllTargets();
6c139d6e
AL
650 bool Bad = true;
651 for (Version **I = VList; *I != 0 && Bad == true; I++)
652 {
653 VerIterator Ver(Cache,*I);
654 PkgIterator Pkg = Ver.ParentPkg();
655
656 // See if the current version is ok
657 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
658 Pkg.State() == PkgIterator::NeedsNothing)
659 {
660 Bad = false;
f4945db3
MV
661 if (Debug == true)
662 clog << "Found ok package " << Pkg.Name() << endl;
6c139d6e
AL
663 continue;
664 }
665 }
666
667 // Look for something that could be configured.
668 for (Version **I = VList; *I != 0 && Bad == true; I++)
669 {
670 VerIterator Ver(Cache,*I);
671 PkgIterator Pkg = Ver.ParentPkg();
672
673 // Not the install version
674 if (Cache[Pkg].InstallVer != *I ||
675 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
676 continue;
677
f4945db3
MV
678 if (Debug == true)
679 clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
6c139d6e
AL
680 Bad = !SmartConfigure(Pkg);
681 }
1006601e 682
421c8d10 683 /* If this or element did not match then continue on to the
1006601e 684 next or element until a matching element is found */
421c8d10 685 if (Bad == true)
1006601e
AL
686 {
687 // This triggers if someone make a pre-depends/depend loop.
421c8d10 688 if (Start == End)
1006601e
AL
689 return _error->Error("Couldn't configure pre-depend %s for %s, "
690 "probably a dependency cycle.",
691 End.TargetPkg().Name(),Pkg.Name());
421c8d10
AL
692 Start++;
693 }
a6c8798a 694 else
421c8d10 695 break;
6c139d6e
AL
696 }
697
b2e465d6
AL
698 if (End->Type == pkgCache::Dep::Conflicts ||
699 End->Type == pkgCache::Dep::Obsoletes)
6c139d6e
AL
700 {
701 /* Look for conflicts. Two packages that are both in the install
702 state cannot conflict so we don't check.. */
b2e465d6 703 SPtrArray<Version *> VList = End.AllTargets();
6c139d6e
AL
704 for (Version **I = VList; *I != 0; I++)
705 {
706 VerIterator Ver(Cache,*I);
707 PkgIterator Pkg = Ver.ParentPkg();
708
709 // See if the current version is conflicting
710 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true)
711 {
712 if (EarlyRemove(Pkg) == false)
713 return _error->Error("Internal Error, Could not early remove %s",Pkg.Name());
714 }
715 }
6c139d6e 716 }
cfcdf7fe
CB
717
718 // Check for breaks
719 if (End->Type == pkgCache::Dep::DpkgBreaks) {
720 SPtrArray<Version *> VList = End.AllTargets();
721 for (Version **I = VList; *I != 0; I++)
722 {
723 VerIterator Ver(Cache,*I);
8b1f5756 724 PkgIterator BrokenPkg = Ver.ParentPkg();
55c04aa4 725 // Check if it needs to be unpacked
8b1f5756
CB
726 if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false &&
727 !List->IsFlag(BrokenPkg,pkgOrderList::UnPacked)) {
728 /* FIXME Setting the flag here prevents breakage loops, that can occur if BrokenPkg (or one of the
729 packages it breaks) breaks Pkg */
730 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
55c04aa4 731 // Found a break, so unpack the package
a6c8798a
CB
732 if (Debug)
733 cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl;
8b1f5756 734 SmartUnPack(BrokenPkg, false);
cfcdf7fe
CB
735 }
736 }
737 }
a6c8798a
CB
738
739 // Check for dependanices that have not been unpacked, probably due to loops.
740 bool Bad = true;
741 while (End->Type == pkgCache::Dep::Depends) {
742 PkgIterator DepPkg;
743 SPtrArray<Version *> VList = Start.AllTargets();
744
745 for (Version **I = VList; *I != 0; I++) {
746 VerIterator Ver(Cache,*I);
747 DepPkg = Ver.ParentPkg();
748
749 if (!Bad) continue;
750
751 if (Debug)
752 cout << " Checking dep on " << DepPkg.Name() << endl;
753 // Check if it satisfies this dependancy
754 if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
755 DepPkg.State() == PkgIterator::NeedsNothing)
756 {
757 Bad = false;
758 continue;
759 }
760
761 if (Cache[DepPkg].InstallVer == *I && !List->IsNow(DepPkg)) {
762 Bad = false;
763 continue;
764 }
765 }
766
767 if (Start==End) {
768 if (Bad) {
769 // FIXME Setting the flag here prevents a loop forming
770 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
771 // Found a break, so unpack the package
772 if (Debug)
773 cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl;
774 //SmartUnPack(DepPkg, false);
775 }
776 break;
777
778 } else {
779 Start++;
780 }
781 }
6c139d6e
AL
782 }
783
784 // Check for reverse conflicts.
5af32db6 785 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
d77b985a 786 instVer.VerStr()) == false)
5af32db6
AL
787 return false;
788
d77b985a 789 for (PrvIterator P = instVer.ProvidesList();
6c139d6e
AL
790 P.end() == false; P++)
791 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
70ae2409 792
d77b985a
DK
793 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
794
795 if (instVer->MultiArch == pkgCache::Version::Same)
796 for (PkgIterator P = Pkg.Group().PackageList();
797 P.end() == false; P = Pkg.Group().NextPkg(P))
798 {
799 if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
800 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
801 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
802 continue;
803 SmartUnPack(P, false);
804 }
805
28166356
DK
806 if(Install(Pkg,FileNames[Pkg->ID]) == false)
807 return false;
808
6c139d6e 809 // Perform immedate configuration of the package.
d77b985a
DK
810 if (Immediate == true &&
811 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
6c139d6e 812 if (SmartConfigure(Pkg) == false)
a6c8798a
CB
813 //return
814 _error->Error(_("Could not perform immediate configuration on '%s'. "
20382bad 815 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
6c139d6e
AL
816
817 return true;
818}
819 /*}}}*/
820// PM::OrderInstall - Installation ordering routine /*{{{*/
821// ---------------------------------------------------------------------
822/* */
281daf46 823pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
6c139d6e 824{
7a1b1f8b 825 if (CreateOrderList() == false)
281daf46
AL
826 return Failed;
827
828 Reset();
6c139d6e 829
30e1eab5 830 if (Debug == true)
5e312de7 831 clog << "Beginning to order" << endl;
6c139d6e 832
5e312de7
DK
833 bool const ordering =
834 _config->FindB("PackageManager::UnpackAll",true) ?
835 List->OrderUnpack(FileNames) : List->OrderCritical();
836 if (ordering == false)
281daf46
AL
837 {
838 _error->Error("Internal ordering error");
839 return Failed;
840 }
841
30e1eab5
AL
842 if (Debug == true)
843 clog << "Done ordering" << endl;
844
281daf46 845 bool DoneSomething = false;
6c139d6e
AL
846 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
847 {
848 PkgIterator Pkg(Cache,*I);
281daf46
AL
849
850 if (List->IsNow(Pkg) == false)
851 {
852 if (Debug == true)
853 clog << "Skipping already done " << Pkg.Name() << endl;
854 continue;
855 }
856
2fd65468 857 if (List->IsMissing(Pkg) == true)
281daf46
AL
858 {
859 if (Debug == true)
a3eaf954 860 clog << "Sequence completed at " << Pkg.Name() << endl;
281daf46
AL
861 if (DoneSomething == false)
862 {
863 _error->Error("Internal Error, ordering was unable to handle the media swap");
864 return Failed;
865 }
866 return Incomplete;
867 }
6c139d6e
AL
868
869 // Sanity check
d0c59649
AL
870 if (Cache[Pkg].Keep() == true &&
871 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
872 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
281daf46 873 {
71a174ee 874 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name());
281daf46
AL
875 return Failed;
876 }
6c139d6e
AL
877
878 // Perform a delete or an install
879 if (Cache[Pkg].Delete() == true)
880 {
881 if (SmartRemove(Pkg) == false)
281daf46 882 return Failed;
6c139d6e
AL
883 }
884 else
885 if (SmartUnPack(Pkg) == false)
281daf46
AL
886 return Failed;
887 DoneSomething = true;
6c139d6e 888 }
5e312de7 889
6c139d6e
AL
890 // Final run through the configure phase
891 if (ConfigureAll() == false)
281daf46 892 return Failed;
6c139d6e
AL
893
894 // Sanity check
895 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
281daf46 896 {
6c139d6e 897 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
281daf46
AL
898 {
899 _error->Error("Internal error, packages left unconfigured. %s",
900 PkgIterator(Cache,*I).Name());
901 return Failed;
902 }
903 }
904
905 return Completed;
6c139d6e
AL
906}
907 /*}}}*/
1d6386f3
MV
908// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
909// ---------------------------------------------------------------------
910pkgPackageManager::OrderResult
911pkgPackageManager::DoInstallPostFork(int statusFd)
912{
913 if(statusFd > 0)
914 // FIXME: use SetCloseExec here once it taught about throwing
915 // exceptions instead of doing _exit(100) on failure
916 fcntl(statusFd,F_SETFD,FD_CLOEXEC);
917 bool goResult = Go(statusFd);
918 if(goResult == false)
919 return Failed;
920
1d6386f3
MV
921 return Res;
922};
923
2a7e07c7
MV
924// PM::DoInstall - Does the installation /*{{{*/
925// ---------------------------------------------------------------------
926/* This uses the filenames in FileNames and the information in the
927 DepCache to perform the installation of packages.*/
928pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
929{
930 if(DoInstallPreFork() == Failed)
931 return Failed;
932
7230ad48 933 return DoInstallPostFork(statusFd);
2a7e07c7 934}
eef71338 935 /*}}}*/