curl tool: reviewed code moved to tool_*.[ch] files

my_setopt and my_setopt_str no longer ignores curl_easy_setopt result.

Fixed some OOM handling issues.
This commit is contained in:
Yang Tse 2011-09-21 01:54:14 +02:00
parent 84221006c9
commit 9ecf53e154
12 changed files with 601 additions and 308 deletions

View File

@ -11,8 +11,8 @@ SOURCE \
main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c xattr.c \
tool_bname.c tool_cfgable.c tool_convert.c tool_dirhie.c \
tool_doswin.c tool_mfiles.c tool_msgs.c tool_myfunc.c \
tool_vms.c
tool_doswin.c tool_easysrc.c tool_mfiles.c tool_msgs.c \
tool_myfunc.c tool_progress.c tool_setopt.c tool_vms.c
SOURCEPATH ../../../lib
SOURCE \

View File

@ -17,15 +17,16 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c xattr.c \
tool_bname.c tool_cfgable.c tool_convert.c tool_dirhie.c \
tool_doswin.c tool_mfiles.c tool_msgs.c tool_myfunc.c \
tool_vms.c
tool_doswin.c tool_easysrc.c tool_mfiles.c tool_msgs.c \
tool_myfunc.c tool_progress.c tool_setopt.c tool_vms.c
CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
config-riscos.h urlglob.h version.h xattr.h \
writeout.h writeenv.h getpass.h homedir.h curlutil.h \
tool_bname.h tool_cfgable.h tool_convert.h tool_dirhie.h \
tool_doswin.h tool_mfiles.h tool_msgs.h tool_myfunc.h \
tool_sdecls.h tool_vms.h
tool_doswin.h tool_easysrc.h tool_mfiles.h tool_msgs.h \
tool_myfunc.h tool_progress.h tool_sdecls.h tool_setopt.h \
tool_vms.h
curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)

View File

@ -146,9 +146,12 @@ RELEASE_OBJS= \
tool_convertr.obj \
tool_dirhier.obj \
tool_doswinr.obj \
tool_easysrcr.obj \
tool_mfilesr.obj \
tool_msgsr.obj \
tool_myfuncr.obj \
tool_progressr.obj \
tool_setoptr.obj \
tool_vmsr.obj \
urlglobr.obj \
writeoutr.obj \
@ -169,9 +172,12 @@ DEBUG_OBJS= \
tool_convertd.obj \
tool_dirhied.obj \
tool_doswind.obj \
tool_easysrcd.obj \
tool_mfilesd.obj \
tool_msgsd.obj \
tool_myfuncd.obj \
tool_progressd.obj \
tool_setoptd.obj \
tool_vmsd.obj \
urlglobd.obj \
writeoutd.obj \
@ -326,12 +332,18 @@ tool_dirhier.obj: tool_dirhie.c
$(CCR) $(CFLAGS) /Fo"$@" tool_dirhie.c
tool_doswinr.obj: tool_doswin.c
$(CCR) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcr.obj: tool_easysrc.c
$(CCR) $(CFLAGS) /Fo"$@" tool_easysrc.c
tool_mfilesr.obj: tool_mfiles.c
$(CCR) $(CFLAGS) /Fo"$@" tool_mfiles.c
tool_msgsr.obj: tool_msgs.c
$(CCR) $(CFLAGS) /Fo"$@" tool_msgs.c
tool_myfuncr.obj: tool_myfunc.c
$(CCR) $(CFLAGS) /Fo"$@" tool_myfunc.c
tool_progressr.obj: tool_progress.c
$(CCR) $(CFLAGS) /Fo"$@" tool_progress.c
tool_setoptr.obj: tool_setopt.c
$(CCR) $(CFLAGS) /Fo"$@" tool_setopt.c
tool_vmsr.obj: tool_vms.c
$(CCR) $(CFLAGS) /Fo"$@" tool_vms.c
xattrr.obj: xattr.c
@ -370,12 +382,18 @@ tool_dirhied.obj: tool_dirhie.c
$(CCD) $(CFLAGS) /Fo"$@" tool_dirhie.c
tool_doswind.obj: tool_doswin.c
$(CCD) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcd.obj: tool_easysrc.c
$(CCD) $(CFLAGS) /Fo"$@" tool_easysrc.c
tool_mfilesd.obj: tool_mfiles.c
$(CCD) $(CFLAGS) /Fo"$@" tool_mfiles.c
tool_msgsd.obj: tool_msgs.c
$(CCD) $(CFLAGS) /Fo"$@" tool_msgs.c
tool_myfuncd.obj: tool_myfunc.c
$(CCD) $(CFLAGS) /Fo"$@" tool_myfunc.c
tool_progressd.obj: tool_progress.c
$(CCD) $(CFLAGS) /Fo"$@" tool_progress.c
tool_setoptd.obj: tool_setopt.c
$(CCD) $(CFLAGS) /Fo"$@" tool_setopt.c
tool_vmsd.obj: tool_vms.c
$(CCD) $(CFLAGS) /Fo"$@" tool_vms.c
xattrd.obj: xattr.c

