Annotation of embedaddon/curl/src/tool_paramhlp.c, revision 1.1

1.1     ! misho       1: /***************************************************************************
        !             2:  *                                  _   _ ____  _
        !             3:  *  Project                     ___| | | |  _ \| |
        !             4:  *                             / __| | | | |_) | |
        !             5:  *                            | (__| |_| |  _ <| |___
        !             6:  *                             \___|\___/|_| \_\_____|
        !             7:  *
        !             8:  * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
        !             9:  *
        !            10:  * This software is licensed as described in the file COPYING, which
        !            11:  * you should have received as part of this distribution. The terms
        !            12:  * are also available at https://curl.haxx.se/docs/copyright.html.
        !            13:  *
        !            14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
        !            15:  * copies of the Software, and permit persons to whom the Software is
        !            16:  * furnished to do so, under the terms of the COPYING file.
        !            17:  *
        !            18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
        !            19:  * KIND, either express or implied.
        !            20:  *
        !            21:  ***************************************************************************/
        !            22: #include "tool_setup.h"
        !            23: 
        !            24: #include "strcase.h"
        !            25: 
        !            26: #define ENABLE_CURLX_PRINTF
        !            27: /* use our own printf() functions */
        !            28: #include "curlx.h"
        !            29: 
        !            30: #include "tool_cfgable.h"
        !            31: #include "tool_getparam.h"
        !            32: #include "tool_getpass.h"
        !            33: #include "tool_homedir.h"
        !            34: #include "tool_msgs.h"
        !            35: #include "tool_paramhlp.h"
        !            36: #include "tool_version.h"
        !            37: 
        !            38: #include "memdebug.h" /* keep this as LAST include */
        !            39: 
        !            40: struct getout *new_getout(struct OperationConfig *config)
        !            41: {
        !            42:   struct getout *node = calloc(1, sizeof(struct getout));
        !            43:   struct getout *last = config->url_last;
        !            44:   if(node) {
        !            45:     /* append this new node last in the list */
        !            46:     if(last)
        !            47:       last->next = node;
        !            48:     else
        !            49:       config->url_list = node; /* first node */
        !            50: 
        !            51:     /* move the last pointer */
        !            52:     config->url_last = node;
        !            53: 
        !            54:     node->flags = config->default_node_flags;
        !            55:   }
        !            56:   return node;
        !            57: }
        !            58: 
        !            59: ParameterError file2string(char **bufp, FILE *file)
        !            60: {
        !            61:   char *string = NULL;
        !            62:   if(file) {
        !            63:     char *ptr;
        !            64:     size_t alloc = 512;
        !            65:     size_t alloc_needed;
        !            66:     char buffer[256];
        !            67:     size_t stringlen = 0;
        !            68:     string = calloc(1, alloc);
        !            69:     if(!string)
        !            70:       return PARAM_NO_MEM;
        !            71: 
        !            72:     while(fgets(buffer, sizeof(buffer), file)) {
        !            73:       size_t buflen;
        !            74:       ptr = strchr(buffer, '\r');
        !            75:       if(ptr)
        !            76:         *ptr = '\0';
        !            77:       ptr = strchr(buffer, '\n');
        !            78:       if(ptr)
        !            79:         *ptr = '\0';
        !            80:       buflen = strlen(buffer);
        !            81:       alloc_needed = stringlen + buflen + 1;
        !            82:       if(alloc < alloc_needed) {
        !            83: #if SIZEOF_SIZE_T < 8
        !            84:         if(alloc >= (size_t)SIZE_T_MAX/2) {
        !            85:           Curl_safefree(string);
        !            86:           return PARAM_NO_MEM;
        !            87:         }
        !            88: #endif
        !            89:         /* doubling is enough since the string to add is always max 256 bytes
        !            90:            and the alloc size start at 512 */
        !            91:         alloc *= 2;
        !            92:         ptr = realloc(string, alloc);
        !            93:         if(!ptr) {
        !            94:           Curl_safefree(string);
        !            95:           return PARAM_NO_MEM;
        !            96:         }
        !            97:         string = ptr;
        !            98:       }
        !            99:       strcpy(string + stringlen, buffer);
        !           100:       stringlen += buflen;
        !           101:     }
        !           102:   }
        !           103:   *bufp = string;
        !           104:   return PARAM_OK;
        !           105: }
        !           106: 
        !           107: ParameterError file2memory(char **bufp, size_t *size, FILE *file)
        !           108: {
        !           109:   char *newbuf;
        !           110:   char *buffer = NULL;
        !           111:   size_t nused = 0;
        !           112: 
        !           113:   if(file) {
        !           114:     size_t nread;
        !           115:     size_t alloc = 512;
        !           116:     do {
        !           117:       if(!buffer || (alloc == nused)) {
        !           118:         /* size_t overflow detection for huge files */
        !           119:         if(alloc + 1 > ((size_t)-1)/2) {
        !           120:           Curl_safefree(buffer);
        !           121:           return PARAM_NO_MEM;
        !           122:         }
        !           123:         alloc *= 2;
        !           124:         /* allocate an extra char, reserved space, for null termination */
        !           125:         newbuf = realloc(buffer, alloc + 1);
        !           126:         if(!newbuf) {
        !           127:           Curl_safefree(buffer);
        !           128:           return PARAM_NO_MEM;
        !           129:         }
        !           130:         buffer = newbuf;
        !           131:       }
        !           132:       nread = fread(buffer + nused, 1, alloc-nused, file);
        !           133:       nused += nread;
        !           134:     } while(nread);
        !           135:     /* null terminate the buffer in case it's used as a string later */
        !           136:     buffer[nused] = '\0';
        !           137:     /* free trailing slack space, if possible */
        !           138:     if(alloc != nused) {
        !           139:       newbuf = realloc(buffer, nused + 1);
        !           140:       if(!newbuf) {
        !           141:         Curl_safefree(buffer);
        !           142:         return PARAM_NO_MEM;
        !           143:       }
        !           144:       buffer = newbuf;
        !           145:     }
        !           146:     /* discard buffer if nothing was read */
        !           147:     if(!nused) {
        !           148:       Curl_safefree(buffer); /* no string */
        !           149:     }
        !           150:   }
        !           151:   *size = nused;
        !           152:   *bufp = buffer;
        !           153:   return PARAM_OK;
        !           154: }
        !           155: 
        !           156: void cleanarg(char *str)
        !           157: {
        !           158: #ifdef HAVE_WRITABLE_ARGV
        !           159:   /* now that GetStr has copied the contents of nextarg, wipe the next
        !           160:    * argument out so that the username:password isn't displayed in the
        !           161:    * system process list */
        !           162:   if(str) {
        !           163:     size_t len = strlen(str);
        !           164:     memset(str, ' ', len);
        !           165:   }
        !           166: #else
        !           167:   (void)str;
        !           168: #endif
        !           169: }
        !           170: 
        !           171: /*
        !           172:  * Parse the string and write the long in the given address. Return PARAM_OK
        !           173:  * on success, otherwise a parameter specific error enum.
        !           174:  *
        !           175:  * Since this function gets called with the 'nextarg' pointer from within the
        !           176:  * getparameter a lot, we must check it for NULL before accessing the str
        !           177:  * data.
        !           178:  */
        !           179: 
        !           180: ParameterError str2num(long *val, const char *str)
        !           181: {
        !           182:   if(str) {
        !           183:     char *endptr;
        !           184:     long num;
        !           185:     errno = 0;
        !           186:     num = strtol(str, &endptr, 10);
        !           187:     if(errno == ERANGE)
        !           188:       return PARAM_NUMBER_TOO_LARGE;
        !           189:     if((endptr != str) && (endptr == str + strlen(str))) {
        !           190:       *val = num;
        !           191:       return PARAM_OK;  /* Ok */
        !           192:     }
        !           193:   }
        !           194:   return PARAM_BAD_NUMERIC; /* badness */
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * Parse the string and write the long in the given address. Return PARAM_OK
        !           199:  * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
        !           200:  *
        !           201:  * Since this function gets called with the 'nextarg' pointer from within the
        !           202:  * getparameter a lot, we must check it for NULL before accessing the str
        !           203:  * data.
        !           204:  */
        !           205: 
        !           206: ParameterError str2unum(long *val, const char *str)
        !           207: {
        !           208:   ParameterError result = str2num(val, str);
        !           209:   if(result != PARAM_OK)
        !           210:     return result;
        !           211:   if(*val < 0)
        !           212:     return PARAM_NEGATIVE_NUMERIC;
        !           213: 
        !           214:   return PARAM_OK;
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * Parse the string and write the long in the given address if it is below the
        !           219:  * maximum allowed value. Return PARAM_OK on success, otherwise a parameter
        !           220:  * error enum. ONLY ACCEPTS POSITIVE NUMBERS!
        !           221:  *
        !           222:  * Since this function gets called with the 'nextarg' pointer from within the
        !           223:  * getparameter a lot, we must check it for NULL before accessing the str
        !           224:  * data.
        !           225:  */
        !           226: 
        !           227: ParameterError str2unummax(long *val, const char *str, long max)
        !           228: {
        !           229:   ParameterError result = str2unum(val, str);
        !           230:   if(result != PARAM_OK)
        !           231:     return result;
        !           232:   if(*val > max)
        !           233:     return PARAM_NUMBER_TOO_LARGE;
        !           234: 
        !           235:   return PARAM_OK;
        !           236: }
        !           237: 
        !           238: 
        !           239: /*
        !           240:  * Parse the string and write the double in the given address. Return PARAM_OK
        !           241:  * on success, otherwise a parameter specific error enum.
        !           242:  *
        !           243:  * The 'max' argument is the maximum value allowed, as the numbers are often
        !           244:  * multiplied when later used.
        !           245:  *
        !           246:  * Since this function gets called with the 'nextarg' pointer from within the
        !           247:  * getparameter a lot, we must check it for NULL before accessing the str
        !           248:  * data.
        !           249:  */
        !           250: 
        !           251: static ParameterError str2double(double *val, const char *str, long max)
        !           252: {
        !           253:   if(str) {
        !           254:     char *endptr;
        !           255:     double num;
        !           256:     errno = 0;
        !           257:     num = strtod(str, &endptr);
        !           258:     if(errno == ERANGE)
        !           259:       return PARAM_NUMBER_TOO_LARGE;
        !           260:     if(num > max) {
        !           261:       /* too large */
        !           262:       return PARAM_NUMBER_TOO_LARGE;
        !           263:     }
        !           264:     if((endptr != str) && (endptr == str + strlen(str))) {
        !           265:       *val = num;
        !           266:       return PARAM_OK;  /* Ok */
        !           267:     }
        !           268:   }
        !           269:   return PARAM_BAD_NUMERIC; /* badness */
        !           270: }
        !           271: 
        !           272: /*
        !           273:  * Parse the string and write the double in the given address. Return PARAM_OK
        !           274:  * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
        !           275:  *
        !           276:  * The 'max' argument is the maximum value allowed, as the numbers are often
        !           277:  * multiplied when later used.
        !           278:  *
        !           279:  * Since this function gets called with the 'nextarg' pointer from within the
        !           280:  * getparameter a lot, we must check it for NULL before accessing the str
        !           281:  * data.
        !           282:  */
        !           283: 
        !           284: ParameterError str2udouble(double *valp, const char *str, long max)
        !           285: {
        !           286:   double value;
        !           287:   ParameterError result = str2double(&value, str, max);
        !           288:   if(result != PARAM_OK)
        !           289:     return result;
        !           290:   if(value < 0)
        !           291:     return PARAM_NEGATIVE_NUMERIC;
        !           292: 
        !           293:   *valp = value;
        !           294:   return PARAM_OK;
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * Parse the string and modify the long in the given address. Return
        !           299:  * non-zero on failure, zero on success.
        !           300:  *
        !           301:  * The string is a list of protocols
        !           302:  *
        !           303:  * Since this function gets called with the 'nextarg' pointer from within the
        !           304:  * getparameter a lot, we must check it for NULL before accessing the str
        !           305:  * data.
        !           306:  */
        !           307: 
        !           308: long proto2num(struct OperationConfig *config, long *val, const char *str)
        !           309: {
        !           310:   char *buffer;
        !           311:   const char *sep = ",";
        !           312:   char *token;
        !           313: 
        !           314:   static struct sprotos {
        !           315:     const char *name;
        !           316:     long bit;
        !           317:   } const protos[] = {
        !           318:     { "all", CURLPROTO_ALL },
        !           319:     { "http", CURLPROTO_HTTP },
        !           320:     { "https", CURLPROTO_HTTPS },
        !           321:     { "ftp", CURLPROTO_FTP },
        !           322:     { "ftps", CURLPROTO_FTPS },
        !           323:     { "scp", CURLPROTO_SCP },
        !           324:     { "sftp", CURLPROTO_SFTP },
        !           325:     { "telnet", CURLPROTO_TELNET },
        !           326:     { "ldap", CURLPROTO_LDAP },
        !           327:     { "ldaps", CURLPROTO_LDAPS },
        !           328:     { "dict", CURLPROTO_DICT },
        !           329:     { "file", CURLPROTO_FILE },
        !           330:     { "tftp", CURLPROTO_TFTP },
        !           331:     { "imap", CURLPROTO_IMAP },
        !           332:     { "imaps", CURLPROTO_IMAPS },
        !           333:     { "pop3", CURLPROTO_POP3 },
        !           334:     { "pop3s", CURLPROTO_POP3S },
        !           335:     { "smtp", CURLPROTO_SMTP },
        !           336:     { "smtps", CURLPROTO_SMTPS },
        !           337:     { "rtsp", CURLPROTO_RTSP },
        !           338:     { "gopher", CURLPROTO_GOPHER },
        !           339:     { "smb", CURLPROTO_SMB },
        !           340:     { "smbs", CURLPROTO_SMBS },
        !           341:     { NULL, 0 }
        !           342:   };
        !           343: 
        !           344:   if(!str)
        !           345:     return 1;
        !           346: 
        !           347:   buffer = strdup(str); /* because strtok corrupts it */
        !           348:   if(!buffer)
        !           349:     return 1;
        !           350: 
        !           351:   /* Allow strtok() here since this isn't used threaded */
        !           352:   /* !checksrc! disable BANNEDFUNC 2 */
        !           353:   for(token = strtok(buffer, sep);
        !           354:       token;
        !           355:       token = strtok(NULL, sep)) {
        !           356:     enum e_action { allow, deny, set } action = allow;
        !           357: 
        !           358:     struct sprotos const *pp;
        !           359: 
        !           360:     /* Process token modifiers */
        !           361:     while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
        !           362:       switch (*token++) {
        !           363:       case '=':
        !           364:         action = set;
        !           365:         break;
        !           366:       case '-':
        !           367:         action = deny;
        !           368:         break;
        !           369:       case '+':
        !           370:         action = allow;
        !           371:         break;
        !           372:       default: /* Includes case of terminating NULL */
        !           373:         Curl_safefree(buffer);
        !           374:         return 1;
        !           375:       }
        !           376:     }
        !           377: 
        !           378:     for(pp = protos; pp->name; pp++) {
        !           379:       if(curl_strequal(token, pp->name)) {
        !           380:         switch(action) {
        !           381:         case deny:
        !           382:           *val &= ~(pp->bit);
        !           383:           break;
        !           384:         case allow:
        !           385:           *val |= pp->bit;
        !           386:           break;
        !           387:         case set:
        !           388:           *val = pp->bit;
        !           389:           break;
        !           390:         }
        !           391:         break;
        !           392:       }
        !           393:     }
        !           394: 
        !           395:     if(!(pp->name)) { /* unknown protocol */
        !           396:       /* If they have specified only this protocol, we say treat it as
        !           397:          if no protocols are allowed */
        !           398:       if(action == set)
        !           399:         *val = 0;
        !           400:       warnf(config->global, "unrecognized protocol '%s'\n", token);
        !           401:     }
        !           402:   }
        !           403:   Curl_safefree(buffer);
        !           404:   return 0;
        !           405: }
        !           406: 
        !           407: /**
        !           408:  * Check if the given string is a protocol supported by libcurl
        !           409:  *
        !           410:  * @param str  the protocol name
        !           411:  * @return PARAM_OK  protocol supported
        !           412:  * @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL  protocol not supported
        !           413:  * @return PARAM_REQUIRES_PARAMETER   missing parameter
        !           414:  */
        !           415: int check_protocol(const char *str)
        !           416: {
        !           417:   const char * const *pp;
        !           418:   const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW);
        !           419:   if(!str)
        !           420:     return PARAM_REQUIRES_PARAMETER;
        !           421:   for(pp = curlinfo->protocols; *pp; pp++) {
        !           422:     if(curl_strequal(*pp, str))
        !           423:       return PARAM_OK;
        !           424:   }
        !           425:   return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
        !           426: }
        !           427: 
        !           428: /**
        !           429:  * Parses the given string looking for an offset (which may be a
        !           430:  * larger-than-integer value). The offset CANNOT be negative!
        !           431:  *
        !           432:  * @param val  the offset to populate
        !           433:  * @param str  the buffer containing the offset
        !           434:  * @return PARAM_OK if successful, a parameter specific error enum if failure.
        !           435:  */
        !           436: ParameterError str2offset(curl_off_t *val, const char *str)
        !           437: {
        !           438:   char *endptr;
        !           439:   if(str[0] == '-')
        !           440:     /* offsets aren't negative, this indicates weird input */
        !           441:     return PARAM_NEGATIVE_NUMERIC;
        !           442: 
        !           443: #if(SIZEOF_CURL_OFF_T > SIZEOF_LONG)
        !           444:   {
        !           445:     CURLofft offt = curlx_strtoofft(str, &endptr, 0, val);
        !           446:     if(CURL_OFFT_FLOW == offt)
        !           447:       return PARAM_NUMBER_TOO_LARGE;
        !           448:     else if(CURL_OFFT_INVAL == offt)
        !           449:       return PARAM_BAD_NUMERIC;
        !           450:   }
        !           451: #else
        !           452:   errno = 0;
        !           453:   *val = strtol(str, &endptr, 0);
        !           454:   if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
        !           455:     return PARAM_NUMBER_TOO_LARGE;
        !           456: #endif
        !           457:   if((endptr != str) && (endptr == str + strlen(str)))
        !           458:     return PARAM_OK;
        !           459: 
        !           460:   return PARAM_BAD_NUMERIC;
        !           461: }
        !           462: 
        !           463: static CURLcode checkpasswd(const char *kind, /* for what purpose */
        !           464:                             const size_t i,   /* operation index */
        !           465:                             const bool last,  /* TRUE if last operation */
        !           466:                             char **userpwd)   /* pointer to allocated string */
        !           467: {
        !           468:   char *psep;
        !           469:   char *osep;
        !           470: 
        !           471:   if(!*userpwd)
        !           472:     return CURLE_OK;
        !           473: 
        !           474:   /* Attempt to find the password separator */
        !           475:   psep = strchr(*userpwd, ':');
        !           476: 
        !           477:   /* Attempt to find the options separator */
        !           478:   osep = strchr(*userpwd, ';');
        !           479: 
        !           480:   if(!psep && **userpwd != ';') {
        !           481:     /* no password present, prompt for one */
        !           482:     char passwd[256] = "";
        !           483:     char prompt[256];
        !           484:     size_t passwdlen;
        !           485:     size_t userlen = strlen(*userpwd);
        !           486:     char *passptr;
        !           487: 
        !           488:     if(osep)
        !           489:       *osep = '\0';
        !           490: 
        !           491:     /* build a nice-looking prompt */
        !           492:     if(!i && last)
        !           493:       curlx_msnprintf(prompt, sizeof(prompt),
        !           494:                       "Enter %s password for user '%s':",
        !           495:                       kind, *userpwd);
        !           496:     else
        !           497:       curlx_msnprintf(prompt, sizeof(prompt),
        !           498:                       "Enter %s password for user '%s' on URL #%zu:",
        !           499:                       kind, *userpwd, i + 1);
        !           500: 
        !           501:     /* get password */
        !           502:     getpass_r(prompt, passwd, sizeof(passwd));
        !           503:     passwdlen = strlen(passwd);
        !           504: 
        !           505:     if(osep)
        !           506:       *osep = ';';
        !           507: 
        !           508:     /* extend the allocated memory area to fit the password too */
        !           509:     passptr = realloc(*userpwd,
        !           510:                       passwdlen + 1 + /* an extra for the colon */
        !           511:                       userlen + 1);   /* an extra for the zero */
        !           512:     if(!passptr)
        !           513:       return CURLE_OUT_OF_MEMORY;
        !           514: 
        !           515:     /* append the password separated with a colon */
        !           516:     passptr[userlen] = ':';
        !           517:     memcpy(&passptr[userlen + 1], passwd, passwdlen + 1);
        !           518:     *userpwd = passptr;
        !           519:   }
        !           520: 
        !           521:   return CURLE_OK;
        !           522: }
        !           523: 
        !           524: ParameterError add2list(struct curl_slist **list, const char *ptr)
        !           525: {
        !           526:   struct curl_slist *newlist = curl_slist_append(*list, ptr);
        !           527:   if(newlist)
        !           528:     *list = newlist;
        !           529:   else
        !           530:     return PARAM_NO_MEM;
        !           531: 
        !           532:   return PARAM_OK;
        !           533: }
        !           534: 
        !           535: int ftpfilemethod(struct OperationConfig *config, const char *str)
        !           536: {
        !           537:   if(curl_strequal("singlecwd", str))
        !           538:     return CURLFTPMETHOD_SINGLECWD;
        !           539:   if(curl_strequal("nocwd", str))
        !           540:     return CURLFTPMETHOD_NOCWD;
        !           541:   if(curl_strequal("multicwd", str))
        !           542:     return CURLFTPMETHOD_MULTICWD;
        !           543: 
        !           544:   warnf(config->global, "unrecognized ftp file method '%s', using default\n",
        !           545:         str);
        !           546: 
        !           547:   return CURLFTPMETHOD_MULTICWD;
        !           548: }
        !           549: 
        !           550: int ftpcccmethod(struct OperationConfig *config, const char *str)
        !           551: {
        !           552:   if(curl_strequal("passive", str))
        !           553:     return CURLFTPSSL_CCC_PASSIVE;
        !           554:   if(curl_strequal("active", str))
        !           555:     return CURLFTPSSL_CCC_ACTIVE;
        !           556: 
        !           557:   warnf(config->global, "unrecognized ftp CCC method '%s', using default\n",
        !           558:         str);
        !           559: 
        !           560:   return CURLFTPSSL_CCC_PASSIVE;
        !           561: }
        !           562: 
        !           563: long delegation(struct OperationConfig *config, const char *str)
        !           564: {
        !           565:   if(curl_strequal("none", str))
        !           566:     return CURLGSSAPI_DELEGATION_NONE;
        !           567:   if(curl_strequal("policy", str))
        !           568:     return CURLGSSAPI_DELEGATION_POLICY_FLAG;
        !           569:   if(curl_strequal("always", str))
        !           570:     return CURLGSSAPI_DELEGATION_FLAG;
        !           571: 
        !           572:   warnf(config->global, "unrecognized delegation method '%s', using none\n",
        !           573:         str);
        !           574: 
        !           575:   return CURLGSSAPI_DELEGATION_NONE;
        !           576: }
        !           577: 
        !           578: /*
        !           579:  * my_useragent: returns allocated string with default user agent
        !           580:  */
        !           581: static char *my_useragent(void)
        !           582: {
        !           583:   return strdup(CURL_NAME "/" CURL_VERSION);
        !           584: }
        !           585: 
        !           586: CURLcode get_args(struct OperationConfig *config, const size_t i)
        !           587: {
        !           588:   CURLcode result = CURLE_OK;
        !           589:   bool last = (config->next ? FALSE : TRUE);
        !           590: 
        !           591:   /* Check we have a password for the given host user */
        !           592:   if(config->userpwd && !config->oauth_bearer) {
        !           593:     result = checkpasswd("host", i, last, &config->userpwd);
        !           594:     if(result)
        !           595:       return result;
        !           596:   }
        !           597: 
        !           598:   /* Check we have a password for the given proxy user */
        !           599:   if(config->proxyuserpwd) {
        !           600:     result = checkpasswd("proxy", i, last, &config->proxyuserpwd);
        !           601:     if(result)
        !           602:       return result;
        !           603:   }
        !           604: 
        !           605:   /* Check we have a user agent */
        !           606:   if(!config->useragent) {
        !           607:     config->useragent = my_useragent();
        !           608:     if(!config->useragent) {
        !           609:       errorf(config->global, "out of memory\n");
        !           610:       result = CURLE_OUT_OF_MEMORY;
        !           611:     }
        !           612:   }
        !           613: 
        !           614:   return result;
        !           615: }
        !           616: 
        !           617: /*
        !           618:  * Parse the string and modify ssl_version in the val argument. Return PARAM_OK
        !           619:  * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
        !           620:  *
        !           621:  * Since this function gets called with the 'nextarg' pointer from within the
        !           622:  * getparameter a lot, we must check it for NULL before accessing the str
        !           623:  * data.
        !           624:  */
        !           625: 
        !           626: ParameterError str2tls_max(long *val, const char *str)
        !           627: {
        !           628:    static struct s_tls_max {
        !           629:     const char *tls_max_str;
        !           630:     long tls_max;
        !           631:   } const tls_max_array[] = {
        !           632:     { "default", CURL_SSLVERSION_MAX_DEFAULT },
        !           633:     { "1.0",     CURL_SSLVERSION_MAX_TLSv1_0 },
        !           634:     { "1.1",     CURL_SSLVERSION_MAX_TLSv1_1 },
        !           635:     { "1.2",     CURL_SSLVERSION_MAX_TLSv1_2 },
        !           636:     { "1.3",     CURL_SSLVERSION_MAX_TLSv1_3 }
        !           637:   };
        !           638:   size_t i = 0;
        !           639:   if(!str)
        !           640:     return PARAM_REQUIRES_PARAMETER;
        !           641:   for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
        !           642:     if(!strcmp(str, tls_max_array[i].tls_max_str)) {
        !           643:       *val = tls_max_array[i].tls_max;
        !           644:       return PARAM_OK;
        !           645:     }
        !           646:   }
        !           647:   return PARAM_BAD_USE;
        !           648: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>