mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 09:21:50 -05:00
curl tool: reviewed code moved to tool_*.[ch] files
This commit is contained in:
parent
8bab6700d9
commit
c6702c7d3f
@ -11,6 +11,13 @@ SOURCE \
|
||||
main.c hugehelp.c urlglob.c writeout.c writeenv.c \
|
||||
getpass.c homedir.c curlutil.c xattr.c \
|
||||
tool_bname.c \
|
||||
tool_cb_dbg.c \
|
||||
tool_cb_hdr.c \
|
||||
tool_cb_prg.c \
|
||||
tool_cb_rea.c \
|
||||
tool_cb_see.c \
|
||||
tool_cb_skt.c \
|
||||
tool_cb_wrt.c \
|
||||
tool_cfgable.c \
|
||||
tool_convert.c \
|
||||
tool_dirhie.c \
|
||||
@ -20,7 +27,6 @@ SOURCE \
|
||||
tool_mfiles.c \
|
||||
tool_msgs.c \
|
||||
tool_myfunc.c \
|
||||
tool_progress.c \
|
||||
tool_setopt.c \
|
||||
tool_vms.c
|
||||
|
||||
|
@ -17,6 +17,13 @@ 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_cb_dbg.c \
|
||||
tool_cb_hdr.c \
|
||||
tool_cb_prg.c \
|
||||
tool_cb_rea.c \
|
||||
tool_cb_see.c \
|
||||
tool_cb_skt.c \
|
||||
tool_cb_wrt.c \
|
||||
tool_cfgable.c \
|
||||
tool_convert.c \
|
||||
tool_dirhie.c \
|
||||
@ -26,7 +33,6 @@ CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
|
||||
tool_mfiles.c \
|
||||
tool_msgs.c \
|
||||
tool_myfunc.c \
|
||||
tool_progress.c \
|
||||
tool_setopt.c \
|
||||
tool_vms.c
|
||||
|
||||
@ -34,6 +40,13 @@ 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_cb_dbg.h \
|
||||
tool_cb_hdr.h \
|
||||
tool_cb_prg.h \
|
||||
tool_cb_rea.h \
|
||||
tool_cb_see.h \
|
||||
tool_cb_skt.h \
|
||||
tool_cb_wrt.h \
|
||||
tool_cfgable.h \
|
||||
tool_convert.h \
|
||||
tool_dirhie.h \
|
||||
@ -43,7 +56,6 @@ CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
|
||||
tool_mfiles.h \
|
||||
tool_msgs.h \
|
||||
tool_myfunc.h \
|
||||
tool_progress.h \
|
||||
tool_sdecls.h \
|
||||
tool_setopt.h \
|
||||
tool_vms.h
|
||||
|
@ -142,6 +142,13 @@ RELEASE_OBJS= \
|
||||
rawstrr.obj \
|
||||
strtoofftr.obj \
|
||||
tool_bnamer.obj \
|
||||
tool_cb_dbgr.obj \
|
||||
tool_cb_hdrr.obj \
|
||||
tool_cb_prgr.obj \
|
||||
tool_cb_rear.obj \
|
||||
tool_cb_seer.obj \
|
||||
tool_cb_sktr.obj \
|
||||
tool_cb_wrtr.obj \
|
||||
tool_cfgabler.obj \
|
||||
tool_convertr.obj \
|
||||
tool_dirhier.obj \
|
||||
@ -151,7 +158,6 @@ RELEASE_OBJS= \
|
||||
tool_mfilesr.obj \
|
||||
tool_msgsr.obj \
|
||||
tool_myfuncr.obj \
|
||||
tool_progressr.obj \
|
||||
tool_setoptr.obj \
|
||||
tool_vmsr.obj \
|
||||
urlglobr.obj \
|
||||
@ -169,6 +175,13 @@ DEBUG_OBJS= \
|
||||
rawstrd.obj \
|
||||
strtoofftd.obj \
|
||||
tool_bnamed.obj \
|
||||
tool_cb_dbgd.obj \
|
||||
tool_cb_hdrd.obj \
|
||||
tool_cb_prgd.obj \
|
||||
tool_cb_read.obj \
|
||||
tool_cb_seed.obj \
|
||||
tool_cb_sktd.obj \
|
||||
tool_cb_wrtd.obj \
|
||||
tool_cfgabled.obj \
|
||||
tool_convertd.obj \
|
||||
tool_dirhied.obj \
|
||||
@ -178,7 +191,6 @@ DEBUG_OBJS= \
|
||||
tool_mfilesd.obj \
|
||||
tool_msgsd.obj \
|
||||
tool_myfuncd.obj \
|
||||
tool_progressd.obj \
|
||||
tool_setoptd.obj \
|
||||
tool_vmsd.obj \
|
||||
urlglobd.obj \
|
||||
@ -326,6 +338,20 @@ strtoofftr.obj: ../lib/strtoofft.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
|
||||
tool_bnamer.obj: tool_bname.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_bname.c
|
||||
tool_cb_dbgr.obj: tool_cb_dbg.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_dbg.c
|
||||
tool_cb_hdrr.obj: tool_cb_hdr.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_hdr.c
|
||||
tool_cb_prgr.obj: tool_cb_prg.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_prg.c
|
||||
tool_cb_rear.obj: tool_cb_rea.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_rea.c
|
||||
tool_cb_seer.obj: tool_cb_see.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_see.c
|
||||
tool_cb_sktr.obj: tool_cb_skt.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_skt.c
|
||||
tool_cb_wrtr.obj: tool_cb_wrt.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cb_wrt.c
|
||||
tool_cfgabler.obj: tool_cfgable.c
|
||||
$(CCR) $(CFLAGS) /Fo"$@" tool_cfgable.c
|
||||
tool_convertr.obj: tool_convert.c
|
||||
@ -344,8 +370,6 @@ 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
|
||||
@ -378,6 +402,20 @@ strtoofftd.obj: ../lib/strtoofft.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
|
||||
tool_bnamed.obj: tool_bname.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_bname.c
|
||||
tool_cb_dbgd.obj: tool_cb_dbg.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_dbg.c
|
||||
tool_cb_hdrd.obj: tool_cb_hdr.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_hdr.c
|
||||
tool_cb_prgd.obj: tool_cb_prg.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_prg.c
|
||||
tool_cb_read.obj: tool_cb_rea.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_rea.c
|
||||
tool_cb_seed.obj: tool_cb_see.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_see.c
|
||||
tool_cb_sktd.obj: tool_cb_skt.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_skt.c
|
||||
tool_cb_wrtd.obj: tool_cb_wrt.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cb_wrt.c
|
||||
tool_cfgabled.obj: tool_cfgable.c
|
||||
$(CCD) $(CFLAGS) /Fo"$@" tool_cfgable.c
|
||||
tool_convertd.obj: tool_convert.c
|
||||
@ -396,8 +434,6 @@ 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
|
||||
|
622
src/main.c
622
src/main.c
@ -102,9 +102,17 @@
|
||||
#include "tool_mfiles.h"
|
||||
#include "tool_msgs.h"
|
||||
#include "tool_myfunc.h"
|
||||
#include "tool_progress.h"
|
||||
#include "tool_cb_prg.h"
|
||||
#include "tool_setopt.h"
|
||||
#include "tool_vms.h"
|
||||
|
||||
#include "tool_cb_rea.h"
|
||||
#include "tool_cb_wrt.h"
|
||||
#include "tool_cb_see.h"
|
||||
#include "tool_cb_skt.h"
|
||||
#include "tool_cb_hdr.h"
|
||||
#include "tool_cb_dbg.h"
|
||||
|
||||
#ifdef USE_MANUAL
|
||||
# include "hugehelp.h"
|
||||
#endif
|
||||
@ -230,44 +238,6 @@ char **__crt0_glob_function (char *arg)
|
||||
"If you'd like to turn off curl's verification of the certificate, use\n" \
|
||||
" the -k (or --insecure) option.\n"
|
||||
|
||||
#if defined(WIN32) && !defined(__MINGW64__)
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
/* 64-bit lseek-like function unavailable */
|
||||
# define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
|
||||
#endif
|
||||
|
||||
#ifdef __POCC__
|
||||
# if(__POCC__ < 450)
|
||||
/* 64-bit lseek-like function unavailable */
|
||||
# define _lseeki64(hnd,ofs,whence) _lseek(hnd,ofs,whence)
|
||||
# else
|
||||
# define _lseeki64(hnd,ofs,whence) _lseek64(hnd,ofs,whence)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Truncate a file handle at a 64-bit position 'where'.
|
||||
*/
|
||||
|
||||
static int ftruncate64(int fd, curl_off_t where)
|
||||
{
|
||||
if(_lseeki64(fd, where, SEEK_SET) < 0)
|
||||
return -1;
|
||||
|
||||
if(!SetEndOfFile((HANDLE)_get_osfhandle(fd)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define ftruncate(fd,where) ftruncate64(fd,where)
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* This is the main global constructor for the app. Call this before
|
||||
* _any_ libcurl usage. If this fails, *NO* libcurl functions may be
|
||||
@ -1210,60 +1180,6 @@ static int ftpcccmethod(struct Configurable *config, const char *str)
|
||||
return CURLFTPSSL_CCC_PASSIVE;
|
||||
}
|
||||
|
||||
|
||||
static int sockoptcallback(void *clientp, curl_socket_t curlfd,
|
||||
curlsocktype purpose)
|
||||
{
|
||||
struct Configurable *config = (struct Configurable *)clientp;
|
||||
int onoff = 1; /* this callback is only used if we ask for keepalives on the
|
||||
connection */
|
||||
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPINTVL)
|
||||
int keepidle = (int)config->alivetime;
|
||||
#endif
|
||||
|
||||
switch(purpose) {
|
||||
case CURLSOCKTYPE_IPCXN:
|
||||
if(setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(clientp, "Could not set SO_KEEPALIVE!\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if(config->alivetime) {
|
||||
#ifdef TCP_KEEPIDLE
|
||||
if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle,
|
||||
sizeof(keepidle)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(clientp, "Could not set TCP_KEEPIDLE!\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPINTVL
|
||||
if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepidle,
|
||||
sizeof(keepidle)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(clientp, "Could not set TCP_KEEPINTVL!\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if !defined(TCP_KEEPIDLE) || !defined(TCP_KEEPINTVL)
|
||||
warnf(clientp, "Keep-alive functionality somewhat crippled due to "
|
||||
"missing support in your operating system!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long delegation(struct Configurable *config,
|
||||
char *str)
|
||||
{
|
||||
@ -3045,369 +2961,6 @@ static void go_sleep(long ms)
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t rc;
|
||||
struct OutStruct *out=(struct OutStruct *)stream;
|
||||
struct Configurable *config = out->config;
|
||||
|
||||
/*
|
||||
* Once that libcurl has called back my_fwrite() the returned value
|
||||
* is checked against the amount that was intended to be written, if
|
||||
* it does not match then it fails with CURLE_WRITE_ERROR. So at this
|
||||
* point returning a value different from sz*nmemb indicates failure.
|
||||
*/
|
||||
const size_t err_rc = (sz * nmemb) ? 0 : 1;
|
||||
|
||||
if(!out->stream) {
|
||||
out->bytes = 0; /* nothing written yet */
|
||||
if(!out->filename) {
|
||||
warnf(config, "Remote filename has no length!\n");
|
||||
return err_rc; /* Failure */
|
||||
}
|
||||
|
||||
if(config->content_disposition) {
|
||||
/* don't overwrite existing files */
|
||||
FILE* f = fopen(out->filename, "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
warnf(config, "Refusing to overwrite %s: %s\n", out->filename,
|
||||
strerror(EEXIST));
|
||||
return err_rc; /* Failure */
|
||||
}
|
||||
}
|
||||
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream) {
|
||||
warnf(config, "Failed to create the file %s: %s\n", out->filename,
|
||||
strerror(errno));
|
||||
return err_rc; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
rc = fwrite(buffer, sz, nmemb, out->stream);
|
||||
|
||||
if((sz * nmemb) == rc)
|
||||
/* we added this amount of data to the output */
|
||||
out->bytes += (sz * nmemb);
|
||||
|
||||
if(config->readbusy) {
|
||||
config->readbusy = FALSE;
|
||||
curl_easy_pause(config->easy, CURLPAUSE_CONT);
|
||||
}
|
||||
|
||||
if(config->nobuffer) {
|
||||
/* disable output buffering */
|
||||
int res = fflush(out->stream);
|
||||
if(res) {
|
||||
/* return a value that isn't the same as sz * nmemb */
|
||||
return err_rc; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define MAX_SEEK 2147483647
|
||||
|
||||
/*
|
||||
* my_seek() is the CURLOPT_SEEKFUNCTION we use
|
||||
*/
|
||||
static int my_seek(void *stream, curl_off_t offset, int whence)
|
||||
{
|
||||
struct InStruct *in=(struct InStruct *)stream;
|
||||
|
||||
#if(CURL_SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)
|
||||
/* The offset check following here is only interesting if curl_off_t is
|
||||
larger than off_t and we are not using the WIN32 large file support
|
||||
macros that provide the support to do 64bit seeks correctly */
|
||||
|
||||
if(offset > MAX_SEEK) {
|
||||
/* Some precaution code to work around problems with different data sizes
|
||||
to allow seeking >32bit even if off_t is 32bit. Should be very rare and
|
||||
is really valid on weirdo-systems. */
|
||||
curl_off_t left = offset;
|
||||
|
||||
if(whence != SEEK_SET)
|
||||
/* this code path doesn't support other types */
|
||||
return 1;
|
||||
|
||||
if(LSEEK_ERROR == lseek(in->fd, 0, SEEK_SET))
|
||||
/* couldn't rewind to beginning */
|
||||
return 1;
|
||||
|
||||
while(left) {
|
||||
long step = (left>MAX_SEEK ? MAX_SEEK : (long)left);
|
||||
if(LSEEK_ERROR == lseek(in->fd, step, SEEK_CUR))
|
||||
/* couldn't seek forwards the desired amount */
|
||||
return 1;
|
||||
left -= step;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if(LSEEK_ERROR == lseek(in->fd, offset, whence))
|
||||
/* couldn't rewind, the reason is in errno but errno is just not portable
|
||||
enough and we don't actually care that much why we failed. We'll let
|
||||
libcurl know that it may try other means if it wants to. */
|
||||
return CURL_SEEKFUNC_CANTSEEK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t my_fread(void *buffer, size_t sz, size_t nmemb, void *userp)
|
||||
{
|
||||
ssize_t rc;
|
||||
struct InStruct *in=(struct InStruct *)userp;
|
||||
|
||||
rc = read(in->fd, buffer, sz*nmemb);
|
||||
if(rc < 0) {
|
||||
if(errno == EAGAIN) {
|
||||
errno = 0;
|
||||
in->config->readbusy = TRUE;
|
||||
return CURL_READFUNC_PAUSE;
|
||||
}
|
||||
/* since size_t is unsigned we can't return negative values fine */
|
||||
rc = 0;
|
||||
}
|
||||
in->config->readbusy = FALSE;
|
||||
return (size_t)rc;
|
||||
}
|
||||
|
||||
static
|
||||
void dump(const char *timebuf, const char *text,
|
||||
FILE *stream, const unsigned char *ptr, size_t size,
|
||||
trace tracetype, curl_infotype infotype)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(tracetype == TRACE_ASCII)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s%s, %zd bytes (0x%zx)\n", timebuf, text, size, size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%04zx: ", i);
|
||||
|
||||
if(tracetype == TRACE_BIN) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* repeat the 0D0A check above but use the host encoding for CRLF */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+1 < size) && ptr[i+c]=='\r' && ptr[i+c+1]=='\n') {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
/* convert to host encoding and print this character */
|
||||
fprintf(stream, "%c", convert_char(infotype, ptr[i+c]));
|
||||
#else
|
||||
(void)infotype;
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR);
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
unsigned char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
struct Configurable *config = (struct Configurable *)userp;
|
||||
FILE *output=config->errors;
|
||||
const char *text;
|
||||
struct timeval tv;
|
||||
struct tm *now;
|
||||
char timebuf[20];
|
||||
time_t secs;
|
||||
static time_t epoch_offset;
|
||||
static int known_offset;
|
||||
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
if(config->tracetime) {
|
||||
tv = cutil_tvnow();
|
||||
if(!known_offset) {
|
||||
epoch_offset = time(NULL) - tv.tv_sec;
|
||||
known_offset = 1;
|
||||
}
|
||||
secs = epoch_offset + tv.tv_sec;
|
||||
now = localtime(&secs); /* not thread safe but we don't care */
|
||||
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ",
|
||||
now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);
|
||||
}
|
||||
else
|
||||
timebuf[0]=0;
|
||||
|
||||
if(!config->trace_stream) {
|
||||
/* open for append */
|
||||
if(curlx_strequal("-", config->trace_dump))
|
||||
config->trace_stream = stdout;
|
||||
else if(curlx_strequal("%", config->trace_dump))
|
||||
/* Ok, this is somewhat hackish but we do it undocumented for now */
|
||||
config->trace_stream = config->errors; /* aka stderr */
|
||||
else {
|
||||
config->trace_stream = fopen(config->trace_dump, "w");
|
||||
config->trace_fopened = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(config->trace_stream)
|
||||
output = config->trace_stream;
|
||||
|
||||
if(!output) {
|
||||
warnf(config, "Failed to create/open output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(config->tracetype == TRACE_PLAIN) {
|
||||
/*
|
||||
* This is the trace look that is similar to what libcurl makes on its
|
||||
* own.
|
||||
*/
|
||||
static const char * const s_infotype[] = {
|
||||
"*", "<", ">", "{", "}", "{", "}"
|
||||
};
|
||||
size_t i;
|
||||
size_t st=0;
|
||||
static bool newl = FALSE;
|
||||
static bool traced_data = FALSE;
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_HEADER_OUT:
|
||||
for(i=0; i<size-1; i++) {
|
||||
if(data[i] == '\n') { /* LF */
|
||||
if(!newl) {
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
}
|
||||
(void)fwrite(data+st, i-st+1, 1, output);
|
||||
st = i+1;
|
||||
newl = FALSE;
|
||||
}
|
||||
}
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
(void)fwrite(data+st, i-st+1, 1, output);
|
||||
newl = (size && (data[size-1] != '\n'))?TRUE:FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
case CURLINFO_TEXT:
|
||||
case CURLINFO_HEADER_IN:
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
(void)fwrite(data, size, 1, output);
|
||||
newl = (size && (data[size-1] != '\n'))?TRUE:FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
case CURLINFO_DATA_IN:
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
if(!traced_data) {
|
||||
/* if the data is output to a tty and we're sending this debug trace
|
||||
to stderr or stdout, we don't display the alert about the data not
|
||||
being shown as the data _is_ shown then just not via this
|
||||
function */
|
||||
if(!config->isatty ||
|
||||
((output != stderr) && (output != stdout))) {
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
fprintf(output, "[data not shown]\n");
|
||||
newl = FALSE;
|
||||
traced_data = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* nada */
|
||||
newl = FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Special processing is needed for CURLINFO_HEADER_OUT blocks
|
||||
* if they contain both headers and data (separated by CRLFCRLF).
|
||||
* We dump the header text and then switch type to CURLINFO_DATA_OUT.
|
||||
*/
|
||||
if((type == CURLINFO_HEADER_OUT) && (size > 4)) {
|
||||
size_t i;
|
||||
for(i = 0; i < size - 4; i++) {
|
||||
if(memcmp(&data[i], "\r\n\r\n", 4) == 0) {
|
||||
/* dump everything through the CRLFCRLF as a sent header */
|
||||
text = "=> Send header";
|
||||
dump(timebuf, text, output, data, i+4, config->tracetype, type);
|
||||
data += i + 3;
|
||||
size -= i + 4;
|
||||
type = CURLINFO_DATA_OUT;
|
||||
data += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(output, "%s== Info: %s", timebuf, data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(timebuf, text, output, data, size, config->tracetype, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RETRY_SLEEP_DEFAULT 1000L /* ms */
|
||||
#define RETRY_SLEEP_MAX 600000L /* ms == 10 minutes */
|
||||
|
||||
@ -3505,147 +3058,6 @@ static char *get_url_file_name(const char *url)
|
||||
return fn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies a file name part and returns an ALLOCATED data buffer.
|
||||
*/
|
||||
static char*
|
||||
parse_filename(char *ptr, size_t len)
|
||||
{
|
||||
char* copy;
|
||||
char* p;
|
||||
char* q;
|
||||
char stop = 0;
|
||||
|
||||
/* simple implementation of strndup() */
|
||||
copy = malloc(len+1);
|
||||
if(!copy)
|
||||
return NULL;
|
||||
memcpy(copy, ptr, len);
|
||||
copy[len] = 0;
|
||||
|
||||
p = copy;
|
||||
if(*p == '\'' || *p == '"') {
|
||||
/* store the starting quote */
|
||||
stop = *p;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
stop = ';';
|
||||
|
||||
/* if the filename contains a path, only use filename portion */
|
||||
q = strrchr(copy, '/');
|
||||
if(q) {
|
||||
p=q+1;
|
||||
if(!*p) {
|
||||
Curl_safefree(copy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the filename contains a backslash, only use filename portion. The idea
|
||||
is that even systems that don't handle backslashes as path separators
|
||||
probably want the path removed for convenience. */
|
||||
q = strrchr(p, '\\');
|
||||
if(q) {
|
||||
p = q+1;
|
||||
if(!*p) {
|
||||
Curl_safefree(copy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* scan for the end letter and stop there */
|
||||
q = p;
|
||||
while(*q) {
|
||||
if(q[1] && q[0]=='\\')
|
||||
q++;
|
||||
else if(q[0] == stop)
|
||||
break;
|
||||
q++;
|
||||
}
|
||||
*q = 0;
|
||||
|
||||
/* make sure the file name doesn't end in \r or \n */
|
||||
q = strchr(p, '\r');
|
||||
if(q)
|
||||
*q = 0;
|
||||
|
||||
q = strchr(p, '\n');
|
||||
if(q)
|
||||
*q = 0;
|
||||
|
||||
if(copy!=p)
|
||||
memmove(copy, p, strlen(p)+1);
|
||||
|
||||
/* in case we built curl debug enabled, we allow an evironment variable
|
||||
* named CURL_TESTDIR to prefix the given file name to put it into a
|
||||
* specific directory
|
||||
*/
|
||||
#ifdef CURLDEBUG
|
||||
{
|
||||
char *tdir = curlx_getenv("CURL_TESTDIR");
|
||||
if(tdir) {
|
||||
char buffer[512]; /* suitably large */
|
||||
snprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy);
|
||||
Curl_safefree(copy);
|
||||
copy = strdup(buffer); /* clone the buffer, we don't use the libcurl
|
||||
aprintf() or similar since we want to use the
|
||||
same memory code as the "real" parse_filename
|
||||
function */
|
||||
curl_free(tdir);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static size_t
|
||||
header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct OutStruct* outs = (struct OutStruct*)stream;
|
||||
const char* str = (char*)ptr;
|
||||
const size_t cb = size*nmemb;
|
||||
const char* end = (char*)ptr + cb;
|
||||
|
||||
if(cb > 20 && checkprefix("Content-disposition:", str)) {
|
||||
char *p = (char*)str + 20;
|
||||
|
||||
/* look for the 'filename=' parameter
|
||||
(encoded filenames (*=) are not supported) */
|
||||
for(;;) {
|
||||
char *filename;
|
||||
size_t len;
|
||||
|
||||
while(*p && (p < end) && !ISALPHA(*p))
|
||||
p++;
|
||||
if(p > end-9)
|
||||
break;
|
||||
|
||||
if(memcmp(p, "filename=", 9)) {
|
||||
/* no match, find next parameter */
|
||||
while((p < end) && (*p != ';'))
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
p+=9;
|
||||
|
||||
/* this expression below typecasts 'cb' only to avoid
|
||||
warning: signed and unsigned type in conditional expression
|
||||
*/
|
||||
len = (ssize_t)cb - (p - str);
|
||||
filename = parse_filename(p, len);
|
||||
if(filename) {
|
||||
outs->filename = filename;
|
||||
outs->alloc_filename = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
static void memory_tracking_init(void)
|
||||
{
|
||||
@ -4322,7 +3734,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
/* where to store */
|
||||
my_setopt(curl, CURLOPT_WRITEDATA, &outs);
|
||||
/* what call to write */
|
||||
my_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
|
||||
|
||||
/* for uploads */
|
||||
input.fd = infd;
|
||||
@ -4331,12 +3743,12 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
/* what call to read */
|
||||
if((outfile && !curlx_strequal("-", outfile)) ||
|
||||
!checkprefix("telnet:", this_url))
|
||||
my_setopt(curl, CURLOPT_READFUNCTION, my_fread);
|
||||
my_setopt(curl, CURLOPT_READFUNCTION, tool_read_cb);
|
||||
|
||||
/* in 7.18.0, the CURLOPT_SEEKFUNCTION/DATA pair is taking over what
|
||||
CURLOPT_IOCTLFUNCTION/DATA pair previously provided for seeking */
|
||||
my_setopt(curl, CURLOPT_SEEKDATA, &input);
|
||||
my_setopt(curl, CURLOPT_SEEKFUNCTION, my_seek);
|
||||
my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb);
|
||||
|
||||
if(config->recvpersecond)
|
||||
/* tell libcurl to use a smaller sized buffer as it allows us to
|
||||
@ -4581,7 +3993,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, my_progress);
|
||||
my_setopt(curl, CURLOPT_PROGRESSFUNCTION, tool_progress_cb);
|
||||
my_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
|
||||
}
|
||||
|
||||
@ -4607,7 +4019,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
my_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
|
||||
|
||||
if(config->tracetype != TRACE_NONE) {
|
||||
my_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb);
|
||||
my_setopt(curl, CURLOPT_DEBUGDATA, config);
|
||||
my_setopt(curl, CURLOPT_VERBOSE, TRUE);
|
||||
}
|
||||
@ -4702,7 +4114,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
|
||||
/* curl 7.17.1 */
|
||||
if(!config->nokeepalive) {
|
||||
my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockoptcallback);
|
||||
my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, tool_sockopt_cb);
|
||||
my_setopt(curl, CURLOPT_SOCKOPTDATA, config);
|
||||
}
|
||||
|
||||
@ -4727,7 +4139,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
|
||||
if((urlnode->flags & GETOUT_USEREMOTE)
|
||||
&& config->content_disposition) {
|
||||
my_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
|
||||
my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb);
|
||||
my_setopt(curl, CURLOPT_HEADERDATA, &outs);
|
||||
}
|
||||
else {
|
||||
@ -5045,6 +4457,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
Curl_safefree(urlnode->infile);
|
||||
urlnode->flags = 0;
|
||||
|
||||
/* TODO: Should CURLE_SSL_CACERT be included as critical error ? */
|
||||
|
||||
/*
|
||||
** Bail out upon critical errors
|
||||
*/
|
||||
|
276
src/tool_cb_dbg.c
Normal file
276
src/tool_cb_dbg.c
Normal file
@ -0,0 +1,276 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "curlutil.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_msgs.h"
|
||||
#include "tool_cb_dbg.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
static void dump(const char *timebuf, const char *text,
|
||||
FILE *stream, const unsigned char *ptr, size_t size,
|
||||
trace tracetype, curl_infotype infotype);
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_DEBUGFUNCTION
|
||||
*/
|
||||
|
||||
int tool_debug_cb(CURL *handle, curl_infotype type,
|
||||
unsigned char *data, size_t size,
|
||||
void *userdata)
|
||||
{
|
||||
struct Configurable *config = userdata;
|
||||
FILE *output = config->errors;
|
||||
const char *text;
|
||||
struct timeval tv;
|
||||
struct tm *now;
|
||||
char timebuf[20];
|
||||
time_t secs;
|
||||
static time_t epoch_offset;
|
||||
static int known_offset;
|
||||
|
||||
(void)handle; /* not used */
|
||||
|
||||
if(config->tracetime) {
|
||||
tv = cutil_tvnow();
|
||||
if(!known_offset) {
|
||||
epoch_offset = time(NULL) - tv.tv_sec;
|
||||
known_offset = 1;
|
||||
}
|
||||
secs = epoch_offset + tv.tv_sec;
|
||||
now = localtime(&secs); /* not thread safe but we don't care */
|
||||
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ",
|
||||
now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);
|
||||
}
|
||||
else
|
||||
timebuf[0] = 0;
|
||||
|
||||
if(!config->trace_stream) {
|
||||
/* open for append */
|
||||
if(curlx_strequal("-", config->trace_dump))
|
||||
config->trace_stream = stdout;
|
||||
else if(curlx_strequal("%", config->trace_dump))
|
||||
/* Ok, this is somewhat hackish but we do it undocumented for now */
|
||||
config->trace_stream = config->errors; /* aka stderr */
|
||||
else {
|
||||
config->trace_stream = fopen(config->trace_dump, "w");
|
||||
config->trace_fopened = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(config->trace_stream)
|
||||
output = config->trace_stream;
|
||||
|
||||
if(!output) {
|
||||
warnf(config, "Failed to create/open output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(config->tracetype == TRACE_PLAIN) {
|
||||
/*
|
||||
* This is the trace look that is similar to what libcurl makes on its
|
||||
* own.
|
||||
*/
|
||||
static const char * const s_infotype[] = {
|
||||
"*", "<", ">", "{", "}", "{", "}"
|
||||
};
|
||||
size_t i;
|
||||
size_t st = 0;
|
||||
static bool newl = FALSE;
|
||||
static bool traced_data = FALSE;
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_HEADER_OUT:
|
||||
for(i = 0; i < size - 1; i++) {
|
||||
if(data[i] == '\n') { /* LF */
|
||||
if(!newl) {
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
}
|
||||
(void)fwrite(data + st, i - st + 1, 1, output);
|
||||
st = i + 1;
|
||||
newl = FALSE;
|
||||
}
|
||||
}
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
(void)fwrite(data + st, i - st + 1, 1, output);
|
||||
newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
case CURLINFO_TEXT:
|
||||
case CURLINFO_HEADER_IN:
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
(void)fwrite(data, size, 1, output);
|
||||
newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
case CURLINFO_DATA_IN:
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
if(!traced_data) {
|
||||
/* if the data is output to a tty and we're sending this debug trace
|
||||
to stderr or stdout, we don't display the alert about the data not
|
||||
being shown as the data _is_ shown then just not via this
|
||||
function */
|
||||
if(!config->isatty ||
|
||||
((output != stderr) && (output != stdout))) {
|
||||
if(!newl)
|
||||
fprintf(output, "%s%s ", timebuf, s_infotype[type]);
|
||||
fprintf(output, "[data not shown]\n");
|
||||
newl = FALSE;
|
||||
traced_data = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* nada */
|
||||
newl = FALSE;
|
||||
traced_data = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Special processing is needed for CURLINFO_HEADER_OUT blocks
|
||||
* if they contain both headers and data (separated by CRLFCRLF).
|
||||
* We dump the header text and then switch type to CURLINFO_DATA_OUT.
|
||||
*/
|
||||
if((type == CURLINFO_HEADER_OUT) && (size > 4)) {
|
||||
size_t i;
|
||||
for(i = 0; i < size - 4; i++) {
|
||||
if(memcmp(&data[i], "\r\n\r\n", 4) == 0) {
|
||||
/* dump everything through the CRLFCRLF as a sent header */
|
||||
text = "=> Send header";
|
||||
dump(timebuf, text, output, data, i + 4, config->tracetype, type);
|
||||
data += i + 3;
|
||||
size -= i + 4;
|
||||
type = CURLINFO_DATA_OUT;
|
||||
data += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(output, "%s== Info: %s", timebuf, data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(timebuf, text, output, data, size, config->tracetype, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump(const char *timebuf, const char *text,
|
||||
FILE *stream, const unsigned char *ptr, size_t size,
|
||||
trace tracetype, curl_infotype infotype)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width = 0x10;
|
||||
|
||||
if(tracetype == TRACE_ASCII)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s%s, %zd bytes (0x%zx)\n", timebuf, text, size, size);
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
||||
fprintf(stream, "%04zx: ", i);
|
||||
|
||||
if(tracetype == TRACE_BIN) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+1 < size) && (ptr[i+c] == 0x0D) && (ptr[i+c+1] == 0x0A)) {
|
||||
i += (c+2-width);
|
||||
break;
|
||||
}
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* repeat the 0D0A check above but use the host encoding for CRLF */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+1 < size) && (ptr[i+c] == '\r') && (ptr[i+c+1] == '\n')) {
|
||||
i += (c+2-width);
|
||||
break;
|
||||
}
|
||||
/* convert to host encoding and print this character */
|
||||
fprintf(stream, "%c", convert_char(infotype, ptr[i+c]));
|
||||
#else
|
||||
(void)infotype;
|
||||
fprintf(stream, "%c", ((ptr[i+c] >= 0x20) && (ptr[i+c] < 0x80)) ?
|
||||
ptr[i+c] : UNPRINTABLE_CHAR);
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if((tracetype == TRACE_ASCII) &&
|
||||
(i+c+2 < size) && (ptr[i+c+1] == 0x0D) && (ptr[i+c+2] == 0x0A)) {
|
||||
i += (c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
35
src/tool_cb_dbg.h
Normal file
35
src/tool_cb_dbg.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_DBG_H
|
||||
#define HEADER_CURL_TOOL_CB_DBG_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"
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_DEBUGFUNCTION
|
||||
*/
|
||||
|
||||
int tool_debug_cb(CURL *handle, curl_infotype type,
|
||||
unsigned char *data, size_t size,
|
||||
void *userdata);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_DBG_H */
|
||||
|
182
src/tool_cb_hdr.c
Normal file
182
src/tool_cb_hdr.c
Normal file
@ -0,0 +1,182 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
#include "rawstr.h"
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
/* use our own printf() functions */
|
||||
#include "curlx.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_cb_hdr.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
static char *parse_filename(const char *ptr, size_t len);
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_HEADERFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
struct OutStruct *outs = userdata;
|
||||
const char *str = ptr;
|
||||
const size_t cb = size * nmemb;
|
||||
const char *end = (char*)ptr + cb;
|
||||
|
||||
if(cb > 20 && checkprefix("Content-disposition:", str)) {
|
||||
const char *p = str + 20;
|
||||
|
||||
/* look for the 'filename=' parameter
|
||||
(encoded filenames (*=) are not supported) */
|
||||
for(;;) {
|
||||
char *filename;
|
||||
size_t len;
|
||||
|
||||
while(*p && (p < end) && !ISALPHA(*p))
|
||||
p++;
|
||||
if(p > end - 9)
|
||||
break;
|
||||
|
||||
if(memcmp(p, "filename=", 9)) {
|
||||
/* no match, find next parameter */
|
||||
while((p < end) && (*p != ';'))
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
p += 9;
|
||||
|
||||
/* this expression below typecasts 'cb' only to avoid
|
||||
warning: signed and unsigned type in conditional expression
|
||||
*/
|
||||
len = (ssize_t)cb - (p - str);
|
||||
filename = parse_filename(p, len);
|
||||
/* TODO: OOM handling - return (size_t)-1 ? */
|
||||
if(filename) {
|
||||
outs->filename = filename;
|
||||
outs->alloc_filename = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies a file name part and returns an ALLOCATED data buffer.
|
||||
*/
|
||||
static char *parse_filename(const char *ptr, size_t len)
|
||||
{
|
||||
char *copy;
|
||||
char *p;
|
||||
char *q;
|
||||
char stop = '\0';
|
||||
|
||||
/* simple implementation of strndup() */
|
||||
copy = malloc(len+1);
|
||||
if(!copy)
|
||||
return NULL;
|
||||
memcpy(copy, ptr, len);
|
||||
copy[len] = '\0';
|
||||
|
||||
p = copy;
|
||||
if(*p == '\'' || *p == '"') {
|
||||
/* store the starting quote */
|
||||
stop = *p;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
stop = ';';
|
||||
|
||||
/* if the filename contains a path, only use filename portion */
|
||||
q = strrchr(copy, '/');
|
||||
if(q) {
|
||||
p = q + 1;
|
||||
if(!*p) {
|
||||
Curl_safefree(copy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the filename contains a backslash, only use filename portion. The idea
|
||||
is that even systems that don't handle backslashes as path separators
|
||||
probably want the path removed for convenience. */
|
||||
q = strrchr(p, '\\');
|
||||
if(q) {
|
||||
p = q + 1;
|
||||
if(!*p) {
|
||||
Curl_safefree(copy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* scan for the end letter and stop there */
|
||||
q = p;
|
||||
while(*q) {
|
||||
if(q[1] && (q[0] == '\\'))
|
||||
q++;
|
||||
else if(q[0] == stop)
|
||||
break;
|
||||
q++;
|
||||
}
|
||||
*q = '\0';
|
||||
|
||||
/* make sure the file name doesn't end in \r or \n */
|
||||
q = strchr(p, '\r');
|
||||
if(q)
|
||||
*q = '\0';
|
||||
|
||||
q = strchr(p, '\n');
|
||||
if(q)
|
||||
*q = '\0';
|
||||
|
||||
if(copy != p)
|
||||
memmove(copy, p, strlen(p) + 1);
|
||||
|
||||
/* in case we built curl debug enabled, we allow an evironment variable
|
||||
* named CURL_TESTDIR to prefix the given file name to put it into a
|
||||
* specific directory
|
||||
*/
|
||||
#ifdef CURLDEBUG
|
||||
{
|
||||
char *tdir = curlx_getenv("CURL_TESTDIR");
|
||||
if(tdir) {
|
||||
char buffer[512]; /* suitably large */
|
||||
snprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy);
|
||||
Curl_safefree(copy);
|
||||
copy = strdup(buffer); /* clone the buffer, we don't use the libcurl
|
||||
aprintf() or similar since we want to use the
|
||||
same memory code as the "real" parse_filename
|
||||
function */
|
||||
curl_free(tdir);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
33
src/tool_cb_hdr.h
Normal file
33
src/tool_cb_hdr.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_HDR_H
|
||||
#define HEADER_CURL_TOOL_CB_HDR_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"
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_HEADERFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_HDR_H */
|
||||
|
@ -28,13 +28,17 @@
|
||||
#include "curlx.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_progress.h"
|
||||
#include "tool_cb_prg.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
int my_progress(void *clientp,
|
||||
double dltotal, double dlnow,
|
||||
double ultotal, double ulnow)
|
||||
/*
|
||||
** callback for CURLOPT_PROGRESSFUNCTION
|
||||
*/
|
||||
|
||||
int tool_progress_cb(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. */
|
@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_TOOL_PROGRESS_H
|
||||
#define HEADER_CURL_TOOL_PROGRESS_H
|
||||
#ifndef HEADER_CURL_TOOL_CB_PRG_H
|
||||
#define HEADER_CURL_TOOL_CB_PRG_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@ -34,12 +34,16 @@ struct ProgressData {
|
||||
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 */
|
||||
/*
|
||||
** callback for CURLOPT_PROGRESSFUNCTION
|
||||
*/
|
||||
|
||||
int tool_progress_cb(void *clientp,
|
||||
double dltotal, double dlnow,
|
||||
double ultotal, double ulnow);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_PRG_H */
|
||||
|
61
src/tool_cb_rea.c
Normal file
61
src/tool_cb_rea.c
Normal file
@ -0,0 +1,61 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
/* use our own printf() functions */
|
||||
#include "curlx.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_cb_rea.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_READFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
|
||||
{
|
||||
ssize_t rc;
|
||||
struct InStruct *in = userdata;
|
||||
|
||||
rc = read(in->fd, buffer, sz*nmemb);
|
||||
if(rc < 0) {
|
||||
if(errno == EAGAIN) {
|
||||
errno = 0;
|
||||
in->config->readbusy = TRUE;
|
||||
return CURL_READFUNC_PAUSE;
|
||||
}
|
||||
/* since size_t is unsigned we can't return negative values fine */
|
||||
rc = 0;
|
||||
}
|
||||
in->config->readbusy = FALSE;
|
||||
return (size_t)rc;
|
||||
}
|
||||
|
33
src/tool_cb_rea.h
Normal file
33
src/tool_cb_rea.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_REA_H
|
||||
#define HEADER_CURL_TOOL_CB_REA_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"
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_READFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_REA_H */
|
||||
|
129
src/tool_cb_see.c
Normal file
129
src/tool_cb_see.c
Normal file
@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
/* use our own printf() functions */
|
||||
#include "curlx.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_cb_see.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
/* OUR_MAX_SEEK_L has 'long' data type, OUR_MAX_SEEK_O has 'curl_off_t,
|
||||
both represent the same value. Maximum offset used here when we lseek
|
||||
using a 'long' data type offset */
|
||||
|
||||
#define OUR_MAX_SEEK_L 2147483647L - 1L
|
||||
#define OUR_MAX_SEEK_O CURL_OFF_T_C(0x7FFFFFFF) - CURL_OFF_T_C(0x1)
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_SEEKFUNCTION
|
||||
**
|
||||
** Notice that this is not supposed to return the resulting offset. This
|
||||
** shall only return CURL_SEEKFUNC_* return codes.
|
||||
*/
|
||||
|
||||
int tool_seek_cb(void *userdata, curl_off_t offset, int whence)
|
||||
{
|
||||
struct InStruct *in = userdata;
|
||||
|
||||
#if(CURL_SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)
|
||||
|
||||
/* The offset check following here is only interesting if curl_off_t is
|
||||
larger than off_t and we are not using the WIN32 large file support
|
||||
macros that provide the support to do 64bit seeks correctly */
|
||||
|
||||
if(offset > OUR_MAX_SEEK_O) {
|
||||
/* Some precaution code to work around problems with different data sizes
|
||||
to allow seeking >32bit even if off_t is 32bit. Should be very rare and
|
||||
is really valid on weirdo-systems. */
|
||||
curl_off_t left = offset;
|
||||
|
||||
if(whence != SEEK_SET)
|
||||
/* this code path doesn't support other types */
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
|
||||
if(LSEEK_ERROR == lseek(in->fd, 0, SEEK_SET))
|
||||
/* couldn't rewind to beginning */
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
|
||||
while(left) {
|
||||
long step = (left > OUR_MAX_SEEK_O) ? OUR_MAX_SEEK_L : (long)left;
|
||||
if(LSEEK_ERROR == lseek(in->fd, step, SEEK_CUR))
|
||||
/* couldn't seek forwards the desired amount */
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
left -= step;
|
||||
}
|
||||
return CURL_SEEKFUNC_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(LSEEK_ERROR == lseek(in->fd, offset, whence))
|
||||
/* couldn't rewind, the reason is in errno but errno is just not portable
|
||||
enough and we don't actually care that much why we failed. We'll let
|
||||
libcurl know that it may try other means if it wants to. */
|
||||
return CURL_SEEKFUNC_CANTSEEK;
|
||||
|
||||
return CURL_SEEKFUNC_OK;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && !defined(__MINGW64__)
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
/* 64-bit lseek-like function unavailable */
|
||||
# define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
|
||||
#endif
|
||||
|
||||
#ifdef __POCC__
|
||||
# if(__POCC__ < 450)
|
||||
/* 64-bit lseek-like function unavailable */
|
||||
# define _lseeki64(hnd,ofs,whence) _lseek(hnd,ofs,whence)
|
||||
# else
|
||||
# define _lseeki64(hnd,ofs,whence) _lseek64(hnd,ofs,whence)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Truncate a file handle at a 64-bit position 'where'.
|
||||
*/
|
||||
|
||||
int tool_ftruncate64(int fd, curl_off_t where)
|
||||
{
|
||||
if(_lseeki64(fd, where, SEEK_SET) < 0)
|
||||
return -1;
|
||||
|
||||
if(!SetEndOfFile((HANDLE)_get_osfhandle(fd)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WIN32 && ! __MINGW64__ */
|
||||
|
45
src/tool_cb_see.h
Normal file
45
src/tool_cb_see.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_SEE_H
|
||||
#define HEADER_CURL_TOOL_CB_SEE_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"
|
||||
|
||||
#if defined(WIN32) && !defined(__MINGW64__)
|
||||
|
||||
int tool_ftruncate64(int fd, curl_off_t where);
|
||||
|
||||
#define ftruncate(fd,where) tool_ftruncate64(fd,where)
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
# define HAVE_FTRUNCATE 1
|
||||
#endif
|
||||
|
||||
#endif /* WIN32 && ! __MINGW64__ */
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_SEEKFUNCTION
|
||||
*/
|
||||
|
||||
int tool_seek_cb(void *userdata, curl_off_t offset, int whence);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_SEE_H */
|
||||
|
97
src/tool_cb_skt.c
Normal file
97
src/tool_cb_skt.c
Normal file
@ -0,0 +1,97 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
/* use our own printf() functions */
|
||||
#include "curlx.h"
|
||||
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_msgs.h"
|
||||
#include "tool_cb_skt.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_SOCKOPTFUNCTION
|
||||
*/
|
||||
|
||||
int tool_sockopt_cb(void *userdata, curl_socket_t curlfd, curlsocktype purpose)
|
||||
{
|
||||
struct Configurable *config = userdata;
|
||||
|
||||
int onoff = 1; /* this callback is only used if we ask for keepalives on the
|
||||
connection */
|
||||
|
||||
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPINTVL)
|
||||
int keepidle = (int)config->alivetime;
|
||||
#endif
|
||||
|
||||
switch(purpose) {
|
||||
case CURLSOCKTYPE_IPCXN:
|
||||
if(setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(config, "Could not set SO_KEEPALIVE!\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if(config->alivetime) {
|
||||
#ifdef TCP_KEEPIDLE
|
||||
if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle,
|
||||
sizeof(keepidle)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(config, "Could not set TCP_KEEPIDLE!\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPINTVL
|
||||
if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepidle,
|
||||
sizeof(keepidle)) < 0) {
|
||||
/* don't abort operation, just issue a warning */
|
||||
SET_SOCKERRNO(0);
|
||||
warnf(config, "Could not set TCP_KEEPINTVL!\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if !defined(TCP_KEEPIDLE) || !defined(TCP_KEEPINTVL)
|
||||
warnf(config, "Keep-alive functionality somewhat crippled due to "
|
||||
"missing support in your operating system!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
35
src/tool_cb_skt.h
Normal file
35
src/tool_cb_skt.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_SKT_H
|
||||
#define HEADER_CURL_TOOL_CB_SKT_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"
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_SOCKOPTFUNCTION
|
||||
*/
|
||||
|
||||
int tool_sockopt_cb(void *userdata,
|
||||
curl_socket_t curlfd,
|
||||
curlsocktype purpose);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_SKT_H */
|
||||
|
103
src/tool_cb_wrt.c
Normal file
103
src/tool_cb_wrt.c
Normal file
@ -0,0 +1,103 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_msgs.h"
|
||||
#include "tool_cb_wrt.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_WRITEFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
|
||||
{
|
||||
size_t rc;
|
||||
struct OutStruct *out = userdata;
|
||||
struct Configurable *config = out->config;
|
||||
|
||||
/*
|
||||
* Once that libcurl has called back tool_write_cb() the returned value
|
||||
* is checked against the amount that was intended to be written, if
|
||||
* it does not match then it fails with CURLE_WRITE_ERROR. So at this
|
||||
* point returning a value different from sz*nmemb indicates failure.
|
||||
*/
|
||||
const size_t err_rc = (sz * nmemb) ? 0 : 1;
|
||||
|
||||
if(!out->stream) {
|
||||
out->bytes = 0; /* nothing written yet */
|
||||
if(!out->filename) {
|
||||
warnf(config, "Remote filename has no length!\n");
|
||||
return err_rc; /* Failure */
|
||||
}
|
||||
|
||||
if(config->content_disposition) {
|
||||
/* don't overwrite existing files */
|
||||
FILE* f = fopen(out->filename, "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
warnf(config, "Refusing to overwrite %s: %s\n", out->filename,
|
||||
strerror(EEXIST));
|
||||
return err_rc; /* Failure */
|
||||
}
|
||||
}
|
||||
|
||||
/* open file for writing */
|
||||
out->stream = fopen(out->filename, "wb");
|
||||
if(!out->stream) {
|
||||
warnf(config, "Failed to create the file %s: %s\n", out->filename,
|
||||
strerror(errno));
|
||||
return err_rc; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
rc = fwrite(buffer, sz, nmemb, out->stream);
|
||||
|
||||
if((sz * nmemb) == rc)
|
||||
/* we added this amount of data to the output */
|
||||
out->bytes += (sz * nmemb);
|
||||
|
||||
if(config->readbusy) {
|
||||
config->readbusy = FALSE;
|
||||
curl_easy_pause(config->easy, CURLPAUSE_CONT);
|
||||
}
|
||||
|
||||
if(config->nobuffer) {
|
||||
/* disable output buffering */
|
||||
int res = fflush(out->stream);
|
||||
if(res) {
|
||||
/* return a value that isn't the same as sz * nmemb */
|
||||
return err_rc; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
33
src/tool_cb_wrt.h
Normal file
33
src/tool_cb_wrt.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HEADER_CURL_TOOL_CB_WRT_H
|
||||
#define HEADER_CURL_TOOL_CB_WRT_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"
|
||||
|
||||
/*
|
||||
** callback for CURLOPT_WRITEFUNCTION
|
||||
*/
|
||||
|
||||
size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_CB_WRT_H */
|
||||
|
@ -175,6 +175,34 @@ SOURCE=.\tool_bname.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_dbg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_hdr.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_prg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_rea.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_see.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_skt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_wrt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cfgable.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -211,10 +239,6 @@ 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
|
||||
@ -283,6 +307,34 @@ SOURCE=.\tool_bname.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_dbg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_hdr.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_prg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_rea.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_see.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_skt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cb_wrt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tool_cfgable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -319,10 +371,6 @@ 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user