1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22#include "tool_setup.h" 23 24#define ENABLE_CURLX_PRINTF 25/* use our own printf() functions */ 26#include "curlx.h" 27 28#include "tool_cfgable.h" 29#include "tool_cb_prg.h" 30 31#include "memdebug.h" /* keep this as LAST include */ 32 33/* 34** callback for CURLOPT_PROGRESSFUNCTION 35*/ 36 37#define MAX_BARLENGTH 256 38 39int tool_progress_cb(void *clientp, 40 double dltotal, double dlnow, 41 double ultotal, double ulnow) 42{ 43 /* The original progress-bar source code was written for curl by Lars Aas, 44 and this new edition inherits some of his concepts. */ 45 46 char line[MAX_BARLENGTH+1]; 47 char format[40]; 48 double frac; 49 double percent; 50 int barwidth; 51 int num; 52 int i; 53 54 struct ProgressData *bar = (struct ProgressData *)clientp; 55 56 /* expected transfer size */ 57 curl_off_t total = (curl_off_t)dltotal + (curl_off_t)ultotal + 58 bar->initial_size; 59 60 /* we've come this far */ 61 curl_off_t point = (curl_off_t)dlnow + (curl_off_t)ulnow + 62 bar->initial_size; 63 64 if(point > total) 65 /* we have got more than the expected total! */ 66 total = point; 67 68 /* simply count invokes */ 69 bar->calls++; 70 71 if(total < 1) { 72 curl_off_t prevblock = bar->prev / 1024; 73 curl_off_t thisblock = point / 1024; 74 while(thisblock > prevblock) { 75 fprintf(bar->out, "#"); 76 prevblock++; 77 } 78 } 79 else if(point != bar->prev) { 80 frac = (double)point / (double)total; 81 percent = frac * 100.0f; 82 barwidth = bar->width - 7; 83 num = (int) (((double)barwidth) * frac); 84 if(num > MAX_BARLENGTH) 85 num = MAX_BARLENGTH; 86 for(i = 0; i < num; i++) 87 line[i] = '#'; 88 line[i] = '\0'; 89 snprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth); 90 fprintf(bar->out, format, line, percent); 91 } 92 fflush(bar->out); 93 bar->prev = point; 94 95 return 0; 96} 97 98void progressbarinit(struct ProgressData *bar, 99 struct Configurable *config) 100{ 101#ifdef __EMX__ 102 /* 20000318 mgs */ 103 int scr_size[2]; 104#endif 105 char *colp; 106 107 memset(bar, 0, sizeof(struct ProgressData)); 108 109 /* pass this through to progress function so 110 * it can display progress towards total file 111 * not just the part that's left. (21-may-03, dbyron) */ 112 if(config->use_resume) 113 bar->initial_size = config->resume_from; 114 115/* TODO: get terminal width through ansi escapes or something similar. 116 try to update width when xterm is resized... - 19990617 larsa */ 117#ifndef __EMX__ 118 /* 20000318 mgs 119 * OS/2 users most likely won't have this env var set, and besides that 120 * we're using our own way to determine screen width */ 121 colp = curlx_getenv("COLUMNS"); 122 if(colp) { 123 char *endptr; 124 long num = strtol(colp, &endptr, 10); 125 if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 0)) 126 bar->width = (int)num; 127 else 128 bar->width = 79; 129 curl_free(colp); 130 } 131 else 132 bar->width = 79; 133#else 134 /* 20000318 mgs 135 * We use this emx library call to get the screen width, and subtract 136 * one from what we got in order to avoid a problem with the cursor 137 * advancing to the next line if we print a string that is as long as 138 * the screen is wide. */ 139 140 _scrsize(scr_size); 141 bar->width = scr_size[0] - 1; 142#endif 143 144 bar->out = config->errors; 145} 146 147