ReactOS 0.4.16-dev-199-g898cc56
progress.c
Go to the documentation of this file.
1/* progress.c
2 *
3 * Copyright (c) 1992-2001 by Mike Gleason.
4 * All rights reserved.
5 *
6 */
7
8#include "syshdrs.h"
9
10#include "util.h"
11#include "trace.h"
12#include "progress.h"
13#include "readln.h"
14
15#ifdef ncftp
16# include "log.h"
17# include "pref.h"
18#endif /* ncftp */
19
20extern const char *tcap_normal;
21extern const char *tcap_boldface;
22extern const char *tcap_underline;
23extern const char *tcap_reverse;
24extern int gScreenColumns;
25
26#ifdef ncftp
27extern char gRemoteCWD[];
28#endif /* ncftp */
29
30
31double
32FileSize(const double size, const char **uStr0, double *const uMult0)
33{
34 double uMult, uTotal;
35 const char *uStr;
36
37 /* The comparisons below may look odd, but the reason
38 * for them is that we only want a maximum of 3 digits
39 * before the decimal point. (I.e., we don't want to
40 * see "1017.2 kB", instead we want "0.99 MB".
41 */
42 if (size > (999.5 * kGigabyte)) {
43 uStr = "TB";
44 uMult = kTerabyte;
45 } else if (size > (999.5 * kMegabyte)) {
46 uStr = "GB";
47 uMult = kGigabyte;
48 } else if (size > (999.5 * kKilobyte)) {
49 uStr = "MB";
50 uMult = kMegabyte;
51 } else if (size > 999.5) {
52 uStr = "kB";
53 uMult = 1024;
54 } else {
55 uStr = "B";
56 uMult = 1;
57 }
58 if (uStr0 != NULL)
59 *uStr0 = uStr;
60 if (uMult0 != NULL)
61 *uMult0 = uMult;
62 uTotal = size / ((double) uMult);
63 if (uTotal < 0.0)
64 uTotal = 0.0;
65 return (uTotal);
66} /* FileSize */
67
68
69
70
71void
73{
74 double rate = 0.0;
75 const char *rStr;
76 static const char *uStr;
77 static double uMult;
78 char localName[32];
79 char line[128];
80 int i;
81
82 switch (mode) {
83 case kPrInitMsg:
84 if (cip->expectedSize != kSizeUnknown) {
85 cip->progress = PrStatBar;
86 PrStatBar(cip, mode);
87 return;
88 }
89 (void) FileSize((double) cip->expectedSize, &uStr, &uMult);
90
91 if (cip->lname == NULL) {
92 localName[0] = '\0';
93 } else {
94 AbbrevStr(localName, cip->lname, sizeof(localName) - 2, 0);
95 if ((cip->usingTAR) && (strlen(localName) < (sizeof(localName) - 6))) {
96 STRNCAT(localName, " (TAR)");
97 }
98 (void) STRNCAT(localName, ":");
99 }
100 if (cip->useProgressMeter) {
101#ifdef ncftp
102 if (cip->usingTAR) {
103 if (OneTimeMessage("tar") != 0) {
104 (void) fprintf(stderr, "\n\
105Note: NcFTP is using on-the-fly TAR on the remote server, which retrieves the\n\
106entire directory as one operation. This allows you to preserve exact file\n\
107timestamps, ownerships, and permissions, as well as a slight performance\n\
108boost.\n\
109\n\
110If you would rather retrieve each file individually, use the \"-T\" flag with\n\
111\"get\". TAR mode cannot be resumed if the transfer fails, so if that happens\n\
112try \"get -T\" to resume the directory transfer.\n\n");
113 }
114 }
115#endif /* ncftp */
116 (void) fprintf(stderr, "%-32s", localName);
117 }
118 break;
119
120 case kPrUpdateMsg:
121 rate = FileSize(cip->kBytesPerSec * 1024.0, &rStr, NULL);
122
123 if (cip->lname == NULL) {
124 localName[0] = '\0';
125 } else {
126 AbbrevStr(localName, cip->lname, sizeof(localName) - 2, 0);
127 if ((cip->usingTAR) && (strlen(localName) < (sizeof(localName) - 6))) {
128 STRNCAT(localName, " (TAR)");
129 }
130 (void) STRNCAT(localName, ":");
131 }
132
133#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
134 (void) sprintf(line, "%-32s %10lld bytes %6.2f %s/s",
135 localName,
137 rate,
138 rStr
139 );
140#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
141 (void) sprintf(line, "%-32s %10qd bytes %6.2f %s/s",
142 localName,
144 rate,
145 rStr
146 );
147#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
148 (void) sprintf(line, "%-32s %10I64d bytes %6.2f %s/s",
149 localName,
151 rate,
152 rStr
153 );
154#else
155 (void) sprintf(line, "%-32s %10ld bytes %6.2f %s/s",
156 localName,
157 (long) (cip->bytesTransferred + cip->startPoint),
158 rate,
159 rStr
160 );
161#endif
162
163 /* Pad the rest of the line with spaces, to erase any
164 * stuff that might have been left over from the last
165 * update.
166 */
167 for (i = (int) strlen(line); i < 80 - 2; i++)
168 line[i] = ' ';
169 line[i] = '\0';
170
171 /* Print the updated information. */
172 (void) fprintf(stderr, "\r%s", line);
173
174#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
175 SetXtermTitle("%s - [%lld bytes]", cip->lname, (longest_int) (cip->bytesTransferred + cip->startPoint));
176#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
177 SetXtermTitle("%s - [%qd bytes]", cip->lname, (longest_int) (cip->bytesTransferred + cip->startPoint));
178#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
179 SetXtermTitle("%s - [%I64d bytes]", cip->lname, (longest_int) (cip->bytesTransferred + cip->startPoint));
180#else
181 SetXtermTitle("%s - [%ld bytes]", cip->lname, (long) (cip->bytesTransferred + cip->startPoint));
182#endif
183 break;
184
185 case kPrEndMsg:
186 (void) fprintf(stderr, "\n\r");
187#ifdef ncftp
188 if (cip->rname != NULL) {
189 char url[256];
190
191 FileToURL(url, sizeof(url), cip->rname, gRemoteCWD, cip->startingWorkingDirectory, cip->user, cip->pass, cip->host, cip->port);
192 LogXfer((cip->netMode == kNetReading) ? "get" : "put", url);
193 }
194#endif
195 break;
196 }
197} /* PrSizeAndRateMeter */
198
199
200
201
202void
203PrStatBar(const FTPCIPtr cip, int mode)
204{
205 double rate, done;
206 int secLeft, minLeft;
207 const char *rStr;
208 static const char *uStr;
209 static double uTotal, uMult;
210 const char *stall;
211 char localName[80];
212 char line[134];
213 int i;
214
215 switch (mode) {
216 case kPrInitMsg:
217 fflush(stdout);
218 if (cip->expectedSize == kSizeUnknown) {
221 return;
222 }
223 uTotal = FileSize((double) cip->expectedSize, &uStr, &uMult);
224
225 if (cip->lname == NULL) {
226 localName[0] = '\0';
227 } else {
228 /* Leave room for a ':' and '\0'. */
229 AbbrevStr(localName, cip->lname, sizeof(localName) - 2, 0);
230 (void) STRNCAT(localName, ":");
231 }
232
233 if (cip->useProgressMeter)
234 (void) fprintf(stderr, "%-32s", localName);
235 break;
236
237 case kPrUpdateMsg:
238 secLeft = (int) (cip->secLeft + 0.5);
239 minLeft = secLeft / 60;
240 secLeft = secLeft - (minLeft * 60);
241 if (minLeft > 999) {
242 minLeft = 999;
243 secLeft = 59;
244 }
245
246 rate = FileSize(cip->kBytesPerSec * 1024.0, &rStr, NULL);
247 done = (double) (cip->bytesTransferred + cip->startPoint) / uMult;
248
249 if (cip->lname == NULL) {
250 localName[0] = '\0';
251 } else {
252 AbbrevStr(localName, cip->lname, 31, 0);
253 (void) STRNCAT(localName, ":");
254 }
255
256 if (cip->stalled < 2)
257 stall = " ";
258 else if (cip->stalled < 15)
259 stall = "-";
260 else
261 stall = "=";
262
263 (void) sprintf(line, "%-32s ETA: %3d:%02d %6.2f/%6.2f %.2s %6.2f %.2s/s %.1s",
264 localName,
265 minLeft,
266 secLeft,
267 done,
268 uTotal,
269 uStr,
270 rate,
271 rStr,
272 stall
273 );
274
275 /* Print the updated information. */
276 (void) fprintf(stderr, "\r%s", line);
277
278 SetXtermTitle("%s - [%.1f%%]", cip->lname, cip->percentCompleted);
279 break;
280
281 case kPrEndMsg:
282
283 rate = FileSize(cip->kBytesPerSec * 1024.0, &rStr, NULL);
284 done = (double) (cip->bytesTransferred + cip->startPoint) / uMult;
285
286 if (cip->expectedSize == (cip->bytesTransferred + cip->startPoint)) {
287 if (cip->lname == NULL) {
288 localName[0] = '\0';
289 } else {
290 AbbrevStr(localName, cip->lname, 52, 0);
291 (void) STRNCAT(localName, ":");
292 }
293
294 (void) sprintf(line, "%-53s %6.2f %.2s %6.2f %.2s/s ",
295 localName,
296 uTotal,
297 uStr,
298 rate,
299 rStr
300 );
301 } else {
302 if (cip->lname == NULL) {
303 localName[0] = '\0';
304 } else {
305 AbbrevStr(localName, cip->lname, 45, 0);
306 (void) STRNCAT(localName, ":");
307 }
308
309 (void) sprintf(line, "%-46s %6.2f/%6.2f %.2s %6.2f %.2s/s ",
310 localName,
311 done,
312 uTotal,
313 uStr,
314 rate,
315 rStr
316 );
317 }
318
319 /* Pad the rest of the line with spaces, to erase any
320 * stuff that might have been left over from the last
321 * update.
322 */
323 for (i = (int) strlen(line); i < 80 - 2; i++)
324 line[i] = ' ';
325 line[i] = '\0';
326
327 /* Print the updated information. */
328 (void) fprintf(stderr, "\r%s\n\r", line);
329#ifdef ncftp
330 if (cip->rname != NULL) {
331 char url[256];
332
333 FileToURL(url, sizeof(url), cip->rname, gRemoteCWD, cip->startingWorkingDirectory, cip->user, cip->pass, cip->host, cip->port);
334 LogXfer((cip->netMode == kNetReading) ? "get" : "put", url);
335 }
336#endif
337 break;
338 }
339} /* PrStatBar */
340
341
342
343
344/* This one is the brainchild of my comrade, Phil Dietz. It shows the
345 * progress as a fancy bar graph.
346 */
347void
348PrPhilBar(const FTPCIPtr cip, int mode)
349{
350 int perc;
352 int curBarLen;
353 static int maxBarLen;
354 char spec1[64], spec3[64];
355 static char bar[256];
356 int i;
357 int secsLeft, minLeft;
358 static const char *uStr;
359 static double uMult;
360 double rate;
361 const char *rStr;
362
363 switch (mode) {
364 case kPrInitMsg:
365 if (cip->expectedSize == kSizeUnknown) {
368 return;
369 }
370 (void) FileSize((double) cip->expectedSize, &uStr, &uMult);
371 fflush(stdout);
372 fprintf(stderr, "%s file: %s \n",
373 (cip->netMode == kNetReading) ? "Receiving" : "Sending",
374 cip->lname
375 );
376
377 for (i=0; i < (int) sizeof(bar) - 1; i++)
378 bar[i] = '=';
379 bar[i] = '\0';
380
381 /* Compute the size of the bar itself. This sits between
382 * two numbers, one on each side of the screen. So the
383 * bar length will vary, depending on how many digits we
384 * need to display the size of the file.
385 */
386 maxBarLen = gScreenColumns - 1 - 28;
387 for (s = cip->expectedSize; s > 0; s /= 10L)
388 maxBarLen--;
389
390 /* Create a specification we can hand to printf. */
391#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
392 (void) sprintf(spec1, " 0 %%%ds %%lld bytes. ETA: --:--", maxBarLen);
393
394 /* Print the first invocation, which is an empty graph
395 * plus the other stuff.
396 */
397 fprintf(stderr, spec1, " ", cip->expectedSize);
398#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
399 (void) sprintf(spec1, " 0 %%%ds %%qd bytes. ETA: --:--", maxBarLen);
400 fprintf(stderr, spec1, " ", cip->expectedSize);
401#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
402 (void) sprintf(spec1, " 0 %%%ds %%I64d bytes. ETA: --:--", maxBarLen);
403 fprintf(stderr, spec1, " ", cip->expectedSize);
404#else
405 (void) sprintf(spec1, " 0 %%%ds %%ld bytes. ETA: --:--", maxBarLen);
406 fprintf(stderr, spec1, " ", (long) cip->expectedSize);
407#endif
408 fflush(stdout);
409 break;
410
411 case kPrUpdateMsg:
412 /* Compute how much of the bar should be colored in. */
413 curBarLen = (int) (cip->percentCompleted * 0.01 * (double)maxBarLen);
414
415 /* Colored portion must be at least one character so
416 * the spec isn't '%0s' which would screw the right side
417 * of the indicator.
418 */
419 if (curBarLen < 1)
420 curBarLen = 1;
421
422 bar[curBarLen - 1] = '>';
423 bar[curBarLen] = '\0';
424
425 /* Make the spec, so we can print the bar and the other stuff. */
426 STRNCPY(spec1, "\r%3d%% 0 ");
427
428#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
429 (void) sprintf(spec3, "%%%ds %%lld bytes. %s%%3d:%%02d",
430 maxBarLen - curBarLen,
431 "ETA:"
432 );
433#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
434 (void) sprintf(spec3, "%%%ds %%qd bytes. %s%%3d:%%02d",
435 maxBarLen - curBarLen,
436 "ETA:"
437 );
438#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
439 (void) sprintf(spec3, "%%%ds %%I64d bytes. %s%%3d:%%02d",
440 maxBarLen - curBarLen,
441 "ETA:"
442 );
443#else
444 (void) sprintf(spec3, "%%%ds %%ld bytes. %s%%3d:%%02d",
445 maxBarLen - curBarLen,
446 "ETA:"
447 );
448#endif
449
450 /* We also show the percentage as a number at the left side. */
451 perc = (int) (cip->percentCompleted);
452 secsLeft = (int) (cip->secLeft);
453 minLeft = secsLeft / 60;
454 secsLeft = secsLeft - (minLeft * 60);
455 if (minLeft > 999) {
456 minLeft = 999;
457 secsLeft = 59;
458 }
459
460 /* Print the updated information. */
461 fprintf(stderr, spec1, perc);
463 fprintf(stderr, spec3,
464 "",
465 cip->expectedSize,
466 minLeft,
467 secsLeft
468 );
469
470 bar[curBarLen - 1] = '=';
471 bar[curBarLen] = '=';
472 fflush(stdout);
473
474 SetXtermTitle("%s - [%.1f%%]", cip->lname, cip->percentCompleted);
475 break;
476 case kPrEndMsg:
477 printf("\n");
478 rate = FileSize(cip->kBytesPerSec * 1024.0, &rStr, NULL);
479
480 (void) fprintf(stderr, "%s: finished in %ld:%02ld:%02ld, %.2f %s/s\n",
481 (cip->lname == NULL) ? "remote" : cip->lname,
482 (long) cip->sec / 3600L,
483 ((long) cip->sec / 60L) % 60L,
484 ((long) cip->sec % 60L),
485 rate,
486 rStr
487 );
488#ifdef ncftp
489 if (cip->rname != NULL) {
490 char url[256];
491
492 FileToURL(url, sizeof(url), cip->rname, gRemoteCWD, cip->startingWorkingDirectory, cip->user, cip->pass, cip->host, cip->port);
493 LogXfer((cip->netMode == kNetReading) ? "get" : "put", url);
494 }
495#endif
496 break;
497 }
498} /* PrPhilBar */
#define STRNCAT(d, s)
Definition: Strn.h:48
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
#define NULL
Definition: types.h:112
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
void bar()
Definition: ehthrow.cxx:142
#define printf
Definition: freeldr.h:97
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
GLdouble s
Definition: gl.h:2039
GLsizeiptr size
Definition: glext.h:5919
GLenum mode
Definition: glext.h:6217
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
char gRemoteCWD[512]
Definition: cmds.c:33
void LogXfer(const char *const mode, const char *const url)
Definition: log.c:28
int gScreenColumns
Definition: cmds.c:78
const char * tcap_reverse
Definition: readln.c:26
const char * tcap_normal
Definition: readln.c:23
void PrStatBar(const FTPCIPtr cip, int mode)
Definition: progress.c:203
const char * tcap_underline
Definition: readln.c:25
void PrSizeAndRateMeter(const FTPCIPtr cip, int mode)
Definition: progress.c:72
const char * tcap_boldface
Definition: readln.c:24
void PrPhilBar(const FTPCIPtr cip, int mode)
Definition: progress.c:348
#define kKilobyte
Definition: progress.h:8
#define kMegabyte
Definition: progress.h:9
#define kGigabyte
Definition: progress.h:10
#define kTerabyte
Definition: progress.h:11
char * FileToURL(char *url, size_t urlsize, const char *const fn, const char *const rcwd, const char *const startdir, const char *const user, const char *const pass, const char *const hname, const unsigned int port)
Definition: util.c:387
void AbbrevStr(char *dst, const char *src, size_t max, int mode)
Definition: util.c:451
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR url[]
Definition: encode.c:1432
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define kNetReading
Definition: ncftp.h:303
#define kSizeUnknown
Definition: ncftp.h:376
#define kPrInitMsg
Definition: ncftp.h:290
#define longest_int
Definition: ncftp.h:68
#define kPrEndMsg
Definition: ncftp.h:292
#define kPrUpdateMsg
Definition: ncftp.h:291
int rate
Definition: pcmconverter.c:97
int OneTimeMessage(const char *const msg)
Definition: pref.c:508
#define long
Definition: qsort.c:33
void SetXtermTitle(const char *const fmt,...)
Definition: readln.c:718
char * startingWorkingDirectory
Definition: ncftp.h:158
char host[64]
Definition: ncftp.h:136
double percentCompleted
Definition: ncftp.h:204
double sec
Definition: ncftp.h:201
FTPProgressMeterProc progress
Definition: ncftp.h:198
double kBytesPerSec
Definition: ncftp.h:203
longest_int startPoint
Definition: ncftp.h:159
int useProgressMeter
Definition: ncftp.h:199
double secLeft
Definition: ncftp.h:202
const char * rname
Definition: ncftp.h:208
const char * lname
Definition: ncftp.h:209
unsigned int port
Definition: ncftp.h:140
char pass[64]
Definition: ncftp.h:138
longest_int expectedSize
Definition: ncftp.h:205
longest_int bytesTransferred
Definition: ncftp.h:197
char user[64]
Definition: ncftp.h:137
Definition: parser.c:49