diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.inc | 16 | ||||
| -rw-r--r-- | src/Makefile.vc6 | 48 | ||||
| -rw-r--r-- | src/main.c | 622 | ||||
| -rw-r--r-- | src/tool_cb_dbg.c | 276 | ||||
| -rw-r--r-- | src/tool_cb_dbg.h | 35 | ||||
| -rw-r--r-- | src/tool_cb_hdr.c | 182 | ||||
| -rw-r--r-- | src/tool_cb_hdr.h | 33 | ||||
| -rw-r--r-- | src/tool_cb_prg.c (renamed from src/tool_progress.c) | 12 | ||||
| -rw-r--r-- | src/tool_cb_prg.h (renamed from src/tool_progress.h) | 18 | ||||
| -rw-r--r-- | src/tool_cb_rea.c | 61 | ||||
| -rw-r--r-- | src/tool_cb_rea.h | 33 | ||||
| -rw-r--r-- | src/tool_cb_see.c | 129 | ||||
| -rw-r--r-- | src/tool_cb_see.h | 45 | ||||
| -rw-r--r-- | src/tool_cb_skt.c | 97 | ||||
| -rw-r--r-- | src/tool_cb_skt.h | 35 | ||||
| -rw-r--r-- | src/tool_cb_wrt.c | 103 | ||||
| -rw-r--r-- | src/tool_cb_wrt.h | 33 | ||||
| -rw-r--r-- | src/vc6curlsrc.dsp | 64 | 
18 files changed, 1211 insertions, 631 deletions
| diff --git a/src/Makefile.inc b/src/Makefile.inc index 70e374bde..28d7f05d9 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -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 diff --git a/src/Makefile.vc6 b/src/Makefile.vc6 index d2ce12ce8..dce14182e 100644 --- a/src/Makefile.vc6 +++ b/src/Makefile.vc6 @@ -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
 diff --git a/src/main.c b/src/main.c index 1c8106626..306df623d 100644 --- a/src/main.c +++ b/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      */ diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c new file mode 100644 index 000000000..7b20a0c01 --- /dev/null +++ b/src/tool_cb_dbg.c @@ -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); +} + diff --git a/src/tool_cb_dbg.h b/src/tool_cb_dbg.h new file mode 100644 index 000000000..6d4446da1 --- /dev/null +++ b/src/tool_cb_dbg.h @@ -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 */ + diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c new file mode 100644 index 000000000..2643ad2cf --- /dev/null +++ b/src/tool_cb_hdr.c @@ -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; +} + diff --git a/src/tool_cb_hdr.h b/src/tool_cb_hdr.h new file mode 100644 index 000000000..8808a4ae1 --- /dev/null +++ b/src/tool_cb_hdr.h @@ -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 */ + diff --git a/src/tool_progress.c b/src/tool_cb_prg.c index e892ff3d2..e141f1e65 100644 --- a/src/tool_progress.c +++ b/src/tool_cb_prg.c @@ -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. */ diff --git a/src/tool_progress.h b/src/tool_cb_prg.h index 7be2744b8..f64335a3b 100644 --- a/src/tool_progress.h +++ b/src/tool_cb_prg.h @@ -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 */ diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c new file mode 100644 index 000000000..34edb063b --- /dev/null +++ b/src/tool_cb_rea.c @@ -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; +} + diff --git a/src/tool_cb_rea.h b/src/tool_cb_rea.h new file mode 100644 index 000000000..40c61f6f1 --- /dev/null +++ b/src/tool_cb_rea.h @@ -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 */ + diff --git a/src/tool_cb_see.c b/src/tool_cb_see.c new file mode 100644 index 000000000..5bac4947b --- /dev/null +++ b/src/tool_cb_see.c @@ -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__ */ + diff --git a/src/tool_cb_see.h b/src/tool_cb_see.h new file mode 100644 index 000000000..530bfacba --- /dev/null +++ b/src/tool_cb_see.h @@ -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 */ + diff --git a/src/tool_cb_skt.c b/src/tool_cb_skt.c new file mode 100644 index 000000000..156c1108e --- /dev/null +++ b/src/tool_cb_skt.c @@ -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; +} + diff --git a/src/tool_cb_skt.h b/src/tool_cb_skt.h new file mode 100644 index 000000000..11bd0c422 --- /dev/null +++ b/src/tool_cb_skt.h @@ -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 */ + diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c new file mode 100644 index 000000000..3a2cd791a --- /dev/null +++ b/src/tool_cb_wrt.c @@ -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; +} + diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h new file mode 100644 index 000000000..a17c14607 --- /dev/null +++ b/src/tool_cb_wrt.h @@ -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 */ + diff --git a/src/vc6curlsrc.dsp b/src/vc6curlsrc.dsp index 9b2011724..f8dadbd67 100644 --- a/src/vc6curlsrc.dsp +++ b/src/vc6curlsrc.dsp @@ -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
 | 
