mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:31:41 +03:00
curlx: curlx_strcopy() instead of strcpy()
This function REQUIRES the size of the target buffer as well as the length of the source string. Meant to make it harder to do a bad strcpy(). Removes 23 calls to strcpy(). Closes #20067
This commit is contained in:
parent
f099c2ca55
commit
a535be4ea0
30 changed files with 195 additions and 97 deletions
|
|
@ -31,6 +31,7 @@ LIB_CURLX_CFILES = \
|
||||||
curlx/inet_pton.c \
|
curlx/inet_pton.c \
|
||||||
curlx/multibyte.c \
|
curlx/multibyte.c \
|
||||||
curlx/nonblock.c \
|
curlx/nonblock.c \
|
||||||
|
curlx/strcopy.c \
|
||||||
curlx/strerr.c \
|
curlx/strerr.c \
|
||||||
curlx/strparse.c \
|
curlx/strparse.c \
|
||||||
curlx/timediff.c \
|
curlx/timediff.c \
|
||||||
|
|
@ -51,6 +52,7 @@ LIB_CURLX_HFILES = \
|
||||||
curlx/multibyte.h \
|
curlx/multibyte.h \
|
||||||
curlx/nonblock.h \
|
curlx/nonblock.h \
|
||||||
curlx/snprintf.h \
|
curlx/snprintf.h \
|
||||||
|
curlx/strcopy.h \
|
||||||
curlx/strerr.h \
|
curlx/strerr.h \
|
||||||
curlx/strparse.h \
|
curlx/strparse.h \
|
||||||
curlx/timediff.h \
|
curlx/timediff.h \
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#include "curl_gethostname.h"
|
#include "curl_gethostname.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
* Curl_gethostname() is a wrapper around gethostname() which allows
|
||||||
|
|
@ -60,7 +60,7 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
||||||
if(force_hostname) {
|
if(force_hostname) {
|
||||||
if(strlen(force_hostname) < (size_t)namelen)
|
if(strlen(force_hostname) < (size_t)namelen)
|
||||||
strcpy(name, force_hostname);
|
curlx_strcopy(name, namelen, force_hostname, strlen(force_hostname));
|
||||||
else
|
else
|
||||||
return 1; /* cannot do it */
|
return 1; /* cannot do it */
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "curl_gssapi.h"
|
#include "curl_gssapi.h"
|
||||||
#include "curl_trc.h"
|
#include "curl_trc.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||||
|
|
@ -224,7 +225,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(ctx->creds, creds);
|
curlx_strcopy(ctx->creds, sizeof(ctx->creds), creds, strlen(creds));
|
||||||
ctx->flags = req_flags;
|
ctx->flags = req_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include "curlx/strparse.h"
|
#include "curlx/strparse.h"
|
||||||
#include "vtls/vtls.h"
|
#include "vtls/vtls.h"
|
||||||
#include "vquic/vquic.h"
|
#include "vquic/vquic.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
static void trc_write(struct Curl_easy *data, curl_infotype type,
|
static void trc_write(struct Curl_easy *data, curl_infotype type,
|
||||||
const char *ptr, size_t size)
|
const char *ptr, size_t size)
|
||||||
|
|
@ -184,7 +185,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||||
len = curl_mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
len = curl_mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||||
|
|
||||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||||
strcpy(data->set.errorbuffer, error);
|
curlx_strcopy(data->set.errorbuffer, CURL_ERROR_SIZE, error, len);
|
||||||
data->state.errorbuf = TRUE; /* wrote error string */
|
data->state.errorbuf = TRUE; /* wrote error string */
|
||||||
}
|
}
|
||||||
error[len++] = '\n';
|
error[len++] = '\n';
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,9 @@
|
||||||
#include "strparse.h"
|
#include "strparse.h"
|
||||||
/* The curlx_str_* parsing functions */
|
/* The curlx_str_* parsing functions */
|
||||||
|
|
||||||
|
#include "strcopy.h"
|
||||||
|
/* curlx_strcopy */
|
||||||
|
|
||||||
#include "dynbuf.h"
|
#include "dynbuf.h"
|
||||||
/* The curlx_dyn_* functions */
|
/* The curlx_dyn_* functions */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "inet_ntop.h"
|
#include "inet_ntop.h"
|
||||||
#include "snprintf.h"
|
#include "snprintf.h"
|
||||||
|
#include "strcopy.h"
|
||||||
|
|
||||||
#define IN6ADDRSZ 16
|
#define IN6ADDRSZ 16
|
||||||
/* #define INADDRSZ 4 */
|
/* #define INADDRSZ 4 */
|
||||||
|
|
@ -78,7 +79,7 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(dst, tmp);
|
curlx_strcopy(dst, size, tmp, len);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,8 +184,7 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||||
*tp++ = ':';
|
*tp++ = ':';
|
||||||
*tp++ = '\0';
|
*tp++ = '\0';
|
||||||
|
|
||||||
/* Check for overflow, copy, and we are done.
|
/* Check for overflow, copy, and we are done. */
|
||||||
*/
|
|
||||||
if((size_t)(tp - tmp) > size) {
|
if((size_t)(tp - tmp) > size) {
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
errno = WSAEINVAL;
|
errno = WSAEINVAL;
|
||||||
|
|
@ -193,7 +193,8 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(dst, tmp);
|
|
||||||
|
curlx_strcopy(dst, size, tmp, strlen(tmp));
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
49
lib/curlx/strcopy.c
Normal file
49
lib/curlx/strcopy.c
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 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 https://curl.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.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: curl
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "../curl_setup.h"
|
||||||
|
#include "strcopy.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* curlx_strcopy() is a replacement for strcpy().
|
||||||
|
*
|
||||||
|
* Provide the target buffer @dest and size of the target buffer @dsize, If
|
||||||
|
* the source string @src with its *string length* @slen fits in the target
|
||||||
|
* buffer it will be copied there - including storing a null terminator.
|
||||||
|
*
|
||||||
|
* If the target buffer is too small, the copy is not performed but if the
|
||||||
|
* target buffer has a non-zero size it will get a null terminator stored.
|
||||||
|
*/
|
||||||
|
void curlx_strcopy(char *dest, /* destination buffer */
|
||||||
|
size_t dsize, /* size of target buffer */
|
||||||
|
const char *src, /* source string */
|
||||||
|
size_t slen) /* length of source string to copy */
|
||||||
|
{
|
||||||
|
DEBUGASSERT(slen < dsize);
|
||||||
|
if(slen < dsize) {
|
||||||
|
memcpy(dest, src, slen);
|
||||||
|
dest[slen] = 0;
|
||||||
|
}
|
||||||
|
else if(dsize)
|
||||||
|
dest[0] = 0;
|
||||||
|
}
|
||||||
32
lib/curlx/strcopy.h
Normal file
32
lib/curlx/strcopy.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef HEADER_CURLX_STRCOPY_H
|
||||||
|
#define HEADER_CURLX_STRCOPY_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 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 https://curl.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.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: curl
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
void curlx_strcopy(char *dest,
|
||||||
|
size_t dsize, /* size of target buffer */
|
||||||
|
const char *src,
|
||||||
|
size_t slen); /* length of string to copy */
|
||||||
|
|
||||||
|
#endif /* HEADER_CURLX_STRCOPY_H */
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "winapi.h"
|
#include "winapi.h"
|
||||||
#include "snprintf.h"
|
#include "snprintf.h"
|
||||||
#include "strerr.h"
|
#include "strerr.h"
|
||||||
|
#include "strcopy.h"
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
/* This is a helper function for curlx_strerror that converts Winsock error
|
/* This is a helper function for curlx_strerror that converts Winsock error
|
||||||
|
|
@ -224,8 +225,7 @@ static const char *get_winsock_error(int err, char *buf, size_t len)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
alen = strlen(p);
|
alen = strlen(p);
|
||||||
if(alen < len)
|
curlx_strcopy(buf, len, p, alen);
|
||||||
strcpy(buf, p);
|
|
||||||
return buf;
|
return buf;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "winapi.h"
|
#include "winapi.h"
|
||||||
#include "snprintf.h"
|
#include "snprintf.h"
|
||||||
|
#include "strcopy.h"
|
||||||
|
|
||||||
/* This is a helper function for curlx_strerror that converts Windows API error
|
/* This is a helper function for curlx_strerror that converts Windows API error
|
||||||
* codes (GetLastError) to error messages.
|
* codes (GetLastError) to error messages.
|
||||||
|
|
@ -93,8 +94,7 @@ const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
|
const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
|
||||||
if(strlen(txt) < buflen)
|
curlx_strcopy(buf, buflen, txt, strlen(txt));
|
||||||
strcpy(buf, txt);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
#include "easy_lock.h"
|
#include "easy_lock.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
#include "curlx/strparse.h"
|
#include "curlx/strparse.h"
|
||||||
|
|
||||||
#if defined(CURLRES_SYNCH) && \
|
#if defined(CURLRES_SYNCH) && \
|
||||||
|
|
@ -622,7 +623,7 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name)
|
||||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||||
memcpy(ca->ai_addr, &sa6, ss_size);
|
memcpy(ca->ai_addr, &sa6, ss_size);
|
||||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||||
strcpy(ca->ai_canonname, name);
|
curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen);
|
||||||
return ca;
|
return ca;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
@ -659,7 +660,7 @@ static struct Curl_addrinfo *get_localhost(int port, const char *name)
|
||||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||||
memcpy(ca->ai_addr, &sa, ss_size);
|
memcpy(ca->ai_addr, &sa, ss_size);
|
||||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||||
strcpy(ca->ai_canonname, name);
|
curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen);
|
||||||
|
|
||||||
ca6 = get_localhost6(port, name);
|
ca6 = get_localhost6(port, name);
|
||||||
if(!ca6)
|
if(!ca6)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "curl_share.h"
|
#include "curl_share.h"
|
||||||
#include "curlx/strparse.h"
|
#include "curlx/strparse.h"
|
||||||
#include "curlx/timeval.h"
|
#include "curlx/timeval.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
#define MAX_HSTS_LINE 4095
|
#define MAX_HSTS_LINE 4095
|
||||||
#define MAX_HSTS_HOSTLEN 2048
|
#define MAX_HSTS_HOSTLEN 2048
|
||||||
|
|
@ -294,7 +295,7 @@ static CURLcode hsts_push(struct Curl_easy *data,
|
||||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
|
stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strcpy(e.expire, UNLIMITED);
|
curlx_strcopy(e.expire, sizeof(e.expire), UNLIMITED, strlen(UNLIMITED));
|
||||||
|
|
||||||
sc = data->set.hsts_write(data, &e, i, data->set.hsts_write_userp);
|
sc = data->set.hsts_write(data, &e, i, data->set.hsts_write_userp);
|
||||||
*stop = (sc != CURLSTS_OK);
|
*stop = (sc != CURLSTS_OK);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "bufref.h"
|
#include "bufref.h"
|
||||||
#include "curl_sasl.h"
|
#include "curl_sasl.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/* meta key for storing protocol meta at easy handle */
|
/* meta key for storing protocol meta at easy handle */
|
||||||
#define CURL_META_IMAP_EASY "meta:proto:imap:easy"
|
#define CURL_META_IMAP_EASY "meta:proto:imap:easy"
|
||||||
|
|
@ -1679,7 +1679,7 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
|
||||||
imap_state(data, imapc, IMAP_SERVERGREET);
|
imap_state(data, imapc, IMAP_SERVERGREET);
|
||||||
|
|
||||||
/* Start off with an response id of '*' */
|
/* Start off with an response id of '*' */
|
||||||
strcpy(imapc->resptag, "*");
|
curlx_strcopy(imapc->resptag, sizeof(imapc->resptag), "*", 1);
|
||||||
|
|
||||||
result = imap_multi_statemach(data, done);
|
result = imap_multi_statemach(data, done);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ struct Curl_easy;
|
||||||
#include "curl_trc.h"
|
#include "curl_trc.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
#include "curlx/fopen.h"
|
#include "curlx/fopen.h"
|
||||||
#include "curlx/base64.h"
|
#include "curlx/base64.h"
|
||||||
|
|
||||||
|
|
@ -602,7 +603,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(softlinebreak) {
|
if(softlinebreak) {
|
||||||
strcpy(buf, "\x3D\x0D\x0A"); /* "=\r\n" */
|
curlx_strcopy(buf, sizeof(buf), "\x3D\x0D\x0A", 3); /* "=\r\n" */
|
||||||
len = 3;
|
len = 3;
|
||||||
consumed = 0;
|
consumed = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "curlx/timeval.h"
|
#include "curlx/timeval.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/* check rate limits within this many recent milliseconds, at minimum. */
|
/* check rate limits within this many recent milliseconds, at minimum. */
|
||||||
#define MIN_RATE_LIMIT_PERIOD 3000
|
#define MIN_RATE_LIMIT_PERIOD 3000
|
||||||
|
|
@ -37,18 +38,18 @@
|
||||||
#ifndef CURL_DISABLE_PROGRESS_METER
|
#ifndef CURL_DISABLE_PROGRESS_METER
|
||||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||||
byte) */
|
byte) */
|
||||||
static void time2str(char *r, curl_off_t seconds)
|
static void time2str(char *r, size_t rsize, curl_off_t seconds)
|
||||||
{
|
{
|
||||||
curl_off_t h;
|
curl_off_t h;
|
||||||
if(seconds <= 0) {
|
if(seconds <= 0) {
|
||||||
strcpy(r, "--:--:--");
|
curlx_strcopy(r, rsize, "--:--:--", 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
h = seconds / 3600;
|
h = seconds / 3600;
|
||||||
if(h <= 99) {
|
if(h <= 99) {
|
||||||
curl_off_t m = (seconds - (h * 3600)) / 60;
|
curl_off_t m = (seconds - (h * 3600)) / 60;
|
||||||
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
||||||
curl_msnprintf(r, 9, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T,
|
curl_msnprintf(r, rsize, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T,
|
||||||
h, m, s);
|
h, m, s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -57,21 +58,21 @@ static void time2str(char *r, curl_off_t seconds)
|
||||||
curl_off_t d = seconds / 86400;
|
curl_off_t d = seconds / 86400;
|
||||||
h = (seconds - (d * 86400)) / 3600;
|
h = (seconds - (d * 86400)) / 3600;
|
||||||
if(d <= 999)
|
if(d <= 999)
|
||||||
curl_msnprintf(r, 9, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h);
|
curl_msnprintf(r, rsize, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h);
|
||||||
else
|
else
|
||||||
curl_msnprintf(r, 9, "%7" FMT_OFF_T "d", d);
|
curl_msnprintf(r, rsize, "%7" FMT_OFF_T "d", d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The point of this function would be to return a string of the input data,
|
/* The point of this function would be to return a string of the input data,
|
||||||
but never longer than 6 columns (+ one zero byte).
|
but never longer than 6 columns (+ one zero byte).
|
||||||
Add suffix k, M, G when suitable... */
|
Add suffix k, M, G when suitable... */
|
||||||
static char *max6data(curl_off_t bytes, char *max6)
|
static char *max6out(curl_off_t bytes, char *max6, size_t mlen)
|
||||||
{
|
{
|
||||||
/* a signed 64-bit value is 8192 petabytes maximum, shown as
|
/* a signed 64-bit value is 8192 petabytes maximum, shown as
|
||||||
8.0E (exabytes)*/
|
8.0E (exabytes)*/
|
||||||
if(bytes < 100000)
|
if(bytes < 100000)
|
||||||
curl_msnprintf(max6, 7, "%6" CURL_FORMAT_CURL_OFF_T, bytes);
|
curl_msnprintf(max6, mlen, "%6" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||||
else {
|
else {
|
||||||
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };
|
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
@ -85,7 +86,7 @@ static char *max6data(curl_off_t bytes, char *max6)
|
||||||
DEBUGASSERT(unit[k]);
|
DEBUGASSERT(unit[k]);
|
||||||
} while(unit[k]);
|
} while(unit[k]);
|
||||||
/* xxx.yU */
|
/* xxx.yU */
|
||||||
curl_msnprintf(max6, 7, "%3" CURL_FORMAT_CURL_OFF_T
|
curl_msnprintf(max6, mlen, "%3" CURL_FORMAT_CURL_OFF_T
|
||||||
".%" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
".%" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
||||||
(bytes % 1024) / (1024 / 10), unit[k]);
|
(bytes % 1024) / (1024 / 10), unit[k]);
|
||||||
}
|
}
|
||||||
|
|
@ -528,9 +529,10 @@ static void progress_meter(struct Curl_easy *data)
|
||||||
/* Since both happen at the same time, total expected duration is max. */
|
/* Since both happen at the same time, total expected duration is max. */
|
||||||
total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs);
|
total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs);
|
||||||
/* create the three time strings */
|
/* create the three time strings */
|
||||||
time2str(time_left, total_estm.secs > 0 ? (total_estm.secs - cur_secs) : 0);
|
time2str(time_left, sizeof(time_left),
|
||||||
time2str(time_total, total_estm.secs);
|
total_estm.secs > 0 ? (total_estm.secs - cur_secs) : 0);
|
||||||
time2str(time_spent, cur_secs);
|
time2str(time_total, sizeof(time_total), total_estm.secs);
|
||||||
|
time2str(time_spent, sizeof(time_spent), cur_secs);
|
||||||
|
|
||||||
/* Get the total amount of data expected to get transferred */
|
/* Get the total amount of data expected to get transferred */
|
||||||
total_expected_size = p->ul_size_known ? p->ul.total_size : p->ul.cur_size;
|
total_expected_size = p->ul_size_known ? p->ul.total_size : p->ul.cur_size;
|
||||||
|
|
@ -554,18 +556,24 @@ static void progress_meter(struct Curl_easy *data)
|
||||||
"%3" FMT_OFF_T " %s "
|
"%3" FMT_OFF_T " %s "
|
||||||
"%3" FMT_OFF_T " %s "
|
"%3" FMT_OFF_T " %s "
|
||||||
"%3" FMT_OFF_T " %s %s %s %s %s %s %s",
|
"%3" FMT_OFF_T " %s %s %s %s %s %s %s",
|
||||||
total_estm.percent, /* 3 letters */ /* total % */
|
total_estm.percent, /* 3 letters */ /* total % */
|
||||||
max6data(total_expected_size, max6[2]), /* total size */
|
max6out(total_expected_size, max6[2],
|
||||||
dl_estm.percent, /* 3 letters */ /* rcvd % */
|
sizeof(max6[2])), /* total size */
|
||||||
max6data(p->dl.cur_size, max6[0]), /* rcvd size */
|
dl_estm.percent, /* 3 letters */ /* rcvd % */
|
||||||
ul_estm.percent, /* 3 letters */ /* xfer % */
|
max6out(p->dl.cur_size, max6[0],
|
||||||
max6data(p->ul.cur_size, max6[1]), /* xfer size */
|
sizeof(max6[0])), /* rcvd size */
|
||||||
max6data(p->dl.speed, max6[3]), /* avrg dl speed */
|
ul_estm.percent, /* 3 letters */ /* xfer % */
|
||||||
max6data(p->ul.speed, max6[4]), /* avrg ul speed */
|
max6out(p->ul.cur_size, max6[1],
|
||||||
time_total, /* 8 letters */ /* total time */
|
sizeof(max6[1])), /* xfer size */
|
||||||
time_spent, /* 8 letters */ /* time spent */
|
max6out(p->dl.speed, max6[3],
|
||||||
time_left, /* 8 letters */ /* time left */
|
sizeof(max6[3])), /* avrg dl speed */
|
||||||
max6data(p->current_speed, max6[5])
|
max6out(p->ul.speed, max6[4],
|
||||||
|
sizeof(max6[4])), /* avrg ul speed */
|
||||||
|
time_total, /* 8 letters */ /* total time */
|
||||||
|
time_spent, /* 8 letters */ /* time spent */
|
||||||
|
time_left, /* 8 letters */ /* time left */
|
||||||
|
max6out(p->current_speed, max6[5],
|
||||||
|
sizeof(max6[5])) /* current speed */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* we flush the output stream to make it appear as soon as possible */
|
/* we flush the output stream to make it appear as soon as possible */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#include "curl_ntlm_core.h"
|
#include "curl_ntlm_core.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "curl_endian.h"
|
#include "curl_endian.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/* meta key for storing protocol meta at easy handle */
|
/* meta key for storing protocol meta at easy handle */
|
||||||
#define CURL_META_SMB_EASY "meta:proto:smb:easy"
|
#define CURL_META_SMB_EASY "meta:proto:smb:easy"
|
||||||
|
|
@ -790,7 +790,7 @@ static CURLcode smb_send_open(struct Curl_easy *data,
|
||||||
msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
|
msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
|
||||||
}
|
}
|
||||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||||
strcpy(msg.bytes, req->path);
|
curlx_strcopy(msg.bytes, sizeof(msg.bytes), req->path, byte_count - 1);
|
||||||
|
|
||||||
return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg,
|
return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg,
|
||||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,4 @@ wchar_t *Curl_wcsdup(const wchar_t *src);
|
||||||
void *Curl_memdup(const void *src, size_t buffer_length);
|
void *Curl_memdup(const void *src, size_t buffer_length);
|
||||||
void *Curl_saferealloc(void *ptr, size_t size);
|
void *Curl_saferealloc(void *ptr, size_t size);
|
||||||
void *Curl_memdup0(const char *src, size_t length);
|
void *Curl_memdup0(const char *src, size_t length);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_STRDUP_H */
|
#endif /* HEADER_CURL_STRDUP_H */
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "curlx/winapi.h"
|
#include "curlx/winapi.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
const char *curl_easy_strerror(CURLcode error)
|
const char *curl_easy_strerror(CURLcode error)
|
||||||
{
|
{
|
||||||
|
|
@ -663,8 +664,7 @@ const char *Curl_sspi_strerror(SECURITY_STATUS err, char *buf, size_t buflen)
|
||||||
txt = "No error";
|
txt = "No error";
|
||||||
else
|
else
|
||||||
txt = "Error";
|
txt = "Error";
|
||||||
if(buflen > strlen(txt))
|
curlx_strcopy(buf, buflen, txt, strlen(txt));
|
||||||
strcpy(buf, txt);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(errno != old_errno)
|
if(errno != old_errno)
|
||||||
|
|
|
||||||
35
lib/tftp.c
35
lib/tftp.c
|
|
@ -62,6 +62,7 @@
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "curlx/strerr.h"
|
#include "curlx/strerr.h"
|
||||||
#include "curlx/strparse.h"
|
#include "curlx/strparse.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/* RFC2348 allows the block size to be negotiated */
|
/* RFC2348 allows the block size to be negotiated */
|
||||||
#define TFTP_BLKSIZE_DEFAULT 512
|
#define TFTP_BLKSIZE_DEFAULT 512
|
||||||
|
|
@ -369,12 +370,17 @@ static CURLcode tftp_parse_option_ack(struct tftp_conn *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode tftp_option_add(struct tftp_conn *state, size_t *csize,
|
static CURLcode tftp_option_add(struct tftp_conn *state, size_t *csize,
|
||||||
char *buf, const char *option)
|
size_t index, const char *option)
|
||||||
{
|
{
|
||||||
if((strlen(option) + *csize + 1) > (size_t)state->blksize)
|
char *buf = (char *)&state->spacket.data[index];
|
||||||
|
size_t oplen = strlen(option);
|
||||||
|
size_t blen;
|
||||||
|
if((state->blksize <= index) ||
|
||||||
|
(oplen + 1) > (size_t)(state->blksize - index))
|
||||||
return CURLE_TFTP_ILLEGAL;
|
return CURLE_TFTP_ILLEGAL;
|
||||||
strcpy(buf, option);
|
blen = state->blksize - index;
|
||||||
*csize += strlen(option) + 1;
|
curlx_strcopy(buf, blen, option, oplen);
|
||||||
|
*csize += oplen + 1;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,32 +485,23 @@ static CURLcode tftp_send_first(struct tftp_conn *state,
|
||||||
data->state.upload && (data->state.infilesize != -1) ?
|
data->state.upload && (data->state.infilesize != -1) ?
|
||||||
data->state.infilesize : 0);
|
data->state.infilesize : 0);
|
||||||
|
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_TSIZE);
|
||||||
(char *)state->spacket.data + sbytes,
|
|
||||||
TFTP_OPTION_TSIZE);
|
|
||||||
if(result == CURLE_OK)
|
if(result == CURLE_OK)
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, buf);
|
||||||
(char *)state->spacket.data + sbytes, buf);
|
|
||||||
|
|
||||||
/* add blksize option */
|
/* add blksize option */
|
||||||
curl_msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
|
curl_msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
|
||||||
if(result == CURLE_OK)
|
if(result == CURLE_OK)
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_BLKSIZE);
|
||||||
(char *)state->spacket.data + sbytes,
|
|
||||||
TFTP_OPTION_BLKSIZE);
|
|
||||||
if(result == CURLE_OK)
|
if(result == CURLE_OK)
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, buf);
|
||||||
(char *)state->spacket.data + sbytes, buf);
|
|
||||||
|
|
||||||
/* add timeout option */
|
/* add timeout option */
|
||||||
curl_msnprintf(buf, sizeof(buf), "%d", state->retry_time);
|
curl_msnprintf(buf, sizeof(buf), "%d", state->retry_time);
|
||||||
if(result == CURLE_OK)
|
if(result == CURLE_OK)
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_INTERVAL);
|
||||||
(char *)state->spacket.data + sbytes,
|
|
||||||
TFTP_OPTION_INTERVAL);
|
|
||||||
if(result == CURLE_OK)
|
if(result == CURLE_OK)
|
||||||
result = tftp_option_add(state, &sbytes,
|
result = tftp_option_add(state, &sbytes, sbytes, buf);
|
||||||
(char *)state->spacket.data + sbytes, buf);
|
|
||||||
|
|
||||||
if(result != CURLE_OK) {
|
if(result != CURLE_OK) {
|
||||||
failf(data, "TFTP buffer too small for options");
|
failf(data, "TFTP buffer too small for options");
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ static CURLUcode ipv6_parse(struct Curl_URL *u, char *hostname,
|
||||||
hostname[hlen] = 0; /* end the address there */
|
hostname[hlen] = 0; /* end the address there */
|
||||||
if(curlx_inet_pton(AF_INET6, hostname, dest) != 1)
|
if(curlx_inet_pton(AF_INET6, hostname, dest) != 1)
|
||||||
return CURLUE_BAD_IPV6;
|
return CURLUE_BAD_IPV6;
|
||||||
if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen)) {
|
if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen + 1)) {
|
||||||
hlen = strlen(hostname); /* might be shorter now */
|
hlen = strlen(hostname); /* might be shorter now */
|
||||||
hostname[hlen + 1] = 0;
|
hostname[hlen + 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#include "../url.h"
|
#include "../url.h"
|
||||||
#include "../bufref.h"
|
#include "../bufref.h"
|
||||||
#include "../curlx/strerr.h"
|
#include "../curlx/strerr.h"
|
||||||
|
#include "../curlx/strcopy.h"
|
||||||
|
|
||||||
/* A stream window is the maximum amount we need to buffer for
|
/* A stream window is the maximum amount we need to buffer for
|
||||||
* each active transfer. We use HTTP/3 flow control and only ACK
|
* each active transfer. We use HTTP/3 flow control and only ACK
|
||||||
|
|
@ -141,7 +142,7 @@ static char *osslq_strerror(unsigned long error, char *buf, size_t size)
|
||||||
if(!*buf) {
|
if(!*buf) {
|
||||||
const char *msg = error ? "Unknown error" : "No error";
|
const char *msg = error ? "Unknown error" : "No error";
|
||||||
if(strlen(msg) < size)
|
if(strlen(msg) < size)
|
||||||
strcpy(buf, msg);
|
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
#include "../multiif.h"
|
#include "../multiif.h"
|
||||||
#include "../curlx/strerr.h"
|
#include "../curlx/strerr.h"
|
||||||
#include "../curlx/strparse.h"
|
#include "../curlx/strparse.h"
|
||||||
|
#include "../curlx/strcopy.h"
|
||||||
#include "../strdup.h"
|
#include "../strdup.h"
|
||||||
#include "apple.h"
|
#include "apple.h"
|
||||||
|
|
||||||
|
|
@ -773,8 +774,7 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size)
|
||||||
|
|
||||||
if(!*buf) {
|
if(!*buf) {
|
||||||
const char *msg = error ? "Unknown error" : "No error";
|
const char *msg = error ? "Unknown error" : "No error";
|
||||||
if(strlen(msg) < size)
|
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||||
strcpy(buf, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
#include "../select.h"
|
#include "../select.h"
|
||||||
#include "../setopt.h"
|
#include "../setopt.h"
|
||||||
#include "../strdup.h"
|
#include "../strdup.h"
|
||||||
|
#include "../curlx/strcopy.h"
|
||||||
|
|
||||||
#ifdef USE_APPLE_SECTRUST
|
#ifdef USE_APPLE_SECTRUST
|
||||||
#include <Security/Security.h>
|
#include <Security/Security.h>
|
||||||
|
|
@ -1082,10 +1083,7 @@ static size_t multissl_version(char *buffer, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size) {
|
if(size) {
|
||||||
if(backends_len < size)
|
curlx_strcopy(buffer, size, backends, backends_len);
|
||||||
strcpy(buffer, backends);
|
|
||||||
else
|
|
||||||
*buffer = 0; /* did not fit */
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@
|
||||||
#include "../connect.h" /* for the connect timeout */
|
#include "../connect.h" /* for the connect timeout */
|
||||||
#include "../progress.h"
|
#include "../progress.h"
|
||||||
#include "../strdup.h"
|
#include "../strdup.h"
|
||||||
|
#include "../curlx/strcopy.h"
|
||||||
#include "x509asn1.h"
|
#include "x509asn1.h"
|
||||||
|
|
||||||
#include <wolfssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
|
|
@ -1542,8 +1543,7 @@ static char *wssl_strerror(unsigned long error, char *buf, unsigned long size)
|
||||||
|
|
||||||
if(!*buf) {
|
if(!*buf) {
|
||||||
const char *msg = error ? "Unknown error" : "No error";
|
const char *msg = error ? "Unknown error" : "No error";
|
||||||
/* the string fits because the assert above assures this */
|
curlx_strcopy(buf, size, msg, strlen(msg));
|
||||||
strcpy(buf, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
||||||
3
lib/ws.c
3
lib/ws.c
|
|
@ -40,6 +40,7 @@
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "curlx/strparse.h"
|
#include "curlx/strparse.h"
|
||||||
|
#include "curlx/strcopy.h"
|
||||||
|
|
||||||
/***
|
/***
|
||||||
RFC 6455 Section 5.2
|
RFC 6455 Section 5.2
|
||||||
|
|
@ -1274,7 +1275,7 @@ CURLcode Curl_ws_request(struct Curl_easy *data, struct dynbuf *req)
|
||||||
curlx_free(randstr);
|
curlx_free(randstr);
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
strcpy(keyval, randstr);
|
curlx_strcopy(keyval, sizeof(keyval), randstr, randlen);
|
||||||
curlx_free(randstr);
|
curlx_free(randstr);
|
||||||
for(i = 0; !result && (i < CURL_ARRAYSIZE(heads)); i++) {
|
for(i = 0; !result && (i < CURL_ARRAYSIZE(heads)); i++) {
|
||||||
if(!Curl_checkheaders(data, heads[i].name, strlen(heads[i].name))) {
|
if(!Curl_checkheaders(data, heads[i].name, strlen(heads[i].name))) {
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ CURLX_CFILES = \
|
||||||
../lib/curlx/fopen.c \
|
../lib/curlx/fopen.c \
|
||||||
../lib/curlx/multibyte.c \
|
../lib/curlx/multibyte.c \
|
||||||
../lib/curlx/nonblock.c \
|
../lib/curlx/nonblock.c \
|
||||||
|
../lib/curlx/strcopy.c \
|
||||||
../lib/curlx/strerr.c \
|
../lib/curlx/strerr.c \
|
||||||
../lib/curlx/strparse.c \
|
../lib/curlx/strparse.c \
|
||||||
../lib/curlx/timediff.c \
|
../lib/curlx/timediff.c \
|
||||||
|
|
@ -55,6 +56,7 @@ CURLX_HFILES = \
|
||||||
../lib/curlx/multibyte.h \
|
../lib/curlx/multibyte.h \
|
||||||
../lib/curlx/nonblock.h \
|
../lib/curlx/nonblock.h \
|
||||||
../lib/curlx/snprintf.h \
|
../lib/curlx/snprintf.h \
|
||||||
|
../lib/curlx/strcopy.h \
|
||||||
../lib/curlx/strerr.h \
|
../lib/curlx/strerr.h \
|
||||||
../lib/curlx/strparse.h \
|
../lib/curlx/strparse.h \
|
||||||
../lib/curlx/timediff.h \
|
../lib/curlx/timediff.h \
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,7 @@ static void memory_tracking_init(void)
|
||||||
if(env) {
|
if(env) {
|
||||||
/* use the value as filename */
|
/* use the value as filename */
|
||||||
char fname[512];
|
char fname[512];
|
||||||
if(strlen(env) >= sizeof(fname))
|
curlx_strcopy(fname, sizeof(fname), env, strlen(env));
|
||||||
env[sizeof(fname) - 1] = '\0';
|
|
||||||
strcpy(fname, env);
|
|
||||||
curl_free(env);
|
curl_free(env);
|
||||||
curl_dbg_memdebug(fname);
|
curl_dbg_memdebug(fname);
|
||||||
/* this weird stuff here is to make curl_free() get called before
|
/* this weird stuff here is to make curl_free() get called before
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@
|
||||||
/* The point of this function would be to return a string of the input data,
|
/* The point of this function would be to return a string of the input data,
|
||||||
but never longer than 5 columns (+ one zero byte).
|
but never longer than 5 columns (+ one zero byte).
|
||||||
Add suffix k, M, G when suitable... */
|
Add suffix k, M, G when suitable... */
|
||||||
static char *max5data(curl_off_t bytes, char *max5)
|
static char *max5data(curl_off_t bytes, char *max5, size_t mlen)
|
||||||
{
|
{
|
||||||
/* a signed 64-bit value is 8192 petabytes maximum */
|
/* a signed 64-bit value is 8192 petabytes maximum */
|
||||||
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 0 };
|
const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };
|
||||||
int k = 0;
|
int k = 0;
|
||||||
if(bytes < 100000) {
|
if(bytes < 100000) {
|
||||||
curl_msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
|
curl_msnprintf(max5, mlen, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
|
||||||
return max5;
|
return max5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,14 +43,14 @@ static char *max5data(curl_off_t bytes, char *max5)
|
||||||
curl_off_t nbytes = bytes / 1024;
|
curl_off_t nbytes = bytes / 1024;
|
||||||
if(nbytes < 100) {
|
if(nbytes < 100) {
|
||||||
/* display with a decimal */
|
/* display with a decimal */
|
||||||
curl_msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
curl_msnprintf(max5, mlen, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
|
||||||
CURL_FORMAT_CURL_OFF_T "%c", bytes / 1024,
|
CURL_FORMAT_CURL_OFF_T "%c", bytes / 1024,
|
||||||
(bytes % 1024) / (1024 / 10), unit[k]);
|
(bytes % 1024) / (1024 / 10), unit[k]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(nbytes < 10000) {
|
else if(nbytes < 10000) {
|
||||||
/* no decimals */
|
/* no decimals */
|
||||||
curl_msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
curl_msnprintf(max5, mlen, "%4" CURL_FORMAT_CURL_OFF_T "%c", nbytes,
|
||||||
unit[k]);
|
unit[k]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -87,18 +87,18 @@ int xferinfo_cb(void *clientp,
|
||||||
|
|
||||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||||
byte) */
|
byte) */
|
||||||
static void time2str(char *r, curl_off_t seconds)
|
static void time2str(char *r, size_t rlen, curl_off_t seconds)
|
||||||
{
|
{
|
||||||
curl_off_t h;
|
curl_off_t h;
|
||||||
if(seconds <= 0) {
|
if(seconds <= 0) {
|
||||||
strcpy(r, "--:--:--");
|
curlx_strcopy(r, rlen, "--:--:--", 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
h = seconds / 3600;
|
h = seconds / 3600;
|
||||||
if(h <= 99) {
|
if(h <= 99) {
|
||||||
curl_off_t m = (seconds - (h * 3600)) / 60;
|
curl_off_t m = (seconds - (h * 3600)) / 60;
|
||||||
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
curl_off_t s = (seconds - (h * 3600)) - (m * 60);
|
||||||
curl_msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T
|
curl_msnprintf(r, rlen, "%2" CURL_FORMAT_CURL_OFF_T
|
||||||
":%02" CURL_FORMAT_CURL_OFF_T
|
":%02" CURL_FORMAT_CURL_OFF_T
|
||||||
":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
|
":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
|
||||||
}
|
}
|
||||||
|
|
@ -108,10 +108,10 @@ static void time2str(char *r, curl_off_t seconds)
|
||||||
curl_off_t d = seconds / 86400;
|
curl_off_t d = seconds / 86400;
|
||||||
h = (seconds - (d * 86400)) / 3600;
|
h = (seconds - (d * 86400)) / 3600;
|
||||||
if(d <= 999)
|
if(d <= 999)
|
||||||
curl_msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
|
curl_msnprintf(r, rlen, "%3" CURL_FORMAT_CURL_OFF_T
|
||||||
"d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
|
"d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
|
||||||
else
|
else
|
||||||
curl_msnprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
|
curl_msnprintf(r, rlen, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -254,14 +254,14 @@ bool progress_meter(CURLM *multi, struct curltime *start, bool final)
|
||||||
if(dlknown && speed) {
|
if(dlknown && speed) {
|
||||||
curl_off_t est = all_dltotal / speed;
|
curl_off_t est = all_dltotal / speed;
|
||||||
curl_off_t left = (all_dltotal - all_dlnow) / speed;
|
curl_off_t left = (all_dltotal - all_dlnow) / speed;
|
||||||
time2str(time_left, left);
|
time2str(time_left, sizeof(time_left), left);
|
||||||
time2str(time_total, est);
|
time2str(time_total, sizeof(time_total), est);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
time2str(time_left, 0);
|
time2str(time_left, sizeof(time_left), 0);
|
||||||
time2str(time_total, 0);
|
time2str(time_total, sizeof(time_total), 0);
|
||||||
}
|
}
|
||||||
time2str(time_spent, spent);
|
time2str(time_spent, sizeof(time_spent), spent);
|
||||||
|
|
||||||
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_ADDED, &xfers_added);
|
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_ADDED, &xfers_added);
|
||||||
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_RUNNING, &xfers_running);
|
(void)curl_multi_get_offt(multi, CURLMINFO_XFERS_RUNNING, &xfers_running);
|
||||||
|
|
@ -281,14 +281,14 @@ bool progress_meter(CURLM *multi, struct curltime *start, bool final)
|
||||||
|
|
||||||
dlpercen, /* 3 letters */
|
dlpercen, /* 3 letters */
|
||||||
ulpercen, /* 3 letters */
|
ulpercen, /* 3 letters */
|
||||||
max5data(all_dlnow, buffer[0]),
|
max5data(all_dlnow, buffer[0], sizeof(buffer[0])),
|
||||||
max5data(all_ulnow, buffer[1]),
|
max5data(all_ulnow, buffer[1], sizeof(buffer[1])),
|
||||||
xfers_added,
|
xfers_added,
|
||||||
xfers_running,
|
xfers_running,
|
||||||
time_total,
|
time_total,
|
||||||
time_spent,
|
time_spent,
|
||||||
time_left,
|
time_left,
|
||||||
max5data(speed, buffer[2]), /* speed */
|
max5data(speed, buffer[2], sizeof(buffer[2])), /* speed */
|
||||||
final ? "\n" : "");
|
final ? "\n" : "");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ CURLX_C = \
|
||||||
../../lib/curl_threads.c \
|
../../lib/curl_threads.c \
|
||||||
../../lib/curlx/fopen.c \
|
../../lib/curlx/fopen.c \
|
||||||
../../lib/curlx/multibyte.c \
|
../../lib/curlx/multibyte.c \
|
||||||
|
../../lib/curlx/strcopy.c \
|
||||||
../../lib/curlx/strerr.c \
|
../../lib/curlx/strerr.c \
|
||||||
../../lib/curlx/strparse.c \
|
../../lib/curlx/strparse.c \
|
||||||
../../lib/curlx/timediff.c \
|
../../lib/curlx/timediff.c \
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ CURLX_C = \
|
||||||
../../lib/curlx/inet_pton.c \
|
../../lib/curlx/inet_pton.c \
|
||||||
../../lib/curlx/multibyte.c \
|
../../lib/curlx/multibyte.c \
|
||||||
../../lib/curlx/nonblock.c \
|
../../lib/curlx/nonblock.c \
|
||||||
|
../../lib/curlx/strcopy.c \
|
||||||
../../lib/curlx/strerr.c \
|
../../lib/curlx/strerr.c \
|
||||||
../../lib/curlx/strparse.c \
|
../../lib/curlx/strparse.c \
|
||||||
../../lib/curlx/timediff.c \
|
../../lib/curlx/timediff.c \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue