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)  

private-download.cc
Go to the documentation of this file.
1 // Include Files /*{{{*/
2 #include <config.h>
3 
4 #include <apt-pkg/acquire-item.h>
5 #include <apt-pkg/acquire.h>
6 #include <apt-pkg/cacheset.h>
7 #include <apt-pkg/clean.h>
8 #include <apt-pkg/cmndline.h>
9 #include <apt-pkg/configuration.h>
10 #include <apt-pkg/error.h>
11 #include <apt-pkg/fileutl.h>
12 #include <apt-pkg/strutl.h>
13 
19 
20 #include <fstream>
21 #include <string>
22 #include <vector>
23 
24 #include <fcntl.h>
25 #include <pwd.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #ifdef HAVE_VFS_H
29 #include <sys/vfs.h>
30 #else
31 #ifdef HAVE_PARAMS_H
32 #include <sys/params.h>
33 #endif
34 #include <sys/mount.h>
35 #endif
36 #include <errno.h>
37 #include <sys/stat.h>
38 #include <sys/statvfs.h>
39 
40 #include <apti18n.h>
41  /*}}}*/
42 
43 // CheckAuth - check if each download comes form a trusted source /*{{{*/
44 bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser)
45 {
46  std::vector<std::string> UntrustedList;
47  for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
48  if (!(*I)->IsTrusted())
49  UntrustedList.push_back((*I)->ShortDesc());
50 
51  if (UntrustedList.empty())
52  return true;
53 
54  return AuthPrompt(UntrustedList, PromptUser);
55 }
56  /*}}}*/
57 bool AuthPrompt(std::vector<std::string> const &UntrustedList, bool const PromptUser)/*{{{*/
58 {
59  ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"), UntrustedList,
60  [](std::string const&) { return true; },
61  [](std::string const&str) { return str; },
62  [](std::string const&) { return ""; });
63 
64  if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
65  {
66  c2out << _("Authentication warning overridden.\n");
67  return true;
68  }
69 
70  if (PromptUser == false)
71  return _error->Error(_("Some packages could not be authenticated"));
72 
73  if (_config->FindI("quiet",0) < 2
74  && _config->FindB("APT::Get::Assume-Yes",false) == false)
75  {
76  if (!YnPrompt(_("Install these packages without verification?"), false))
77  return _error->Error(_("Some packages could not be authenticated"));
78 
79  return true;
80  }
81  else if (_config->FindB("APT::Get::Force-Yes",false) == true) {
82  return true;
83  }
84 
85  return _error->Error(_("There were unauthenticated packages and -y was used without --allow-unauthenticated"));
86 }
87  /*}}}*/
88 bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failure, bool * const TransientNetworkFailure)/*{{{*/
89 {
91  if(PulseInterval > 0)
92  res = Fetcher.Run(PulseInterval);
93  else
94  res = Fetcher.Run();
95 
96  if (res == pkgAcquire::Failed)
97  return false;
98 
99  for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin();
100  I != Fetcher.ItemsEnd(); ++I)
101  {
102 
103  if ((*I)->Status == pkgAcquire::Item::StatDone &&
104  (*I)->Complete == true)
105  continue;
106 
107  if (TransientNetworkFailure != NULL && (*I)->Status == pkgAcquire::Item::StatIdle)
108  {
109  *TransientNetworkFailure = true;
110  continue;
111  }
112 
113  ::URI uri((*I)->DescURI());
114  uri.User.clear();
115  uri.Password.clear();
116  std::string descUri = std::string(uri);
117  _error->Error(_("Failed to fetch %s %s"), descUri.c_str(),
118  (*I)->ErrorText.c_str());
119 
120  if (Failure != NULL)
121  *Failure = true;
122  }
123 
124  return true;
125 }
126  /*}}}*/
127 bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes)/*{{{*/
128 {
129  uint32_t const RAMFS_MAGIC = 0x858458f6;
130  /* Check for enough free space, but only if we are actually going to
131  download */
132  if (_config->FindB("APT::Get::Print-URIs", false) == true ||
133  _config->FindB("APT::Get::Download", true) == false)
134  return true;
135 
136  struct statvfs Buf;
137  if (statvfs(Dir.c_str(),&Buf) != 0) {
138  if (errno == EOVERFLOW)
139  return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
140  Dir.c_str());
141  else
142  return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
143  Dir.c_str());
144  }
145  else
146  {
147  unsigned long long const FreeBlocks = _config->Find("APT::Sandbox::User").empty() ? Buf.f_bfree : Buf.f_bavail;
148  if (FreeBlocks < (FetchBytes / Buf.f_bsize))
149  {
150  struct statfs Stat;
151  if (statfs(Dir.c_str(),&Stat) != 0
152 #ifdef HAVE_STRUCT_STATFS_F_TYPE
153  || Stat.f_type != RAMFS_MAGIC
154 #endif
155  )
156  return _error->Error(_("You don't have enough free space in %s."),
157  Dir.c_str());
158  }
159  }
160  return true;
161 }
162  /*}}}*/
163 
165  Stat(std::cout, ScreenWidth, _config->FindI("quiet",0))
166 {
167  SetLog(&Stat);
168 }
169 
170 // DoDownload - download a binary /*{{{*/
172 {
173  CacheFile Cache;
174  if (Cache.ReadOnlyOpen() == false)
175  return false;
176 
177  APT::CacheSetHelper helper;
179  CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper);
180 
181  if (verset.empty() == true)
182  return false;
183 
184  pkgRecords Recs(Cache);
185  pkgSourceList *SrcList = Cache.GetSourceList();
186 
187  // reuse the usual acquire methods for deb files, but don't drop them into
188  // the usual directories - keep everything in the current directory
189  aptAcquireWithTextStatus Fetcher;
190  std::vector<std::string> storefile(verset.size());
191  std::string const cwd = SafeGetCWD();
192  _config->Set("Dir::Cache::Archives", cwd);
193  int i = 0;
194  for (APT::VersionSet::const_iterator Ver = verset.begin();
195  Ver != verset.end(); ++Ver, ++i)
196  {
197  pkgAcquire::Item *I = new pkgAcqArchive(&Fetcher, SrcList, &Recs, *Ver, storefile[i]);
198  if (storefile[i].empty())
199  continue;
200  std::string const filename = cwd + flNotDir(storefile[i]);
201  storefile[i].assign(filename);
202  I->DestFile.assign(filename);
203  }
204 
205  // Just print out the uris and exit if the --print-uris flag was used
206  if (_config->FindB("APT::Get::Print-URIs") == true)
207  {
208  pkgAcquire::UriIterator I = Fetcher.UriBegin();
209  for (; I != Fetcher.UriEnd(); ++I)
210  std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
211  I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
212  return true;
213  }
214 
215  if (_error->PendingError() == true || CheckAuth(Fetcher, false) == false)
216  return false;
217 
218  bool Failed = false;
219  if (AcquireRun(Fetcher, 0, &Failed, NULL) == false)
220  return false;
221 
222  // copy files in local sources to the current directory
223  for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
224  {
225  std::string const filename = cwd + flNotDir((*I)->DestFile);
226  if ((*I)->Local == true &&
227  filename != (*I)->DestFile &&
228  (*I)->Status == pkgAcquire::Item::StatDone &&
229  dynamic_cast<pkgAcqArchive*>(*I) != nullptr)
230  {
231  std::ifstream src((*I)->DestFile.c_str(), std::ios::binary);
232  std::ofstream dst(filename.c_str(), std::ios::binary);
233  dst << src.rdbuf();
234  chmod(filename.c_str(), 0644);
235  }
236  }
237  return Failed == false;
238 }
239  /*}}}*/
240 // DoChangelog - Get changelog from the command line /*{{{*/
242 {
243  CacheFile Cache;
244  if (Cache.ReadOnlyOpen() == false)
245  return false;
246 
247  APT::CacheSetHelper helper;
249  CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper);
250  if (verset.empty() == true)
251  return _error->Error(_("No packages found"));
252 
253  bool const downOnly = _config->FindB("APT::Get::Download-Only", false);
254  bool const printOnly = _config->FindB("APT::Get::Print-URIs", false);
255  if (printOnly)
256  _config->CndSet("Acquire::Changelogs::AlwaysOnline", true);
257 
258  aptAcquireWithTextStatus Fetcher;
259  for (APT::VersionList::const_iterator Ver = verset.begin();
260  Ver != verset.end();
261  ++Ver)
262  {
263  if (printOnly)
264  new pkgAcqChangelog(&Fetcher, Ver, "/dev/null");
265  else if (downOnly)
266  new pkgAcqChangelog(&Fetcher, Ver, ".");
267  else
268  new pkgAcqChangelog(&Fetcher, Ver);
269  }
270 
271  if (printOnly == false)
272  {
273  bool Failed = false;
274  if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true)
275  return false;
276  }
277 
278  if (downOnly == false || printOnly == true)
279  {
280  bool Failed = false;
281  for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
282  {
283  if (printOnly)
284  {
285  if ((*I)->ErrorText.empty() == false)
286  {
287  Failed = true;
288  _error->Error("%s", (*I)->ErrorText.c_str());
289  }
290  else
291  std::cout << '\'' << (*I)->DescURI() << "' " << flNotDir((*I)->DestFile) << std::endl;
292  }
293  else
294  DisplayFileInPager((*I)->DestFile);
295  }
296  return Failed == false;
297  }
298 
299  return true;
300 }
301  /*}}}*/
302 
303 // DoClean - Remove download archives /*{{{*/
305 {
306  std::string const archivedir = _config->FindDir("Dir::Cache::archives");
307  std::string const listsdir = _config->FindDir("Dir::state::lists");
308 
309  if (_config->FindB("APT::Get::Simulate") == true)
310  {
311  std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache");
312  std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache");
313  std::cout << "Del " << archivedir << "* " << archivedir << "partial/*"<< std::endl
314  << "Del " << listsdir << "partial/*" << std::endl
315  << "Del " << pkgcache << " " << srcpkgcache << std::endl;
316  return true;
317  }
318 
319  pkgAcquire Fetcher;
320  if (archivedir.empty() == false && FileExists(archivedir) == true &&
321  Fetcher.GetLock(archivedir) == true)
322  {
323  Fetcher.Clean(archivedir);
324  Fetcher.Clean(archivedir + "partial/");
325  }
326 
327  if (listsdir.empty() == false && FileExists(listsdir) == true &&
328  Fetcher.GetLock(listsdir) == true)
329  {
330  Fetcher.Clean(listsdir + "partial/");
331  }
332 
334 
335  return true;
336 }
337  /*}}}*/
338 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
339 // ---------------------------------------------------------------------
340 /* This is similar to clean but it only purges things that cannot be
341  downloaded, that is old versions of cached packages. */
343 {
344  protected:
345  virtual void Erase(int const dirfd, char const * const File, std::string const &Pkg, std::string const &Ver,struct stat const &St) APT_OVERRIDE
346  {
347  c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << std::endl;
348 
349  if (_config->FindB("APT::Get::Simulate") == false)
350  RemoveFileAt("Cleaner::Erase", dirfd, File);
351  };
352 };
354 {
355  std::string const archivedir = _config->FindDir("Dir::Cache::Archives");
356  if (FileExists(archivedir) == false)
357  return true;
358 
359  // Lock the archive directory
360  FileFd Lock;
361  if (_config->FindB("Debug::NoLocking",false) == false)
362  {
363  int lock_fd = GetLock(flCombine(archivedir, "lock"));
364  if (lock_fd < 0)
365  return _error->Error(_("Unable to lock the download directory"));
366  Lock.Fd(lock_fd);
367  }
368 
369  CacheFile Cache;
370  if (Cache.Open(false) == false)
371  return false;
372 
373  LogCleaner Cleaner;
374 
375  return Cleaner.Go(archivedir, *Cache) &&
376  Cleaner.Go(flCombine(archivedir, "partial/"), *Cache);
377 }
378  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
bool empty() const APT_OVERRIDE
Definition: cacheset.h:815
size_t size() const APT_OVERRIDE
Definition: cacheset.h:817
const_iterator begin() const
Definition: cacheset.h:825
static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper)
returns all versions specified on the commandline
Definition: cacheset.h:870
const_iterator end() const
Definition: cacheset.h:826
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
std::string Find(const char *Name, const char *Default=0) const
bool FindB(const char *Name, bool const &Default=false) const
std::string FindDir(const char *Name, const char *Default=0) const
void CndSet(const char *Name, const std::string &Value)
std::string FindFile(const char *Name, const char *Default=0) const
Definition: fileutl.h:39
int Fd()
Definition: fileutl.h:147
virtual void Erase(int const dirfd, char const *const File, std::string const &Pkg, std::string const &Ver, struct stat const &St) APT_OVERRIDE
Definition: strutl.h:193
std::string User
Definition: strutl.h:199
std::string Password
Definition: strutl.h:200
std::string URI
Definition: metaindex.h:39
An item that is responsible for fetching a package file. {{{.
Definition: acquire-item.h:944
Retrieve the changelog for the given version {{{.
Represents the process by which a pkgAcquire object should retrieve a file or a collection of files.
Definition: acquire-item.h:59
UriIterator UriBegin()
Get the head of the list of enqueued item URIs.
Definition: acquire.cc:872
ItemIterator ItemsEnd()
Get the end iterator of the list of items.
Definition: acquire.h:305
UriIterator UriEnd()
Get the end iterator of the list of enqueued item URIs.
Definition: acquire.cc:880
bool GetLock(std::string const &Lock)
acquire lock and perform directory setup
Definition: acquire.cc:136
void SetLog(pkgAcquireStatus *Progress)
Definition: acquire.h:344
friend class Item
Definition: acquire.h:106
bool Clean(std::string Dir)
Definition: acquire.cc:790
RunResult
Provides information on how a download terminated.
Definition: acquire.h:257
@ Failed
Some files failed to download.
Definition: acquire.h:262
std::vector< Item * >::iterator ItemIterator
Definition: acquire.h:111
UriIterator(pkgAcquire::Queue *Q)
Create a new UriIterator.
RunResult Run(int PulseInterval=500000)
Download all the items that have been Add()ed to this download process.
Definition: acquire.cc:689
ItemIterator ItemsBegin()
Get the head of the list of items.
Definition: acquire.h:301
bool Go(std::string Dir, pkgCache &Cache)
Definition: clean.cc:34
pkgSourceList * GetSourceList()
Definition: cachefile.h:76
static void RemoveCaches()
Definition: cachefile.cc:308
bool ReadOnlyOpen(OpProgress *Progress=NULL)
Definition: cachefile.h:67
Configuration * _config
int GetLock(string File, bool Errors)
Definition: fileutl.cc:243
string flNotDir(string File)
Definition: fileutl.cc:664
bool FileExists(string File)
Definition: fileutl.cc:326
string flCombine(string Dir, string File)
Definition: fileutl.cc:740
bool RemoveFileAt(char const *const Function, int const dirfd, std::string const &FileName)
Definition: fileutl.cc:183
string SafeGetCWD()
Definition: fileutl.cc:637
#define APT_OVERRIDE
Definition: macros.h:111
bool AuthPrompt(std::vector< std::string > const &UntrustedList, bool const PromptUser)
bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool *const Failure, bool *const TransientNetworkFailure)
bool DoChangelog(CommandLine &CmdL)
bool DoDownload(CommandLine &CmdL)
bool DoClean(CommandLine &)
bool DoAutoClean(CommandLine &)
bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes)
bool CheckAuth(pkgAcquire &Fetcher, bool const PromptUser)
bool YnPrompt(char const *const Question, bool const Default, bool const ShowGlobalErrors, std::ostream &c1o, std::ostream &c2o)
unsigned int ScreenWidth
APT_PUBLIC std::ostream c1out
bool ShowList(std::ostream &out, std::string const &Title, Container const &cont, PredicateC Predicate, DisplayP PkgDisplay, DisplayV VerboseDisplay)
APT_PUBLIC std::ostream c2out
bool DisplayFileInPager(std::string const &filename)
string SizeToStr(double Size)
Definition: strutl.cc:437