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.c639
1 files changed, 433 insertions, 206 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c
index a0cceb2..ba60089 100644
--- a/mod_log_sql.c
+++ b/mod_log_sql.c
@@ -1,21 +1,19 @@
1/* $Id: mod_log_sql.c,v 1.16 2002/09/04 18:46:00 helios Exp $ */ 1/* $Id: mod_log_sql.c,v 1.17 2002/11/14 03:51:35 helios Exp $ */
2 2
3/* --------* 3/* --------*
4 * DEFINES * 4 * DEFINES *
5 * --------*/ 5 * --------*/
6 6
7/* The enduser probably won't modify these */ 7/* The enduser may wish to modify this */
8#undef DEBUG
9
10/* The enduser won't modify these */
8#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") 11#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
9#define ERRLEVEL APLOG_ERR|APLOG_NOERRNO 12#define ERRLEVEL APLOG_ERR|APLOG_NOERRNO
10#define WARNINGLEVEL APLOG_WARNING|APLOG_NOERRNO 13#define WARNINGLEVEL APLOG_WARNING|APLOG_NOERRNO
11#define NOTICELEVEL APLOG_NOTICE|APLOG_NOERRNO 14#define NOTICELEVEL APLOG_NOTICE|APLOG_NOERRNO
12#define DEBUGLEVEL APLOG_DEBUG|APLOG_NOERRNO 15#define DEBUGLEVEL APLOG_DEBUG|APLOG_NOERRNO
13 16
14/* The enduser may wish to modify these */
15#define WANT_SSL_LOGGING
16#undef DEBUG
17
18
19/* ---------* 17/* ---------*
20 * INCLUDES * 18 * INCLUDES *
21 * ---------*/ 19 * ---------*/
@@ -41,7 +39,7 @@
41 * -------------*/ 39 * -------------*/
42 40
43/* Declare ourselves so the configuration routines can find and know us. */ 41/* Declare ourselves so the configuration routines can find and know us. */
44module mysql_log_module; 42module sql_log_module;
45 43
46/* The contents of these are known 'Apache wide' and are not variable 44/* The contents of these are known 'Apache wide' and are not variable
47 * on a per-virtual-server basis. Every virtual server 'knows' the 45 * on a per-virtual-server basis. Every virtual server 'knows' the
@@ -51,18 +49,21 @@ MYSQL sql_server, *mysql_log = NULL;
51 49
52int massvirtual = 0; 50int massvirtual = 0;
53int create_tables = 0; 51int create_tables = 0;
52int force_preserve = 0;
54char *db_name = NULL; 53char *db_name = NULL;
55char *db_host = NULL; 54char *db_host = NULL;
56char *db_user = NULL; 55char *db_user = NULL;
57char *db_pwd = NULL; 56char *db_pwd = NULL;
57char *mach_id = NULL;
58char *socket_file = "/tmp/mysql.sock"; 58char *socket_file = "/tmp/mysql.sock";
59unsigned int tcp_port = 3306;
59 60
60typedef const char *(*item_key_func) (request_rec *, char *); 61typedef const char *(*item_key_func) (request_rec *, char *);
61 62
62/* But the contents of this structure will vary by virtual server. 63/* But the contents of this structure will vary by virtual server.
63 * This permits each virtual server to vary its configuration slightly 64 * This permits each virtual server to vary its configuration slightly
64 * for per-server customization. 65 * for per-server customization.
65 * 66 *
66 * Each child process has its own segregated copy of this structure. 67 * Each child process has its own segregated copy of this structure.
67 */ 68 */
68typedef struct { 69typedef struct {
@@ -73,9 +74,11 @@ typedef struct {
73 array_header *notes_list; 74 array_header *notes_list;
74 array_header *hout_list; 75 array_header *hout_list;
75 array_header *hin_list; 76 array_header *hin_list;
77 array_header *cookie_list;
76 char *notes_table_name; 78 char *notes_table_name;
77 char *hout_table_name; 79 char *hout_table_name;
78 char *hin_table_name; 80 char *hin_table_name;
81 char *cookie_table_name;
79 char *transfer_table_name; 82 char *transfer_table_name;
80 char *transfer_log_format; 83 char *transfer_log_format;
81 char *preserve_file; 84 char *preserve_file;
@@ -133,7 +136,7 @@ static const char *extract_remote_user(request_rec *r, char *a)
133static const char *extract_ssl_keysize(request_rec *r, char *a) 136static const char *extract_ssl_keysize(request_rec *r, char *a)
134{ 137{
135 char *result = NULL; 138 char *result = NULL;
136 139
137 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 140 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
138 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE"); 141 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE");
139 #ifdef DEBUG 142 #ifdef DEBUG
@@ -150,7 +153,7 @@ static const char *extract_ssl_keysize(request_rec *r, char *a)
150static const char *extract_ssl_maxkeysize(request_rec *r, char *a) 153static const char *extract_ssl_maxkeysize(request_rec *r, char *a)
151{ 154{
152 char *result = NULL; 155 char *result = NULL;
153 156
154 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 157 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
155 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE"); 158 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE");
156 #ifdef DEBUG 159 #ifdef DEBUG
@@ -167,7 +170,7 @@ static const char *extract_ssl_maxkeysize(request_rec *r, char *a)
167static const char *extract_ssl_cipher(request_rec *r, char *a) 170static const char *extract_ssl_cipher(request_rec *r, char *a)
168{ 171{
169 char *result = NULL; 172 char *result = NULL;
170 173
171 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 174 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
172 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); 175 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");
173 #ifdef DEBUG 176 #ifdef DEBUG
@@ -225,6 +228,7 @@ static const char *extract_bytes_sent(request_rec *r, char *a)
225 } 228 }
226} 229}
227 230
231/*
228static const char *extract_header_in(request_rec *r, char *a) 232static const char *extract_header_in(request_rec *r, char *a)
229{ 233{
230 return table_get(r->headers_in, a); 234 return table_get(r->headers_in, a);
@@ -241,6 +245,7 @@ static const char *extract_header_out(request_rec *r, char *a)
241 } 245 }
242 return table_get(r->err_headers_out, a); 246 return table_get(r->err_headers_out, a);
243} 247}
248*/
244 249
245static const char *extract_request_time(request_rec *r, char *a) 250static const char *extract_request_time(request_rec *r, char *a)
246{ 251{
@@ -278,6 +283,14 @@ static const char *extract_virtual_host(request_rec *r, char *a)
278 return ap_get_server_name(r); 283 return ap_get_server_name(r);
279} 284}
280 285
286static const char *extract_machine_id(request_rec *r, char *a)
287{
288 if (!mach_id)
289 return "-";
290 else
291 return mach_id;
292}
293
281static const char *extract_server_port(request_rec *r, char *a) 294static const char *extract_server_port(request_rec *r, char *a)
282{ 295{
283 char portnum[22]; 296 char portnum[22];
@@ -309,7 +322,7 @@ static const char *extract_referer(request_rec *r, char *a)
309static const char *extract_agent(request_rec *r, char *a) 322static const char *extract_agent(request_rec *r, char *a)
310{ 323{
311 const char *tempag; 324 const char *tempag;
312 325
313 tempag = table_get(r->headers_in, "User-Agent"); 326 tempag = table_get(r->headers_in, "User-Agent");
314 if (!tempag) 327 if (!tempag)
315 { 328 {
@@ -325,14 +338,14 @@ static const char *extract_cookie(request_rec *r, char *a)
325 char *cookieend; 338 char *cookieend;
326 char *isvalid; 339 char *isvalid;
327 char *cookiebuf; 340 char *cookiebuf;
328 341
329 log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); 342 log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module);
330 343
331 if (cls->cookie_name != NULL) { 344 if (cls->cookie_name != NULL) {
332 #ifdef DEBUG 345 #ifdef DEBUG
333 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", cls->cookie_name); 346 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", cls->cookie_name);
334 #endif 347 #endif
335 348
336 /* Fetch out the cookie header */ 349 /* Fetch out the cookie header */
337 cookiestr = (char *)table_get(r->headers_in, "cookie2"); 350 cookiestr = (char *)table_get(r->headers_in, "cookie2");
338 if (cookiestr != NULL) { 351 if (cookiestr != NULL) {
@@ -346,7 +359,7 @@ static const char *extract_cookie(request_rec *r, char *a)
346 isvalid += strlen(cls->cookie_name) + 1; 359 isvalid += strlen(cls->cookie_name) + 1;
347 /* Duplicate it into the pool */ 360 /* Duplicate it into the pool */
348 cookiebuf = ap_pstrdup(r->pool, isvalid); 361 cookiebuf = ap_pstrdup(r->pool, isvalid);
349 /* Segregate just this cookie out of the string 362 /* Segregate just this cookie out of the string
350 * with a terminating nul at the first semicolon */ 363 * with a terminating nul at the first semicolon */
351 cookieend = strchr(cookiebuf, ';'); 364 cookieend = strchr(cookiebuf, ';');
352 if (cookieend != NULL) 365 if (cookieend != NULL)
@@ -354,7 +367,7 @@ static const char *extract_cookie(request_rec *r, char *a)
354 return cookiebuf; 367 return cookiebuf;
355 } 368 }
356 } 369 }
357 370
358 cookiestr = (char *)table_get(r->headers_in, "cookie"); 371 cookiestr = (char *)table_get(r->headers_in, "cookie");
359 if (cookiestr != NULL) { 372 if (cookiestr != NULL) {
360 #ifdef DEBUG 373 #ifdef DEBUG
@@ -370,7 +383,7 @@ static const char *extract_cookie(request_rec *r, char *a)
370 return cookiebuf; 383 return cookiebuf;
371 } 384 }
372 } 385 }
373 386
374 cookiestr = table_get(r->headers_out, "set-cookie"); 387 cookiestr = table_get(r->headers_out, "set-cookie");
375 if (cookiestr != NULL) { 388 if (cookiestr != NULL) {
376 #ifdef DEBUG 389 #ifdef DEBUG
@@ -387,10 +400,81 @@ static const char *extract_cookie(request_rec *r, char *a)
387 } 400 }
388 } 401 }
389 } 402 }
390 403
391 return "-"; 404 return "-";
392} 405}
393 406
407static const char *extract_specific_cookie(request_rec *r, char *a)
408{
409 const char *cookiestr;
410 char *cookieend;
411 char *isvalid;
412 char *cookiebuf;
413
414 if (a != NULL) {
415 #ifdef DEBUG
416 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", a);
417 #endif
418
419 /* Fetch out the cookie header */
420 cookiestr = (char *)table_get(r->headers_in, "cookie2");
421 if (cookiestr != NULL) {
422 #ifdef DEBUG
423 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie2: [%s]", cookiestr);
424 #endif
425 /* Does the cookie string contain one with our name? */
426 isvalid = strstr(cookiestr, a);
427 if (isvalid != NULL) {
428 /* Move past the cookie name and equal sign */
429 isvalid += strlen(a) + 1;
430 /* Duplicate it into the pool */
431 cookiebuf = ap_pstrdup(r->pool, isvalid);
432 /* Segregate just this cookie out of the string
433 * with a terminating nul at the first semicolon */
434 cookieend = strchr(cookiebuf, ';');
435 if (cookieend != NULL)
436 *cookieend = '\0';
437 return cookiebuf;
438 }
439 }
440
441 cookiestr = (char *)table_get(r->headers_in, "cookie");
442 if (cookiestr != NULL) {
443 #ifdef DEBUG
444 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie: [%s]", cookiestr);
445 #endif
446 isvalid = strstr(cookiestr, a);
447 if (isvalid != NULL) {
448 isvalid += strlen(a) + 1;
449 cookiebuf = ap_pstrdup(r->pool, isvalid);
450 cookieend = strchr(cookiebuf, ';');
451 if (cookieend != NULL)
452 *cookieend = '\0';
453 return cookiebuf;
454 }
455 }
456
457 cookiestr = table_get(r->headers_out, "set-cookie");
458 if (cookiestr != NULL) {
459 #ifdef DEBUG
460 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Set-Cookie: [%s]", cookiestr);
461 #endif
462 isvalid = strstr(cookiestr, a);
463 if (isvalid != NULL) {
464 isvalid += strlen(a) + 1;
465 cookiebuf = ap_pstrdup(r->pool, isvalid);
466 cookieend = strchr(cookiebuf, ';');
467 if (cookieend != NULL)
468 *cookieend = '\0';
469 return cookiebuf;
470 }
471 }
472 }
473
474 return "-";
475}
476
477
394static const char *extract_request_timestamp(request_rec *r, char *a) 478static const char *extract_request_timestamp(request_rec *r, char *a)
395{ 479{
396 char tstr[32]; 480 char tstr[32];
@@ -399,13 +483,13 @@ static const char *extract_request_timestamp(request_rec *r, char *a)
399 return pstrdup(r->pool, tstr); 483 return pstrdup(r->pool, tstr);
400} 484}
401 485
486/*
402static const char *extract_note(request_rec *r, char *a) 487static const char *extract_note(request_rec *r, char *a)
403{ 488{
404 return ap_table_get(r->notes, a); 489 return ap_table_get(r->notes, a);
405 490
406 /*ap_table_do(extract_table, r, r->notes, NULL);*/
407
408} 491}
492*/
409 493
410static const char *extract_env_var(request_rec *r, char *a) 494static const char *extract_env_var(request_rec *r, char *a)
411{ 495{
@@ -415,7 +499,7 @@ static const char *extract_env_var(request_rec *r, char *a)
415static const char *extract_unique_id(request_rec *r, char *a) 499static const char *extract_unique_id(request_rec *r, char *a)
416{ 500{
417 const char *tempid; 501 const char *tempid;
418 502
419 tempid = ap_table_get(r->subprocess_env, "UNIQUE_ID"); 503 tempid = ap_table_get(r->subprocess_env, "UNIQUE_ID");
420 if (!tempid) 504 if (!tempid)
421 return "-"; 505 return "-";
@@ -437,32 +521,30 @@ struct log_sql_item_list {
437 521
438 { 'A', extract_agent, "agent", 1, 1 }, 522 { 'A', extract_agent, "agent", 1, 1 },
439 { 'b', extract_bytes_sent, "bytes_sent", 0, 0 }, 523 { 'b', extract_bytes_sent, "bytes_sent", 0, 0 },
440 { 'c', extract_cookie, "cookie", 0, 1 }, 524 { 'c', extract_cookie, "cookie", 0, 1 },
441 { 'e', extract_env_var, "env_var", 0, 1 }, 525 { 'e', extract_env_var, "env_var", 0, 1 },
442 { 'f', extract_request_file, "request_file", 0, 1 }, 526 { 'f', extract_request_file, "request_file", 0, 1 },
443 { 'H', extract_request_protocol, "request_protocol", 0, 1 }, 527 { 'H', extract_request_protocol, "request_protocol", 0, 1 },
444 { 'h', extract_remote_host, "remote_host", 0, 1 }, 528 { 'h', extract_remote_host, "remote_host", 0, 1 },
445 { 'i', extract_header_in, "header_in", 0, 1 },
446 { 'I', extract_unique_id, "id", 0, 1 }, 529 { 'I', extract_unique_id, "id", 0, 1 },
447 { 'l', extract_remote_logname, "remote_logname", 0, 1 }, 530 { 'l', extract_remote_logname, "remote_logname", 0, 1 },
448 { 'm', extract_request_method, "request_method", 0, 1 }, 531 { 'm', extract_request_method, "request_method", 0, 1 },
449 { 'n', extract_note, "note", 0, 1 }, 532 { 'M', extract_machine_id, "machine_id", 0, 1 },
450 { 'o', extract_header_out, "header_out", 0, 1 }, 533 { 'P', extract_child_pid, "child_pid", 0, 0 },
451 { 'P', extract_child_pid, "child_pid", 0, 0 }, 534 { 'p', extract_server_port, "server_port", 0, 0 },
452 { 'p', extract_server_port, "server_port", 0, 0 }, 535 { 'R', extract_referer, "referer", 1, 1 },
453 { 'R', extract_referer, "referer", 1, 1 }, 536 { 'r', extract_request_line, "request_line", 1, 1 },
454 { 'r', extract_request_line, "request_line", 1, 1 }, 537 { 'S', extract_request_timestamp, "time_stamp", 0, 0 },
455 { 'S', extract_request_timestamp, "time_stamp", 0, 0 }, 538 { 's', extract_status, "status", 1, 0 },
456 { 's', extract_status, "status", 1, 0 }, 539 { 'T', extract_request_duration, "request_duration", 1, 0 },
457 { 'T', extract_request_duration, "request_duration", 1, 0 }, 540 { 't', extract_request_time, "request_time", 0, 1 },
458 { 't', extract_request_time, "request_time", 0, 1 }, 541 { 'u', extract_remote_user, "remote_user", 0, 1 },
459 { 'u', extract_remote_user, "remote_user", 0, 1 }, 542 { 'U', extract_request_uri, "request_uri", 1, 1 },
460 { 'U', extract_request_uri, "request_uri", 1, 1 }, 543 { 'v', extract_virtual_host, "virtual_host", 0, 1 },
461 { 'v', extract_virtual_host, "virtual_host", 0, 1 },
462 #ifdef WANT_SSL_LOGGING 544 #ifdef WANT_SSL_LOGGING
463 { 'q', extract_ssl_keysize, "ssl_keysize", 0, 1 }, 545 { 'q', extract_ssl_keysize, "ssl_keysize", 0, 1 },
464 { 'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1 }, 546 { 'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1 },
465 { 'z', extract_ssl_cipher, "ssl_cipher", 0, 1 }, 547 { 'z', extract_ssl_cipher, "ssl_cipher", 0, 1 },
466 #endif 548 #endif
467 {'\0'} 549 {'\0'}
468}; 550};
@@ -479,7 +561,7 @@ const char *escape_query(const char *from_str, pool *p)
479 char *to_str; 561 char *to_str;
480 unsigned long length = strlen(from_str); 562 unsigned long length = strlen(from_str);
481 unsigned long retval; 563 unsigned long retval;
482 564
483 /* Pre-allocate a new string that could hold twice the original, which would only 565 /* Pre-allocate a new string that could hold twice the original, which would only
484 * happen if the whole original string was 'dangerous' characters. 566 * happen if the whole original string was 'dangerous' characters.
485 */ 567 */
@@ -487,20 +569,20 @@ const char *escape_query(const char *from_str, pool *p)
487 if (!to_str) { 569 if (!to_str) {
488 return from_str; 570 return from_str;
489 } 571 }
490 572
491 if (!mysql_log) { 573 if (!mysql_log) {
492 /* Well, I would have liked to use the current database charset. mysql is 574 /* Well, I would have liked to use the current database charset. mysql is
493 * unavailable, however, so I fall back to the slightly less respectful 575 * unavailable, however, so I fall back to the slightly less respectful
494 * mysql_escape_string() function that uses the default charset. 576 * mysql_escape_string() function that uses the default charset.
495 */ 577 */
496 retval = mysql_escape_string(to_str, from_str, length); 578 retval = mysql_escape_string(to_str, from_str, length);
497 } else { 579 } else {
498 /* MySQL is available, so I'll go ahead and respect the current charset when 580 /* MySQL is available, so I'll go ahead and respect the current charset when
499 * I perform the escape. 581 * I perform the escape.
500 */ 582 */
501 retval = mysql_real_escape_string(mysql_log, to_str, from_str, length); 583 retval = mysql_real_escape_string(mysql_log, to_str, from_str, length);
502 } 584 }
503 585
504 if (retval) 586 if (retval)
505 return to_str; 587 return to_str;
506 else 588 else
@@ -508,24 +590,37 @@ const char *escape_query(const char *from_str, pool *p)
508 } 590 }
509} 591}
510 592
511int open_logdb_link() 593int open_logdb_link(server_rec* s)
512{ 594{
513 /* Returns 2 if already connected, 1 if successful, 0 if unsuccessful */ 595 /* Returns:
514 596 3 if preserve forced
515 if (mysql_log != NULL) { 597 2 if already connected
598 1 if successful
599 0 if unsuccessful
600 */
601
602 if (force_preserve)
603 return 3;
604
605 if (mysql_log != NULL)
516 return 2; 606 return 2;
517 }
518 607
519 if (db_name) { 608 if (db_name) {
520 mysql_init(&sql_server); 609 mysql_init(&sql_server);
521 mysql_log = mysql_real_connect(&sql_server, db_host, db_user, db_pwd, db_name, 0, socket_file, 0); 610 mysql_log = mysql_real_connect(&sql_server, db_host, db_user, db_pwd, db_name, tcp_port, socket_file, 0);
522 611
523 if (mysql_log != NULL) { 612 if (mysql_log) {
524 return 1; 613 return 1;
525 } else { 614 } else {
615 #ifdef DEBUG
616 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&sql_server));
617 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
618 db_host, tcp_port, db_name, db_user, socket_file);
619 #endif
526 return 0; 620 return 0;
527 } 621 }
528 } 622 }
623
529 return 0; 624 return 0;
530} 625}
531 626
@@ -536,13 +631,13 @@ static int trace(void *data, const char *key, const char *val)
536 request_rec *r = (request_rec *)data; 631 request_rec *r = (request_rec *)data;
537 632
538 fp = pfopen(r->pool, "/tmp/trace", "a"); 633 fp = pfopen(r->pool, "/tmp/trace", "a");
539 634
540 if (fp) { 635 if (fp) {
541 fprintf(fp, "Field '%s' == '%s'\n", key, val); 636 fprintf(fp, "Field '%s' == '%s'\n", key, val);
542 } 637 }
543 638
544 pfclose(r->pool, fp); 639 pfclose(r->pool, fp);
545 640
546 return TRUE; 641 return TRUE;
547} 642}
548#endif 643#endif
@@ -557,8 +652,8 @@ const char *extract_table(void *data, const char *key, const char *val)
557void preserve_entry(request_rec *r, const char *query) 652void preserve_entry(request_rec *r, const char *query)
558{ 653{
559 FILE *fp; 654 FILE *fp;
560 log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); 655 log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module);
561 656
562 fp = pfopen(r->pool, cls->preserve_file, "a"); 657 fp = pfopen(r->pool, cls->preserve_file, "a");
563 if (fp == NULL) 658 if (fp == NULL)
564 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: attempted append of local preserve file but failed."); 659 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: attempted append of local preserve file but failed.");
@@ -567,7 +662,7 @@ void preserve_entry(request_rec *r, const char *query)
567 pfclose(r->pool, fp); 662 pfclose(r->pool, fp);
568 #ifdef DEBUG 663 #ifdef DEBUG
569 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file); 664 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file);
570 #endif 665 #endif
571 } 666 }
572} 667}
573 668
@@ -588,32 +683,32 @@ unsigned int safe_mysql_query(request_rec *r, const char *query)
588 struct timespec delay, remainder; 683 struct timespec delay, remainder;
589 int ret; 684 int ret;
590 void (*handler) (int); 685 void (*handler) (int);
591 686
592 687
593 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ 688 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
594 handler = signal(SIGPIPE, SIG_IGN); 689 handler = signal(SIGPIPE, SIG_IGN);
595 690
596 /* First attempt for the query */ 691 /* First attempt for the query */
597 if (mysql_log != NULL) 692 if (mysql_log != NULL)
598 retval = mysql_query(mysql_log, query); 693 retval = mysql_query(mysql_log, query);
599 else 694 else
600 return 1; 695 return 1;
601 696
602 if ( retval != 0 ) 697 if ( retval != 0 )
603 { 698 {
604 /* If we ran the query and it returned an error, try to be robust. 699 /* If we ran the query and it returned an error, try to be robust.
605 * (After all, the module thought it had a valid mysql_log connection but the query 700 * (After all, the module thought it had a valid mysql_log connection but the query
606 * could have failed for a number of reasons, so we have to be extra-safe and check.) */ 701 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
607 702
608 log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); 703 log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module);
609 704
610 real_error = mysql_errno(mysql_log); /* What really happened? */ 705 real_error = mysql_errno(mysql_log); /* What really happened? */
611 706
612 /* Something went wrong, so start by trying to restart the db link. */ 707 /* Something went wrong, so start by trying to restart the db link. */
613 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log)); 708 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log));
614 mysql_close(mysql_log); 709 mysql_close(mysql_log);
615 mysql_log = NULL; 710 mysql_log = NULL;
616 open_logdb_link(); 711 open_logdb_link(r->server);
617 712
618 if (mysql_log == NULL) { /* still unable to link */ 713 if (mysql_log == NULL) { /* still unable to link */
619 signal(SIGPIPE, handler); 714 signal(SIGPIPE, handler);
@@ -639,13 +734,13 @@ unsigned int safe_mysql_query(request_rec *r, const char *query)
639 real_error = mysql_errno(mysql_log); 734 real_error = mysql_errno(mysql_log);
640 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log)); 735 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log));
641 retval = real_error; 736 retval = real_error;
642 } else 737 } else
643 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); 738 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful");
644 } 739 }
645 740
646 /* Restore SIGPIPE to its original handler function */ 741 /* Restore SIGPIPE to its original handler function */
647 signal(SIGPIPE, handler); 742 signal(SIGPIPE, handler);
648 743
649 return retval; 744 return retval;
650} 745}
651 746
@@ -661,18 +756,20 @@ int safe_create_tables(log_sql_state *cls, request_rec *r)
661{ 756{
662 int retval; 757 int retval;
663 unsigned int create_results; 758 unsigned int create_results;
664 char *create_access = NULL; 759 char *create_access = NULL;
665 char *create_notes = NULL; 760 char *create_notes = NULL;
666 char *create_hout = NULL; 761 char *create_hout = NULL;
667 char *create_hin = NULL; 762 char *create_hin = NULL;
668 763 char *create_cookies = NULL;
669 char *createprefix = "create table if not exists "; 764
765 char *createprefix = "create table if not exists `";
670 char *access_suffix = 766 char *access_suffix =
671 " (id char(19),\ 767 "` (id char(19),\
672 agent varchar(255),\ 768 agent varchar(255),\
673 bytes_sent int unsigned,\ 769 bytes_sent int unsigned,\
674 child_pid smallint unsigned,\ 770 child_pid smallint unsigned,\
675 cookie varchar(255),\ 771 cookie varchar(255),\
772 machine_id varchar(25),\
676 request_file varchar(255),\ 773 request_file varchar(255),\
677 referer varchar(255),\ 774 referer varchar(255),\
678 remote_host varchar(50),\ 775 remote_host varchar(50),\
@@ -680,7 +777,7 @@ int safe_create_tables(log_sql_state *cls, request_rec *r)
680 remote_user varchar(50),\ 777 remote_user varchar(50),\
681 request_duration smallint unsigned,\ 778 request_duration smallint unsigned,\
682 request_line varchar(255),\ 779 request_line varchar(255),\
683 request_method varchar(6),\ 780 request_method varchar(10),\
684 request_protocol varchar(10),\ 781 request_protocol varchar(10),\
685 request_time char(28),\ 782 request_time char(28),\
686 request_uri varchar(50),\ 783 request_uri varchar(50),\
@@ -691,58 +788,71 @@ int safe_create_tables(log_sql_state *cls, request_rec *r)
691 status smallint unsigned,\ 788 status smallint unsigned,\
692 time_stamp int unsigned,\ 789 time_stamp int unsigned,\
693 virtual_host varchar(50))"; 790 virtual_host varchar(50))";
694 791
695 char *notes_suffix = 792 char *notes_suffix =
696 " (id char(19),\ 793 "` (id char(19),\
697 item varchar(80),\ 794 item varchar(80),\
698 val varchar(80))"; 795 val varchar(80))";
699 796
700 char *headers_suffix = 797 char *headers_suffix =
701 " (id char(19),\ 798 "` (id char(19),\
702 item varchar(80),\ 799 item varchar(80),\
703 val varchar(80))"; 800 val varchar(80))";
704 801
802 char *cookies_suffix =
803 "` (id char(19),\
804 item varchar(80),\
805 val varchar(80))";
806
705 /* Find memory long enough to hold the whole CREATE string + \0 */ 807 /* Find memory long enough to hold the whole CREATE string + \0 */
706 create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL); 808 create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL);
707 create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL); 809 create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL);
708 create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL); 810 create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL);
709 create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); 811 create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL);
710 812 create_cookies= ap_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, NULL);
813
711 #ifdef DEBUG 814 #ifdef DEBUG
712 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access); 815 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access);
713 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_notes); 816 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_notes);
714 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hout); 817 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hout);
715 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hin); 818 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hin);
819 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_cookies);
716 #endif 820 #endif
717 821
718 /* Assume that things worked unless told otherwise */ 822 /* Assume that things worked unless told otherwise */
719 cls->table_made = 1; 823 cls->table_made = 1;
720 retval = 0; 824 retval = 0;
721 825
722 if ((create_results = safe_mysql_query(r, create_access)) != 0) { 826 if ((create_results = safe_mysql_query(r, create_access)) != 0) {
723 cls->table_made = 0; 827 cls->table_made = 0;
724 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table"); 828 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table");
725 retval = create_results; 829 retval = create_results;
726 } 830 }
727 831
728 if ((create_results = safe_mysql_query(r, create_notes)) != 0) { 832 if ((create_results = safe_mysql_query(r, create_notes)) != 0) {
729 cls->table_made = 0; 833 cls->table_made = 0;
730 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); 834 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table");
731 retval = create_results; 835 retval = create_results;
732 } 836 }
733 837
734 if ((create_results = safe_mysql_query(r, create_hin)) != 0) { 838 if ((create_results = safe_mysql_query(r, create_hin)) != 0) {
735 cls->table_made = 0; 839 cls->table_made = 0;
736 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); 840 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table");
737 retval = create_results; 841 retval = create_results;
738 } 842 }
739 843
740 if ((create_results = safe_mysql_query(r, create_hout)) != 0) { 844 if ((create_results = safe_mysql_query(r, create_hout)) != 0) {
741 cls->table_made = 0; 845 cls->table_made = 0;
742 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table"); 846 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table");
743 retval = create_results; 847 retval = create_results;
744 } 848 }
745 849
850 if ((create_results = safe_mysql_query(r, create_cookies)) != 0) {
851 cls->table_made = 0;
852 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table");
853 retval = create_results;
854 }
855
746 return retval; 856 return retval;
747} 857}
748 858
@@ -757,6 +867,18 @@ const char *set_log_sql_massvirtual(cmd_parms *parms, void *dummy, int flag)
757 return NULL; 867 return NULL;
758} 868}
759 869
870const char *set_log_sql_force_preserve(cmd_parms *parms, void *dummy, int flag)
871{
872 force_preserve = ( flag ? 1 : 0);
873 return NULL;
874}
875
876const char *set_log_sql_machine_id(cmd_parms *parms, void *dummy, char *arg)
877{
878 mach_id = arg;
879 return NULL;
880}
881
760const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) 882const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag)
761{ 883{
762 if (massvirtual != 0) 884 if (massvirtual != 0)
@@ -774,7 +896,7 @@ const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg)
774 896
775const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) 897const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
776{ 898{
777 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 899 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
778 900
779 cls->cookie_name = arg; 901 cls->cookie_name = arg;
780 return NULL; 902 return NULL;
@@ -783,7 +905,7 @@ const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
783const char *set_log_sql_preserve_file(cmd_parms *parms, void *dummy, char *arg) 905const char *set_log_sql_preserve_file(cmd_parms *parms, void *dummy, char *arg)
784{ 906{
785 /* char *pfile; */ 907 /* char *pfile; */
786 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 908 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
787 909
788 /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */ 910 /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */
789 cls->preserve_file = arg; 911 cls->preserve_file = arg;
@@ -806,7 +928,7 @@ const char *set_log_sql_info(cmd_parms *parms, void *dummy, char *host, char *us
806 928
807const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg) 929const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg)
808{ 930{
809 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 931 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
810 932
811 if (massvirtual != 0) 933 if (massvirtual != 0)
812 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLTransferLogTable when LogSQLMassVirtualHosting is On. Ignoring."); 934 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLTransferLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
@@ -815,9 +937,20 @@ const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg)
815 return NULL; 937 return NULL;
816} 938}
817 939
940const char *set_log_sql_cookie_table(cmd_parms *parms, void *dummy, char *arg)
941{
942 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
943
944 if (massvirtual != 0)
945 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCookieLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
946 else
947 cls->cookie_table_name = arg;
948 return NULL;
949}
950
818const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg) 951const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg)
819{ 952{
820 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 953 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
821 954
822 if (massvirtual != 0) 955 if (massvirtual != 0)
823 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLNotesLogTable when LogSQLMassVirtualHosting is On. Ignoring."); 956 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLNotesLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
@@ -828,7 +961,7 @@ const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg)
828 961
829const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg) 962const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg)
830{ 963{
831 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 964 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
832 965
833 if (massvirtual != 0) 966 if (massvirtual != 0)
834 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersInLogTable when LogSQLMassVirtualHosting is On. Ignoring."); 967 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersInLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
@@ -839,7 +972,7 @@ const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg)
839 972
840const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg) 973const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg)
841{ 974{
842 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 975 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
843 976
844 if (massvirtual != 0) 977 if (massvirtual != 0)
845 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersOutLogTable when LogSQLMassVirtualHosting is On. Ignoring."); 978 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersOutLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
@@ -850,7 +983,7 @@ const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg)
850 983
851const char *set_log_sql_transfer_log_format(cmd_parms *parms, void *dummy, char *arg) 984const char *set_log_sql_transfer_log_format(cmd_parms *parms, void *dummy, char *arg)
852{ 985{
853 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 986 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
854 987
855 cls->transfer_log_format = arg; 988 cls->transfer_log_format = arg;
856 return NULL; 989 return NULL;
@@ -863,10 +996,17 @@ const char *set_log_sql_socket_file(cmd_parms *parms, void *dummy, char *arg)
863 return NULL; 996 return NULL;
864} 997}
865 998
999const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, char *arg)
1000{
1001 tcp_port = (unsigned int)atoi(arg);
1002
1003 return NULL;
1004}
1005
866const char *add_log_sql_referer_ignore(cmd_parms *parms, void *dummy, char *arg) 1006const char *add_log_sql_referer_ignore(cmd_parms *parms, void *dummy, char *arg)
867{ 1007{
868 char **addme; 1008 char **addme;
869 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1009 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
870 1010
871 addme = push_array(cls->referer_ignore_list); 1011 addme = push_array(cls->referer_ignore_list);
872 *addme = pstrdup(cls->referer_ignore_list->pool, arg); 1012 *addme = pstrdup(cls->referer_ignore_list->pool, arg);
@@ -876,7 +1016,7 @@ const char *add_log_sql_referer_ignore(cmd_parms *parms, void *dummy, char *arg)
876const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg) 1016const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg)
877{ 1017{
878 char **addme; 1018 char **addme;
879 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1019 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
880 1020
881 addme = push_array(cls->transfer_ignore_list); 1021 addme = push_array(cls->transfer_ignore_list);
882 *addme = pstrdup(cls->transfer_ignore_list->pool, arg); 1022 *addme = pstrdup(cls->transfer_ignore_list->pool, arg);
@@ -886,7 +1026,7 @@ const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg
886const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg) 1026const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg)
887{ 1027{
888 char **addme; 1028 char **addme;
889 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1029 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
890 1030
891 addme = push_array(cls->remhost_ignore_list); 1031 addme = push_array(cls->remhost_ignore_list);
892 *addme = pstrdup(cls->remhost_ignore_list->pool, arg); 1032 *addme = pstrdup(cls->remhost_ignore_list->pool, arg);
@@ -896,7 +1036,7 @@ const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg)
896const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg) 1036const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg)
897{ 1037{
898 char **addme; 1038 char **addme;
899 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1039 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
900 1040
901 addme = push_array(cls->notes_list); 1041 addme = push_array(cls->notes_list);
902 *addme = pstrdup(cls->notes_list->pool, arg); 1042 *addme = pstrdup(cls->notes_list->pool, arg);
@@ -906,7 +1046,7 @@ const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg)
906const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg) 1046const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg)
907{ 1047{
908 char **addme; 1048 char **addme;
909 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1049 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
910 1050
911 addme = push_array(cls->hout_list); 1051 addme = push_array(cls->hout_list);
912 *addme = pstrdup(cls->hout_list->pool, arg); 1052 *addme = pstrdup(cls->hout_list->pool, arg);
@@ -916,13 +1056,22 @@ const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg)
916const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg) 1056const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg)
917{ 1057{
918 char **addme; 1058 char **addme;
919 log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); 1059 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
920 1060
921 addme = push_array(cls->hin_list); 1061 addme = push_array(cls->hin_list);
922 *addme = pstrdup(cls->hin_list->pool, arg); 1062 *addme = pstrdup(cls->hin_list->pool, arg);
923 return NULL; 1063 return NULL;
924} 1064}
925 1065
1066const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
1067{
1068 char **addme;
1069 log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1070
1071 addme = push_array(cls->cookie_list);
1072 *addme = pstrdup(cls->cookie_list->pool, arg);
1073 return NULL;
1074}
926 1075
927 1076
928 1077
@@ -932,7 +1081,7 @@ const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg)
932 *------------------------------------------------------------*/ 1081 *------------------------------------------------------------*/
933 1082
934 1083
935/* 1084/*
936 * This function is called during server initialisation when an heavy-weight 1085 * This function is called during server initialisation when an heavy-weight
937 * process (such as a child) is being initialised. As with the 1086 * process (such as a child) is being initialised. As with the
938 * module-initialisation function, any information that needs to be recorded 1087 * module-initialisation function, any information that needs to be recorded
@@ -943,19 +1092,20 @@ const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg)
943static void log_sql_child_init(server_rec *s, pool *p) 1092static void log_sql_child_init(server_rec *s, pool *p)
944{ 1093{
945 int retval; 1094 int retval;
946 1095
947 retval = open_logdb_link(); 1096 retval = open_logdb_link(s);
948 if (retval == 0) 1097 if (retval == 0)
949 ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); 1098 ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link");
950 1099
951 #ifdef DEBUG 1100 #ifdef DEBUG
952 if (retval > 0) { 1101 if ( (retval == 1) || (retval == 2) )
953 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link successful"); 1102 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link successful");
954 } 1103 if (retval == 3)
1104 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link said that preservation is forced");
955 #endif 1105 #endif
956} 1106}
957 1107
958/* 1108/*
959 * This function is called when an heavy-weight process (such as a child) is 1109 * This function is called when an heavy-weight process (such as a child) is
960 * being run down or destroyed. As with the child-initialisation function, 1110 * being run down or destroyed. As with the child-initialisation function,
961 * any information that needs to be recorded must be in static cells, since 1111 * any information that needs to be recorded must be in static cells, since
@@ -973,15 +1123,15 @@ static void log_sql_child_exit(server_rec *s, pool *p)
973void *log_sql_initializer(server_rec *main_server, pool *p) 1123void *log_sql_initializer(server_rec *main_server, pool *p)
974{ 1124{
975 server_rec *s; 1125 server_rec *s;
976 1126
977 log_sql_state main_conf = ap_get_module_config(main_server->module_config, &mysql_log_module); 1127 log_sql_state main_conf = ap_get_module_config(main_server->module_config, &sql_log_module);
978 1128
979 for (server_rec *s = main_server; s; s = s->next) { 1129 for (server_rec *s = main_server; s; s = s->next) {
980 conf = ap_get_module_config(s->module_config, &mysql_log_module); 1130 conf = ap_get_module_config(s->module_config, &sql_log_module);
981 if (conf->transfer_log_format == NULL && s != main_server) { 1131 if (conf->transfer_log_format == NULL && s != main_server) {
982 *conf = *main_conf; 1132 *conf = *main_conf;
983 } 1133 }
984 1134
985} 1135}
986 */ 1136 */
987 1137
@@ -996,26 +1146,28 @@ void *log_sql_initializer(server_rec *main_server, pool *p)
996 */ 1146 */
997void *log_sql_make_state(pool *p, server_rec *s) 1147void *log_sql_make_state(pool *p, server_rec *s)
998{ 1148{
999 1149
1000 log_sql_state *cls = (log_sql_state *) ap_palloc(p, sizeof(log_sql_state)); 1150 log_sql_state *cls = (log_sql_state *) ap_palloc(p, sizeof(log_sql_state));
1001 1151
1002 cls->transfer_table_name = NULL; 1152 /* These defaults are overridable in the httpd.conf file. */
1003 cls->transfer_log_format = NULL; 1153 cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */
1154 cls->transfer_log_format = "AbHhmRSsTUuv";
1004 cls->notes_table_name = "notes"; 1155 cls->notes_table_name = "notes";
1005 cls->hin_table_name = "headers_in"; 1156 cls->hin_table_name = "headers_in";
1006 cls->hout_table_name = "headers_out"; 1157 cls->hout_table_name = "headers_out";
1007 1158 cls->cookie_table_name = "cookies";
1159 cls->preserve_file = "/tmp/sql-preserve";
1160
1008 cls->referer_ignore_list = make_array(p, 1, sizeof(char *)); 1161 cls->referer_ignore_list = make_array(p, 1, sizeof(char *));
1009 cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); 1162 cls->transfer_ignore_list = make_array(p, 1, sizeof(char *));
1010 cls->remhost_ignore_list = make_array(p, 1, sizeof(char *)); 1163 cls->remhost_ignore_list = make_array(p, 1, sizeof(char *));
1011 cls->notes_list = make_array(p, 1, sizeof(char *)); 1164 cls->notes_list = make_array(p, 1, sizeof(char *));
1012 cls->hin_list = make_array(p, 1, sizeof(char *)); 1165 cls->hin_list = make_array(p, 1, sizeof(char *));
1013 cls->hout_list = make_array(p, 1, sizeof(char *)); 1166 cls->hout_list = make_array(p, 1, sizeof(char *));
1167 cls->cookie_list = make_array(p, 1, sizeof(char *));
1014 cls->table_made = 0; 1168 cls->table_made = 0;
1015
1016 cls->preserve_file = "/tmp/sql-preserve";
1017 cls->cookie_name = NULL; 1169 cls->cookie_name = NULL;
1018 1170
1019 return (void *) cls; 1171 return (void *) cls;
1020} 1172}
1021 1173
@@ -1036,9 +1188,15 @@ command_rec log_sql_cmds[] = {
1036 {"LogSQLHeadersInLogTable", set_log_sql_hin_table, NULL, RSRC_CONF, TAKE1, 1188 {"LogSQLHeadersInLogTable", set_log_sql_hin_table, NULL, RSRC_CONF, TAKE1,
1037 "The database table that holds the inbound headers"} 1189 "The database table that holds the inbound headers"}
1038 , 1190 ,
1191 {"LogSQLCookieLogTable", set_log_sql_cookie_table, NULL, RSRC_CONF, TAKE1,
1192 "The database table that holds the cookie info"}
1193 ,
1039 {"LogSQLTransferLogFormat", set_log_sql_transfer_log_format, NULL, RSRC_CONF, TAKE1, 1194 {"LogSQLTransferLogFormat", set_log_sql_transfer_log_format, NULL, RSRC_CONF, TAKE1,
1040 "Instruct the module what information to log to the database transfer log"} 1195 "Instruct the module what information to log to the database transfer log"}
1041 , 1196 ,
1197 {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1,
1198 "Machine ID that the module will log, useful in web clusters to differentiate machines"}
1199 ,
1042 {"LogSQLRefererIgnore", add_log_sql_referer_ignore, NULL, RSRC_CONF, ITERATE, 1200 {"LogSQLRefererIgnore", add_log_sql_referer_ignore, NULL, RSRC_CONF, ITERATE,
1043 "List of referers to ignore. Accesses that match will not be logged to database"} 1201 "List of referers to ignore. Accesses that match will not be logged to database"}
1044 , 1202 ,
@@ -1052,7 +1210,7 @@ command_rec log_sql_cmds[] = {
1052 "The name of the database database for logging"} 1210 "The name of the database database for logging"}
1053 , 1211 ,
1054 {"LogSQLWhichCookie", set_log_sql_cookie, NULL, RSRC_CONF, TAKE1, 1212 {"LogSQLWhichCookie", set_log_sql_cookie, NULL, RSRC_CONF, TAKE1,
1055 "The CookieName that you want logged when using the 'c' config directive"} 1213 "The single cookie that you want logged in the access_log when using the 'c' config directive"}
1056 , 1214 ,
1057 {"LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF, TAKE3, 1215 {"LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF, TAKE3,
1058 "The database host, user-id and password for logging"} 1216 "The database host, user-id and password for logging"}
@@ -1063,33 +1221,42 @@ command_rec log_sql_cmds[] = {
1063 {"LogSQLMassVirtualHosting", set_log_sql_massvirtual, NULL, RSRC_CONF, FLAG, 1221 {"LogSQLMassVirtualHosting", set_log_sql_massvirtual, NULL, RSRC_CONF, FLAG,
1064 "Activates option(s) useful for ISPs performing mass virutal hosting"} 1222 "Activates option(s) useful for ISPs performing mass virutal hosting"}
1065 , 1223 ,
1224 {"LogSQLForcePreserve", set_log_sql_force_preserve, NULL, RSRC_CONF, FLAG,
1225 "Forces logging to preserve file and bypasses database"}
1226 ,
1066 {"LogSQLPreserveFile", set_log_sql_preserve_file, NULL, RSRC_CONF, TAKE1, 1227 {"LogSQLPreserveFile", set_log_sql_preserve_file, NULL, RSRC_CONF, TAKE1,
1067 "Name of the file to use for data preservation during database downtime"} 1228 "Name of the file to use for data preservation during database downtime"}
1068 , 1229 ,
1069 {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1, 1230 {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1,
1070 "Name of the file to employ for socket connections to database"} 1231 "Name of the file to employ for socket connections to database"}
1071 , 1232 ,
1233 {"LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF, TAKE1,
1234 "Port number to use for TCP connections to database, defaults to 3306 if not set"}
1235 ,
1072 {"LogSQLWhichNotes", add_log_sql_note, NULL, RSRC_CONF, ITERATE, 1236 {"LogSQLWhichNotes", add_log_sql_note, NULL, RSRC_CONF, ITERATE,
1073 "Members of the 'notes' that you would like to log"} 1237 "Notes that you would like to log in a separate table"}
1074 , 1238 ,
1075 {"LogSQLWhichHeadersOut", add_log_sql_hout, NULL, RSRC_CONF, ITERATE, 1239 {"LogSQLWhichHeadersOut", add_log_sql_hout, NULL, RSRC_CONF, ITERATE,
1076 "Members of the 'headers out' that you would like to log"} 1240 "Outbound headers that you would like to log in a separate table"}
1077 , 1241 ,
1078 {"LogSQLWhichHeadersIn", add_log_sql_hin, NULL, RSRC_CONF, ITERATE, 1242 {"LogSQLWhichHeadersIn", add_log_sql_hin, NULL, RSRC_CONF, ITERATE,
1079 "Members of the 'headers in' that you would like to log"} 1243 "Inbound headers that you would like to log in a separate table"}
1244 ,
1245 {"LogSQLWhichCookies", add_log_sql_cookie, NULL, RSRC_CONF, ITERATE,
1246 "The cookie(s) that you would like to log in a separate table"}
1080 , 1247 ,
1081 {NULL} 1248 {NULL}
1082}; 1249};
1083 1250
1084 1251
1085 1252
1086/* Routine to perform the actual construction and execution of the relevant 1253/* Routine to perform the actual construction and execution of the relevant
1087 * INSERT statements. 1254 * INSERT statements.
1088 */ 1255 */
1089int log_sql_transaction(request_rec *orig) 1256int log_sql_transaction(request_rec *orig)
1090{ 1257{
1091 char **ptrptr, **ptrptr2; 1258 char **ptrptr, **ptrptr2;
1092 log_sql_state *cls = get_module_config(orig->server->module_config, &mysql_log_module); 1259 log_sql_state *cls = get_module_config(orig->server->module_config, &sql_log_module);
1093 const char *access_query; 1260 const char *access_query;
1094 request_rec *r; 1261 request_rec *r;
1095 1262
@@ -1101,36 +1268,43 @@ int log_sql_transaction(request_rec *orig)
1101 char *notes_base = "notes_"; 1268 char *notes_base = "notes_";
1102 char *hout_base = "headout_"; 1269 char *hout_base = "headout_";
1103 char *hin_base = "headin_"; 1270 char *hin_base = "headin_";
1271 char *cookie_base = "cookies_";
1104 char *a_tablename; 1272 char *a_tablename;
1105 char *n_tablename; 1273 char *n_tablename;
1106 char *i_tablename; 1274 char *i_tablename;
1107 char *o_tablename; 1275 char *o_tablename;
1276 char *c_tablename;
1108 int i; 1277 int i;
1109 1278
1110 /* Find memory long enough to hold the table name + \0. */ 1279 /* Find memory long enough to hold the table name + \0. */
1111 a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); 1280 a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL);
1112 n_tablename = ap_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL); 1281 n_tablename = ap_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL);
1113 i_tablename = ap_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL); 1282 i_tablename = ap_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL);
1114 o_tablename = ap_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL); 1283 o_tablename = ap_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL);
1115 1284 c_tablename = ap_pstrcat(orig->pool, cookie_base, ap_get_server_name(orig), NULL);
1116 /* Transform any dots or dashes to underscores */ 1285
1286 /* Transform any dots to underscores */
1117 for (i = 0; i < strlen(a_tablename); i++) { 1287 for (i = 0; i < strlen(a_tablename); i++) {
1118 if ( (a_tablename[i] == '.') || (a_tablename[i] == '-') ) 1288 if (a_tablename[i] == '.')
1119 a_tablename[i] = '_'; 1289 a_tablename[i] = '_';
1120 } 1290 }
1121 for (i = 0; i < strlen(n_tablename); i++) { 1291 for (i = 0; i < strlen(n_tablename); i++) {
1122 if ( (n_tablename[i] == '.') || (n_tablename[i] == '-') ) 1292 if (n_tablename[i] == '.')
1123 n_tablename[i] = '_'; 1293 n_tablename[i] = '_';
1124 } 1294 }
1125 for (i = 0; i < strlen(i_tablename); i++) { 1295 for (i = 0; i < strlen(i_tablename); i++) {
1126 if ( (i_tablename[i] == '.') || (i_tablename[i] == '-') ) 1296 if (i_tablename[i] == '.')
1127 i_tablename[i] = '_'; 1297 i_tablename[i] = '_';
1128 } 1298 }
1129 for (i = 0; i < strlen(o_tablename); i++) { 1299 for (i = 0; i < strlen(o_tablename); i++) {
1130 if ( (o_tablename[i] == '.') || (o_tablename[i] == '-') ) 1300 if (o_tablename[i] == '.')
1131 o_tablename[i] = '_'; 1301 o_tablename[i] = '_';
1132 } 1302 }
1133 1303 for (i = 0; i < strlen(c_tablename); i++) {
1304 if (c_tablename[i] == '.')
1305 c_tablename[i] = '_';
1306 }
1307
1134 /* Tell this virtual server its transfer table name, and 1308 /* Tell this virtual server its transfer table name, and
1135 * turn on create_tables, which is implied by massvirtual. 1309 * turn on create_tables, which is implied by massvirtual.
1136 */ 1310 */
@@ -1138,9 +1312,10 @@ int log_sql_transaction(request_rec *orig)
1138 cls->notes_table_name = n_tablename; 1312 cls->notes_table_name = n_tablename;
1139 cls->hout_table_name = o_tablename; 1313 cls->hout_table_name = o_tablename;
1140 cls->hin_table_name = i_tablename; 1314 cls->hin_table_name = i_tablename;
1315 cls->cookie_table_name = c_tablename;
1141 create_tables = 1; 1316 create_tables = 1;
1142 } 1317 }
1143 1318
1144 /* Do we have enough info to log? */ 1319 /* Do we have enough info to log? */
1145 if ( cls->transfer_table_name == NULL ) { 1320 if ( cls->transfer_table_name == NULL ) {
1146 return DECLINED; 1321 return DECLINED;
@@ -1152,11 +1327,12 @@ int log_sql_transaction(request_rec *orig)
1152 char *note_query = NULL; 1327 char *note_query = NULL;
1153 char *hin_query = NULL; 1328 char *hin_query = NULL;
1154 char *hout_query = NULL; 1329 char *hout_query = NULL;
1330 char *cookie_query = NULL;
1155 const char *unique_id; 1331 const char *unique_id;
1156 const char *formatted_item; 1332 const char *formatted_item;
1157 int i, j, length; 1333 int i, j, length;
1158 int result; 1334 int result;
1159 1335
1160 for (r = orig; r->next; r = r->next) { 1336 for (r = orig; r->next; r = r->next) {
1161 continue; 1337 continue;
1162 } 1338 }
@@ -1188,10 +1364,6 @@ int log_sql_transaction(request_rec *orig)
1188 } 1364 }
1189 } 1365 }
1190 1366
1191 /* If not specified by the user, use the default format */
1192 if (cls->transfer_log_format == NULL) {
1193 cls->transfer_log_format = "AbHhmRSsTUuv";
1194 }
1195 length = strlen(cls->transfer_log_format); 1367 length = strlen(cls->transfer_log_format);
1196 1368
1197 /* Iterate through the format characters and set up the INSERT string according to 1369 /* Iterate through the format characters and set up the INSERT string according to
@@ -1205,20 +1377,20 @@ int log_sql_transaction(request_rec *orig)
1205 /* Yes, this key is one of the configured keys. 1377 /* Yes, this key is one of the configured keys.
1206 * Call the key's function and put the returned value into 'formatted_item' */ 1378 * Call the key's function and put the returned value into 'formatted_item' */
1207 formatted_item = log_sql_item_keys[j].func(log_sql_item_keys[j].want_orig_default ? orig : r, ""); 1379 formatted_item = log_sql_item_keys[j].func(log_sql_item_keys[j].want_orig_default ? orig : r, "");
1208 1380
1209 /* Massage 'formatted_item' for proper SQL eligibility... */ 1381 /* Massage 'formatted_item' for proper SQL eligibility... */
1210 if (!formatted_item) { 1382 if (!formatted_item) {
1211 formatted_item = ""; 1383 formatted_item = "";
1212 } else if (formatted_item[0] == '-' && formatted_item[1] == '\0' && !log_sql_item_keys[j].string_contents) { 1384 } else if (formatted_item[0] == '-' && formatted_item[1] == '\0' && !log_sql_item_keys[j].string_contents) {
1213 /* If apache tried to log a '-' character for a numeric field, convert that to a zero 1385 /* If apache tried to log a '-' character for a numeric field, convert that to a zero
1214 * because the database expects a numeral and will reject the '-' character. */ 1386 * because the database expects a numeral and will reject the '-' character. */
1215 formatted_item = "0"; 1387 formatted_item = "0";
1216 } 1388 }
1217 1389
1218 /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ 1390 /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */
1219 fields = pstrcat(r->pool, fields, (i > 0 ? "," : ""), 1391 fields = pstrcat(r->pool, fields, (i > 0 ? "," : ""),
1220 log_sql_item_keys[j].sql_field_name, NULL); 1392 log_sql_item_keys[j].sql_field_name, NULL);
1221 1393
1222 values = pstrcat(r->pool, values, (i > 0 ? "," : ""), 1394 values = pstrcat(r->pool, values, (i > 0 ? "," : ""),
1223 (log_sql_item_keys[j].string_contents ? "'" : ""), 1395 (log_sql_item_keys[j].string_contents ? "'" : ""),
1224 escape_query(formatted_item, r->pool), 1396 escape_query(formatted_item, r->pool),
@@ -1230,129 +1402,181 @@ int log_sql_transaction(request_rec *orig)
1230 } 1402 }
1231 } 1403 }
1232 1404
1233 /* Work through the list of notes defined by LogSQLNotesToLog */ 1405 /* Work through the list of notes defined by LogSQLWhichNotes */
1234 i = 0; 1406 i = 0;
1235 unique_id = extract_unique_id(r, ""); 1407 unique_id = extract_unique_id(r, "");
1236 1408
1237 ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size)); 1409 ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size));
1238 for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) { 1410 for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) {
1239 /* If the specified note (*ptrptr) exists for the current request... */ 1411 /* If the specified note (*ptrptr) exists for the current request... */
1240 if ((theitem = ap_table_get(r->notes, *ptrptr))) { 1412 if ((theitem = ap_table_get(r->notes, *ptrptr))) {
1241 itemsets = ap_pstrcat(r->pool, itemsets, 1413 itemsets = ap_pstrcat(r->pool, itemsets,
1242 (i > 0 ? "," : ""), 1414 (i > 0 ? "," : ""),
1243 "('", 1415 "('",
1244 unique_id, 1416 unique_id,
1245 "','", 1417 "','",
1246 escape_query(*ptrptr, r->pool), 1418 escape_query(*ptrptr, r->pool),
1247 "','", 1419 "','",
1248 escape_query(theitem, r->pool), 1420 escape_query(theitem, r->pool),
1249 "')", 1421 "')",
1250 NULL); 1422 NULL);
1251 i++; 1423 i++;
1252 } 1424 }
1253 } 1425 }
1254 if ( itemsets != "" ) { 1426 if ( itemsets != "" ) {
1255 note_query = ap_pstrcat(r->pool, "insert into ", cls->notes_table_name, " (id, item, val) values ", itemsets, NULL); 1427 note_query = ap_pstrcat(r->pool, "insert into `", cls->notes_table_name, "` (id, item, val) values ", itemsets, NULL);
1256 #ifdef DEBUG 1428 #ifdef DEBUG
1257 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: note string: %s", note_query); 1429 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: note string: %s", note_query);
1258 #endif 1430 #endif
1259 } 1431 }
1260 1432
1261 /* Work through the list of headers-out defined by LogSQLHeadersOutToLog */ 1433 /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/
1262 i = 0; 1434 i = 0;
1263 itemsets = ""; 1435 itemsets = "";
1264 1436
1265 ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size)); 1437 ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size));
1266 for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) { 1438 for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) {
1267 /* If the specified note (*ptrptr) exists for the current request... */ 1439 /* If the specified header (*ptrptr) exists for the current request... */
1268 if ((theitem = ap_table_get(r->headers_out, *ptrptr))) { 1440 if ((theitem = ap_table_get(r->headers_out, *ptrptr))) {
1269 itemsets = ap_pstrcat(r->pool, itemsets, 1441 itemsets = ap_pstrcat(r->pool, itemsets,
1270 (i > 0 ? "," : ""), 1442 (i > 0 ? "," : ""),
1271 "('", 1443 "('",
1272 unique_id, 1444 unique_id,
1273 "','", 1445 "','",
1274 escape_query(*ptrptr, r->pool), 1446 escape_query(*ptrptr, r->pool),
1275 "','", 1447 "','",
1276 escape_query(theitem, r->pool), 1448 escape_query(theitem, r->pool),
1277 "')", 1449 "')",
1278 NULL); 1450 NULL);
1279 i++; 1451 i++;
1280 } 1452 }
1281 } 1453 }
1282 if ( itemsets != "" ) { 1454 if ( itemsets != "" ) {
1283 hout_query = ap_pstrcat(r->pool, "insert into ", cls->hout_table_name, " (id, item, val) values ", itemsets, NULL); 1455 hout_query = ap_pstrcat(r->pool, "insert into `", cls->hout_table_name, "` (id, item, val) values ", itemsets, NULL);
1284 #ifdef DEBUG 1456 #ifdef DEBUG
1285 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_out string: %s", hout_query); 1457 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_out string: %s", hout_query);
1286 #endif 1458 #endif
1287 } 1459 }
1288 1460
1289 1461
1290 /* Work through the list of headers-in defined by LogSQLHeadersInToLog */ 1462 /* Work through the list of headers-in defined by LogSQLWhichHeadersIn */
1291 i = 0; 1463 i = 0;
1292 itemsets = ""; 1464 itemsets = "";
1293 1465
1294 ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size)); 1466 ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size));
1295 for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) { 1467 for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) {
1296 /* If the specified note (*ptrptr) exists for the current request... */ 1468 /* If the specified header (*ptrptr) exists for the current request... */
1297 if ((theitem = ap_table_get(r->headers_in, *ptrptr))) { 1469 if ((theitem = ap_table_get(r->headers_in, *ptrptr))) {
1298 itemsets = ap_pstrcat(r->pool, itemsets, 1470 itemsets = ap_pstrcat(r->pool, itemsets,
1299 (i > 0 ? "," : ""), 1471 (i > 0 ? "," : ""),
1300 "('", 1472 "('",
1301 unique_id, 1473 unique_id,
1302 "','", 1474 "','",
1303 escape_query(*ptrptr, r->pool), 1475 escape_query(*ptrptr, r->pool),
1304 "','", 1476 "','",
1305 escape_query(theitem, r->pool), 1477 escape_query(theitem, r->pool),
1306 "')", 1478 "')",
1307 NULL); 1479 NULL);
1308 i++; 1480 i++;
1309 } 1481 }
1310 } 1482 }
1311 if ( itemsets != "" ) { 1483 if ( itemsets != "" ) {
1312 hin_query = ap_pstrcat(r->pool, "insert into ", cls->hin_table_name, " (id, item, val) values ", itemsets, NULL); 1484 hin_query = ap_pstrcat(r->pool, "insert into `", cls->hin_table_name, "` (id, item, val) values ", itemsets, NULL);
1313 #ifdef DEBUG 1485 #ifdef DEBUG
1314 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_in string: %s", hin_query); 1486 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_in string: %s", hin_query);
1315 #endif 1487 #endif
1316 } 1488 }
1317 1489
1490
1491 /* Work through the list of cookies defined by LogSQLWhichCookies */
1492 i = 0;
1493 itemsets = "";
1494
1495 ptrptr2 = (char **) (cls->cookie_list->elts + (cls->cookie_list->nelts * cls->cookie_list->elt_size));
1496 for (ptrptr = (char **) cls->cookie_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->cookie_list->elt_size)) {
1497 /* If the specified cookie (*ptrptr) exists for the current request... */
1498 if ( strncmp((theitem = extract_specific_cookie(r, *ptrptr)), "-", 1) ) {
1499 itemsets = ap_pstrcat(r->pool, itemsets,
1500 (i > 0 ? "," : ""),
1501 "('",
1502 unique_id,
1503 "','",
1504 escape_query(*ptrptr, r->pool),
1505 "','",
1506 escape_query(theitem, r->pool),
1507 "')",
1508 NULL);
1509 i++;
1510 }
1511
1512 }
1513 if ( itemsets != "" ) {
1514 cookie_query = ap_pstrcat(r->pool, "insert into `", cls->cookie_table_name, "` (id, item, val) values ", itemsets, NULL);
1515 #ifdef DEBUG
1516 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: cookie string: %s", cookie_query);
1517 #endif
1518 }
1519
1520
1318 /* Set up the actual INSERT statement */ 1521 /* Set up the actual INSERT statement */
1319 access_query = ap_pstrcat(r->pool, "insert into ", cls->transfer_table_name, " (", fields, ") values (", values, ")", NULL); 1522 access_query = ap_pstrcat(r->pool, "insert into `", cls->transfer_table_name, "` (", fields, ") values (", values, ")", NULL);
1320 1523
1321 #ifdef DEBUG 1524 #ifdef DEBUG
1322 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: access string: %s", access_query); 1525 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: access string: %s", access_query);
1323 #endif 1526 #endif
1324 1527
1528 /* If the person activated force-preserve, go ahead and push all the entries
1529 * into the preserve file, then return.
1530 */
1531 if (force_preserve) {
1532 #ifdef DEBUG
1533 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: preservation forced");
1534 #endif
1535 preserve_entry(orig, access_query);
1536 if ( note_query != NULL )
1537 preserve_entry(orig, note_query);
1538 if ( hin_query != NULL )
1539 preserve_entry(orig, hin_query);
1540 if ( hout_query != NULL )
1541 preserve_entry(orig, hout_query);
1542 if ( cookie_query != NULL )
1543 preserve_entry(orig, cookie_query);
1544 return OK;
1545 }
1546
1325 /* How's our mysql link integrity? */ 1547 /* How's our mysql link integrity? */
1326 if (mysql_log == NULL) { 1548 if (mysql_log == NULL) {
1327 1549
1328 /* Make a try to establish the link */ 1550 /* Make a try to establish the link */
1329 open_logdb_link(); 1551 open_logdb_link(r->server);
1330 1552
1331 if (mysql_log == NULL) { 1553 if (mysql_log == NULL) {
1332 /* Unable to re-establish a DB link, so assume that it's really 1554 /* Unable to re-establish a DB link, so assume that it's really
1333 * gone and send the entry to the preserve file instead. 1555 * gone and send the entry to the preserve file instead.
1334 * This short-circuits safe_mysql_query during a db outage and therefore 1556 * This short-circuits safe_mysql_query during a db outage and therefore
1335 * we don't keep logging the db error over and over. 1557 * we don't keep logging the db error over and over.
1336 */ 1558 */
1337 preserve_entry(orig, access_query); 1559 preserve_entry(orig, access_query);
1338 if ( note_query != NULL ) 1560 if ( note_query != NULL )
1339 preserve_entry(orig, note_query); 1561 preserve_entry(orig, note_query);
1340 if ( hin_query != NULL ) 1562 if ( hin_query != NULL )
1341 preserve_entry(orig, hin_query); 1563 preserve_entry(orig, hin_query);
1342 if ( hout_query != NULL ) 1564 if ( hout_query != NULL )
1343 preserve_entry(orig, hout_query); 1565 preserve_entry(orig, hout_query);
1344 1566 if ( cookie_query != NULL )
1567 preserve_entry(orig, cookie_query);
1568
1345 return OK; 1569 return OK;
1346 } else { 1570 } else {
1347 /* Whew, we got the DB link back */ 1571 /* Whew, we got the DB link back */
1348 ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: child established database connection"); 1572 ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: child established database connection");
1349 } 1573 }
1350 } 1574 }
1351 1575
1352 1576
1353 /* ---> So as of here we have a non-null value of mysql_log. <--- */ 1577 /* ---> So as of here we have a non-null value of mysql_log. <--- */
1354 /* ---> i.e. we have a good MySQL connection. <--- */ 1578 /* ---> i.e. we have a good MySQL connection. <--- */
1355 1579
1356 1580
1357 /* Make the tables if we're supposed to. */ 1581 /* Make the tables if we're supposed to. */
1358 if ((cls->table_made != 1) && (create_tables != 0)) { 1582 if ((cls->table_made != 1) && (create_tables != 0)) {
@@ -1362,14 +1586,14 @@ int log_sql_transaction(request_rec *orig)
1362 else 1586 else
1363 ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig)); 1587 ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig));
1364 } 1588 }
1365 1589
1366 /* Make the access-table insert */ 1590 /* Make the access-table insert */
1367 result = safe_mysql_query(orig, access_query); 1591 result = safe_mysql_query(orig, access_query);
1368 1592
1369 /* It failed, but NOT because table didn't exist */ 1593 /* It failed, but NOT because table didn't exist */
1370 if ( (result != 0) && (result != 1146) ) 1594 if ( (result != 0) && (result != 1146) )
1371 preserve_entry(orig,access_query); 1595 preserve_entry(orig,access_query);
1372 1596
1373 /* It failed because table didn't exist */ 1597 /* It failed because table didn't exist */
1374 if (result == 1146) { 1598 if (result == 1146) {
1375 ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: hmm, table didn't yet exist; creating"); 1599 ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: hmm, table didn't yet exist; creating");
@@ -1387,17 +1611,20 @@ int log_sql_transaction(request_rec *orig)
1387 } 1611 }
1388 } 1612 }
1389 } 1613 }
1390 1614
1391 /* Log the optional notes, headers, etc. */ 1615 /* Log the optional notes, headers, etc. */
1392 if ( note_query != NULL ) 1616 if ( note_query != NULL )
1393 safe_mysql_query(orig, note_query); 1617 safe_mysql_query(orig, note_query);
1394 1618
1395 if ( hout_query != NULL ) 1619 if ( hout_query != NULL )
1396 safe_mysql_query(orig, hout_query); 1620 safe_mysql_query(orig, hout_query);
1397 1621
1398 if ( hin_query != NULL ) 1622 if ( hin_query != NULL )
1399 safe_mysql_query(orig, hin_query); 1623 safe_mysql_query(orig, hin_query);
1400 1624
1625 if ( cookie_query != NULL )
1626 safe_mysql_query(orig, cookie_query);
1627
1401 return OK; 1628 return OK;
1402 } 1629 }
1403} 1630}
@@ -1406,7 +1633,7 @@ int log_sql_transaction(request_rec *orig)
1406 1633
1407 1634
1408/* The configuration array that sets up the hooks into the module. */ 1635/* The configuration array that sets up the hooks into the module. */
1409module mysql_log_module = { 1636module sql_log_module = {
1410 STANDARD_MODULE_STUFF, 1637 STANDARD_MODULE_STUFF,
1411 NULL, /* module initializer */ 1638 NULL, /* module initializer */
1412 NULL, /* create per-dir config */ 1639 NULL, /* create per-dir config */
@@ -1428,5 +1655,5 @@ module mysql_log_module = {
1428 log_sql_child_exit, /* process exit/cleanup */ 1655 log_sql_child_exit, /* process exit/cleanup */
1429 NULL /* [1] post read-request */ 1656 NULL /* [1] post read-request */
1430#endif 1657#endif
1431 1658
1432}; 1659};