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