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