summaryrefslogtreecommitdiffstats
path: root/mod_log_sql.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r--mod_log_sql.c992
1 files changed, 532 insertions, 460 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c
index fc9dcc0..7320f66 100644
--- a/mod_log_sql.c
+++ b/mod_log_sql.c
@@ -1,4 +1,19 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.14 2004/02/05 21:59:46 urkle Exp $ */
2/* --------*
3 * DEFINES *
4 * --------*/
5
6/* The enduser may wish to modify this */
7#define DEBUG
8
9/* The enduser won't modify these */
10#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
11
12/* ---------*
13 * INCLUDES *
14 * ---------*/
15#include "mysql.h"
16#include "mysqld_error.h"
2 17
3#if defined(WITH_APACHE20) 18#if defined(WITH_APACHE20)
4# include "apache20.h" 19# include "apache20.h"
@@ -36,7 +51,7 @@
36#define DEFAULT_HIN_TABLE_NAME "headers_in" 51#define DEFAULT_HIN_TABLE_NAME "headers_in"
37#define DEFAULT_HOUT_TABLE_NAME "headers_out" 52#define DEFAULT_HOUT_TABLE_NAME "headers_out"
38#define DEFAULT_COOKIE_TABLE_NAME "cookies" 53#define DEFAULT_COOKIE_TABLE_NAME "cookies"
39#define DEFAULT_PRESERVE_FILE "logs/mod_log_sql-preserve" 54#define DEFAULT_PRESERVE_FILE "/tmp/sql-preserve"
40 55
41/* -------------* 56/* -------------*
42 * DECLARATIONS * 57 * DECLARATIONS *
@@ -54,11 +69,17 @@ typedef struct {
54 int massvirtual; 69 int massvirtual;
55 int createtables; 70 int createtables;
56 int forcepreserve; 71 int forcepreserve;
57 int disablepreserve; 72 char *tabletype;
73 char *dbname;
74 char *dbhost;
75 char *dbuser;
76 char *dbpwd;
58 char *machid; 77 char *machid;
59 int announce; 78 char *socketfile;
60 logsql_dbconnection db; 79 unsigned int tcpport;
61 logsql_dbdriver *driver; 80 int insertdelayed;
81 MYSQL server;
82 MYSQL *server_p;
62} global_config_t; 83} global_config_t;
63 84
64static global_config_t global_config; 85static global_config_t global_config;
@@ -66,11 +87,11 @@ static global_config_t global_config;
66/* structure to hold helper function info */ 87/* structure to hold helper function info */
67typedef struct { 88typedef struct {
68 char key; /* item letter character */ 89 char key; /* item letter character */
69 logsql_item_func *func; /* its extraction function */ 90 log_sql_item_func *func; /* its extraction function */
70 const char *sql_field_name; /* its column in SQL */ 91 const char *sql_field_name; /* its column in SQL */
71 int want_orig_default; /* if it requires the original request prior to internal redirection */ 92 int want_orig_default; /* if it requires the original request prior to internal redirection */
72 int string_contents; /* if it returns a string */ 93 int string_contents; /* if it returns a string */
73} logsql_item; 94} log_sql_item;
74 95
75/* But the contents of this structure will vary by virtual server. 96/* But the contents of this structure will vary by virtual server.
76 * This permits each virtual server to vary its configuration slightly 97 * This permits each virtual server to vary its configuration slightly
@@ -93,28 +114,33 @@ typedef struct {
93 const char *transfer_table_name; 114 const char *transfer_table_name;
94 const char *transfer_log_format; 115 const char *transfer_log_format;
95 apr_pool_t *parsed_pool; 116 apr_pool_t *parsed_pool;
96 logsql_item **parsed_log_format; 117 log_sql_item **parsed_log_format;
97 const char *preserve_file; 118 const char *preserve_file;
98 const char *cookie_name; 119 const char *cookie_name;
99} logsql_state; 120} logsql_state;
100 121
101 122
102/* list of "handlers" for log types */ 123/* -----------------*
103static apr_array_header_t *logsql_item_list; 124 * HELPER FUNCTIONS *
125 * -----------------*/
126
127static int safe_create_tables(logsql_state *cls, request_rec *r);
104 128
105/* Registration function for extract functions * 129static apr_array_header_t *log_sql_item_list;
130
131/* Registration Function for extract functions *
106 * and update parse cache for transfer_log_format * 132 * and update parse cache for transfer_log_format *
107 * this is exported from the module */ 133 * this is exported from the module */
108LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p, 134LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p,
109 char key, logsql_item_func *func, const char *sql_field_name, 135 char key, log_sql_item_func *func, const char *sql_field_name,
110 int want_orig_default, int string_contents) 136 int want_orig_default, int string_contents)
111{ 137{
112 server_rec *ts; 138 server_rec *ts;
113 logsql_item *item; 139 log_sql_item *item;
114 if (!logsql_item_list) 140 if (!log_sql_item_list)
115 logsql_item_list = apr_array_make(p,10, sizeof(logsql_item)); 141 log_sql_item_list = apr_array_make(p,10, sizeof(log_sql_item));
116 142
117 item= apr_array_push(logsql_item_list); 143 item= apr_array_push(log_sql_item_list);
118 item->key = key; 144 item->key = key;
119 item->func = func; 145 item->func = func;
120 item->sql_field_name = sql_field_name; 146 item->sql_field_name = sql_field_name;
@@ -128,21 +154,14 @@ LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p,
128 char *pos; 154 char *pos;
129 155
130 if (cfg->transfer_log_format) { 156 if (cfg->transfer_log_format) {
131 if ( (pos = ap_strchr_c(cfg->transfer_log_format,key))!=NULL) { 157 if ( (pos = strchr(cfg->transfer_log_format,key))!=NULL) {
132 cfg->parsed_log_format[pos - cfg->transfer_log_format] = item; 158 cfg->parsed_log_format[pos - cfg->transfer_log_format] = item;
133 } 159 }
134 } 160 }
135 } 161 }
136} 162}
137 163
138/* Registration function for database drivers */ 164/* Include all the extract functions */
139LOGSQL_DECLARE(void) log_sql_register_driver(apr_pool_t *p,
140 logsql_dbdriver *driver)
141{
142 global_config.driver = driver;
143}
144
145/* Include all the core extract functions */
146#include "functions.h" 165#include "functions.h"
147#if defined(WITH_APACHE13) 166#if defined(WITH_APACHE13)
148# include "functions13.h" 167# include "functions13.h"
@@ -150,33 +169,82 @@ LOGSQL_DECLARE(void) log_sql_register_driver(apr_pool_t *p,
150# include "functions20.h" 169# include "functions20.h"
151#endif 170#endif
152 171
153static logsql_opendb_ret log_sql_opendb_link(server_rec* s) 172/* Routine to escape the 'dangerous' characters that would otherwise
173 * corrupt the INSERT string: ', \, and "
174 */
175static const char *escape_query(const char *from_str, apr_pool_t *p)
154{ 176{
155 logsql_opendb_ret result; 177 if (!from_str)
156 if (global_config.forcepreserve) { 178 return NULL;
157 global_config.db.connected = 1; 179 else {
158 return LOGSQL_OPENDB_PRESERVE; 180 char *to_str;
159 } 181 unsigned long length = strlen(from_str);
160 if (global_config.db.connected) { 182 unsigned long retval;
161 return LOGSQL_OPENDB_ALREADY; 183
184 /* Pre-allocate a new string that could hold twice the original, which would only
185 * happen if the whole original string was 'dangerous' characters.
186 */
187 to_str = (char *) apr_palloc(p, length * 2 + 1);
188 if (!to_str) {
189 return from_str;
190 }
191
192 if (!global_config.server_p) {
193 /* Well, I would have liked to use the current database charset. mysql is
194 * unavailable, however, so I fall back to the slightly less respectful
195 * mysql_escape_string() function that uses the default charset.
196 */
197 retval = mysql_escape_string(to_str, from_str, length);
198 } else {
199 /* MySQL is available, so I'll go ahead and respect the current charset when
200 * I perform the escape.
201 */
202 retval = mysql_real_escape_string(global_config.server_p, to_str, from_str, length);
203 }
204
205 if (retval)
206 return to_str;
207 else
208 return from_str;
162 } 209 }
163 /* database 210}
164 host 211
165 user 212static int open_logdb_link(server_rec* s)
166 passwd 213{
214 /* Returns:
215 3 if preserve forced
216 2 if already connected
217 1 if successful
218 0 if unsuccessful
167 */ 219 */
168 if (global_config.db.parms) { 220
169 result = global_config.driver->connect(s, &global_config.db); 221 if (global_config.forcepreserve)
170 if (result==LOGSQL_OPENDB_FAIL) { 222 return 3;
171 global_config.db.connected = 0; 223
224 if (global_config.server_p)
225 return 2;
226
227 if ((global_config.dbname) && (global_config.dbhost) && (global_config.dbuser) && (global_config.dbpwd)) {
228 mysql_init(&global_config.server);
229 global_config.server_p = mysql_real_connect(&global_config.server, global_config.dbhost, global_config.dbuser, global_config.dbpwd, global_config.dbname, global_config.tcpport, global_config.socketfile, 0);
230
231 if (global_config.server_p) {
232 #ifdef DEBUG
233 log_error(APLOG_MARK,APLOG_DEBUG,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
234 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
235 #endif
236 return 1;
172 } else { 237 } else {
173 global_config.db.connected = 1; 238 #ifdef DEBUG
239 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&global_config.server));
240 log_error(APLOG_MARK,APLOG_DEBUG,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
241 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
242 #endif
243 return 0;
174 } 244 }
175 return result;
176 } else { 245 } else {
177 log_error(APLOG_MARK, APLOG_ERR, 0, s, 246 log_error(APLOG_MARK,APLOG_ERR,s,"mod_log_sql: insufficient configuration info to establish database link");
178 "mod_log_sql: insufficient configuration info to establish database link"); 247 return 0;
179 return LOGSQL_OPENDB_FAIL;
180 } 248 }
181} 249}
182 250
@@ -194,22 +262,15 @@ static void preserve_entry(request_rec *r, const char *query)
194 #if defined(WITH_APACHE20) 262 #if defined(WITH_APACHE20)
195 apr_file_t *fp; 263 apr_file_t *fp;
196 apr_status_t result; 264 apr_status_t result;
265 result = apr_file_open(&fp, cls->preserve_file,APR_APPEND, APR_OS_DEFAULT, r->pool);
197 #elif defined(WITH_APACHE13) 266 #elif defined(WITH_APACHE13)
198 FILE *fp; 267 FILE *fp;
199 int result; 268 int result;
200 #endif
201 /* If preserve file is disabled bail out */
202 if (global_config.disablepreserve)
203 return;
204 #if defined(WITH_APACHE20)
205 result = apr_file_open(&fp, cls->preserve_file,APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, r->pool);
206 #elif defined(WITH_APACHE13)
207 fp = ap_pfopen(r->pool, cls->preserve_file, "a"); 269 fp = ap_pfopen(r->pool, cls->preserve_file, "a");
208 result = (fp)?0:errno; 270 result = (fp)?0:1;
209 #endif 271 #endif
210 if (result != APR_SUCCESS) { 272 if (result != APR_SUCCESS) {
211 log_error(APLOG_MARK, APLOG_ERR, result, r->server, 273 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: attempted append of local preserve file but failed.");
212 "attempted append of local preserve file '%s' but failed.",cls->preserve_file);
213 } else { 274 } else {
214 #if defined(WITH_APACHE20) 275 #if defined(WITH_APACHE20)
215 apr_file_printf(fp,"%s;\n", query); 276 apr_file_printf(fp,"%s;\n", query);
@@ -218,12 +279,252 @@ static void preserve_entry(request_rec *r, const char *query)
218 fprintf(fp,"%s;\n", query); 279 fprintf(fp,"%s;\n", query);
219 ap_pfclose(r->pool, fp); 280 ap_pfclose(r->pool, fp);
220 #endif 281 #endif
221 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 282 #ifdef DEBUG
222 "mod_log_sql: entry preserved in %s", cls->preserve_file); 283 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file);
284 #endif
223 } 285 }
224} 286}
225 287
226 288
289/*-----------------------------------------------------*
290 * safe_sql_query: perform a database query with *
291 * a degree of safety and error checking. *
292 * *
293 * Parms: request record, SQL insert statement *
294 * Returns: 0 (OK) on success *
295 * 1 if have no log handle *
296 * 2 if insert delayed failed (kluge) *
297 * the actual MySQL return code on error *
298 *-----------------------------------------------------*/
299static unsigned int safe_sql_query(request_rec *r, const char *query)
300{
301 int retval;
302 struct timespec delay, remainder;
303 int ret;
304 void (*handler) (int);
305 logsql_state *cls;
306 unsigned int real_error = 0;
307 const char *real_error_str = NULL;
308
309 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
310 handler = signal(SIGPIPE, SIG_IGN);
311
312 /* First attempt for the query */
313 if (!global_config.server_p) {
314 signal(SIGPIPE, handler);
315 return 1;
316 } else if (!(retval = mysql_query(global_config.server_p, query))) {
317 signal(SIGPIPE, handler);
318 return 0;
319 }
320
321 /* If we ran the query and it returned an error, try to be robust.
322 * (After all, the module thought it had a valid mysql_log connection but the query
323 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
324 if (global_config.insertdelayed) {
325 real_error_str = MYSQL_ERROR(global_config.server_p);
326 } else {
327 real_error = mysql_errno(global_config.server_p);
328 }
329
330 /* Check to see if the error is "nonexistent table" */
331 if (global_config.insertdelayed) {
332 retval = (strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"));
333 } else {
334 retval = (real_error == ER_NO_SUCH_TABLE);
335 }
336 if (retval) {
337 if (global_config.createtables) {
338 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: table doesn't exist...creating now");
339 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
340 if (safe_create_tables(cls, r)) {
341 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r));
342 preserve_entry(r, query);
343 retval = mysql_errno(global_config.server_p);
344 } else {
345 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: tables successfully created - retrying query");
346 if (mysql_query(global_config.server_p, query)) {
347 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: giving up, preserving query");
348 preserve_entry(r, query);
349 retval = mysql_errno(global_config.server_p);
350 } else
351 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: query successful after table creation");
352 retval = 0;
353 }
354 } else {
355 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query");
356 preserve_entry(r, query);
357 retval = ER_NO_SUCH_TABLE;
358 }
359 /* Restore SIGPIPE to its original handler function */
360 signal(SIGPIPE, handler);
361 return retval;
362 }
363
364 /* Handle all other types of errors */
365
366 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
367
368 /* Something went wrong, so start by trying to restart the db link. */
369 if (global_config.insertdelayed) {
370 real_error = 2;
371 } else {
372 real_error = mysql_errno(global_config.server_p);
373 }
374
375 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: first attempt failed, API said: error %d, \"%s\"", real_error, MYSQL_ERROR(global_config.server_p));
376 mysql_close(global_config.server_p);
377 global_config.server_p = NULL;
378 open_logdb_link(r->server);
379
380 if (global_config.server_p == NULL) { /* still unable to link */
381 signal(SIGPIPE, handler);
382 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection.");
383 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file);
384 return 1;
385 } else
386 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: db reconnect successful");
387
388 /* First sleep for a tiny amount of time. */
389 delay.tv_sec = 0;
390 delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */
391 ret = nanosleep(&delay, &remainder);
392 if (ret && errno != EINTR)
393 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: nanosleep unsuccessful");
394
395 /* Then make our second attempt */
396 retval = mysql_query(global_config.server_p,query);
397
398 /* If this one also failed, log that and append to our local offline file */
399 if (retval) {
400 if (global_config.insertdelayed) {
401 real_error = 2;
402 } else {
403 real_error = mysql_errno(global_config.server_p);
404 }
405
406 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(global_config.server_p));
407 preserve_entry(r, query);
408 retval = real_error;
409 } else
410 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: second attempt successful");
411
412 /* Restore SIGPIPE to its original handler function */
413 signal(SIGPIPE, handler);
414 return retval;
415}
416
417/*-----------------------------------------------------*
418 * safe_create_tables: create SQL table set for the *
419 * virtual server represented by cls. *
420 * *
421 * Parms: virtserver structure, request record *
422 * Returns: 0 on no errors *
423 * mysql error code on failure *
424 *-----------------------------------------------------*/
425static int safe_create_tables(logsql_state *cls, request_rec *r)
426{
427 int retval;
428 unsigned int create_results;
429 char *create_access = NULL;
430 char *create_notes = NULL;
431 char *create_hout = NULL;
432 char *create_hin = NULL;
433 char *create_cookies = NULL;
434
435 char *type_suffix = NULL;
436
437 char *createprefix = "create table if not exists `";
438 char *access_suffix =
439 "` (id char(19),\
440 agent varchar(255),\
441 bytes_sent int unsigned,\
442 child_pid smallint unsigned,\
443 cookie varchar(255),\
444 machine_id varchar(25),\
445 request_file varchar(255),\
446 referer varchar(255),\
447 remote_host varchar(50),\
448 remote_logname varchar(50),\
449 remote_user varchar(50),\
450 request_duration smallint unsigned,\
451 request_line varchar(255),\
452 request_method varchar(10),\
453 request_protocol varchar(10),\
454 request_time char(28),\
455 request_uri varchar(255),\
456 request_args varchar(255),\
457 server_port smallint unsigned,\
458 ssl_cipher varchar(25),\
459 ssl_keysize smallint unsigned,\
460 ssl_maxkeysize smallint unsigned,\
461 status smallint unsigned,\
462 time_stamp int unsigned,\
463 virtual_host varchar(255))";
464
465 char *notes_suffix =
466 "` (id char(19),\
467 item varchar(80),\
468 val varchar(80))";
469
470 char *headers_suffix =
471 "` (id char(19),\
472 item varchar(80),\
473 val varchar(80))";
474
475 char *cookies_suffix =
476 "` (id char(19),\
477 item varchar(80),\
478 val varchar(80))";
479 if (global_config.tabletype) {
480 type_suffix = apr_pstrcat(r->pool, " TYPE=", global_config.tabletype, NULL);
481 }
482 /* Find memory long enough to hold the whole CREATE string + \0 */
483 create_access = apr_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, type_suffix, NULL);
484 create_notes = apr_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, type_suffix, NULL);
485 create_hout = apr_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, type_suffix, NULL);
486 create_hin = apr_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, type_suffix, NULL);
487 create_cookies= apr_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, type_suffix, NULL);
488
489 #ifdef DEBUG
490 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_access);
491 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_notes);
492 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_hout);
493 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_hin);
494 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_cookies);
495 #endif
496
497 /* Assume that things worked unless told otherwise */
498 retval = 0;
499
500 if ((create_results = safe_sql_query(r, create_access))) {
501 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create access table");
502 retval = create_results;
503 }
504
505 if ((create_results = safe_sql_query(r, create_notes))) {
506 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create notes table");
507 retval = create_results;
508 }
509
510 if ((create_results = safe_sql_query(r, create_hin))) {
511 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create header_in table");
512 retval = create_results;
513 }
514
515 if ((create_results = safe_sql_query(r, create_hout))) {
516 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create header_out table");
517 retval = create_results;
518 }
519
520 if ((create_results = safe_sql_query(r, create_cookies))) {
521 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create cookies table");
522 retval = create_results;
523 }
524
525 return retval;
526}
527
227/* ------------------------------------------------* 528/* ------------------------------------------------*
228 * Command handlers that are called according * 529 * Command handlers that are called according *
229 * to the directives found at Apache runtime. * 530 * to the directives found at Apache runtime. *
@@ -266,6 +567,7 @@ static const char *set_global_string_slot(cmd_parms *cmd,
266 *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg); 567 *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg);
267 return NULL; 568 return NULL;
268} 569}
570
269static const char *set_server_string_slot(cmd_parms *cmd, 571static const char *set_server_string_slot(cmd_parms *cmd,
270 void *struct_ptr, 572 void *struct_ptr,
271 const char *arg) 573 const char *arg)
@@ -279,27 +581,6 @@ static const char *set_server_string_slot(cmd_parms *cmd,
279 return NULL; 581 return NULL;
280} 582}
281 583
282static const char *set_server_file_slot(cmd_parms *cmd,
283 void *struct_ptr,
284 const char *arg)
285{
286 void *ptr = ap_get_module_config(cmd->server->module_config,
287 &log_sql_module);
288 int offset = (int)(long)cmd->info;
289 const char *path;
290
291 path = ap_server_root_relative(cmd->pool, (char *)arg);
292
293 if (!path) {
294 return apr_pstrcat(cmd->pool, "Invalid file path ",
295 arg, NULL);
296 }
297
298 *(const char **)((char*)ptr + offset) = path;
299
300 return NULL;
301}
302
303static const char *set_logformat_slot(cmd_parms *cmd, 584static const char *set_logformat_slot(cmd_parms *cmd,
304 void *struct_ptr, 585 void *struct_ptr,
305 const char *arg) 586 const char *arg)
@@ -310,7 +591,7 @@ static const char *set_logformat_slot(cmd_parms *cmd,
310 cfg->transfer_log_format = arg; 591 cfg->transfer_log_format = arg;
311/* apr_pool_clear(cfg->parsed_pool);*/ 592/* apr_pool_clear(cfg->parsed_pool);*/
312 cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool, 593 cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool,
313 strlen(arg) * sizeof(logsql_item *)); 594 strlen(arg) * sizeof(log_sql_item *));
314 return NULL; 595 return NULL;
315} 596}
316 597
@@ -326,69 +607,16 @@ static const char *set_server_nmv_string_slot(cmd_parms *parms,
326 return set_server_string_slot(parms,struct_ptr,arg); 607 return set_server_string_slot(parms,struct_ptr,arg);
327} 608}
328 609
329/* Set a DB connection parameter */ 610static const char *set_log_sql_info(cmd_parms *cmd, void *dummy, const char *host, const char *user, const char *pwd)
330static const char *set_dbparam(cmd_parms *cmd,
331 void *struct_ptr,
332 const char *key,
333 const char *val)
334{ 611{
335 if (!global_config.db.parms) { 612 if (*host != '.') {
336 global_config.db.parms = apr_table_make(cmd->pool,5); 613 global_config.dbhost = apr_pstrdup(cmd->pool,host);
337 } 614 }
338 apr_table_set(global_config.db.parms,key,val); 615 if (*user != '.') {
339 return NULL; 616 global_config.dbuser = apr_pstrdup(cmd->pool,user);
340} 617 }
341 618 if (*pwd != '.') {
342static const char *set_dbparam_slot(cmd_parms *cmd, 619 global_config.dbpwd = apr_pstrdup(cmd->pool,pwd);
343 void *struct_ptr,
344 const char *arg)
345{
346 const char *param = (char *)cmd->info;
347 set_dbparam(cmd,NULL,param,arg);
348 return NULL;
349}
350
351/* Sets basic connection info */
352static const char *set_log_sql_info(cmd_parms *cmd, void *dummy,
353 const char *host, const char *user, const char *pwd)
354{
355 if (!user) { /* user is null, so only one arg passed */
356 /* TODO: to more error checking/force all params to be set */
357 apr_uri_t uri;
358 apr_uri_parse(cmd->pool, host, &uri);
359 if (uri.scheme) {
360 set_dbparam(cmd, NULL, "driver", uri.scheme);
361 }
362 if (uri.hostname) {
363 set_dbparam(cmd, NULL, "hostname", uri.hostname);
364 }
365 if (uri.user) {
366 set_dbparam(cmd, NULL, "username", uri.user);
367 }
368 if (uri.password) {
369 set_dbparam(cmd, NULL, "password", uri.password);
370 }
371 if (uri.port_str) {
372 set_dbparam(cmd, NULL, "port", uri.port_str);
373 }
374 if (uri.path) {
375 /* extract Database name */
376 char *off = ap_strchr(++uri.path,'/');
377 if (off)
378 *off='\0';
379 set_dbparam(cmd, NULL, "database", uri.path);
380
381 }
382 } else {
383 if (*host != '.') {
384 set_dbparam(cmd, NULL, "hostname", host);
385 }
386 if (*user != '.') {
387 set_dbparam(cmd, NULL, "username", user);
388 }
389 if (*pwd != '.') {
390 set_dbparam(cmd, NULL, "password", pwd);
391 }
392 } 620 }
393 return NULL; 621 return NULL;
394} 622}
@@ -401,13 +629,20 @@ static const char *add_server_string_slot(cmd_parms *cmd,
401 void *ptr = ap_get_module_config(cmd->server->module_config, 629 void *ptr = ap_get_module_config(cmd->server->module_config,
402 &log_sql_module); 630 &log_sql_module);
403 int offset = (int)(long)cmd->info; 631 int offset = (int)(long)cmd->info;
404 apr_array_header_t *ary = *(apr_array_header_t **)((char *)ptr + offset); 632 apr_array_header_t *ary = *(apr_array_header_t **)(ptr + offset);
405 addme = apr_array_push(ary); 633 addme = apr_array_push(ary);
406 *addme = apr_pstrdup(ary->pool, arg); 634 *addme = apr_pstrdup(ary->pool, arg);
407 635
408 return NULL; 636 return NULL;
409} 637}
410 638
639static const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, const char *arg)
640{
641 global_config.tcpport = (unsigned int)atoi(arg);
642
643 return NULL;
644}
645
411/*------------------------------------------------------------* 646/*------------------------------------------------------------*
412 * Apache-specific hooks into the module code * 647 * Apache-specific hooks into the module code *
413 * that are defined in the array 'mysql_lgog_module' (at EOF) * 648 * that are defined in the array 'mysql_lgog_module' (at EOF) *
@@ -416,47 +651,59 @@ static const char *add_server_string_slot(cmd_parms *cmd,
416#if defined(WITH_APACHE20) 651#if defined(WITH_APACHE20)
417static apr_status_t log_sql_close_link(void *data) 652static apr_status_t log_sql_close_link(void *data)
418{ 653{
419 global_config.driver->disconnect(&global_config.db); 654 mysql_close(global_config.server_p);
420 return APR_SUCCESS; 655 return APR_SUCCESS;
421} 656}
422#elif defined(WITH_APACHE13) 657#elif defined(WITH_APACHE13)
423static void log_sql_child_exit(server_rec *s, apr_pool_t *p) 658static void log_sql_child_exit(server_rec *s, apr_pool_t *p)
424{ 659{
425 global_config.driver->disconnect(&global_config.db); 660 mysql_close(global_config.server_p);
426} 661}
427#endif 662#endif
428 663
429/* Child Init */ 664/* Child Init */
430#if defined(WITH_APACHE20) 665#if defined(WITH_APACHE20)
431static void log_sql_child_init(apr_pool_t *p, server_rec *s) 666static void log_sql_child_init(apr_pool_t *p, server_rec *s)
667{
668 apr_pool_cleanup_register(p, NULL, log_sql_close_link, log_sql_close_link);
669}
670
671static int log_sql_open(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s)
432#elif defined(WITH_APACHE13) 672#elif defined(WITH_APACHE13)
433static void log_sql_child_init(server_rec *s, apr_pool_t *p) 673static void log_sql_child_init(server_rec *s, apr_pool_t *p)
434#endif 674#endif
435{ 675{
436 logsql_opendb_ret retval; 676 int retval;
437# if defined(WITH_APACHE20) 677 /* Open a link to the database */
438 /* Register cleanup hook to close DDB connection (apache 2 doesn't have child_exit) */ 678 retval = open_logdb_link(s);
439 apr_pool_cleanup_register(p, NULL, log_sql_close_link, log_sql_close_link); 679 if (!retval)
440# endif 680 log_error(APLOG_MARK,APLOG_ERR,s,"mod_log_sql: child spawned but unable to open database link");
441 /* Open a link to the database */ 681
442 retval = log_sql_opendb_link(s); 682 #ifdef DEBUG
443 switch (retval) { 683 if ( (retval == 1) || (retval == 2) )
444 case LOGSQL_OPENDB_FAIL: 684 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: open_logdb_link successful");
445 log_error(APLOG_MARK, APLOG_ERR, 0, s, 685 if (retval == 3)
446 "mod_log_sql: child spawned but unable to open database link"); 686 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: open_logdb_link said that preservation is forced");
447 break; 687 #endif
448 case LOGSQL_OPENDB_SUCCESS: 688#if defined(WITH_APACHE20)
449 case LOGSQL_OPENDB_ALREADY: 689 return OK;
450 log_error(APLOG_MARK,APLOG_DEBUG,0, s, 690#endif
451 "mod_log_sql: open_logdb_link successful");
452 break;
453 case LOGSQL_OPENDB_PRESERVE:
454 log_error(APLOG_MARK,APLOG_DEBUG, 0, s,
455 "mod_log_sql: open_logdb_link said that preservation is forced");
456 break;
457 }
458} 691}
692/*
693void *log_sql_initializer(server_rec *main_server, apr_pool_t *p)
694{
695 server_rec *s;
696
697 logsql_state main_conf = ap_get_module_config(main_server->module_config, &log_sql_module);
698
699 for (server_rec *s = main_server; s; s = s->next) {
700 conf = ap_get_module_config(s->module_config, &log_sql_module);
701 if (conf->transfer_log_format == NULL && s != main_server) {
702 *conf = *main_conf;
703 }
459 704
705}
706 */
460/* post_config / module_init */ 707/* post_config / module_init */
461#if defined(WITH_APACHE20) 708#if defined(WITH_APACHE20)
462static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) 709static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
@@ -464,6 +711,12 @@ static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptem
464static void log_sql_module_init(server_rec *s, apr_pool_t *p) 711static void log_sql_module_init(server_rec *s, apr_pool_t *p)
465#endif 712#endif
466{ 713{
714 /* Initialize Global configuration */
715 if (!global_config.socketfile)
716 global_config.socketfile = "/tmp/mysql.sock";
717 if (!global_config.tcpport)
718 global_config.tcpport = 3306;
719
467 /* TODO: Add local_address, remote_address, server_name, connection_status */ 720 /* TODO: Add local_address, remote_address, server_name, connection_status */
468 /* Register handlers */ 721 /* Register handlers */
469 log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1); 722 log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1);
@@ -490,136 +743,11 @@ static void log_sql_module_init(server_rec *s, apr_pool_t *p)
490 log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1); 743 log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1);
491 log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1); 744 log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1);
492 745
493 if (global_config.announce) {
494 ap_add_version_component(p, PACKAGE_NAME"/"PACKAGE_VERSION);
495 }
496 /* ap_server_root_relative any default preserve file locations */
497 {
498 server_rec *cur_s;
499 const char *default_p = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE);
500 for (cur_s = s; cur_s != NULL; cur_s= cur_s->next) {
501 logsql_state *cls = ap_get_module_config(cur_s->module_config,
502 &log_sql_module);
503 if (cls->preserve_file == DEFAULT_PRESERVE_FILE)
504 cls->preserve_file = default_p;
505 }
506 }
507#if defined(WITH_APACHE20) 746#if defined(WITH_APACHE20)
508 return OK; 747 return OK;
509#endif 748#endif
510} 749}
511 750
512/* This function handles calling the DB module, handling errors
513 * of missing tables and lost DB connections, and falling back to
514 * preserving the DB query.
515 *
516 * Parms: request record, table type, table name, and the full SQL command
517 */
518
519static logsql_query_ret safe_sql_insert(request_rec *r, logsql_tabletype table_type,
520 const char *table_name, const char *query) {
521
522 logsql_query_ret result;
523 logsql_state *cls = ap_get_module_config(r->server->module_config,
524 &log_sql_module);
525
526 if (!global_config.db.connected) {
527 /* preserve query */
528 return LOGSQL_QUERY_NOLINK;
529 }
530
531 result = global_config.driver->insert(r,&global_config.db,query);
532
533 /* If we ran the query and it returned an error, try to be robust.
534 * (After all, the module thought it had a valid mysql_log connection but the query
535 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
536 switch (result) {
537 case LOGSQL_QUERY_SUCCESS:
538 return LOGSQL_QUERY_SUCCESS;
539 case LOGSQL_QUERY_NOLINK:
540 return LOGSQL_QUERY_FAIL;
541 /* TODO: What do we do here */
542 case LOGSQL_QUERY_FAIL:
543 global_config.driver->disconnect(&global_config.db);
544 global_config.db.connected = 0;
545 /* re-open the connection and try again */
546 if (log_sql_opendb_link(r->server) != LOGSQL_OPENDB_FAIL) {
547 log_error(APLOG_MARK,APLOG_NOTICE,0, r->server,"db reconnect successful");
548# if defined(WITH_APACHE20)
549 apr_sleep(apr_time_from_sec(0.25)); /* pause for a quarter second */
550# elif defined(WITH_APACHE13)
551# if defined(WIN32)
552 Sleep((DWORD)0.25);
553# else
554 {
555 struct timespec delay, remainder;
556 int nanoret;
557 delay.tv_sec = 0;
558 delay.tv_nsec = 250000000; /* pause for a quarter second */
559 nanoret = nanosleep(&delay, &remainder);
560 if (nanoret && errno != EINTR) {
561 log_error(APLOG_MARK,APLOG_ERR, errno, r->server,"nanosleep unsuccessful");
562 }
563 }
564# endif /* win32 */
565# endif
566 result = global_config.driver->insert(r,&global_config.db,query);
567 if (result == LOGSQL_QUERY_SUCCESS) {
568 return LOGSQL_QUERY_SUCCESS;
569 } else {
570 log_error(APLOG_MARK,APLOG_ERR,0,r->server,"second attempt failed");
571 preserve_entry(r, query);
572 return LOGSQL_QUERY_PRESERVED;
573 }
574 } else {
575 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
576 "reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection.");
577 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
578 "log entries are being preserved in %s",cls->preserve_file);
579 preserve_entry(r, query);
580 return LOGSQL_QUERY_PRESERVED;
581 }
582 break;
583 case LOGSQL_QUERY_NOTABLE:
584 if (global_config.createtables) {
585 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
586 "table doesn't exist...creating now");
587 if ((result = global_config.driver->create_table(r, &global_config.db, table_type,
588 table_name))!=LOGSQL_TABLE_SUCCESS) {
589 log_error(APLOG_MARK,APLOG_ERR,result,r->server,
590 "child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r));
591 preserve_entry(r, query);
592 return LOGSQL_QUERY_PRESERVED;
593 } else {
594 log_error(APLOG_MARK,APLOG_ERR,result, r->server,
595 "tables successfully created - retrying query");
596 if ((result = global_config.driver->insert(r,&global_config.db,query))!=LOGSQL_QUERY_SUCCESS) {
597 log_error(APLOG_MARK,APLOG_ERR,result, r->server,
598 "giving up, preserving query");
599 preserve_entry(r, query);
600 return LOGSQL_QUERY_PRESERVED;
601 } else {
602 log_error(APLOG_MARK,APLOG_NOTICE,0, r->server,
603 "query successful after table creation");
604 return LOGSQL_QUERY_SUCCESS;
605 }
606 }
607 } else {
608 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
609 "table doesn't exist, creation denied by configuration, preserving query");
610 preserve_entry(r, query);
611 return LOGSQL_QUERY_PRESERVED;
612 }
613 break;
614 default:
615 log_error(APLOG_MARK,APLOG_ERR,0, r->server,
616 "Invalid return code from mog_log_query");
617 return LOGSQL_QUERY_FAIL;
618 break;
619 }
620 return LOGSQL_QUERY_FAIL;
621}
622
623/* This function gets called to create a per-server configuration 751/* This function gets called to create a per-server configuration
624 * record. It will always be called for the main server and 752 * record. It will always be called for the main server and
625 * for each virtual server that is established. Each server maintains 753 * for each virtual server that is established. Each server maintains
@@ -636,7 +764,7 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s)
636 cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT; 764 cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT;
637 apr_pool_create(&cls->parsed_pool, p); 765 apr_pool_create(&cls->parsed_pool, p);
638 cls->parsed_log_format = apr_pcalloc(cls->parsed_pool, 766 cls->parsed_log_format = apr_pcalloc(cls->parsed_pool,
639 strlen(cls->transfer_log_format) * sizeof(logsql_item *)); 767 strlen(cls->transfer_log_format) * sizeof(log_sql_item *));
640 cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; 768 cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME;
641 cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; 769 cls->hin_table_name = DEFAULT_HIN_TABLE_NAME;
642 cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; 770 cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME;
@@ -654,92 +782,31 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s)
654 return (void *) cls; 782 return (void *) cls;
655} 783}
656 784
657
658/* Iterates through an array of char* and searches for a matching element
659 * Returns 0 if not found, 1 if found */
660static int in_array(apr_array_header_t *ary, const char *elem)
661{
662 int itr;
663 for (itr = 0; itr < ary->nelts; itr++) {
664 if (!strcmp(elem,((char **)ary->elts)[itr])) {
665 return 1;
666 }
667 }
668 return 0;
669}
670
671
672/* Parse through cookie lists and merge based on +/- prefixes */
673#define DO_MERGE_ARRAY(parent,child,pool) \
674if (apr_is_empty_array(child)) { \
675 apr_array_cat(child, parent); \
676} else { \
677 apr_array_header_t *addlist, *dellist; \
678 char **elem, **ptr = (char **)(child->elts); \
679 int itr, overwrite = 0; \
680 addlist = apr_array_make(pool,5,sizeof(char *)); \
681 dellist = apr_array_make(subp,5,sizeof(char *)); \
682\
683 for (itr=0; itr<child->nelts; itr++) { \
684 if (*ptr[itr] == '+') { \
685 elem = (char **)apr_array_push(addlist); \
686 *elem = (ptr[itr]+1); \
687 } else if (*ptr[itr] == '-') { \
688 elem = (char **)apr_array_push(dellist); \
689 *elem = (ptr[itr]+1); \
690 } else { \
691 overwrite = 1; \
692 elem = (char **)apr_array_push(addlist); \
693 *elem = ptr[itr]; \
694 } \
695 } \
696 child = apr_array_make(p,1,sizeof(char *)); \
697 ptr = (char **)(parent->elts); \
698 if (overwrite==0) { \
699 /* if we are not overwriting the existing then prepare for merge */ \
700 for (itr=0; itr<parent->nelts; itr++) { \
701 if (!in_array(addlist, ptr[itr]) && !in_array(dellist,ptr[itr])) { \
702 elem = apr_array_push(child); \
703 *elem = apr_pstrdup(p, ptr[itr]); \
704 } \
705 } \
706 } \
707 apr_array_cat(child, addlist); \
708}
709
710static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) 785static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv)
711{ 786{
712 /* Fetch the two states to merge */ 787 /* Fetch the two states to merge */
713 logsql_state *parent = (logsql_state *) basev; 788 logsql_state *parent = (logsql_state *) basev;
714 logsql_state *child = (logsql_state *) addv; 789 logsql_state *child = (logsql_state *) addv;
715 790
716 apr_pool_t *subp;
717
718 apr_pool_create(&subp,p);
719
720 /* Child can override these, otherwise they default to parent's choice. 791 /* Child can override these, otherwise they default to parent's choice.
721 * If the parent didn't set them, create reasonable defaults for the 792 * If the parent didn't set them, create reasonable defaults for the
722 * ones that should have such default settings. Leave the others null. */ 793 * ones that should have such default settings. Leave the others null. */
723 794
795 child->transfer_table_name = child->transfer_table_name ?
796 child->transfer_table_name : parent->transfer_table_name;
724 /* No default for transfer_table_name because we want its absence 797 /* No default for transfer_table_name because we want its absence
725 * to disable logging. */ 798 * to disable logging. */
726 if (!child->transfer_table_name) {
727 child->transfer_table_name = parent->transfer_table_name;
728 }
729 799
730 if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) { 800 if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) {
731 child->transfer_log_format = parent->transfer_log_format; 801 child->transfer_log_format = parent->transfer_log_format;
732 /*apr_pool_clear(child->parsed_pool);*/ 802 /*apr_pool_clear(child->parsed_pool);*/
733 child->parsed_log_format = apr_pcalloc(child->parsed_pool, 803 child->parsed_log_format = apr_pcalloc(child->parsed_pool,
734 strlen(child->transfer_log_format) * sizeof(logsql_item *)); 804 strlen(child->transfer_log_format) * sizeof(log_sql_item *));
735 } 805 }
736 806
737 if (child->preserve_file == DEFAULT_PRESERVE_FILE) 807 if (child->preserve_file == DEFAULT_PRESERVE_FILE)
738 child->preserve_file = parent->preserve_file; 808 child->preserve_file = parent->preserve_file;
739 /* server_root_relative the preserve file location */ 809
740 if (child->preserve_file == DEFAULT_PRESERVE_FILE)
741 child->preserve_file = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE);
742
743 if (child->notes_table_name == DEFAULT_NOTES_TABLE_NAME) 810 if (child->notes_table_name == DEFAULT_NOTES_TABLE_NAME)
744 child->notes_table_name = parent->notes_table_name; 811 child->notes_table_name = parent->notes_table_name;
745 812
@@ -752,20 +819,30 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv)
752 if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME) 819 if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME)
753 child->cookie_table_name = parent->cookie_table_name; 820 child->cookie_table_name = parent->cookie_table_name;
754 821
755 DO_MERGE_ARRAY(parent->transfer_ignore_list, child->transfer_ignore_list, subp); 822 if (apr_is_empty_array(child->transfer_ignore_list))
756 DO_MERGE_ARRAY(parent->transfer_accept_list, child->transfer_accept_list, subp); 823 apr_array_cat(child->transfer_ignore_list, parent->transfer_ignore_list);
757 DO_MERGE_ARRAY(parent->remhost_ignore_list, child->remhost_ignore_list, subp); 824
758 DO_MERGE_ARRAY(parent->notes_list, child->notes_list, subp); 825 if (apr_is_empty_array(child->transfer_accept_list))
759 DO_MERGE_ARRAY(parent->hin_list, child->hin_list, subp); 826 apr_array_cat(child->transfer_accept_list, parent->transfer_accept_list);
760 DO_MERGE_ARRAY(parent->hout_list, child->hout_list, subp); 827
761 DO_MERGE_ARRAY(parent->cookie_list,child->cookie_list, subp); 828 if (apr_is_empty_array(child->remhost_ignore_list))
829 apr_array_cat(child->remhost_ignore_list, parent->remhost_ignore_list);
762 830
763 apr_pool_destroy(subp); 831 if (apr_is_empty_array(child->notes_list))
832 apr_array_cat(child->notes_list, parent->notes_list);
833
834 if (apr_is_empty_array(child->hin_list))
835 apr_array_cat(child->hin_list, parent->hin_list);
836
837 if (apr_is_empty_array(child->hout_list))
838 apr_array_cat(child->hout_list, parent->hout_list);
839
840 if (apr_is_empty_array(child->cookie_list))
841 apr_array_cat(child->cookie_list, parent->cookie_list);
764 842
765 if (!child->cookie_name) 843 if (!child->cookie_name)
766 child->cookie_name = parent->cookie_name; 844 child->cookie_name = parent->cookie_name;
767 845
768
769 return (void*) child; 846 return (void*) child;
770} 847}
771 848
@@ -850,7 +927,7 @@ static int log_sql_transaction(request_rec *orig)
850 if ((r->uri) && (cls->transfer_accept_list->nelts)) { 927 if ((r->uri) && (cls->transfer_accept_list->nelts)) {
851 proceed = 0; 928 proceed = 0;
852 for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size)) 929 for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size))
853 if (ap_strstr(r->uri, *ptrptr)) { 930 if (strstr(r->uri, *ptrptr)) {
854 proceed = 1; 931 proceed = 1;
855 break; 932 break;
856 } 933 }
@@ -863,7 +940,7 @@ static int log_sql_transaction(request_rec *orig)
863 ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); 940 ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size));
864 if (r->uri) { 941 if (r->uri) {
865 for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) 942 for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size))
866 if (ap_strstr(r->uri, *ptrptr)) { 943 if (strstr(r->uri, *ptrptr)) {
867 return OK; 944 return OK;
868 } 945 }
869 } 946 }
@@ -874,7 +951,7 @@ static int log_sql_transaction(request_rec *orig)
874 thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); 951 thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL);
875 if (thehost) { 952 if (thehost) {
876 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) 953 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size))
877 if (ap_strstr(thehost, *ptrptr)) { 954 if (strstr(thehost, *ptrptr)) {
878 return OK; 955 return OK;
879 } 956 }
880 } 957 }
@@ -884,9 +961,9 @@ static int log_sql_transaction(request_rec *orig)
884 * what the user has configured. */ 961 * what the user has configured. */
885 length = strlen(cls->transfer_log_format); 962 length = strlen(cls->transfer_log_format);
886 for (i = 0; i<length; i++) { 963 for (i = 0; i<length; i++) {
887 logsql_item *item = cls->parsed_log_format[i]; 964 log_sql_item *item = cls->parsed_log_format[i];
888 if (item==NULL) { 965 if (item==NULL) {
889 log_error(APLOG_MARK, APLOG_ERR, 0, orig->server, 966 log_error(APLOG_MARK, APLOG_ERR, orig->server,
890 "Log Format '%c' unknown",cls->transfer_log_format[i]); 967 "Log Format '%c' unknown",cls->transfer_log_format[i]);
891 continue; 968 continue;
892 } 969 }
@@ -909,7 +986,7 @@ static int log_sql_transaction(request_rec *orig)
909 item->sql_field_name, NULL); 986 item->sql_field_name, NULL);
910 values = apr_pstrcat(r->pool, values, (i ? "," : ""), 987 values = apr_pstrcat(r->pool, values, (i ? "," : ""),
911 (item->string_contents ? "'" : ""), 988 (item->string_contents ? "'" : ""),
912 global_config.driver->escape(formatted_item, r->pool,&global_config.db), 989 escape_query(formatted_item, r->pool),
913 (item->string_contents ? "'" : ""), NULL); 990 (item->string_contents ? "'" : ""), NULL);
914 } 991 }
915 992
@@ -926,9 +1003,9 @@ static int log_sql_transaction(request_rec *orig)
926 "('", 1003 "('",
927 unique_id, 1004 unique_id,
928 "','", 1005 "','",
929 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1006 escape_query(*ptrptr, r->pool),
930 "','", 1007 "','",
931 global_config.driver->escape(theitem, r->pool,&global_config.db), 1008 escape_query(theitem, r->pool),
932 "')", 1009 "')",
933 NULL); 1010 NULL);
934 i++; 1011 i++;
@@ -936,9 +1013,11 @@ static int log_sql_transaction(request_rec *orig)
936 } 1013 }
937 if ( itemsets != "" ) { 1014 if ( itemsets != "" ) {
938 note_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1015 note_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
939 /*global_config.insertdelayed?"delayed":*/"", notes_tablename, itemsets); 1016 global_config.insertdelayed?"delayed":"", notes_tablename, itemsets);
940 1017
941 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: note string: %s", note_query); 1018 #ifdef DEBUG
1019 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: note string: %s", note_query);
1020 #endif
942 } 1021 }
943 1022
944 /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/ 1023 /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/
@@ -954,9 +1033,9 @@ static int log_sql_transaction(request_rec *orig)
954 "('", 1033 "('",
955 unique_id, 1034 unique_id,
956 "','", 1035 "','",
957 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1036 escape_query(*ptrptr, r->pool),
958 "','", 1037 "','",
959 global_config.driver->escape(theitem, r->pool,&global_config.db), 1038 escape_query(theitem, r->pool),
960 "')", 1039 "')",
961 NULL); 1040 NULL);
962 i++; 1041 i++;
@@ -964,9 +1043,11 @@ static int log_sql_transaction(request_rec *orig)
964 } 1043 }
965 if ( itemsets != "" ) { 1044 if ( itemsets != "" ) {
966 hout_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1045 hout_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
967 /*global_config.insertdelayed?"delayed":*/"", hout_tablename, itemsets); 1046 global_config.insertdelayed?"delayed":"", hout_tablename, itemsets);
968 1047
969 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_out string: %s", hout_query); 1048 #ifdef DEBUG
1049 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: header_out string: %s", hout_query);
1050 #endif
970 } 1051 }
971 1052
972 1053
@@ -983,9 +1064,9 @@ static int log_sql_transaction(request_rec *orig)
983 "('", 1064 "('",
984 unique_id, 1065 unique_id,
985 "','", 1066 "','",
986 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1067 escape_query(*ptrptr, r->pool),
987 "','", 1068 "','",
988 global_config.driver->escape(theitem, r->pool,&global_config.db), 1069 escape_query(theitem, r->pool),
989 "')", 1070 "')",
990 NULL); 1071 NULL);
991 i++; 1072 i++;
@@ -993,9 +1074,11 @@ static int log_sql_transaction(request_rec *orig)
993 } 1074 }
994 if ( itemsets != "" ) { 1075 if ( itemsets != "" ) {
995 hin_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1076 hin_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
996 /*global_config.insertdelayed?"delayed":*/"", hin_tablename, itemsets); 1077 global_config.insertdelayed?"delayed":"", hin_tablename, itemsets);
997 1078
998 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_in string: %s", hin_query); 1079 #ifdef DEBUG
1080 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: header_in string: %s", hin_query);
1081 #endif
999 } 1082 }
1000 1083
1001 1084
@@ -1012,9 +1095,9 @@ static int log_sql_transaction(request_rec *orig)
1012 "('", 1095 "('",
1013 unique_id, 1096 unique_id,
1014 "','", 1097 "','",
1015 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1098 escape_query(*ptrptr, r->pool),
1016 "','", 1099 "','",
1017 global_config.driver->escape(theitem, r->pool,&global_config.db), 1100 escape_query(theitem, r->pool),
1018 "')", 1101 "')",
1019 NULL); 1102 NULL);
1020 i++; 1103 i++;
@@ -1023,23 +1106,29 @@ static int log_sql_transaction(request_rec *orig)
1023 } 1106 }
1024 if ( itemsets != "" ) { 1107 if ( itemsets != "" ) {
1025 cookie_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1108 cookie_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1026 /*global_config.insertdelayed?"delayed":*/"", cookie_tablename, itemsets); 1109 global_config.insertdelayed?"delayed":"", cookie_tablename, itemsets);
1027 1110
1028 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: cookie string: %s", cookie_query); 1111 #ifdef DEBUG
1112 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: cookie string: %s", cookie_query);
1113 #endif
1029 } 1114 }
1030 1115
1031 1116
1032 /* Set up the actual INSERT statement */ 1117 /* Set up the actual INSERT statement */
1033 access_query = apr_psprintf(r->pool, "insert %s into `%s` (%s) values (%s)", 1118 access_query = apr_psprintf(r->pool, "insert %s into `%s` (%s) values (%s)",
1034 /*global_config.insertdelayed?"delayed":*/"", transfer_tablename, fields, values); 1119 global_config.insertdelayed?"delayed":"", transfer_tablename, fields, values);
1035 1120
1036 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"mod_log_sql: access string: %s", access_query); 1121 #ifdef DEBUG
1122 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: access string: %s", access_query);
1123 #endif
1037 1124
1038 /* If the person activated force-preserve, go ahead and push all the entries 1125 /* If the person activated force-preserve, go ahead and push all the entries
1039 * into the preserve file, then return. 1126 * into the preserve file, then return.
1040 */ 1127 */
1041 if (global_config.forcepreserve) { 1128 if (global_config.forcepreserve) {
1042 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: preservation forced"); 1129 #ifdef DEBUG
1130 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: preservation forced");
1131 #endif
1043 preserve_entry(orig, access_query); 1132 preserve_entry(orig, access_query);
1044 if ( note_query != NULL ) 1133 if ( note_query != NULL )
1045 preserve_entry(orig, note_query); 1134 preserve_entry(orig, note_query);
@@ -1053,12 +1142,12 @@ static int log_sql_transaction(request_rec *orig)
1053 } 1142 }
1054 1143
1055 /* How's our mysql link integrity? */ 1144 /* How's our mysql link integrity? */
1056 if (!global_config.db.connected) { 1145 if (global_config.server_p == NULL) {
1057 1146
1058 /* Make a try to establish the link */ 1147 /* Make a try to establish the link */
1059 log_sql_opendb_link(r->server); 1148 open_logdb_link(r->server);
1060 1149
1061 if (!global_config.db.connected) { 1150 if (global_config.server_p == NULL) {
1062 /* Unable to re-establish a DB link, so assume that it's really 1151 /* Unable to re-establish a DB link, so assume that it's really
1063 * gone and send the entry to the preserve file instead. 1152 * gone and send the entry to the preserve file instead.
1064 * This short-circuits safe_sql_query() during a db outage and therefore 1153 * This short-circuits safe_sql_query() during a db outage and therefore
@@ -1077,7 +1166,7 @@ static int log_sql_transaction(request_rec *orig)
1077 return OK; 1166 return OK;
1078 } else { 1167 } else {
1079 /* Whew, we got the DB link back */ 1168 /* Whew, we got the DB link back */
1080 log_error(APLOG_MARK,APLOG_NOTICE,0, orig->server,"mod_log_sql: child established database connection"); 1169 log_error(APLOG_MARK,APLOG_NOTICE,orig->server,"mod_log_sql: child established database connection");
1081 } 1170 }
1082 } 1171 }
1083 1172
@@ -1086,20 +1175,20 @@ static int log_sql_transaction(request_rec *orig)
1086 /* ---> i.e. we have a good MySQL connection. <--- */ 1175 /* ---> i.e. we have a good MySQL connection. <--- */
1087 1176
1088 /* Make the access-table insert */ 1177 /* Make the access-table insert */
1089 safe_sql_insert(orig,LOGSQL_TABLE_ACCESS,transfer_tablename,access_query); 1178 safe_sql_query(orig, access_query);
1090 1179
1091 /* Log the optional notes, headers, etc. */ 1180 /* Log the optional notes, headers, etc. */
1092 if (note_query) 1181 if (note_query)
1093 safe_sql_insert(orig, LOGSQL_TABLE_NOTES,notes_tablename,note_query); 1182 safe_sql_query(orig, note_query);
1094 1183
1095 if (hout_query) 1184 if (hout_query)
1096 safe_sql_insert(orig, LOGSQL_TABLE_HEADERSOUT,hout_tablename,hout_query); 1185 safe_sql_query(orig, hout_query);
1097 1186
1098 if (hin_query) 1187 if (hin_query)
1099 safe_sql_insert(orig, LOGSQL_TABLE_HEADERSIN,hin_tablename,hin_query); 1188 safe_sql_query(orig, hin_query);
1100 1189
1101 if (cookie_query) 1190 if (cookie_query)
1102 safe_sql_insert(orig, LOGSQL_TABLE_COOKIES,cookie_tablename,cookie_query); 1191 safe_sql_query(orig, cookie_query);
1103 1192
1104 return OK; 1193 return OK;
1105 } 1194 }
@@ -1110,38 +1199,6 @@ static int log_sql_transaction(request_rec *orig)
1110 * Structure: command, function called, NULL, where available, how many arguments, verbose description 1199 * Structure: command, function called, NULL, where available, how many arguments, verbose description
1111 */ 1200 */
1112static const command_rec log_sql_cmds[] = { 1201static const command_rec log_sql_cmds[] = {
1113 AP_INIT_FLAG("LogSQLAnnounce", set_global_flag_slot,
1114 (void *)APR_OFFSETOF(global_config_t, announce), RSRC_CONF,
1115 "Whether to announce that mod_log_sql is loaded in the server header")
1116 ,
1117 /* DB connection parameters */
1118 AP_INIT_TAKE13("LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF,
1119 "The database connection URI in the form &quot;driver://user:password@hostname:port/database&quot;")
1120 ,
1121 AP_INIT_TAKE2("LogSQLDBParam", set_dbparam, NULL, RSRC_CONF,
1122 "First argument is the DB parameter, second is the value to assign")
1123 ,
1124 AP_INIT_FLAG("LogSQLForcePreserve", set_global_flag_slot,
1125 (void *)APR_OFFSETOF(global_config_t, forcepreserve), RSRC_CONF,
1126 "Forces logging to preserve file and bypasses database")
1127 ,
1128 AP_INIT_FLAG("LogSQLDisablePreserve", set_global_flag_slot,
1129 (void *)APR_OFFSETOF(global_config_t, disablepreserve), RSRC_CONF,
1130 "Completely disables use of the preserve file")
1131 ,
1132 AP_INIT_TAKE1("LogSQLPreserveFile", set_server_file_slot,
1133 (void *)APR_OFFSETOF(logsql_state,preserve_file), RSRC_CONF,
1134 "Name of the file to use for data preservation during database downtime")
1135 ,
1136 AP_INIT_FLAG("LogSQLCreateTables", set_global_nmv_flag_slot,
1137 (void *)APR_OFFSETOF(global_config_t, createtables), RSRC_CONF,
1138 "Turn on module's capability to create its SQL tables on the fly")
1139 ,
1140 /* Table names */
1141 AP_INIT_FLAG("LogSQLMassVirtualHosting", set_global_flag_slot,
1142 (void *)APR_OFFSETOF(global_config_t, massvirtual), RSRC_CONF,
1143 "Activates option(s) useful for ISPs performing mass virutal hosting")
1144 ,
1145 AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot, 1202 AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot,
1146 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF, 1203 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF,
1147 "The database table that holds the transfer log") 1204 "The database table that holds the transfer log")
@@ -1162,17 +1219,14 @@ static const command_rec log_sql_cmds[] = {
1162 (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, 1219 (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF,
1163 "The database table that holds the cookie info") 1220 "The database table that holds the cookie info")
1164 , 1221 ,
1165 /* Log format */
1166 AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot, 1222 AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot,
1167 NULL, RSRC_CONF, 1223 NULL, RSRC_CONF,
1168 "Instruct the module what information to log to the database transfer log") 1224 "Instruct the module what information to log to the database transfer log")
1169 , 1225 ,
1170 /* Machine ID */
1171 AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, 1226 AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot,
1172 (void *)APR_OFFSETOF(global_config_t, machid), RSRC_CONF, 1227 (void *)APR_OFFSETOF(global_config_t, machid), RSRC_CONF,
1173 "Machine ID that the module will log, useful in web clusters to differentiate machines") 1228 "Machine ID that the module will log, useful in web clusters to differentiate machines")
1174 , 1229 ,
1175 /* Limits on logging */
1176 AP_INIT_ITERATE("LogSQLRequestAccept", add_server_string_slot, 1230 AP_INIT_ITERATE("LogSQLRequestAccept", add_server_string_slot,
1177 (void *)APR_OFFSETOF(logsql_state, transfer_accept_list), RSRC_CONF, 1231 (void *)APR_OFFSETOF(logsql_state, transfer_accept_list), RSRC_CONF,
1178 "List of URIs to accept for logging. Accesses that don't match will not be logged") 1232 "List of URIs to accept for logging. Accesses that don't match will not be logged")
@@ -1185,11 +1239,48 @@ static const command_rec log_sql_cmds[] = {
1185 (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF, 1239 (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF,
1186 "List of remote hosts to ignore. Accesses that match will not be logged to database") 1240 "List of remote hosts to ignore. Accesses that match will not be logged to database")
1187 , 1241 ,
1188 /* Special loggin table configuration */ 1242 AP_INIT_TAKE1("LogSQLDatabase", set_global_string_slot,
1243 (void *)APR_OFFSETOF(global_config_t, dbname), RSRC_CONF,
1244 "The name of the database database for logging")
1245 ,
1189 AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot, 1246 AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot,
1190 (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF, 1247 (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF,
1191 "The single cookie that you want logged in the access_log when using the 'c' config directive") 1248 "The single cookie that you want logged in the access_log when using the 'c' config directive")
1192 , 1249 ,
1250 AP_INIT_TAKE3("LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF,
1251 "The database host, user-id and password for logging")
1252 ,
1253 AP_INIT_FLAG("LogSQLCreateTables", set_global_nmv_flag_slot,
1254 (void *)APR_OFFSETOF(global_config_t, createtables), RSRC_CONF,
1255 "Turn on module's capability to create its SQL tables on the fly")
1256 ,
1257 AP_INIT_FLAG("LogSQLMassVirtualHosting", set_global_flag_slot,
1258 (void *)APR_OFFSETOF(global_config_t, massvirtual), RSRC_CONF,
1259 "Activates option(s) useful for ISPs performing mass virutal hosting")
1260 ,
1261 AP_INIT_FLAG("LogSQLDelayedInserts", set_global_flag_slot,
1262 (void *)APR_OFFSETOF(global_config_t, insertdelayed), RSRC_CONF,
1263 "Whether to use delayed inserts")
1264 ,
1265 AP_INIT_FLAG("LogSQLForcePreserve", set_global_flag_slot,
1266 (void *)APR_OFFSETOF(global_config_t, forcepreserve), RSRC_CONF,
1267 "Forces logging to preserve file and bypasses database")
1268 ,
1269 AP_INIT_TAKE1("LogSQLPreserveFile", set_global_string_slot,
1270 (void *)APR_OFFSETOF(logsql_state,preserve_file), RSRC_CONF,
1271 "Name of the file to use for data preservation during database downtime")
1272 ,
1273 AP_INIT_TAKE1("LogSQLSocketFile", set_global_string_slot,
1274 (void *)APR_OFFSETOF(global_config_t, socketfile), RSRC_CONF,
1275 "Name of the file to employ for socket connections to database")
1276 ,
1277 AP_INIT_TAKE1("LogSQLTableType", set_global_string_slot,
1278 (void *)APR_OFFSETOF(global_config_t, tabletype), RSRC_CONF,
1279 "What kind of table to create (MyISAM, InnoDB,...) when creating tables")
1280 ,
1281 AP_INIT_TAKE1("LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF,
1282 "Port number to use for TCP connections to database, defaults to 3306 if not set")
1283 ,
1193 AP_INIT_ITERATE("LogSQLWhichNotes", add_server_string_slot, 1284 AP_INIT_ITERATE("LogSQLWhichNotes", add_server_string_slot,
1194 (void *)APR_OFFSETOF(logsql_state, notes_list), RSRC_CONF, 1285 (void *)APR_OFFSETOF(logsql_state, notes_list), RSRC_CONF,
1195 "Notes that you would like to log in a separate table") 1286 "Notes that you would like to log in a separate table")
@@ -1206,26 +1297,6 @@ static const command_rec log_sql_cmds[] = {
1206 (void *)APR_OFFSETOF(logsql_state, cookie_list), RSRC_CONF, 1297 (void *)APR_OFFSETOF(logsql_state, cookie_list), RSRC_CONF,
1207 "The cookie(s) that you would like to log in a separate table") 1298 "The cookie(s) that you would like to log in a separate table")
1208 , 1299 ,
1209 AP_INIT_RAW_ARGS("LogSQLDeprecated", ap_set_deprecated, NULL, RSRC_CONF,
1210 "<br><b>Deprecated</b><br>The following Commands are deprecated and should not be used.. <br>Read the documentation for more information<br><b>Deprecated</b>")
1211 ,
1212 /* Deprecated commands */
1213 AP_INIT_TAKE1("LogSQLDatabase", set_dbparam_slot,
1214 (void *)"database", RSRC_CONF,
1215 "<b>(Deprecated) Use LogSQLDBParam database dbname.</b> The name of the database database for logging")
1216 ,
1217 AP_INIT_TAKE1("LogSQLTableType", set_dbparam_slot,
1218 (void *)"tabletype", RSRC_CONF,
1219 "<b>(Deprecated) Use LogSQLDBParam tabletype type.</b> What kind of table to create (MyISAM, InnoDB,...) when creating tables")
1220 ,
1221 AP_INIT_TAKE1("LogSQLSocketFile", set_dbparam_slot,
1222 (void *)"socketfile", RSRC_CONF,
1223 "<b>(Deprecated) Use LogSQLDBParam socketfile socket.</b> Name of the file to employ for socket connections to database")
1224 ,
1225 AP_INIT_TAKE1("LogSQLTCPPort", set_dbparam_slot,
1226 (void *)"port", RSRC_CONF,
1227 "<b>(Deprecated) Use LogSQLDBParam port port.</b> Port number to use for TCP connections to database, defaults to 3306 if not set")
1228 ,
1229 {NULL} 1300 {NULL}
1230}; 1301};
1231/* The configuration array that sets up the hooks into the module. */ 1302/* The configuration array that sets up the hooks into the module. */
@@ -1233,6 +1304,7 @@ static const command_rec log_sql_cmds[] = {
1233static void register_hooks(apr_pool_t *p) { 1304static void register_hooks(apr_pool_t *p) {
1234 ap_hook_post_config(log_sql_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); 1305 ap_hook_post_config(log_sql_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1235 ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE); 1306 ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE);
1307 ap_hook_open_logs(log_sql_open, NULL, NULL, APR_HOOK_MIDDLE);
1236 ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE); 1308 ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE);
1237} 1309}
1238 1310
@@ -1246,7 +1318,7 @@ module AP_MODULE_DECLARE_DATA log_sql_module = {
1246 register_hooks /* register hooks */ 1318 register_hooks /* register hooks */
1247}; 1319};
1248#elif defined(WITH_APACHE13) 1320#elif defined(WITH_APACHE13)
1249module MODULE_VAR_EXPORT log_sql_module = { 1321module log_sql_module = {
1250 STANDARD_MODULE_STUFF, 1322 STANDARD_MODULE_STUFF,
1251 log_sql_module_init, /* module initializer */ 1323 log_sql_module_init, /* module initializer */
1252 NULL, /* create per-dir config */ 1324 NULL, /* create per-dir config */