apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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