View File

@ -97,9 +97,12 @@
#include "tool_convert.h"
#include "tool_dirhie.h"
#include "tool_doswin.h"
#include "tool_easysrc.h"
#include "tool_mfiles.h"
#include "tool_msgs.h"
#include "tool_myfunc.h"
#include "tool_progress.h"
#include "tool_setopt.h"
#include "tool_vms.h"
#ifdef USE_MANUAL
# include "hugehelp.h"
@ -181,9 +184,6 @@ char **__crt0_glob_function (char *arg)
#define CURLseparator "--_curl_--"
#define CURL_PROGRESS_STATS 0 /* default progress display */
#define CURL_PROGRESS_BAR 1
/*
* Default sizeof(off_t) in case it hasn't been defined in config file.
*/
@ -3177,121 +3177,6 @@ static size_t my_fread(void *buffer, size_t sz, size_t nmemb, void *userp)
return (size_t)rc;
}
struct ProgressData {
int calls;
curl_off_t prev;
int width;
FILE *out; /* where to write everything to */
curl_off_t initial_size;
};
static int myprogress (void *clientp,
double dltotal,
double dlnow,
double ultotal,
double ulnow)
{
/* The original progress-bar source code was written for curl by Lars Aas,
and this new edition inherits some of his concepts. */
char line[256];
char outline[256];
char format[40];
double frac;
double percent;
int barwidth;
int num;
int i;
struct ProgressData *bar = (struct ProgressData *)clientp;
curl_off_t total = (curl_off_t)dltotal + (curl_off_t)ultotal +
bar->initial_size; /* expected transfer size */
curl_off_t point = (curl_off_t)dlnow + (curl_off_t)ulnow +
bar->initial_size; /* we've come this far */
if(point > total)
/* we have got more than the expected total! */
total = point;
bar->calls++; /* simply count invokes */
if(total < 1) {
curl_off_t prevblock = bar->prev / 1024;
curl_off_t thisblock = point / 1024;
while(thisblock > prevblock) {
fprintf( bar->out, "#" );
prevblock++;
}
}
else {
frac = (double)point / (double)total;
percent = frac * 100.0f;
barwidth = bar->width - 7;
num = (int) (((double)barwidth) * frac);
for(i = 0; i < num; i++)
line[i] = '#';
line[i] = '\0';
snprintf( format, sizeof(format), "%%-%ds %%5.1f%%%%", barwidth );
snprintf( outline, sizeof(outline), format, line, percent );
fprintf( bar->out, "\r%s", outline );
}
fflush(bar->out);
bar->prev = point;
return 0;
}
static
void progressbarinit(struct ProgressData *bar,
struct Configurable *config)
{
#ifdef __EMX__
/* 20000318 mgs */
int scr_size [2];
#endif
char *colp;
memset(bar, 0, sizeof(struct ProgressData));
/* pass this through to progress function so
* it can display progress towards total file
* not just the part that's left. (21-may-03, dbyron) */
if(config->use_resume)
bar->initial_size = config->resume_from;
/* TODO: get terminal width through ansi escapes or something similar.
try to update width when xterm is resized... - 19990617 larsa */
#ifndef __EMX__
/* 20000318 mgs
* OS/2 users most likely won't have this env var set, and besides that
* we're using our own way to determine screen width */
colp = curlx_getenv("COLUMNS");
if(colp != NULL) {
char *endptr;
long num = strtol(colp, &endptr, 10);
if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 0))
bar->width = (int)num;
else
bar->width = 79;
curl_free(colp);
}
else
bar->width = 79;
#else
/* 20000318 mgs
* We use this emx library call to get the screen width, and subtract
* one from what we got in order to avoid a problem with the cursor
* advancing to the next line if we print a string that is as long as
* the screen is wide. */
_scrsize(scr_size);
bar->width = scr_size[0] - 1;
#endif
bar->out = config->errors;
}
static
void dump(const char *timebuf, const char *text,
FILE *stream, const unsigned char *ptr, size_t size,
@ -3539,165 +3424,6 @@ output_expected(const char* url, const char* uploadfile)
return FALSE; /* non-HTTP upload, probably no output should be expected */
}
#define my_setopt(x,y,z) _my_setopt(x, FALSE, config, #y, y, z)
#define my_setopt_str(x,y,z) _my_setopt(x, TRUE, config, #y, y, z)
static struct curl_slist *easycode;
static struct curl_slist *easycode_remarks;
static CURLcode _my_setopt(CURL *curl, bool str, struct Configurable *config,
const char *name, CURLoption tag, ...);
static CURLcode _my_setopt(CURL *curl, bool str, struct Configurable *config,
const char *name, CURLoption tag, ...)
{
va_list arg;
CURLcode ret;
char *bufp;
char value[256];
bool remark=FALSE;
bool skip=FALSE;
va_start(arg, tag);
if(tag < CURLOPTTYPE_OBJECTPOINT) {
long lval = va_arg(arg, long);
snprintf(value, sizeof(value), "%ldL", lval);
ret = curl_easy_setopt(curl, tag, lval);
if(!lval)
skip = TRUE;
}
else if(tag < CURLOPTTYPE_OFF_T) {
void *pval = va_arg(arg, void *);
unsigned char *ptr = (unsigned char *)pval;
/* function pointers are never printable */
if(tag >= CURLOPTTYPE_FUNCTIONPOINT) {
if(pval) {
strcpy(value, "functionpointer"); /* 'value' fits 256 bytes */
remark = TRUE;
}
else
skip = TRUE;
}
else if(pval && str)
snprintf(value, sizeof(value), "\"%s\"", (char *)ptr);
else if(pval) {
strcpy(value, "objectpointer"); /* 'value' fits 256 bytes */
remark = TRUE;
}
else
skip = TRUE;
ret = curl_easy_setopt(curl, tag, pval);
}
else {
curl_off_t oval = va_arg(arg, curl_off_t);
snprintf(value, sizeof(value),
"(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
ret = curl_easy_setopt(curl, tag, oval);
if(!oval)
skip = TRUE;
}
if(config->libcurl && !skip) {
/* we only use this for real if --libcurl was used */
if(remark)
bufp = curlx_maprintf("%s set to a %s", name, value);
else
bufp = curlx_maprintf("curl_easy_setopt(hnd, %s, %s);", name, value);
if(!bufp)
ret = CURLE_OUT_OF_MEMORY;
else {
struct curl_slist *list =
curl_slist_append(remark?easycode_remarks:easycode, bufp);
if(remark)
easycode_remarks = list;
else
easycode = list;
}
if(bufp)
curl_free(bufp);
}
va_end(arg);
return ret;
}
static const char * const srchead[]={
"/********* Sample code generated by the curl command line tool **********",
" * All curl_easy_setopt() options are documented at:",
" * http://curl.haxx.se/libcurl/c/curl_easy_setopt.html",
" ************************************************************************/",
"#include <curl/curl.h>",
"",
"int main(int argc, char *argv[])",
"{",
" CURLcode ret;",
NULL
};
static void dumpeasycode(struct Configurable *config)
{
struct curl_slist *ptr;
char *o = config->libcurl;
if(o) {
FILE *out;
bool fopened = FALSE;
if(strcmp(o, "-")) {
out = fopen(o, "wt");
fopened = TRUE;
}
else
out= stdout;
if(!out)
warnf(config, "Failed to open %s to write libcurl code!\n", o);
else {
int i;
const char *c;
for(i=0; ((c = srchead[i]) != '\0'); i++)
fprintf(out, "%s\n", c);
ptr = easycode;
while(ptr) {
fprintf(out, " %s\n", ptr->data);
ptr = ptr->next;
}
ptr = easycode_remarks;
if(ptr) {
fprintf(out,
"\n /* Here is a list of options the curl code"
" used that cannot get generated\n"
" as source easily. You may select to either"
" not use them or implement\n them yourself.\n"
"\n");
while(ptr) {
fprintf(out, " %s\n", ptr->data);
ptr = ptr->next;
}
fprintf(out, "\n */\n");
}
fprintf(out,
" return (int)ret;\n"
"}\n"
"/**** End of sample code ****/\n");
if(fopened)
fclose(out);
}
}
curl_slist_free_all(easycode);
}
static bool stdin_upload(const char *uploadfile)
{
return (curlx_strequal(uploadfile, "-") ||
@ -4126,16 +3852,34 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
!config->capath &&
!config->insecure_ok) {
env = curlx_getenv("CURL_CA_BUNDLE");
if(env)
GetStr(&config->cacert, env);
if(env) {
config->cacert = strdup(env);
if(!config->cacert) {
clean_getout(config);
curl_free(env);
goto quit_curl;
}
}
else {
env = curlx_getenv("SSL_CERT_DIR");
if(env)
GetStr(&config->capath, env);
if(env) {
config->capath = strdup(env);
if(!config->capath) {
clean_getout(config);
curl_free(env);
goto quit_curl;
}
}
else {
env = curlx_getenv("SSL_CERT_FILE");
if(env)
GetStr(&config->cacert, env);
if(env) {
config->cacert = strdup(env);
if(!config->cacert) {
clean_getout(config);
curl_free(env);
goto quit_curl;
}
}
}
}
@ -4170,9 +3914,9 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
}
}
/* This is the first entry added to easycode and it initializes the slist */
easycode = curl_slist_append(easycode, "CURL *hnd = curl_easy_init();");
if(!easycode) {
/* This is the first entry added to easysrc and it initializes the slist */
easysrc = curl_slist_append(easysrc, "CURL *hnd = curl_easy_init();");
if(!easysrc) {
clean_getout(config);
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
@ -4760,7 +4504,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
!config->noprogress && !config->mute) {
/* we want the alternative style, then we have to implement it
ourselves! */
my_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
my_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress);
my_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
}
@ -4798,17 +4542,14 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
my_setopt(curl, CURLOPT_VERBOSE, TRUE);
}
res = CURLE_OK;
/* new in curl ?? */
/* new in curl 7.9.3 */
if(config->engine) {
res = my_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
res = res_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
if(res)
goto show_error;
my_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1);
}
if(res != CURLE_OK)
goto show_error;
if(config->encoding)
my_setopt_str(curl, CURLOPT_ACCEPT_ENCODING, "");
@ -4953,8 +4694,10 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
my_setopt(curl, CURLOPT_RESOLVE, config->resolve);
/* new in 7.21.4 */
my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME, config->tls_username);
my_setopt_str(curl, CURLOPT_TLSAUTH_PASSWORD, config->tls_password);
if(config->tls_username)
my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME, config->tls_username);
if(config->tls_password)
my_setopt_str(curl, CURLOPT_TLSAUTH_PASSWORD, config->tls_password);
/* new in 7.22.0 */
if(config->gssapi_delegation)
@ -4967,7 +4710,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
for(;;) {
res = curl_easy_perform(curl);
if(!curl_slist_append(easycode, "ret = curl_easy_perform(hnd);")) {
if(!curl_slist_append(easysrc, "ret = curl_easy_perform(hnd);")) {
res = CURLE_OUT_OF_MEMORY;
break;
}
@ -5221,8 +4964,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
/* cleanup the curl handle! */
curl_easy_cleanup(curl);
config->easy = NULL; /* cleanup now */
if(easycode)
curl_slist_append(easycode, "curl_easy_cleanup(hnd);");
if(easysrc)
curl_slist_append(easysrc, "curl_easy_cleanup(hnd);");
if(heads.stream && (heads.stream != stdout))
fclose(heads.stream);
@ -5233,7 +4976,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
/* Dump the libcurl code if previously enabled.
NOTE: that this function relies on config->errors amongst other things
so not everything can be closed and cleaned before this is called */
dumpeasycode(config);
dumpeasysrc(config);
if(config->errors_fopened)
fclose(config->errors);

View File

@ -91,7 +91,7 @@ struct Configurable {
bool netrc_opt;
bool netrc;
char *netrc_file;
bool noprogress;
bool noprogress; /* don't show progress meter, --silent given */
bool isatty; /* updated internally only if output is a tty */
struct getout *url_list; /* point to the first node */
struct getout *url_last; /* point to the last/current node */
@ -119,7 +119,7 @@ struct Configurable {
trace tracetype;
bool tracetime; /* include timestamp? */
long httpversion;
int progressmode;
int progressmode; /* CURL_PROGRESS_BAR or CURL_PROGRESS_STATS */
bool nobuffer;
bool readbusy; /* set when reading input returns EAGAIN */
bool globoff;

112
src/tool_easysrc.c Normal file
View File

@ -0,0 +1,112 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#include <curl/curl.h>
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
#include "tool_cfgable.h"
#include "tool_easysrc.h"
#include "tool_msgs.h"
#include "memdebug.h" /* keep this as LAST include */
/* global variable definitions, for easy-interface source code generation */
struct curl_slist *easysrc = NULL;
struct curl_slist *easysrc_remarks = NULL;
static const char *const srchead[]={
"/********* Sample code generated by the curl command line tool **********",
" * All curl_easy_setopt() options are documented at:",
" * http://curl.haxx.se/libcurl/c/curl_easy_setopt.html",
" ************************************************************************/",
"#include <curl/curl.h>",
"",
"int main(int argc, char *argv[])",
"{",
" CURLcode ret;",
NULL
};
void dumpeasysrc(struct Configurable *config)
{
struct curl_slist *ptr;
char *o = config->libcurl;
if(o) {
FILE *out;
bool fopened = FALSE;
if(strcmp(o, "-")) {
out = fopen(o, "wt");
fopened = TRUE;
}
else
out = stdout;
if(!out)
warnf(config, "Failed to open %s to write libcurl code!\n", o);
else {
int i;
const char *c;
for(i=0; ((c = srchead[i]) != '\0'); i++)
fprintf(out, "%s\n", c);
ptr = easysrc;
while(ptr) {
fprintf(out, " %s\n", ptr->data);
ptr = ptr->next;
}
ptr = easysrc_remarks;
if(ptr) {
fprintf(out,
"\n /* Here is a list of options the curl code"
" used that cannot get generated\n"
" as source easily. You may select to either"
" not use them or implement\n them yourself.\n"
"\n");
while(ptr) {
fprintf(out, " %s\n", ptr->data);
ptr = ptr->next;
}
fprintf(out, "\n */\n");
}
fprintf(out,
" return (int)ret;\n"
"}\n"
"/**** End of sample code ****/\n");
if(fopened)
fclose(out);
}
}
curl_slist_free_all(easysrc_remarks);
curl_slist_free_all(easysrc);
easysrc_remarks = NULL;
easysrc = NULL;
}

33
src/tool_easysrc.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef HEADER_CURL_TOOL_EASYSRC_H
#define HEADER_CURL_TOOL_EASYSRC_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
/* global variable declarations, for easy-interface source code generation */
extern struct curl_slist *easysrc;
extern struct curl_slist *easysrc_remarks;
void dumpeasysrc(struct Configurable *config);
#endif /* HEADER_CURL_TOOL_EASYSRC_H */

142
src/tool_progress.c Normal file
View File

@ -0,0 +1,142 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#include <curl/curl.h>
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
#include "tool_cfgable.h"
#include "tool_progress.h"
#include "memdebug.h" /* keep this as LAST include */
int my_progress(void *clientp,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
/* The original progress-bar source code was written for curl by Lars Aas,
and this new edition inherits some of his concepts. */
char line[256];
char outline[256];
char format[40];
double frac;
double percent;
int barwidth;
int num;
int i;
struct ProgressData *bar = (struct ProgressData *)clientp;
/* expected transfer size */
curl_off_t total = (curl_off_t)dltotal + (curl_off_t)ultotal +
bar->initial_size;
/* we've come this far */
curl_off_t point = (curl_off_t)dlnow + (curl_off_t)ulnow +
bar->initial_size;
if(point > total)
/* we have got more than the expected total! */
total = point;
/* simply count invokes */
bar->calls++;
if(total < 1) {
curl_off_t prevblock = bar->prev / 1024;
curl_off_t thisblock = point / 1024;
while(thisblock > prevblock) {
fprintf(bar->out, "#");
prevblock++;
}
}
else {
frac = (double)point / (double)total;
percent = frac * 100.0f;
barwidth = bar->width - 7;
num = (int) (((double)barwidth) * frac);
for(i = 0; i < num; i++)
line[i] = '#';
line[i] = '\0';
snprintf(format, sizeof(format), "%%-%ds %%5.1f%%%%", barwidth);
snprintf(outline, sizeof(outline), format, line, percent);
fprintf(bar->out, "\r%s", outline);
}
fflush(bar->out);
bar->prev = point;
return 0;
}
void progressbarinit(struct ProgressData *bar,
struct Configurable *config)
{
#ifdef __EMX__
/* 20000318 mgs */
int scr_size[2];
#endif
char *colp;
memset(bar, 0, sizeof(struct ProgressData));
/* pass this through to progress function so
* it can display progress towards total file
* not just the part that's left. (21-may-03, dbyron) */
if(config->use_resume)
bar->initial_size = config->resume_from;
/* TODO: get terminal width through ansi escapes or something similar.
try to update width when xterm is resized... - 19990617 larsa */
#ifndef __EMX__
/* 20000318 mgs
* OS/2 users most likely won't have this env var set, and besides that
* we're using our own way to determine screen width */
colp = curlx_getenv("COLUMNS");
if(colp) {
char *endptr;
long num = strtol(colp, &endptr, 10);
if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 0))
bar->width = (int)num;
else
bar->width = 79;
curl_free(colp);
}
else
bar->width = 79;
#else
/* 20000318 mgs
* We use this emx library call to get the screen width, and subtract
* one from what we got in order to avoid a problem with the cursor
* advancing to the next line if we print a string that is as long as
* the screen is wide. */
_scrsize(scr_size);
bar->width = scr_size[0] - 1;
#endif
bar->out = config->errors;
}

45
src/tool_progress.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef HEADER_CURL_TOOL_PROGRESS_H
#define HEADER_CURL_TOOL_PROGRESS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#define CURL_PROGRESS_STATS 0 /* default progress display */
#define CURL_PROGRESS_BAR 1
struct ProgressData {
int calls;
curl_off_t prev;
int width;
FILE *out; /* where to write everything to */
curl_off_t initial_size;
};
int my_progress(void *clientp,
double dltotal, double dlnow,
double ultotal, double ulnow);
void progressbarinit(struct ProgressData *bar,
struct Configurable *config);
#endif /* HEADER_CURL_TOOL_PROGRESS_H */

125
src/tool_setopt.c Normal file
View File

@ -0,0 +1,125 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#include <curl/curl.h>
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
#include "tool_cfgable.h"
#include "tool_easysrc.h"
#include "tool_setopt.h"
#include "memdebug.h" /* keep this as LAST include */
CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
const char *name, CURLoption tag, ...)
{
va_list arg;
char *bufp;
char value[256];
bool remark = FALSE;
bool skip = FALSE;
CURLcode ret = CURLE_OK;
va_start(arg, tag);
if(tag < CURLOPTTYPE_OBJECTPOINT) {
long lval = va_arg(arg, long);
snprintf(value, sizeof(value), "%ldL", lval);
ret = curl_easy_setopt(curl, tag, lval);
if(!lval)
skip = TRUE;
}
else if(tag < CURLOPTTYPE_OFF_T) {
void *pval = va_arg(arg, void *);
unsigned char *ptr = (unsigned char *)pval;
/* function pointers are never printable */
if(tag >= CURLOPTTYPE_FUNCTIONPOINT) {
if(pval) {
strcpy(value, "functionpointer"); /* 'value' fits 256 bytes */
remark = TRUE;
}
else
skip = TRUE;
}
else if(pval && str)
snprintf(value, sizeof(value), "\"%s\"", (char *)ptr);
else if(pval) {
strcpy(value, "objectpointer"); /* 'value' fits 256 bytes */
remark = TRUE;
}
else
skip = TRUE;
ret = curl_easy_setopt(curl, tag, pval);
}
else {
curl_off_t oval = va_arg(arg, curl_off_t);
snprintf(value, sizeof(value),
"(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
ret = curl_easy_setopt(curl, tag, oval);
if(!oval)
skip = TRUE;
}
va_end(arg);
if(config->libcurl && !skip && !ret) {
/* we only use this for real if --libcurl was used */
if(remark)
bufp = curlx_maprintf("%s set to a %s", name, value);
else
bufp = curlx_maprintf("curl_easy_setopt(hnd, %s, %s);", name, value);
if(!bufp)
ret = CURLE_OUT_OF_MEMORY;
else {
struct curl_slist *list =
curl_slist_append(remark?easysrc_remarks:easysrc, bufp);
curl_free(bufp);
if(!list) {
curl_slist_free_all(easysrc_remarks);
curl_slist_free_all(easysrc);
easysrc_remarks = NULL;
easysrc = NULL;
ret = CURLE_OUT_OF_MEMORY;
}
else if(remark)
easysrc_remarks = list;
else
easysrc = list;
}
}
return ret;
}

50
src/tool_setopt.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef HEADER_CURL_TOOL_SETOPT_H
#define HEADER_CURL_TOOL_SETOPT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
const char *name, CURLoption tag, ...);
/*
* Macros used in operate()
*/
#define my_setopt(x,y,z) do { \
res = tool_setopt(x, FALSE, config, #y, y, z); \
if(res) \
goto quit_curl; \
} WHILE_FALSE
#define my_setopt_str(x,y,z) do { \
res = tool_setopt(x, TRUE, config, #y, y, z); \
if(res) \
goto quit_curl; \
} WHILE_FALSE
#define res_setopt(x,y,z) tool_setopt(x, FALSE, config, #y, y, z)
#define res_setopt_str(x,y,z) tool_setopt(x, TRUE, config, #y, y, z)
#endif /* HEADER_CURL_TOOL_SETOPT_H */

View File

@ -191,6 +191,10 @@ SOURCE=.\tool_doswin.c
# End Source File
# Begin Source File
SOURCE=.\tool_easysrc.c
# End Source File
# Begin Source File
SOURCE=.\tool_mfiles.c
# End Source File
# Begin Source File
@ -203,6 +207,14 @@ SOURCE=.\tool_myfunc.c
# End Source File
# Begin Source File
SOURCE=.\tool_progress.c
# End Source File
# Begin Source File
SOURCE=.\tool_setopt.c
# End Source File
# Begin Source File
SOURCE=.\tool_vms.c
# End Source File
# Begin Source File
@ -283,6 +295,10 @@ SOURCE=.\tool_doswin.h
# End Source File
# Begin Source File
SOURCE=.\tool_easysrc.h
# End Source File
# Begin Source File
SOURCE=.\tool_mfiles.h
# End Source File
# Begin Source File
@ -295,10 +311,18 @@ SOURCE=.\tool_myfunc.h
# End Source File
# Begin Source File
SOURCE=.\tool_progress.h
# End Source File
# Begin Source File
SOURCE=.\tool_sdecls.h
# End Source File
# Begin Source File
SOURCE=.\tool_setopt.h
# End Source File
# Begin Source File
SOURCE=.\tool_vms.h
# End Source File
# Begin Source File