cleanup headers and especially #includes everywhere
[ntk/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
6c139d6e 264 if (EarlyRemove(D.ParentPkg()) == 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 /*}}}*/
316// PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
317// ---------------------------------------------------------------------
c7c7d3e8
CB
318/* This function tries to put the system in a state where Pkg can be configured.
319 This involves checking each of Pkg's dependanies and unpacking and
320 configuring packages where needed.
321
322 Note on failure: This method can fail, without causing any problems.
323 This can happen when using Immediate-Configure-All, SmartUnPack may call
1e3f4083 324 SmartConfigure, it may fail because of a complex dependency situation, but
c7c7d3e8
CB
325 a error will only be reported if ConfigureAll fails. This is why some of the
326 messages this function reports on failure (return false;) as just warnings
327 only shown when debuging*/
d41d0e01 328bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
6c139d6e 329{
38ff3de6 330 // If this is true, only check and correct and dependencies without the Loop flag
2dd2c801 331 bool const PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
d41d0e01 332
987d8d03
CB
333 if (Debug) {
334 VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
90436124 335 clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.FullName() << " (" << InstallVer.VerStr() << ")";
d41d0e01 336 if (PkgLoop)
38ff3de6 337 clog << " (Only Correct Dependencies)";
d41d0e01 338 clog << endl;
987d8d03 339 }
0eacf067 340
590f1923 341 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
b2e465d6 342
38ff3de6 343 /* Because of the ordered list, most dependencies should be unpacked,
c7c7d3e8 344 however if there is a loop (A depends on B, B depends on A) this will not
38ff3de6 345 be the case, so check for dependencies before configuring. */
2dd2c801 346 bool Bad = false, Changed = false;
9c5104cf 347 const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
bce4caa3 348 unsigned int i=0;
42d51f33 349 std::list<DepIterator> needConfigure;
bce4caa3
MV
350 do
351 {
2dd2c801
DK
352 Changed = false;
353 for (DepIterator D = instVer.DependsList(); D.end() == false; )
354 {
355 // Compute a single dependency element (glob or)
356 pkgCache::DepIterator Start, End;
357 D.GlobOr(Start,End);
358
359 if (End->Type != pkgCache::Dep::Depends)
360 continue;
361 Bad = true;
362
42d51f33 363 // Check for dependencies that have not been unpacked, probably due to loops.
2dd2c801
DK
364 for (DepIterator Cur = Start; true; ++Cur)
365 {
366 SPtrArray<Version *> VList = Cur.AllTargets();
367
368 for (Version **I = VList; *I != 0; ++I)
6c139d6e 369 {
2dd2c801
DK
370 VerIterator Ver(Cache,*I);
371 PkgIterator DepPkg = Ver.ParentPkg();
372
373 // Check if the current version of the package is available and will satisfy this dependency
374 if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
375 List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
376 DepPkg.State() == PkgIterator::NeedsNothing)
377 {
378 Bad = false;
379 break;
380 }
381
382 // Check if the version that is going to be installed will satisfy the dependency
42d51f33 383 if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
2dd2c801
DK
384 continue;
385
42d51f33 386 if (PkgLoop == true)
2dd2c801 387 {
42d51f33
DK
388 if (Debug)
389 std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
390 Bad = false;
391 break;
392 }
393 else
394 {
395 if (Debug)
396 clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl;
2dd2c801
DK
397 if (PkgLoop == false)
398 List->Flag(Pkg,pkgOrderList::Loop);
42d51f33 399 if (SmartUnPack(DepPkg, true, Depth + 1) == true)
2dd2c801
DK
400 {
401 Bad = false;
402 if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
42d51f33 403 Changed = true;
2dd2c801
DK
404 }
405 if (PkgLoop == false)
42d51f33 406 List->RmFlag(Pkg,pkgOrderList::Loop);
2dd2c801
DK
407 if (Bad == false)
408 break;
409 }
590f1923 410 }
42d51f33
DK
411
412 if (Cur == End || Bad == false)
2dd2c801 413 break;
42d51f33 414 }
2dd2c801
DK
415
416 if (Bad == false)
417 continue;
418
42d51f33
DK
419 needConfigure.push_back(Start);
420 }
421 if (i++ > max_loops)
422 return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (1) for %s, aborting", Pkg.FullName().c_str());
423 } while (Changed == true);
424
425 Bad = false, Changed = false, i = 0;
426 do
427 {
428 Changed = false;
6420c00e 429 for (std::list<DepIterator>::const_iterator D = needConfigure.begin(); D != needConfigure.end(); ++D)
42d51f33 430 {
6420c00e 431 // Compute a single dependency element (glob or) without modifying D
42d51f33 432 pkgCache::DepIterator Start, End;
6420c00e
DK
433 {
434 pkgCache::DepIterator Discard = *D;
435 Discard.GlobOr(Start,End);
436 }
42d51f33
DK
437
438 if (End->Type != pkgCache::Dep::Depends)
439 continue;
440 Bad = true;
441
442 // Search for dependencies which are unpacked but aren't configured yet (maybe loops)
2dd2c801
DK
443 for (DepIterator Cur = Start; true; ++Cur)
444 {
445 SPtrArray<Version *> VList = Cur.AllTargets();
446
447 for (Version **I = VList; *I != 0; ++I)
448 {
449 VerIterator Ver(Cache,*I);
450 PkgIterator DepPkg = Ver.ParentPkg();
451
452 // Check if the version that is going to be installed will satisfy the dependency
42d51f33 453 if (Cache[DepPkg].InstallVer != *I)
2dd2c801
DK
454 continue;
455
42d51f33 456 if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
d9f6c795 457 {
42d51f33
DK
458 if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop)
459 {
460 // This dependency has already been dealt with by another SmartConfigure on Pkg
461 Bad = false;
462 break;
463 }
464 /* Check for a loop to prevent one forming
465 If A depends on B and B depends on A, SmartConfigure will
466 just hop between them if this is not checked. Dont remove the
467 loop flag after finishing however as loop is already set.
468 This means that there is another SmartConfigure call for this
469 package and it will remove the loop flag */
2dd2c801
DK
470 if (PkgLoop == false)
471 List->Flag(Pkg,pkgOrderList::Loop);
42d51f33 472 if (SmartConfigure(DepPkg, Depth + 1) == true)
2dd2c801
DK
473 {
474 Bad = false;
475 if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
42d51f33 476 Changed = true;
2dd2c801
DK
477 }
478 if (PkgLoop == false)
42d51f33
DK
479 List->RmFlag(Pkg,pkgOrderList::Loop);
480 // If SmartConfigure was succesfull, Bad is false, so break
2dd2c801
DK
481 if (Bad == false)
482 break;
d9f6c795 483 }
42d51f33
DK
484 else if (List->IsFlag(DepPkg,pkgOrderList::Configured))
485 {
486 Bad = false;
487 break;
488 }
590f1923 489 }
42d51f33 490 if (Cur == End || Bad == false)
2dd2c801 491 break;
42d51f33
DK
492 }
493
494
2dd2c801 495 if (Bad == true && Changed == false && Debug == true)
6420c00e 496 std::clog << OutputInDepth(Depth) << "Could not satisfy " << *D << std::endl;
6c139d6e 497 }
bce4caa3 498 if (i++ > max_loops)
42d51f33 499 return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (2) for %s, aborting", Pkg.FullName().c_str());
2dd2c801 500 } while (Changed == true);
c7c7d3e8
CB
501
502 if (Bad) {
503 if (Debug)
90436124 504 _error->Warning(_("Could not configure '%s'. "),Pkg.FullName().c_str());
6c139d6e 505 return false;
c7c7d3e8 506 }
a99d02a8
CB
507
508 if (PkgLoop) return true;
5e312de7
DK
509
510 static std::string const conf = _config->Find("PackageManager::Configure","all");
511 static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
512
17182c0c 513 if (List->IsFlag(Pkg,pkgOrderList::Configured))
90436124 514 return _error->Error("Internal configure error on '%s'.", Pkg.FullName().c_str());
5e312de7 515
590f1923
CB
516 if (ConfigurePkgs == true && Configure(Pkg) == false)
517 return false;
75a90b93 518
590f1923 519 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
6c139d6e 520
894d672e 521 if ((Cache[Pkg].InstVerIter(Cache)->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
d77b985a
DK
522 for (PkgIterator P = Pkg.Group().PackageList();
523 P.end() == false; P = Pkg.Group().NextPkg(P))
524 {
525 if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true ||
2b8b1e7a 526 List->IsFlag(P,pkgOrderList::UnPacked) == false ||
d77b985a
DK
527 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
528 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
529 continue;
d41d0e01 530 SmartConfigure(P, (Depth +1));
d77b985a
DK
531 }
532
6c139d6e
AL
533 // Sanity Check
534 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
90436124 535 return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str());
20382bad 536
6c139d6e
AL
537 return true;
538}
539 /*}}}*/
6c139d6e
AL
540// PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
541// ---------------------------------------------------------------------
542/* This is called to deal with conflicts arising from unpacking */
543bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
544{
545 if (List->IsNow(Pkg) == false)
546 return true;
547
548 // Already removed it
549 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
550 return true;
551
552 // Woops, it will not be re-installed!
553 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
554 return false;
9d4c8f67
AL
555
556 // Essential packages get special treatment
5af32db6 557 bool IsEssential = false;
c5200869
JAK
558 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0 ||
559 (Pkg->Flags & pkgCache::Flag::Important) != 0)
5af32db6
AL
560 IsEssential = true;
561
562 /* Check for packages that are the dependents of essential packages and
563 promote them too */
564 if (Pkg->CurrentVer != 0)
565 {
566 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
f7f0d6c7 567 IsEssential == false; ++D)
5af32db6 568 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
c5200869
JAK
569 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0 ||
570 (D.ParentPkg()->Flags & pkgCache::Flag::Important) != 0)
5af32db6
AL
571 IsEssential = true;
572 }
573
574 if (IsEssential == true)
9d4c8f67
AL
575 {
576 if (_config->FindB("APT::Force-LoopBreak",false) == false)
b2e465d6
AL
577 return _error->Error(_("This installation run will require temporarily "
578 "removing the essential package %s due to a "
579 "Conflicts/Pre-Depends loop. This is often bad, "
580 "but if you really want to do it, activate the "
90436124 581 "APT::Force-LoopBreak option."),Pkg.FullName().c_str());
9d4c8f67 582 }
6c139d6e
AL
583
584 bool Res = SmartRemove(Pkg);
585 if (Cache[Pkg].Delete() == false)
586 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
587
588 return Res;
589}
590 /*}}}*/
591// PM::SmartRemove - Removal Helper /*{{{*/
592// ---------------------------------------------------------------------
593/* */
594bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
595{
596 if (List->IsNow(Pkg) == false)
597 return true;
598
599 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
803ea2a8 600
28166356 601 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
6c139d6e
AL
602}
603 /*}}}*/
604// PM::SmartUnPack - Install helper /*{{{*/
605// ---------------------------------------------------------------------
1e3f4083 606/* This puts the system in a state where it can Unpack Pkg, if Pkg is already
590f1923 607 unpacked, or when it has been unpacked, if Immediate==true it configures it. */
6c139d6e 608bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
d77b985a 609{
d41d0e01 610 return SmartUnPack(Pkg, true, 0);
d77b985a 611}
d41d0e01 612bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int const Depth)
6c139d6e 613{
d41d0e01
CB
614 bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
615
987d8d03 616 if (Debug) {
90436124 617 clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.FullName();
987d8d03
CB
618 VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
619 if (Pkg.CurrentVer() == 0)
c4f931f8 620 clog << " (install version " << InstallVer.VerStr() << ")";
987d8d03 621 else
c4f931f8 622 clog << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")";
d41d0e01 623 if (PkgLoop)
c4f931f8
MV
624 clog << " (Only Perform PreUnpack Checks)";
625 clog << endl;
987d8d03 626 }
cfcdf7fe 627
d77b985a
DK
628 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
629
c7c7d3e8 630 /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked.
98ee4922 631 It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should
c7c7d3e8 632 avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with
1e3f4083 633 complex dependency structures, trying to configure some packages while breaking the loops can complicate things .
98ee4922 634 This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
c7c7d3e8 635 or by the ConfigureAll call at the end of the for loop in OrderInstall. */
98ee4922 636 bool Changed = false;
9c5104cf 637 const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
5ab7b53b 638 unsigned int i = 0;
bce4caa3
MV
639 do
640 {
98ee4922
DK
641 Changed = false;
642 for (DepIterator D = instVer.DependsList(); D.end() == false; )
6c139d6e 643 {
98ee4922
DK
644 // Compute a single dependency element (glob or)
645 pkgCache::DepIterator Start, End;
646 D.GlobOr(Start,End);
f4945db3 647
98ee4922
DK
648 if (End->Type == pkgCache::Dep::PreDepends)
649 {
650 bool Bad = true;
651 if (Debug)
652 clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.FullName() << std::endl;
653
654 // Look for easy targets: packages that are already okay
655 for (DepIterator Cur = Start; Bad == true; ++Cur)
6c139d6e 656 {
d8e25d34 657 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
658 for (Version **I = VList; *I != 0; ++I)
659 {
660 VerIterator Ver(Cache,*I);
661 PkgIterator Pkg = Ver.ParentPkg();
662
663 // See if the current version is ok
664 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
665 Pkg.State() == PkgIterator::NeedsNothing)
666 {
667 Bad = false;
668 if (Debug)
669 clog << OutputInDepth(Depth) << "Found ok package " << Pkg.FullName() << endl;
670 break;
671 }
672 }
673 if (Cur == End)
674 break;
17182c0c 675 }
6c139d6e 676
98ee4922 677 // Look for something that could be configured.
275024e9 678 for (DepIterator Cur = Start; Bad == true && Cur.end() == false; ++Cur)
98ee4922 679 {
d8e25d34 680 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
681 for (Version **I = VList; *I != 0; ++I)
682 {
683 VerIterator Ver(Cache,*I);
684 PkgIterator Pkg = Ver.ParentPkg();
1006601e 685
98ee4922
DK
686 // Not the install version
687 if (Cache[Pkg].InstallVer != *I ||
688 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
689 continue;
690
691 if (List->IsFlag(Pkg,pkgOrderList::Configured))
692 {
693 Bad = false;
694 break;
695 }
696
697 // check if it needs unpack or if if configure is enough
698 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
699 {
700 if (Debug)
701 clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.FullName() << endl;
702 // SmartUnpack with the ImmediateFlag to ensure its really ready
703 if (SmartUnPack(Pkg, true, Depth + 1) == true)
704 {
705 Bad = false;
706 if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
707 Changed = true;
708 break;
709 }
710 }
711 else
712 {
713 if (Debug)
714 clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.FullName() << endl;
715 if (SmartConfigure(Pkg, Depth + 1) == true)
716 {
717 Bad = false;
718 if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
719 Changed = true;
720 break;
721 }
722 }
e2a5ff0c 723 }
6c139d6e 724 }
98ee4922
DK
725
726 if (Bad == true)
727 {
728 if (Start == End)
729 return _error->Error("Couldn't configure pre-depend %s for %s, "
730 "probably a dependency cycle.",
731 End.TargetPkg().FullName().c_str(),Pkg.FullName().c_str());
732 }
733 else
734 continue;
6c139d6e 735 }
98ee4922
DK
736 else if (End->Type == pkgCache::Dep::Conflicts ||
737 End->Type == pkgCache::Dep::Obsoletes)
cfcdf7fe 738 {
98ee4922
DK
739 /* Look for conflicts. Two packages that are both in the install
740 state cannot conflict so we don't check.. */
741 SPtrArray<Version *> VList = End.AllTargets();
742 for (Version **I = VList; *I != 0; I++)
3e9ab9f0 743 {
98ee4922
DK
744 VerIterator Ver(Cache,*I);
745 PkgIterator ConflictPkg = Ver.ParentPkg();
746 VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer);
3e9ab9f0 747
98ee4922
DK
748 // See if the current version is conflicting
749 if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg))
750 {
2252183c
DK
751 if (Debug)
752 clog << OutputInDepth(Depth) << Pkg.FullName() << " conflicts with " << ConflictPkg.FullName() << endl;
98ee4922
DK
753 /* If a loop is not present or has not yet been detected, attempt to unpack packages
754 to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */
755 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
440d3d65 756 {
98ee4922 757 if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0)
440d3d65 758 {
98ee4922 759 if (Debug)
544cc111 760 clog << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to prevent conflict" << endl;
98ee4922
DK
761 List->Flag(Pkg,pkgOrderList::Loop);
762 if (SmartUnPack(ConflictPkg,false, Depth + 1) == true)
763 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
764 Changed = true;
765 // Remove loop to allow it to be used later if needed
766 List->RmFlag(Pkg,pkgOrderList::Loop);
440d3d65 767 }
98ee4922
DK
768 else if (EarlyRemove(ConflictPkg) == false)
769 return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str());
440d3d65 770 }
98ee4922 771 else if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == false)
440d3d65
DK
772 {
773 if (Debug)
544cc111 774 clog << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.FullName() << " to conflict violation" << endl;
98ee4922
DK
775 if (EarlyRemove(ConflictPkg) == false)
776 return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str());
777 }
778 }
779 }
780 }
781 else if (End->Type == pkgCache::Dep::DpkgBreaks)
782 {
783 SPtrArray<Version *> VList = End.AllTargets();
784 for (Version **I = VList; *I != 0; ++I)
785 {
786 VerIterator Ver(Cache,*I);
787 PkgIterator BrokenPkg = Ver.ParentPkg();
788 if (BrokenPkg.CurrentVer() != Ver)
789 {
790 if (Debug)
791 std::clog << OutputInDepth(Depth) << " Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl;
792 continue;
793 }
794
795 // Check if it needs to be unpacked
796 if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false &&
797 List->IsNow(BrokenPkg))
798 {
799 if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop)
800 {
1e3f4083 801 // This dependency has already been dealt with by another SmartUnPack on Pkg
98ee4922 802 break;
440d3d65
DK
803 }
804 else
2264548f 805 {
98ee4922
DK
806 // Found a break, so see if we can unpack the package to avoid it
807 // but do not set loop if another SmartUnPack already deals with it
808 // Also, avoid it if the package we would unpack pre-depends on this one
809 VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer);
810 bool circle = false;
811 for (pkgCache::DepIterator D = InstallVer.DependsList(); D.end() == false; ++D)
440d3d65 812 {
98ee4922
DK
813 if (D->Type != pkgCache::Dep::PreDepends)
814 continue;
815 SPtrArray<Version *> VL = D.AllTargets();
816 for (Version **I = VL; *I != 0; ++I)
817 {
818 VerIterator V(Cache,*I);
819 PkgIterator P = V.ParentPkg();
820 // we are checking for installation as an easy 'protection' against or-groups and (unchosen) providers
177645ed 821 if (P != Pkg || (P.CurrentVer() != V && Cache[P].InstallVer != V))
98ee4922
DK
822 continue;
823 circle = true;
824 break;
825 }
826 if (circle == true)
827 break;
828 }
829 if (circle == true)
830 {
831 if (Debug)
544cc111 832 clog << OutputInDepth(Depth) << " Avoiding " << End << " avoided as " << BrokenPkg.FullName() << " has a pre-depends on " << Pkg.FullName() << std::endl;
98ee4922
DK
833 continue;
834 }
835 else
836 {
837 if (Debug)
838 {
544cc111 839 clog << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.FullName() << " to avoid " << End;
98ee4922 840 if (PkgLoop == true)
544cc111
MV
841 clog << " (Looping)";
842 clog << std::endl;
98ee4922
DK
843 }
844 if (PkgLoop == false)
845 List->Flag(Pkg,pkgOrderList::Loop);
846 if (SmartUnPack(BrokenPkg, false, Depth + 1) == true)
847 {
848 if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) == false)
849 Changed = true;
850 }
851 if (PkgLoop == false)
852 List->RmFlag(Pkg,pkgOrderList::Loop);
440d3d65 853 }
2264548f 854 }
6b92f60c 855 }
6b92f60c 856 // Check if a package needs to be removed
98ee4922 857 else if (Cache[BrokenPkg].Delete() == true && List->IsFlag(BrokenPkg,pkgOrderList::Configured) == false)
6b92f60c
DK
858 {
859 if (Debug)
544cc111 860 clog << OutputInDepth(Depth) << " Removing " << BrokenPkg.FullName() << " to avoid " << End << endl;
6b92f60c
DK
861 SmartRemove(BrokenPkg);
862 }
6c139d6e
AL
863 }
864 }
6c139d6e 865 }
bce4caa3 866 if (i++ > max_loops)
91ea3def 867 return _error->Error("Internal error: APT::pkgPackageManager::MaxLoopCount reached in SmartConfigure for %s, aborting", Pkg.FullName().c_str());
98ee4922 868 } while (Changed == true);
9fc57a59 869
6c139d6e 870 // Check for reverse conflicts.
5af32db6 871 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
d77b985a 872 instVer.VerStr()) == false)
c7c7d3e8 873 return false;
5af32db6 874
d77b985a 875 for (PrvIterator P = instVer.ProvidesList();
f7f0d6c7 876 P.end() == false; ++P)
32d9baea
DK
877 if (Pkg->Group != P.OwnerPkg()->Group)
878 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
70ae2409 879
75a90b93
DK
880 if (PkgLoop)
881 return true;
940f2160 882
d77b985a
DK
883 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
884
2a2a7ef4 885 if (Immediate == true && (instVer->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
30426f48
DK
886 {
887 /* Do lockstep M-A:same unpacking in two phases:
888 First unpack all installed architectures, then the not installed.
889 This way we avoid that M-A: enabled packages are installed before
890 their older non-M-A enabled packages are replaced by newer versions */
891 bool const installed = Pkg->CurrentVer != 0;
36635720
DK
892 if (installed == true &&
893 (instVer != Pkg.CurrentVer() ||
894 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
895 Install(Pkg,FileNames[Pkg->ID]) == false)
30426f48 896 return false;
d77b985a
DK
897 for (PkgIterator P = Pkg.Group().PackageList();
898 P.end() == false; P = Pkg.Group().NextPkg(P))
899 {
30426f48 900 if (P->CurrentVer == 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
d77b985a
DK
901 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
902 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
903 continue;
75a90b93 904 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48 905 return false;
d77b985a 906 }
30426f48
DK
907 if (installed == false && Install(Pkg,FileNames[Pkg->ID]) == false)
908 return false;
909 for (PkgIterator P = Pkg.Group().PackageList();
910 P.end() == false; P = Pkg.Group().NextPkg(P))
911 {
912 if (P->CurrentVer != 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
2b8b1e7a 913 List->IsFlag(P,pkgOrderList::Configured) == true ||
30426f48
DK
914 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
915 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
916 continue;
75a90b93 917 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48
DK
918 return false;
919 }
920 }
cd5e8444 921 // packages which are already unpacked don't need to be unpacked again
d4b4e5ea
DK
922 else if ((instVer != Pkg.CurrentVer() ||
923 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
924 Install(Pkg,FileNames[Pkg->ID]) == false)
28166356
DK
925 return false;
926
d41d0e01 927 if (Immediate == true) {
590f1923 928 // Perform immedate configuration of the package.
d41d0e01 929 if (SmartConfigure(Pkg, Depth + 1) == false)
590f1923 930 _error->Warning(_("Could not perform immediate configuration on '%s'. "
90436124 931 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),2);
590f1923 932 }
6c139d6e
AL
933
934 return true;
935}
936 /*}}}*/
937// PM::OrderInstall - Installation ordering routine /*{{{*/
938// ---------------------------------------------------------------------
939/* */
281daf46 940pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
6c139d6e 941{
7a1b1f8b 942 if (CreateOrderList() == false)
281daf46
AL
943 return Failed;
944
945 Reset();
6c139d6e 946
30e1eab5 947 if (Debug == true)
5e312de7 948 clog << "Beginning to order" << endl;
6c139d6e 949
5e312de7
DK
950 bool const ordering =
951 _config->FindB("PackageManager::UnpackAll",true) ?
952 List->OrderUnpack(FileNames) : List->OrderCritical();
953 if (ordering == false)
281daf46
AL
954 {
955 _error->Error("Internal ordering error");
956 return Failed;
957 }
958
30e1eab5
AL
959 if (Debug == true)
960 clog << "Done ordering" << endl;
961
281daf46 962 bool DoneSomething = false;
91c03d37 963 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
6c139d6e
AL
964 {
965 PkgIterator Pkg(Cache,*I);
e2a5ff0c 966
281daf46
AL
967 if (List->IsNow(Pkg) == false)
968 {
b684d8c7 969 if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) {
d41d0e01 970 if (SmartConfigure(Pkg, 0) == false && Debug)
90436124 971 _error->Warning("Internal Error, Could not configure %s",Pkg.FullName().c_str());
634985f8 972 // FIXME: The above warning message might need changing
b684d8c7 973 } else {
634985f8 974 if (Debug == true)
90436124 975 clog << "Skipping already done " << Pkg.FullName() << endl;
634985f8 976 }
281daf46 977 continue;
634985f8 978
281daf46
AL
979 }
980
2fd65468 981 if (List->IsMissing(Pkg) == true)
281daf46
AL
982 {
983 if (Debug == true)
90436124 984 clog << "Sequence completed at " << Pkg.FullName() << endl;
281daf46
AL
985 if (DoneSomething == false)
986 {
987 _error->Error("Internal Error, ordering was unable to handle the media swap");
988 return Failed;
989 }
990 return Incomplete;
991 }
6c139d6e
AL
992
993 // Sanity check
d0c59649
AL
994 if (Cache[Pkg].Keep() == true &&
995 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
996 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
281daf46 997 {
90436124 998 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.FullName().c_str());
281daf46
AL
999 return Failed;
1000 }
6c139d6e
AL
1001
1002 // Perform a delete or an install
1003 if (Cache[Pkg].Delete() == true)
1004 {
1005 if (SmartRemove(Pkg) == false)
281daf46 1006 return Failed;
6c139d6e
AL
1007 }
1008 else
d41d0e01 1009 if (SmartUnPack(Pkg,List->IsFlag(Pkg,pkgOrderList::Immediate),0) == false)
281daf46
AL
1010 return Failed;
1011 DoneSomething = true;
590f1923
CB
1012
1013 if (ImmConfigureAll) {
1e3f4083 1014 /* ConfigureAll here to pick up and packages left unconfigured because they were unpacked in the
590f1923 1015 "PreUnpack Checks" section */
c7c7d3e8
CB
1016 if (!ConfigureAll())
1017 return Failed;
590f1923 1018 }
6c139d6e 1019 }
5e312de7 1020
6c139d6e
AL
1021 // Final run through the configure phase
1022 if (ConfigureAll() == false)
281daf46 1023 return Failed;
6c139d6e
AL
1024
1025 // Sanity check
91c03d37 1026 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
281daf46 1027 {
6c139d6e 1028 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
281daf46
AL
1029 {
1030 _error->Error("Internal error, packages left unconfigured. %s",
90436124 1031 PkgIterator(Cache,*I).FullName().c_str());
281daf46
AL
1032 return Failed;
1033 }
9fc57a59 1034 }
281daf46
AL
1035
1036 return Completed;
6c139d6e 1037}
3b1b0f29
MV
1038// PM::DoInstallPostFork - compat /*{{{*/
1039// ---------------------------------------------------------------------
1040 /*}}}*/
bd5f39b3 1041#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
3b1b0f29
MV
1042pkgPackageManager::OrderResult
1043pkgPackageManager::DoInstallPostFork(int statusFd)
1044{
bd5f39b3
MV
1045 APT::Progress::PackageManager *progress = new
1046 APT::Progress::PackageManagerProgressFd(statusFd);
1047 pkgPackageManager::OrderResult res = DoInstallPostFork(progress);
1048 delete progress;
1049 return res;
1050}
6c139d6e 1051 /*}}}*/
1d6386f3
MV
1052// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
1053// ---------------------------------------------------------------------
1054pkgPackageManager::OrderResult
e6ad8031 1055pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress)
1d6386f3 1056{
5e9458e2
MV
1057 bool goResult = Go(progress);
1058 if(goResult == false)
1059 return Failed;
1060
1061 return Res;
1d6386f3 1062};
bd5f39b3
MV
1063#else
1064pkgPackageManager::OrderResult
1065pkgPackageManager::DoInstallPostFork(int statusFd)
1066{
1067 bool goResult = Go(statusFd);
1068 if(goResult == false)
1069 return Failed;
1070
1071 return Res;
1072}
1073#endif
e6ad8031 1074 /*}}}*/
2a7e07c7
MV
1075// PM::DoInstall - Does the installation /*{{{*/
1076// ---------------------------------------------------------------------
3b1b0f29 1077/* compat */
bd5f39b3 1078#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
3b1b0f29
MV
1079pkgPackageManager::OrderResult
1080pkgPackageManager::DoInstall(int statusFd)
1081{
1082 APT::Progress::PackageManager *progress = new
1083 APT::Progress::PackageManagerProgressFd(statusFd);
1084 OrderResult res = DoInstall(progress);
1085 delete progress;
1086 return res;
1087 }
bd5f39b3
MV
1088#else
1089pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
1090{
1091 if(DoInstallPreFork() == Failed)
1092 return Failed;
1093
1094 return DoInstallPostFork(statusFd);
1095}
1096#endif
3b1b0f29
MV
1097 /*}}}*/
1098// PM::DoInstall - Does the installation /*{{{*/
1099// ---------------------------------------------------------------------
2a7e07c7
MV
1100/* This uses the filenames in FileNames and the information in the
1101 DepCache to perform the installation of packages.*/
bd5f39b3 1102#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
e6ad8031
MV
1103pkgPackageManager::OrderResult
1104pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress)
2a7e07c7
MV
1105{
1106 if(DoInstallPreFork() == Failed)
1107 return Failed;
1108
e6ad8031 1109 return DoInstallPostFork(progress);
2a7e07c7 1110}
bd5f39b3 1111#endif
eef71338 1112 /*}}}*/