]> git.saurik.com Git - apt.git/blame - apt-pkg/packagemanager.cc
Removed temp debug lines.
[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);
079cc404 170
7a1b1f8b
AL
171 // Generate the list of affected packages and sort it
172 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
173 {
e7b470ee
AL
174 // Ignore no-version packages
175 if (I->VersionList == 0)
176 continue;
177
138d4b3d
AL
178 // Mark the package and its dependends for immediate configuration
179 if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
180 (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) &&
079cc404 181 NoImmConfigure == false)
7a1b1f8b 182 {
3a6d37fd
MV
183 if(Debug)
184 clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl;
7a1b1f8b 185 List->Flag(I,pkgOrderList::Immediate);
3a6d37fd
MV
186
187 // Look for other install packages to make immediate configurea
188 ImmediateAdd(I, true);
d38b7b3d
AL
189
190 // And again with the current version.
3a6d37fd 191 ImmediateAdd(I, false);
7a1b1f8b
AL
192 }
193
194 // Not interesting
195 if ((Cache[I].Keep() == true ||
196 Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
d556d1a1 197 I.State() == pkgCache::PkgIterator::NeedsNothing &&
d0c59649 198 (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
d556d1a1
AL
199 (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
200 (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
7a1b1f8b
AL
201 continue;
202
203 // Append it to the list
138d4b3d 204 List->push_back(I);
7a1b1f8b
AL
205 }
206
207 return true;
208}
209 /*}}}*/
6c139d6e
AL
210// PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
211// ---------------------------------------------------------------------
212/* The restriction on provides is to eliminate the case when provides
213 are transitioning between valid states [ie exim to smail] */
214bool pkgPackageManager::DepAlwaysTrue(DepIterator D)
215{
216 if (D.TargetPkg()->ProvidesList != 0)
217 return false;
218
219 if ((Cache[D] & pkgDepCache::DepInstall) != 0 &&
220 (Cache[D] & pkgDepCache::DepNow) != 0)
221 return true;
222 return false;
223}
224 /*}}}*/
225// PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
226// ---------------------------------------------------------------------
227/* This looks over the reverses for a conflicts line that needs early
228 removal. */
229bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
230 const char *Ver)
231{
232 for (;D.end() == false; D++)
233 {
b2e465d6
AL
234 if (D->Type != pkgCache::Dep::Conflicts &&
235 D->Type != pkgCache::Dep::Obsoletes)
6c139d6e 236 continue;
5af32db6
AL
237
238 // The package hasnt been changed
239 if (List->IsNow(Pkg) == false)
240 continue;
6c139d6e 241
5af32db6
AL
242 // Ignore self conflicts, ignore conflicts from irrelevent versions
243 if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
6c139d6e
AL
244 continue;
245
b2e465d6 246 if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
6c139d6e 247 continue;
b2e465d6 248
6c139d6e 249 if (EarlyRemove(D.ParentPkg()) == false)
5af32db6
AL
250 return _error->Error("Reverse conflicts early remove for package '%s' failed",
251 Pkg.Name());
252 }
6c139d6e
AL
253 return true;
254}
255 /*}}}*/
256// PM::ConfigureAll - Run the all out configuration /*{{{*/
257// ---------------------------------------------------------------------
258/* This configures every package. It is assumed they are all unpacked and
259 that the final configuration is valid. */
260bool pkgPackageManager::ConfigureAll()
261{
b2e465d6 262 pkgOrderList OList(&Cache);
6c139d6e
AL
263
264 // Populate the order list
265 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
266 if (List->IsFlag(pkgCache::PkgIterator(Cache,*I),
267 pkgOrderList::UnPacked) == true)
268 OList.push_back(*I);
269
270 if (OList.OrderConfigure() == false)
271 return false;
5e312de7
DK
272
273 std::string const conf = _config->Find("PackageManager::Configure","all");
274 bool const ConfigurePkgs = (conf == "all");
275
6c139d6e
AL
276 // Perform the configuring
277 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
278 {
279 PkgIterator Pkg(Cache,*I);
803ea2a8 280
b9f3f1f9 281 if (ConfigurePkgs == true && VerifyConfigure(Pkg,OList) == false)
6c139d6e
AL
282 return false;
283
284 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
285 }
286
287 return true;
288}
289 /*}}}*/
290// PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
291// ---------------------------------------------------------------------
292/* This routine scheduals the configuration of the given package and all
293 of it's dependents. */
294bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
295{
0eacf067
MV
296 if (Debug == true)
297 clog << "SmartConfigure " << Pkg.Name() << endl;
298
b2e465d6 299 pkgOrderList OList(&Cache);
6c139d6e
AL
300
301 if (DepAdd(OList,Pkg) == false)
302 return false;
5e312de7
DK
303
304 static std::string const conf = _config->Find("PackageManager::Configure","all");
305 static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
306
307 if (ConfigurePkgs == true)
308 if (OList.OrderConfigure() == false)
309 return false;
310
6c139d6e
AL
311 // Perform the configuring
312 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
313 {
314 PkgIterator Pkg(Cache,*I);
315
b9f3f1f9 316 if (ConfigurePkgs == true && VerifyConfigure(Pkg,OList) == false)
6c139d6e
AL
317 return false;
318
319 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
320 }
321
d77b985a
DK
322 if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same)
323 for (PkgIterator P = Pkg.Group().PackageList();
324 P.end() == false; P = Pkg.Group().NextPkg(P))
325 {
326 if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true ||
327 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
328 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
329 continue;
330 SmartConfigure(P);
331 }
332
6c139d6e
AL
333 // Sanity Check
334 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
be2db981 335 return _error->Error(_("Could not perform immediate configuration on '%s'. "
20382bad
DK
336 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
337
6c139d6e 338 return true;
4264ebeb
CB
339}
340
341// PM::VerifyConfigure - Check configuration of dependancies /*{{{*/
342// ---------------------------------------------------------------------
343/* This routine checks that all a packages dependancies have been
344 configured, before it is going to be configured. If this gives a warning
345 on a virtual package, it means that the package thats providing it is not
346 configured*/
347bool pkgPackageManager::VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList)
348{
349 // If this is true at the end, then the package should not be configured
350 bool error=true;
351 // This holds the the OR status of the previous dependancy
352 bool previousOr=false;
353
354 // First iterate through the dependancies of Pkg
355 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++)
356 {
357
358 /* If the dependancy is of type Depends or PreDepends, we need to check it, but only if it is going to be
359 configured at some point */
360 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) {
361
362 /* If the previous package and this package are OR dependancies, and the previous package satisfied the dependancy
363 then skip this dependancy as it is not relevent, this will repeat for the next package if the situation is the
364 same */
365 if (previousOr && !error) { // As error has not been reset, this refers to the previous dependancy
366 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
367 continue;
368 }
369
370 // Reset error
371 error = true;
372
373 // Check thorugh all possible versions of this dependancy (D)
374 SPtrArray<Version *> VList = D.AllTargets();
375 for (Version **I = VList; *I != 0; I++)
376 {
377 VerIterator DepVer(Cache,*I);
378 PkgIterator DepPkg = DepVer.ParentPkg();
379 VerIterator DepInstallVer(Cache,Cache[DepPkg].InstallVer);
380
381 if (DepPkg.CurrentVer() == DepVer && !List->IsFlag(DepPkg,pkgOrderList::UnPacked)) {
4264ebeb
CB
382 error=false;
383 break;
384 }
385
386 if (Cache[DepPkg].InstallVer == DepVer &&
387 (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) {
4264ebeb
CB
388 error=false;
389 break;
390 }
391 }
392
393 /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR
394 the next one might */
395 if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
396 _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name());
397 return false;
398 /* If the previous package is a OR but not this package, but there is still an error then fail as it will not
399 be satisfied */
400 } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
401 _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name());
402 return false;
403 }
404
405 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
406 } else {
407 previousOr=false;
408 }
409 }
410 return true;
411}
412
413// PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/
414// ---------------------------------------------------------------------
415/* This routine verifies if a package can be configured and if so
416 configures it */
417bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList)
418{
419 if (VerifyConfigure(Pkg, OList))
420 return Configure(Pkg);
421 else
422 return false;
423
6c139d6e
AL
424}
425 /*}}}*/
426// PM::DepAdd - Add all dependents to the oder list /*{{{*/
427// ---------------------------------------------------------------------
428/* This recursively adds all dependents to the order list */
429bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth)
430{
431 if (OList.IsFlag(Pkg,pkgOrderList::Added) == true)
432 return true;
433 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
434 return true;
435 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
436 return false;
131418cf
MV
437
438 if (Debug)
439 std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl;
b2e465d6 440
6c139d6e
AL
441 // Put the package on the list
442 OList.push_back(Pkg);
443 OList.Flag(Pkg,pkgOrderList::Added);
444 Depth++;
445
446 // Check the dependencies to see if they are all satisfied.
447 bool Bad = false;
448 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
449 {
b50b2c97 450 if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
6c139d6e
AL
451 {
452 D++;
453 continue;
454 }
455
456 // Grok or groups
457 Bad = true;
458 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
459 {
b50b2c97 460 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
6c139d6e
AL
461
462 if (Bad == false)
463 continue;
464
b2e465d6 465 SPtrArray<Version *> VList = D.AllTargets();
6c139d6e
AL
466 for (Version **I = VList; *I != 0 && Bad == true; I++)
467 {
468 VerIterator Ver(Cache,*I);
469 PkgIterator Pkg = Ver.ParentPkg();
470
471 // See if the current version is ok
472 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
473 Pkg.State() == PkgIterator::NeedsNothing)
474 {
475 Bad = false;
476 continue;
477 }
478
479 // Not the install version
480 if (Cache[Pkg].InstallVer != *I ||
481 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
482 continue;
b2e465d6 483
6c139d6e
AL
484 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true)
485 Bad = !DepAdd(OList,Pkg,Depth);
486 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
487 Bad = false;
488 }
6c139d6e
AL
489 }
490
491 if (Bad == true)
492 {
131418cf
MV
493 if (Debug)
494 std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl;
6c139d6e
AL
495 OList.Flag(Pkg,0,pkgOrderList::Added);
496 OList.pop_back();
497 Depth--;
498 return false;
499 }
500 }
501
502 Depth--;
503 return true;
504}
505 /*}}}*/
506// PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
507// ---------------------------------------------------------------------
508/* This is called to deal with conflicts arising from unpacking */
509bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
510{
511 if (List->IsNow(Pkg) == false)
512 return true;
513
514 // Already removed it
515 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
516 return true;
517
518 // Woops, it will not be re-installed!
519 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
520 return false;
9d4c8f67
AL
521
522 // Essential packages get special treatment
5af32db6 523 bool IsEssential = false;
9d4c8f67 524 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
5af32db6
AL
525 IsEssential = true;
526
527 /* Check for packages that are the dependents of essential packages and
528 promote them too */
529 if (Pkg->CurrentVer != 0)
530 {
531 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
532 IsEssential == false; D++)
533 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
534 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
535 IsEssential = true;
536 }
537
538 if (IsEssential == true)
9d4c8f67
AL
539 {
540 if (_config->FindB("APT::Force-LoopBreak",false) == false)
b2e465d6
AL
541 return _error->Error(_("This installation run will require temporarily "
542 "removing the essential package %s due to a "
543 "Conflicts/Pre-Depends loop. This is often bad, "
544 "but if you really want to do it, activate the "
545 "APT::Force-LoopBreak option."),Pkg.Name());
9d4c8f67 546 }
6c139d6e
AL
547
548 bool Res = SmartRemove(Pkg);
549 if (Cache[Pkg].Delete() == false)
550 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
551
552 return Res;
553}
554 /*}}}*/
555// PM::SmartRemove - Removal Helper /*{{{*/
556// ---------------------------------------------------------------------
557/* */
558bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
559{
560 if (List->IsNow(Pkg) == false)
561 return true;
562
563 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
803ea2a8 564
28166356 565 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
803ea2a8 566 return true;
6c139d6e
AL
567}
568 /*}}}*/
569// PM::SmartUnPack - Install helper /*{{{*/
570// ---------------------------------------------------------------------
571/* This performs the task of handling pre-depends. */
572bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
d77b985a
DK
573{
574 return SmartUnPack(Pkg, true);
575}
576bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate)
6c139d6e
AL
577{
578 // Check if it is already unpacked
579 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
580 Cache[Pkg].Keep() == true)
581 {
582 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
d77b985a
DK
583 if (Immediate == true &&
584 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
6c139d6e 585 if (SmartConfigure(Pkg) == false)
be2db981 586 return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'. "
f66a64c2 587 "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
6c139d6e
AL
588 return true;
589 }
981d20eb 590
d77b985a
DK
591 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
592
6c139d6e
AL
593 /* See if this packages install version has any predependencies
594 that are not met by 'now' packages. */
d77b985a 595 for (DepIterator D = instVer.DependsList();
421c8d10 596 D.end() == false; )
6c139d6e 597 {
421c8d10
AL
598 // Compute a single dependency element (glob or)
599 pkgCache::DepIterator Start;
600 pkgCache::DepIterator End;
601 D.GlobOr(Start,End);
602
603 while (End->Type == pkgCache::Dep::PreDepends)
6c139d6e 604 {
f4945db3
MV
605 if (Debug == true)
606 clog << "PreDepends order for " << Pkg.Name() << std::endl;
607
6c139d6e 608 // Look for possible ok targets.
b2e465d6 609 SPtrArray<Version *> VList = Start.AllTargets();
6c139d6e
AL
610 bool Bad = true;
611 for (Version **I = VList; *I != 0 && Bad == true; I++)
612 {
613 VerIterator Ver(Cache,*I);
614 PkgIterator Pkg = Ver.ParentPkg();
615
616 // See if the current version is ok
617 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
618 Pkg.State() == PkgIterator::NeedsNothing)
619 {
620 Bad = false;
f4945db3
MV
621 if (Debug == true)
622 clog << "Found ok package " << Pkg.Name() << endl;
6c139d6e
AL
623 continue;
624 }
625 }
626
627 // Look for something that could be configured.
628 for (Version **I = VList; *I != 0 && Bad == true; I++)
629 {
630 VerIterator Ver(Cache,*I);
631 PkgIterator Pkg = Ver.ParentPkg();
632
633 // Not the install version
634 if (Cache[Pkg].InstallVer != *I ||
635 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
636 continue;
637
f4945db3
MV
638 if (Debug == true)
639 clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
6c139d6e
AL
640 Bad = !SmartConfigure(Pkg);
641 }
1006601e 642
421c8d10 643 /* If this or element did not match then continue on to the
1006601e 644 next or element until a matching element is found */
421c8d10 645 if (Bad == true)
1006601e
AL
646 {
647 // This triggers if someone make a pre-depends/depend loop.
421c8d10 648 if (Start == End)
1006601e
AL
649 return _error->Error("Couldn't configure pre-depend %s for %s, "
650 "probably a dependency cycle.",
651 End.TargetPkg().Name(),Pkg.Name());
421c8d10
AL
652 Start++;
653 }
654 else
655 break;
6c139d6e
AL
656 }
657
b2e465d6
AL
658 if (End->Type == pkgCache::Dep::Conflicts ||
659 End->Type == pkgCache::Dep::Obsoletes)
6c139d6e
AL
660 {
661 /* Look for conflicts. Two packages that are both in the install
662 state cannot conflict so we don't check.. */
b2e465d6 663 SPtrArray<Version *> VList = End.AllTargets();
6c139d6e
AL
664 for (Version **I = VList; *I != 0; I++)
665 {
666 VerIterator Ver(Cache,*I);
667 PkgIterator Pkg = Ver.ParentPkg();
668
669 // See if the current version is conflicting
670 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true)
671 {
672 if (EarlyRemove(Pkg) == false)
673 return _error->Error("Internal Error, Could not early remove %s",Pkg.Name());
674 }
675 }
6c139d6e
AL
676 }
677 }
678
679 // Check for reverse conflicts.
5af32db6 680 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
d77b985a 681 instVer.VerStr()) == false)
5af32db6
AL
682 return false;
683
d77b985a 684 for (PrvIterator P = instVer.ProvidesList();
6c139d6e
AL
685 P.end() == false; P++)
686 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
70ae2409 687
d77b985a
DK
688 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
689
690 if (instVer->MultiArch == pkgCache::Version::Same)
691 for (PkgIterator P = Pkg.Group().PackageList();
692 P.end() == false; P = Pkg.Group().NextPkg(P))
693 {
694 if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
695 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
696 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
697 continue;
698 SmartUnPack(P, false);
699 }
700
28166356
DK
701 if(Install(Pkg,FileNames[Pkg->ID]) == false)
702 return false;
703
6c139d6e 704 // Perform immedate configuration of the package.
d77b985a
DK
705 if (Immediate == true &&
706 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
6c139d6e 707 if (SmartConfigure(Pkg) == false)
be2db981 708 return _error->Error(_("Could not perform immediate configuration on '%s'. "
20382bad 709 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
6c139d6e
AL
710
711 return true;
712}
713 /*}}}*/
714// PM::OrderInstall - Installation ordering routine /*{{{*/
715// ---------------------------------------------------------------------
716/* */
281daf46 717pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
6c139d6e 718{
7a1b1f8b 719 if (CreateOrderList() == false)
281daf46
AL
720 return Failed;
721
722 Reset();
6c139d6e 723
30e1eab5 724 if (Debug == true)
5e312de7 725 clog << "Beginning to order" << endl;
6c139d6e 726
5e312de7
DK
727 bool const ordering =
728 _config->FindB("PackageManager::UnpackAll",true) ?
729 List->OrderUnpack(FileNames) : List->OrderCritical();
730 if (ordering == false)
281daf46
AL
731 {
732 _error->Error("Internal ordering error");
733 return Failed;
734 }
735
30e1eab5
AL
736 if (Debug == true)
737 clog << "Done ordering" << endl;
738
281daf46 739 bool DoneSomething = false;
6c139d6e
AL
740 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
741 {
742 PkgIterator Pkg(Cache,*I);
281daf46
AL
743
744 if (List->IsNow(Pkg) == false)
745 {
746 if (Debug == true)
747 clog << "Skipping already done " << Pkg.Name() << endl;
748 continue;
749 }
750
2fd65468 751 if (List->IsMissing(Pkg) == true)
281daf46
AL
752 {
753 if (Debug == true)
a3eaf954 754 clog << "Sequence completed at " << Pkg.Name() << endl;
281daf46
AL
755 if (DoneSomething == false)
756 {
757 _error->Error("Internal Error, ordering was unable to handle the media swap");
758 return Failed;
759 }
760 return Incomplete;
761 }
6c139d6e
AL
762
763 // Sanity check
d0c59649
AL
764 if (Cache[Pkg].Keep() == true &&
765 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
766 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
281daf46 767 {
71a174ee 768 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name());
281daf46
AL
769 return Failed;
770 }
6c139d6e
AL
771
772 // Perform a delete or an install
773 if (Cache[Pkg].Delete() == true)
774 {
775 if (SmartRemove(Pkg) == false)
281daf46 776 return Failed;
6c139d6e
AL
777 }
778 else
779 if (SmartUnPack(Pkg) == false)
281daf46
AL
780 return Failed;
781 DoneSomething = true;
6c139d6e 782 }
5e312de7 783
6c139d6e
AL
784 // Final run through the configure phase
785 if (ConfigureAll() == false)
281daf46 786 return Failed;
6c139d6e
AL
787
788 // Sanity check
789 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
281daf46 790 {
6c139d6e 791 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
281daf46
AL
792 {
793 _error->Error("Internal error, packages left unconfigured. %s",
794 PkgIterator(Cache,*I).Name());
795 return Failed;
796 }
797 }
798
799 return Completed;
6c139d6e
AL
800}
801 /*}}}*/
1d6386f3
MV
802// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
803// ---------------------------------------------------------------------
804pkgPackageManager::OrderResult
805pkgPackageManager::DoInstallPostFork(int statusFd)
806{
807 if(statusFd > 0)
808 // FIXME: use SetCloseExec here once it taught about throwing
809 // exceptions instead of doing _exit(100) on failure
810 fcntl(statusFd,F_SETFD,FD_CLOEXEC);
811 bool goResult = Go(statusFd);
812 if(goResult == false)
813 return Failed;
814
1d6386f3
MV
815 return Res;
816};
817
2a7e07c7
MV
818// PM::DoInstall - Does the installation /*{{{*/
819// ---------------------------------------------------------------------
820/* This uses the filenames in FileNames and the information in the
821 DepCache to perform the installation of packages.*/
822pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
823{
824 if(DoInstallPreFork() == Failed)
825 return Failed;
826
7230ad48 827 return DoInstallPostFork(statusFd);
2a7e07c7
MV
828}
829 /*}}}*/