1 /**
2 * @file db.c Database routines for ndo2db daemon
3 */
4 /*
5 * Copyright 2009-2014 Nagios Core Development Team and Community Contributors
6 * Copyright 2005-2009 Ethan Galstad
7 *
8 * This file is part of NDOUtils.
9 *
10 * NDOUtils is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * NDOUtils is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with NDOUtils. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 /* include our project's header files */
24 #include "../include/config.h"
25 #include "../include/common.h"
26 #include "../include/io.h"
27 #include "../include/utils.h"
28 #include "../include/protoapi.h"
29 #include "../include/ndo2db.h"
30 #include "../include/dbhandlers.h"
31 #include "../include/db.h"
32
33 extern int errno;
34
35 extern ndo2db_dbconfig ndo2db_db_settings;
36 extern time_t ndo2db_db_last_checkin_time;
37
38 char *ndo2db_db_rawtablenames[NDO2DB_MAX_DBTABLES]={
39 "instances",
40 "conninfo",
41 "objects",
42 "objecttypes",
43 "logentries",
44 "systemcommands",
45 "eventhandlers",
46 "servicechecks",
47 "hostchecks",
48 "programstatus",
49 "externalcommands",
50 "servicestatus",
51 "hoststatus",
52 "processevents",
53 "timedevents",
54 "timedeventqueue",
55 "flappinghistory",
56 "commenthistory",
57 "comments",
58 "notifications",
59 "contactnotifications",
60 "contactnotificationmethods",
61 "acknowledgements",
62 "statehistory",
63 "downtimehistory",
64 "scheduleddowntime",
65 "configfiles",
66 "configfilevariables",
67 "runtimevariables",
68 "contactstatus",
69 "customvariablestatus",
70 "",
71 "",
72 "",
73 "",
74 "",
75 "",
76 "",
77 "",
78 "",
79 "commands",
80 "timeperiods",
81 "timeperiod_timeranges",
82 "contactgroups",
83 "contactgroup_members",
84 "hostgroups",
85 "hostgroup_members",
86 "servicegroups",
87 "servicegroup_members",
88 "hostescalations",
89 "hostescalation_contacts",
90 "serviceescalations",
91 "serviceescalation_contacts",
92 "hostdependencies",
93 "servicedependencies",
94 "contacts",
95 "contact_addresses",
96 "contact_notificationcommands",
97 "hosts",
98 "host_parenthosts",
99 "host_contacts",
100 "services",
101 "service_contacts",
102 "customvariables",
103 "host_contactgroups",
104 "service_contactgroups",
105 "hostescalation_contactgroups",
106 "serviceescalation_contactgroups",
107 "service_parentservices",
108 };
109
110
111 char *ndo2db_db_tablenames[NDO2DB_MAX_DBTABLES];
112
113 /*
114 #define DEBUG_NDO2DB_QUERIES 1
115 */
116
117 /****************************************************************************/
118 /* CONNECTION FUNCTIONS */
119 /****************************************************************************/
120
121 /* initialize database structures */
ndo2db_db_init(ndo2db_idi * idi)122 int ndo2db_db_init(ndo2db_idi *idi){
123 register int x;
124
125 if(idi==NULL)
126 return NDO_ERROR;
127
128 /* initialize db server type */
129 idi->dbinfo.server_type=ndo2db_db_settings.server_type;
130
131 /* initialize table names */
132 for(x=0;x<NDO2DB_MAX_DBTABLES;x++){
133 if((ndo2db_db_tablenames[x]=(char *)malloc(strlen(ndo2db_db_rawtablenames[x])+((ndo2db_db_settings.dbprefix==NULL)?0:strlen(ndo2db_db_settings.dbprefix))+1))==NULL)
134 return NDO_ERROR;
135 sprintf(ndo2db_db_tablenames[x],"%s%s",(ndo2db_db_settings.dbprefix==NULL)?"":ndo2db_db_settings.dbprefix,ndo2db_db_rawtablenames[x]);
136 }
137
138 /* initialize other variables */
139 idi->dbinfo.connected=NDO_FALSE;
140 idi->dbinfo.error=NDO_FALSE;
141 idi->dbinfo.instance_id=0L;
142 idi->dbinfo.conninfo_id=0L;
143 idi->dbinfo.latest_program_status_time=(time_t)0L;
144 idi->dbinfo.latest_host_status_time=(time_t)0L;
145 idi->dbinfo.latest_service_status_time=(time_t)0L;
146 idi->dbinfo.latest_queued_event_time=(time_t)0L;
147 idi->dbinfo.latest_realtime_data_time=(time_t)0L;
148 idi->dbinfo.latest_comment_time=(time_t)0L;
149 idi->dbinfo.clean_event_queue=NDO_FALSE;
150 idi->dbinfo.last_notification_id=0L;
151 idi->dbinfo.last_contact_notification_id=0L;
152 idi->dbinfo.max_timedevents_age=ndo2db_db_settings.max_timedevents_age;
153 idi->dbinfo.max_systemcommands_age=ndo2db_db_settings.max_systemcommands_age;
154 idi->dbinfo.max_servicechecks_age=ndo2db_db_settings.max_servicechecks_age;
155 idi->dbinfo.max_hostchecks_age=ndo2db_db_settings.max_hostchecks_age;
156 idi->dbinfo.max_eventhandlers_age=ndo2db_db_settings.max_eventhandlers_age;
157 idi->dbinfo.max_externalcommands_age=ndo2db_db_settings.max_externalcommands_age;
158 idi->dbinfo.max_notifications_age=ndo2db_db_settings.max_notifications_age;
159 idi->dbinfo.max_contactnotifications_age=ndo2db_db_settings.max_contactnotifications_age;
160 idi->dbinfo.max_contactnotificationmethods_age=ndo2db_db_settings.max_contactnotificationmethods_age;
161 idi->dbinfo.max_logentries_age=ndo2db_db_settings.max_logentries_age;
162 idi->dbinfo.max_acknowledgements_age=ndo2db_db_settings.max_acknowledgements_age;
163 idi->dbinfo.last_table_trim_time=(time_t)0L;
164 idi->dbinfo.last_logentry_time=(time_t)0L;
165 idi->dbinfo.last_logentry_data=NULL;
166 idi->dbinfo.object_hashlist=NULL;
167
168 /* initialize db structures, etc. */
169 if(!mysql_init(&idi->dbinfo.mysql_conn)){
170 syslog(LOG_USER|LOG_INFO,"Error: mysql_init() failed\n");
171 return NDO_ERROR;
172 }
173
174 return NDO_OK;
175 }
176
177
178 /* clean up database structures */
ndo2db_db_deinit(ndo2db_idi * idi)179 int ndo2db_db_deinit(ndo2db_idi *idi){
180 register int x;
181
182 if(idi==NULL)
183 return NDO_ERROR;
184
185 /* free table names */
186 for(x=0;x<NDO2DB_MAX_DBTABLES;x++){
187 if(ndo2db_db_tablenames[x])
188 free(ndo2db_db_tablenames[x]);
189 ndo2db_db_tablenames[x]=NULL;
190 }
191
192 /* free cached object ids */
193 ndo2db_free_cached_object_ids(idi);
194
195 return NDO_OK;
196 }
197
198
199 /* connects to the database server */
ndo2db_db_connect(ndo2db_idi * idi)200 int ndo2db_db_connect(ndo2db_idi *idi){
201 int result=NDO_OK;
202
203 if(idi==NULL)
204 return NDO_ERROR;
205
206 /* we're already connected... */
207 if(idi->dbinfo.connected==NDO_TRUE)
208 return NDO_OK;
209
210 if (!mysql_real_connect(
211 &idi->dbinfo.mysql_conn,
212 ndo2db_db_settings.host,
213 ndo2db_db_settings.username,
214 ndo2db_db_settings.password,
215 ndo2db_db_settings.dbname,
216 ndo2db_db_settings.port,
217 ndo2db_db_settings.socket,
218 CLIENT_REMEMBER_OPTIONS
219 )) {
220 mysql_close(&idi->dbinfo.mysql_conn);
221 syslog(LOG_USER|LOG_INFO,"Error: Could not connect to MySQL database: %s",mysql_error(&idi->dbinfo.mysql_conn));
222 result=NDO_ERROR;
223 idi->disconnect_client=NDO_TRUE;
224 } else {
225 idi->dbinfo.connected=NDO_TRUE;
226 syslog(LOG_USER|LOG_DEBUG,"Successfully connected to MySQL database");
227 }
228
229 return result;
230 }
231
232
233 /* disconnects from the database server */
ndo2db_db_disconnect(ndo2db_idi * idi)234 int ndo2db_db_disconnect(ndo2db_idi *idi){
235
236 if(idi==NULL)
237 return NDO_ERROR;
238
239 /* we're not connected... */
240 if(idi->dbinfo.connected==NDO_FALSE)
241 return NDO_OK;
242
243 /* close the connection to the database server */
244 mysql_close(&idi->dbinfo.mysql_conn);
245 idi->dbinfo.connected=NDO_FALSE;
246 syslog(LOG_USER|LOG_DEBUG,"Successfully disconnected from MySQL database");
247
248 return NDO_OK;
249 }
250
251
252 /* post-connect routines */
ndo2db_db_hello(ndo2db_idi * idi)253 int ndo2db_db_hello(ndo2db_idi *idi){
254 char *buf=NULL;
255 char *ts=NULL;
256 int result=NDO_OK;
257 int have_instance=NDO_FALSE;
258 time_t current_time;
259
260 /* make sure we have an instance name */
261 if(idi->instance_name==NULL)
262 idi->instance_name=strdup("default");
263
264 /* get existing instance */
265 if(asprintf(&buf,"SELECT instance_id FROM %s WHERE instance_name='%s'",ndo2db_db_tablenames[NDO2DB_DBTABLE_INSTANCES],idi->instance_name)==-1)
266 buf=NULL;
267 if((result=ndo2db_db_query(idi,buf))==NDO_OK){
268 idi->dbinfo.mysql_result=mysql_store_result(&idi->dbinfo.mysql_conn);
269 if((idi->dbinfo.mysql_row=mysql_fetch_row(idi->dbinfo.mysql_result))!=NULL){
270 ndo2db_convert_string_to_unsignedlong(idi->dbinfo.mysql_row[0],&idi->dbinfo.instance_id);
271 have_instance=NDO_TRUE;
272 }
273 mysql_free_result(idi->dbinfo.mysql_result);
274 idi->dbinfo.mysql_result=NULL;
275 }
276 free(buf);
277
278 /* insert new instance if necessary */
279 if(have_instance==NDO_FALSE){
280 if(asprintf(&buf,"INSERT INTO %s SET instance_name='%s'",ndo2db_db_tablenames[NDO2DB_DBTABLE_INSTANCES],idi->instance_name)==-1)
281 buf=NULL;
282 if((result=ndo2db_db_query(idi,buf))==NDO_OK){
283 idi->dbinfo.instance_id=mysql_insert_id(&idi->dbinfo.mysql_conn);
284 }
285 free(buf);
286 }
287
288 ts=ndo2db_db_timet_to_sql(idi,idi->data_start_time);
289
290 /* record initial connection information */
291 if(asprintf(&buf,"INSERT INTO %s SET instance_id='%lu', connect_time=NOW(), last_checkin_time=NOW(), bytes_processed='0', lines_processed='0', entries_processed='0', agent_name='%s', agent_version='%s', disposition='%s', connect_source='%s', connect_type='%s', data_start_time=%s"
292 ,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONNINFO]
293 ,idi->dbinfo.instance_id
294 ,idi->agent_name
295 ,idi->agent_version
296 ,idi->disposition
297 ,idi->connect_source
298 ,idi->connect_type
299 ,ts
300 )==-1)
301 buf=NULL;
302 if((result=ndo2db_db_query(idi,buf))==NDO_OK){
303 idi->dbinfo.conninfo_id=mysql_insert_id(&idi->dbinfo.mysql_conn);
304 }
305 free(buf);
306 free(ts);
307
308 /* get cached object ids... */
309 ndo2db_get_cached_object_ids(idi);
310
311 /* get latest times from various tables... */
312 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_PROGRAMSTATUS],"status_update_time",(unsigned long *)&idi->dbinfo.latest_program_status_time);
313 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_HOSTSTATUS],"status_update_time",(unsigned long *)&idi->dbinfo.latest_host_status_time);
314 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_SERVICESTATUS],"status_update_time",(unsigned long *)&idi->dbinfo.latest_service_status_time);
315 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONTACTSTATUS],"status_update_time",(unsigned long *)&idi->dbinfo.latest_contact_status_time);
316 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_TIMEDEVENTQUEUE],"queued_time",(unsigned long *)&idi->dbinfo.latest_queued_event_time);
317 ndo2db_db_get_latest_data_time(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_COMMENTS],"entry_time",(unsigned long *)&idi->dbinfo.latest_comment_time);
318
319 /* calculate time of latest realtime data */
320 idi->dbinfo.latest_realtime_data_time=(time_t)0L;
321 if(idi->dbinfo.latest_program_status_time>idi->dbinfo.latest_realtime_data_time)
322 idi->dbinfo.latest_realtime_data_time=idi->dbinfo.latest_program_status_time;
323 if(idi->dbinfo.latest_host_status_time>idi->dbinfo.latest_realtime_data_time)
324 idi->dbinfo.latest_realtime_data_time=idi->dbinfo.latest_host_status_time;
325 if(idi->dbinfo.latest_service_status_time>idi->dbinfo.latest_realtime_data_time)
326 idi->dbinfo.latest_realtime_data_time=idi->dbinfo.latest_service_status_time;
327 if(idi->dbinfo.latest_contact_status_time>idi->dbinfo.latest_realtime_data_time)
328 idi->dbinfo.latest_realtime_data_time=idi->dbinfo.latest_contact_status_time;
329 if(idi->dbinfo.latest_queued_event_time>idi->dbinfo.latest_realtime_data_time)
330 idi->dbinfo.latest_realtime_data_time=idi->dbinfo.latest_queued_event_time;
331
332 /* get current time */
333 /* make sure latest time stamp isn't in the future - this will cause problems if a backwards system time change occurs */
334 time(¤t_time);
335 if(idi->dbinfo.latest_realtime_data_time>current_time)
336 idi->dbinfo.latest_realtime_data_time=current_time;
337
338 /* set flags to clean event queue, etc. */
339 idi->dbinfo.clean_event_queue=NDO_TRUE;
340
341 /* set misc data */
342 idi->dbinfo.last_notification_id=0L;
343 idi->dbinfo.last_contact_notification_id=0L;
344
345 return result;
346 }
347
348
349 /* pre-disconnect routines */
ndo2db_db_goodbye(ndo2db_idi * idi)350 int ndo2db_db_goodbye(ndo2db_idi *idi){
351 int result=NDO_OK;
352 char *buf=NULL;
353 char *ts=NULL;
354
355 ts=ndo2db_db_timet_to_sql(idi,idi->data_end_time);
356
357 /* record last connection information */
358 if(asprintf(&buf,"UPDATE %s SET disconnect_time=NOW(), last_checkin_time=NOW(), data_end_time=%s, bytes_processed='%lu', lines_processed='%lu', entries_processed='%lu' WHERE conninfo_id='%lu'"
359 ,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONNINFO]
360 ,ts
361 ,idi->bytes_processed
362 ,idi->lines_processed
363 ,idi->entries_processed
364 ,idi->dbinfo.conninfo_id
365 )==-1)
366 buf=NULL;
367 result=ndo2db_db_query(idi,buf);
368 free(buf);
369
370 free(ts);
371
372 return result;
373 }
374
375
376 /* checking routines */
ndo2db_db_checkin(ndo2db_idi * idi)377 int ndo2db_db_checkin(ndo2db_idi *idi){
378 int result=NDO_OK;
379 char *buf=NULL;
380
381 /* record last connection information */
382 if(asprintf(&buf,"UPDATE %s SET last_checkin_time=NOW(), bytes_processed='%lu', lines_processed='%lu', entries_processed='%lu' WHERE conninfo_id='%lu'"
383 ,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONNINFO]
384 ,idi->bytes_processed
385 ,idi->lines_processed
386 ,idi->entries_processed
387 ,idi->dbinfo.conninfo_id
388 )==-1)
389 buf=NULL;
390 result=ndo2db_db_query(idi,buf);
391 free(buf);
392
393 time(&ndo2db_db_last_checkin_time);
394
395 return result;
396 }
397
398
399
400 /****************************************************************************/
401 /* MISC FUNCTIONS */
402 /****************************************************************************/
403
404 /* escape a string for a SQL statement */
ndo2db_db_escape_string(ndo2db_idi * idi,char * buf)405 char *ndo2db_db_escape_string(ndo2db_idi *idi, char *buf){
406 register int x,y,z;
407 char *newbuf=NULL;
408
409 if(idi==NULL || buf==NULL)
410 return NULL;
411
412 z=strlen(buf);
413
414 /* allocate space for the new string */
415 if((newbuf=(char *)malloc((z*2)+1))==NULL)
416 return NULL;
417
418 /* escape characters */
419 for(x=0,y=0;x<z;x++){
420
421 if(buf[x]=='\'' || buf[x]=='\"' || buf[x]=='*' || buf[x]=='\\' || buf[x]=='$' || buf[x]=='?' || buf[x]=='.' || buf[x]=='^' || buf[x]=='+' || buf[x]=='[' || buf[x]==']' || buf[x]=='(' || buf[x]==')')
422 newbuf[y++]='\\';
423
424 newbuf[y++]=buf[x];
425 }
426
427 /* terminate escape string */
428 newbuf [y]='\0';
429
430 return newbuf;
431 }
432
433
434 /* SQL query conversion of time_t format to date/time format */
ndo2db_db_timet_to_sql(ndo2db_idi * idi,time_t t)435 char *ndo2db_db_timet_to_sql(ndo2db_idi *idi, time_t t){
436 char *buf=NULL;
437 (void)idi; /* Unused, don't warn. */
438
439 asprintf(&buf,"FROM_UNIXTIME(%lu)",(unsigned long)t);
440
441 return buf;
442 }
443
444
445 /* SQL query conversion of date/time format to time_t format */
ndo2db_db_sql_to_timet(ndo2db_idi * idi,char * field)446 char *ndo2db_db_sql_to_timet(ndo2db_idi *idi, char *field){
447 char *buf=NULL;
448 (void)idi; /* Unused, don't warn. */
449
450 asprintf(&buf,"UNIX_TIMESTAMP(%s)",(field==NULL)?"":field);
451
452 return buf;
453 }
454
455
456 /* executes a SQL statement */
ndo2db_db_query(ndo2db_idi * idi,char * buf)457 int ndo2db_db_query(ndo2db_idi *idi, char *buf){
458 int result=NDO_OK;
459 int query_result=0;
460
461 if(idi==NULL || buf==NULL)
462 return NDO_ERROR;
463
464 /* if we're not connected, try and reconnect... */
465 if(idi->dbinfo.connected==NDO_FALSE){
466 if(ndo2db_db_connect(idi)==NDO_ERROR)
467 return NDO_ERROR;
468 ndo2db_db_hello(idi);
469 }
470
471 #ifdef DEBUG_NDO2DB_QUERIES
472 printf("%s\n\n",buf);
473 #endif
474
475 ndo2db_log_debug_info(NDO2DB_DEBUGL_SQL,0,"%s\n",buf);
476
477 if (mysql_query(&idi->dbinfo.mysql_conn,buf)) {
478 syslog(LOG_USER|LOG_INFO,"Error: mysql_query() failed for '%s'\n",buf);
479 syslog(LOG_USER|LOG_INFO,"mysql_error: '%s'\n", mysql_error(&idi->dbinfo.mysql_conn));
480 result=NDO_ERROR;
481 }
482
483 /* handle errors */
484 if(result==NDO_ERROR)
485 ndo2db_handle_db_error(idi,query_result);
486
487 return result;
488 }
489
490
491 /* frees memory associated with a query */
ndo2db_db_free_query(ndo2db_idi * idi)492 int ndo2db_db_free_query(ndo2db_idi *idi){
493
494 if(idi==NULL)
495 return NDO_ERROR;
496
497 return NDO_OK;
498 }
499
500
501 /* handles SQL query errors */
ndo2db_handle_db_error(ndo2db_idi * idi,int query_result)502 int ndo2db_handle_db_error(ndo2db_idi *idi, int query_result){
503 int result=0;
504
505 if(idi==NULL)
506 return NDO_ERROR;
507
508 /* we're not currently connected... */
509 if(idi->dbinfo.connected==NDO_FALSE)
510 return NDO_OK;
511
512 result=mysql_errno(&idi->dbinfo.mysql_conn);
513 if(result==CR_SERVER_LOST || result==CR_SERVER_GONE_ERROR){
514 syslog(LOG_USER|LOG_INFO,"Error: Connection to MySQL database has been lost!\n");
515 ndo2db_db_disconnect(idi);
516 idi->disconnect_client=NDO_TRUE;
517 }
518
519 return NDO_OK;
520 }
521
522
523 /* clears data from a given table (current instance only) */
ndo2db_db_clear_table(ndo2db_idi * idi,char * table_name)524 int ndo2db_db_clear_table(ndo2db_idi *idi, char *table_name){
525 char *buf=NULL;
526 int result=NDO_OK;
527
528 if(idi==NULL || table_name==NULL)
529 return NDO_ERROR;
530
531 if(asprintf(&buf,"DELETE FROM %s WHERE instance_id='%lu'"
532 ,table_name
533 ,idi->dbinfo.instance_id
534 )==-1)
535 buf=NULL;
536
537 result=ndo2db_db_query(idi,buf);
538 free(buf);
539
540 return result;
541 }
542
543
544 /* gets latest data time value from a given table */
ndo2db_db_get_latest_data_time(ndo2db_idi * idi,char * table_name,char * field_name,unsigned long * t)545 int ndo2db_db_get_latest_data_time(ndo2db_idi *idi, char *table_name, char *field_name, unsigned long *t){
546 char *buf=NULL;
547 char *ts[1];
548 int result=NDO_OK;
549
550 if(idi==NULL || table_name==NULL || field_name==NULL || t==NULL)
551 return NDO_ERROR;
552
553 *t=(time_t)0L;
554 ts[0]=ndo2db_db_sql_to_timet(idi,field_name);
555
556 if(asprintf(&buf,"SELECT %s AS latest_time FROM %s WHERE instance_id='%lu' ORDER BY %s DESC LIMIT 0,1"
557 ,ts[0]
558 ,table_name
559 ,idi->dbinfo.instance_id
560 ,field_name
561 )==-1)
562 buf=NULL;
563
564 if((result=ndo2db_db_query(idi,buf))==NDO_OK){
565 idi->dbinfo.mysql_result=mysql_store_result(&idi->dbinfo.mysql_conn);
566 if((idi->dbinfo.mysql_row=mysql_fetch_row(idi->dbinfo.mysql_result))!=NULL){
567 ndo2db_convert_string_to_unsignedlong(idi->dbinfo.mysql_row[0],t);
568 }
569 mysql_free_result(idi->dbinfo.mysql_result);
570 idi->dbinfo.mysql_result=NULL;
571 }
572 free(buf);
573 free(ts[0]);
574
575 return result;
576 }
577
578
579 /* trim/delete old data from a given table */
ndo2db_db_trim_data_table(ndo2db_idi * idi,char * table_name,char * field_name,unsigned long t)580 int ndo2db_db_trim_data_table(ndo2db_idi *idi, char *table_name, char *field_name, unsigned long t){
581 char *buf=NULL;
582 char *ts[1];
583 int result=NDO_OK;
584
585 if(idi==NULL || table_name==NULL || field_name==NULL)
586 return NDO_ERROR;
587
588 ts[0]=ndo2db_db_timet_to_sql(idi,(time_t)t);
589
590 if(asprintf(&buf,"DELETE FROM %s WHERE instance_id='%lu' AND %s<%s"
591 ,table_name
592 ,idi->dbinfo.instance_id
593 ,field_name
594 ,ts[0]
595 )==-1)
596 buf=NULL;
597
598 result=ndo2db_db_query(idi,buf);
599 free(buf);
600 free(ts[0]);
601
602 return result;
603 }
604
605
606 /* performs some periodic table maintenance... */
ndo2db_db_perform_maintenance(ndo2db_idi * idi)607 int ndo2db_db_perform_maintenance(ndo2db_idi *idi){
608 time_t current_time;
609
610 /* get the current time */
611 time(¤t_time);
612
613 /* trim tables */
614 if ((current_time-(time_t)60)>idi->dbinfo.last_table_trim_time) {
615 if (idi->dbinfo.max_timedevents_age>0L) {
616 syslog(LOG_USER|LOG_INFO,"Trimming timedevents.");
617 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_TIMEDEVENTS],"scheduled_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_timedevents_age));
618 }
619 if (idi->dbinfo.max_systemcommands_age>0L) {
620 syslog(LOG_USER|LOG_INFO,"Trimming systemcommands.");
621 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_SYSTEMCOMMANDS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_systemcommands_age));
622 }
623 if (idi->dbinfo.max_servicechecks_age>0L) {
624 syslog(LOG_USER|LOG_INFO,"Trimming servicechecks.");
625 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_SERVICECHECKS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_servicechecks_age));
626 }
627 if (idi->dbinfo.max_hostchecks_age>0L) {
628 syslog(LOG_USER|LOG_INFO,"Trimming hostchecks.");
629 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_HOSTCHECKS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_hostchecks_age));
630 }
631 if (idi->dbinfo.max_eventhandlers_age>0L) {
632 syslog(LOG_USER|LOG_INFO,"Trimming eventhandlers.");
633 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_EVENTHANDLERS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_eventhandlers_age));
634 }
635 if (idi->dbinfo.max_externalcommands_age>0L) {
636 syslog(LOG_USER|LOG_INFO,"Trimming externalcommands.");
637 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_EXTERNALCOMMANDS],"entry_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_externalcommands_age));
638 }
639 if (idi->dbinfo.max_notifications_age>0L) {
640 syslog(LOG_USER|LOG_INFO,"Trimming notifications.");
641 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_NOTIFICATIONS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_notifications_age));
642 }
643 if (idi->dbinfo.max_contactnotifications_age>0L) {
644 syslog(LOG_USER|LOG_INFO,"Trimming contactnotifications.");
645 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONTACTNOTIFICATIONS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_contactnotifications_age));
646 }
647 if (idi->dbinfo.max_contactnotificationmethods_age>0L) {
648 syslog(LOG_USER|LOG_INFO,"Trimming contactnotificationmethods.");
649 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_CONTACTNOTIFICATIONMETHODS],"start_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_contactnotificationmethods_age));
650 }
651 if (idi->dbinfo.max_logentries_age>0L) {
652 syslog(LOG_USER|LOG_INFO,"Trimming logentries.");
653 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_LOGENTRIES],"entry_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_logentries_age));
654 }
655 if (idi->dbinfo.max_acknowledgements_age>0L) {
656 syslog(LOG_USER|LOG_INFO,"Trimming acknowledgements.");
657 ndo2db_db_trim_data_table(idi,ndo2db_db_tablenames[NDO2DB_DBTABLE_ACKNOWLEDGEMENTS],"entry_time",(time_t)((unsigned long)current_time-idi->dbinfo.max_acknowledgements_age));
658 }
659 idi->dbinfo.last_table_trim_time=current_time;
660 }
661
662 return NDO_OK;
663 }
664