showlog: Show all host and service states by default
[nagios-reports-module.git] / sql.c
blob2a9c56773ee4e21baabc55c6c170a601b133cfc6
1 #include "ndbneb.h"
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include "sql.h"
5 #include "logging.h"
7 static struct {
8 char *host;
9 char *name;
10 char *user;
11 char *pass;
12 char *table;
13 unsigned int port;
14 MYSQL *link;
15 } db;
17 #undef ESC_BUFS
18 #define ESC_BUFS 8 /* must be a power of 2 */
19 #define MAX_ESC_STRING 65536
21 typedef unsigned int uint;
23 #define esc(s) sql_escape(s)
24 char *sql_escape(const char *str)
26 static int idx = 0;
27 static char *buf_ary[ESC_BUFS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
28 static uint bufsize[ESC_BUFS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
29 char *buf;
30 int len;
32 if (!str || !*str)
33 return "";
35 len = strlen(str);
36 if (len > MAX_ESC_STRING) {
37 lwarn("Unescaped string too large (%d bytes, %d is allowed)",
38 len, MAX_ESC_STRING);
39 return "";
42 if (bufsize[idx] < len * 2) {
43 uint size = len * 2;
44 if (size < 16384)
45 size = 16384;
47 buf_ary[idx] = realloc(buf_ary[idx], size);
48 if (!buf_ary[idx]) {
49 bufsize[idx] = 0;
50 lwarn("Failed to allocate %d bytes for sql escape buffer", size);
51 return "";
53 bufsize[idx] = size;
55 buf = buf_ary[idx];
56 idx = (idx + 1) & (ESC_BUFS - 1);
57 mysql_real_escape_string(db.link, buf, str, len);
59 return buf;
63 * these two functions are only here to allow callers
64 * access to error reporting without having to expose
65 * the db-link to theh callers. It's also nifty as we
66 * want to remain database layer agnostic
68 const char *sql_error()
70 if (db.link)
71 return mysql_error(db.link);
73 return "unknown error (no link)";
76 int sql_errno(void)
78 if (db.link)
79 return mysql_errno(db.link);
81 return -1;
84 SQL_RESULT *sql_get_result(void)
86 if (db.link)
87 return mysql_use_result(db.link);
89 return NULL;
92 SQL_ROW sql_fetch_row(MYSQL_RES *result)
94 if (result)
95 return mysql_fetch_row(result);
97 return NULL;
100 void sql_free_result(SQL_RESULT *result)
102 if (result)
103 mysql_free_result(result);
106 int sql_query(const char *fmt, ...)
108 char *query;
109 int len, result = 0;
110 va_list ap;
112 va_start(ap, fmt);
113 len = vasprintf(&query, fmt, ap);
114 va_end(ap);
116 if (len == -1 || !query) {
117 lerr("sql_query: Failed to build query from format-string '%s'", fmt);
118 return -1;
120 if ((result = mysql_real_query(db.link, query, len))) {
121 lerr("mysql_query(): Retrying failed query [%s]: %s",
122 query, mysql_error(db.link));
124 sql_close();
125 sql_init();
126 if ((result = mysql_real_query(db.link, query, len)))
127 lerr("mysql_query(): Dropping failed query [%s]: %s",
128 query, mysql_error(db.link));
131 free(query);
133 return result;
136 int sql_init(void)
138 if (!(db.link = mysql_init(NULL)))
139 return -1;
141 if (!db.host) {
142 db.host = "";
143 db.port = 0;
146 if (!(mysql_real_connect(db.link, db.host, db.user, db.pass,
147 db.name, db.port, NULL, 0)))
149 lerr("Failed to connect to '%s' at '%s':'%d' using %s:%s as credentials: %s",
150 db.name, db.host, db.port, db.user, db.pass, mysql_error(db.link));
152 db.link = NULL;
153 return -1;
156 return 0;
159 int sql_close(void)
161 if (db.link)
162 mysql_close(db.link);
164 return 0;
167 const char *sql_table_name(void)
169 if (!db.table)
170 return "report_data";
172 return db.table;
175 int sql_config(const char *key, const char *value)
177 if (!prefixcmp(key, "db_database"))
178 db.name = strdup(value);
179 else if (!prefixcmp(key, "db_user"))
180 db.user = strdup(value);
181 else if (!prefixcmp(key, "db_pass"))
182 db.pass = strdup(value);
183 else if (!prefixcmp(key, "db_host"))
184 db.host = strdup(value);
185 else if (!prefixcmp(key, "db_table")) {
186 db.table = strdup(value);
188 else if (!prefixcmp(key, "db_port")) {
189 char *endp;
191 db.port = (unsigned int)strtoul(value, &endp, 0);
193 if (endp == value || *endp != 0)
194 return -1;
196 else
197 return -1; /* config error */
199 return 0;