1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * _ _ ____ _ 3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Project ___| | | | _ \| | 4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * / __| | | | |_) | | 5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * | (__| |_| | _ <| |___ 6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * \___|\___/|_| \_\_____| 7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. 9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_setup.h" 23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define ENABLE_CURLX_PRINTF 25e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* use our own printf() functions */ 26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curlx.h" 27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_cfgable.h" 29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_getparam.h" 30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_helpers.h" 31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_homedir.h" 32e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_msgs.h" 33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_parsecfg.h" 34e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 35e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "memdebug.h" /* keep this as LAST include */ 36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define CURLRC DOT_CHAR "curlrc" 38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* only acknowledge colon or equals as separators if the option was not 40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET specified with an initial dash! */ 41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':'))) 42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const char *unslashquote(const char *line, char *param); 44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic char *my_get_line(FILE *fp); 45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* return 0 on everything-is-fine, and non-zero otherwise */ 47e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint parseconfig(const char *filename, struct GlobalConfig *global) 48e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int res; 50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET FILE *file; 51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char filebuffer[512]; 52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool usedarg; 53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *home; 54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int rc = 0; 55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct OperationConfig *operation = global->first; 56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!filename || !*filename) { 58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* NULL or no file name attempts to load .curlrc from the homedir! */ 59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifndef __AMIGA__ 61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = CURLRC; /* sensible default */ 62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET home = homedir(); /* portable homedir finder */ 63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(home) { 64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(strlen(home) < (sizeof(filebuffer) - strlen(CURLRC))) { 65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET snprintf(filebuffer, sizeof(filebuffer), 66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "%s%s%s", home, DIR_CHAR, CURLRC); 67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef WIN32 69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Check if the file exists - if not, try CURLRC in the same 70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * directory as our executable 71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET file = fopen(filebuffer, FOPEN_READTEXT); 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(file != NULL) { 74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fclose(file); 75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = filebuffer; 76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Get the filename of our executable. GetModuleFileName is 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * already declared via inclusions done in setup header file. 80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * We assume that we are using the ASCII version here. 81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int n = GetModuleFileName(0, filebuffer, sizeof(filebuffer)); 83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(n > 0 && n < (int)sizeof(filebuffer)) { 84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* We got a valid filename - get the directory part */ 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *lastdirchar = strrchr(filebuffer, '\\'); 86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(lastdirchar) { 87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t remaining; 88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *lastdirchar = 0; 89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* If we have enough space, build the RC filename */ 90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET remaining = sizeof(filebuffer) - strlen(filebuffer); 91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(strlen(CURLRC) < remaining - 1) { 92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET snprintf(lastdirchar, remaining, 93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "%s%s", DIR_CHAR, CURLRC); 94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Don't bother checking if it exists - we do 95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * that later 96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = filebuffer; 98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else /* WIN32 */ 103e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = filebuffer; 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif /* WIN32 */ 105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(home); /* we've used it, now free it */ 107e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# else /* __AMIGA__ */ 110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* On AmigaOS all the config files are into env: 111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = "ENV:" CURLRC; 113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 116e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(strcmp(filename, "-")) 118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET file = fopen(filename, FOPEN_READTEXT); 119e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 120e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET file = stdin; 121e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(file) { 123e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *line; 124e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *aline; 125e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *option; 126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *param; 127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int lineno = 0; 128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool alloced_param; 129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool dashed_option; 130e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(NULL != (aline = my_get_line(file))) { 132e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET lineno++; 133e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line = aline; 134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET alloced_param=FALSE; 135e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* line with # in the first non-blank column is a comment! */ 137e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && ISSPACE(*line)) 138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET switch(*line) { 141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '#': 142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '/': 143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\r': 144e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\n': 145e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '*': 146e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\0': 147e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(aline); 148e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET continue; 149e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 150e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 151e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* the option keywords starts here */ 152e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET option = line; 153e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 154e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* the option starts with a dash? */ 155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET dashed_option = option[0]=='-'?TRUE:FALSE; 156e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 157e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option)) 158e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 159e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* ... and has ended here */ 160e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(*line) 162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *line++ = '\0'; /* zero terminate, we have a local copy of the data */ 163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef DEBUG_CONFIG 165e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(stderr, "GOT: %s\n", option); 166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 168e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* pass spaces and separator(s) */ 169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option))) 170e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 171e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 172e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* the parameter starts here (unless quoted) */ 173e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(*line == '\"') { 174e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* quoted parameter, do the quote dance */ 175e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET param = malloc(strlen(line) + 1); /* parameter */ 177e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!param) { 178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* out of memory */ 179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(aline); 180e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rc = 1; 181e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 182e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 183e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET alloced_param = TRUE; 184e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)unslashquote(line, param); 185e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 186e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 187e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET param = line; /* parameter starts here */ 188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && !ISSPACE(*line)) 189e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 190e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(*line) { 192e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *line = '\0'; /* zero terminate */ 193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* to detect mistakes better, see if there's data following */ 195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* pass all spaces */ 197e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && ISSPACE(*line)) 198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 199e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 200e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET switch(*line) { 201e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\0': 202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\r': 203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\n': 204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '#': /* comment */ 205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET default: 207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET warnf(operation->global, "%s:%d: warning: '%s' uses unquoted " 208e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "white space in the line that may cause side-effects!\n", 209e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename, lineno, option); 210e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 211e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 212e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 213e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 214e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!*param) { 215e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* do this so getparameter can check for required parameters. 216e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Otherwise it always thinks there's a parameter. */ 217e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(alloced_param) 218e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(param); 219e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET param = NULL; 220e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 221e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 222e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef DEBUG_CONFIG 223e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)")); 224e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 225e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = getparameter(option, param, &usedarg, global, operation); 226e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 227e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(param && *param && !usedarg) 228e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* we passed in a parameter that wasn't used! */ 229e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = PARAM_GOT_EXTRA_PARAMETER; 230e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 231e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(res == PARAM_NEXT_OPERATION) { 232e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(operation->url_list && operation->url_list->url) { 233e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Allocate the next config */ 234e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET operation->next = malloc(sizeof(struct OperationConfig)); 235e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(operation->next) { 236e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Initialise the newly created config */ 237e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config_init(operation->next); 238e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 239e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Copy the easy handle */ 240e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET operation->next->easy = global->easy; 241e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 242e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Set the global config pointer */ 243e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET operation->next->global = global; 244e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 245e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Update the last operation pointer */ 246e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET global->last = operation->next; 247e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 248e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Move onto the new config */ 249e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET operation->next->prev = operation; 250e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET operation = operation->next; 251e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 252e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 253e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = PARAM_NO_MEM; 254e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 255e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 256e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 257e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) { 258e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* the help request isn't really an error */ 259e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!strcmp(filename, "-")) { 260e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename = (char *)"<stdin>"; 261e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 262e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(res != PARAM_HELP_REQUESTED && 263e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res != PARAM_MANUAL_REQUESTED && 264e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res != PARAM_VERSION_INFO_REQUESTED && 265e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res != PARAM_ENGINES_REQUESTED) { 266e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const char *reason = param2text(res); 267e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET warnf(operation->global, "%s:%d: warning: '%s' %s\n", 268e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename, lineno, option, reason); 269e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 270e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 271e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 272e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(alloced_param) 273e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(param); 274e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 275e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(aline); 276e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 277e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(file != stdin) 278e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fclose(file); 279e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 280e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 281e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rc = 1; /* couldn't open the file */ 282e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 283e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return rc; 284e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 285e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 286e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 287e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copies the string from line to the buffer at param, unquoting 288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * backslash-quoted characters and NUL-terminating the output string. 289e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Stops at the first non-backslash-quoted double quote character or the 290e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * end of the input string. param must be at least as long as the input 291e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * string. Returns the pointer after the last handled input character. 292e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 293e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const char *unslashquote(const char *line, char *param) 294e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 295e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(*line && (*line != '\"')) { 296e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(*line == '\\') { 297e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char out; 298e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 299e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 300e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* default is to output the letter after the backslash */ 301e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET switch(out = *line) { 302e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case '\0': 303e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET continue; /* this'll break out of the loop */ 304e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case 't': 305e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET out = '\t'; 306e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 307e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case 'n': 308e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET out = '\n'; 309e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 310e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case 'r': 311e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET out = '\r'; 312e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 313e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case 'v': 314e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET out = '\v'; 315e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 316e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 317e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *param++ = out; 318e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line++; 319e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 320e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 321e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *param++ = *line++; 322e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 323e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *param = '\0'; /* always zero terminate */ 324e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return line; 325e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 326e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 327e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 328e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Reads a line from the given file, ensuring is NUL terminated. 329e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * The pointer must be freed by the caller. 330e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * NULL is returned on an out of memory condition. 331e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 332e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic char *my_get_line(FILE *fp) 333e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 334e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char buf[4096]; 335e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *nl = NULL; 336e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *line = NULL; 337e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 338e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET do { 339e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(NULL == fgets(buf, sizeof(buf), fp)) 340e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 341e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!line) { 342e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line = strdup(buf); 343e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!line) 344e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 345e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 346e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 347e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *ptr; 348e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t linelen = strlen(line); 349e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ptr = realloc(line, linelen + strlen(buf) + 1); 350e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!ptr) { 351e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(line); 352e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 353e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 354e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET line = ptr; 355e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET strcpy(&line[linelen], buf); 356e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 357e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nl = strchr(line, '\n'); 358e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } while(!nl); 359e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 360e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(nl) 361e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *nl = '\0'; 362e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 363e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return line; 364e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 365e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 366