summaryrefslogtreecommitdiffstatsabout
path: root/src/mod_log_sql_dbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_log_sql_dbi.c')
-rw-r--r--src/mod_log_sql_dbi.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/mod_log_sql_dbi.c b/src/mod_log_sql_dbi.c
new file mode 100644
index 0000000..5b83836
--- /dev/null
+++ b/src/mod_log_sql_dbi.c
@@ -0,0 +1,263 @@
1/* $Id: mod_log_sql_dbi.c 120 2004-04-17 15:14:12Z urkle@drip.ws $ */
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
12#ifdef HAVE_CONFIG_H
13/* Undefine these to prevent conflicts between Apache ap_config_auto.h and
14 * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt.
15 */
16#undef PACKAGE_BUGREPORT
17#undef PACKAGE_NAME
18#undef PACKAGE_STRING
19#undef PACKAGE_TARNAME
20#undef PACKAGE_VERSION
21
22#include "autoconfig.h"
23#endif
24
25#include "mod_log_sql.h"
26
27#include "dbi/dbi.h"
28
29typedef struct {
30 dbi_conn conn;
31} dbi_conn_rec;
32
33/* Connect to the MYSQL database */
34static logsql_opendb_ret log_sql_dbi_connect(server_rec *s, logsql_dbconnection *db)
35{
36 const char *driver = apr_table_get(db->parms,"driver");
37 const char *host = apr_table_get(db->parms,"hostname");
38 const char *user = apr_table_get(db->parms,"username");
39 const char *passwd = apr_table_get(db->parms,"password");
40 const char *database = apr_table_get(db->parms,"database");
41 const char *s_tcpport = apr_table_get(db->parms,"port");
42 unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):0;
43 const char *socketfile = apr_table_get(db->parms,"socketfile");
44 //dbi_result result;
45 dbi_conn_rec *dblink = db->handle;
46 if (!dblink) {
47 dblink = apr_pcalloc(db->p, sizeof(*dblink));
48 db->handle = (void *)dblink;
49 }
50
51 dblink->conn = dbi_conn_new(driver);
52
53 dbi_conn_set_option(dblink->conn, "host", host);
54 dbi_conn_set_option(dblink->conn, "username", user);
55 dbi_conn_set_option(dblink->conn, "password", passwd);
56 dbi_conn_set_option(dblink->conn, "dbname", database);
57 if (tcpport) {
58 dbi_conn_set_option_numeric(dblink->conn, "port", tcpport);
59 }
60
61 if (socketfile && !strcmp(driver,"mysql")) {
62 dbi_conn_set_option(dblink->conn, "mysql_unix_socket", socketfile);
63 }
64
65 if (!dbi_conn_connect(dblink->conn)) {
66 log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
67 "HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
68 host, tcpport, database, user, socketfile);
69 return LOGSQL_OPENDB_SUCCESS;
70 } else {
71 const char *error;
72 dbi_conn_error(dblink->conn, &error);
73 log_error(APLOG_MARK, APLOG_ERR, 0, s,
74 "DBI Error: %s", error);
75 log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
76 "HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
77 host, tcpport, database, user, socketfile);
78 return LOGSQL_OPENDB_FAIL;
79 }
80}
81
82/* Close the DB link */
83static void log_sql_dbi_close(logsql_dbconnection *db)
84{
85 dbi_conn_rec *dblink = db->handle;
86 dbi_conn_close(dblink->conn);
87 dblink->conn = NULL;
88}
89
90/* Routine to escape the 'dangerous' characters that would otherwise
91 * corrupt the INSERT string: ', \, and "
92 */
93static const char *log_sql_dbi_escape(request_rec *r,const char *from_str, apr_pool_t *p,
94 logsql_dbconnection *db)
95{
96 dbi_conn_rec *dblink = db->handle;
97
98 if (!from_str)
99 return NULL;
100 else {
101 char *to_str = strdup(from_str);
102 char *retval;
103 dbi_driver_quote_string(dbi_conn_get_driver(dblink->conn), &to_str);
104 retval = apr_pstrdup(p, to_str);
105 free(to_str);
106 return retval;
107 }
108}
109
110/* Run a mysql insert query and return a categorized error or success */
111static logsql_query_ret log_sql_dbi_query(request_rec *r,logsql_dbconnection *db,
112 const char *query)
113{
114 const char *error;
115 dbi_result result;
116 dbi_conn_rec *dblink = db->handle;
117
118 if (!dblink->conn) {
119 return LOGSQL_QUERY_NOLINK;
120 }
121
122 /* Run the query */
123 if ((result = dbi_conn_query(dblink->conn, query))) {
124 return LOGSQL_QUERY_SUCCESS;
125 }
126 /* Check to see if the error is "nonexistent table" */
127 dbi_conn_error(dblink->conn, &error);
128 log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
129 "DBI Error: %s", error);
130/* if (real_error == ER_NO_SUCH_TABLE) {
131 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query");
132 return LOGSQL_QUERY_NOTABLE;
133 }*/
134 return LOGSQL_QUERY_FAIL;
135}
136
137/* Create table table_name of type table_type. */
138static logsql_table_ret log_sql_dbi_create(request_rec *r, logsql_dbconnection *db,
139 logsql_tabletype table_type, const char *table_name)
140{
141 dbi_result result;
142 const char *driver = apr_table_get(db->parms,"driver");
143 const char *tabletype = apr_table_get(db->parms,"tabletype");
144 char *type_suffix = NULL;
145
146 char *create_prefix = "create table if not exists `";
147 char *create_suffix = NULL;
148 char *create_sql;
149
150 dbi_conn_rec *dblink = db->handle;
151
152/* if (!global_config.createtables) {
153 return APR_SUCCESS;
154 }*/
155
156 switch (table_type) {
157 case LOGSQL_TABLE_ACCESS:
158 create_suffix =
159 "` (id char(19),\
160 agent varchar(255),\
161 bytes_sent int unsigned,\
162 child_pid smallint unsigned,\
163 cookie varchar(255),\
164 machine_id varchar(25),\
165 request_file varchar(255),\
166 referer varchar(255),\
167 remote_host varchar(50),\
168 remote_logname varchar(50),\
169 remote_user varchar(50),\
170 request_duration smallint unsigned,\
171 request_line varchar(255),\
172 request_method varchar(10),\
173 request_protocol varchar(10),\
174 request_time char(28),\
175 request_uri varchar(255),\
176 request_args varchar(255),\
177 server_port smallint unsigned,\
178 ssl_cipher varchar(25),\
179 ssl_keysize smallint unsigned,\
180 ssl_maxkeysize smallint unsigned,\
181 status smallint unsigned,\
182 time_stamp int unsigned,\
183 virtual_host varchar(255))";
184 break;
185 case LOGSQL_TABLE_COOKIES:
186 case LOGSQL_TABLE_HEADERSIN:
187 case LOGSQL_TABLE_HEADERSOUT:
188 case LOGSQL_TABLE_NOTES:
189 create_suffix =
190 "` (id char(19),\
191 item varchar(80),\
192 val varchar(80))";
193 break;
194 }
195
196 if (tabletype && !strcmp(driver,"mysql")) {
197 type_suffix = apr_pstrcat(r->pool, " TYPE=",
198 tabletype, NULL);
199 }
200 /* Find memory long enough to hold the whole CREATE string + \0 */
201 create_sql = apr_pstrcat(r->pool, create_prefix, table_name, create_suffix,
202 type_suffix, NULL);
203
204 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql);
205
206 if (!dblink) {
207 return LOGSQL_QUERY_NOLINK;
208 }
209
210 /* Run the create query */
211 if (!(result = dbi_conn_query(dblink, create_sql))) {
212 const char *error;
213 dbi_conn_error(dblink->conn, &error);
214 log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
215 "DBI Error: %s", error);
216 return LOGSQL_TABLE_FAIL;
217 }
218
219 return LOGSQL_TABLE_SUCCESS;
220}
221
222static logsql_dbdriver log_sql_dbi_driver = {
223 "dbi",
224 NULL,
225 log_sql_dbi_connect, /* open DB connection */
226 log_sql_dbi_close, /* close DB connection */
227 log_sql_dbi_escape, /* escape query */
228 log_sql_dbi_query, /* insert query */
229 log_sql_dbi_create /* create table */
230};
231
232static apr_status_t log_sql_dbi_cleanup(void *data)
233{
234 dbi_shutdown();
235#if defined(WITH_APACHE20)
236 return APR_SUCCESS;
237#endif
238}
239
240LOGSQL_REGISTER(dbi) {
241 dbi_driver driver;
242 const char **driver_list;
243 int count = 1;
244
245 dbi_initialize(NULL);
246
247 for (driver = dbi_driver_list(NULL);
248 driver;
249 driver = dbi_driver_list(driver)) {
250 count++;
251 }
252 driver_list = apr_pcalloc(p, sizeof(char *) * (count));
253 count = 0;
254 for (driver = dbi_driver_list(NULL);
255 driver;
256 driver = dbi_driver_list(driver)) {
257 driver_list[count++] = dbi_driver_get_name(driver);
258 }
259 log_sql_dbi_driver.provided_drivers = driver_list;
260 log_sql_register_driver(p,&log_sql_dbi_driver);
261 apr_pool_cleanup_register(p, NULL, log_sql_dbi_cleanup, NULL);
262 LOGSQL_REGISTER_RETURN;
263}