diff options
author | Edward Rudd <urkle@outoforder.cc> | 2008-10-22 12:40:58 (GMT) |
---|---|---|
committer | Edward Rudd <urkle@outoforder.cc> | 2008-10-22 12:40:58 (GMT) |
commit | 0ddd719a72469f732a881c93d4c804e9aca787fe (patch) | |
tree | e05821ff5a6ad0f00d63f23090ce4f2ec19bef75 /utility/config.c | |
parent | cc75ebf7e8560a69a6847f0260cce4772fff440a (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.c | 263 |
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 | ||
10 | apr_hash_t *g_config_opts; | 12 | apr_hash_t *g_config_opts; |
11 | 13 | ||
12 | apr_status_t config_set_string(config_t *cfg, config_opt_t *opt, int argc, | 14 | static 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 | ||
22 | apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, | 25 | static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, |
26 | const char **argv) __attribute__ ((__unused__)); | ||
27 | static 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 | ||
32 | apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, | 38 | static 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 | ||
42 | apr_status_t config_set_loglevel(config_t *cfg, config_opt_t *opt, int argc, | 49 | static 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 | ||
60 | apr_status_t config_set_dbconnect(config_t *cfg, config_opt_t *opt, int argc, | 68 | static 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 | ||
66 | apr_status_t config_set_dbparam(config_t *cfg, config_opt_t *opt, int argc, | 74 | static 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 | ||
72 | apr_status_t config_set_inputfile(config_t *cfg, config_opt_t *opt, int argc, | 80 | static 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 | ||
82 | apr_status_t config_set_dummy(config_t *cfg, config_opt_t *opt, int argc, | 91 | static 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 | ||
88 | apr_status_t config_set_logformat(config_t *cfg, config_opt_t *opt, int argc, | 97 | static 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 | ||
120 | static 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 | |||
172 | static 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 | |||
110 | void config_dump(config_t *cfg) | 200 | void 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); | |
143 | static 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 | ||
155 | void config_add_option(apr_pool_t *p, const char *const name, | 255 | static 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 | ||
170 | void config_init(apr_pool_t *p) | 270 | void 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 | ||
223 | int config_merge(void *rec, const char *key, const char *value) { | 340 | static 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 | |||