Initial commit from my GSoC project. Added a verification function (VerifyConfigure...
[ntk/apt.git] / apt-pkg / packagemanager.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: packagemanager.cc,v 1.30 2003/04/27 03:04:15 doogie Exp $
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 /*{{{*/
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>
21 #include <apt-pkg/acquire-item.h>
22 #include <apt-pkg/algorithms.h>
23 #include <apt-pkg/configuration.h>
24 #include <apt-pkg/sptr.h>
25
26 #include <apti18n.h>
27 #include <iostream>
28 #include <fcntl.h>
29 /*}}}*/
30 using namespace std;
31
32 // PM::PackageManager - Constructor /*{{{*/
33 // ---------------------------------------------------------------------
34 /* */
35 pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache)
36 {
37 FileNames = new string[Cache.Head().PackageCount];
38 List = 0;
39 Debug = _config->FindB("Debug::pkgPackageManager",false);
40 }
41 /*}}}*/
42 // PM::PackageManager - Destructor /*{{{*/
43 // ---------------------------------------------------------------------
44 /* */
45 pkgPackageManager::~pkgPackageManager()
46 {
47 delete List;
48 delete [] FileNames;
49 }
50 /*}}}*/
51 // PM::GetArchives - Queue the archives for download /*{{{*/
52 // ---------------------------------------------------------------------
53 /* */
54 bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
55 pkgRecords *Recs)
56 {
57 if (CreateOrderList() == false)
58 return false;
59
60 bool const ordering =
61 _config->FindB("PackageManager::UnpackAll",true) ?
62 List->OrderUnpack() : List->OrderCritical();
63 if (ordering == false)
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);
69 FileNames[Pkg->ID] = string();
70
71 // Skip packages to erase
72 if (Cache[Pkg].Delete() == true)
73 continue;
74
75 // Skip Packages that need configure only.
76 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
77 Cache[Pkg].Keep() == true)
78 continue;
79
80 // Skip already processed packages
81 if (List->IsNow(Pkg) == false)
82 continue;
83
84 new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
85 FileNames[Pkg->ID]);
86 }
87
88 return true;
89 }
90 /*}}}*/
91 // PM::FixMissing - Keep all missing packages /*{{{*/
92 // ---------------------------------------------------------------------
93 /* This is called to correct the installation when packages could not
94 be downloaded. */
95 bool pkgPackageManager::FixMissing()
96 {
97 pkgDepCache::ActionGroup group(Cache);
98 pkgProblemResolver Resolve(&Cache);
99 List->SetFileList(FileNames);
100
101 bool Bad = false;
102 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
103 {
104 if (List->IsMissing(I) == false)
105 continue;
106
107 // Okay, this file is missing and we need it. Mark it for keep
108 Bad = true;
109 Cache.MarkKeep(I, false, false);
110 }
111
112 // We have to empty the list otherwise it will not have the new changes
113 delete List;
114 List = 0;
115
116 if (Bad == false)
117 return true;
118
119 // Now downgrade everything that is broken
120 return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
121 }
122 /*}}}*/
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 */
128 void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned const int &Depth)
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)
149 clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl;
150 List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
151 ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
152 }
153 }
154 return;
155 }
156 /*}}}*/
157 // PM::CreateOrderList - Create the ordering class /*{{{*/
158 // ---------------------------------------------------------------------
159 /* This populates the ordering list with all the packages that are
160 going to change. */
161 bool pkgPackageManager::CreateOrderList()
162 {
163 if (List != 0)
164 return true;
165
166 delete List;
167 List = new pkgOrderList(&Cache);
168
169 static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
170
171 // Generate the list of affected packages and sort it
172 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
173 {
174 // Ignore no-version packages
175 if (I->VersionList == 0)
176 continue;
177
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) &&
181 NoImmConfigure == false)
182 {
183 if(Debug)
184 clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl;
185 List->Flag(I,pkgOrderList::Immediate);
186
187 // Look for other install packages to make immediate configurea
188 ImmediateAdd(I, true);
189
190 // And again with the current version.
191 ImmediateAdd(I, false);
192 }
193
194 // Not interesting
195 if ((Cache[I].Keep() == true ||
196 Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
197 I.State() == pkgCache::PkgIterator::NeedsNothing &&
198 (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
199 (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
200 (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
201 continue;
202
203 // Append it to the list
204 List->push_back(I);
205 }
206
207 return true;
208 }
209 /*}}}*/
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] */
214 bool 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. */
229 bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
230 const char *Ver)
231 {
232 for (;D.end() == false; D++)
233 {
234 if (D->Type != pkgCache::Dep::Conflicts &&
235 D->Type != pkgCache::Dep::Obsoletes)
236 continue;
237
238 // The package hasnt been changed
239 if (List->IsNow(Pkg) == false)
240 continue;
241
242 // Ignore self conflicts, ignore conflicts from irrelevent versions
243 if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
244 continue;
245
246 if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
247 continue;
248
249 if (EarlyRemove(D.ParentPkg()) == false)
250 return _error->Error("Reverse conflicts early remove for package '%s' failed",
251 Pkg.Name());
252 }
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. */
260 bool pkgPackageManager::ConfigureAll()
261 {
262 pkgOrderList OList(&Cache);
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;
272
273 std::string const conf = _config->Find("PackageManager::Configure","all");
274 bool const ConfigurePkgs = (conf == "all");
275
276 // Perform the configuring
277 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
278 {
279 PkgIterator Pkg(Cache,*I);
280
281 if (ConfigurePkgs == true && VerifyConfigure(Pkg) == false)
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. */
294 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
295 {
296 if (Debug == true)
297 clog << "SmartConfigure " << Pkg.Name() << endl;
298
299 pkgOrderList OList(&Cache);
300
301 if (DepAdd(OList,Pkg) == false)
302 return false;
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
311 // Perform the configuring
312 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
313 {
314 PkgIterator Pkg(Cache,*I);
315
316 if (ConfigurePkgs == true && VerifyConfigure(Pkg) == false)
317 return false;
318
319 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
320 }
321
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
333 // Sanity Check
334 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
335 return _error->Error(_("Could not perform immediate configuration on '%s'. "
336 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
337
338 return true;
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*/
347 bool 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)) {
382 clog << "Version " << DepPkg.CurrentVer() << " is installed on the system, satifying this dependancy" << endl;
383 error=false;
384 break;
385 }
386
387 if (Cache[DepPkg].InstallVer == DepVer &&
388 (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) {
389 clog << "Version " << DepInstallVer.VerStr() << " is going to be installed on the system, satifying this dependancy" << endl;
390 error=false;
391 break;
392 }
393 }
394
395 /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR
396 the next one might */
397 if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
398 _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name());
399 return false;
400 /* If the previous package is a OR but not this package, but there is still an error then fail as it will not
401 be satisfied */
402 } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
403 _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name());
404 return false;
405 }
406
407 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
408 } else {
409 previousOr=false;
410 }
411 }
412 return true;
413 }
414
415 // PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/
416 // ---------------------------------------------------------------------
417 /* This routine verifies if a package can be configured and if so
418 configures it */
419 bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList)
420 {
421 if (VerifyConfigure(Pkg, OList))
422 return Configure(Pkg);
423 else
424 return false;
425
426 }
427 /*}}}*/
428 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
429 // ---------------------------------------------------------------------
430 /* This recursively adds all dependents to the order list */
431 bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth)
432 {
433 if (OList.IsFlag(Pkg,pkgOrderList::Added) == true)
434 return true;
435 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
436 return true;
437 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
438 return false;
439
440 if (Debug)
441 std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl;
442
443 // Put the package on the list
444 OList.push_back(Pkg);
445 OList.Flag(Pkg,pkgOrderList::Added);
446 Depth++;
447
448 // Check the dependencies to see if they are all satisfied.
449 bool Bad = false;
450 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
451 {
452 if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
453 {
454 D++;
455 continue;
456 }
457
458 // Grok or groups
459 Bad = true;
460 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
461 {
462 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
463
464 if (Bad == false)
465 continue;
466
467 SPtrArray<Version *> VList = D.AllTargets();
468 for (Version **I = VList; *I != 0 && Bad == true; I++)
469 {
470 VerIterator Ver(Cache,*I);
471 PkgIterator Pkg = Ver.ParentPkg();
472
473 // See if the current version is ok
474 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
475 Pkg.State() == PkgIterator::NeedsNothing)
476 {
477 Bad = false;
478 continue;
479 }
480
481 // Not the install version
482 if (Cache[Pkg].InstallVer != *I ||
483 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
484 continue;
485
486 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true)
487 Bad = !DepAdd(OList,Pkg,Depth);
488 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
489 Bad = false;
490 }
491 }
492
493 if (Bad == true)
494 {
495 if (Debug)
496 std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl;
497 OList.Flag(Pkg,0,pkgOrderList::Added);
498 OList.pop_back();
499 Depth--;
500 return false;
501 }
502 }
503
504 Depth--;
505 return true;
506 }
507 /*}}}*/
508 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
509 // ---------------------------------------------------------------------
510 /* This is called to deal with conflicts arising from unpacking */
511 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
512 {
513 if (List->IsNow(Pkg) == false)
514 return true;
515
516 // Already removed it
517 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
518 return true;
519
520 // Woops, it will not be re-installed!
521 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
522 return false;
523
524 // Essential packages get special treatment
525 bool IsEssential = false;
526 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
527 IsEssential = true;
528
529 /* Check for packages that are the dependents of essential packages and
530 promote them too */
531 if (Pkg->CurrentVer != 0)
532 {
533 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
534 IsEssential == false; D++)
535 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
536 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
537 IsEssential = true;
538 }
539
540 if (IsEssential == true)
541 {
542 if (_config->FindB("APT::Force-LoopBreak",false) == false)
543 return _error->Error(_("This installation run will require temporarily "
544 "removing the essential package %s due to a "
545 "Conflicts/Pre-Depends loop. This is often bad, "
546 "but if you really want to do it, activate the "
547 "APT::Force-LoopBreak option."),Pkg.Name());
548 }
549
550 bool Res = SmartRemove(Pkg);
551 if (Cache[Pkg].Delete() == false)
552 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
553
554 return Res;
555 }
556 /*}}}*/
557 // PM::SmartRemove - Removal Helper /*{{{*/
558 // ---------------------------------------------------------------------
559 /* */
560 bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
561 {
562 if (List->IsNow(Pkg) == false)
563 return true;
564
565 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
566
567 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
568 return true;
569 }
570 /*}}}*/
571 // PM::SmartUnPack - Install helper /*{{{*/
572 // ---------------------------------------------------------------------
573 /* This performs the task of handling pre-depends. */
574 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
575 {
576 return SmartUnPack(Pkg, true);
577 }
578 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate)
579 {
580 // Check if it is already unpacked
581 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
582 Cache[Pkg].Keep() == true)
583 {
584 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
585 if (Immediate == true &&
586 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
587 if (SmartConfigure(Pkg) == false)
588 return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'. "
589 "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
590 return true;
591 }
592
593 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
594
595 /* See if this packages install version has any predependencies
596 that are not met by 'now' packages. */
597 for (DepIterator D = instVer.DependsList();
598 D.end() == false; )
599 {
600 // Compute a single dependency element (glob or)
601 pkgCache::DepIterator Start;
602 pkgCache::DepIterator End;
603 D.GlobOr(Start,End);
604
605 while (End->Type == pkgCache::Dep::PreDepends)
606 {
607 if (Debug == true)
608 clog << "PreDepends order for " << Pkg.Name() << std::endl;
609
610 // Look for possible ok targets.
611 SPtrArray<Version *> VList = Start.AllTargets();
612 bool Bad = true;
613 for (Version **I = VList; *I != 0 && Bad == true; I++)
614 {
615 VerIterator Ver(Cache,*I);
616 PkgIterator Pkg = Ver.ParentPkg();
617
618 // See if the current version is ok
619 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
620 Pkg.State() == PkgIterator::NeedsNothing)
621 {
622 Bad = false;
623 if (Debug == true)
624 clog << "Found ok package " << Pkg.Name() << endl;
625 continue;
626 }
627 }
628
629 // Look for something that could be configured.
630 for (Version **I = VList; *I != 0 && Bad == true; I++)
631 {
632 VerIterator Ver(Cache,*I);
633 PkgIterator Pkg = Ver.ParentPkg();
634
635 // Not the install version
636 if (Cache[Pkg].InstallVer != *I ||
637 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
638 continue;
639
640 if (Debug == true)
641 clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
642 Bad = !SmartConfigure(Pkg);
643 }
644
645 /* If this or element did not match then continue on to the
646 next or element until a matching element is found */
647 if (Bad == true)
648 {
649 // This triggers if someone make a pre-depends/depend loop.
650 if (Start == End)
651 return _error->Error("Couldn't configure pre-depend %s for %s, "
652 "probably a dependency cycle.",
653 End.TargetPkg().Name(),Pkg.Name());
654 Start++;
655 }
656 else
657 break;
658 }
659
660 if (End->Type == pkgCache::Dep::Conflicts ||
661 End->Type == pkgCache::Dep::Obsoletes)
662 {
663 /* Look for conflicts. Two packages that are both in the install
664 state cannot conflict so we don't check.. */
665 SPtrArray<Version *> VList = End.AllTargets();
666 for (Version **I = VList; *I != 0; I++)
667 {
668 VerIterator Ver(Cache,*I);
669 PkgIterator Pkg = Ver.ParentPkg();
670
671 // See if the current version is conflicting
672 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true)
673 {
674 if (EarlyRemove(Pkg) == false)
675 return _error->Error("Internal Error, Could not early remove %s",Pkg.Name());
676 }
677 }
678 }
679 }
680
681 // Check for reverse conflicts.
682 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
683 instVer.VerStr()) == false)
684 return false;
685
686 for (PrvIterator P = instVer.ProvidesList();
687 P.end() == false; P++)
688 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
689
690 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
691
692 if (instVer->MultiArch == pkgCache::Version::Same)
693 for (PkgIterator P = Pkg.Group().PackageList();
694 P.end() == false; P = Pkg.Group().NextPkg(P))
695 {
696 if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
697 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
698 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
699 continue;
700 SmartUnPack(P, false);
701 }
702
703 if(Install(Pkg,FileNames[Pkg->ID]) == false)
704 return false;
705
706 // Perform immedate configuration of the package.
707 if (Immediate == true &&
708 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
709 if (SmartConfigure(Pkg) == false)
710 return _error->Error(_("Could not perform immediate configuration on '%s'. "
711 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
712
713 return true;
714 }
715 /*}}}*/
716 // PM::OrderInstall - Installation ordering routine /*{{{*/
717 // ---------------------------------------------------------------------
718 /* */
719 pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
720 {
721 if (CreateOrderList() == false)
722 return Failed;
723
724 Reset();
725
726 if (Debug == true)
727 clog << "Beginning to order" << endl;
728
729 bool const ordering =
730 _config->FindB("PackageManager::UnpackAll",true) ?
731 List->OrderUnpack(FileNames) : List->OrderCritical();
732 if (ordering == false)
733 {
734 _error->Error("Internal ordering error");
735 return Failed;
736 }
737
738 if (Debug == true)
739 clog << "Done ordering" << endl;
740
741 bool DoneSomething = false;
742 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
743 {
744 PkgIterator Pkg(Cache,*I);
745
746 if (List->IsNow(Pkg) == false)
747 {
748 if (Debug == true)
749 clog << "Skipping already done " << Pkg.Name() << endl;
750 continue;
751 }
752
753 if (List->IsMissing(Pkg) == true)
754 {
755 if (Debug == true)
756 clog << "Sequence completed at " << Pkg.Name() << endl;
757 if (DoneSomething == false)
758 {
759 _error->Error("Internal Error, ordering was unable to handle the media swap");
760 return Failed;
761 }
762 return Incomplete;
763 }
764
765 // Sanity check
766 if (Cache[Pkg].Keep() == true &&
767 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
768 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
769 {
770 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name());
771 return Failed;
772 }
773
774 // Perform a delete or an install
775 if (Cache[Pkg].Delete() == true)
776 {
777 if (SmartRemove(Pkg) == false)
778 return Failed;
779 }
780 else
781 if (SmartUnPack(Pkg) == false)
782 return Failed;
783 DoneSomething = true;
784 }
785
786 // Final run through the configure phase
787 if (ConfigureAll() == false)
788 return Failed;
789
790 // Sanity check
791 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
792 {
793 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
794 {
795 _error->Error("Internal error, packages left unconfigured. %s",
796 PkgIterator(Cache,*I).Name());
797 return Failed;
798 }
799 }
800
801 return Completed;
802 }
803 /*}}}*/
804 // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
805 // ---------------------------------------------------------------------
806 pkgPackageManager::OrderResult
807 pkgPackageManager::DoInstallPostFork(int statusFd)
808 {
809 if(statusFd > 0)
810 // FIXME: use SetCloseExec here once it taught about throwing
811 // exceptions instead of doing _exit(100) on failure
812 fcntl(statusFd,F_SETFD,FD_CLOEXEC);
813 bool goResult = Go(statusFd);
814 if(goResult == false)
815 return Failed;
816
817 return Res;
818 };
819
820 // PM::DoInstall - Does the installation /*{{{*/
821 // ---------------------------------------------------------------------
822 /* This uses the filenames in FileNames and the information in the
823 DepCache to perform the installation of packages.*/
824 pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
825 {
826 if(DoInstallPreFork() == Failed)
827 return Failed;
828
829 return DoInstallPostFork(statusFd);
830 }
831 /*}}}*/