]> git.saurik.com Git - apt.git/blob - apt-pkg/packagemanager.cc
ab1b13de8c5554fe0a21ce106074449dae2d39da
[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,OList) == 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,OList) == 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 (Debug == true)
350 clog << "VerifyConfigure " << Pkg.Name() << endl;
351
352 // If this is true at the end, then the package should not be configured
353 bool error=true;
354 // This holds the the OR status of the previous dependancy
355 bool previousOr=false;
356
357 // First iterate through the dependancies of Pkg
358 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++)
359 {
360
361 /* If the dependancy is of type Depends or PreDepends, we need to check it, but only if it is going to be
362 configured at some point */
363 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) {
364
365 /* If the previous package and this package are OR dependancies, and the previous package satisfied the dependancy
366 then skip this dependancy as it is not relevent, this will repeat for the next package if the situation is the
367 same */
368 if (previousOr && !error) { // As error has not been reset, this refers to the previous dependancy
369 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
370 continue;
371 }
372
373 // Reset error
374 error = true;
375
376 // Check thorugh all possible versions of this dependancy (D)
377 SPtrArray<Version *> VList = D.AllTargets();
378 for (Version **I = VList; *I != 0; I++)
379 {
380 VerIterator DepVer(Cache,*I);
381 PkgIterator DepPkg = DepVer.ParentPkg();
382 VerIterator DepInstallVer(Cache,Cache[DepPkg].InstallVer);
383
384 if (DepPkg.CurrentVer() == DepVer && !List->IsFlag(DepPkg,pkgOrderList::UnPacked)) {
385 error=false;
386 break;
387 }
388
389 if (Cache[DepPkg].InstallVer == DepVer &&
390 (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) {
391 error=false;
392 break;
393 }
394 }
395
396 /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR
397 the next one might */
398 if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
399 _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name());
400 return false;
401 /* If the previous package is a OR but not this package, but there is still an error then fail as it will not
402 be satisfied */
403 } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) {
404 _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name());
405 return false;
406 }
407
408 previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
409 } else {
410 previousOr=false;
411 }
412 }
413 return true;
414 }
415
416 // PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/
417 // ---------------------------------------------------------------------
418 /* This routine verifies if a package can be configured and if so
419 configures it */
420 bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList)
421 {
422 if (VerifyConfigure(Pkg, OList))
423 return Configure(Pkg);
424 else
425 return false;
426
427 }
428 /*}}}*/
429 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
430 // ---------------------------------------------------------------------
431 /* This recursively adds all dependents to the order list */
432 bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth)
433 {
434 if (OList.IsFlag(Pkg,pkgOrderList::Added) == true)
435 return true;
436 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
437 return true;
438 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
439 return false;
440
441 if (Debug)
442 std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl;
443
444 // Put the package on the list
445 OList.push_back(Pkg);
446 OList.Flag(Pkg,pkgOrderList::Added);
447 Depth++;
448
449 // Check the dependencies to see if they are all satisfied.
450 bool Bad = false;
451 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
452 {
453 if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
454 {
455 D++;
456 continue;
457 }
458
459 // Grok or groups
460 Bad = true;
461 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
462 {
463 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
464
465 if (Bad == false)
466 continue;
467
468 SPtrArray<Version *> VList = D.AllTargets();
469 for (Version **I = VList; *I != 0 && Bad == true; I++)
470 {
471 VerIterator Ver(Cache,*I);
472 PkgIterator Pkg = Ver.ParentPkg();
473
474 // See if the current version is ok
475 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
476 Pkg.State() == PkgIterator::NeedsNothing)
477 {
478 Bad = false;
479 continue;
480 }
481
482 std::clog << OutputInDepth(Depth) << Pkg.Name() << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << " Unpacked " << List->IsFlag(Pkg,pkgOrderList::UnPacked) << std::endl;
483
484 // Not the install version
485 if (Cache[Pkg].InstallVer != *I ||
486 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
487 continue;
488
489 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true)
490 Bad = !DepAdd(OList,Pkg,Depth);
491 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
492 Bad = false;
493 }
494 }
495
496 if (Bad == true)
497 {
498 if (Debug)
499 std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl;
500 OList.Flag(Pkg,0,pkgOrderList::Added);
501 OList.pop_back();
502 Depth--;
503 return false;
504 }
505 }
506
507 Depth--;
508 return true;
509 }
510 /*}}}*/
511 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
512 // ---------------------------------------------------------------------
513 /* This is called to deal with conflicts arising from unpacking */
514 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
515 {
516 if (List->IsNow(Pkg) == false)
517 return true;
518
519 // Already removed it
520 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
521 return true;
522
523 // Woops, it will not be re-installed!
524 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
525 return false;
526
527 // Essential packages get special treatment
528 bool IsEssential = false;
529 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
530 IsEssential = true;
531
532 /* Check for packages that are the dependents of essential packages and
533 promote them too */
534 if (Pkg->CurrentVer != 0)
535 {
536 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
537 IsEssential == false; D++)
538 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
539 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
540 IsEssential = true;
541 }
542
543 if (IsEssential == true)
544 {
545 if (_config->FindB("APT::Force-LoopBreak",false) == false)
546 return _error->Error(_("This installation run will require temporarily "
547 "removing the essential package %s due to a "
548 "Conflicts/Pre-Depends loop. This is often bad, "
549 "but if you really want to do it, activate the "
550 "APT::Force-LoopBreak option."),Pkg.Name());
551 }
552
553 bool Res = SmartRemove(Pkg);
554 if (Cache[Pkg].Delete() == false)
555 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
556
557 return Res;
558 }
559 /*}}}*/
560 // PM::SmartRemove - Removal Helper /*{{{*/
561 // ---------------------------------------------------------------------
562 /* */
563 bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
564 {
565 if (List->IsNow(Pkg) == false)
566 return true;
567
568 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
569
570 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
571 return true;
572 }
573 /*}}}*/
574 // PM::SmartUnPack - Install helper /*{{{*/
575 // ---------------------------------------------------------------------
576 /* This performs the task of handling pre-depends. */
577 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
578 {
579 return SmartUnPack(Pkg, true);
580 }
581 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate)
582 {
583 if (Debug == true)
584 clog << "SmartUnPack " << Pkg.Name() << endl;
585
586 // Check if it is already unpacked
587 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
588 Cache[Pkg].Keep() == true)
589 {
590 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
591 if (Immediate == true &&
592 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
593 if (SmartConfigure(Pkg) == false)
594 return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'. "
595 "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
596 return true;
597 }
598
599 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
600
601 /* See if this packages install version has any predependencies
602 that are not met by 'now' packages. */
603 for (DepIterator D = instVer.DependsList();
604 D.end() == false; )
605 {
606 // Compute a single dependency element (glob or)
607 pkgCache::DepIterator Start;
608 pkgCache::DepIterator End;
609 D.GlobOr(Start,End);
610
611 while (End->Type == pkgCache::Dep::PreDepends)
612 {
613 if (Debug == true)
614 clog << "PreDepends order for " << Pkg.Name() << std::endl;
615
616 // Look for possible ok targets.
617 SPtrArray<Version *> VList = Start.AllTargets();
618 bool Bad = true;
619 for (Version **I = VList; *I != 0 && Bad == true; I++)
620 {
621 VerIterator Ver(Cache,*I);
622 PkgIterator Pkg = Ver.ParentPkg();
623
624 // See if the current version is ok
625 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
626 Pkg.State() == PkgIterator::NeedsNothing)
627 {
628 Bad = false;
629 if (Debug == true)
630 clog << "Found ok package " << Pkg.Name() << endl;
631 continue;
632 }
633 }
634
635 // Look for something that could be configured.
636 for (Version **I = VList; *I != 0 && Bad == true; I++)
637 {
638 VerIterator Ver(Cache,*I);
639 PkgIterator Pkg = Ver.ParentPkg();
640
641 // Not the install version
642 if (Cache[Pkg].InstallVer != *I ||
643 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
644 continue;
645
646 if (Debug == true)
647 clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
648 Bad = !SmartConfigure(Pkg);
649 }
650
651 /* If this or element did not match then continue on to the
652 next or element until a matching element is found */
653 if (Bad == true)
654 {
655 // This triggers if someone make a pre-depends/depend loop.
656 if (Start == End)
657 return _error->Error("Couldn't configure pre-depend %s for %s, "
658 "probably a dependency cycle.",
659 End.TargetPkg().Name(),Pkg.Name());
660 Start++;
661 }
662 else
663 break;
664 }
665
666 if (End->Type == pkgCache::Dep::Conflicts ||
667 End->Type == pkgCache::Dep::Obsoletes)
668 {
669 /* Look for conflicts. Two packages that are both in the install
670 state cannot conflict so we don't check.. */
671 SPtrArray<Version *> VList = End.AllTargets();
672 for (Version **I = VList; *I != 0; I++)
673 {
674 VerIterator Ver(Cache,*I);
675 PkgIterator Pkg = Ver.ParentPkg();
676
677 // See if the current version is conflicting
678 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true)
679 {
680 if (EarlyRemove(Pkg) == false)
681 return _error->Error("Internal Error, Could not early remove %s",Pkg.Name());
682 }
683 }
684 }
685
686 // Check for breaks
687 if (End->Type == pkgCache::Dep::DpkgBreaks) {
688 SPtrArray<Version *> VList = End.AllTargets();
689 for (Version **I = VList; *I != 0; I++)
690 {
691 VerIterator Ver(Cache,*I);
692 PkgIterator Pkg = Ver.ParentPkg();
693 // Found a break, so unpack the package
694 if (List->IsNow(Pkg)) {
695 SmartUnPack(Pkg, false);
696 }
697 }
698 }
699 }
700
701 // Check for reverse conflicts.
702 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
703 instVer.VerStr()) == false)
704 return false;
705
706 for (PrvIterator P = instVer.ProvidesList();
707 P.end() == false; P++)
708 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
709
710 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
711
712 if (instVer->MultiArch == pkgCache::Version::Same)
713 for (PkgIterator P = Pkg.Group().PackageList();
714 P.end() == false; P = Pkg.Group().NextPkg(P))
715 {
716 if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
717 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
718 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
719 continue;
720 SmartUnPack(P, false);
721 }
722
723 if(Install(Pkg,FileNames[Pkg->ID]) == false)
724 return false;
725
726 // Perform immedate configuration of the package.
727 if (Immediate == true &&
728 List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
729 if (SmartConfigure(Pkg) == false)
730 return _error->Error(_("Could not perform immediate configuration on '%s'. "
731 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
732
733 return true;
734 }
735 /*}}}*/
736 // PM::OrderInstall - Installation ordering routine /*{{{*/
737 // ---------------------------------------------------------------------
738 /* */
739 pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
740 {
741 if (CreateOrderList() == false)
742 return Failed;
743
744 Reset();
745
746 if (Debug == true)
747 clog << "Beginning to order" << endl;
748
749 bool const ordering =
750 _config->FindB("PackageManager::UnpackAll",true) ?
751 List->OrderUnpack(FileNames) : List->OrderCritical();
752 if (ordering == false)
753 {
754 _error->Error("Internal ordering error");
755 return Failed;
756 }
757
758 if (Debug == true)
759 clog << "Done ordering" << endl;
760
761 bool DoneSomething = false;
762 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
763 {
764 PkgIterator Pkg(Cache,*I);
765
766 if (List->IsNow(Pkg) == false)
767 {
768 if (Debug == true)
769 clog << "Skipping already done " << Pkg.Name() << endl;
770 continue;
771 }
772
773 if (List->IsMissing(Pkg) == true)
774 {
775 if (Debug == true)
776 clog << "Sequence completed at " << Pkg.Name() << endl;
777 if (DoneSomething == false)
778 {
779 _error->Error("Internal Error, ordering was unable to handle the media swap");
780 return Failed;
781 }
782 return Incomplete;
783 }
784
785 // Sanity check
786 if (Cache[Pkg].Keep() == true &&
787 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
788 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
789 {
790 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name());
791 return Failed;
792 }
793
794 // Perform a delete or an install
795 if (Cache[Pkg].Delete() == true)
796 {
797 if (SmartRemove(Pkg) == false)
798 return Failed;
799 }
800 else
801 if (SmartUnPack(Pkg) == false)
802 return Failed;
803 DoneSomething = true;
804 }
805
806 // Final run through the configure phase
807 if (ConfigureAll() == false)
808 return Failed;
809
810 // Sanity check
811 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
812 {
813 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
814 {
815 _error->Error("Internal error, packages left unconfigured. %s",
816 PkgIterator(Cache,*I).Name());
817 return Failed;
818 }
819 }
820
821 return Completed;
822 }
823 /*}}}*/
824 // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
825 // ---------------------------------------------------------------------
826 pkgPackageManager::OrderResult
827 pkgPackageManager::DoInstallPostFork(int statusFd)
828 {
829 if(statusFd > 0)
830 // FIXME: use SetCloseExec here once it taught about throwing
831 // exceptions instead of doing _exit(100) on failure
832 fcntl(statusFd,F_SETFD,FD_CLOEXEC);
833 bool goResult = Go(statusFd);
834 if(goResult == false)
835 return Failed;
836
837 return Res;
838 };
839
840 // PM::DoInstall - Does the installation /*{{{*/
841 // ---------------------------------------------------------------------
842 /* This uses the filenames in FileNames and the information in the
843 DepCache to perform the installation of packages.*/
844 pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
845 {
846 if(DoInstallPreFork() == Failed)
847 return Failed;
848
849 return DoInstallPostFork(statusFd);
850 }
851 /*}}}*/