tool_getparam: Support size modifiers for --max-filesize

- Move the size modifier detection code from limit-rate to its own
  function so that it can also be used with max-filesize.

Size modifiers are the suffixes such as G (gigabyte), M (megabyte) etc.

For example --max-filesize 1G

Ref: https://curl.haxx.se/mail/archive-2017-12/0000.html

Closes https://github.com/curl/curl/pull/2179
This commit is contained in:
Gisle Vanem 2017-12-17 17:26:10 -05:00 committed by Jay Satiro
parent b399b04902
commit 859ac36021
3 changed files with 69 additions and 36 deletions

View File

@ -8,7 +8,7 @@ your transfer not to use your entire bandwidth. To make it slower than it
otherwise would be. otherwise would be.
The given speed is measured in bytes/second, unless a suffix is appended. The given speed is measured in bytes/second, unless a suffix is appended.
Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it Appending 'k' or 'K' will count the number as kilobytes, 'm' or 'M' makes it
megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
If you also use the --speed-limit option, that option will take precedence and If you also use the --speed-limit option, that option will take precedence and

View File

@ -7,6 +7,10 @@ Specify the maximum size (in bytes) of a file to download. If the file
requested is larger than this value, the transfer will not start and curl will requested is larger than this value, the transfer will not start and curl will
return with exit code 63. return with exit code 63.
A size modifier may be used. For example, Appending 'k' or 'K' will count the
number as kilobytes, 'm' or 'M' makes it megabytes, while 'g' or 'G' makes it
gigabytes. Examples: 200K, 3m and 1G. (Added in 7.58.0)
\fBNOTE:\fP The file size is not always known prior to download, and for such \fBNOTE:\fP The file size is not always known prior to download, and for such
files this option has no effect even if the file transfer ends up being larger files this option has no effect even if the file transfer ends up being larger
than this given limit. This concerns both FTP and HTTP transfers. than this given limit. This concerns both FTP and HTTP transfers.

View File

@ -424,6 +424,58 @@ GetFileAndPassword(char *nextarg, char **file, char **password)
cleanarg(nextarg); cleanarg(nextarg);
} }
/* Get a size parameter for '--limit-rate' or '--max-filesize'.
* We support a 'G', 'M' or 'K' suffix too.
*/
static ParameterError GetSizeParameter(struct GlobalConfig *global,
const char *arg,
const char *which,
curl_off_t *value_out)
{
char *unit;
curl_off_t value;
if(curlx_strtoofft(arg, &unit, 0, &value)) {
warnf(global, "invalid number specified for %s\n", which);
return PARAM_BAD_USE;
}
if(!*unit)
unit = (char *)"b";
else if(strlen(unit) > 1)
unit = (char *)"w"; /* unsupported */
switch(*unit) {
case 'G':
case 'g':
if(value > (CURL_OFF_T_MAX / (1024*1024*1024)))
return PARAM_NUMBER_TOO_LARGE;
value *= 1024*1024*1024;
break;
case 'M':
case 'm':
if(value > (CURL_OFF_T_MAX / (1024*1024)))
return PARAM_NUMBER_TOO_LARGE;
value *= 1024*1024;
break;
case 'K':
case 'k':
if(value > (CURL_OFF_T_MAX / 1024))
return PARAM_NUMBER_TOO_LARGE;
value *= 1024;
break;
case 'b':
case 'B':
/* for plain bytes, leave as-is */
break;
default:
warnf(global, "unsupported %s unit. Use G, M, K or B!\n", which);
return PARAM_BAD_USE;
}
*value_out = value;
return PARAM_OK;
}
ParameterError getparameter(const char *flag, /* f or -long-flag */ ParameterError getparameter(const char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */ char *nextarg, /* NULL if unset */
bool *usedarg, /* set to TRUE if the arg bool *usedarg, /* set to TRUE if the arg
@ -589,40 +641,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break; break;
case 'i': /* --limit-rate */ case 'i': /* --limit-rate */
{ {
/* We support G, M, K too */
char *unit;
curl_off_t value; curl_off_t value;
if(curlx_strtoofft(nextarg, &unit, 0, &value)) { ParameterError pe = GetSizeParameter(global, nextarg, "rate", &value);
warnf(global, "unsupported rate\n");
return PARAM_BAD_USE;
}
if(!*unit) if(pe != PARAM_OK)
unit = (char *)"b"; return pe;
else if(strlen(unit) > 1)
unit = (char *)"w"; /* unsupported */
switch(*unit) {
case 'G':
case 'g':
value *= 1024*1024*1024;
break;
case 'M':
case 'm':
value *= 1024*1024;
break;
case 'K':
case 'k':
value *= 1024;
break;
case 'b':
case 'B':
/* for plain bytes, leave as-is */
break;
default:
warnf(global, "unsupported rate unit. Use G, M, K or B!\n");
return PARAM_BAD_USE;
}
config->recvpersecond = value; config->recvpersecond = value;
config->sendpersecond = value; config->sendpersecond = value;
} }
@ -753,9 +776,15 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
return PARAM_LIBCURL_DOESNT_SUPPORT; return PARAM_LIBCURL_DOESNT_SUPPORT;
break; break;
case 'y': /* --max-filesize */ case 'y': /* --max-filesize */
err = str2offset(&config->max_filesize, nextarg); {
if(err) curl_off_t value;
return err; ParameterError pe =
GetSizeParameter(global, nextarg, "max-filesize", &value);
if(pe != PARAM_OK)
return pe;
config->max_filesize = value;
}
break; break;
case 'z': /* --disable-eprt */ case 'z': /* --disable-eprt */
config->disable_eprt = toggle; config->disable_eprt = toggle;