]> git.saurik.com Git - apt.git/blame - apt-pkg/packagemanager.cc
properly handle already reinstall pkgs in ordering
[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 /*{{{*/
453b82a3 16#include <config.h>
ea542140 17
094a497d
AL
18#include <apt-pkg/packagemanager.h>
19#include <apt-pkg/orderlist.h>
20#include <apt-pkg/depcache.h>
21#include <apt-pkg/error.h>
22#include <apt-pkg/version.h>
03e39e59 23#include <apt-pkg/acquire-item.h>
30e1eab5
AL
24#include <apt-pkg/algorithms.h>
25#include <apt-pkg/configuration.h>
b2e465d6 26#include <apt-pkg/sptr.h>
453b82a3
DK
27#include <apt-pkg/macros.h>
28#include <apt-pkg/pkgcache.h>
29#include <apt-pkg/cacheiterators.h>
30#include <apt-pkg/strutl.h>
b58f28d4 31#include <apt-pkg/install-progress.h>
453b82a3
DK
32
33#include <stddef.h>
34#include <list>
35#include <string>
5819a761 36#include <iostream>
a00a9b44
DK
37
38#include <apti18n.h>
92fcbfc1 39 /*}}}*/
5819a761
AL
40using namespace std;
41
590f1923
CB
42bool pkgPackageManager::SigINTStop = false;
43
6c139d6e
AL
44// PM::PackageManager - Constructor /*{{{*/
45// ---------------------------------------------------------------------
46/* */
dcaa1185
DK
47pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache),
48 List(NULL), Res(Incomplete)
6c139d6e
AL
49{
50 FileNames = new string[Cache.Head().PackageCount];
30e1eab5 51 Debug = _config->FindB("Debug::pkgPackageManager",false);
dcaa1185
DK
52 NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
53 ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false);
6c139d6e
AL
54}
55 /*}}}*/
56// PM::PackageManager - Destructor /*{{{*/
57// ---------------------------------------------------------------------
58/* */
59pkgPackageManager::~pkgPackageManager()
60{
61 delete List;
62 delete [] FileNames;
63}
64 /*}}}*/
03e39e59
AL
65// PM::GetArchives - Queue the archives for download /*{{{*/
66// ---------------------------------------------------------------------
67/* */
68bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
69 pkgRecords *Recs)
70{
7a1b1f8b
AL
71 if (CreateOrderList() == false)
72 return false;
73
5e312de7
DK
74 bool const ordering =
75 _config->FindB("PackageManager::UnpackAll",true) ?
76 List->OrderUnpack() : List->OrderCritical();
77 if (ordering == false)
7a1b1f8b
AL
78 return _error->Error("Internal ordering error");
79
91c03d37 80 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
7a1b1f8b
AL
81 {
82 PkgIterator Pkg(Cache,*I);
281daf46
AL
83 FileNames[Pkg->ID] = string();
84
7a1b1f8b
AL
85 // Skip packages to erase
86 if (Cache[Pkg].Delete() == true)
03e39e59 87 continue;
d38b7b3d
AL
88
89 // Skip Packages that need configure only.
9dbb421f
AL
90 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
91 Cache[Pkg].Keep() == true)
d38b7b3d 92 continue;
281daf46
AL
93
94 // Skip already processed packages
95 if (List->IsNow(Pkg) == false)
96 continue;
803ea2a8 97
7a1b1f8b
AL
98 new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
99 FileNames[Pkg->ID]);
03e39e59 100 }
7a1b1f8b 101
03e39e59
AL
102 return true;
103}
104 /*}}}*/
6c139d6e
AL
105// PM::FixMissing - Keep all missing packages /*{{{*/
106// ---------------------------------------------------------------------
107/* This is called to correct the installation when packages could not
108 be downloaded. */
109bool pkgPackageManager::FixMissing()
bdae53f1 110{
e6756cde 111 pkgDepCache::ActionGroup group(Cache);
b2e465d6 112 pkgProblemResolver Resolve(&Cache);
2fd65468 113 List->SetFileList(FileNames);
e6756cde 114
9dbb421f 115 bool Bad = false;
f7f0d6c7 116 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 117 {
2fd65468 118 if (List->IsMissing(I) == false)
9dbb421f 119 continue;
2fd65468 120
9dbb421f
AL
121 // Okay, this file is missing and we need it. Mark it for keep
122 Bad = true;
74a05226 123 Cache.MarkKeep(I, false, false);
6c139d6e 124 }
bdae53f1
AL
125
126 // We have to empty the list otherwise it will not have the new changes
127 delete List;
128 List = 0;
6c139d6e 129
9dbb421f
AL
130 if (Bad == false)
131 return true;
132
6c139d6e 133 // Now downgrade everything that is broken
30e1eab5 134 return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
6c139d6e
AL
135}
136 /*}}}*/
3a6d37fd
MV
137// PM::ImmediateAdd - Add the immediate flag recursivly /*{{{*/
138// ---------------------------------------------------------------------
139/* This adds the immediate flag to the pkg and recursively to the
140 dependendies
141 */
d183f850 142void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned const int &Depth)
3a6d37fd
MV
143{
144 DepIterator D;
145
146 if(UseInstallVer)
147 {
148 if(Cache[I].InstallVer == 0)
149 return;
150 D = Cache[I].InstVerIter(Cache).DependsList();
151 } else {
152 if (I->CurrentVer == 0)
153 return;
154 D = I.CurrentVer().DependsList();
155 }
156
f7f0d6c7 157 for ( /* nothing */ ; D.end() == false; ++D)
3a6d37fd
MV
158 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
159 {
160 if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
161 {
162 if(Debug)
90436124 163 clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.FullName() << endl;
3a6d37fd 164 List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
d183f850 165 ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
3a6d37fd
MV
166 }
167 }
168 return;
169}
170 /*}}}*/
7a1b1f8b
AL
171// PM::CreateOrderList - Create the ordering class /*{{{*/
172// ---------------------------------------------------------------------
173/* This populates the ordering list with all the packages that are
174 going to change. */
175bool pkgPackageManager::CreateOrderList()
176{
281daf46
AL
177 if (List != 0)
178 return true;
179
7a1b1f8b 180 delete List;
b2e465d6 181 List = new pkgOrderList(&Cache);
dcaa1185 182
a6c8798a
CB
183 if (Debug && ImmConfigureAll)
184 clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl;
079cc404 185
7a1b1f8b 186 // Generate the list of affected packages and sort it
f7f0d6c7 187 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
7a1b1f8b 188 {
e7b470ee
AL
189 // Ignore no-version packages
190 if (I->VersionList == 0)
191 continue;
192
138d4b3d 193 // Mark the package and its dependends for immediate configuration
fb805d80 194 if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) &&
a6c8798a 195 NoImmConfigure == false) || ImmConfigureAll)
7a1b1f8b 196 {
a6c8798a 197 if(Debug && !ImmConfigureAll)
90436124 198 clog << "CreateOrderList(): Adding Immediate flag for " << I.FullName() << endl;
7a1b1f8b 199 List->Flag(I,pkgOrderList::Immediate);
d38b7b3d 200
a6c8798a 201 if (!ImmConfigureAll) {
a6c8798a
CB
202 // Look for other install packages to make immediate configurea
203 ImmediateAdd(I, true);
e2a5ff0c 204
a6c8798a
CB
205 // And again with the current version.
206 ImmediateAdd(I, false);
207 }
7a1b1f8b
AL
208 }
209
210 // Not interesting
211 if ((Cache[I].Keep() == true ||
212 Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
d556d1a1 213 I.State() == pkgCache::PkgIterator::NeedsNothing &&
d0c59649 214 (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
d556d1a1
AL
215 (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
216 (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
7a1b1f8b
AL
217 continue;
218
219 // Append it to the list
138d4b3d 220 List->push_back(I);
7a1b1f8b
AL
221 }
222
223 return true;
224}
225 /*}}}*/
1e3f4083 226// PM::DepAlwaysTrue - Returns true if this dep is irrelevant /*{{{*/
6c139d6e
AL
227// ---------------------------------------------------------------------
228/* The restriction on provides is to eliminate the case when provides
229 are transitioning between valid states [ie exim to smail] */
230bool pkgPackageManager::DepAlwaysTrue(DepIterator D)
231{
232 if (D.TargetPkg()->ProvidesList != 0)
233 return false;
234
235 if ((Cache[D] & pkgDepCache::DepInstall) != 0 &&
236 (Cache[D] & pkgDepCache::DepNow) != 0)
237 return true;
238 return false;
239}
240 /*}}}*/
241// PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
242// ---------------------------------------------------------------------
243/* This looks over the reverses for a conflicts line that needs early
244 removal. */
245bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
246 const char *Ver)
247{
f7f0d6c7 248 for (;D.end() == false; ++D)
6c139d6e 249 {
b2e465d6
AL
250 if (D->Type != pkgCache::Dep::Conflicts &&
251 D->Type != pkgCache::Dep::Obsoletes)
6c139d6e 252 continue;
5af32db6 253
1e3f4083 254 // The package hasn't been changed
5af32db6
AL
255 if (List->IsNow(Pkg) == false)
256 continue;
6c139d6e 257
1e3f4083 258 // Ignore self conflicts, ignore conflicts from irrelevant versions
85434114 259 if (D.IsIgnorable(Pkg) || D.ParentVer() != D.ParentPkg().CurrentVer())
6c139d6e
AL
260 continue;
261
b2e465d6 262 if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
6c139d6e 263 continue;
b2e465d6 264
0eb4af9d 265 if (EarlyRemove(D.ParentPkg(), &D) == false)
5af32db6 266 return _error->Error("Reverse conflicts early remove for package '%s' failed",
90436124 267 Pkg.FullName().c_str());
5af32db6 268 }
6c139d6e
AL
269 return true;
270}
271 /*}}}*/
272// PM::ConfigureAll - Run the all out configuration /*{{{*/
273// ---------------------------------------------------------------------
274/* This configures every package. It is assumed they are all unpacked and
590f1923
CB
275 that the final configuration is valid. This is also used to catch packages
276 that have not been configured when using ImmConfigureAll */
6c139d6e
AL
277bool pkgPackageManager::ConfigureAll()
278{
b2e465d6 279 pkgOrderList OList(&Cache);
6c139d6e
AL
280
281 // Populate the order list
91c03d37 282 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
6c139d6e
AL
283 if (List->IsFlag(pkgCache::PkgIterator(Cache,*I),
284 pkgOrderList::UnPacked) == true)
285 OList.push_back(*I);
286
287 if (OList.OrderConfigure() == false)
288 return false;
5e312de7
DK
289
290 std::string const conf = _config->Find("PackageManager::Configure","all");
291 bool const ConfigurePkgs = (conf == "all");
292
6c139d6e 293 // Perform the configuring
91c03d37 294 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); ++I)
6c139d6e
AL
295 {
296 PkgIterator Pkg(Cache,*I);
17182c0c
CB
297
298 /* Check if the package has been configured, this can happen if SmartConfigure
299 calls its self */
300 if (List->IsFlag(Pkg,pkgOrderList::Configured)) continue;
803ea2a8 301
d41d0e01 302 if (ConfigurePkgs == true && SmartConfigure(Pkg, 0) == false) {
c7c7d3e8
CB
303 if (ImmConfigureAll)
304 _error->Error(_("Could not perform immediate configuration on '%s'. "
90436124 305 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),1);
c7c7d3e8 306 else
90436124 307 _error->Error("Internal error, packages left unconfigured. %s",Pkg.FullName().c_str());
6c139d6e 308 return false;
634985f8 309 }
6c139d6e
AL
310
311 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
312 }
313
314 return true;
315}
316 /*}}}*/
0eb4af9d
DK
317// PM::NonLoopingSmart - helper to avoid loops while calling Smart methods /*{{{*/
318// -----------------------------------------------------------------------
319/* ensures that a loop of the form A depends B, B depends A (and similar)
320 is not leading us down into infinite recursion segfault land */
321bool pkgPackageManager::NonLoopingSmart(SmartAction const action, pkgCache::PkgIterator &Pkg,
322 pkgCache::PkgIterator DepPkg, int const Depth, bool const PkgLoop,
323 bool * const Bad, bool * const Changed)
324{
325 if (PkgLoop == false)
326 List->Flag(Pkg,pkgOrderList::Loop);
327 bool success = false;
328 switch(action)
329 {
330 case UNPACK_IMMEDIATE: success = SmartUnPack(DepPkg, true, Depth + 1); break;
331 case UNPACK: success = SmartUnPack(DepPkg, false, Depth + 1); break;
332 case CONFIGURE: success = SmartConfigure(DepPkg, Depth + 1); break;
333 }
334 if (PkgLoop == false)
335 List->RmFlag(Pkg,pkgOrderList::Loop);
336
337 if (success == false)
338 return false;
339
340 if (Bad != NULL)
341 *Bad = false;
342 if (Changed != NULL && List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
343 *Changed = true;
344 return true;
345}
346 /*}}}*/
6c139d6e
AL
347// PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
348// ---------------------------------------------------------------------
c7c7d3e8 349/* This function tries to put the system in a state where Pkg can be configured.
0eb4af9d
DK
350 This involves checking each of Pkg's dependencies and unpacking and
351 configuring packages where needed. */
d41d0e01 352bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
6c139d6e 353{
38ff3de6 354 // If this is true, only check and correct and dependencies without the Loop flag
2dd2c801 355 bool const PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
d41d0e01 356
987d8d03
CB
357 if (Debug) {
358 VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
90436124 359 clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.FullName() << " (" << InstallVer.VerStr() << ")";
d41d0e01 360 if (PkgLoop)
38ff3de6 361 clog << " (Only Correct Dependencies)";
d41d0e01 362 clog << endl;
987d8d03 363 }
0eacf067 364
590f1923 365 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
0eb4af9d
DK
366
367 /* Because of the ordered list, most dependencies should be unpacked,
368 however if there is a loop (A depends on B, B depends on A) this will not
38ff3de6 369 be the case, so check for dependencies before configuring. */
2dd2c801 370 bool Bad = false, Changed = false;
9c5104cf 371 const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
bce4caa3 372 unsigned int i=0;
42d51f33 373 std::list<DepIterator> needConfigure;
bce4caa3
MV
374 do
375 {
2f589691
MV
376 // Check each dependency and see if anything needs to be done
377 // so that it can be configured
2dd2c801
DK
378 Changed = false;
379 for (DepIterator D = instVer.DependsList(); D.end() == false; )
380 {
381 // Compute a single dependency element (glob or)
382 pkgCache::DepIterator Start, End;
383 D.GlobOr(Start,End);
384
385 if (End->Type != pkgCache::Dep::Depends)
386 continue;
387 Bad = true;
388
2f589691
MV
389 // the first pass checks if we its all good, i.e. if we have
390 // to do anything at all
2dd2c801
DK
391 for (DepIterator Cur = Start; true; ++Cur)
392 {
393 SPtrArray<Version *> VList = Cur.AllTargets();
394
395 for (Version **I = VList; *I != 0; ++I)
6c139d6e 396 {
2dd2c801
DK
397 VerIterator Ver(Cache,*I);
398 PkgIterator DepPkg = Ver.ParentPkg();
399
400 // Check if the current version of the package is available and will satisfy this dependency
401 if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
402 List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
4e6a7e26
DK
403 DepPkg.State() == PkgIterator::NeedsNothing &&
404 (Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
2dd2c801
DK
405 {
406 Bad = false;
407 break;
408 }
409
2f589691
MV
410 // Check if the version that is going to be installed will satisfy the dependency
411 if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
412 continue;
413
414 if (PkgLoop == true)
415 {
416 if (Debug)
4e6a7e26
DK
417 std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
418 if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
419 Bad = false;
420 else if (Debug)
421 std::clog << ", but it isn't unpacked yet";
422 if (Debug)
423 std::clog << std::endl;
2f589691
MV
424 }
425 }
426
427 if (Cur == End || Bad == false)
428 break;
429 }
430
431 // this dependency is in a good state, so we can stop
432 if (Bad == false)
433 {
434 if (Debug)
4e6a7e26 435 std::clog << OutputInDepth(Depth) << "Found ok dep " << Start.TargetPkg() << std::endl;
2f589691
MV
436 continue;
437 }
438
439 // Check for dependencies that have not been unpacked,
440 // probably due to loops.
441 for (DepIterator Cur = Start; true; ++Cur)
442 {
443 SPtrArray<Version *> VList = Cur.AllTargets();
444
445 for (Version **I = VList; *I != 0; ++I)
446 {
447 VerIterator Ver(Cache,*I);
448 PkgIterator DepPkg = Ver.ParentPkg();
449
450 // Check if the current version of the package is available and will satisfy this dependency
451 if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
452 List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
4e6a7e26
DK
453 DepPkg.State() == PkgIterator::NeedsNothing &&
454 (Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
2f589691
MV
455 continue;
456
2dd2c801 457 // Check if the version that is going to be installed will satisfy the dependency
42d51f33 458 if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
2dd2c801
DK
459 continue;
460
42d51f33 461 if (PkgLoop == true)
2dd2c801 462 {
42d51f33 463 if (Debug)
4e6a7e26
DK
464 std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
465 if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
466 Bad = false;
467 else if (Debug)
468 std::clog << ", but it isn't unpacked yet";
469 if (Debug)
470 std::clog << std::endl;
42d51f33
DK
471 }
472 else
473 {
474 if (Debug)
475 clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl;
0eb4af9d 476 if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
71e7a0f3 477 return false;
2dd2c801 478 }
2f589691
MV
479 // at this point we either unpacked a Dep or we are in a loop,
480 // no need to unpack a second one
0eb4af9d 481 break;
590f1923 482 }
42d51f33
DK
483
484 if (Cur == End || Bad == false)
2dd2c801 485 break;
42d51f33 486 }
2dd2c801
DK
487
488 if (Bad == false)
489 continue;
490
42d51f33
DK
491 needConfigure.push_back(Start);
492 }
493 if (i++ > max_loops)
494 return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (1) for %s, aborting", Pkg.FullName().c_str());
495 } while (Changed == true);
496
2f589691 497 // now go over anything that needs configuring
42d51f33
DK
498 Bad = false, Changed = false, i = 0;
499 do
500 {
501 Changed = false;
6420c00e 502 for (std::list<DepIterator>::const_iterator D = needConfigure.begin(); D != needConfigure.end(); ++D)
42d51f33 503 {
6420c00e 504 // Compute a single dependency element (glob or) without modifying D
42d51f33 505 pkgCache::DepIterator Start, End;
6420c00e
DK
506 {
507 pkgCache::DepIterator Discard = *D;
508 Discard.GlobOr(Start,End);
509 }
42d51f33
DK
510
511 if (End->Type != pkgCache::Dep::Depends)
512 continue;
513 Bad = true;
514
515 // Search for dependencies which are unpacked but aren't configured yet (maybe loops)
2dd2c801
DK
516 for (DepIterator Cur = Start; true; ++Cur)
517 {
518 SPtrArray<Version *> VList = Cur.AllTargets();
519
520 for (Version **I = VList; *I != 0; ++I)
521 {
522 VerIterator Ver(Cache,*I);
523 PkgIterator DepPkg = Ver.ParentPkg();
524
525 // Check if the version that is going to be installed will satisfy the dependency
42d51f33 526 if (Cache[DepPkg].InstallVer != *I)
2dd2c801
DK
527 continue;
528
42d51f33 529 if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
d9f6c795 530 {
42d51f33
DK
531 if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop)
532 {
533 // This dependency has already been dealt with by another SmartConfigure on Pkg
534 Bad = false;
535 break;
536 }
0eb4af9d
DK
537 if (Debug)
538 std::clog << OutputInDepth(Depth) << "Configure already unpacked " << DepPkg << std::endl;
539 if (NonLoopingSmart(CONFIGURE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
71e7a0f3 540 return false;
71e7a0f3 541 break;
0eb4af9d 542
d9f6c795 543 }
42d51f33
DK
544 else if (List->IsFlag(DepPkg,pkgOrderList::Configured))
545 {
546 Bad = false;
547 break;
548 }
590f1923 549 }
42d51f33 550 if (Cur == End || Bad == false)
2dd2c801 551 break;
42d51f33
DK
552 }
553
554
2dd2c801 555 if (Bad == true && Changed == false && Debug == true)
6420c00e 556 std::clog << OutputInDepth(Depth) << "Could not satisfy " << *D << std::endl;
6c139d6e 557 }
bce4caa3 558 if (i++ > max_loops)
42d51f33 559 return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (2) for %s, aborting", Pkg.FullName().c_str());
2dd2c801 560 } while (Changed == true);
0eb4af9d 561
71e7a0f3
DK
562 if (Bad == true)
563 return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str());
0eb4af9d 564
a99d02a8 565 if (PkgLoop) return true;
5e312de7
DK
566
567 static std::string const conf = _config->Find("PackageManager::Configure","all");
568 static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
569
0eb4af9d 570 if (List->IsFlag(Pkg,pkgOrderList::Configured))
90436124 571 return _error->Error("Internal configure error on '%s'.", Pkg.FullName().c_str());
5e312de7 572
590f1923
CB
573 if (ConfigurePkgs == true && Configure(Pkg) == false)
574 return false;
75a90b93 575
590f1923 576 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
6c139d6e 577
894d672e 578 if ((Cache[Pkg].InstVerIter(Cache)->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
d77b985a
DK
579 for (PkgIterator P = Pkg.Group().PackageList();
580 P.end() == false; P = Pkg.Group().NextPkg(P))
581 {
582 if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true ||
2b8b1e7a 583 List->IsFlag(P,pkgOrderList::UnPacked) == false ||
d77b985a
DK
584 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
585 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
586 continue;
71e7a0f3
DK
587 if (SmartConfigure(P, (Depth +1)) == false)
588 return false;
d77b985a
DK
589 }
590
6c139d6e
AL
591 // Sanity Check
592 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
90436124 593 return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str());
20382bad 594
6c139d6e
AL
595 return true;
596}
597 /*}}}*/
6c139d6e
AL
598// PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
599// ---------------------------------------------------------------------
600/* This is called to deal with conflicts arising from unpacking */
601bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
0eb4af9d
DK
602{
603 return EarlyRemove(Pkg, NULL);
604}
605bool pkgPackageManager::EarlyRemove(PkgIterator Pkg, DepIterator const * const Dep)
6c139d6e
AL
606{
607 if (List->IsNow(Pkg) == false)
608 return true;
0eb4af9d 609
6c139d6e
AL
610 // Already removed it
611 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
612 return true;
0eb4af9d 613
6c139d6e
AL
614 // Woops, it will not be re-installed!
615 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
616 return false;
9d4c8f67 617
0eb4af9d
DK
618 // these breaks on M-A:same packages can be dealt with. They 'loop' by design
619 if (Dep != NULL && (*Dep)->Type == pkgCache::Dep::DpkgBreaks && Dep->IsMultiArchImplicit() == true)
620 return true;
621
9d4c8f67 622 // Essential packages get special treatment
5af32db6 623 bool IsEssential = false;
c5200869
JAK
624 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0 ||
625 (Pkg->Flags & pkgCache::Flag::Important) != 0)
5af32db6
AL
626 IsEssential = true;
627
0eb4af9d 628 /* Check for packages that are the dependents of essential packages and
5af32db6
AL
629 promote them too */
630 if (Pkg->CurrentVer != 0)
631 {
0eb4af9d 632 for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() == false &&
f7f0d6c7 633 IsEssential == false; ++D)
5af32db6 634 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
c5200869
JAK
635 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0 ||
636 (D.ParentPkg()->Flags & pkgCache::Flag::Important) != 0)
5af32db6
AL
637 IsEssential = true;
638 }
639
640 if (IsEssential == true)
9d4c8f67
AL
641 {
642 if (_config->FindB("APT::Force-LoopBreak",false) == false)
b2e465d6
AL
643 return _error->Error(_("This installation run will require temporarily "
644 "removing the essential package %s due to a "
645 "Conflicts/Pre-Depends loop. This is often bad, "
646 "but if you really want to do it, activate the "
90436124 647 "APT::Force-LoopBreak option."),Pkg.FullName().c_str());
9d4c8f67 648 }
0eb4af9d
DK
649 // dpkg will auto-deconfigure it, no need for the big remove hammer
650 else if (Dep != NULL && (*Dep)->Type == pkgCache::Dep::DpkgBreaks)
651 return true;
652
6c139d6e
AL
653 bool Res = SmartRemove(Pkg);
654 if (Cache[Pkg].Delete() == false)
655 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
0eb4af9d 656
6c139d6e
AL
657 return Res;
658}
659 /*}}}*/
660// PM::SmartRemove - Removal Helper /*{{{*/
661// ---------------------------------------------------------------------
662/* */
663bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
664{
665 if (List->IsNow(Pkg) == false)
666 return true;
667
668 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
803ea2a8 669
28166356 670 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
6c139d6e
AL
671}
672 /*}}}*/
673// PM::SmartUnPack - Install helper /*{{{*/
674// ---------------------------------------------------------------------
1e3f4083 675/* This puts the system in a state where it can Unpack Pkg, if Pkg is already
590f1923 676 unpacked, or when it has been unpacked, if Immediate==true it configures it. */
6c139d6e 677bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
d77b985a 678{
d41d0e01 679 return SmartUnPack(Pkg, true, 0);
d77b985a 680}
d41d0e01 681bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int const Depth)
6c139d6e 682{
d41d0e01
CB
683 bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
684
987d8d03 685 if (Debug) {
90436124 686 clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.FullName();
987d8d03
CB
687 VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
688 if (Pkg.CurrentVer() == 0)
c4f931f8 689 clog << " (install version " << InstallVer.VerStr() << ")";
987d8d03 690 else
c4f931f8 691 clog << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")";
d41d0e01 692 if (PkgLoop)
c4f931f8 693 clog << " (Only Perform PreUnpack Checks)";
0caa5a4c
DK
694 if (Immediate)
695 clog << " immediately";
c4f931f8 696 clog << endl;
987d8d03 697 }
cfcdf7fe 698
d77b985a
DK
699 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
700
0eb4af9d 701 /* PreUnpack Checks: This loop checks and attempts to rectify any problems that would prevent the package being unpacked.
98ee4922 702 It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should
c7c7d3e8 703 avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with
0eb4af9d 704 complex dependency structures, trying to configure some packages while breaking the loops can complicate things.
98ee4922 705 This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
c7c7d3e8 706 or by the ConfigureAll call at the end of the for loop in OrderInstall. */
0eb4af9d
DK
707 bool SomethingBad = false, Changed = false;
708 bool couldBeTemporaryRemoved = Depth != 0 && List->IsFlag(Pkg,pkgOrderList::Removed) == false;
9c5104cf 709 const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
5ab7b53b 710 unsigned int i = 0;
bce4caa3
MV
711 do
712 {
98ee4922
DK
713 Changed = false;
714 for (DepIterator D = instVer.DependsList(); D.end() == false; )
6c139d6e 715 {
98ee4922
DK
716 // Compute a single dependency element (glob or)
717 pkgCache::DepIterator Start, End;
718 D.GlobOr(Start,End);
f4945db3 719
98ee4922
DK
720 if (End->Type == pkgCache::Dep::PreDepends)
721 {
722 bool Bad = true;
723 if (Debug)
724 clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.FullName() << std::endl;
725
726 // Look for easy targets: packages that are already okay
727 for (DepIterator Cur = Start; Bad == true; ++Cur)
6c139d6e 728 {
d8e25d34 729 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
730 for (Version **I = VList; *I != 0; ++I)
731 {
732 VerIterator Ver(Cache,*I);
733 PkgIterator Pkg = Ver.ParentPkg();
734
735 // See if the current version is ok
736 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
4e6a7e26
DK
737 Pkg.State() == PkgIterator::NeedsNothing &&
738 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
98ee4922
DK
739 {
740 Bad = false;
741 if (Debug)
742 clog << OutputInDepth(Depth) << "Found ok package " << Pkg.FullName() << endl;
743 break;
744 }
745 }
746 if (Cur == End)
747 break;
17182c0c 748 }
6c139d6e 749
98ee4922 750 // Look for something that could be configured.
275024e9 751 for (DepIterator Cur = Start; Bad == true && Cur.end() == false; ++Cur)
98ee4922 752 {
d8e25d34 753 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
754 for (Version **I = VList; *I != 0; ++I)
755 {
756 VerIterator Ver(Cache,*I);
0eb4af9d 757 PkgIterator DepPkg = Ver.ParentPkg();
1006601e 758
98ee4922 759 // Not the install version
4e6a7e26
DK
760 if (Cache[DepPkg].InstallVer != *I)
761 continue;
762
763 if (Cache[DepPkg].Keep() == true && DepPkg.State() == PkgIterator::NeedsNothing &&
764 (Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
98ee4922
DK
765 continue;
766
0eb4af9d 767 if (List->IsFlag(DepPkg,pkgOrderList::Configured))
98ee4922
DK
768 {
769 Bad = false;
770 break;
771 }
772
773 // check if it needs unpack or if if configure is enough
0eb4af9d 774 if (List->IsFlag(DepPkg,pkgOrderList::UnPacked) == false)
98ee4922 775 {
4e6a7e26
DK
776 // two packages pre-depending on each other can't be handled sanely
777 if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop)
778 {
779 // this isn't an error as there is potential for something else to satisfy it
780 // (like a provides or an or-group member)
781 if (Debug)
782 clog << OutputInDepth(Depth) << "Unpack loop detected between " << DepPkg.FullName() << " and " << Pkg.FullName() << endl;
783 continue;
784 }
785
98ee4922 786 if (Debug)
0eb4af9d
DK
787 clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << DepPkg.FullName() << endl;
788 if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
71e7a0f3 789 return false;
98ee4922
DK
790 }
791 else
792 {
793 if (Debug)
0eb4af9d
DK
794 clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << DepPkg.FullName() << endl;
795 if (NonLoopingSmart(CONFIGURE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
71e7a0f3 796 return false;
98ee4922 797 }
0eb4af9d 798 break;
e2a5ff0c 799 }
6c139d6e 800 }
98ee4922
DK
801
802 if (Bad == true)
0eb4af9d 803 SomethingBad = true;
6c139d6e 804 }
98ee4922 805 else if (End->Type == pkgCache::Dep::Conflicts ||
0eb4af9d
DK
806 End->Type == pkgCache::Dep::Obsoletes ||
807 End->Type == pkgCache::Dep::DpkgBreaks)
cfcdf7fe 808 {
98ee4922 809 SPtrArray<Version *> VList = End.AllTargets();
0eb4af9d 810 for (Version **I = VList; *I != 0; ++I)
3e9ab9f0 811 {
98ee4922
DK
812 VerIterator Ver(Cache,*I);
813 PkgIterator ConflictPkg = Ver.ParentPkg();
0eb4af9d
DK
814 if (ConflictPkg.CurrentVer() != Ver)
815 {
816 if (Debug)
817 std::clog << OutputInDepth(Depth) << "Ignore not-installed version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
818 continue;
819 }
3e9ab9f0 820
0eb4af9d 821 if (List->IsNow(ConflictPkg) == false)
98ee4922 822 {
2252183c 823 if (Debug)
0eb4af9d
DK
824 std::clog << OutputInDepth(Depth) << "Ignore already dealt-with version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
825 continue;
826 }
3e9ab9f0 827
0eb4af9d 828 if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
98ee4922 829 {
2252183c 830 if (Debug)
0eb4af9d
DK
831 clog << OutputInDepth(Depth) << "Ignoring " << End << " as " << ConflictPkg.FullName() << "was temporarily removed" << endl;
832 continue;
833 }
834
835 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) && PkgLoop)
836 {
837 if (End->Type == pkgCache::Dep::DpkgBreaks && End.IsMultiArchImplicit() == true)
440d3d65
DK
838 {
839 if (Debug)
0eb4af9d
DK
840 clog << OutputInDepth(Depth) << "Because dependency is MultiArchImplicit we ignored looping on: " << ConflictPkg << endl;
841 continue;
98ee4922 842 }
98ee4922 843 if (Debug)
440d3d65 844 {
0eb4af9d
DK
845 if (End->Type == pkgCache::Dep::DpkgBreaks)
846 clog << OutputInDepth(Depth) << "Because of breaks knot, deconfigure " << ConflictPkg.FullName() << " temporarily" << endl;
847 else
71e7a0f3 848 clog << OutputInDepth(Depth) << "Because of conflict knot, removing " << ConflictPkg.FullName() << " temporarily" << endl;
98ee4922 849 }
0eb4af9d
DK
850 if (EarlyRemove(ConflictPkg, &End) == false)
851 return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str());
852 SomethingBad = true;
98ee4922
DK
853 continue;
854 }
855
0eb4af9d 856 if (Cache[ConflictPkg].Delete() == false)
98ee4922 857 {
0eb4af9d 858 if (Debug)
98ee4922 859 {
0eb4af9d
DK
860 clog << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to avoid " << End;
861 if (PkgLoop == true)
862 clog << " (Looping)";
863 clog << std::endl;
440d3d65 864 }
0eb4af9d
DK
865 // we would like to avoid temporary removals and all that at best via a simple unpack
866 _error->PushToStack();
867 if (NonLoopingSmart(UNPACK, Pkg, ConflictPkg, Depth, PkgLoop, NULL, &Changed) == false)
2264548f 868 {
0eb4af9d
DK
869 // but if it fails ignore this failure and look for alternative ways of solving
870 if (Debug)
440d3d65 871 {
1df24acf 872 clog << OutputInDepth(Depth) << "Avoidance unpack of " << ConflictPkg.FullName() << " failed for " << End << " ignoring:" << std::endl;
0eb4af9d
DK
873 _error->DumpErrors(std::clog);
874 }
875 _error->RevertToStack();
876 // ignorance can only happen if a) one of the offenders is already gone
877 if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
440d3d65 878 {
0eb4af9d
DK
879 if (Debug)
880 clog << OutputInDepth(Depth) << "But " << ConflictPkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
98ee4922 881 }
0eb4af9d 882 else if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
98ee4922
DK
883 {
884 if (Debug)
0eb4af9d 885 clog << OutputInDepth(Depth) << "But " << Pkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
98ee4922 886 }
0eb4af9d 887 // or b) we can make one go (removal or dpkg auto-deconfigure)
98ee4922
DK
888 else
889 {
890 if (Debug)
0eb4af9d
DK
891 clog << OutputInDepth(Depth) << "So temprorary remove/deconfigure " << ConflictPkg.FullName() << " to satisfy " << End << endl;
892 if (EarlyRemove(ConflictPkg, &End) == false)
893 return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str());
440d3d65 894 }
2264548f 895 }
0eb4af9d
DK
896 else
897 _error->MergeWithStack();
6b92f60c 898 }
0eb4af9d 899 else
6b92f60c
DK
900 {
901 if (Debug)
0eb4af9d
DK
902 clog << OutputInDepth(Depth) << "Removing " << ConflictPkg.FullName() << " now to avoid " << End << endl;
903 // no earlyremove() here as user has already agreed to the permanent removal
904 if (SmartRemove(Pkg) == false)
905 return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str());
6b92f60c 906 }
6c139d6e
AL
907 }
908 }
6c139d6e 909 }
bce4caa3 910 if (i++ > max_loops)
91ea3def 911 return _error->Error("Internal error: APT::pkgPackageManager::MaxLoopCount reached in SmartConfigure for %s, aborting", Pkg.FullName().c_str());
98ee4922 912 } while (Changed == true);
0eb4af9d
DK
913
914 if (SomethingBad == true)
915 return _error->Error("Couldn't configure %s, probably a dependency cycle.", Pkg.FullName().c_str());
916
917 if (couldBeTemporaryRemoved == true && List->IsFlag(Pkg,pkgOrderList::Removed) == true)
918 {
919 if (Debug)
920 std::clog << OutputInDepth(Depth) << "Prevent unpack as " << Pkg << " is currently temporarily removed" << std::endl;
921 return true;
922 }
923
6c139d6e 924 // Check for reverse conflicts.
5af32db6 925 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
d77b985a 926 instVer.VerStr()) == false)
c7c7d3e8 927 return false;
5af32db6 928
d77b985a 929 for (PrvIterator P = instVer.ProvidesList();
f7f0d6c7 930 P.end() == false; ++P)
32d9baea
DK
931 if (Pkg->Group != P.OwnerPkg()->Group)
932 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
70ae2409 933
75a90b93
DK
934 if (PkgLoop)
935 return true;
940f2160 936
d77b985a
DK
937 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
938
2a2a7ef4 939 if (Immediate == true && (instVer->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
30426f48
DK
940 {
941 /* Do lockstep M-A:same unpacking in two phases:
942 First unpack all installed architectures, then the not installed.
943 This way we avoid that M-A: enabled packages are installed before
944 their older non-M-A enabled packages are replaced by newer versions */
945 bool const installed = Pkg->CurrentVer != 0;
36635720
DK
946 if (installed == true &&
947 (instVer != Pkg.CurrentVer() ||
948 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
949 Install(Pkg,FileNames[Pkg->ID]) == false)
30426f48 950 return false;
d77b985a
DK
951 for (PkgIterator P = Pkg.Group().PackageList();
952 P.end() == false; P = Pkg.Group().NextPkg(P))
953 {
30426f48 954 if (P->CurrentVer == 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
d77b985a
DK
955 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
956 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
957 continue;
75a90b93 958 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48 959 return false;
d77b985a 960 }
30426f48
DK
961 if (installed == false && Install(Pkg,FileNames[Pkg->ID]) == false)
962 return false;
963 for (PkgIterator P = Pkg.Group().PackageList();
964 P.end() == false; P = Pkg.Group().NextPkg(P))
965 {
966 if (P->CurrentVer != 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
2b8b1e7a 967 List->IsFlag(P,pkgOrderList::Configured) == true ||
30426f48
DK
968 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
969 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
970 continue;
75a90b93 971 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48
DK
972 return false;
973 }
974 }
cd5e8444 975 // packages which are already unpacked don't need to be unpacked again
d4b4e5ea
DK
976 else if ((instVer != Pkg.CurrentVer() ||
977 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
978 Install(Pkg,FileNames[Pkg->ID]) == false)
28166356
DK
979 return false;
980
d41d0e01 981 if (Immediate == true) {
590f1923 982 // Perform immedate configuration of the package.
d41d0e01 983 if (SmartConfigure(Pkg, Depth + 1) == false)
0eb4af9d 984 _error->Error(_("Could not perform immediate configuration on '%s'. "
90436124 985 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),2);
590f1923 986 }
6c139d6e
AL
987
988 return true;
989}
990 /*}}}*/
991// PM::OrderInstall - Installation ordering routine /*{{{*/
992// ---------------------------------------------------------------------
993/* */
281daf46 994pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
6c139d6e 995{
7a1b1f8b 996 if (CreateOrderList() == false)
281daf46
AL
997 return Failed;
998
999 Reset();
6c139d6e 1000
30e1eab5 1001 if (Debug == true)
5e312de7 1002 clog << "Beginning to order" << endl;
6c139d6e 1003
5e312de7
DK
1004 bool const ordering =
1005 _config->FindB("PackageManager::UnpackAll",true) ?
1006 List->OrderUnpack(FileNames) : List->OrderCritical();
1007 if (ordering == false)
281daf46
AL
1008 {
1009 _error->Error("Internal ordering error");
1010 return Failed;
1011 }
1012
30e1eab5
AL
1013 if (Debug == true)
1014 clog << "Done ordering" << endl;
1015
281daf46 1016 bool DoneSomething = false;
91c03d37 1017 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
6c139d6e
AL
1018 {
1019 PkgIterator Pkg(Cache,*I);
0caa5a4c 1020
281daf46
AL
1021 if (List->IsNow(Pkg) == false)
1022 {
0caa5a4c
DK
1023 if (Debug == true)
1024 clog << "Skipping already done " << Pkg.FullName() << endl;
281daf46
AL
1025 continue;
1026 }
0caa5a4c 1027
2fd65468 1028 if (List->IsMissing(Pkg) == true)
281daf46
AL
1029 {
1030 if (Debug == true)
90436124 1031 clog << "Sequence completed at " << Pkg.FullName() << endl;
281daf46
AL
1032 if (DoneSomething == false)
1033 {
1034 _error->Error("Internal Error, ordering was unable to handle the media swap");
1035 return Failed;
1036 }
1037 return Incomplete;
1038 }
6c139d6e
AL
1039
1040 // Sanity check
d0c59649
AL
1041 if (Cache[Pkg].Keep() == true &&
1042 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
1043 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
281daf46 1044 {
90436124 1045 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.FullName().c_str());
281daf46
AL
1046 return Failed;
1047 }
6c139d6e
AL
1048
1049 // Perform a delete or an install
1050 if (Cache[Pkg].Delete() == true)
1051 {
1052 if (SmartRemove(Pkg) == false)
281daf46 1053 return Failed;
6c139d6e
AL
1054 }
1055 else
d41d0e01 1056 if (SmartUnPack(Pkg,List->IsFlag(Pkg,pkgOrderList::Immediate),0) == false)
281daf46
AL
1057 return Failed;
1058 DoneSomething = true;
590f1923
CB
1059
1060 if (ImmConfigureAll) {
1e3f4083 1061 /* ConfigureAll here to pick up and packages left unconfigured because they were unpacked in the
590f1923 1062 "PreUnpack Checks" section */
c7c7d3e8
CB
1063 if (!ConfigureAll())
1064 return Failed;
590f1923 1065 }
6c139d6e 1066 }
5e312de7 1067
6c139d6e
AL
1068 // Final run through the configure phase
1069 if (ConfigureAll() == false)
281daf46 1070 return Failed;
6c139d6e
AL
1071
1072 // Sanity check
91c03d37 1073 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
281daf46 1074 {
6c139d6e 1075 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
281daf46
AL
1076 {
1077 _error->Error("Internal error, packages left unconfigured. %s",
90436124 1078 PkgIterator(Cache,*I).FullName().c_str());
281daf46
AL
1079 return Failed;
1080 }
9fc57a59 1081 }
281daf46
AL
1082
1083 return Completed;
6c139d6e 1084}
3b1b0f29
MV
1085// PM::DoInstallPostFork - compat /*{{{*/
1086// ---------------------------------------------------------------------
1087 /*}}}*/
ccf6bdb3 1088#if APT_PKG_ABI >= 413
3b1b0f29
MV
1089pkgPackageManager::OrderResult
1090pkgPackageManager::DoInstallPostFork(int statusFd)
1091{
bd5f39b3
MV
1092 APT::Progress::PackageManager *progress = new
1093 APT::Progress::PackageManagerProgressFd(statusFd);
1094 pkgPackageManager::OrderResult res = DoInstallPostFork(progress);
1095 delete progress;
1096 return res;
1097}
6c139d6e 1098 /*}}}*/
1d6386f3
MV
1099// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
1100// ---------------------------------------------------------------------
1101pkgPackageManager::OrderResult
e6ad8031 1102pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress)
1d6386f3 1103{
5e9458e2
MV
1104 bool goResult = Go(progress);
1105 if(goResult == false)
1106 return Failed;
1107
1108 return Res;
bf3ad91f 1109}
bd5f39b3
MV
1110#else
1111pkgPackageManager::OrderResult
1112pkgPackageManager::DoInstallPostFork(int statusFd)
1113{
1114 bool goResult = Go(statusFd);
1115 if(goResult == false)
1116 return Failed;
1117
1118 return Res;
1119}
1120#endif
e6ad8031 1121 /*}}}*/
2a7e07c7
MV
1122// PM::DoInstall - Does the installation /*{{{*/
1123// ---------------------------------------------------------------------
3b1b0f29 1124/* compat */
ccf6bdb3 1125#if APT_PKG_ABI >= 413
3b1b0f29
MV
1126pkgPackageManager::OrderResult
1127pkgPackageManager::DoInstall(int statusFd)
1128{
1129 APT::Progress::PackageManager *progress = new
1130 APT::Progress::PackageManagerProgressFd(statusFd);
1131 OrderResult res = DoInstall(progress);
1132 delete progress;
1133 return res;
1134 }
bd5f39b3
MV
1135#else
1136pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
1137{
1138 if(DoInstallPreFork() == Failed)
1139 return Failed;
1140
1141 return DoInstallPostFork(statusFd);
1142}
1143#endif
3b1b0f29
MV
1144 /*}}}*/
1145// PM::DoInstall - Does the installation /*{{{*/
1146// ---------------------------------------------------------------------
2a7e07c7
MV
1147/* This uses the filenames in FileNames and the information in the
1148 DepCache to perform the installation of packages.*/
ccf6bdb3 1149#if APT_PKG_ABI >= 413
e6ad8031
MV
1150pkgPackageManager::OrderResult
1151pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress)
2a7e07c7
MV
1152{
1153 if(DoInstallPreFork() == Failed)
1154 return Failed;
1155
e6ad8031 1156 return DoInstallPostFork(progress);
2a7e07c7 1157}
bd5f39b3 1158#endif
eef71338 1159 /*}}}*/