summaryrefslogtreecommitdiffstatsabout
path: root/utility/config.c
diff options
context:
space:
mode:
authorEdward Rudd <urkle@outoforder.cc>2008-10-22 12:40:58 (GMT)
committer Edward Rudd <urkle@outoforder.cc>2008-10-22 12:40:58 (GMT)
commit0ddd719a72469f732a881c93d4c804e9aca787fe (patch)
treee05821ff5a6ad0f00d63f23090ce4f2ec19bef75 /utility/config.c
parentcc75ebf7e8560a69a6847f0260cce4772fff440a (diff)
added more config options
included PCRE wrapper from httpd more complete log parser code. fixed NASTY bug with setting values in the hash tables (Need to DUP the strings before setting the keys)
Diffstat (limited to 'utility/config.c')
-rw-r--r--utility/config.c263
1 files changed, 190 insertions, 73 deletions
diff --git a/utility/config.c b/utility/config.c
index 6b3dce1..847d474 100644
--- a/utility/config.c
+++ b/utility/config.c
@@ -3,53 +3,61 @@
3#include "apr_file_io.h" 3#include "apr_file_io.h"
4#include "apr_strings.h" 4#include "apr_strings.h"
5#include "apr_hash.h" 5#include "apr_hash.h"
6#include "apr_lib.h" 6
7#include "shell.h" 7#include "shell.h"
8#include "config.h" 8#include "config.h"
9#include "util.h"
10#include "logparse.h"
9 11
10apr_hash_t *g_config_opts; 12apr_hash_t *g_config_opts;
11 13
12apr_status_t config_set_string(config_t *cfg, config_opt_t *opt, int argc, 14static apr_status_t config_set_string(config_t *cfg, config_opt_t *opt,
13 const char **argv) 15 int argc, const char **argv)
14{ 16{
15 int offset = (int)(long)opt->data; 17 int offset = (int)(long)opt->data;
16 char **data = (char **)((void *)cfg + offset); 18 char **data = (char **)((void *)cfg + offset);
17 if (argc != 2) return APR_EINVAL; 19 if (argc != 2)
20 return APR_EINVAL;
18 *data = apr_pstrdup(cfg->pool, argv[1]); 21 *data = apr_pstrdup(cfg->pool, argv[1]);
19 return APR_SUCCESS; 22 return APR_SUCCESS;
20} 23}
21 24
22apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, 25static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc,
26 const char **argv) __attribute__ ((__unused__));
27static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc,
23 const char **argv) 28 const char **argv)
24{ 29{
25 int offset = (int)(long)opt->data; 30 int offset = (int)(long)opt->data;
26 int *data = (int *)((void *)cfg + offset); 31 int *data = (int *)((void *)cfg + offset);
27 if (argc != 2) return APR_EINVAL; 32 if (argc != 2)
33 return APR_EINVAL;
28 *data = apr_atoi64(argv[1]); 34 *data = apr_atoi64(argv[1]);
29 return APR_SUCCESS; 35 return APR_SUCCESS;
30} 36}
31 37
32apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, 38static apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc,
33 const char **argv) 39 const char **argv)
34{ 40{
35 int offset = (int)(long)opt->data; 41 int offset = (int)(long)opt->data;
36 int *data = (int *)((void *)cfg + offset); 42 int *data = (int *)((void *)cfg + offset);
37 if (argc != 2) return APR_EINVAL; 43 if (argc != 2)
44 return APR_EINVAL;
38 *data = CHECK_YESNO(argv[1]); 45 *data = CHECK_YESNO(argv[1]);
39 return APR_SUCCESS; 46 return APR_SUCCESS;
40} 47}
41 48
42apr_status_t config_set_loglevel(config_t *cfg, config_opt_t *opt, int argc, 49static apr_status_t config_set_loglevel(config_t *cfg, config_opt_t *opt,
43 const char **argv) 50 int argc, const char **argv)
44{ 51{
45 if (argc != 2) return APR_EINVAL; 52 if (argc != 2)
46 if (!strcasecmp(argv[1],"error")) { 53 return APR_EINVAL;
54 if (!strcasecmp(argv[1], "error")) {
47 cfg->loglevel = LOGLEVEL_ERROR; 55 cfg->loglevel = LOGLEVEL_ERROR;
48 } else if (!strcasecmp(argv[1],"warn")) { 56 } else if (!strcasecmp(argv[1], "warn")) {
49 cfg->loglevel = LOGLEVEL_WARN; 57 cfg->loglevel = LOGLEVEL_WARN;
50 } else if (!strcasecmp(argv[1],"debug")) { 58 } else if (!strcasecmp(argv[1], "debug")) {
51 cfg->loglevel = LOGLEVEL_DEBUG; 59 cfg->loglevel = LOGLEVEL_DEBUG;
52 } else if (!strcasecmp(argv[1],"quiet")) { 60 } else if (!strcasecmp(argv[1], "quiet")) {
53 cfg->loglevel = LOGLEVEL_QUIET; 61 cfg->loglevel = LOGLEVEL_QUIET;
54 } else { 62 } else {
55 cfg->loglevel = LOGLEVEL_ERROR; 63 cfg->loglevel = LOGLEVEL_ERROR;
@@ -57,49 +65,51 @@ apr_status_t config_set_loglevel(config_t *cfg, config_opt_t *opt, int argc,
57 return APR_SUCCESS; 65 return APR_SUCCESS;
58} 66}
59 67
60apr_status_t config_set_dbconnect(config_t *cfg, config_opt_t *opt, int argc, 68static apr_status_t config_set_dbconnect(config_t *cfg, config_opt_t *opt,
61 const char **argv) 69 int argc, const char **argv)
62{ 70{
63 return APR_SUCCESS; 71 return APR_SUCCESS;
64} 72}
65 73
66apr_status_t config_set_dbparam(config_t *cfg, config_opt_t *opt, int argc, 74static apr_status_t config_set_dbparam(config_t *cfg, config_opt_t *opt,
67 const char **argv) 75 int argc, const char **argv)
68{ 76{
69 return APR_SUCCESS; 77 return APR_SUCCESS;
70} 78}
71 79
72apr_status_t config_set_inputfile(config_t *cfg, config_opt_t *opt, int argc, 80static apr_status_t config_set_inputfile(config_t *cfg, config_opt_t *opt,
73 const char **argv) 81 int argc, const char **argv)
74{ 82{
75 char **newp; 83 char **newp;
76 if (argc != 2) return APR_EINVAL; 84 if (argc != 2)
85 return APR_EINVAL;
77 newp = (char **)apr_array_push(cfg->input_files); 86 newp = (char **)apr_array_push(cfg->input_files);
78 *newp = apr_pstrdup(cfg->pool, argv[1]); 87 *newp = apr_pstrdup(cfg->pool, argv[1]);
79 return APR_SUCCESS; 88 return APR_SUCCESS;
80} 89}
81 90
82apr_status_t config_set_dummy(config_t *cfg, config_opt_t *opt, int argc, 91static apr_status_t config_set_dummy(config_t *cfg, config_opt_t *opt,
83 const char **argv) 92 int argc, const char **argv)
84{ 93{
85 return APR_SUCCESS; 94 return APR_SUCCESS;
86} 95}
87 96
88apr_status_t config_set_logformat(config_t *cfg, config_opt_t *opt, int argc, 97static apr_status_t config_set_logformat(config_t *cfg, config_opt_t *opt,
89 const char **argv) 98 int argc, const char **argv)
90{ 99{
91 config_logformat_t *format; 100 config_logformat_t *format;
92 config_logformat_field_t *field; 101 config_logformat_field_t *field;
93 102
94 if (argc != 4) return APR_EINVAL; 103 if (argc != 4)
104 return APR_EINVAL;
95 105
96 format = apr_hash_get(cfg->log_formats,argv[1],APR_HASH_KEY_STRING); 106 format = apr_hash_get(cfg->log_formats, argv[1], APR_HASH_KEY_STRING);
97 if (!format) { 107 if (!format) {
98 format = apr_palloc(cfg->pool, sizeof(config_logformat_t)); 108 format = apr_palloc(cfg->pool, sizeof(config_logformat_t));
99 format->name = apr_pstrdup(cfg->pool, argv[1]); 109 format->name = apr_pstrdup(cfg->pool, argv[1]);
100 format->fields = apr_array_make(cfg->pool, 5, 110 format->fields = apr_array_make(cfg->pool, 5,
101 sizeof(config_logformat_field_t)); 111 sizeof(config_logformat_field_t));
102 apr_hash_set(cfg->log_formats, argv[1], APR_HASH_KEY_STRING, format); 112 apr_hash_set(cfg->log_formats, apr_pstrdup(cfg->pool,argv[1]), APR_HASH_KEY_STRING, format);
103 } 113 }
104 field = (config_logformat_field_t *)apr_array_push(format->fields); 114 field = (config_logformat_field_t *)apr_array_push(format->fields);
105 field->name = apr_pstrdup(cfg->pool, argv[2]); 115 field->name = apr_pstrdup(cfg->pool, argv[2]);
@@ -107,18 +117,100 @@ apr_status_t config_set_logformat(config_t *cfg, config_opt_t *opt, int argc,
107 return APR_SUCCESS; 117 return APR_SUCCESS;
108} 118}
109 119
120static apr_status_t config_set_output_field(config_t *cfg, config_opt_t *opt,
121 int argc, const char **argv)
122{
123 config_output_field_t *field;
124 char *type, *size, *temp;
125
126 if (argc < 4)
127 return APR_EINVAL;
128 field = (config_output_field_t *)apr_array_push(cfg->output_fields);
129 field->field = apr_pstrdup(cfg->pool, argv[1]);
130 field->source = apr_pstrdup(cfg->pool, argv[3]);
131
132 type = size = apr_pstrdup(cfg->pool, argv[2]);
133 while (*size!='\0' && *size!='(')
134 size++;
135 if (*size == '(') {
136 *size = '\0';
137 size++;
138 temp = size;
139 while (*temp != '\0' && *temp != ')')
140 temp++;
141 *temp = '\0';
142 field->size = apr_atoi64(size);
143 }
144 if (strcasecmp("VARCHAR", type)==0) {
145 field->datatype = LOGSQL_DATATYPE_VARCHAR;
146 } else if (strcasecmp("INT", type)==0) {
147 field->datatype = LOGSQL_DATATYPE_INT;
148 } else if (strcasecmp("CHAR", type)==0) {
149 field->datatype = LOGSQL_DATATYPE_CHAR;
150 } else if (strcasecmp("SMALLINT", type)==0) {
151 field->datatype = LOGSQL_DATATYPE_SMALLINT;
152 } else if (strcasecmp("BIGINT", type)==0) {
153 field->datatype = LOGSQL_DATATYPE_BIGINT;
154 } else {
155 return APR_EINVAL;
156 }
157
158 // Has a function
159 if (argc > 4) {
160 int i;
161 field->fname = apr_pstrdup(cfg->pool, argv[4]);
162 field->func = parser_get_func(field->fname);
163 field->args = apr_pcalloc(cfg->pool, sizeof(char *) * (argc-4+1));
164 for (i=5; i<=argc; i++) {
165 field->args[i-5] = apr_pstrdup(cfg->pool, argv[i]);
166 }
167 }
168
169 return APR_SUCCESS;
170}
171
172static apr_status_t config_set_filter(config_t *cfg, config_opt_t *opt,
173 int argc, const char **argv)
174{
175 int argn = 1;
176 config_filter_t *filter;
177 filter = apr_pcalloc(cfg->pool, sizeof(config_filter_t));
178
179 if (opt->name[0]!='L') { // Pre or post 2-3 args
180 if (argc == 1)
181 return APR_EINVAL;
182 filter->field = apr_pstrdup(cfg->pool, argv[1]);
183 argn++;
184 } // Otherwise Line based only 1-2 args (no field)
185 if (argc <= argn)
186 return APR_EINVAL;
187 if (argv[argn][0] == '+')
188 argn++;
189 if (argv[argn][0] == '-') {
190 filter->negative = 1;
191 argn++;
192 }
193 if (argc <= argn)
194 return APR_EINVAL;
195 filter->filter = apr_pstrdup(cfg->pool, argv[argn]);
196 filter->regex = ap_pregcomp(cfg->pool, filter->filter, AP_REG_ICASE);
197 return APR_SUCCESS;
198}
199
110void config_dump(config_t *cfg) 200void config_dump(config_t *cfg)
111{ 201{
112 apr_hash_index_t *hi; 202 apr_hash_index_t *hi;
203 int i;
204 config_output_field_t *fields;
113 205
114 printf("ErrorLog: %s\n",cfg->errorlog); 206 printf("ErrorLog: %s\n", cfg->errorlog);
115 printf("LogLevel: %d\n",cfg->loglevel); 207 printf("LogLevel: %d\n", cfg->loglevel);
116 208
117 printf("InputDir: %s\n",cfg->input_dir); 209 printf("InputDir: %s\n", cfg->input_dir);
118 210
119 printf("Table: %s\n",cfg->table); 211 printf("Table: %s\n", cfg->table);
120 printf("Transactions: %d\n",cfg->transactions); 212 printf("Transactions: %d\n", cfg->transactions);
121 printf("MachineID: %s\n",cfg->machineid); 213 printf("MachineID: %s\n", cfg->machineid);
122 214
123 printf("Log formats:\n"); 215 printf("Log formats:\n");
124 for (hi = apr_hash_first(cfg->pool, cfg->log_formats); hi; hi 216 for (hi = apr_hash_first(cfg->pool, cfg->log_formats); hi; hi
@@ -128,31 +220,39 @@ void config_dump(config_t *cfg)
128 int i; 220 int i;
129 221
130 apr_hash_this(hi, NULL, NULL, (void **)&format); 222 apr_hash_this(hi, NULL, NULL, (void **)&format);
131 printf(">> %s\n",format->name); 223 printf(">> '%s'\n", format->name);
132 fields = (config_logformat_field_t *)format->fields->elts; 224 fields = (config_logformat_field_t *)format->fields->elts;
133 for (i=0; i<format->fields->nelts; i++) { 225 for (i=0; i<format->fields->nelts; i++) {
134 printf(">>>> %s:%s\n", fields[i].name, fields[i].datatype); 226 printf(">>>> %s:%s\n", fields[i].name, fields[i].datatype);
135 } 227 }
136 } 228 }
137 printf("Log Format: %s\n",cfg->logformat); 229 printf("Log Format: '%s'\n", cfg->logformat);
138 230
139 printf("DryRun: %d\n",cfg->dryrun); 231 printf("Output Fields:\n");
140 printf("Summary: %d\n",cfg->summary); 232 fields = (config_output_field_t *)cfg->output_fields->elts;
141} 233 for (i=0; i<cfg->output_fields->nelts; i++) {
142 234 printf(">> %s %s(%d): %s", fields[i].field, logsql_field_datatyeName(fields[i].datatype), fields[i].size, fields[i].source);
143static char *lowerstr(apr_pool_t *pool, const char *input) { 235 if (fields[i].func) {
144 char *temp; 236 printf(" :: %s(", fields[i].fname);
145 char *itr; 237 if (fields[i].args) {
146 temp = apr_pstrdup(pool, input); 238 int a = 0;
147 for (itr=temp; *itr!='\0'; itr++) { 239 while (fields[i].args[a]) {
148 *itr = apr_tolower(*itr); 240 printf("%s,", fields[i].args[a]);
241 a++;
242 }
243 }
244 printf(")");
149 } 245 }
150 return temp; 246 printf("\n");
247 }
248
249 printf("DryRun: %d\n", cfg->dryrun);
250 printf("Summary: %d\n", cfg->summary);
151} 251}
152 252
153#define config_get_option(name) apr_hash_get(g_config_opts, name, APR_HASH_KEY_STRING) 253#define config_get_option(name) apr_hash_get(g_config_opts, name, APR_HASH_KEY_STRING)
154 254
155void config_add_option(apr_pool_t *p, const char *const name, 255static void config_add_option(apr_pool_t *p, const char *const name,
156 const char *const help, config_func_t func, void *data) 256 const char *const help, config_func_t func, void *data)
157{ 257{
158 config_opt_t *opt; 258 config_opt_t *opt;
@@ -164,22 +264,24 @@ void config_add_option(apr_pool_t *p, const char *const name,
164 opt->help = help; 264 opt->help = help;
165 opt->func = func; 265 opt->func = func;
166 opt->data = data; 266 opt->data = data;
167 apr_hash_set(g_config_opts, lowerstr(p,name), APR_HASH_KEY_STRING, opt); 267 apr_hash_set(g_config_opts, lowerstr(p, name), APR_HASH_KEY_STRING, opt);
168} 268}
169 269
170void config_init(apr_pool_t *p) 270void config_init(apr_pool_t *p)
171{ 271{
172 config_add_option(p, "ErrorLog", "File to log errors", 272 config_add_option(p, "ErrorLog", "File to log errors", config_set_string,
173 config_set_string, (void *)APR_OFFSETOF(config_t, errorlog)); 273 (void *)APR_OFFSETOF(config_t, errorlog));
174 config_add_option(p, "LogLevel", "Set Log Level (error, warn, debug, quiet)", 274 config_add_option(p, "LogLevel",
175 config_set_loglevel, NULL); 275 "Set Log Level (error, warn, debug, quiet)", config_set_loglevel,
276 NULL);
176 277
177 config_add_option(p, "InputDirectory", "Directory to scan for log files", 278 config_add_option(p, "InputDirectory", "Directory to scan for log files",
178 config_set_string, (void *)APR_OFFSETOF(config_t, input_dir)); 279 config_set_string, (void *)APR_OFFSETOF(config_t, input_dir));
179 config_add_option(p, "InputFile", "Parse only this file", 280 config_add_option(p, "InputFile", "Parse only this file",
180 config_set_inputfile, NULL); 281 config_set_inputfile, NULL);
181 282
182 config_add_option(p, "DBConnect", "DB Connection information type://user:pass@hostname/database", 283 config_add_option(p, "DBConnect",
284 "DB Connection information type://user:pass@hostname/database",
183 config_set_dbconnect, NULL); 285 config_set_dbconnect, NULL);
184 config_add_option(p, "DBParam", "DB Connection Parameter", 286 config_add_option(p, "DBParam", "DB Connection Parameter",
185 config_set_dbparam, NULL); 287 config_set_dbparam, NULL);
@@ -187,14 +289,28 @@ void config_init(apr_pool_t *p)
187 config_set_string, (void *)APR_OFFSETOF(config_t, table)); 289 config_set_string, (void *)APR_OFFSETOF(config_t, table));
188 config_add_option(p, "UseTransactions", "Enable Transactions?", 290 config_add_option(p, "UseTransactions", "Enable Transactions?",
189 config_set_flag, (void *)APR_OFFSETOF(config_t, transactions)); 291 config_set_flag, (void *)APR_OFFSETOF(config_t, transactions));
190 config_add_option(p, "MachineID", "Machine ID to set", 292 config_add_option(p, "MachineID", "Machine ID to set", config_set_string,
191 config_set_string, (void *)APR_OFFSETOF(config_t, machineid)); 293 (void *)APR_OFFSETOF(config_t, machineid));
192 294
193 config_add_option(p, "LogFormatConfig", "Define input log formats", 295 config_add_option(p, "LogFormatConfig", "Define input log formats",
194 config_set_logformat, NULL); 296 config_set_logformat, NULL);
195 config_add_option(p, "LogFormat", "Use this logformat when parsing files", 297 config_add_option(p, "LogFormat", "Use this logformat when parsing files",
196 config_set_string, (void *)APR_OFFSETOF(config_t, logformat)); 298 config_set_string, (void *)APR_OFFSETOF(config_t, logformat));
197 299
300 config_add_option(p, "LineFilter",
301 "A regular expression to apply to the input line",
302 config_set_filter, (void *)APR_OFFSETOF(config_t, linefilters));
303 config_add_option(p, "PreFilter",
304 "A regular expression to apply to a specific input field",
305 config_set_filter, (void *)APR_OFFSETOF(config_t, prefilters));
306 config_add_option(p, "PostFilter",
307 "A regular expression to apply to a specific SQL output field",
308 config_set_filter, (void *)APR_OFFSETOF(config_t, postfilters));
309
310 config_add_option(p, "OutputField",
311 "Define output fields: field datatype source optfunc optarg...",
312 config_set_output_field, NULL);
313
198 config_add_option(p, "DryRun", "Don't perform any actual database changes", 314 config_add_option(p, "DryRun", "Don't perform any actual database changes",
199 config_set_flag, (void *)APR_OFFSETOF(config_t, dryrun)); 315 config_set_flag, (void *)APR_OFFSETOF(config_t, dryrun));
200 config_add_option(p, "Config", "Dummy to handle config directive", 316 config_add_option(p, "Config", "Dummy to handle config directive",
@@ -216,16 +332,20 @@ config_t *config_create(apr_pool_t *p)
216 cfg->input_files = apr_array_make(cfg->pool, 10, sizeof(char *)); 332 cfg->input_files = apr_array_make(cfg->pool, 10, sizeof(char *));
217 cfg->dbconfig = apr_table_make(cfg->pool, 5); 333 cfg->dbconfig = apr_table_make(cfg->pool, 5);
218 cfg->log_formats = apr_hash_make(cfg->pool); 334 cfg->log_formats = apr_hash_make(cfg->pool);
219 335 cfg->output_fields = apr_array_make(cfg->pool, 10,
336 sizeof(config_output_field_t));
220 return cfg; 337 return cfg;
221} 338}
222 339
223int config_merge(void *rec, const char *key, const char *value) { 340static int config_merge(void *rec, const char *key, const char *value)
341{
224 config_t *cfg = (config_t *)rec; 342 config_t *cfg = (config_t *)rec;
225 343
226 config_opt_t *opt = config_get_option(key); 344 config_opt_t *opt= config_get_option(key);
227 if (opt) { 345 if (opt) {
228 const char *args[] = {key, value}; 346 const char *args[] = {
347 key,
348 value };
229 opt->func(cfg, opt, 2, args); 349 opt->func(cfg, opt, 2, args);
230 } else { 350 } else {
231 printf("Unhandled: %s\n", key); 351 printf("Unhandled: %s\n", key);
@@ -238,11 +358,11 @@ apr_status_t config_read(config_t *cfg, const char *filename,
238{ 358{
239 apr_finfo_t finfo; 359 apr_finfo_t finfo;
240 apr_file_t *file; 360 apr_file_t *file;
241 apr_status_t rv, ret = APR_SUCCESS; 361 apr_status_t rv, ret= APR_SUCCESS;
242 apr_pool_t *tp, *targp; 362 apr_pool_t *tp, *targp;
243 config_opt_t *opt; 363 config_opt_t *opt;
244 char buff[1024]; 364 char buff[1024];
245 char *ptr, *ptr2; 365 char *ptr;
246 char **targv; 366 char **targv;
247 int targc; 367 int targc;
248 int line; 368 int line;
@@ -254,7 +374,7 @@ apr_status_t config_read(config_t *cfg, const char *filename,
254 return APR_ENOENT; 374 return APR_ENOENT;
255 } 375 }
256 rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, 376 rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED,
257 APR_OS_DEFAULT, tp); 377 APR_OS_DEFAULT, tp);
258 if (rv != APR_SUCCESS) 378 if (rv != APR_SUCCESS)
259 return rv; 379 return rv;
260 380
@@ -267,10 +387,7 @@ apr_status_t config_read(config_t *cfg, const char *filename,
267 // skip leading white space 387 // skip leading white space
268 for (ptr = buff; *ptr == ' ' || *ptr == '\t'; ptr++) 388 for (ptr = buff; *ptr == ' ' || *ptr == '\t'; ptr++)
269 ; 389 ;
270 // chomp off newline 390 line_chomp(ptr);
271 for (ptr2 = ptr + strlen(ptr); *ptr2 != '\r' && *ptr2 != '\n'; ptr2--)
272 ;
273 *ptr2 = '\0';
274 391
275 // skip comments 392 // skip comments
276 if (*ptr == '#') 393 if (*ptr == '#')
@@ -278,9 +395,10 @@ apr_status_t config_read(config_t *cfg, const char *filename,
278 if (*ptr == '\0') 395 if (*ptr == '\0')
279 continue; 396 continue;
280 apr_pool_clear(targp); 397 apr_pool_clear(targp);
281 apr_tokenize_to_argv(buff, &targv, targp); 398 apr_tokenize_to_argv(ptr, &targv, targp);
282 targc = 0; 399 targc = 0;
283 while (targv[targc]) targc++; 400 while (targv[targc])
401 targc++;
284 opt = config_get_option(lowerstr(targp,targv[0])); 402 opt = config_get_option(lowerstr(targp,targv[0]));
285 if (opt) { 403 if (opt) {
286 rv = opt->func(cfg, opt, targc, (const char **)targv); 404 rv = opt->func(cfg, opt, targc, (const char **)targv);
@@ -296,10 +414,9 @@ apr_status_t config_read(config_t *cfg, const char *filename,
296 } while (rv == APR_SUCCESS); 414 } while (rv == APR_SUCCESS);
297 415
298 // Apply merges 416 // Apply merges
299 apr_table_do(config_merge,(void *)cfg,merge,NULL); 417 apr_table_do(config_merge, (void *)cfg, merge, NULL);
300 418
301 apr_file_close(file); 419 apr_file_close(file);
302 apr_pool_destroy(tp); 420 apr_pool_destroy(tp);
303 return ret; 421 return ret;
304} 422}
305