00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tool_setup.h"
00023
00024 #define ENABLE_CURLX_PRINTF
00025
00026 #include "curlx.h"
00027
00028 #include "tool_cfgable.h"
00029 #include "tool_getparam.h"
00030 #include "tool_helpers.h"
00031 #include "tool_homedir.h"
00032 #include "tool_msgs.h"
00033 #include "tool_parsecfg.h"
00034
00035 #include "memdebug.h"
00036
00037 #define CURLRC DOT_CHAR "curlrc"
00038
00039
00040
00041 #define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':')))
00042
00043 static const char *unslashquote(const char *line, char *param);
00044 static char *my_get_line(FILE *fp);
00045
00046
00047 int parseconfig(const char *filename, struct GlobalConfig *global)
00048 {
00049 int res;
00050 FILE *file;
00051 char filebuffer[512];
00052 bool usedarg;
00053 char *home;
00054 int rc = 0;
00055 struct OperationConfig *operation = global->first;
00056
00057 if(!filename || !*filename) {
00058
00059
00060 #ifndef __AMIGA__
00061 filename = CURLRC;
00062 home = homedir();
00063 if(home) {
00064 if(strlen(home) < (sizeof(filebuffer) - strlen(CURLRC))) {
00065 snprintf(filebuffer, sizeof(filebuffer),
00066 "%s%s%s", home, DIR_CHAR, CURLRC);
00067
00068 #ifdef WIN32
00069
00070
00071
00072 file = fopen(filebuffer, FOPEN_READTEXT);
00073 if(file != NULL) {
00074 fclose(file);
00075 filename = filebuffer;
00076 }
00077 else {
00078
00079
00080
00081
00082 int n = GetModuleFileName(0, filebuffer, sizeof(filebuffer));
00083 if(n > 0 && n < (int)sizeof(filebuffer)) {
00084
00085 char *lastdirchar = strrchr(filebuffer, '\\');
00086 if(lastdirchar) {
00087 size_t remaining;
00088 *lastdirchar = 0;
00089
00090 remaining = sizeof(filebuffer) - strlen(filebuffer);
00091 if(strlen(CURLRC) < remaining - 1) {
00092 snprintf(lastdirchar, remaining,
00093 "%s%s", DIR_CHAR, CURLRC);
00094
00095
00096
00097 filename = filebuffer;
00098 }
00099 }
00100 }
00101 }
00102 #else
00103 filename = filebuffer;
00104 #endif
00105 }
00106 Curl_safefree(home);
00107 }
00108
00109 # else
00110
00111
00112 filename = "ENV:" CURLRC;
00113
00114 #endif
00115 }
00116
00117 if(strcmp(filename, "-"))
00118 file = fopen(filename, FOPEN_READTEXT);
00119 else
00120 file = stdin;
00121
00122 if(file) {
00123 char *line;
00124 char *aline;
00125 char *option;
00126 char *param;
00127 int lineno = 0;
00128 bool alloced_param;
00129 bool dashed_option;
00130
00131 while(NULL != (aline = my_get_line(file))) {
00132 lineno++;
00133 line = aline;
00134 alloced_param=FALSE;
00135
00136
00137 while(*line && ISSPACE(*line))
00138 line++;
00139
00140 switch(*line) {
00141 case '#':
00142 case '/':
00143 case '\r':
00144 case '\n':
00145 case '*':
00146 case '\0':
00147 Curl_safefree(aline);
00148 continue;
00149 }
00150
00151
00152 option = line;
00153
00154
00155 dashed_option = option[0]=='-'?TRUE:FALSE;
00156
00157 while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option))
00158 line++;
00159
00160
00161 if(*line)
00162 *line++ = '\0';
00163
00164 #ifdef DEBUG_CONFIG
00165 fprintf(stderr, "GOT: %s\n", option);
00166 #endif
00167
00168
00169 while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option)))
00170 line++;
00171
00172
00173 if(*line == '\"') {
00174
00175 line++;
00176 param = malloc(strlen(line) + 1);
00177 if(!param) {
00178
00179 Curl_safefree(aline);
00180 rc = 1;
00181 break;
00182 }
00183 alloced_param = TRUE;
00184 (void)unslashquote(line, param);
00185 }
00186 else {
00187 param = line;
00188 while(*line && !ISSPACE(*line))
00189 line++;
00190
00191 if(*line) {
00192 *line = '\0';
00193
00194
00195 line++;
00196
00197 while(*line && ISSPACE(*line))
00198 line++;
00199
00200 switch(*line) {
00201 case '\0':
00202 case '\r':
00203 case '\n':
00204 case '#':
00205 break;
00206 default:
00207 warnf(operation->global, "%s:%d: warning: '%s' uses unquoted "
00208 "white space in the line that may cause side-effects!\n",
00209 filename, lineno, option);
00210 }
00211 }
00212 if(!*param)
00213
00214
00215 param = NULL;
00216 }
00217
00218 #ifdef DEBUG_CONFIG
00219 fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)"));
00220 #endif
00221 res = getparameter(option, param, &usedarg, global, operation);
00222
00223 if(param && *param && !usedarg)
00224
00225 res = PARAM_GOT_EXTRA_PARAMETER;
00226
00227 if(res == PARAM_NEXT_OPERATION) {
00228 if(operation->url_list && operation->url_list->url) {
00229
00230 operation->next = malloc(sizeof(struct OperationConfig));
00231 if(operation->next) {
00232
00233 config_init(operation->next);
00234
00235
00236 operation->next->easy = global->easy;
00237
00238
00239 operation->next->global = global;
00240
00241
00242 global->last = operation->next;
00243
00244
00245 operation->next->prev = operation;
00246 operation = operation->next;
00247 }
00248 else
00249 res = PARAM_NO_MEM;
00250 }
00251 }
00252
00253 if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) {
00254
00255 if(!strcmp(filename, "-")) {
00256 filename = (char *)"<stdin>";
00257 }
00258 if(res != PARAM_HELP_REQUESTED &&
00259 res != PARAM_MANUAL_REQUESTED &&
00260 res != PARAM_VERSION_INFO_REQUESTED &&
00261 res != PARAM_ENGINES_REQUESTED) {
00262 const char *reason = param2text(res);
00263 warnf(operation->global, "%s:%d: warning: '%s' %s\n",
00264 filename, lineno, option, reason);
00265 }
00266 }
00267
00268 if(alloced_param)
00269 Curl_safefree(param);
00270
00271 Curl_safefree(aline);
00272 }
00273 if(file != stdin)
00274 fclose(file);
00275 }
00276 else
00277 rc = 1;
00278
00279 return rc;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 static const char *unslashquote(const char *line, char *param)
00290 {
00291 while(*line && (*line != '\"')) {
00292 if(*line == '\\') {
00293 char out;
00294 line++;
00295
00296
00297 switch(out = *line) {
00298 case '\0':
00299 continue;
00300 case 't':
00301 out = '\t';
00302 break;
00303 case 'n':
00304 out = '\n';
00305 break;
00306 case 'r':
00307 out = '\r';
00308 break;
00309 case 'v':
00310 out = '\v';
00311 break;
00312 }
00313 *param++ = out;
00314 line++;
00315 }
00316 else
00317 *param++ = *line++;
00318 }
00319 *param = '\0';
00320 return line;
00321 }
00322
00323
00324
00325
00326
00327
00328 static char *my_get_line(FILE *fp)
00329 {
00330 char buf[4096];
00331 char *nl = NULL;
00332 char *line = NULL;
00333
00334 do {
00335 if(NULL == fgets(buf, sizeof(buf), fp))
00336 break;
00337 if(!line) {
00338 line = strdup(buf);
00339 if(!line)
00340 return NULL;
00341 }
00342 else {
00343 char *ptr;
00344 size_t linelen = strlen(line);
00345 ptr = realloc(line, linelen + strlen(buf) + 1);
00346 if(!ptr) {
00347 Curl_safefree(line);
00348 return NULL;
00349 }
00350 line = ptr;
00351 strcpy(&line[linelen], buf);
00352 }
00353 nl = strchr(line, '\n');
00354 } while(!nl);
00355
00356 if(nl)
00357 *nl = '\0';
00358
00359 return line;
00360 }
00361