]> git.saurik.com Git - apt.git/blame - apt-private/acqprogress.cc
call URIStart in cdrom and file method
[apt.git] / apt-private / acqprogress.cc
CommitLineData
b9179170
MV
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b9179170
MV
3/* ######################################################################
4
dfad5bee
DK
5 Acquire Progress - Command line progress meter
6
b9179170
MV
7 ##################################################################### */
8 /*}}}*/
9// Include files /*{{{*/
10#include<config.h>
11
453b82a3 12#include <apt-pkg/acquire.h>
b9179170
MV
13#include <apt-pkg/acquire-item.h>
14#include <apt-pkg/acquire-worker.h>
15#include <apt-pkg/configuration.h>
16#include <apt-pkg/strutl.h>
17#include <apt-pkg/error.h>
18
453b82a3
DK
19#include <apt-private/acqprogress.h>
20
21#include <string.h>
b9179170
MV
22#include <stdio.h>
23#include <signal.h>
24#include <iostream>
b8eba208 25#include <sstream>
b9179170
MV
26#include <unistd.h>
27
b9179170
MV
28#include <apti18n.h>
29 /*}}}*/
30
b9179170
MV
31// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
32// ---------------------------------------------------------------------
33/* */
dfad5bee
DK
34AcqTextStatus::AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth,unsigned int const Quiet) :
35 pkgAcquireStatus(), out(out), ScreenWidth(ScreenWidth), LastLineLength(0), ID(0), Quiet(Quiet)
b9179170 36{
18cce398
DK
37 // testcases use it to disable pulses without disabling other user messages
38 if (Quiet == 0 && _config->FindB("quiet::NoUpdate", false) == true)
39 this->Quiet = 1;
b9179170
MV
40}
41 /*}}}*/
42// AcqTextStatus::Start - Downloading has started /*{{{*/
43// ---------------------------------------------------------------------
44/* */
d3e8fbb3 45void AcqTextStatus::Start()
b9179170 46{
d3e8fbb3 47 pkgAcquireStatus::Start();
b8eba208 48 LastLineLength = 0;
b9179170 49 ID = 1;
d3e8fbb3 50}
b9179170
MV
51 /*}}}*/
52// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
53// ---------------------------------------------------------------------
54/* */
55void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
56{
57 if (Quiet > 1)
58 return;
59
b8eba208 60 clearLastLine();
d3e8fbb3 61
dfad5bee
DK
62 out << _("Hit ") << Itm.Description;
63 out << std::endl;
b9179170 64 Update = true;
d3e8fbb3 65}
b9179170
MV
66 /*}}}*/
67// AcqTextStatus::Fetch - An item has started to download /*{{{*/
68// ---------------------------------------------------------------------
69/* This prints out the short description and the expected size */
70void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
71{
72 Update = true;
73 if (Itm.Owner->Complete == true)
74 return;
d3e8fbb3 75
b9179170 76 Itm.Owner->ID = ID++;
d3e8fbb3 77
b9179170
MV
78 if (Quiet > 1)
79 return;
80
b8eba208 81 clearLastLine();
d3e8fbb3 82
dfad5bee 83 out << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
b9179170 84 if (Itm.Owner->FileSize != 0)
dfad5bee
DK
85 out << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
86 out << std::endl;
d3e8fbb3 87}
b9179170
MV
88 /*}}}*/
89// AcqTextStatus::Done - Completed a download /*{{{*/
90// ---------------------------------------------------------------------
91/* We don't display anything... */
65512241 92void AcqTextStatus::Done(pkgAcquire::ItemDesc &/*Itm*/)
b9179170
MV
93{
94 Update = true;
d3e8fbb3 95}
b9179170
MV
96 /*}}}*/
97// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
98// ---------------------------------------------------------------------
99/* We print out the error text */
100void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
101{
102 if (Quiet > 1)
103 return;
104
105 // Ignore certain kinds of transient failures (bad code)
106 if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
107 return;
d3e8fbb3 108
b8eba208 109 clearLastLine();
d3e8fbb3 110
b9179170
MV
111 if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
112 {
dfad5bee 113 out << _("Ign ") << Itm.Description << std::endl;
d6cf2345
DK
114 if (Itm.Owner->ErrorText.empty() == false &&
115 _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == true)
dfad5bee 116 out << " " << Itm.Owner->ErrorText << std::endl;
b9179170
MV
117 }
118 else
119 {
dfad5bee
DK
120 out << _("Err ") << Itm.Description << std::endl;
121 out << " " << Itm.Owner->ErrorText << std::endl;
b9179170 122 }
d3e8fbb3 123
b9179170 124 Update = true;
d3e8fbb3 125}
b9179170
MV
126 /*}}}*/
127// AcqTextStatus::Stop - Finished downloading /*{{{*/
128// ---------------------------------------------------------------------
129/* This prints out the bytes downloaded and the overall average line
130 speed */
131void AcqTextStatus::Stop()
132{
133 pkgAcquireStatus::Stop();
134 if (Quiet > 1)
135 return;
136
b8eba208 137 clearLastLine();
b9179170 138
0c8171d7
DK
139 if (_config->FindB("quiet::NoStatistic", false) == true)
140 return;
141
b9179170 142 if (FetchedBytes != 0 && _error->PendingError() == false)
dfad5bee 143 ioprintf(out,_("Fetched %sB in %s (%sB/s)\n"),
b9179170
MV
144 SizeToStr(FetchedBytes).c_str(),
145 TimeToStr(ElapsedTime).c_str(),
146 SizeToStr(CurrentCPS).c_str());
147}
148 /*}}}*/
149// AcqTextStatus::Pulse - Regular event pulse /*{{{*/
150// ---------------------------------------------------------------------
151/* This draws the current progress. Each line has an overall percent
dfad5bee 152 meter and a per active item status meter along with an overall
b9179170
MV
153 bandwidth and ETA indicator. */
154bool AcqTextStatus::Pulse(pkgAcquire *Owner)
155{
156 pkgAcquireStatus::Pulse(Owner);
d3e8fbb3 157
b9179170
MV
158 if (Quiet > 0)
159 return true;
d3e8fbb3 160
b9179170 161 enum {Long = 0,Medium,Short} Mode = Medium;
d3e8fbb3 162
b8eba208 163 std::string Line;
b9179170 164 {
b8eba208
DK
165 std::stringstream S;
166 for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
167 I = Owner->WorkerStep(I))
b9179170 168 {
b8eba208
DK
169 // There is no item running
170 if (I->CurrentItem == 0)
b9179170 171 {
b8eba208
DK
172 if (I->Status.empty() == false)
173 S << " [" << I->Status << "]";
d3e8fbb3 174
b8eba208
DK
175 continue;
176 }
b9179170 177
b8eba208
DK
178 // Add in the short description
179 S << " [";
180 if (I->CurrentItem->Owner->ID != 0)
181 S << I->CurrentItem->Owner->ID << " ";
182 S << I->CurrentItem->ShortDesc;
d3e8fbb3 183
b8eba208
DK
184 // Show the short mode string
185 if (I->CurrentItem->Owner->ActiveSubprocess.empty() == false)
186 S << " " << I->CurrentItem->Owner->ActiveSubprocess;
d3e8fbb3 187
b8eba208
DK
188 // Add the current progress
189 if (Mode == Long)
190 S << " " << I->CurrentSize;
b9179170 191 else
b8eba208
DK
192 {
193 if (Mode == Medium || I->TotalSize == 0)
194 S << " " << SizeToStr(I->CurrentSize) << "B";
195 }
196
197 // Add the total size and percent
198 if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
199 {
200 if (Mode == Short)
201 ioprintf(S, " %.0f%%", (I->CurrentSize*100.0)/I->TotalSize);
202 else
203 ioprintf(S, "/%sB %.0f%%", SizeToStr(I->TotalSize).c_str(),
b9179170 204 (I->CurrentSize*100.0)/I->TotalSize);
b8eba208
DK
205 }
206 S << "]";
d3e8fbb3 207 }
b9179170 208
b8eba208
DK
209 // Show at least something
210 Line = S.str();
211 S.clear();
212 if (Line.empty() == true)
213 Line = _(" [Working]");
214 }
215 // Put in the percent done
216 {
217 std::stringstream S;
218 ioprintf(S, "%.0f%%", Percent);
219 S << Line;
220 Line = S.str();
221 S.clear();
222 }
d3e8fbb3 223
b9179170
MV
224 /* Put in the ETA and cps meter, block off signals to prevent strangeness
225 during resizing */
226 sigset_t Sigs,OldSigs;
227 sigemptyset(&Sigs);
228 sigaddset(&Sigs,SIGWINCH);
229 sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
d3e8fbb3 230
b9179170 231 if (CurrentCPS != 0)
d3e8fbb3 232 {
b9179170 233 unsigned long long ETA = (TotalBytes - CurrentBytes)/CurrentCPS;
b8eba208
DK
234 std::string Tmp = " " + SizeToStr(CurrentCPS) + "B/s " + TimeToStr(ETA);
235 size_t alignment = Line.length() + Tmp.length();
236 if (alignment < ScreenWidth)
d3e8fbb3 237 {
b8eba208
DK
238 alignment = ScreenWidth - alignment;
239 for (size_t i = 0; i < alignment; ++i)
240 Line.append(" ");
241 Line.append(Tmp);
d3e8fbb3 242 }
b9179170 243 }
b8eba208
DK
244 if (Line.length() > ScreenWidth)
245 Line.erase(ScreenWidth);
b9179170
MV
246 sigprocmask(SIG_SETMASK,&OldSigs,0);
247
248 // Draw the current status
249 if (_config->FindB("Apt::Color", false) == true)
dfad5bee 250 out << _config->Find("APT::Color::Yellow");
b8eba208
DK
251 if (LastLineLength > Line.length())
252 clearLastLine();
b9179170 253 else
dfad5bee
DK
254 out << '\r';
255 out << Line << std::flush;
b9179170 256 if (_config->FindB("Apt::Color", false) == true)
dfad5bee 257 out << _config->Find("APT::Color::Neutral") << std::flush;
b9179170 258
b8eba208 259 LastLineLength = Line.length();
b9179170
MV
260 Update = false;
261
262 return true;
263}
264 /*}}}*/
265// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
266// ---------------------------------------------------------------------
267/* Prompt for a media swap */
dfad5bee 268bool AcqTextStatus::MediaChange(std::string Media, std::string Drive)
b9179170
MV
269{
270 // If we do not output on a terminal and one of the options to avoid user
271 // interaction is given, we assume that no user is present who could react
272 // on your media change request
273 if (isatty(STDOUT_FILENO) != 1 && Quiet >= 2 &&
274 (_config->FindB("APT::Get::Assume-Yes",false) == true ||
275 _config->FindB("APT::Get::Force-Yes",false) == true ||
276 _config->FindB("APT::Get::Trivial-Only",false) == true))
277
278 return false;
279
b8eba208 280 clearLastLine();
dfad5bee 281 ioprintf(out,_("Media change: please insert the disc labeled\n"
b9179170
MV
282 " '%s'\n"
283 "in the drive '%s' and press enter\n"),
284 Media.c_str(),Drive.c_str());
285
286 char C = 0;
287 bool bStatus = true;
288 while (C != '\n' && C != '\r')
289 {
290 int len = read(STDIN_FILENO,&C,1);
291 if(C == 'c' || len <= 0)
292 bStatus = false;
293 }
294
295 if(bStatus)
296 Update = true;
297 return bStatus;
298}
299 /*}}}*/
b8eba208 300void AcqTextStatus::clearLastLine() { /*{{{*/
dfad5bee 301 if (Quiet > 0 || LastLineLength == 0)
b8eba208
DK
302 return;
303
304 // do not try to clear more than the (now smaller) screen
305 if (LastLineLength > ScreenWidth)
306 LastLineLength = ScreenWidth;
307
dfad5bee 308 out << '\r';
b8eba208 309 for (size_t i = 0; i < LastLineLength; ++i)
dfad5bee
DK
310 out << ' ';
311 out << '\r' << std::flush;
b8eba208
DK
312}
313 /*}}}*/