]> git.saurik.com Git - apt.git/blame - apt-pkg/packagemanager.cc
abstract version hash comparison a bit
[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 624 clog << " (Only Perform PreUnpack Checks)";
0caa5a4c
DK
625 if (Immediate)
626 clog << " immediately";
c4f931f8 627 clog << endl;
987d8d03 628 }
cfcdf7fe 629
d77b985a
DK
630 VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
631
c7c7d3e8 632 /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked.
98ee4922 633 It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should
c7c7d3e8 634 avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with
1e3f4083 635 complex dependency structures, trying to configure some packages while breaking the loops can complicate things .
98ee4922 636 This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
c7c7d3e8 637 or by the ConfigureAll call at the end of the for loop in OrderInstall. */
98ee4922 638 bool Changed = false;
9c5104cf 639 const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
5ab7b53b 640 unsigned int i = 0;
bce4caa3
MV
641 do
642 {
98ee4922
DK
643 Changed = false;
644 for (DepIterator D = instVer.DependsList(); D.end() == false; )
6c139d6e 645 {
98ee4922
DK
646 // Compute a single dependency element (glob or)
647 pkgCache::DepIterator Start, End;
648 D.GlobOr(Start,End);
f4945db3 649
98ee4922
DK
650 if (End->Type == pkgCache::Dep::PreDepends)
651 {
652 bool Bad = true;
653 if (Debug)
654 clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.FullName() << std::endl;
655
656 // Look for easy targets: packages that are already okay
657 for (DepIterator Cur = Start; Bad == true; ++Cur)
6c139d6e 658 {
d8e25d34 659 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
660 for (Version **I = VList; *I != 0; ++I)
661 {
662 VerIterator Ver(Cache,*I);
663 PkgIterator Pkg = Ver.ParentPkg();
664
665 // See if the current version is ok
666 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
667 Pkg.State() == PkgIterator::NeedsNothing)
668 {
669 Bad = false;
670 if (Debug)
671 clog << OutputInDepth(Depth) << "Found ok package " << Pkg.FullName() << endl;
672 break;
673 }
674 }
675 if (Cur == End)
676 break;
17182c0c 677 }
6c139d6e 678
98ee4922 679 // Look for something that could be configured.
275024e9 680 for (DepIterator Cur = Start; Bad == true && Cur.end() == false; ++Cur)
98ee4922 681 {
d8e25d34 682 SPtrArray<Version *> VList = Cur.AllTargets();
98ee4922
DK
683 for (Version **I = VList; *I != 0; ++I)
684 {
685 VerIterator Ver(Cache,*I);
686 PkgIterator Pkg = Ver.ParentPkg();
1006601e 687
98ee4922
DK
688 // Not the install version
689 if (Cache[Pkg].InstallVer != *I ||
690 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
691 continue;
692
693 if (List->IsFlag(Pkg,pkgOrderList::Configured))
694 {
695 Bad = false;
696 break;
697 }
698
699 // check if it needs unpack or if if configure is enough
700 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
701 {
702 if (Debug)
703 clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.FullName() << endl;
704 // SmartUnpack with the ImmediateFlag to ensure its really ready
705 if (SmartUnPack(Pkg, true, Depth + 1) == true)
706 {
707 Bad = false;
708 if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
709 Changed = true;
710 break;
711 }
712 }
713 else
714 {
715 if (Debug)
716 clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.FullName() << endl;
717 if (SmartConfigure(Pkg, Depth + 1) == true)
718 {
719 Bad = false;
720 if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
721 Changed = true;
722 break;
723 }
724 }
e2a5ff0c 725 }
6c139d6e 726 }
98ee4922
DK
727
728 if (Bad == true)
729 {
730 if (Start == End)
731 return _error->Error("Couldn't configure pre-depend %s for %s, "
732 "probably a dependency cycle.",
733 End.TargetPkg().FullName().c_str(),Pkg.FullName().c_str());
734 }
735 else
736 continue;
6c139d6e 737 }
98ee4922
DK
738 else if (End->Type == pkgCache::Dep::Conflicts ||
739 End->Type == pkgCache::Dep::Obsoletes)
cfcdf7fe 740 {
98ee4922
DK
741 /* Look for conflicts. Two packages that are both in the install
742 state cannot conflict so we don't check.. */
743 SPtrArray<Version *> VList = End.AllTargets();
744 for (Version **I = VList; *I != 0; I++)
3e9ab9f0 745 {
98ee4922
DK
746 VerIterator Ver(Cache,*I);
747 PkgIterator ConflictPkg = Ver.ParentPkg();
748 VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer);
3e9ab9f0 749
98ee4922
DK
750 // See if the current version is conflicting
751 if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg))
752 {
2252183c
DK
753 if (Debug)
754 clog << OutputInDepth(Depth) << Pkg.FullName() << " conflicts with " << ConflictPkg.FullName() << endl;
98ee4922
DK
755 /* If a loop is not present or has not yet been detected, attempt to unpack packages
756 to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */
757 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
440d3d65 758 {
98ee4922 759 if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0)
440d3d65 760 {
98ee4922 761 if (Debug)
544cc111 762 clog << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to prevent conflict" << endl;
98ee4922
DK
763 List->Flag(Pkg,pkgOrderList::Loop);
764 if (SmartUnPack(ConflictPkg,false, Depth + 1) == true)
765 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
766 Changed = true;
767 // Remove loop to allow it to be used later if needed
768 List->RmFlag(Pkg,pkgOrderList::Loop);
440d3d65 769 }
98ee4922
DK
770 else if (EarlyRemove(ConflictPkg) == false)
771 return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str());
440d3d65 772 }
98ee4922 773 else if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == false)
440d3d65
DK
774 {
775 if (Debug)
544cc111 776 clog << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.FullName() << " to conflict violation" << endl;
98ee4922
DK
777 if (EarlyRemove(ConflictPkg) == false)
778 return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str());
779 }
780 }
781 }
782 }
783 else if (End->Type == pkgCache::Dep::DpkgBreaks)
784 {
785 SPtrArray<Version *> VList = End.AllTargets();
786 for (Version **I = VList; *I != 0; ++I)
787 {
788 VerIterator Ver(Cache,*I);
789 PkgIterator BrokenPkg = Ver.ParentPkg();
790 if (BrokenPkg.CurrentVer() != Ver)
791 {
792 if (Debug)
793 std::clog << OutputInDepth(Depth) << " Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl;
794 continue;
795 }
796
797 // Check if it needs to be unpacked
798 if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false &&
799 List->IsNow(BrokenPkg))
800 {
801 if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop)
802 {
1e3f4083 803 // This dependency has already been dealt with by another SmartUnPack on Pkg
98ee4922 804 break;
440d3d65
DK
805 }
806 else
2264548f 807 {
98ee4922
DK
808 // Found a break, so see if we can unpack the package to avoid it
809 // but do not set loop if another SmartUnPack already deals with it
810 // Also, avoid it if the package we would unpack pre-depends on this one
811 VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer);
812 bool circle = false;
813 for (pkgCache::DepIterator D = InstallVer.DependsList(); D.end() == false; ++D)
440d3d65 814 {
98ee4922
DK
815 if (D->Type != pkgCache::Dep::PreDepends)
816 continue;
817 SPtrArray<Version *> VL = D.AllTargets();
818 for (Version **I = VL; *I != 0; ++I)
819 {
820 VerIterator V(Cache,*I);
821 PkgIterator P = V.ParentPkg();
822 // we are checking for installation as an easy 'protection' against or-groups and (unchosen) providers
177645ed 823 if (P != Pkg || (P.CurrentVer() != V && Cache[P].InstallVer != V))
98ee4922
DK
824 continue;
825 circle = true;
826 break;
827 }
828 if (circle == true)
829 break;
830 }
831 if (circle == true)
832 {
833 if (Debug)
544cc111 834 clog << OutputInDepth(Depth) << " Avoiding " << End << " avoided as " << BrokenPkg.FullName() << " has a pre-depends on " << Pkg.FullName() << std::endl;
98ee4922
DK
835 continue;
836 }
837 else
838 {
839 if (Debug)
840 {
544cc111 841 clog << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.FullName() << " to avoid " << End;
98ee4922 842 if (PkgLoop == true)
544cc111
MV
843 clog << " (Looping)";
844 clog << std::endl;
98ee4922
DK
845 }
846 if (PkgLoop == false)
847 List->Flag(Pkg,pkgOrderList::Loop);
848 if (SmartUnPack(BrokenPkg, false, Depth + 1) == true)
849 {
850 if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) == false)
851 Changed = true;
852 }
853 if (PkgLoop == false)
854 List->RmFlag(Pkg,pkgOrderList::Loop);
440d3d65 855 }
2264548f 856 }
6b92f60c 857 }
6b92f60c 858 // Check if a package needs to be removed
98ee4922 859 else if (Cache[BrokenPkg].Delete() == true && List->IsFlag(BrokenPkg,pkgOrderList::Configured) == false)
6b92f60c
DK
860 {
861 if (Debug)
544cc111 862 clog << OutputInDepth(Depth) << " Removing " << BrokenPkg.FullName() << " to avoid " << End << endl;
6b92f60c
DK
863 SmartRemove(BrokenPkg);
864 }
6c139d6e
AL
865 }
866 }
6c139d6e 867 }
bce4caa3 868 if (i++ > max_loops)
91ea3def 869 return _error->Error("Internal error: APT::pkgPackageManager::MaxLoopCount reached in SmartConfigure for %s, aborting", Pkg.FullName().c_str());
98ee4922 870 } while (Changed == true);
9fc57a59 871
6c139d6e 872 // Check for reverse conflicts.
5af32db6 873 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
d77b985a 874 instVer.VerStr()) == false)
c7c7d3e8 875 return false;
5af32db6 876
d77b985a 877 for (PrvIterator P = instVer.ProvidesList();
f7f0d6c7 878 P.end() == false; ++P)
32d9baea
DK
879 if (Pkg->Group != P.OwnerPkg()->Group)
880 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
70ae2409 881
75a90b93
DK
882 if (PkgLoop)
883 return true;
940f2160 884
d77b985a
DK
885 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
886
2a2a7ef4 887 if (Immediate == true && (instVer->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
30426f48
DK
888 {
889 /* Do lockstep M-A:same unpacking in two phases:
890 First unpack all installed architectures, then the not installed.
891 This way we avoid that M-A: enabled packages are installed before
892 their older non-M-A enabled packages are replaced by newer versions */
893 bool const installed = Pkg->CurrentVer != 0;
36635720
DK
894 if (installed == true &&
895 (instVer != Pkg.CurrentVer() ||
896 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
897 Install(Pkg,FileNames[Pkg->ID]) == false)
30426f48 898 return false;
d77b985a
DK
899 for (PkgIterator P = Pkg.Group().PackageList();
900 P.end() == false; P = Pkg.Group().NextPkg(P))
901 {
30426f48 902 if (P->CurrentVer == 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
d77b985a
DK
903 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
904 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
905 continue;
75a90b93 906 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48 907 return false;
d77b985a 908 }
30426f48
DK
909 if (installed == false && Install(Pkg,FileNames[Pkg->ID]) == false)
910 return false;
911 for (PkgIterator P = Pkg.Group().PackageList();
912 P.end() == false; P = Pkg.Group().NextPkg(P))
913 {
914 if (P->CurrentVer != 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
2b8b1e7a 915 List->IsFlag(P,pkgOrderList::Configured) == true ||
30426f48
DK
916 Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
917 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
918 continue;
75a90b93 919 if (SmartUnPack(P, false, Depth + 1) == false)
30426f48
DK
920 return false;
921 }
922 }
cd5e8444 923 // packages which are already unpacked don't need to be unpacked again
d4b4e5ea
DK
924 else if ((instVer != Pkg.CurrentVer() ||
925 ((Cache[Pkg].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)) &&
926 Install(Pkg,FileNames[Pkg->ID]) == false)
28166356
DK
927 return false;
928
d41d0e01 929 if (Immediate == true) {
590f1923 930 // Perform immedate configuration of the package.
d41d0e01 931 if (SmartConfigure(Pkg, Depth + 1) == false)
590f1923 932 _error->Warning(_("Could not perform immediate configuration on '%s'. "
90436124 933 "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),2);
590f1923 934 }
6c139d6e
AL
935
936 return true;
937}
938 /*}}}*/
939// PM::OrderInstall - Installation ordering routine /*{{{*/
940// ---------------------------------------------------------------------
941/* */
281daf46 942pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
6c139d6e 943{
7a1b1f8b 944 if (CreateOrderList() == false)
281daf46
AL
945 return Failed;
946
947 Reset();
6c139d6e 948
30e1eab5 949 if (Debug == true)
5e312de7 950 clog << "Beginning to order" << endl;
6c139d6e 951
5e312de7
DK
952 bool const ordering =
953 _config->FindB("PackageManager::UnpackAll",true) ?
954 List->OrderUnpack(FileNames) : List->OrderCritical();
955 if (ordering == false)
281daf46
AL
956 {
957 _error->Error("Internal ordering error");
958 return Failed;
959 }
960
30e1eab5
AL
961 if (Debug == true)
962 clog << "Done ordering" << endl;
963
281daf46 964 bool DoneSomething = false;
91c03d37 965 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
6c139d6e
AL
966 {
967 PkgIterator Pkg(Cache,*I);
0caa5a4c 968
281daf46
AL
969 if (List->IsNow(Pkg) == false)
970 {
0caa5a4c
DK
971 if (Debug == true)
972 clog << "Skipping already done " << Pkg.FullName() << endl;
281daf46
AL
973 continue;
974 }
0caa5a4c 975
2fd65468 976 if (List->IsMissing(Pkg) == true)
281daf46
AL
977 {
978 if (Debug == true)
90436124 979 clog << "Sequence completed at " << Pkg.FullName() << endl;
281daf46
AL
980 if (DoneSomething == false)
981 {
982 _error->Error("Internal Error, ordering was unable to handle the media swap");
983 return Failed;
984 }
985 return Incomplete;
986 }
6c139d6e
AL
987
988 // Sanity check
d0c59649
AL
989 if (Cache[Pkg].Keep() == true &&
990 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
991 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
281daf46 992 {
90436124 993 _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.FullName().c_str());
281daf46
AL
994 return Failed;
995 }
6c139d6e
AL
996
997 // Perform a delete or an install
998 if (Cache[Pkg].Delete() == true)
999 {
1000 if (SmartRemove(Pkg) == false)
281daf46 1001 return Failed;
6c139d6e
AL
1002 }
1003 else
d41d0e01 1004 if (SmartUnPack(Pkg,List->IsFlag(Pkg,pkgOrderList::Immediate),0) == false)
281daf46
AL
1005 return Failed;
1006 DoneSomething = true;
590f1923
CB
1007
1008 if (ImmConfigureAll) {
1e3f4083 1009 /* ConfigureAll here to pick up and packages left unconfigured because they were unpacked in the
590f1923 1010 "PreUnpack Checks" section */
c7c7d3e8
CB
1011 if (!ConfigureAll())
1012 return Failed;
590f1923 1013 }
6c139d6e 1014 }
5e312de7 1015
6c139d6e
AL
1016 // Final run through the configure phase
1017 if (ConfigureAll() == false)
281daf46 1018 return Failed;
6c139d6e
AL
1019
1020 // Sanity check
91c03d37 1021 for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I)
281daf46 1022 {
6c139d6e 1023 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
281daf46
AL
1024 {
1025 _error->Error("Internal error, packages left unconfigured. %s",
90436124 1026 PkgIterator(Cache,*I).FullName().c_str());
281daf46
AL
1027 return Failed;
1028 }
9fc57a59 1029 }
281daf46
AL
1030
1031 return Completed;
6c139d6e 1032}
3b1b0f29
MV
1033// PM::DoInstallPostFork - compat /*{{{*/
1034// ---------------------------------------------------------------------
1035 /*}}}*/
bd5f39b3 1036#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
3b1b0f29
MV
1037pkgPackageManager::OrderResult
1038pkgPackageManager::DoInstallPostFork(int statusFd)
1039{
bd5f39b3
MV
1040 APT::Progress::PackageManager *progress = new
1041 APT::Progress::PackageManagerProgressFd(statusFd);
1042 pkgPackageManager::OrderResult res = DoInstallPostFork(progress);
1043 delete progress;
1044 return res;
1045}
6c139d6e 1046 /*}}}*/
1d6386f3
MV
1047// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/
1048// ---------------------------------------------------------------------
1049pkgPackageManager::OrderResult
e6ad8031 1050pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress)
1d6386f3 1051{
5e9458e2
MV
1052 bool goResult = Go(progress);
1053 if(goResult == false)
1054 return Failed;
1055
1056 return Res;
1d6386f3 1057};
bd5f39b3
MV
1058#else
1059pkgPackageManager::OrderResult
1060pkgPackageManager::DoInstallPostFork(int statusFd)
1061{
1062 bool goResult = Go(statusFd);
1063 if(goResult == false)
1064 return Failed;
1065
1066 return Res;
1067}
1068#endif
e6ad8031 1069 /*}}}*/
2a7e07c7
MV
1070// PM::DoInstall - Does the installation /*{{{*/
1071// ---------------------------------------------------------------------
3b1b0f29 1072/* compat */
bd5f39b3 1073#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
3b1b0f29
MV
1074pkgPackageManager::OrderResult
1075pkgPackageManager::DoInstall(int statusFd)
1076{
1077 APT::Progress::PackageManager *progress = new
1078 APT::Progress::PackageManagerProgressFd(statusFd);
1079 OrderResult res = DoInstall(progress);
1080 delete progress;
1081 return res;
1082 }
bd5f39b3
MV
1083#else
1084pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
1085{
1086 if(DoInstallPreFork() == Failed)
1087 return Failed;
1088
1089 return DoInstallPostFork(statusFd);
1090}
1091#endif
3b1b0f29
MV
1092 /*}}}*/
1093// PM::DoInstall - Does the installation /*{{{*/
1094// ---------------------------------------------------------------------
2a7e07c7
MV
1095/* This uses the filenames in FileNames and the information in the
1096 DepCache to perform the installation of packages.*/
bd5f39b3 1097#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
e6ad8031
MV
1098pkgPackageManager::OrderResult
1099pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress)
2a7e07c7
MV
1100{
1101 if(DoInstallPreFork() == Failed)
1102 return Failed;
1103
e6ad8031 1104 return DoInstallPostFork(progress);
2a7e07c7 1105}
bd5f39b3 1106#endif
eef71338 1107 /*}}}*/