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)  

acqprogress.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  Acquire Progress - Command line progress meter
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include files /*{{{*/
10 #include <config.h>
11 
12 #include <apt-pkg/acquire-item.h>
13 #include <apt-pkg/acquire-worker.h>
14 #include <apt-pkg/acquire.h>
15 #include <apt-pkg/configuration.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/strutl.h>
18 
21 
22 #include <iostream>
23 #include <sstream>
24 #include <signal.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28 
29 #include <apti18n.h>
30  /*}}}*/
31 
32 // AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
33 // ---------------------------------------------------------------------
34 /* */
35 AcqTextStatus::AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth,unsigned int const Quiet) :
36  pkgAcquireStatus(), out(out), ScreenWidth(ScreenWidth), LastLineLength(0), ID(0), Quiet(Quiet)
37 {
38  // testcases use it to disable pulses without disabling other user messages
39  if (Quiet == 0 && _config->FindB("quiet::NoUpdate", false) == true)
40  this->Quiet = 1;
41  if (Quiet < 2 && _config->FindB("quiet::NoProgress", false) == true)
42  this->Quiet = 2;
43 }
44  /*}}}*/
45 // AcqTextStatus::Start - Downloading has started /*{{{*/
46 // ---------------------------------------------------------------------
47 /* */
49 {
51  LastLineLength = 0;
52  ID = 1;
53 }
54  /*}}}*/
55 void AcqTextStatus::AssignItemID(pkgAcquire::ItemDesc &Itm) /*{{{*/
56 {
57  /* In theory calling it from Fetch() would be enough, but to be
58  safe we call it from IMSHit and Fail as well.
59  Also, an Item can pass through multiple stages, so ensure
60  that it keeps the same number */
61  if (Itm.Owner->ID == 0)
62  Itm.Owner->ID = ID++;
63 }
64  /*}}}*/
65 // AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
66 // ---------------------------------------------------------------------
67 /* */
68 void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
69 {
70  if (Quiet > 1)
71  return;
72 
73  AssignItemID(Itm);
74  clearLastLine();
75 
76  // TRANSLATOR: Very short word to be displayed before unchanged files in 'apt-get update'
77  ioprintf(out, _("Hit:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
78  out << std::endl;
79  Update = true;
80 }
81  /*}}}*/
82 // AcqTextStatus::Fetch - An item has started to download /*{{{*/
83 // ---------------------------------------------------------------------
84 /* This prints out the short description and the expected size */
85 void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
86 {
87  Update = true;
88  if (Itm.Owner->Complete == true)
89  return;
90  AssignItemID(Itm);
91 
92  if (Quiet > 1)
93  return;
94 
95  clearLastLine();
96 
97  // TRANSLATOR: Very short word to be displayed for files processed in 'apt-get update'
98  // Potentially replaced later by "Hit:", "Ign:" or "Err:" if something (bad) happens
99  ioprintf(out, _("Get:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
100  if (Itm.Owner->FileSize != 0)
101  out << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
102  out << std::endl;
103 }
104  /*}}}*/
105 // AcqTextStatus::Done - Completed a download /*{{{*/
106 // ---------------------------------------------------------------------
107 /* We don't display anything... */
108 void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
109 {
110  Update = true;
111  AssignItemID(Itm);
112 }
113  /*}}}*/
114 // AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
115 // ---------------------------------------------------------------------
116 /* We print out the error text */
117 void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
118 {
119  if (Quiet > 1)
120  return;
121 
122  AssignItemID(Itm);
123  clearLastLine();
124 
125  bool ShowErrorText = true;
126  if (Itm.Owner->Status == pkgAcquire::Item::StatDone || Itm.Owner->Status == pkgAcquire::Item::StatIdle)
127  {
128  // TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
129  // which failed to download, but the error is ignored (compare "Err:")
130  ioprintf(out, _("Ign:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
131  if (Itm.Owner->ErrorText.empty() ||
132  _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == false)
133  ShowErrorText = false;
134  }
135  else
136  {
137  // TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
138  // which failed to download and the error is critical (compare "Ign:")
139  ioprintf(out, _("Err:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
140  }
141 
142  if (ShowErrorText)
143  {
144  std::string::size_type line_start = 0;
145  std::string::size_type line_end;
146  while ((line_end = Itm.Owner->ErrorText.find_first_of("\n\r", line_start)) != std::string::npos) {
147  out << std::endl << " " << Itm.Owner->ErrorText.substr(line_start, line_end - line_start);
148  line_start = Itm.Owner->ErrorText.find_first_not_of("\n\r", line_end + 1);
149  if (line_start == std::string::npos)
150  break;
151  }
152  if (line_start == 0)
153  out << std::endl << " " << Itm.Owner->ErrorText;
154  else if (line_start != std::string::npos)
155  out << std::endl << " " << Itm.Owner->ErrorText.substr(line_start);
156  }
157  out << std::endl;
158 
159  Update = true;
160 }
161  /*}}}*/
162 // AcqTextStatus::Stop - Finished downloading /*{{{*/
163 // ---------------------------------------------------------------------
164 /* This prints out the bytes downloaded and the overall average line
165  speed */
167 {
169  if (Quiet > 1)
170  return;
171 
172  clearLastLine();
173 
174  if (_config->FindB("quiet::NoStatistic", false) == true)
175  return;
176 
177  if (FetchedBytes != 0 && _error->PendingError() == false)
178  ioprintf(out,_("Fetched %sB in %s (%sB/s)\n"),
179  SizeToStr(FetchedBytes).c_str(),
180  TimeToStr(ElapsedTime).c_str(),
181  SizeToStr(CurrentCPS).c_str());
182 }
183  /*}}}*/
184 // AcqTextStatus::Pulse - Regular event pulse /*{{{*/
185 // ---------------------------------------------------------------------
186 /* This draws the current progress. Each line has an overall percent
187  meter and a per active item status meter along with an overall
188  bandwidth and ETA indicator. */
190 {
192 
193  if (Quiet > 0)
194  return true;
195 
196  std::string Line;
197  {
198  std::stringstream S;
199  for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
200  I = Owner->WorkerStep(I))
201  {
202  // There is no item running
203  if (I->CurrentItem == 0)
204  {
205  if (I->Status.empty() == false)
206  S << " [" << I->Status << "]";
207 
208  continue;
209  }
210 
211  // Add in the short description
212  S << " [";
213  if (I->CurrentItem->Owner->ID != 0)
214  S << std::to_string(I->CurrentItem->Owner->ID) << " ";
215  S << I->CurrentItem->ShortDesc;
216 
217  // Show the short mode string
218  if (I->CurrentItem->Owner->ActiveSubprocess.empty() == false)
219  S << " " << I->CurrentItem->Owner->ActiveSubprocess;
220 
221  enum {Long = 0,Medium,Short} Mode = Medium;
222  // Add the current progress
223  if (Mode == Long)
224  S << " " << std::to_string(I->CurrentItem->CurrentSize);
225  else
226  {
227  if (Mode == Medium || I->CurrentItem->TotalSize == 0)
228  S << " " << SizeToStr(I->CurrentItem->CurrentSize) << "B";
229  }
230 
231  // Add the total size and percent
232  if (I->CurrentItem->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
233  {
234  if (Mode == Short)
235  ioprintf(S, " %.0f%%", (I->CurrentItem->CurrentSize*100.0)/I->CurrentItem->TotalSize);
236  else
237  ioprintf(S, "/%sB %.0f%%", SizeToStr(I->CurrentItem->TotalSize).c_str(),
238  (I->CurrentItem->CurrentSize*100.0)/I->CurrentItem->TotalSize);
239  }
240  S << "]";
241  }
242 
243  // Show at least something
244  Line = S.str();
245  S.clear();
246  if (Line.empty() == true)
247  Line = _(" [Working]");
248  }
249  // Put in the percent done
250  {
251  std::stringstream S;
252  ioprintf(S, "%.0f%%", Percent);
253  S << Line;
254  Line = S.str();
255  S.clear();
256  }
257 
258  /* Put in the ETA and cps meter, block off signals to prevent strangeness
259  during resizing */
260  sigset_t Sigs,OldSigs;
261  sigemptyset(&Sigs);
262  sigaddset(&Sigs,SIGWINCH);
263  sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
264 
265  if (CurrentCPS != 0)
266  {
267  unsigned long long ETA = (TotalBytes - CurrentBytes)/CurrentCPS;
268  std::string Tmp = " " + SizeToStr(CurrentCPS) + "B/s " + TimeToStr(ETA);
269  size_t alignment = Line.length() + Tmp.length();
270  if (alignment < ScreenWidth)
271  {
272  alignment = ScreenWidth - alignment;
273  for (size_t i = 0; i < alignment; ++i)
274  Line.append(" ");
275  Line.append(Tmp);
276  }
277  }
278  if (Line.length() > ScreenWidth)
279  Line.erase(ScreenWidth);
280  sigprocmask(SIG_SETMASK,&OldSigs,0);
281 
282  // Draw the current status
283  if (_config->FindB("Apt::Color", false) == true)
284  out << _config->Find("APT::Color::Yellow");
285  if (LastLineLength > Line.length())
286  clearLastLine();
287  else
288  out << '\r';
289  out << Line << std::flush;
290  if (_config->FindB("Apt::Color", false) == true)
291  out << _config->Find("APT::Color::Neutral") << std::flush;
292 
293  LastLineLength = Line.length();
294  Update = false;
295 
296  return true;
297 }
298  /*}}}*/
299 // AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
300 // ---------------------------------------------------------------------
301 /* Prompt for a media swap */
302 bool AcqTextStatus::MediaChange(std::string Media, std::string Drive)
303 {
304  // If we do not output on a terminal and one of the options to avoid user
305  // interaction is given, we assume that no user is present who could react
306  // on your media change request
307  if (isatty(STDOUT_FILENO) != 1 && Quiet >= 2 &&
308  (_config->FindB("APT::Get::Assume-Yes",false) == true ||
309  _config->FindB("APT::Get::Force-Yes",false) == true ||
310  _config->FindB("APT::Get::Trivial-Only",false) == true))
311 
312  return false;
313 
314  clearLastLine();
315  ioprintf(out,_("Media change: please insert the disc labeled\n"
316  " '%s'\n"
317  "in the drive '%s' and press [Enter]\n"),
318  Media.c_str(),Drive.c_str());
319 
320  char C = 0;
321  bool bStatus = true;
322  while (C != '\n' && C != '\r')
323  {
324  int len = read(STDIN_FILENO,&C,1);
325  if(C == 'c' || len <= 0) {
326  bStatus = false;
327  break;
328  }
329  }
330 
331  if(bStatus)
332  Update = true;
333  return bStatus;
334 }
335  /*}}}*/
336 bool AcqTextStatus::ReleaseInfoChanges(metaIndex const * const L, metaIndex const * const N, std::vector<ReleaseInfoChange> &&Changes)/*{{{*/
337 {
338  if (Quiet >= 2 || isatty(STDOUT_FILENO) != 1 || isatty(STDIN_FILENO) != 1 ||
339  _config->FindB("APT::Get::Update::InteractiveReleaseInfoChanges", false) == false)
340  return pkgAcquireStatus::ReleaseInfoChanges(nullptr, nullptr, std::move(Changes));
341 
342  _error->PushToStack();
343  auto const confirmed = pkgAcquireStatus::ReleaseInfoChanges(L, N, std::move(Changes));
344  if (confirmed == true)
345  {
346  _error->MergeWithStack();
347  return true;
348  }
349  clearLastLine();
350  _error->DumpErrors(out, GlobalError::NOTICE, false);
351  _error->RevertToStack();
352  return YnPrompt(_("Do you want to accept these changes and continue updating from this repository?"), false, false, out, out);
353 }
354  /*}}}*/
356  if (Quiet > 0 || LastLineLength == 0)
357  return;
358 
359  // do not try to clear more than the (now smaller) screen
362 
363  out << '\r';
364  for (size_t i = 0; i < LastLineLength; ++i)
365  out << ' ';
366  out << '\r' << std::flush;
367 }
368  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
unsigned Quiet
virtual void Stop() APT_OVERRIDE
Invoked when the Acquire process stops running.
Definition: acqprogress.cc:166
virtual bool ReleaseInfoChanges(metaIndex const *const LastRelease, metaIndex const *const CurrentRelease, std::vector< ReleaseInfoChange > &&Changes) APT_OVERRIDE
ask the user for confirmation of changes to infos about a repository
Definition: acqprogress.cc:336
unsigned int & ScreenWidth
Definition: acqprogress.h:21
virtual bool MediaChange(std::string Media, std::string Drive) APT_OVERRIDE
Invoked when the user should be prompted to change the inserted removable media.
Definition: acqprogress.cc:302
unsigned long Quiet
Definition: acqprogress.h:24
virtual void IMSHit(pkgAcquire::ItemDesc &Itm) APT_OVERRIDE
Invoked when an item is confirmed to be up-to-date.
Definition: acqprogress.cc:68
virtual void Fetch(pkgAcquire::ItemDesc &Itm) APT_OVERRIDE
Invoked when some of an item's data is fetched.
Definition: acqprogress.cc:85
unsigned long ID
Definition: acqprogress.h:23
size_t LastLineLength
Definition: acqprogress.h:22
bool Pulse(pkgAcquire *Owner) APT_OVERRIDE
Periodically invoked while the Acquire process is underway.
Definition: acqprogress.cc:189
virtual void Fail(pkgAcquire::ItemDesc &Itm) APT_OVERRIDE
Invoked when the process of fetching an item encounters a fatal error.
Definition: acqprogress.cc:117
AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth, unsigned int const Quiet)
Definition: acqprogress.cc:35
virtual void Done(pkgAcquire::ItemDesc &Itm) APT_OVERRIDE
Invoked when an item is successfully and completely fetched.
Definition: acqprogress.cc:108
std::ostream & out
Definition: acqprogress.h:20
APT_HIDDEN void AssignItemID(pkgAcquire::ItemDesc &Itm)
Definition: acqprogress.cc:55
virtual void Start() APT_OVERRIDE
Invoked when the Acquire process starts running.
Definition: acqprogress.cc:48
APT_HIDDEN void clearLastLine()
Definition: acqprogress.cc:355
std::string Find(const char *Name, const char *Default=0) const
bool FindB(const char *Name, bool const &Default=false) const
@ NOTICE
deprecation warnings, old fallback behavior, …
Definition: error.h:64
A monitor object for downloads controlled by the pkgAcquire class. {{{.
Definition: acquire.h:696
virtual void Start()
Invoked when the Acquire process starts running.
Definition: acquire.cc:1436
virtual void Stop()
Invoked when the Acquire process stops running.
Definition: acquire.cc:1452
unsigned long long ElapsedTime
The amount of time that has elapsed since the download started.
Definition: acquire.h:738
virtual bool Pulse(pkgAcquire *Owner)
Periodically invoked while the Acquire process is underway.
Definition: acquire.cc:1302
double Percent
The estimated percentage of the download (0-100)
Definition: acquire.h:752
unsigned long long FetchedBytes
The total number of bytes accounted for by items that were successfully fetched.
Definition: acquire.h:733
bool Update
If true, the download scheduler should call Pulse() at the next available opportunity.
Definition: acquire.h:759
unsigned long long CurrentBytes
The number of bytes fetched as of the most recent call to pkgAcquireStatus::Pulse,...
Definition: acquire.h:721
unsigned long long TotalBytes
The total number of bytes that need to be fetched.
Definition: acquire.h:728
unsigned long long CurrentCPS
The current rate of download as of the most recent call to pkgAcquireStatus::Pulse,...
Definition: acquire.h:716
virtual bool ReleaseInfoChanges(metaIndex const *const LastRelease, metaIndex const *const CurrentRelease, std::vector< ReleaseInfoChange > &&Changes)
ask the user for confirmation of changes to infos about a repository
Definition: acquire.cc:1478
Represents the process by which a pkgAcquire object should retrieve a file or a collection of files.
Definition: acquire-item.h:59
Worker * WorkersBegin()
Get the first Worker object.
Definition: acquire.h:291
Worker(Queue *OwnerQ, MethodConfig *Config, pkgAcquireStatus *Log)
Create a new Worker to download files.
Worker * WorkerStep(Worker *I) APT_PURE
Advance to the next Worker object.
Definition: acquire.cc:781
Configuration * _config
bool YnPrompt(char const *const Question, bool const Default, bool const ShowGlobalErrors, std::ostream &c1o, std::ostream &c2o)
unsigned int ScreenWidth
string SizeToStr(double Size)
Definition: strutl.cc:437
void ioprintf(ostream &out, const char *format,...)
Definition: strutl.cc:1433
string TimeToStr(unsigned long Sec)
Definition: strutl.cc:473