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