summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG15
-rw-r--r--Makefile.in2
-rw-r--r--configure.ac2
-rw-r--r--create_tables.sql2
-rw-r--r--mod_log_sql.c1153
-rw-r--r--mod_log_sql.prj10
6 files changed, 599 insertions, 585 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 1576da7..de34ba1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,20 +1,23 @@
1$Id: CHANGELOG,v 1.1 2003/12/20 07:16:05 urkle Exp $ 1$Id: CHANGELOG,v 1.2 2003/12/22 04:45:38 urkle Exp $
2 2
3TODO: 3TODO:
4* Rethink documentation flow and rewrite? 4* Rethink documentation flow and rewrite?
5* Port connection portion to other DBMS? Genericize the module? Start with 5* Port connection portion to other DBMS? Genericize the module? Start with
6 PostgreSQL. 6 PostgreSQL. (provider mechanism, and libDBI)
7* GNU autoconf
8* merge server config into vh config 7* merge server config into vh config
9* port to Apache 2.x
10* does determining table name in massvirtual mode upon every request 8* does determining table name in massvirtual mode upon every request
11 cause performance degradation? If so fix. 9 cause performance degradation? If so fix.
12* LogSQLRotateLogs directive with daily/monthly/weekly/etc. 10* LogSQLRotateLogs directive with daily/monthly/weekly/etc.
13* new format char: IP as bigint? 11* new format char: IP as bigint? ( not w/ ipV6 )
14* socket-based middleman daemon with configurable conns, or connect/disconnect. 12* socket-based middleman daemon with configurable conns, or connect/disconnect.
15* ignore by cookie 13* ignore by cookie
16 14
17CHANGES: 15CHANGES:
161.90: ?
17* updated code to compile under apache 2.0
18* rewrote and consolidate configuration handler routines
19* made all functions static.
20* made delayed insert configurable, instead of compile time
18 21
191.18: 221.18:
20* Delayed inserts (a MySQL extension) are now available at compile-time. 23* Delayed inserts (a MySQL extension) are now available at compile-time.
@@ -351,5 +354,3 @@ to MySQL
351* Segmentation fault in case of certain parameters lacking fixed. 354* Segmentation fault in case of certain parameters lacking fixed.
352* Worked around the SIGPIPE signal that's sent in certain events from 355* Worked around the SIGPIPE signal that's sent in certain events from
353* mysql_query(). Minor modifications 356* mysql_query(). Minor modifications
354
355
diff --git a/Makefile.in b/Makefile.in
index 5902fab..b143029 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -11,7 +11,7 @@ CFLAGS = -Wc,-Wall -Wc,-Werror -Wc,-fno-strict-aliasing
11 11
12INCLUDES = -I/usr/include/mysql 12INCLUDES = -I/usr/include/mysql
13 13
14LDADD = 14LDADD = -L/usr/lib/mysql -lmysqlclient
15 15
16EXTRA_DIST = INSTALL LICENSE CHANGELOG make_combined_log.pl 16EXTRA_DIST = INSTALL LICENSE CHANGELOG make_combined_log.pl
17 17
diff --git a/configure.ac b/configure.ac
index 2011793..4fa277a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
1dnl Required initializer 1dnl Required initializer
2AC_INIT(mod_log_sql, 1.99) 2AC_INIT(mod_log_sql, 1.90)
3AC_PREREQ(2.53) 3AC_PREREQ(2.53)
4AC_CONFIG_HEADERS(config.h) 4AC_CONFIG_HEADERS(config.h)
5 5
diff --git a/create_tables.sql b/create_tables.sql
index dbcfbe4..0266b52 100644
--- a/create_tables.sql
+++ b/create_tables.sql
@@ -15,7 +15,7 @@ create table access_log (
15 request_method varchar(10) , 15 request_method varchar(10) ,
16 request_protocol varchar(10) , 16 request_protocol varchar(10) ,
17 request_time char(28), 17 request_time char(28),
18 request_uri varchar(50), 18 request_uri varchar(255),
19 request_args varchar(255), 19 request_args varchar(255),
20 server_port smallint unsigned, 20 server_port smallint unsigned,
21 ssl_cipher varchar(25), 21 ssl_cipher varchar(25),
diff --git a/mod_log_sql.c b/mod_log_sql.c
index 60d2b33..8a48b17 100644
--- a/mod_log_sql.c
+++ b/mod_log_sql.c
@@ -1,70 +1,92 @@
1/* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.2 2003/12/21 17:45:51 urkle Exp $ */ 1/* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.3 2003/12/22 04:45:38 urkle Exp $ */
2/* --------* 2/* --------*
3 * DEFINES * 3 * DEFINES *
4 * --------*/ 4 * --------*/
5 5
6/* The enduser may wish to modify this */ 6/* The enduser may wish to modify this */
7#undef DEBUG 7#define DEBUG
8 8
9/* The enduser won't modify these */ 9/* The enduser won't modify these */
10#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") 10#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
11#define ERRLEVEL APLOG_ERR|APLOG_NOERRNO
12#define WARNINGLEVEL APLOG_WARNING|APLOG_NOERRNO
13#define NOTICELEVEL APLOG_NOTICE|APLOG_NOERRNO
14#define DEBUGLEVEL APLOG_DEBUG|APLOG_NOERRNO
15 11
16/* ---------* 12/* ---------*
17 * INCLUDES * 13 * INCLUDES *
18 * ---------*/ 14 * ---------*/
19#include <time.h> 15
20#include <stdio.h> 16#include "apr_strings.h"
21#include <stdlib.h> 17#include "apr_lib.h"
22#include <string.h> 18#include "apr_hash.h"
19#include "apr_optional.h"
20#define APR_WANT_STRFUNC
21#include "apr_want.h"
22#include "apr_tables.h"
23
24#include "ap_config.h"
25
23#include "httpd.h" 26#include "httpd.h"
24#include "http_config.h" 27#include "http_config.h"
25#include "http_log.h"
26#include "http_core.h" 28#include "http_core.h"
29#include "http_log.h"
30#include "http_protocol.h"
31
32#include "util_time.h"
33
34#if APR_HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37#ifdef HAVE_LIMITS_H
38#include <limits.h>
39#endif
40
27#include "mysql.h" 41#include "mysql.h"
28#include "mysqld_error.h" 42#include "mysqld_error.h"
29 43
30#if MODULE_MAGIC_NUMBER >= 19980324 /* M_M_N is defined in /usr/local/Apache/include/ap_mmn.h, 19990320 as of this writing. */ 44#ifdef HAVE_CONFIG_H
31 #include "ap_compat.h" 45/* Undefine these to prevent conflicts between Apache ap_config_auto.h and
46 * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt.
47 */
48#undef PACKAGE_BUGREPORT
49#undef PACKAGE_NAME
50#undef PACKAGE_STRING
51#undef PACKAGE_TARNAME
52#undef PACKAGE_VERSION
53
54#include "config.h"
32#endif 55#endif
33 56
34#ifdef WANT_SSL_LOGGING 57#ifdef WANT_SSL_LOGGING
35 #include "mod_ssl.h" 58#include "mod_ssl.h"
36#endif 59#endif
37 60
38
39/* -------------* 61/* -------------*
40 * DECLARATIONS * 62 * DECLARATIONS *
41 * -------------*/ 63 * -------------*/
42 64
43/* Declare ourselves so the configuration routines can find and know us. */ 65/* Declare ourselves so the configuration routines can find and know us. */
44module sql_log_module; 66module AP_MODULE_DECLARE_DATA log_sql_module;
45 67
46/* The contents of these are known 'Apache wide' and are not variable 68/* The contents of these are known 'Apache wide' and are not variable
47 * on a per-virtual-server basis. Every virtual server 'knows' the 69 * on a per-virtual-server basis. Every virtual server 'knows' the
48 * same versions of these variables. 70 * same versions of these variables.
49 */ 71 */
50MYSQL logsql_server, *logsql_server_p = NULL; 72
51 73typedef struct {
52int logsql_massvirtual = 0; 74 int massvirtual;
53int logsql_createtables = 0; 75 int createtables;
54int logsql_forcepreserve = 0; 76 int forcepreserve;
55char *logsql_dbname = NULL; 77 char *dbname;
56char *logsql_dbhost = NULL; 78 char *dbhost;
57char *logsql_dbuser = NULL; 79 char *dbuser;
58char *logsql_dbpwd = NULL; 80 char *dbpwd;
59char *logsql_machid = NULL; 81 char *machid;
60char *logsql_socketfile = "/tmp/mysql.sock"; 82 char *socketfile;
61unsigned int logsql_tcpport = 3306; 83 unsigned int tcpport;
62 84 int insertdelayed;
63#ifdef WANT_DELAYED_MYSQL_INSERT 85 MYSQL server;
64 char *logsql_insertclause = "insert delayed into "; 86 MYSQL *server_p;
65#else 87} global_config_t;
66 char *logsql_insertclause = "insert into "; 88
67#endif 89static global_config_t global_config;
68 90
69typedef const char *(*item_key_func) (request_rec *, char *); 91typedef const char *(*item_key_func) (request_rec *, char *);
70 92
@@ -75,13 +97,13 @@ typedef const char *(*item_key_func) (request_rec *, char *);
75 * Each child process has its own segregated copy of this structure. 97 * Each child process has its own segregated copy of this structure.
76 */ 98 */
77typedef struct { 99typedef struct {
78 apr_array_t *transfer_ignore_list; 100 apr_array_header_t *transfer_ignore_list;
79 array_header *transfer_accept_list; 101 apr_array_header_t *transfer_accept_list;
80 array_header *remhost_ignore_list; 102 apr_array_header_t *remhost_ignore_list;
81 array_header *notes_list; 103 apr_array_header_t *notes_list;
82 array_header *hout_list; 104 apr_array_header_t *hout_list;
83 array_header *hin_list; 105 apr_array_header_t *hin_list;
84 array_header *cookie_list; 106 apr_array_header_t *cookie_list;
85 char *notes_table_name; 107 char *notes_table_name;
86 char *hout_table_name; 108 char *hout_table_name;
87 char *hin_table_name; 109 char *hin_table_name;
@@ -97,16 +119,16 @@ typedef struct {
97 * HELPER FUNCTIONS * 119 * HELPER FUNCTIONS *
98 * -----------------*/ 120 * -----------------*/
99 121
100int safe_create_tables(logsql_state *cls, request_rec *r); 122static int safe_create_tables(logsql_state *cls, request_rec *r);
101 123
102static char *format_integer(pool *p, int i) 124static char *format_integer(apr_pool_t *p, int i)
103{ 125{
104 char dummy[40]; 126 char dummy[40];
105 ap_snprintf(dummy, sizeof(dummy), "%d", i); 127 apr_snprintf(dummy, sizeof(dummy), "%d", i);
106 return pstrdup(p, dummy); 128 return apr_pstrdup(p, dummy);
107} 129}
108 130
109static char *pfmt(pool *p, int i) 131static char *pfmt(apr_pool_t *p, int i)
110{ 132{
111 if (i <= 0) { 133 if (i <= 0) {
112 return "-"; 134 return "-";
@@ -122,17 +144,17 @@ static char *pfmt(pool *p, int i)
122 144
123static const char *extract_remote_host(request_rec *r, char *a) 145static const char *extract_remote_host(request_rec *r, char *a)
124{ 146{
125 return (char *) get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); 147 return (char *) ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL);
126} 148}
127 149
128static const char *extract_remote_logname(request_rec *r, char *a) 150static const char *extract_remote_logname(request_rec *r, char *a)
129{ 151{
130 return (char *) get_remote_logname(r); 152 return (char *) ap_get_remote_logname(r);
131} 153}
132 154
133static const char *extract_remote_user(request_rec *r, char *a) 155static const char *extract_remote_user(request_rec *r, char *a)
134{ 156{
135 char *rvalue = r->connection->user; 157 char *rvalue = r->user;
136 158
137 if (rvalue == NULL) { 159 if (rvalue == NULL) {
138 rvalue = "-"; 160 rvalue = "-";
@@ -150,7 +172,7 @@ static const char *extract_ssl_keysize(request_rec *r, char *a)
150 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 172 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
151 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE"); 173 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE");
152 #ifdef DEBUG 174 #ifdef DEBUG
153 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"SSL_KEYSIZE: %s", result); 175 ap_log_error(APLOG_MARK,APLOG_DEBUG,r->server,"SSL_KEYSIZE: %s", result);
154 #endif 176 #endif
155 if (result != NULL && result[0] == '\0') 177 if (result != NULL && result[0] == '\0')
156 result = NULL; 178 result = NULL;
@@ -167,7 +189,7 @@ static const char *extract_ssl_maxkeysize(request_rec *r, char *a)
167 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 189 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
168 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE"); 190 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE");
169 #ifdef DEBUG 191 #ifdef DEBUG
170 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"SSL_ALGKEYSIZE: %s", result); 192 ap_log_error(APLOG_MARK,APLOG_DEBUG,r->server,"SSL_ALGKEYSIZE: %s", result);
171 #endif 193 #endif
172 if (result != NULL && result[0] == '\0') 194 if (result != NULL && result[0] == '\0')
173 result = NULL; 195 result = NULL;
@@ -184,7 +206,7 @@ static const char *extract_ssl_cipher(request_rec *r, char *a)
184 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { 206 if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) {
185 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); 207 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");
186 #ifdef DEBUG 208 #ifdef DEBUG
187 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"SSL_CIPHER: %s", result); 209 ap_log_error(APLOG_MARK,APLOG_DEBUG,r->server,"SSL_CIPHER: %s", result);
188 #endif 210 #endif
189 if (result != NULL && result[0] == '\0') 211 if (result != NULL && result[0] == '\0')
190 result = NULL; 212 result = NULL;
@@ -232,14 +254,10 @@ static const char *extract_status(request_rec *r, char *a)
232 254
233static const char *extract_bytes_sent(request_rec *r, char *a) 255static const char *extract_bytes_sent(request_rec *r, char *a)
234{ 256{
235 if (!r->sent_bodyct) { 257 if (!r->sent_bodyct || !r->bytes_sent) {
236 return "-"; 258 return "-";
237 } else { 259 } else {
238 long int bs; 260 return apr_psprintf(r->pool, "%" APR_OFF_T_FMT, r->bytes_sent);
239 char dummy[40];
240 bgetopt(r->connection->client, BO_BYTECT, &bs);
241 ap_snprintf(dummy, sizeof(dummy), "%ld", bs);
242 return pstrdup(r->pool, dummy);
243 } 261 }
244} 262}
245 263
@@ -261,71 +279,141 @@ static const char *extract_header_out(request_rec *r, char *a)
261 return table_get(r->err_headers_out, a); 279 return table_get(r->err_headers_out, a);
262} 280}
263*/ 281*/
282static const char *extract_request_time_custom(request_rec *r, char *a,
283 apr_time_exp_t *xt)
284{
285 apr_size_t retcode;
286 char tstr[MAX_STRING_LEN];
287 apr_strftime(tstr, &retcode, sizeof(tstr), a, xt);
288 return apr_pstrdup(r->pool, tstr);
289}
290
291#define DEFAULT_REQUEST_TIME_SIZE 32
292typedef struct {
293 unsigned t;
294 char timestr[DEFAULT_REQUEST_TIME_SIZE];
295 unsigned t_validate;
296} cached_request_time;
297
298#define TIME_CACHE_SIZE 4
299#define TIME_CACHE_MASK 3
300static cached_request_time request_time_cache[TIME_CACHE_SIZE];
264 301
265static const char *extract_request_time(request_rec *r, char *a) 302static const char *extract_request_time(request_rec *r, char *a)
266{ 303{
267 int timz; 304 apr_time_exp_t xt;
268 struct tm *t;
269 char tstr[MAX_STRING_LEN];
270
271 t = get_gmtoff(&timz);
272 305
306 /* Please read comments in mod_log_config.h for more info about
307 * the I_INSIST....COMPLIANCE define
308 */
273 if (a && *a) { /* Custom format */ 309 if (a && *a) { /* Custom format */
274 strftime(tstr, MAX_STRING_LEN, a, t); 310#ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE
311 ap_explode_recent_localtime(&xt, apr_time_now());
312#else
313 ap_explode_recent_localtime(&xt, r->request_time);
314#endif
315 return extract_request_time_custom(r, a, &xt);
275 } else { /* CLF format */ 316 } else { /* CLF format */
276 char sign = (timz < 0 ? '-' : '+'); 317 /* This code uses the same technique as ap_explode_recent_localtime():
277 318 * optimistic caching with logic to detect and correct race conditions.
278 if (timz < 0) { 319 * See the comments in server/util_time.c for more information.
279 timz = -timz; 320 */
321 cached_request_time* cached_time = apr_palloc(r->pool,
322 sizeof(*cached_time));
323#ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE
324 apr_time_t request_time = apr_time_now();
325#else
326 apr_time_t request_time = r->request_time;
327#endif
328 unsigned t_seconds = (unsigned)apr_time_sec(request_time);
329 unsigned i = t_seconds & TIME_CACHE_MASK;
330 memcpy(cached_time, &(request_time_cache[i]), sizeof(*cached_time));
331 if ((t_seconds != cached_time->t) ||
332 (t_seconds != cached_time->t_validate)) {
333
334 /* Invalid or old snapshot, so compute the proper time string
335 * and store it in the cache
336 */
337 char sign;
338 int timz;
339
340 ap_explode_recent_localtime(&xt, r->request_time);
341 timz = xt.tm_gmtoff;
342 if (timz < 0) {
343 timz = -timz;
344 sign = '-';
345 }
346 else {
347 sign = '+';
348 }
349 cached_time->t = t_seconds;
350 apr_snprintf(cached_time->timestr, DEFAULT_REQUEST_TIME_SIZE,
351 "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]",
352 xt.tm_mday, apr_month_snames[xt.tm_mon],
353 xt.tm_year+1900, xt.tm_hour, xt.tm_min, xt.tm_sec,
354 sign, timz / (60*60), timz % (60*60));
355 cached_time->t_validate = t_seconds;
356 memcpy(&(request_time_cache[i]), cached_time,
357 sizeof(*cached_time));
280 } 358 }
281 strftime(tstr, MAX_STRING_LEN, "[%d/%b/%Y:%H:%M:%S ", t); 359 return cached_time->timestr;
282 ap_snprintf(tstr + strlen(tstr), sizeof(tstr) - strlen(tstr), "%c%.2d%.2d]", sign, timz / 60, timz % 60);
283 } 360 }
284
285 return pstrdup(r->pool, tstr);
286} 361}
287 362
288static const char *extract_request_duration(request_rec *r, char *a) 363static const char *extract_request_duration(request_rec *r, char *a)
289{ 364{
290 char duration[22]; /* Long enough for 2^64 */ 365 apr_time_t duration = apr_time_now() - r->request_time;
366 return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, apr_time_sec(duration));
367}
291 368
292 ap_snprintf(duration, sizeof(duration), "%ld", time(NULL) - r->request_time); 369static const char *extract_request_duration_microseconds(request_rec *r, char *a) __attribute__ ((unused));
293 return pstrdup(r->pool, duration); 370static const char *extract_request_duration_microseconds(request_rec *r, char *a)
371{
372 return apr_psprintf(r->pool, "%" APR_TIME_T_FMT,
373 (apr_time_now() - r->request_time));
294} 374}
295 375
296static const char *extract_virtual_host(request_rec *r, char *a) 376static const char *extract_virtual_host(request_rec *r, char *a)
297{ 377{
298 return ap_get_server_name(r); 378 return apr_pstrdup(r->pool, r->server->server_hostname);
299} 379}
300 380
301static const char *extract_machine_id(request_rec *r, char *a) 381static const char *extract_machine_id(request_rec *r, char *a)
302{ 382{
303 if (!logsql_machid) 383 if (!global_config.machid)
304 return "-"; 384 return "-";
305 else 385 else
306 return logsql_machid; 386 return global_config.machid;
307} 387}
308 388
309static const char *extract_server_port(request_rec *r, char *a) 389static const char *extract_server_port(request_rec *r, char *a)
310{ 390{
311 char portnum[22]; 391 return apr_psprintf(r->pool, "%u",
312 392 r->server->port ? r->server->port : ap_default_port(r));
313 ap_snprintf(portnum, sizeof(portnum), "%u", r->server->port);
314 return pstrdup(r->pool, portnum);
315} 393}
316 394
317static const char *extract_child_pid(request_rec *r, char *a) 395static const char *extract_child_pid(request_rec *r, char *a)
318{ 396{
319 char pidnum[22]; 397 if (*a == '\0' || !strcmp(a, "pid")) {
320 ap_snprintf(pidnum, sizeof(pidnum), "%ld", (long) getpid()); 398 return apr_psprintf(r->pool, "%" APR_PID_T_FMT, getpid());
321 return pstrdup(r->pool, pidnum); 399 }
400 else if (!strcmp(a, "tid")) {
401#if APR_HAS_THREADS
402 apr_os_thread_t tid = apr_os_thread_current();
403#else
404 int tid = 0; /* APR will format "0" anyway but an arg is needed */
405#endif
406 return apr_psprintf(r->pool, "%pT", &tid);
407 }
408 /* bogus format */
409 return a;
322} 410}
323 411
324static const char *extract_referer(request_rec *r, char *a) 412static const char *extract_referer(request_rec *r, char *a)
325{ 413{
326 const char *tempref; 414 const char *tempref;
327 415
328 tempref = table_get(r->headers_in, "Referer"); 416 tempref = apr_table_get(r->headers_in, "Referer");
329 if (!tempref) 417 if (!tempref)
330 { 418 {
331 return "-"; 419 return "-";
@@ -338,7 +426,7 @@ static const char *extract_agent(request_rec *r, char *a)
338{ 426{
339 const char *tempag; 427 const char *tempag;
340 428
341 tempag = table_get(r->headers_in, "User-Agent"); 429 tempag = apr_table_get(r->headers_in, "User-Agent");
342 if (!tempag) 430 if (!tempag)
343 { 431 {
344 return "-"; 432 return "-";
@@ -354,18 +442,21 @@ static const char *extract_cookie(request_rec *r, char *a)
354 char *isvalid; 442 char *isvalid;
355 char *cookiebuf; 443 char *cookiebuf;
356 444
357 logsql_state *cls = get_module_config(r->server->module_config, &sql_log_module); 445 logsql_state *cls = ap_get_module_config(r->server->module_config,
446 &log_sql_module);
358 447
359 if (cls->cookie_name != NULL) { 448 if (cls->cookie_name != NULL) {
360 #ifdef DEBUG 449 #ifdef DEBUG
361 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", cls->cookie_name); 450 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, r,
451 "watching for cookie '%s'", cls->cookie_name);
362 #endif 452 #endif
363 453
364 /* Fetch out the cookie header */ 454 /* Fetch out the cookie header */
365 cookiestr = (char *)table_get(r->headers_in, "cookie2"); 455 cookiestr = (char *)apr_table_get(r->headers_in, "cookie2");
366 if (cookiestr != NULL) { 456 if (cookiestr != NULL) {
367 #ifdef DEBUG 457 #ifdef DEBUG
368 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie2: [%s]", cookiestr); 458 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, r,
459 "Cookie2: [%s]", cookiestr);
369 #endif 460 #endif
370 /* Does the cookie string contain one with our name? */ 461 /* Does the cookie string contain one with our name? */
371 isvalid = strstr(cookiestr, cls->cookie_name); 462 isvalid = strstr(cookiestr, cls->cookie_name);
@@ -373,7 +464,7 @@ static const char *extract_cookie(request_rec *r, char *a)
373 /* Move past the cookie name and equal sign */ 464 /* Move past the cookie name and equal sign */
374 isvalid += strlen(cls->cookie_name) + 1; 465 isvalid += strlen(cls->cookie_name) + 1;
375 /* Duplicate it into the pool */ 466 /* Duplicate it into the pool */
376 cookiebuf = ap_pstrdup(r->pool, isvalid); 467 cookiebuf = apr_pstrdup(r->pool, isvalid);
377 /* Segregate just this cookie out of the string 468 /* Segregate just this cookie out of the string
378 * with a terminating nul at the first semicolon */ 469 * with a terminating nul at the first semicolon */
379 cookieend = strchr(cookiebuf, ';'); 470 cookieend = strchr(cookiebuf, ';');
@@ -383,15 +474,16 @@ static const char *extract_cookie(request_rec *r, char *a)
383 } 474 }
384 } 475 }
385 476
386 cookiestr = (char *)table_get(r->headers_in, "cookie"); 477 cookiestr = (char *)apr_table_get(r->headers_in, "cookie");
387 if (cookiestr != NULL) { 478 if (cookiestr != NULL) {
388 #ifdef DEBUG 479 #ifdef DEBUG
389 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie: [%s]", cookiestr); 480 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,r,
481 "Cookie: [%s]", cookiestr);
390 #endif 482 #endif
391 isvalid = strstr(cookiestr, cls->cookie_name); 483 isvalid = strstr(cookiestr, cls->cookie_name);
392 if (isvalid != NULL) { 484 if (isvalid != NULL) {
393 isvalid += strlen(cls->cookie_name) + 1; 485 isvalid += strlen(cls->cookie_name) + 1;
394 cookiebuf = ap_pstrdup(r->pool, isvalid); 486 cookiebuf = apr_pstrdup(r->pool, isvalid);
395 cookieend = strchr(cookiebuf, ';'); 487 cookieend = strchr(cookiebuf, ';');
396 if (cookieend != NULL) 488 if (cookieend != NULL)
397 *cookieend = '\0'; 489 *cookieend = '\0';
@@ -399,15 +491,16 @@ static const char *extract_cookie(request_rec *r, char *a)
399 } 491 }
400 } 492 }
401 493
402 cookiestr = table_get(r->headers_out, "set-cookie"); 494 cookiestr = apr_table_get(r->headers_out, "set-cookie");
403 if (cookiestr != NULL) { 495 if (cookiestr != NULL) {
404 #ifdef DEBUG 496 #ifdef DEBUG
405 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Set-Cookie: [%s]", cookiestr); 497 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,r,
498 "Set-Cookie: [%s]", cookiestr);
406 #endif 499 #endif
407 isvalid = strstr(cookiestr, cls->cookie_name); 500 isvalid = strstr(cookiestr, cls->cookie_name);
408 if (isvalid != NULL) { 501 if (isvalid != NULL) {
409 isvalid += strlen(cls->cookie_name) + 1; 502 isvalid += strlen(cls->cookie_name) + 1;
410 cookiebuf = ap_pstrdup(r->pool, isvalid); 503 cookiebuf = apr_pstrdup(r->pool, isvalid);
411 cookieend = strchr(cookiebuf, ';'); 504 cookieend = strchr(cookiebuf, ';');
412 if (cookieend != NULL) 505 if (cookieend != NULL)
413 *cookieend = '\0'; 506 *cookieend = '\0';
@@ -428,14 +521,16 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
428 521
429 if (a != NULL) { 522 if (a != NULL) {
430 #ifdef DEBUG 523 #ifdef DEBUG
431 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", a); 524 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,
525 r,"watching for cookie '%s'", a);
432 #endif 526 #endif
433 527
434 /* Fetch out the cookie header */ 528 /* Fetch out the cookie header */
435 cookiestr = (char *)table_get(r->headers_in, "cookie2"); 529 cookiestr = (char *)apr_table_get(r->headers_in, "cookie2");
436 if (cookiestr != NULL) { 530 if (cookiestr != NULL) {
437 #ifdef DEBUG 531 #ifdef DEBUG
438 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie2: [%s]", cookiestr); 532 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,r,
533 "Cookie2: [%s]", cookiestr);
439 #endif 534 #endif
440 /* Does the cookie string contain one with our name? */ 535 /* Does the cookie string contain one with our name? */
441 isvalid = strstr(cookiestr, a); 536 isvalid = strstr(cookiestr, a);
@@ -443,7 +538,7 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
443 /* Move past the cookie name and equal sign */ 538 /* Move past the cookie name and equal sign */
444 isvalid += strlen(a) + 1; 539 isvalid += strlen(a) + 1;
445 /* Duplicate it into the pool */ 540 /* Duplicate it into the pool */
446 cookiebuf = ap_pstrdup(r->pool, isvalid); 541 cookiebuf = apr_pstrdup(r->pool, isvalid);
447 /* Segregate just this cookie out of the string 542 /* Segregate just this cookie out of the string
448 * with a terminating nul at the first semicolon */ 543 * with a terminating nul at the first semicolon */
449 cookieend = strchr(cookiebuf, ';'); 544 cookieend = strchr(cookiebuf, ';');
@@ -453,15 +548,16 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
453 } 548 }
454 } 549 }
455 550
456 cookiestr = (char *)table_get(r->headers_in, "cookie"); 551 cookiestr = (char *)apr_table_get(r->headers_in, "cookie");
457 if (cookiestr != NULL) { 552 if (cookiestr != NULL) {
458 #ifdef DEBUG 553 #ifdef DEBUG
459 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie: [%s]", cookiestr); 554 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,r,
555 "Cookie: [%s]", cookiestr);
460 #endif 556 #endif
461 isvalid = strstr(cookiestr, a); 557 isvalid = strstr(cookiestr, a);
462 if (isvalid != NULL) { 558 if (isvalid != NULL) {
463 isvalid += strlen(a) + 1; 559 isvalid += strlen(a) + 1;
464 cookiebuf = ap_pstrdup(r->pool, isvalid); 560 cookiebuf = apr_pstrdup(r->pool, isvalid);
465 cookieend = strchr(cookiebuf, ';'); 561 cookieend = strchr(cookiebuf, ';');
466 if (cookieend != NULL) 562 if (cookieend != NULL)
467 *cookieend = '\0'; 563 *cookieend = '\0';
@@ -469,15 +565,16 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
469 } 565 }
470 } 566 }
471 567
472 cookiestr = table_get(r->headers_out, "set-cookie"); 568 cookiestr = apr_table_get(r->headers_out, "set-cookie");
473 if (cookiestr != NULL) { 569 if (cookiestr != NULL) {
474 #ifdef DEBUG 570 #ifdef DEBUG
475 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Set-Cookie: [%s]", cookiestr); 571 ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0,r,
572 "Set-Cookie: [%s]", cookiestr);
476 #endif 573 #endif
477 isvalid = strstr(cookiestr, a); 574 isvalid = strstr(cookiestr, a);
478 if (isvalid != NULL) { 575 if (isvalid != NULL) {
479 isvalid += strlen(a) + 1; 576 isvalid += strlen(a) + 1;
480 cookiebuf = ap_pstrdup(r->pool, isvalid); 577 cookiebuf = apr_pstrdup(r->pool, isvalid);
481 cookieend = strchr(cookiebuf, ';'); 578 cookieend = strchr(cookiebuf, ';');
482 if (cookieend != NULL) 579 if (cookieend != NULL)
483 *cookieend = '\0'; 580 *cookieend = '\0';
@@ -492,30 +589,27 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
492 589
493static const char *extract_request_timestamp(request_rec *r, char *a) 590static const char *extract_request_timestamp(request_rec *r, char *a)
494{ 591{
495 char tstr[32]; 592 return apr_psprintf(r->pool, "%ld", time(NULL));
496
497 ap_snprintf(tstr, 32, "%ld", time(NULL));
498 return pstrdup(r->pool, tstr);
499} 593}
500 594
501/* 595/*
502static const char *extract_note(request_rec *r, char *a) 596static const char *extract_note(request_rec *r, char *a)
503{ 597{
504 return ap_table_get(r->notes, a); 598 return apr_table_get(r->notes, a);
505 599
506} 600}
507*/ 601*/
508 602
509static const char *extract_env_var(request_rec *r, char *a) 603static const char *extract_env_var(request_rec *r, char *a)
510{ 604{
511 return ap_table_get(r->subprocess_env, a); 605 return apr_table_get(r->subprocess_env, a);
512} 606}
513 607
514static const char *extract_unique_id(request_rec *r, char *a) 608static const char *extract_unique_id(request_rec *r, char *a)
515{ 609{
516 const char *tempid; 610 const char *tempid;
517 611
518 tempid = ap_table_get(r->subprocess_env, "UNIQUE_ID"); 612 tempid = apr_table_get(r->subprocess_env, "UNIQUE_ID");
519 if (!tempid) 613 if (!tempid)
520 return "-"; 614 return "-";
521 else 615 else
@@ -532,7 +626,7 @@ struct log_sql_item_list {
532 const char *sql_field_name; /* its column in SQL */ 626 const char *sql_field_name; /* its column in SQL */
533 int want_orig_default; /* if it requires the original request prior to internal redirection */ 627 int want_orig_default; /* if it requires the original request prior to internal redirection */
534 int string_contents; /* if it returns a string */ 628 int string_contents; /* if it returns a string */
535 } log_sql_item_keys[] = { 629 } static log_sql_item_keys[] = {
536 630
537 { 'A', extract_agent, "agent", 1, 1 }, 631 { 'A', extract_agent, "agent", 1, 1 },
538 { 'a', extract_request_args, "request_args", 1, 1 }, 632 { 'a', extract_request_args, "request_args", 1, 1 },
@@ -569,7 +663,7 @@ struct log_sql_item_list {
569/* Routine to escape the 'dangerous' characters that would otherwise 663/* Routine to escape the 'dangerous' characters that would otherwise
570 * corrupt the INSERT string: ', \, and " 664 * corrupt the INSERT string: ', \, and "
571 */ 665 */
572const char *escape_query(const char *from_str, pool *p) 666static const char *escape_query(const char *from_str, apr_pool_t *p)
573{ 667{
574 if (!from_str) 668 if (!from_str)
575 return NULL; 669 return NULL;
@@ -581,12 +675,12 @@ const char *escape_query(const char *from_str, pool *p)
581 /* Pre-allocate a new string that could hold twice the original, which would only 675 /* Pre-allocate a new string that could hold twice the original, which would only
582 * happen if the whole original string was 'dangerous' characters. 676 * happen if the whole original string was 'dangerous' characters.
583 */ 677 */
584 to_str = (char *) ap_palloc(p, length * 2 + 1); 678 to_str = (char *) apr_palloc(p, length * 2 + 1);
585 if (!to_str) { 679 if (!to_str) {
586 return from_str; 680 return from_str;
587 } 681 }
588 682
589 if (!logsql_server_p) { 683 if (!global_config.server_p) {
590 /* Well, I would have liked to use the current database charset. mysql is 684 /* Well, I would have liked to use the current database charset. mysql is
591 * unavailable, however, so I fall back to the slightly less respectful 685 * unavailable, however, so I fall back to the slightly less respectful
592 * mysql_escape_string() function that uses the default charset. 686 * mysql_escape_string() function that uses the default charset.
@@ -596,7 +690,7 @@ const char *escape_query(const char *from_str, pool *p)
596 /* MySQL is available, so I'll go ahead and respect the current charset when 690 /* MySQL is available, so I'll go ahead and respect the current charset when
597 * I perform the escape. 691 * I perform the escape.
598 */ 692 */
599 retval = mysql_real_escape_string(logsql_server_p, to_str, from_str, length); 693 retval = mysql_real_escape_string(global_config.server_p, to_str, from_str, length);
600 } 694 }
601 695
602 if (retval) 696 if (retval)
@@ -606,7 +700,7 @@ const char *escape_query(const char *from_str, pool *p)
606 } 700 }
607} 701}
608 702
609int open_logdb_link(server_rec* s) 703static int open_logdb_link(server_rec* s)
610{ 704{
611 /* Returns: 705 /* Returns:
612 3 if preserve forced 706 3 if preserve forced
@@ -615,91 +709,89 @@ int open_logdb_link(server_rec* s)
615 0 if unsuccessful 709 0 if unsuccessful
616 */ 710 */
617 711
618 if (logsql_forcepreserve) 712 if (global_config.forcepreserve)
619 return 3; 713 return 3;
620 714
621 if (logsql_server_p) 715 if (global_config.server_p)
622 return 2; 716 return 2;
623 717
624 if ((logsql_dbname) && (logsql_dbhost) && (logsql_dbuser) && (logsql_dbpwd)) { 718 if ((global_config.dbname) && (global_config.dbhost) && (global_config.dbuser) && (global_config.dbpwd)) {
625 mysql_init(&logsql_server); 719 mysql_init(&global_config.server);
626 logsql_server_p = mysql_real_connect(&logsql_server, logsql_dbhost, logsql_dbuser, logsql_dbpwd, logsql_dbname, logsql_tcpport, logsql_socketfile, 0); 720 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);
627 721
628 if (logsql_server_p) { 722 if (global_config.server_p) {
629 #ifdef DEBUG 723 #ifdef DEBUG
630 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", 724 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
631 logsql_dbhost, logsql_tcpport, logsql_dbname, logsql_dbuser, logsql_socketfile); 725 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
632 #endif 726 #endif
633 return 1; 727 return 1;
634 } else { 728 } else {
635 #ifdef DEBUG 729 #ifdef DEBUG
636 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&logsql_server)); 730 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&global_config.server));
637 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", 731 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
638 logsql_dbhost, logsql_tcpport, logsql_dbname, logsql_dbuser, logsql_socketfile); 732 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
639 #endif 733 #endif
640 return 0; 734 return 0;
641 } 735 }
642 } else { 736 } else {
643 ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: insufficient configuration info to establish database link"); 737 ap_log_error(APLOG_MARK,APLOG_ERR,0,s,"mod_log_sql: insufficient configuration info to establish database link");
644 return 0; 738 return 0;
645 } 739 }
646} 740}
647 741
648const char *extract_table(void *data, const char *key, const char *val) 742/*static const char *extract_table(void *data, const char *key, const char *val)
649{ 743{
650 request_rec *r = (request_rec *)data; 744 request_rec *r = (request_rec *)data;
651 745
652 return ap_pstrcat(r->pool, key, " = ", val, " ", NULL); 746 return apr_pstrcat(r->pool, key, " = ", val, " ", NULL);
653} 747}*/
654 748
655void preserve_entry(request_rec *r, const char *query) 749static void preserve_entry(request_rec *r, const char *query)
656{ 750{
657 FILE *fp; 751 apr_file_t *fp;
658 logsql_state *cls = get_module_config(r->server->module_config, &sql_log_module); 752 logsql_state *cls = ap_get_module_config(r->server->module_config,
753 &log_sql_module);
659 754
660 fp = pfopen(r->pool, cls->preserve_file, "a"); 755 if (apr_file_open(&fp, cls->preserve_file,APR_APPEND, APR_OS_DEFAULT, r->pool)!=APR_SUCCESS) {
661 if (fp == NULL) 756 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: attempted append of local preserve file but failed.");
662 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: attempted append of local preserve file but failed."); 757 } else {
663 else { 758 apr_file_printf(fp,"%s;\n", query);
664 fprintf(fp,"%s;\n", query); 759 apr_file_close(fp);
665 pfclose(r->pool, fp);
666 #ifdef DEBUG 760 #ifdef DEBUG
667 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file); 761 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file);
668 #endif 762 #endif
669 } 763 }
670} 764}
671 765
672 766
673/*-----------------------------------------------------*/ 767/*-----------------------------------------------------*
674/* safe_sql_query: perform a database query with */ 768 * safe_sql_query: perform a database query with *
675/* a degree of safety and error checking. */ 769 * a degree of safety and error checking. *
676/* */ 770 * *
677/* Parms: request record, SQL insert statement */ 771 * Parms: request record, SQL insert statement *
678/* Returns: 0 (OK) on success */ 772 * Returns: 0 (OK) on success *
679/* 1 if have no log handle */ 773 * 1 if have no log handle *
680/* 2 if insert delayed failed (kluge) */ 774 * 2 if insert delayed failed (kluge) *
681/* the actual MySQL return code on error */ 775 * the actual MySQL return code on error *
682/*-----------------------------------------------------*/ 776 *-----------------------------------------------------*/
683unsigned int safe_sql_query(request_rec *r, const char *query) 777static unsigned int safe_sql_query(request_rec *r, const char *query)
684{ 778{
685 int retval; 779 int retval;
686 struct timespec delay, remainder; 780 struct timespec delay, remainder;
687 int ret; 781 int ret;
688 void (*handler) (int); 782 void (*handler) (int);
689 logsql_state *cls; 783 logsql_state *cls;
690 unsigned int real_error; 784 unsigned int real_error = 0;
691 #ifdef WANT_DELAYED_MYSQL_INSERT 785 char *real_error_str = NULL;
692 char *real_error_str;
693 #endif
694 786
695 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ 787 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
696 handler = signal(SIGPIPE, SIG_IGN); 788 handler = signal(SIGPIPE, SIG_IGN);
697 789
698 /* First attempt for the query */ 790 /* First attempt for the query */
699 if (!logsql_server_p) { 791 if (!global_config.server_p) {
700 signal(SIGPIPE, handler); 792 signal(SIGPIPE, handler);
701 return 1; 793 return 1;
702 } else if (!(retval = mysql_query(logsql_server_p, query))) { 794 } else if (!(retval = mysql_query(global_config.server_p, query))) {
703 signal(SIGPIPE, handler); 795 signal(SIGPIPE, handler);
704 return 0; 796 return 0;
705 } 797 }
@@ -707,37 +799,38 @@ unsigned int safe_sql_query(request_rec *r, const char *query)
707 /* If we ran the query and it returned an error, try to be robust. 799 /* If we ran the query and it returned an error, try to be robust.
708 * (After all, the module thought it had a valid mysql_log connection but the query 800 * (After all, the module thought it had a valid mysql_log connection but the query
709 * could have failed for a number of reasons, so we have to be extra-safe and check.) */ 801 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
710 #ifdef WANT_DELAYED_MYSQL_INSERT 802 if (global_config.insertdelayed) {
711 real_error_str = MYSQL_ERROR(logsql_server_p); 803 real_error_str = MYSQL_ERROR(global_config.server_p);
712 #else 804 } else {
713 real_error = mysql_errno(logsql_server_p); 805 real_error = mysql_errno(global_config.server_p);
714 #endif 806 }
715 807
716 /* Check to see if the error is "nonexistent table" */ 808 /* Check to see if the error is "nonexistent table" */
717 #ifdef WANT_DELAYED_MYSQL_INSERT 809 if (global_config.insertdelayed) {
718 if ((strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"))) { 810 retval = (strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"));
719 #else 811 } else {
720 if (real_error == ER_NO_SUCH_TABLE) { 812 retval = (real_error == ER_NO_SUCH_TABLE);
721 #endif 813 }
722 if (logsql_createtables) { 814 if (retval) {
723 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: table doesn't exist...creating now"); 815 if (global_config.createtables) {
724 cls = get_module_config(r->server->module_config, &sql_log_module); 816 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: table doesn't exist...creating now");
817 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
725 if (safe_create_tables(cls, r)) { 818 if (safe_create_tables(cls, r)) {
726 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r)); 819 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r));
727 preserve_entry(r, query); 820 preserve_entry(r, query);
728 retval = mysql_errno(logsql_server_p); 821 retval = mysql_errno(global_config.server_p);
729 } else { 822 } else {
730 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: tables successfully created - retrying query"); 823 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: tables successfully created - retrying query");
731 if (mysql_query(logsql_server_p, query)) { 824 if (mysql_query(global_config.server_p, query)) {
732 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: giving up, preserving query"); 825 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: giving up, preserving query");
733 preserve_entry(r, query); 826 preserve_entry(r, query);
734 retval = mysql_errno(logsql_server_p); 827 retval = mysql_errno(global_config.server_p);
735 } else 828 } else
736 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: query successful after table creation"); 829 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: query successful after table creation");
737 retval = 0; 830 retval = 0;
738 } 831 }
739 } else { 832 } else {
740 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query"); 833 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query");
741 preserve_entry(r, query); 834 preserve_entry(r, query);
742 retval = ER_NO_SUCH_TABLE; 835 retval = ER_NO_SUCH_TABLE;
743 } 836 }
@@ -748,64 +841,66 @@ unsigned int safe_sql_query(request_rec *r, const char *query)
748 841
749 /* Handle all other types of errors */ 842 /* Handle all other types of errors */
750 843
751 cls = get_module_config(r->server->module_config, &sql_log_module); 844 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
752 845
753 /* Something went wrong, so start by trying to restart the db link. */ 846 /* Something went wrong, so start by trying to restart the db link. */
754 #ifdef WANT_DELAYED_MYSQL_INSERT 847 if (global_config.insertdelayed) {
755 real_error = 2; 848 real_error = 2;
756 #else 849 } else {
757 real_error = mysql_errno(logsql_server_p); 850 real_error = mysql_errno(global_config.server_p);
758 #endif 851 }
759 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: error %d, \"%s\"", real_error, MYSQL_ERROR(logsql_server_p)); 852
760 mysql_close(logsql_server_p); 853 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: first attempt failed, API said: error %d, \"%s\"", real_error, MYSQL_ERROR(global_config.server_p));
761 logsql_server_p = NULL; 854 mysql_close(global_config.server_p);
855 global_config.server_p = NULL;
762 open_logdb_link(r->server); 856 open_logdb_link(r->server);
763 857
764 if (logsql_server_p == NULL) { /* still unable to link */ 858 if (global_config.server_p == NULL) { /* still unable to link */
765 signal(SIGPIPE, handler); 859 signal(SIGPIPE, handler);
766 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); 860 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection.");
767 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); 861 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file);
768 return 1; 862 return 1;
769 } else 863 } else
770 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: db reconnect successful"); 864 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: db reconnect successful");
771 865
772 /* First sleep for a tiny amount of time. */ 866 /* First sleep for a tiny amount of time. */
773 delay.tv_sec = 0; 867 delay.tv_sec = 0;
774 delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ 868 delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */
775 ret = nanosleep(&delay, &remainder); 869 ret = nanosleep(&delay, &remainder);
776 if (ret && errno != EINTR) 870 if (ret && errno != EINTR)
777 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); 871 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: nanosleep unsuccessful");
778 872
779 /* Then make our second attempt */ 873 /* Then make our second attempt */
780 retval = mysql_query(logsql_server_p,query); 874 retval = mysql_query(global_config.server_p,query);
781 875
782 /* If this one also failed, log that and append to our local offline file */ 876 /* If this one also failed, log that and append to our local offline file */
783 if (retval) { 877 if (retval) {
784 #ifdef WANT_DELAYED_MYSQL_INSERT 878 if (global_config.insertdelayed) {
785 real_error = 2; 879 real_error = 2;
786 #else 880 } else {
787 real_error = mysql_errno(logsql_server_p); 881 real_error = mysql_errno(global_config.server_p);
788 #endif 882 }
789 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(logsql_server_p)); 883
884 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(global_config.server_p));
790 preserve_entry(r, query); 885 preserve_entry(r, query);
791 retval = real_error; 886 retval = real_error;
792 } else 887 } else
793 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); 888 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: second attempt successful");
794 889
795 /* Restore SIGPIPE to its original handler function */ 890 /* Restore SIGPIPE to its original handler function */
796 signal(SIGPIPE, handler); 891 signal(SIGPIPE, handler);
797 return retval; 892 return retval;
798} 893}
799 894
800/*-----------------------------------------------------*/ 895/*-----------------------------------------------------*
801/* safe_create_tables: create SQL table set for the */ 896 * safe_create_tables: create SQL table set for the *
802/* virtual server represented by cls. */ 897 * virtual server represented by cls. *
803/* */ 898 * *
804/* Parms: virtserver structure, request record */ 899 * Parms: virtserver structure, request record *
805/* Returns: 0 on no errors */ 900 * Returns: 0 on no errors *
806/* mysql error code on failure */ 901 * mysql error code on failure *
807/*-----------------------------------------------------*/ 902 *-----------------------------------------------------*/
808int safe_create_tables(logsql_state *cls, request_rec *r) 903static int safe_create_tables(logsql_state *cls, request_rec *r)
809{ 904{
810 int retval; 905 int retval;
811 unsigned int create_results; 906 unsigned int create_results;
@@ -859,45 +954,45 @@ int safe_create_tables(logsql_state *cls, request_rec *r)
859 val varchar(80))"; 954 val varchar(80))";
860 955
861 /* Find memory long enough to hold the whole CREATE string + \0 */ 956 /* Find memory long enough to hold the whole CREATE string + \0 */
862 create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL); 957 create_access = apr_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL);
863 create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL); 958 create_notes = apr_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL);
864 create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL); 959 create_hout = apr_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL);
865 create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); 960 create_hin = apr_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL);
866 create_cookies= ap_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, NULL); 961 create_cookies= apr_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, NULL);
867 962
868 #ifdef DEBUG 963 #ifdef DEBUG
869 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access); 964 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: create string: %s", create_access);
870 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_notes); 965 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: create string: %s", create_notes);
871 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hout); 966 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: create string: %s", create_hout);
872 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hin); 967 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: create string: %s", create_hin);
873 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_cookies); 968 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: create string: %s", create_cookies);
874 #endif 969 #endif
875 970
876 /* Assume that things worked unless told otherwise */ 971 /* Assume that things worked unless told otherwise */
877 retval = 0; 972 retval = 0;
878 973
879 if ((create_results = safe_sql_query(r, create_access))) { 974 if ((create_results = safe_sql_query(r, create_access))) {
880 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table"); 975 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: failed to create access table");
881 retval = create_results; 976 retval = create_results;
882 } 977 }
883 978
884 if ((create_results = safe_sql_query(r, create_notes))) { 979 if ((create_results = safe_sql_query(r, create_notes))) {
885 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); 980 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: failed to create notes table");
886 retval = create_results; 981 retval = create_results;
887 } 982 }
888 983
889 if ((create_results = safe_sql_query(r, create_hin))) { 984 if ((create_results = safe_sql_query(r, create_hin))) {
890 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); 985 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: failed to create header_out table");
891 retval = create_results; 986 retval = create_results;
892 } 987 }
893 988
894 if ((create_results = safe_sql_query(r, create_hout))) { 989 if ((create_results = safe_sql_query(r, create_hout))) {
895 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table"); 990 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: failed to create header_in table");
896 retval = create_results; 991 retval = create_results;
897 } 992 }
898 993
899 if ((create_results = safe_sql_query(r, create_cookies))) { 994 if ((create_results = safe_sql_query(r, create_cookies))) {
900 ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table"); 995 ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"mod_log_sql: failed to create cookies table");
901 retval = create_results; 996 retval = create_results;
902 } 997 }
903 998
@@ -909,220 +1004,102 @@ int safe_create_tables(logsql_state *cls, request_rec *r)
909 * to the directives found at Apache runtime. * 1004 * to the directives found at Apache runtime. *
910 * ------------------------------------------------*/ 1005 * ------------------------------------------------*/
911 1006
912const char *set_log_sql_massvirtual(cmd_parms *parms, void *dummy, int flag)
913{
914 logsql_massvirtual = ( flag ? 1 : 0);
915 return NULL;
916}
917 1007
918const char *set_log_sql_force_preserve(cmd_parms *parms, void *dummy, int flag) 1008static const char *set_global_flag_slot(cmd_parms *cmd,
1009 void *struct_ptr,
1010 int flag)
919{ 1011{
920 logsql_forcepreserve = ( flag ? 1 : 0); 1012 int offset = (int)(long)&global_config;
921 return NULL;
922}
923 1013
924const char *set_log_sql_machine_id(cmd_parms *parms, void *dummy, char *arg) 1014 *(int *)((char *)struct_ptr + offset) = flag ? 1 : 0;
925{ 1015
926 logsql_machid = arg; 1016 return NULL;
927 return NULL;
928} 1017}
929 1018
930const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) 1019static const char *set_global_nmv_flag_slot(cmd_parms *parms,
1020 void *struct_ptr,
1021 int flag)
931{ 1022{
932 if (logsql_massvirtual) 1023 if (global_config.massvirtual)
933 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCreateTables when LogSQLMassVirtualHosting is On. Ignoring."); 1024 return apr_psprintf(parms->pool,
1025 "mod_log_sql: do not set %s when LogSQLMassVirtualHosting is On.",
1026 parms->cmd->name);
934 else 1027 else
935 logsql_createtables = ( flag ? 1 : 0); 1028 return set_global_flag_slot(parms,struct_ptr,flag);
936 return NULL;
937} 1029}
938 1030
939const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) 1031static const char *set_global_string_slot(cmd_parms *cmd,
1032 void *struct_ptr,
1033 const char *arg)
940{ 1034{
941 logsql_dbname = arg; 1035 int offset = (int)(long)&global_config;
942 return NULL; 1036
1037 *(const char **)((char *)struct_ptr + offset) = apr_pstrdup(cmd->pool,arg);
1038
1039 return NULL;
943} 1040}
944 1041
945const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) 1042static const char *set_server_string_slot(cmd_parms *cmd,
1043 void *struct_ptr,
1044 const char *arg)
946{ 1045{
947 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); 1046 int offset = (int)(long)ap_get_module_config(cmd->server->module_config,
1047 &log_sql_module);
948 1048
949 cls->cookie_name = arg; 1049 *(const char **)((char *)struct_ptr + offset) = arg;
950 return NULL; 1050
1051 return NULL;
951} 1052}
952 1053
953const char *set_log_sql_preserve_file(cmd_parms *parms, void *dummy, char *arg)
954{
955 /* char *pfile; */
956 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
957 1054
958 /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */ 1055static const char *set_server_nmv_string_slot(cmd_parms *parms,
959 cls->preserve_file = arg; 1056 void *struct_ptr,
960 return NULL; 1057 const char *arg)
1058{
1059 if (global_config.massvirtual)
1060 return apr_psprintf(parms->pool,
1061 "mod_log_sql: do not set %s when LogSQLMassVirtualHosting is On.",
1062 parms->cmd->name);
1063 else
1064 return set_server_string_slot(parms,struct_ptr,arg);
961} 1065}
962 1066
963const char *set_log_sql_info(cmd_parms *parms, void *dummy, char *host, char *user, char *pwd) 1067static const char *set_log_sql_info(cmd_parms *cmd, void *dummy, const char *host, const char *user, const char *pwd)
964{ 1068{
965 if (*host != '.') { 1069 if (*host != '.') {
966 logsql_dbhost = host; 1070 global_config.dbhost = apr_pstrdup(cmd->pool,host);
967 } 1071 }
968 if (*user != '.') { 1072 if (*user != '.') {
969 logsql_dbuser = user; 1073 global_config.dbuser = apr_pstrdup(cmd->pool,user);
970 } 1074 }
971 if (*pwd != '.') { 1075 if (*pwd != '.') {
972 logsql_dbpwd = pwd; 1076 global_config.dbpwd = apr_pstrdup(cmd->pool,pwd);
973 } 1077 }
974 return NULL; 1078 return NULL;
975} 1079}
976 1080
977const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg) 1081static const char *add_server_string_slot(cmd_parms *cmd,
978{ 1082 void *struct_ptr,
979 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); 1083 const char *arg)
980
981 if (logsql_massvirtual != 0)
982 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLTransferLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
983 else
984 cls->transfer_table_name = arg;
985 return NULL;
986}
987
988const char *set_log_sql_cookie_table(cmd_parms *parms, void *dummy, char *arg)
989{
990 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
991
992 if (logsql_massvirtual != 0)
993 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCookieLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
994 else
995 cls->cookie_table_name = arg;
996 return NULL;
997}
998
999const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg)
1000{
1001 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1002
1003 if (logsql_massvirtual != 0)
1004 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLNotesLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
1005 else
1006 cls->notes_table_name = arg;
1007 return NULL;
1008}
1009
1010const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg)
1011{
1012 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1013
1014 if (logsql_massvirtual != 0)
1015 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersInLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
1016 else
1017 cls->hin_table_name = arg;
1018 return NULL;
1019}
1020
1021const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg)
1022{
1023 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1024
1025 if (logsql_massvirtual != 0)
1026 ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersOutLogTable when LogSQLMassVirtualHosting is On. Ignoring.");
1027 else
1028 cls->hout_table_name = arg;
1029 return NULL;
1030}
1031
1032const char *set_log_sql_transfer_log_format(cmd_parms *parms, void *dummy, char *arg)
1033{
1034 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1035
1036 cls->transfer_log_format = arg;
1037 return NULL;
1038}
1039
1040const char *set_log_sql_socket_file(cmd_parms *parms, void *dummy, char *arg)
1041{
1042 logsql_socketfile = arg;
1043
1044 return NULL;
1045}
1046
1047const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, char *arg)
1048{
1049 logsql_tcpport = (unsigned int)atoi(arg);
1050
1051 return NULL;
1052}
1053
1054const char *add_log_sql_transfer_accept(cmd_parms *parms, void *dummy, char *arg)
1055{
1056 char **addme;
1057 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1058
1059 addme = push_array(cls->transfer_accept_list);
1060 *addme = pstrdup(cls->transfer_accept_list->pool, arg);
1061 return NULL;
1062}
1063
1064const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg)
1065{
1066 char **addme;
1067 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1068
1069 addme = push_array(cls->transfer_ignore_list);
1070 *addme = pstrdup(cls->transfer_ignore_list->pool, arg);
1071 return NULL;
1072}
1073
1074const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg)
1075{ 1084{
1076 char **addme; 1085 char **addme;
1077 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); 1086 int offset = (int)(long)ap_get_module_config(cmd->server->module_config,
1078 1087 &log_sql_module);
1079 addme = push_array(cls->remhost_ignore_list); 1088 apr_array_header_t *ary = *(apr_array_header_t **)((apr_array_header_t *)struct_ptr + offset);
1080 *addme = pstrdup(cls->remhost_ignore_list->pool, arg);
1081 return NULL;
1082}
1083 1089
1084const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg) 1090 addme = apr_array_push(ary);
1085{ 1091 *addme = apr_pstrdup(ary->pool, arg);
1086 char **addme; 1092
1087 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1088
1089 addme = push_array(cls->notes_list);
1090 *addme = pstrdup(cls->notes_list->pool, arg);
1091 return NULL; 1093 return NULL;
1092} 1094}
1093 1095
1094const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg) 1096static const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, const char *arg)
1095{ 1097{
1096 char **addme; 1098 global_config.tcpport = (unsigned int)atoi(arg);
1097 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1098 1099
1099 addme = push_array(cls->hout_list); 1100 return NULL;
1100 *addme = pstrdup(cls->hout_list->pool, arg);
1101 return NULL;
1102}
1103
1104const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg)
1105{
1106 char **addme;
1107 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1108
1109 addme = push_array(cls->hin_list);
1110 *addme = pstrdup(cls->hin_list->pool, arg);
1111 return NULL;
1112}
1113
1114const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
1115{
1116 char **addme;
1117 logsql_state *cls = get_module_config(parms->server->module_config, &sql_log_module);
1118
1119 addme = push_array(cls->cookie_list);
1120 *addme = pstrdup(cls->cookie_list->pool, arg);
1121 return NULL;
1122} 1101}
1123 1102
1124
1125
1126/*------------------------------------------------------------* 1103/*------------------------------------------------------------*
1127 * Apache-specific hooks into the module code * 1104 * Apache-specific hooks into the module code *
1128 * that are defined in the array 'mysql_lgog_module' (at EOF) * 1105 * that are defined in the array 'mysql_lgog_module' (at EOF) *
@@ -1130,6 +1107,20 @@ const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
1130 1107
1131 1108
1132/* 1109/*
1110 * This function is called when an heavy-weight process (such as a child) is
1111 * being run down or destroyed. As with the child-initialisation function,
1112 * any information that needs to be recorded must be in static cells, since
1113 * there's no configuration record.
1114 *
1115 * There is no return value.
1116 */
1117static apr_status_t log_sql_close_link(void *data)
1118{
1119 mysql_close(global_config.server_p);
1120 return APR_SUCCESS;
1121}
1122
1123/*
1133 * This function is called during server initialisation when an heavy-weight 1124 * This function is called during server initialisation when an heavy-weight
1134 * process (such as a child) is being initialised. As with the 1125 * process (such as a child) is being initialised. As with the
1135 * module-initialisation function, any information that needs to be recorded 1126 * module-initialisation function, any information that needs to be recorded
@@ -1137,46 +1128,37 @@ const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg)
1137 * 1128 *
1138 * There is no return value. 1129 * There is no return value.
1139 */ 1130 */
1140static void log_sql_child_init(server_rec *s, pool *p) 1131static void log_sql_child_init(apr_pool_t *p, server_rec *s)
1141{ 1132{
1142 int retval; 1133 apr_pool_cleanup_register(p, NULL, log_sql_close_link, log_sql_close_link);
1134
1135}
1143 1136
1144 /* Open a link to the database */ 1137static int log_sql_open(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s)
1138{
1139 int retval;
1140 /* Open a link to the database */
1145 retval = open_logdb_link(s); 1141 retval = open_logdb_link(s);
1146 if (!retval) 1142 if (!retval)
1147 ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); 1143 ap_log_error(APLOG_MARK,APLOG_ERR,0,s,"mod_log_sql: child spawned but unable to open database link");
1148 1144
1149 #ifdef DEBUG 1145 #ifdef DEBUG
1150 if ( (retval == 1) || (retval == 2) ) 1146 if ( (retval == 1) || (retval == 2) )
1151 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link successful"); 1147 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,s,"mod_log_sql: open_logdb_link successful");
1152 if (retval == 3) 1148 if (retval == 3)
1153 ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link said that preservation is forced"); 1149 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,s,"mod_log_sql: open_logdb_link said that preservation is forced");
1154 #endif 1150 #endif
1151 return OK;
1155} 1152}
1156
1157/* 1153/*
1158 * This function is called when an heavy-weight process (such as a child) is 1154void *log_sql_initializer(server_rec *main_server, apr_pool_t *p)
1159 * being run down or destroyed. As with the child-initialisation function,
1160 * any information that needs to be recorded must be in static cells, since
1161 * there's no configuration record.
1162 *
1163 * There is no return value.
1164 */
1165static void log_sql_child_exit(server_rec *s, pool *p)
1166{
1167 mysql_close(logsql_server_p);
1168}
1169
1170
1171/*
1172void *log_sql_initializer(server_rec *main_server, pool *p)
1173{ 1155{
1174 server_rec *s; 1156 server_rec *s;
1175 1157
1176 logsql_state main_conf = ap_get_module_config(main_server->module_config, &sql_log_module); 1158 logsql_state main_conf = ap_get_module_config(main_server->module_config, &log_sql_module);
1177 1159
1178 for (server_rec *s = main_server; s; s = s->next) { 1160 for (server_rec *s = main_server; s; s = s->next) {
1179 conf = ap_get_module_config(s->module_config, &sql_log_module); 1161 conf = ap_get_module_config(s->module_config, &log_sql_module);
1180 if (conf->transfer_log_format == NULL && s != main_server) { 1162 if (conf->transfer_log_format == NULL && s != main_server) {
1181 *conf = *main_conf; 1163 *conf = *main_conf;
1182 } 1164 }
@@ -1193,10 +1175,18 @@ void *log_sql_initializer(server_rec *main_server, pool *p)
1193 * The return value is a pointer to the created module-specific 1175 * The return value is a pointer to the created module-specific
1194 * structure. 1176 * structure.
1195 */ 1177 */
1196void *log_sql_make_state(pool *p, server_rec *s) 1178static int log_sql_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
1197{ 1179{
1180 /* Initialize Global configuration */
1181 memset(&global_config,0,sizeof(global_config));
1182 global_config.socketfile = "/tmp/mysql.sock";
1183 global_config.tcpport = 3306;
1184 return OK;
1185}
1198 1186
1199 logsql_state *cls = (logsql_state *) ap_palloc(p, sizeof(logsql_state)); 1187static void *log_sql_make_state(apr_pool_t *p, server_rec *s)
1188{
1189 logsql_state *cls = (logsql_state *) apr_palloc(p, sizeof(logsql_state));
1200 1190
1201 /* These defaults are overridable in the httpd.conf file. */ 1191 /* These defaults are overridable in the httpd.conf file. */
1202 cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */ 1192 cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */
@@ -1207,111 +1197,32 @@ void *log_sql_make_state(pool *p, server_rec *s)
1207 cls->cookie_table_name = "cookies"; 1197 cls->cookie_table_name = "cookies";
1208 cls->preserve_file = "/tmp/sql-preserve"; 1198 cls->preserve_file = "/tmp/sql-preserve";
1209 1199
1210 cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); 1200 cls->transfer_ignore_list = apr_array_make(p, 1, sizeof(char *));
1211 cls->transfer_accept_list = make_array(p, 1, sizeof(char *)); 1201 cls->transfer_accept_list = apr_array_make(p, 1, sizeof(char *));
1212 cls->remhost_ignore_list = make_array(p, 1, sizeof(char *)); 1202 cls->remhost_ignore_list = apr_array_make(p, 1, sizeof(char *));
1213 cls->notes_list = make_array(p, 1, sizeof(char *)); 1203 cls->notes_list = apr_array_make(p, 1, sizeof(char *));
1214 cls->hin_list = make_array(p, 1, sizeof(char *)); 1204 cls->hin_list = apr_array_make(p, 1, sizeof(char *));
1215 cls->hout_list = make_array(p, 1, sizeof(char *)); 1205 cls->hout_list = apr_array_make(p, 1, sizeof(char *));
1216 cls->cookie_list = make_array(p, 1, sizeof(char *)); 1206 cls->cookie_list = apr_array_make(p, 1, sizeof(char *));
1217 cls->cookie_name = NULL; 1207 cls->cookie_name = NULL;
1218 1208
1219 return (void *) cls; 1209 return (void *) cls;
1220} 1210}
1221 1211
1222
1223/* Setup of the available httpd.conf configuration commands.
1224 * Structure: command, function called, NULL, where available, how many arguments, verbose description
1225 */
1226command_rec log_sql_cmds[] = {
1227 {"LogSQLTransferLogTable", set_log_sql_transfer_table, NULL, RSRC_CONF, TAKE1,
1228 "The database table that holds the transfer log"}
1229 ,
1230 {"LogSQLNotesLogTable", set_log_sql_notes_table, NULL, RSRC_CONF, TAKE1,
1231 "The database table that holds the notes"}
1232 ,
1233 {"LogSQLHeadersOutLogTable", set_log_sql_hout_table, NULL, RSRC_CONF, TAKE1,
1234 "The database table that holds the outbound headers"}
1235 ,
1236 {"LogSQLHeadersInLogTable", set_log_sql_hin_table, NULL, RSRC_CONF, TAKE1,
1237 "The database table that holds the inbound headers"}
1238 ,
1239 {"LogSQLCookieLogTable", set_log_sql_cookie_table, NULL, RSRC_CONF, TAKE1,
1240 "The database table that holds the cookie info"}
1241 ,
1242 {"LogSQLTransferLogFormat", set_log_sql_transfer_log_format, NULL, RSRC_CONF, TAKE1,
1243 "Instruct the module what information to log to the database transfer log"}
1244 ,
1245 {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1,
1246 "Machine ID that the module will log, useful in web clusters to differentiate machines"}
1247 ,
1248 {"LogSQLRequestAccept", add_log_sql_transfer_accept, NULL, RSRC_CONF, ITERATE,
1249 "List of URIs to accept for logging. Accesses that don't match will not be logged"}
1250 ,
1251 {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE,
1252 "List of URIs to ignore. Accesses that match will not be logged to database"}
1253 ,
1254 {"LogSQLRemhostIgnore", add_log_sql_remhost_ignore, NULL, RSRC_CONF, ITERATE,
1255 "List of remote hosts to ignore. Accesses that match will not be logged to database"}
1256 ,
1257 {"LogSQLDatabase", set_log_sql_db, NULL, RSRC_CONF, TAKE1,
1258 "The name of the database database for logging"}
1259 ,
1260 {"LogSQLWhichCookie", set_log_sql_cookie, NULL, RSRC_CONF, TAKE1,
1261 "The single cookie that you want logged in the access_log when using the 'c' config directive"}
1262 ,
1263 {"LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF, TAKE3,
1264 "The database host, user-id and password for logging"}
1265 ,
1266 {"LogSQLCreateTables", set_log_sql_create, NULL, RSRC_CONF, FLAG,
1267 "Turn on module's capability to create its SQL tables on the fly"}
1268 ,
1269 {"LogSQLMassVirtualHosting", set_log_sql_massvirtual, NULL, RSRC_CONF, FLAG,
1270 "Activates option(s) useful for ISPs performing mass virutal hosting"}
1271 ,
1272 {"LogSQLForcePreserve", set_log_sql_force_preserve, NULL, RSRC_CONF, FLAG,
1273 "Forces logging to preserve file and bypasses database"}
1274 ,
1275 {"LogSQLPreserveFile", set_log_sql_preserve_file, NULL, RSRC_CONF, TAKE1,
1276 "Name of the file to use for data preservation during database downtime"}
1277 ,
1278 {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1,
1279 "Name of the file to employ for socket connections to database"}
1280 ,
1281 {"LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF, TAKE1,
1282 "Port number to use for TCP connections to database, defaults to 3306 if not set"}
1283 ,
1284 {"LogSQLWhichNotes", add_log_sql_note, NULL, RSRC_CONF, ITERATE,
1285 "Notes that you would like to log in a separate table"}
1286 ,
1287 {"LogSQLWhichHeadersOut", add_log_sql_hout, NULL, RSRC_CONF, ITERATE,
1288 "Outbound headers that you would like to log in a separate table"}
1289 ,
1290 {"LogSQLWhichHeadersIn", add_log_sql_hin, NULL, RSRC_CONF, ITERATE,
1291 "Inbound headers that you would like to log in a separate table"}
1292 ,
1293 {"LogSQLWhichCookies", add_log_sql_cookie, NULL, RSRC_CONF, ITERATE,
1294 "The cookie(s) that you would like to log in a separate table"}
1295 ,
1296 {NULL}
1297};
1298
1299
1300
1301/* Routine to perform the actual construction and execution of the relevant 1212/* Routine to perform the actual construction and execution of the relevant
1302 * INSERT statements. 1213 * INSERT statements.
1303 */ 1214 */
1304int log_sql_transaction(request_rec *orig) 1215static int log_sql_transaction(request_rec *orig)
1305{ 1216{
1306 char **ptrptr, **ptrptr2; 1217 char **ptrptr, **ptrptr2;
1307 logsql_state *cls = get_module_config(orig->server->module_config, &sql_log_module); 1218 logsql_state *cls = ap_get_module_config(orig->server->module_config, &log_sql_module);
1308 const char *access_query; 1219 const char *access_query;
1309 request_rec *r; 1220 request_rec *r;
1310 1221
1311 /* We handle mass virtual hosting differently. Dynamically determine the name 1222 /* We handle mass virtual hosting differently. Dynamically determine the name
1312 * of the table from the virtual server's name, and flag it for creation. 1223 * of the table from the virtual server's name, and flag it for creation.
1313 */ 1224 */
1314 if (logsql_massvirtual) { 1225 if (global_config.massvirtual) {
1315 char *access_base = "access_"; 1226 char *access_base = "access_";
1316 char *notes_base = "notes_"; 1227 char *notes_base = "notes_";
1317 char *hout_base = "headout_"; 1228 char *hout_base = "headout_";
@@ -1325,11 +1236,11 @@ int log_sql_transaction(request_rec *orig)
1325 unsigned int i; 1236 unsigned int i;
1326 1237
1327 /* Find memory long enough to hold the table name + \0. */ 1238 /* Find memory long enough to hold the table name + \0. */
1328 a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); 1239 a_tablename = apr_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL);
1329 n_tablename = ap_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL); 1240 n_tablename = apr_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL);
1330 i_tablename = ap_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL); 1241 i_tablename = apr_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL);
1331 o_tablename = ap_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL); 1242 o_tablename = apr_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL);
1332 c_tablename = ap_pstrcat(orig->pool, cookie_base, ap_get_server_name(orig), NULL); 1243 c_tablename = apr_pstrcat(orig->pool, cookie_base, ap_get_server_name(orig), NULL);
1333 1244
1334 /* Transform any dots to underscores */ 1245 /* Transform any dots to underscores */
1335 for (i = 0; i < strlen(a_tablename); i++) { 1246 for (i = 0; i < strlen(a_tablename); i++) {
@@ -1361,7 +1272,7 @@ int log_sql_transaction(request_rec *orig)
1361 cls->hout_table_name = o_tablename; 1272 cls->hout_table_name = o_tablename;
1362 cls->hin_table_name = i_tablename; 1273 cls->hin_table_name = i_tablename;
1363 cls->cookie_table_name = c_tablename; 1274 cls->cookie_table_name = c_tablename;
1364 logsql_createtables = 1; 1275 global_config.createtables = 1;
1365 } 1276 }
1366 1277
1367 /* Do we have enough info to log? */ 1278 /* Do we have enough info to log? */
@@ -1416,7 +1327,7 @@ int log_sql_transaction(request_rec *orig)
1416 /* Go through each element of the ignore list and compare it to the 1327 /* Go through each element of the ignore list and compare it to the
1417 * remote host. If we get a match, return without logging */ 1328 * remote host. If we get a match, return without logging */
1418 ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size)); 1329 ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size));
1419 thehost = get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); 1330 thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL);
1420 if (thehost) { 1331 if (thehost) {
1421 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) 1332 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size))
1422 if (strstr(thehost, *ptrptr)) { 1333 if (strstr(thehost, *ptrptr)) {
@@ -1448,10 +1359,10 @@ int log_sql_transaction(request_rec *orig)
1448 } 1359 }
1449 1360
1450 /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ 1361 /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */
1451 fields = pstrcat(r->pool, fields, (i > 0 ? "," : ""), 1362 fields = apr_pstrcat(r->pool, fields, (i > 0 ? "," : ""),
1452 log_sql_item_keys[j].sql_field_name, NULL); 1363 log_sql_item_keys[j].sql_field_name, NULL);
1453 1364
1454 values = pstrcat(r->pool, values, (i > 0 ? "," : ""), 1365 values = apr_pstrcat(r->pool, values, (i > 0 ? "," : ""),
1455 (log_sql_item_keys[j].string_contents ? "'" : ""), 1366 (log_sql_item_keys[j].string_contents ? "'" : ""),
1456 escape_query(formatted_item, r->pool), 1367 escape_query(formatted_item, r->pool),
1457 (log_sql_item_keys[j].string_contents ? "'" : ""), NULL); 1368 (log_sql_item_keys[j].string_contents ? "'" : ""), NULL);
@@ -1469,8 +1380,8 @@ int log_sql_transaction(request_rec *orig)
1469 ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size)); 1380 ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size));
1470 for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) { 1381 for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) {
1471 /* If the specified note (*ptrptr) exists for the current request... */ 1382 /* If the specified note (*ptrptr) exists for the current request... */
1472 if ((theitem = ap_table_get(r->notes, *ptrptr))) { 1383 if ((theitem = apr_table_get(r->notes, *ptrptr))) {
1473 itemsets = ap_pstrcat(r->pool, itemsets, 1384 itemsets = apr_pstrcat(r->pool, itemsets,
1474 (i > 0 ? "," : ""), 1385 (i > 0 ? "," : ""),
1475 "('", 1386 "('",
1476 unique_id, 1387 unique_id,
@@ -1484,9 +1395,10 @@ int log_sql_transaction(request_rec *orig)
1484 } 1395 }
1485 } 1396 }
1486 if ( itemsets != "" ) { 1397 if ( itemsets != "" ) {
1487 note_query = ap_pstrcat(r->pool, logsql_insertclause, "`", cls->notes_table_name, "` (id, item, val) values ", itemsets, NULL); 1398 note_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1399 global_config.insertdelayed?"delayed":NULL, cls->notes_table_name, itemsets);
1488 #ifdef DEBUG 1400 #ifdef DEBUG
1489 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: note string: %s", note_query); 1401 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,orig->server,"mod_log_sql: note string: %s", note_query);
1490 #endif 1402 #endif
1491 } 1403 }
1492 1404
@@ -1497,8 +1409,8 @@ int log_sql_transaction(request_rec *orig)
1497 ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size)); 1409 ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size));
1498 for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) { 1410 for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) {
1499 /* If the specified header (*ptrptr) exists for the current request... */ 1411 /* If the specified header (*ptrptr) exists for the current request... */
1500 if ((theitem = ap_table_get(r->headers_out, *ptrptr))) { 1412 if ((theitem = apr_table_get(r->headers_out, *ptrptr))) {
1501 itemsets = ap_pstrcat(r->pool, itemsets, 1413 itemsets = apr_pstrcat(r->pool, itemsets,
1502 (i > 0 ? "," : ""), 1414 (i > 0 ? "," : ""),
1503 "('", 1415 "('",
1504 unique_id, 1416 unique_id,
@@ -1512,9 +1424,10 @@ int log_sql_transaction(request_rec *orig)
1512 } 1424 }
1513 } 1425 }
1514 if ( itemsets != "" ) { 1426 if ( itemsets != "" ) {
1515 hout_query = ap_pstrcat(r->pool, logsql_insertclause, "`", cls->hout_table_name, "` (id, item, val) values ", itemsets, NULL); 1427 hout_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1428 global_config.insertdelayed?"delayed":NULL, cls->hout_table_name, itemsets);
1516 #ifdef DEBUG 1429 #ifdef DEBUG
1517 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_out string: %s", hout_query); 1430 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,orig->server,"mod_log_sql: header_out string: %s", hout_query);
1518 #endif 1431 #endif
1519 } 1432 }
1520 1433
@@ -1526,8 +1439,8 @@ int log_sql_transaction(request_rec *orig)
1526 ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size)); 1439 ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size));
1527 for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) { 1440 for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) {
1528 /* If the specified header (*ptrptr) exists for the current request... */ 1441 /* If the specified header (*ptrptr) exists for the current request... */
1529 if ((theitem = ap_table_get(r->headers_in, *ptrptr))) { 1442 if ((theitem = apr_table_get(r->headers_in, *ptrptr))) {
1530 itemsets = ap_pstrcat(r->pool, itemsets, 1443 itemsets = apr_pstrcat(r->pool, itemsets,
1531 (i > 0 ? "," : ""), 1444 (i > 0 ? "," : ""),
1532 "('", 1445 "('",
1533 unique_id, 1446 unique_id,
@@ -1541,9 +1454,11 @@ int log_sql_transaction(request_rec *orig)
1541 } 1454 }
1542 } 1455 }
1543 if ( itemsets != "" ) { 1456 if ( itemsets != "" ) {
1544 hin_query = ap_pstrcat(r->pool, logsql_insertclause, "`", cls->hin_table_name, "` (id, item, val) values ", itemsets, NULL); 1457 hin_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1458 global_config.insertdelayed?"delayed":NULL, cls->hin_table_name, itemsets);
1459
1545 #ifdef DEBUG 1460 #ifdef DEBUG
1546 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_in string: %s", hin_query); 1461 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,orig->server,"mod_log_sql: header_in string: %s", hin_query);
1547 #endif 1462 #endif
1548 } 1463 }
1549 1464
@@ -1556,7 +1471,7 @@ int log_sql_transaction(request_rec *orig)
1556 for (ptrptr = (char **) cls->cookie_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->cookie_list->elt_size)) { 1471 for (ptrptr = (char **) cls->cookie_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->cookie_list->elt_size)) {
1557 /* If the specified cookie (*ptrptr) exists for the current request... */ 1472 /* If the specified cookie (*ptrptr) exists for the current request... */
1558 if ( strncmp((theitem = extract_specific_cookie(r, *ptrptr)), "-", 1) ) { 1473 if ( strncmp((theitem = extract_specific_cookie(r, *ptrptr)), "-", 1) ) {
1559 itemsets = ap_pstrcat(r->pool, itemsets, 1474 itemsets = apr_pstrcat(r->pool, itemsets,
1560 (i > 0 ? "," : ""), 1475 (i > 0 ? "," : ""),
1561 "('", 1476 "('",
1562 unique_id, 1477 unique_id,
@@ -1571,26 +1486,28 @@ int log_sql_transaction(request_rec *orig)
1571 1486
1572 } 1487 }
1573 if ( itemsets != "" ) { 1488 if ( itemsets != "" ) {
1574 cookie_query = ap_pstrcat(r->pool, logsql_insertclause, "`", cls->cookie_table_name, "` (id, item, val) values ", itemsets, NULL); 1489 cookie_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1490 global_config.insertdelayed?"delayed":NULL, cls->cookie_table_name, itemsets);
1575 #ifdef DEBUG 1491 #ifdef DEBUG
1576 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: cookie string: %s", cookie_query); 1492 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,orig->server,"mod_log_sql: cookie string: %s", cookie_query);
1577 #endif 1493 #endif
1578 } 1494 }
1579 1495
1580 1496
1581 /* Set up the actual INSERT statement */ 1497 /* Set up the actual INSERT statement */
1582 access_query = ap_pstrcat(r->pool, logsql_insertclause, "`", cls->transfer_table_name, "` (", fields, ") values (", values, ")", NULL); 1498 access_query = apr_psprintf(r->pool, "insert %s into `%s` (%s) values (%s)",
1499 global_config.insertdelayed?"delayed":NULL, cls->transfer_table_name, fields, values);
1583 1500
1584 #ifdef DEBUG 1501 #ifdef DEBUG
1585 ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: access string: %s", access_query); 1502 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"mod_log_sql: access string: %s", access_query);
1586 #endif 1503 #endif
1587 1504
1588 /* If the person activated force-preserve, go ahead and push all the entries 1505 /* If the person activated force-preserve, go ahead and push all the entries
1589 * into the preserve file, then return. 1506 * into the preserve file, then return.
1590 */ 1507 */
1591 if (logsql_forcepreserve) { 1508 if (global_config.forcepreserve) {
1592 #ifdef DEBUG 1509 #ifdef DEBUG
1593 ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: preservation forced"); 1510 ap_log_error(APLOG_MARK,APLOG_DEBUG,0,orig->server,"mod_log_sql: preservation forced");
1594 #endif 1511 #endif
1595 preserve_entry(orig, access_query); 1512 preserve_entry(orig, access_query);
1596 if ( note_query != NULL ) 1513 if ( note_query != NULL )
@@ -1605,12 +1522,12 @@ int log_sql_transaction(request_rec *orig)
1605 } 1522 }
1606 1523
1607 /* How's our mysql link integrity? */ 1524 /* How's our mysql link integrity? */
1608 if (logsql_server_p == NULL) { 1525 if (global_config.server_p == NULL) {
1609 1526
1610 /* Make a try to establish the link */ 1527 /* Make a try to establish the link */
1611 open_logdb_link(r->server); 1528 open_logdb_link(r->server);
1612 1529
1613 if (logsql_server_p == NULL) { 1530 if (global_config.server_p == NULL) {
1614 /* Unable to re-establish a DB link, so assume that it's really 1531 /* Unable to re-establish a DB link, so assume that it's really
1615 * gone and send the entry to the preserve file instead. 1532 * gone and send the entry to the preserve file instead.
1616 * This short-circuits safe_sql_query() during a db outage and therefore 1533 * This short-circuits safe_sql_query() during a db outage and therefore
@@ -1629,7 +1546,7 @@ int log_sql_transaction(request_rec *orig)
1629 return OK; 1546 return OK;
1630 } else { 1547 } else {
1631 /* Whew, we got the DB link back */ 1548 /* Whew, we got the DB link back */
1632 ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: child established database connection"); 1549 ap_log_error(APLOG_MARK,APLOG_NOTICE,0,orig->server,"mod_log_sql: child established database connection");
1633 } 1550 }
1634 } 1551 }
1635 1552
@@ -1660,28 +1577,120 @@ int log_sql_transaction(request_rec *orig)
1660 1577
1661 1578
1662 1579
1580/* Setup of the available httpd.conf configuration commands.
1581 * Structure: command, function called, NULL, where available, how many arguments, verbose description
1582 */
1583static const command_rec log_sql_cmds[] = {
1584 AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot,
1585 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF,
1586 "The database table that holds the transfer log")
1587 ,
1588 AP_INIT_TAKE1("LogSQLNotesLogTable", set_server_nmv_string_slot,
1589 (void *)APR_OFFSETOF(logsql_state, notes_table_name), RSRC_CONF,
1590 "The database table that holds the notes")
1591 ,
1592 AP_INIT_TAKE1("LogSQLHeadersOutLogTable", set_server_nmv_string_slot,
1593 (void *)APR_OFFSETOF(logsql_state, hout_table_name), RSRC_CONF,
1594 "The database table that holds the outbound headers")
1595 ,
1596 AP_INIT_TAKE1("LogSQLHeadersInLogTable", set_server_nmv_string_slot,
1597 (void *)APR_OFFSETOF(logsql_state, hin_table_name), RSRC_CONF,
1598 "The database table that holds the inbound headers")
1599 ,
1600 AP_INIT_TAKE1("LogSQLCookieLogTable", set_server_nmv_string_slot,
1601 (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF,
1602 "The database table that holds the cookie info")
1603 ,
1604 AP_INIT_TAKE1("LogSQLTransferLogFormat", set_server_string_slot,
1605 (void *)APR_OFFSETOF(logsql_state,transfer_log_format), RSRC_CONF,
1606 "Instruct the module what information to log to the database transfer log")
1607 ,
1608 AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot,
1609 (void *)APR_OFFSETOF(global_config_t, machid), RSRC_CONF,
1610 "Machine ID that the module will log, useful in web clusters to differentiate machines")
1611 ,
1612 AP_INIT_ITERATE("LogSQLRequestAccept", add_server_string_slot,
1613 (void *)APR_OFFSETOF(logsql_state, transfer_accept_list), RSRC_CONF,
1614 "List of URIs to accept for logging. Accesses that don't match will not be logged")
1615 ,
1616 AP_INIT_ITERATE("LogSQLRequestIgnore", add_server_string_slot,
1617 (void *)APR_OFFSETOF(logsql_state, transfer_ignore_list), RSRC_CONF,
1618 "List of URIs to ignore. Accesses that match will not be logged to database")
1619 ,
1620 AP_INIT_ITERATE("LogSQLRemhostIgnore", add_server_string_slot,
1621 (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF,
1622 "List of remote hosts to ignore. Accesses that match will not be logged to database")
1623 ,
1624 AP_INIT_TAKE1("LogSQLDatabase", set_global_string_slot,
1625 (void *)APR_OFFSETOF(global_config_t, dbname), RSRC_CONF,
1626 "The name of the database database for logging")
1627 ,
1628 AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot,
1629 (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF,
1630 "The single cookie that you want logged in the access_log when using the 'c' config directive")
1631 ,
1632 AP_INIT_TAKE3("LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF,
1633 "The database host, user-id and password for logging")
1634 ,
1635 AP_INIT_FLAG("LogSQLCreateTables", set_global_nmv_flag_slot,
1636 (void *)APR_OFFSETOF(global_config_t, createtables), RSRC_CONF,
1637 "Turn on module's capability to create its SQL tables on the fly")
1638 ,
1639 AP_INIT_FLAG("LogSQLMassVirtualHosting", set_global_flag_slot,
1640 (void *)APR_OFFSETOF(global_config_t, massvirtual), RSRC_CONF,
1641 "Activates option(s) useful for ISPs performing mass virutal hosting")
1642 ,
1643 AP_INIT_FLAG("LogSQLDelayedInserts", set_global_flag_slot,
1644 (void *)APR_OFFSETOF(global_config_t, insertdelayed), RSRC_CONF,
1645 "Whether to use delayed inserts")
1646 ,
1647 AP_INIT_FLAG("LogSQLForcePreserve", set_global_flag_slot,
1648 (void *)APR_OFFSETOF(global_config_t, forcepreserve), RSRC_CONF,
1649 "Forces logging to preserve file and bypasses database")
1650 ,
1651 AP_INIT_TAKE1("LogSQLPreserveFile", set_global_string_slot,
1652 (void *)APR_OFFSETOF(logsql_state,preserve_file), RSRC_CONF,
1653 "Name of the file to use for data preservation during database downtime")
1654 ,
1655 AP_INIT_TAKE1("LogSQLSocketFile", set_global_string_slot,
1656 (void *)APR_OFFSETOF(global_config_t, socketfile), RSRC_CONF,
1657 "Name of the file to employ for socket connections to database")
1658 ,
1659 AP_INIT_TAKE1("LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF,
1660 "Port number to use for TCP connections to database, defaults to 3306 if not set")
1661 ,
1662 AP_INIT_ITERATE("LogSQLWhichNotes", add_server_string_slot,
1663 (void *)APR_OFFSETOF(logsql_state, notes_list), RSRC_CONF,
1664 "Notes that you would like to log in a separate table")
1665 ,
1666 AP_INIT_ITERATE("LogSQLWhichHeadersOut", add_server_string_slot,
1667 (void *)APR_OFFSETOF(logsql_state, hout_list), RSRC_CONF,
1668 "Outbound headers that you would like to log in a separate table")
1669 ,
1670 AP_INIT_ITERATE("LogSQLWhichHeadersIn", add_server_string_slot,
1671 (void *)APR_OFFSETOF(logsql_state, hin_list), RSRC_CONF,
1672 "Inbound headers that you would like to log in a separate table")
1673 ,
1674 AP_INIT_ITERATE("LogSQLWhichCookies", add_server_string_slot,
1675 (void *)APR_OFFSETOF(logsql_state, cookie_list), RSRC_CONF,
1676 "The cookie(s) that you would like to log in a separate table")
1677 ,
1678 {NULL}
1679};
1663/* The configuration array that sets up the hooks into the module. */ 1680/* The configuration array that sets up the hooks into the module. */
1664module sql_log_module = { 1681static void register_hooks(apr_pool_t *p) {
1665 STANDARD_MODULE_STUFF, 1682 ap_hook_pre_config(log_sql_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1666 NULL, /* module initializer */ 1683 ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE);
1667 NULL, /* create per-dir config */ 1684 ap_hook_open_logs(log_sql_open, NULL, NULL, APR_HOOK_MIDDLE);
1668 NULL, /* merge per-dir config */ 1685 ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE);
1669 log_sql_make_state, /* create server config */ 1686}
1670 NULL, /* merge server config */ 1687
1671 log_sql_cmds, /* config directive table */ 1688module AP_MODULE_DECLARE_DATA log_sql_module = {
1672 NULL, /* [9] content handlers */ 1689 STANDARD20_MODULE_STUFF,
1673 NULL, /* [2] URI-to-filename translation */ 1690 NULL, /* create per-directory config structures */
1674 NULL, /* [5] check/validate user_id */ 1691 NULL, /* merge per-directory config structures */
1675 NULL, /* [6] check authorization */ 1692 log_sql_make_state, /* create per-server config structures */
1676 NULL, /* [4] check access by host */ 1693 NULL, /* merge per-server config structures */
1677 NULL, /* [7] MIME type checker/setter */ 1694 log_sql_cmds, /* command handlers */
1678 NULL, /* [8] fixups */ 1695 register_hooks /* register hooks */
1679 log_sql_transaction, /* [10] logger */
1680 NULL /* [3] header parser */
1681#if MODULE_MAGIC_NUMBER >= 19970728 /* 1.3-dev or later support these additionals... */
1682 ,log_sql_child_init, /* child process initializer */
1683 log_sql_child_exit, /* process exit/cleanup */
1684 NULL /* [1] post read-request */
1685#endif
1686
1687}; 1696};
diff --git a/mod_log_sql.prj b/mod_log_sql.prj
index ed84264..774fb61 100644
--- a/mod_log_sql.prj
+++ b/mod_log_sql.prj
@@ -29,7 +29,7 @@ anjuta.compatibility.level=1
29project.name=mod_log_sql 29project.name=mod_log_sql
30project.type=GENERIC 30project.type=GENERIC
31project.target.type=EXECUTABLE 31project.target.type=EXECUTABLE
32project.version=1.99 32project.version=1.90
33project.author=Edward Rudd 33project.author=Edward Rudd
34project.source.target=unknown 34project.source.target=unknown
35project.has.gettext=0 35project.has.gettext=0
@@ -72,7 +72,8 @@ module.data.type=
72module.data.expanded=1 72module.data.expanded=1
73module.data.files=\ 73module.data.files=\
74 Makefile.in\ 74 Makefile.in\
75 configure.ac 75 configure.ac\
76 create_tables.sql
76 77
77module.help.name=. 78module.help.name=.
78module.help.type= 79module.help.type=
@@ -84,7 +85,10 @@ module.doc.type=
84module.doc.expanded=1 85module.doc.expanded=1
85module.doc.files=\ 86module.doc.files=\
86 Documentation/README\ 87 Documentation/README\
87 INSTALL 88 INSTALL\
89 Documentation/documentation.lyx\
90 CHANGELOG\
91 LICENSE
88 92
89module.po.expanded=0 93module.po.expanded=0
90module.po.files= 94module.po.files=