ReactOS  0.4.14-dev-77-gd9e7c48
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 
20 extern const char *tcap_normal;
21 extern const char *tcap_boldface;
22 extern const char *tcap_underline;
23 extern const char *tcap_reverse;
24 extern int gScreenColumns;
25 
26 #ifdef ncftp
27 extern char gRemoteCWD[];
28 #endif /* ncftp */
29 
30 
31 double
32 FileSize(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 
71 void
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\
105 Note: NcFTP is using on-the-fly TAR on the remote server, which retrieves the\n\
106 entire directory as one operation. This allows you to preserve exact file\n\
107 timestamps, ownerships, and permissions, as well as a slight performance\n\
108 boost.\n\
109 \n\
110 If 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\
112 try \"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,
136  (longest_int) (cip->bytesTransferred + cip->startPoint),
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,
143  (longest_int) (cip->bytesTransferred + cip->startPoint),
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,
150  (longest_int) (cip->bytesTransferred + cip->startPoint),
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 
202 void
203 PrStatBar(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[128];
213  int i;
214 
215  switch (mode) {
216  case kPrInitMsg:
217  fflush(stdout);
218  if (cip->expectedSize == kSizeUnknown) {
220  PrSizeAndRateMeter(cip, mode);
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  */
347 void
348 PrPhilBar(const FTPCIPtr cip, int mode)
349 {
350  int perc;
351  longest_int s;
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) {
367  PrSizeAndRateMeter(cip, mode);
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);
462  fprintf(stderr, "%s%s%s", tcap_reverse, bar, tcap_normal);
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 */
longest_int expectedSize
Definition: ncftp.h:205
unsigned int port
Definition: ncftp.h:140
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char pass[64]
Definition: ncftp.h:138
const char * tcap_reverse
Definition: readln.c:26
void AbbrevStr(char *dst, const char *src, size_t max, int mode)
Definition: util.c:451
#define kPrInitMsg
Definition: ncftp.h:290
char user[64]
Definition: ncftp.h:137
double sec
Definition: ncftp.h:201
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
FTPProgressMeterProc progress
Definition: ncftp.h:198
int rate
Definition: pcmconverter.c:98
void PrSizeAndRateMeter(const FTPCIPtr cip, int mode)
Definition: progress.c:72
int useProgressMeter
Definition: ncftp.h:199
FILE * stdout
int gScreenColumns
Definition: main.c:34
#define kGigabyte
Definition: progress.h:10
#define sprintf(buf, format,...)
Definition: sprintf.c:55
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
#define kTerabyte
Definition: progress.h:11
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
char host[64]
Definition: ncftp.h:136
int OneTimeMessage(const char *const msg)
Definition: pref.c:508
double percentCompleted
Definition: ncftp.h:204
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
void SetXtermTitle(const char *const fmt,...)
Definition: readln.c:718
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
void PrPhilBar(const FTPCIPtr cip, int mode)
Definition: progress.c:348
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
const char * tcap_boldface
Definition: readln.c:24
#define kPrEndMsg
Definition: ncftp.h:292
const char * rname
Definition: ncftp.h:208
#define STRNCAT(d, s)
Definition: Strn.h:48
char * startingWorkingDirectory
Definition: ncftp.h:158
GLsizeiptr size
Definition: glext.h:5919
static const WCHAR url[]
Definition: encode.c:1432
#define longest_int
Definition: ncftp.h:68
#define kNetReading
Definition: ncftp.h:303
const char * tcap_normal
Definition: readln.c:23
longest_int bytesTransferred
Definition: ncftp.h:197
double secLeft
Definition: ncftp.h:202
static const WCHAR L[]
Definition: oid.c:1250
char gRemoteCWD[512]
Definition: cmds.c:33
GLdouble s
Definition: gl.h:2039
GLenum mode
Definition: glext.h:6217
double kBytesPerSec
Definition: ncftp.h:203
#define kKilobyte
Definition: progress.h:8
#define kPrUpdateMsg
Definition: ncftp.h:291
longest_int startPoint
Definition: ncftp.h:159
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
void PrStatBar(const FTPCIPtr cip, int mode)
Definition: progress.c:203
#define long
Definition: qsort.c:33
const char * lname
Definition: ncftp.h:209
#define kMegabyte
Definition: progress.h:9
#define kSizeUnknown
Definition: ncftp.h:376
FILE * stderr
void LogXfer(const char *const mode, const char *const url)
Definition: log.c:28
double FileSize(const double size, const char **uStr0, double *const uMult0)
Definition: progress.c:32
const char * tcap_underline
Definition: readln.c:25
#define printf
Definition: config.h:203
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31