summaryrefslogtreecommitdiffstats
path: root/mod_log_sql_mysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod_log_sql_mysql.c')
-rw-r--r--mod_log_sql_mysql.c259
1 files changed, 0 insertions, 259 deletions
diff --git a/mod_log_sql_mysql.c b/mod_log_sql_mysql.c
deleted file mode 100644
index e64044e..0000000
--- a/mod_log_sql_mysql.c
+++ /dev/null
@@ -1,259 +0,0 @@
1/* $Id$ */
2
3#if defined(WITH_APACHE20)
4# include "apache20.h"
5#elif defined(WITH_APACHE13)
6# include "apache13.h"
7#else
8# error Unsupported Apache version
9#endif
10
11#ifdef HAVE_CONFIG_H
12/* Undefine these to prevent conflicts between Apache ap_config_auto.h and
13 * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt.
14 */
15#undef PACKAGE_BUGREPORT
16#undef PACKAGE_NAME
17#undef PACKAGE_STRING
18#undef PACKAGE_TARNAME
19#undef PACKAGE_VERSION
20
21#include "config.h"
22#endif
23
24#include "mod_log_sql.h"
25
26#include "mysql.h"
27#include "mysqld_error.h"
28
29/* The enduser won't modify these */
30#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
31
32/* Connect to the MYSQL database */
33static logsql_opendb_ret log_sql_mysql_connect(server_rec *s, logsql_dbconnection *db)
34{
35 const char *host = apr_table_get(db->parms,"hostname");
36 const char *user = apr_table_get(db->parms,"username");
37 const char *passwd = apr_table_get(db->parms,"password");
38 const char *database = apr_table_get(db->parms,"database");
39 const char *s_tcpport = apr_table_get(db->parms,"port");
40 unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):3306;
41 const char *socketfile = apr_table_get(db->parms,"socketfile");
42 MYSQL *dblink = db->handle;
43
44 dblink = mysql_init(dblink);
45 db->handle = (void *)dblink;
46
47
48 if (!socketfile) {
49 socketfile = "/var/lib/mysql/mysql.sock";
50 }
51
52 if (mysql_real_connect(dblink, host, user, passwd, database, tcpport,
53 socketfile, 0)) {
54 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
55 host, tcpport, database, user, socketfile);
56 return LOGSQL_OPENDB_SUCCESS;
57 } else {
58 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"mod_log_sql: database connection error: %s",
59 MYSQL_ERROR(dblink));
60 log_error(APLOG_MARK,APLOG_DEBUG, 0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
61 host, tcpport, database, user, socketfile);
62 return LOGSQL_OPENDB_FAIL;
63 }
64}
65
66/* Close the DB link */
67static void log_sql_mysql_close(logsql_dbconnection *db)
68{
69 mysql_close((MYSQL *)db->handle);
70}
71
72/* Routine to escape the 'dangerous' characters that would otherwise
73 * corrupt the INSERT string: ', \, and "
74 */
75static const char *log_sql_mysql_escape(const char *from_str, apr_pool_t *p,
76 logsql_dbconnection *db)
77{
78 if (!from_str)
79 return NULL;
80 else {
81 char *to_str;
82 unsigned long length = strlen(from_str);
83 unsigned long retval;
84
85 /* Pre-allocate a new string that could hold twice the original, which would only
86 * happen if the whole original string was 'dangerous' characters.
87 */
88 to_str = (char *) apr_palloc(p, length * 2 + 1);
89 if (!to_str) {
90 return from_str;
91 }
92
93 if (!db->connected) {
94 /* Well, I would have liked to use the current database charset. mysql is
95 * unavailable, however, so I fall back to the slightly less respectful
96 * mysql_escape_string() function that uses the default charset.
97 */
98 retval = mysql_escape_string(to_str, from_str, length);
99 } else {
100 /* MySQL is available, so I'll go ahead and respect the current charset when
101 * I perform the escape.
102 */
103 retval = mysql_real_escape_string((MYSQL *)db->handle, to_str, from_str, length);
104 }
105
106 if (retval)
107 return to_str;
108 else
109 return from_str;
110 }
111}
112#if defined(WIN32)
113#define SIGNAL_GRAB
114#define SIGNAL_RELEASE
115#define SIGNAL_VAR
116#else
117#define SIGNAL_VAR void (*handler) (int);
118#define SIGNAL_GRAB handler = signal(SIGPIPE, SIG_IGN);
119#define SIGNAL_RELEASE signal(SIGPIPE, handler);
120#endif
121/* Run a mysql insert query and return a categorized error or success */
122static logsql_query_ret log_sql_mysql_query(request_rec *r,logsql_dbconnection *db,
123 const char *query)
124{
125 int retval;
126 SIGNAL_VAR
127
128 unsigned int real_error = 0;
129 /*const char *real_error_str = NULL;*/
130
131 MYSQL *dblink = (MYSQL *)db->handle;
132
133 if (!dblink) {
134 return LOGSQL_QUERY_NOLINK;
135 }
136
137 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
138 SIGNAL_GRAB
139
140 /* Run the query */
141 if (!(retval = mysql_query(dblink, query))) {
142 SIGNAL_RELEASE
143 return LOGSQL_QUERY_SUCCESS;
144 }
145 /* Check to see if the error is "nonexistent table" */
146 real_error = mysql_errno(dblink);
147
148 if (real_error == ER_NO_SUCH_TABLE) {
149 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query");
150 /* Restore SIGPIPE to its original handler function */
151 SIGNAL_RELEASE
152 return LOGSQL_QUERY_NOTABLE;
153 }
154
155 /* Restore SIGPIPE to its original handler function */
156 SIGNAL_RELEASE
157 return LOGSQL_QUERY_FAIL;
158}
159
160/* Create table table_name of type table_type. */
161static logsql_table_ret log_sql_mysql_create(request_rec *r, logsql_dbconnection *db,
162 logsql_tabletype table_type, const char *table_name)
163{
164 int retval;
165 const char *tabletype = apr_table_get(db->parms,"tabletype");
166 SIGNAL_VAR
167 char *type_suffix = NULL;
168
169 char *create_prefix = "create table if not exists `";
170 char *create_suffix = NULL;
171 char *create_sql;
172
173 MYSQL *dblink = (MYSQL *)db->handle;
174
175/* if (!global_config.createtables) {
176 return APR_SUCCESS;
177 }*/
178
179 switch (table_type) {
180 case LOGSQL_TABLE_ACCESS:
181 create_suffix =
182 "` (id char(19),\
183 agent varchar(255),\
184 bytes_sent int unsigned,\
185 child_pid smallint unsigned,\
186 cookie varchar(255),\
187 machine_id varchar(25),\
188 request_file varchar(255),\
189 referer varchar(255),\
190 remote_host varchar(50),\
191 remote_logname varchar(50),\
192 remote_user varchar(50),\
193 request_duration smallint unsigned,\
194 request_line varchar(255),\
195 request_method varchar(10),\
196 request_protocol varchar(10),\
197 request_time char(28),\
198 request_uri varchar(255),\
199 request_args varchar(255),\
200 server_port smallint unsigned,\
201 ssl_cipher varchar(25),\
202 ssl_keysize smallint unsigned,\
203 ssl_maxkeysize smallint unsigned,\
204 status smallint unsigned,\
205 time_stamp int unsigned,\
206 virtual_host varchar(255))";
207 break;
208 case LOGSQL_TABLE_COOKIES:
209 case LOGSQL_TABLE_HEADERSIN:
210 case LOGSQL_TABLE_HEADERSOUT:
211 case LOGSQL_TABLE_NOTES:
212 create_suffix =
213 "` (id char(19),\
214 item varchar(80),\
215 val varchar(80))";
216 break;
217 }
218
219 if (tabletype) {
220 type_suffix = apr_pstrcat(r->pool, " TYPE=",
221 tabletype, NULL);
222 }
223 /* Find memory long enough to hold the whole CREATE string + \0 */
224 create_sql = apr_pstrcat(r->pool, create_prefix, table_name, create_suffix,
225 type_suffix, NULL);
226
227 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql);
228
229 if (!dblink) {
230 return LOGSQL_QUERY_NOLINK;
231 }
232 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
233 SIGNAL_GRAB
234
235 /* Run the create query */
236 if ((retval = mysql_query(dblink, create_sql))) {
237 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"failed to create table: %s",
238 table_name);
239 SIGNAL_RELEASE
240 return LOGSQL_TABLE_FAIL;
241 }
242 SIGNAL_RELEASE
243 return LOGSQL_TABLE_SUCCESS;
244}
245
246static char *supported_drivers[] = {"mysql",NULL};
247static logsql_dbdriver mysql_driver = {
248 supported_drivers,
249 log_sql_mysql_connect, /* open DB connection */
250 log_sql_mysql_close, /* close DB connection */
251 log_sql_mysql_escape, /* escape query */
252 log_sql_mysql_query, /* insert query */
253 log_sql_mysql_create /* create table */
254};
255
256LOGSQL_REGISTER(mysql) {
257 log_sql_register_driver(p,&mysql_driver);
258 LOGSQL_REGISTER_RETURN;
259}