Commit 859ac360 authored by Gisle Vanem's avatar Gisle Vanem Committed by Jay Satiro
Browse files

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
parent b399b049
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ your transfer not to use your entire bandwidth. To make it slower than it
otherwise would be.

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.

If you also use the --speed-limit option, that option will take precedence and
+4 −0
Original line number Diff line number Diff line
@@ -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
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
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.
+64 −35
Original line number Diff line number Diff line
@@ -424,6 +424,58 @@ GetFileAndPassword(char *nextarg, char **file, char **password)
  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 */
                            char *nextarg,    /* NULL if unset */
                            bool *usedarg,    /* set to TRUE if the arg
@@ -589,40 +641,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
        break;
      case 'i': /* --limit-rate */
      {
        /* We support G, M, K too */
        char *unit;
        curl_off_t value;
        if(curlx_strtoofft(nextarg, &unit, 0, &value)) {
          warnf(global, "unsupported rate\n");
          return PARAM_BAD_USE;
        }

        if(!*unit)
          unit = (char *)"b";
        else if(strlen(unit) > 1)
          unit = (char *)"w"; /* unsupported */
        ParameterError pe = GetSizeParameter(global, nextarg, "rate", &value);

        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;
        }
        if(pe != PARAM_OK)
           return pe;
        config->recvpersecond = value;
        config->sendpersecond = value;
      }
@@ -753,9 +776,15 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
          return PARAM_LIBCURL_DOESNT_SUPPORT;
        break;
      case 'y': /* --max-filesize */
        err = str2offset(&config->max_filesize, nextarg);
        if(err)
          return err;
        {
          curl_off_t value;
          ParameterError pe =
            GetSizeParameter(global, nextarg, "max-filesize", &value);

          if(pe != PARAM_OK)
             return pe;
          config->max_filesize = value;
        }
        break;
      case 'z': /* --disable-eprt */
        config->disable_eprt = toggle;