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)  

apt-internal-solver.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* #####################################################################
4 
5  cover around the internal solver to be able to run it like an external
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include Files /*{{{*/
10 #include <config.h>
11 
12 #include <apt-pkg/algorithms.h>
13 #include <apt-pkg/cachefile.h>
14 #include <apt-pkg/cacheset.h>
15 #include <apt-pkg/cmndline.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/depcache.h>
18 #include <apt-pkg/edsp.h>
19 #include <apt-pkg/error.h>
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/init.h>
22 #include <apt-pkg/pkgcache.h>
23 #include <apt-pkg/pkgsystem.h>
24 #include <apt-pkg/strutl.h>
25 #include <apt-pkg/upgrade.h>
26 
30 
31 #include <cstdio>
32 #include <iostream>
33 #include <list>
34 #include <sstream>
35 #include <string>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 
40 #include <apti18n.h>
41  /*}}}*/
42 
43 static bool ShowHelp(CommandLine &) /*{{{*/
44 {
45  std::cout <<
46  _("Usage: apt-internal-solver\n"
47  "\n"
48  "apt-internal-solver is an interface to use the current internal\n"
49  "resolver for the APT family like an external one, for debugging or\n"
50  "the like.\n");
51  return true;
52 }
53  /*}}}*/
54 APT_NORETURN static void DIE(std::string const &message) { /*{{{*/
55  std::cerr << "ERROR: " << message << std::endl;
56  _error->DumpErrors(std::cerr);
57  exit(EXIT_FAILURE);
58 }
59  /*}}}*/
60 static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
61 {
62  return {};
63 }
64  /*}}}*/
65 static bool WriteSolution(pkgDepCache &Cache, FileFd &output) /*{{{*/
66 {
67  bool Okay = output.Failed() == false;
68  for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false && likely(Okay); ++Pkg)
69  {
70  if (Cache[Pkg].Delete() == true)
71  Okay &= EDSP::WriteSolutionStanza(output, "Remove", Pkg.CurrentVer());
72  else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
73  Okay &= EDSP::WriteSolutionStanza(output, "Install", Cache.GetCandidateVersion(Pkg));
74  else if (Cache[Pkg].Garbage == true)
75  Okay &= EDSP::WriteSolutionStanza(output, "Autoremove", Pkg.CurrentVer());
76  }
77  return Okay;
78 }
79  /*}}}*/
80 int main(int argc,const char *argv[]) /*{{{*/
81 {
82  // we really don't need anything
84 
85  CommandLine CmdL;
87 
88  if (CmdL.FileList[0] != 0 && strcmp(CmdL.FileList[0], "scenario") == 0)
89  {
90  if (pkgInitSystem(*_config,_system) == false) {
91  std::cerr << "System could not be initialized!" << std::endl;
92  return 1;
93  }
95  CacheFile.Open(NULL, false);
97  FileFd output;
98  if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
99  return 2;
100  if (pkgset.empty() == true)
102  else
103  {
104  std::vector<bool> pkgvec(CacheFile->Head().PackageCount, false);
105  for (auto const &p: pkgset)
106  pkgvec[p->ID] = true;
107  EDSP::WriteLimitedScenario(CacheFile, output, pkgvec);
108  }
109  output.Close();
110  _error->DumpErrors(std::cerr);
111  return 0;
112  }
113 
114  // Deal with stdout not being a tty
115  if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
116  _config->Set("quiet","1");
117 
118  if (_config->FindI("quiet", 0) < 1)
119  _config->Set("Debug::EDSP::WriteSolution", true);
120 
121  _config->Set("APT::System", "Debian APT solver interface");
122  _config->Set("APT::Solver", "internal");
123  _config->Set("edsp::scenario", "/nonexistent/stdin");
124  _config->Clear("Dir::Log");
125  FileFd output;
126  if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
127  DIE("stdout couldn't be opened");
128  int const input = STDIN_FILENO;
129  SetNonBlock(input, false);
130 
131  EDSP::WriteProgress(0, "Start up solver…", output);
132 
133  if (pkgInitSystem(*_config,_system) == false)
134  DIE("System could not be initialized!");
135 
136  EDSP::WriteProgress(1, "Read request…", output);
137 
138  if (WaitFd(input, false, 5) == false)
139  DIE("WAIT timed out in the resolver");
140 
141  std::list<std::string> install, remove;
142  unsigned int flags;
143  if (EDSP::ReadRequest(input, install, remove, flags) == false)
144  DIE("Parsing the request failed!");
145 
146  EDSP::WriteProgress(5, "Read scenario…", output);
147 
149  if (CacheFile.Open(NULL, false) == false)
150  DIE("Failed to open CacheFile!");
151 
152  EDSP::WriteProgress(50, "Apply request on scenario…", output);
153 
154  if (EDSP::ApplyRequest(install, remove, CacheFile) == false)
155  DIE("Failed to apply request to depcache!");
156 
158  for (std::list<std::string>::const_iterator i = remove.begin();
159  i != remove.end(); ++i) {
160  pkgCache::PkgIterator P = CacheFile->FindPkg(*i);
161  Fix.Clear(P);
162  Fix.Protect(P);
163  Fix.Remove(P);
164  }
165 
166  for (std::list<std::string>::const_iterator i = install.begin();
167  i != install.end(); ++i) {
168  pkgCache::PkgIterator P = CacheFile->FindPkg(*i);
169  Fix.Clear(P);
170  Fix.Protect(P);
171  }
172 
173  for (std::list<std::string>::const_iterator i = install.begin();
174  i != install.end(); ++i)
175  CacheFile->MarkInstall(CacheFile->FindPkg(*i), true);
176 
177  EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output);
178 
179  std::string failure;
180  if (flags & EDSP::Request::UPGRADE_ALL) {
181  int upgrade_flags = APT::Upgrade::ALLOW_EVERYTHING;
184  if (flags & EDSP::Request::FORBID_REMOVE)
185  upgrade_flags |= APT::Upgrade::FORBID_REMOVE_PACKAGES;
186 
187  if (APT::Upgrade::Upgrade(CacheFile, upgrade_flags))
188  ;
189  else if (upgrade_flags == APT::Upgrade::ALLOW_EVERYTHING)
190  failure = "ERR_UNSOLVABLE_FULL_UPGRADE";
191  else
192  failure = "ERR_UNSOLVABLE_UPGRADE";
193  } else if (Fix.Resolve() == false)
194  failure = "ERR_UNSOLVABLE";
195 
196  if (failure.empty() == false) {
197  std::ostringstream broken;
198  ShowBroken(broken, CacheFile, false);
199  EDSP::WriteError(failure.c_str(), broken.str(), output);
200  return 0;
201  }
202 
203  EDSP::WriteProgress(95, "Write solution…", output);
204 
205  if (WriteSolution(CacheFile, output) == false)
206  DIE("Failed to output the solution!");
207 
208  EDSP::WriteProgress(100, "Done", output);
209 
210  return DispatchCommandLine(CmdL, {});
211 }
212  /*}}}*/
static bool WriteSolution(pkgDepCache &Cache, FileFd &output)
static bool ShowHelp(CommandLine &)
static std::vector< aptDispatchWithHelp > GetCommands()
static APT_NORETURN void DIE(std::string const &message)
int main(int argc, const char *argv[])
bool empty() const APT_OVERRIDE
Definition: cacheset.h:361
static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper)
returns all packages specified on the commandline
Definition: cacheset.h:478
bool Open(bool WithLock=true)
const char ** FileList
Definition: cmndline.h:78
int FindI(const char *Name, int const &Default=0) const
void Set(const std::string &Name, const std::string &Value)
Definition: configuration.h:92
void Clear(const std::string &Name)
Definition: fileutl.h:39
bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false)
Definition: fileutl.cc:2572
@ WriteOnly
Definition: fileutl.h:60
@ BufferedWrite
Definition: fileutl.h:67
bool Failed()
Definition: fileutl.h:151
bool Close()
Definition: fileutl.cc:2977
pkgCache::VerIterator GetCandidateVersion(pkgCache::PkgIterator const &Pkg)
Definition: depcache.cc:1863
PkgIterator PkgBegin()
Definition: depcache.h:356
void Clear(pkgCache::PkgIterator Pkg)
Definition: algorithms.h:132
bool Resolve(bool BrokenFix=false, OpProgress *const Progress=NULL)
Definition: algorithms.cc:741
void Remove(pkgCache::PkgIterator Pkg)
Definition: algorithms.h:131
void Protect(pkgCache::PkgIterator Pkg)
Definition: algorithms.h:130
Configuration * _config
void SetNonBlock(int Fd, bool Block)
Definition: fileutl.cc:804
bool WaitFd(int Fd, bool write, unsigned long timeout)
Definition: fileutl.cc:819
bool DropPrivileges()
Drop privileges.
Definition: fileutl.cc:3260
bool pkgInitSystem(Configuration &Cnf, pkgSystem *&Sys)
Definition: init.cc:257
#define APT_NORETURN
Definition: macros.h:57
@ FORBID_REMOVE_PACKAGES
Definition: upgrade.h:23
@ FORBID_INSTALL_NEW_PACKAGES
Definition: upgrade.h:24
@ ALLOW_EVERYTHING
Definition: upgrade.h:25
APT_PUBLIC bool Upgrade(pkgDepCache &Cache, int UpgradeMode, OpProgress *const Progress=NULL)
Definition: upgrade.cc:268
@ FORBID_REMOVE
Definition: edsp.h:35
@ FORBID_NEW_INSTALL
Definition: edsp.h:34
@ UPGRADE_ALL
Definition: edsp.h:33
APT_PUBLIC bool ApplyRequest(std::list< std::string > const &install, std::list< std::string > const &remove, pkgDepCache &Cache)
takes the request lists and applies it on the cache
Definition: edsp.cc:595
APT_PUBLIC bool WriteSolutionStanza(FileFd &output, char const *const Type, pkgCache::VerIterator const &Ver)
formats a solution stanza for the given version
Definition: edsp.cc:620
APT_PUBLIC bool ReadRequest(int const input, std::list< std::string > &install, std::list< std::string > &remove, unsigned int &flags)
search and read the request stanza for action later
Definition: edsp.cc:543
APT_PUBLIC bool WriteLimitedScenario(pkgDepCache &Cache, FileFd &output, std::vector< bool > const &pkgset, OpProgress *Progress=NULL)
creates a limited scenario representing the package universe
Definition: edsp.cc:291
APT_PUBLIC bool WriteProgress(unsigned short const percent, const char *const message, FileFd &output)
sends a progress report
Definition: edsp.cc:630
APT_PUBLIC bool WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progress=NULL)
creates the scenario representing the package universe
Definition: edsp.cc:263
APT_PUBLIC bool WriteError(char const *const uuid, std::string const &message, FileFd &output)
sends an error report
Definition: edsp.cc:641
pkgCache - Structure definitions for the cache file
pkgSystem * _system
Definition: pkgsystem.cc:24
std::vector< CommandLine::Dispatch > ParseCommandLine(CommandLine &CmdL, APT_CMD const Binary, Configuration *const *const Cnf, pkgSystem **const Sys, int const argc, const char *argv[], bool(*ShowHelp)(CommandLine &), std::vector< aptDispatchWithHelp >(*GetCommands)(void))
unsigned short DispatchCommandLine(CommandLine &CmdL, std::vector< CommandLine::Dispatch > const &Cmds)
@ APT_INTERNAL_SOLVER
void ShowBroken(ostream &out, CacheFile &Cache, bool const Now)