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