Base code merged to SPIN 2.4
[platform/upstream/curl.git] / src / tool_getparam.c
index 05dd648..5b60c9c 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, 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
 /* use our own printf() functions */
 #include "curlx.h"
 
-#ifdef USE_MANUAL
-#  include "tool_hugehelp.h"
-#endif
-
 #include "tool_binmode.h"
 #include "tool_cfgable.h"
 #include "tool_cb_prg.h"
 #include "tool_formparse.h"
 #include "tool_getparam.h"
-#include "tool_help.h"
 #include "tool_helpers.h"
 #include "tool_libinfo.h"
 #include "tool_metalink.h"
@@ -181,6 +176,7 @@ static const struct LongShort aliases[]= {
   {"$J", "metalink",                 FALSE},
   {"$K", "sasl-ir",                  FALSE},
   {"$L", "test-event",               FALSE},
+  {"$M", "unix-socket",              TRUE},
   {"0",   "http1.0",                 FALSE},
   {"01",  "http1.1",                 FALSE},
   {"02",  "http2",                   FALSE},
@@ -220,6 +216,8 @@ static const struct LongShort aliases[]= {
   {"Em", "tlsauthtype",              TRUE},
   {"En", "ssl-allow-beast",          FALSE},
   {"Eo", "login-options",            TRUE},
+  {"Ep", "pinnedpubkey",             TRUE},
+  {"Eq", "cert-status",              FALSE},
   {"f",  "fail",                     FALSE},
   {"F",  "form",                     TRUE},
   {"Fs", "form-string",              TRUE},
@@ -227,6 +225,7 @@ static const struct LongShort aliases[]= {
   {"G",  "get",                      FALSE},
   {"h",  "help",                     FALSE},
   {"H",  "header",                   TRUE},
+  {"Hp", "proxy-header",             TRUE},
   {"i",  "include",                  FALSE},
   {"I",  "head",                     FALSE},
   {"j",  "junk-session-cookies",     FALSE},
@@ -272,6 +271,7 @@ static const struct LongShort aliases[]= {
   {"y",  "speed-time",               TRUE},
   {"z",  "time-cond",                TRUE},
   {"#",  "progress-bar",             FALSE},
+  {":",  "next",                     FALSE},
   {"~",  "xattr",                    FALSE},
 };
 
@@ -378,7 +378,8 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
                             char *nextarg, /* NULL if unset */
                             bool *usedarg, /* set to TRUE if the arg
                                               has been used */
-                            struct Configurable *config)
+                            struct GlobalConfig *global,
+                            struct OperationConfig *config)
 {
   char letter;
   char subletter = '\0'; /* subletters can only occur on long options */
@@ -439,12 +440,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
     /* we can loop here if we have multiple single-letters */
 
     if(!longopt) {
-      if(NULL != parse) {
-        letter = (char)*parse;
-      }
-      else {
-        letter = '\0';
-      }
+      letter = (char)*parse;
       subletter='\0';
     }
     else {
@@ -525,20 +521,20 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         GetStr(&config->dns_servers, nextarg);
         break;
       case 'g': /* --trace */
-        GetStr(&config->trace_dump, nextarg);
-        if(config->tracetype && (config->tracetype != TRACE_BIN))
+        GetStr(&global->trace_dump, nextarg);
+        if(global->tracetype && (global->tracetype != TRACE_BIN))
           warnf(config, "--trace overrides an earlier trace/verbose option\n");
-        config->tracetype = TRACE_BIN;
+        global->tracetype = TRACE_BIN;
         break;
       case 'G': /* --npn */
         config->nonpn = (!toggle)?TRUE:FALSE;
         break;
       case 'h': /* --trace-ascii */
-        GetStr(&config->trace_dump, nextarg);
-        if(config->tracetype && (config->tracetype != TRACE_ASCII))
+        GetStr(&global->trace_dump, nextarg);
+        if(global->tracetype && (global->tracetype != TRACE_ASCII))
           warnf(config,
                 "--trace-ascii overrides an earlier trace/verbose option\n");
-        config->tracetype = TRACE_ASCII;
+        global->tracetype = TRACE_ASCII;
         break;
       case 'H': /* --alpn */
         config->noalpn = (!toggle)?TRUE:FALSE;
@@ -599,13 +595,13 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
 
       case 'l': /* --negotiate */
         if(toggle) {
-          if(curlinfo->features & CURL_VERSION_GSSNEGOTIATE)
-            config->authtype |= CURLAUTH_GSSNEGOTIATE;
+          if(curlinfo->features & CURL_VERSION_SPNEGO)
+            config->authtype |= CURLAUTH_NEGOTIATE;
           else
             return PARAM_LIBCURL_DOESNT_SUPPORT;
         }
         else
-          config->authtype &= ~CURLAUTH_GSSNEGOTIATE;
+          config->authtype &= ~CURLAUTH_NEGOTIATE;
         break;
 
       case 'm': /* --ntlm */
@@ -684,14 +680,14 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
           if(!newfile)
             warnf(config, "Failed to open %s!\n", nextarg);
           else {
-            if(config->errors_fopened)
-              fclose(config->errors);
-            config->errors = newfile;
-            config->errors_fopened = TRUE;
+            if(global->errors_fopened)
+              fclose(global->errors);
+            global->errors = newfile;
+            global->errors_fopened = TRUE;
           }
         }
         else
-          config->errors = stdout;
+          global->errors = stdout;
         break;
       case 'w': /* --interface */
         /* interface */
@@ -699,8 +695,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         break;
       case 'x': /* --krb */
         /* kerberos level string */
-        if(curlinfo->features & (CURL_VERSION_KERBEROS4 |
-                                 CURL_VERSION_GSSNEGOTIATE))
+        if(curlinfo->features & CURL_VERSION_KERBEROS4)
           GetStr(&config->krblevel, nextarg);
         else
           return PARAM_LIBCURL_DOESNT_SUPPORT;
@@ -800,11 +795,12 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         break;
 
       case 'k': /* --proxy-negotiate */
-        if(curlinfo->features & CURL_VERSION_GSSNEGOTIATE)
+        if(curlinfo->features & CURL_VERSION_SPNEGO)
           config->proxynegotiate = toggle;
         else
           return PARAM_LIBCURL_DOESNT_SUPPORT;
         break;
+
       case 'm': /* --ftp-account */
         GetStr(&config->ftp_account, nextarg);
         break;
@@ -812,7 +808,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         config->proxyanyauth = toggle;
         break;
       case 'o': /* --trace-time */
-        config->tracetime = toggle;
+        global->tracetime = toggle;
         break;
       case 'p': /* --ignore-content-length */
         config->ignorecl = toggle;
@@ -870,7 +866,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
               "--libcurl option was disabled at build-time!\n");
         return PARAM_OPTION_UNKNOWN;
 #else
-        GetStr(&config->libcurl, nextarg);
+        GetStr(&global->libcurl, nextarg);
         break;
 #endif
       case '#': /* --raw */
@@ -982,14 +978,19 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         warnf(config, "--test-event is ignored unless a debug build!\n");
 #endif
         break;
+      case 'M': /* --unix-socket */
+        GetStr(&config->unix_socket_path, nextarg);
+        break;
       }
       break;
     case '#': /* --progress-bar */
       if(toggle)
