Join with aliencode
[ntk/apt.git] / cmdline / acqprogress.cc
CommitLineData
0919e3f9
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b2e465d6 3// $Id: acqprogress.cc,v 1.21 2001/02/20 07:03:17 jgg Exp $
0919e3f9
AL
4/* ######################################################################
5
6 Acquire Progress - Command line progress meter
7
8 ##################################################################### */
9 /*}}}*/
10// Include files /*{{{*/
11#include "acqprogress.h"
12#include <apt-pkg/acquire-item.h>
13#include <apt-pkg/acquire-worker.h>
cdcc6d34 14#include <apt-pkg/strutl.h>
8508b1df 15#include <apt-pkg/error.h>
b0db36b1 16
b2e465d6
AL
17#include <apti18n.h>
18
0919e3f9 19#include <stdio.h>
b0db36b1 20#include <signal.h>
0919e3f9
AL
21 /*}}}*/
22
23// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
24// ---------------------------------------------------------------------
25/* */
d7827aca 26AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) :
0919e3f9
AL
27 ScreenWidth(ScreenWidth), Quiet(Quiet)
28{
29}
30 /*}}}*/
31// AcqTextStatus::Start - Downloading has started /*{{{*/
32// ---------------------------------------------------------------------
33/* */
34void AcqTextStatus::Start()
35{
36 pkgAcquireStatus::Start();
37 BlankLine[0] = 0;
38 ID = 1;
39};
40 /*}}}*/
41// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
42// ---------------------------------------------------------------------
43/* */
44void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
45{
46 if (Quiet > 1)
47 return;
48
49 if (Quiet <= 0)
50 cout << '\r' << BlankLine << '\r';
51
b2e465d6 52 cout << _("Hit ") << Itm.Description;
0919e3f9 53 if (Itm.Owner->FileSize != 0)
314037ba 54 cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
0919e3f9
AL
55 cout << endl;
56 Update = true;
57};
58 /*}}}*/
59// AcqTextStatus::Fetch - An item has started to download /*{{{*/
60// ---------------------------------------------------------------------
61/* This prints out the short description and the expected size */
62void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
63{
64 Update = true;
65 if (Itm.Owner->Complete == true)
66 return;
67
68 Itm.Owner->ID = ID++;
69
70 if (Quiet > 1)
71 return;
72
73 if (Quiet <= 0)
74 cout << '\r' << BlankLine << '\r';
75
b2e465d6 76 cout << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
0919e3f9 77 if (Itm.Owner->FileSize != 0)
314037ba 78 cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
0919e3f9
AL
79 cout << endl;
80};
81 /*}}}*/
82// AcqTextStatus::Done - Completed a download /*{{{*/
83// ---------------------------------------------------------------------
84/* We don't display anything... */
85void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
86{
87 Update = true;
88};
89 /*}}}*/
90// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
91// ---------------------------------------------------------------------
92/* We print out the error text */
93void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
94{
95 if (Quiet > 1)
96 return;
97
b800c80c 98 // Ignore certain kinds of transient failures (bad code)
281daf46
AL
99 if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
100 return;
101
0919e3f9
AL
102 if (Quiet <= 0)
103 cout << '\r' << BlankLine << '\r';
104
2b154e53 105 if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
681d76d0 106 {
b2e465d6 107 cout << _("Ign ") << Itm.Description << endl;
681d76d0
AL
108 }
109 else
110 {
b2e465d6 111 cout << _("Err ") << Itm.Description << endl;
681d76d0
AL
112 cout << " " << Itm.Owner->ErrorText << endl;
113 }
114
0919e3f9
AL
115 Update = true;
116};
117 /*}}}*/
118// AcqTextStatus::Stop - Finished downloading /*{{{*/
119// ---------------------------------------------------------------------
120/* This prints out the bytes downloaded and the overall average line
121 speed */
122void AcqTextStatus::Stop()
123{
124 pkgAcquireStatus::Stop();
125 if (Quiet > 1)
126 return;
127
128 if (Quiet <= 0)
9e2a06ff 129 cout << '\r' << BlankLine << '\r' << flush;
b2e465d6 130
8508b1df 131 if (FetchedBytes != 0 && _error->PendingError() == false)
b2e465d6
AL
132 ioprintf(cout,_("Fetched %sB in %s (%sB/s)\n"),
133 SizeToStr(FetchedBytes).c_str(),
134 TimeToStr(ElapsedTime).c_str(),
135 SizeToStr(CurrentCPS).c_str());
0919e3f9
AL
136}
137 /*}}}*/
138// AcqTextStatus::Pulse - Regular event pulse /*{{{*/
139// ---------------------------------------------------------------------
140/* This draws the current progress. Each line has an overall percent
141 meter and a per active item status meter along with an overall
142 bandwidth and ETA indicator. */
024d1123 143bool AcqTextStatus::Pulse(pkgAcquire *Owner)
0919e3f9
AL
144{
145 if (Quiet > 0)
024d1123 146 return true;
0919e3f9
AL
147
148 pkgAcquireStatus::Pulse(Owner);
149
150 enum {Long = 0,Medium,Short} Mode = Long;
151
8b067c22 152 char Buffer[1024];
0919e3f9
AL
153 char *End = Buffer + sizeof(Buffer);
154 char *S = Buffer;
8b067c22
AL
155 if (ScreenWidth >= sizeof(Buffer))
156 ScreenWidth = sizeof(Buffer)-1;
157
0919e3f9 158 // Put in the percent done
d568ed2d
AL
159 sprintf(S,"%ld%%",long(double((CurrentBytes + CurrentItems)*100.0)/double(TotalBytes+TotalItems)));
160
161 bool Shown = false;
0919e3f9
AL
162 for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
163 I = Owner->WorkerStep(I))
164 {
165 S += strlen(S);
166
167 // There is no item running
168 if (I->CurrentItem == 0)
169 {
170 if (I->Status.empty() == false)
afce5764 171 {
0919e3f9 172 snprintf(S,End-S," [%s]",I->Status.c_str());
afce5764
AL
173 Shown = true;
174 }
175
0919e3f9
AL
176 continue;
177 }
178
d568ed2d
AL
179 Shown = true;
180
0919e3f9
AL
181 // Add in the short description
182 if (I->CurrentItem->Owner->ID != 0)
eec898ad 183 snprintf(S,End-S," [%lu %s",I->CurrentItem->Owner->ID,
0919e3f9
AL
184 I->CurrentItem->ShortDesc.c_str());
185 else
186 snprintf(S,End-S," [%s",I->CurrentItem->ShortDesc.c_str());
187 S += strlen(S);
188
189 // Show the short mode string
190 if (I->CurrentItem->Owner->Mode != 0)
191 {
192 snprintf(S,End-S," %s",I->CurrentItem->Owner->Mode);
193 S += strlen(S);
194 }
195
196 // Add the current progress
197 if (Mode == Long)
f40e3a64 198 snprintf(S,End-S," %lu",I->CurrentSize);
0919e3f9
AL
199 else
200 {
201 if (Mode == Medium || I->TotalSize == 0)
314037ba 202 snprintf(S,End-S," %sB",SizeToStr(I->CurrentSize).c_str());
0919e3f9
AL
203 }
204 S += strlen(S);
205
206 // Add the total size and percent
207 if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
208 {
209 if (Mode == Short)
f40e3a64 210 snprintf(S,End-S," %lu%%",
0919e3f9
AL
211 long(double(I->CurrentSize*100.0)/double(I->TotalSize)));
212 else
314037ba 213 snprintf(S,End-S,"/%sB %lu%%",SizeToStr(I->TotalSize).c_str(),
0919e3f9
AL
214 long(double(I->CurrentSize*100.0)/double(I->TotalSize)));
215 }
216 S += strlen(S);
217 snprintf(S,End-S,"]");
218 }
219
d568ed2d
AL
220 // Show something..
221 if (Shown == false)
b2e465d6 222 snprintf(S,End-S,_(" [Working]"));
d568ed2d 223
b0db36b1
AL
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);
230
0919e3f9
AL
231 if (CurrentCPS != 0)
232 {
233 char Tmp[300];
234 unsigned long ETA = (unsigned long)((TotalBytes - CurrentBytes)/CurrentCPS);
314037ba 235 sprintf(Tmp," %sB/s %s",SizeToStr(CurrentCPS).c_str(),TimeToStr(ETA).c_str());
0919e3f9
AL
236 unsigned int Len = strlen(Buffer);
237 unsigned int LenT = strlen(Tmp);
238 if (Len + LenT < ScreenWidth)
239 {
240 memset(Buffer + Len,' ',ScreenWidth - Len);
241 strcpy(Buffer + ScreenWidth - LenT,Tmp);
242 }
243 }
244 Buffer[ScreenWidth] = 0;
b0db36b1 245 BlankLine[ScreenWidth] = 0;
b2e465d6 246 sigprocmask(SIG_SETMASK,&OldSigs,0);
b0db36b1 247
0919e3f9
AL
248 // Draw the current status
249 if (strlen(Buffer) == strlen(BlankLine))
250 cout << '\r' << Buffer << flush;
251 else
252 cout << '\r' << BlankLine << '\r' << Buffer << flush;
253 memset(BlankLine,' ',strlen(Buffer));
254 BlankLine[strlen(Buffer)] = 0;
255
256 Update = false;
024d1123
AL
257
258 return true;
0919e3f9
AL
259}
260 /*}}}*/
542ec555
AL
261// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
262// ---------------------------------------------------------------------
263/* Prompt for a media swap */
264bool AcqTextStatus::MediaChange(string Media,string Drive)
265{
266 if (Quiet <= 0)
b2e465d6
AL
267 cout << '\r' << BlankLine << '\r';
268 ioprintf(cout,_("Media Change: Please insert the disc labeled '%s' in "
269 "the drive '%s' and press enter\n"),
270 Media.c_str(),Drive.c_str());
542ec555 271
ac49a1e5
AL
272 char C = 0;
273 while (C != '\n' && C != '\r')
274 read(STDIN_FILENO,&C,1);
542ec555
AL
275
276 Update = true;
277 return true;
278}
279 /*}}}*/