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