-        config->progressmode = CURL_PROGRESS_BAR;
+        global->progressmode = CURL_PROGRESS_BAR;
       else
-        config->progressmode = CURL_PROGRESS_STATS;
+        global->progressmode = CURL_PROGRESS_STATS;
       break;
+    case ':': /* --next */
+      return PARAM_NEXT_OPERATION;
     case '~': /* --xattr */
       config->xattr = toggle;
       break;
@@ -1239,7 +1240,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
            &-letter */
         char *oldpost = config->postfields;
         curl_off_t oldlen = config->postfieldsize;
-        curl_off_t newlen = oldlen + size + 2;
+        curl_off_t newlen = oldlen + curlx_uztoso(size) + 2;
         config->postfields = malloc((size_t)newlen);
         if(!config->postfields) {
           Curl_safefree(oldpost);
@@ -1257,7 +1258,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       }
       else {
         config->postfields = postdata;
-        config->postfieldsize = size;
+        config->postfieldsize = curlx_uztoso(size);
       }
     }
     /*
@@ -1358,6 +1359,15 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         GetStr(&config->login_options, nextarg);
         break;
 
+      case 'p': /* Pinned public key DER file */
+        /* Pinned public key DER file */
+        GetStr(&config->pinnedpubkey, nextarg);
+        break;
+
+      case 'q': /* --cert-status */
+        config->verifystatus = TRUE;
+        break;
+
       default: /* certificate file */
       {
         char *certname, *passphrase;
@@ -1399,14 +1409,16 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
 
     case 'h': /* h for help */
       if(toggle) {
-        tool_help();
         return PARAM_HELP_REQUESTED;
       }
       /* we now actually support --no-help too! */
       break;
     case 'H':
       /* A custom header to append to a list */
-      err = add2list(&config->headers, nextarg);
+      if(subletter == 'p') /* --proxy-header */
+        err = add2list(&config->proxyheaders, nextarg);
+      else
+        err = add2list(&config->headers, nextarg);
       if(err)
         return err;
       break;
@@ -1439,7 +1451,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       config->insecure_ok = toggle;
       break;
     case 'K': /* parse config file */
-      if(parseconfig(nextarg, config))
+      if(parseconfig(nextarg, global))
         warnf(config, "error trying read config from the '%s' file\n",
               nextarg);
       break;
@@ -1465,8 +1477,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
     case 'M': /* M for manual, huge help */
       if(toggle) { /* --no-manual shows no manual... */
 #ifdef USE_MANUAL
-        hugehelp();
-        return PARAM_HELP_REQUESTED;
+        return PARAM_MANUAL_REQUESTED;
 #else
         warnf(config,
               "built-in manual was disabled at build-time!\n");
@@ -1622,18 +1633,18 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
     case 's':
       /* don't show progress meter, don't show errors : */
       if(toggle)
-        config->mute = config->noprogress = TRUE;
+        global->mute = global->noprogress = TRUE;
       else
-        config->mute = config->noprogress = FALSE;
-      if(config->showerror < 0)
+        global->mute = global->noprogress = FALSE;
+      if(global->showerror < 0)
         /* if still on the default value, set showerror to the reverse of
            toggle. This is to allow -S and -s to be used in an independent
            order but still have the same effect. */
-        config->showerror = (!toggle)?TRUE:FALSE; /* toggle off */
+        global->showerror = (!toggle)?TRUE:FALSE; /* toggle off */
       break;
     case 'S':
       /* show errors */
-      config->showerror = toggle?1:0; /* toggle on if used with -s */
+      global->showerror = toggle?1:0; /* toggle on if used with -s */
       break;
     case 't':
       /* Telnet options */
@@ -1687,24 +1698,22 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
     case 'v':
       if(toggle) {
         /* the '%' thing here will cause the trace get sent to stderr */
-        Curl_safefree(config->trace_dump);
-        config->trace_dump = strdup("%");
-        if(!config->trace_dump)
+        Curl_safefree(global->trace_dump);
+        global->trace_dump = strdup("%");
+        if(!global->trace_dump)
           return PARAM_NO_MEM;
-        if(config->tracetype && (config->tracetype != TRACE_PLAIN))
+        if(global->tracetype && (global->tracetype != TRACE_PLAIN))
           warnf(config,
                 "-v, --verbose overrides an earlier trace/verbose option\n");
-        config->tracetype = TRACE_PLAIN;
+        global->tracetype = TRACE_PLAIN;
       }
       else
         /* verbose is disabled here */
-        config->tracetype = TRACE_NONE;
+        global->tracetype = TRACE_NONE;
       break;
     case 'V':
-      if(toggle) {  /* --no-version yields no output! */
-        tool_version_info();
-        return PARAM_HELP_REQUESTED;
-      }
+      if(toggle)    /* --no-version yields no output! */
+        return PARAM_VERSION_INFO_REQUESTED;
       break;
 
     case 'w':
@@ -1763,6 +1772,7 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       switch(*nextarg) {
       case '+':
         nextarg++;
+        /* FALLTHROUGH */
       default:
         /* If-Modified-Since: (section 14.28 in RFC2068) */
         config->timecond = CURL_TIMECOND_IFMODSINCE;
@@ -1807,40 +1817,19 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
   return PARAM_OK;
 }
 
-ParameterError parse_args(struct Configurable *config, int argc,
+ParameterError parse_args(struct GlobalConfig *config, int argc,
                           argv_item_t argv[])
 {
   int i;
   bool stillflags;
-  char *orig_opt;
+  char *orig_opt = NULL;
   ParameterError result = PARAM_OK;
+  struct OperationConfig *operation = config->first;
 
   for(i = 1, stillflags = TRUE; i < argc && !result; i++) {
     orig_opt = argv[i];
 
-    if(curlx_strequal(":", argv[i]) &&
-       (config->url_list && config->url_list->url)) {
-
-      /* Allocate the next config */
-      config->next = malloc(sizeof(struct Configurable));
-      if(config->next) {
-        /* Initialise the newly created config */
-        config_init(config->next);
-
-        /* Copy the easy handle */
-        config->next->easy = config->easy;
-
-        /* Move onto the new config */
-        config->next->prev = config;
-        config = config->next;
-
-        /* Reset the flag indicator */
-        stillflags = TRUE;
-      }
-      else
-        result = PARAM_NO_MEM;
-    }
-    else if(stillflags && ('-' == argv[i][0])) {
+    if(stillflags && ('-' == argv[i][0])) {
       char *nextarg;
       bool passarg;
       char *flag = argv[i];
@@ -1852,8 +1841,37 @@ ParameterError parse_args(struct Configurable *config, int argc,
       else {
         nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL;
 
-        result = getparameter(flag, nextarg, &passarg, config);
-        if(!result && passarg)
+        result = getparameter(flag, nextarg, &passarg, config, operation);
+        if(result == PARAM_NEXT_OPERATION) {
+          /* Reset result as PARAM_NEXT_OPERATION is only used here and not
+             returned from this function */
+          result = PARAM_OK;
+
+          if(operation->url_list && operation->url_list->url) {
+            /* Allocate the next config */
+            operation->next = malloc(sizeof(struct OperationConfig));
+            if(operation->next) {
+              /* Initialise the newly created config */
+              config_init(operation->next);
+
+              /* Copy the easy handle */
+              operation->next->easy = config->easy;
+
+              /* Set the global config pointer */
+              operation->next->global = config;
+
+              /* Update the last operation pointer */
+              config->last = operation->next;
+
+              /* Move onto the new config */
+              operation->next->prev = operation;
+              operation = operation->next;
+            }
+            else
+              result = PARAM_NO_MEM;
+          }
+        }
+        else if(!result && passarg)
           i++; /* we're supposed to skip this */
       }
     }
@@ -1861,15 +1879,18 @@ ParameterError parse_args(struct Configurable *config, int argc,
       bool used;
 
       /* Just add the URL please */
-      result = getparameter((char *)"--url", argv[i], &used, config);
+      result = getparameter((char *)"--url", argv[i], &used, config,
+                            operation);
     }
   }
 
   if(result && result != PARAM_HELP_REQUESTED &&
+     result != PARAM_MANUAL_REQUESTED &&
+     result != PARAM_VERSION_INFO_REQUESTED &&
      result != PARAM_ENGINES_REQUESTED) {
     const char *reason = param2text(result);
 
-    if(!curlx_strequal(":", orig_opt))
+    if(orig_opt && !curlx_strequal(":", orig_opt))
       helpf(config->errors, "option %s: %s\n", orig_opt, reason);
     else
       helpf(config->errors, "%s\n", reason);