Icinga-core 1.4.0
next gen monitoring
module/idoutils/src/ido2db.c
Go to the documentation of this file.
00001 /***************************************************************
00002  * IDO2DB.C - IDO To Database Daemon
00003  *
00004  * Copyright (c) 2005-2008 Ethan Galstad
00005  * Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org)
00006  *
00007  **************************************************************/
00008 
00009 /*#define DEBUG_MEMORY 1*/
00010 
00011 #ifdef DEBUG_MEMORY
00012 #include <mcheck.h>
00013 #endif
00014 
00015 /* include our project's header files */
00016 #include "../../../include/config.h"
00017 #include "../include/common.h"
00018 #include "../include/io.h"
00019 #include "../include/utils.h"
00020 #include "../include/protoapi.h"
00021 #include "../include/ido2db.h"
00022 #include "../include/db.h"
00023 #include "../include/dbhandlers.h"
00024 
00025 
00026 #ifdef HAVE_SSL
00027 #include "../../../include/dh.h"
00028 #endif
00029 
00030 extern int use_ssl;
00031 
00032 extern int errno;
00033 
00034 extern char *ido2db_db_tablenames[IDO2DB_MAX_DBTABLES];
00035 
00036 #ifdef USE_LIBDBI
00037 extern int ido2db_check_dbd_driver(void);
00038 #endif
00039 
00040 /* use global dynamic buffer for mutex locks */
00041 ido_dbuf dbuf;
00042 static pthread_mutex_t ido2db_dbuf_lock;
00043 
00044 static void *ido2db_thread_cleanup_exit_handler(void *);
00045 static void *ido2db_thread_worker_exit_handler(void *);
00046 
00047 /*
00048 pthread_mutex_lock(&ido2db_dbuf_lock);
00049 pthread_mutex_unlock(&ido2db_dbuf_lock);
00050 */
00051 
00052 #ifdef HAVE_SSL
00053 SSL_METHOD *meth;
00054 SSL_CTX *ctx;
00055 int allow_weak_random_seed = IDO_FALSE;
00056 #endif
00057 
00058 char *ido2db_config_file=NULL;
00059 char *lock_file=NULL;
00060 char *ido2db_user=NULL;
00061 char *ido2db_group=NULL;
00062 
00063 int ido2db_sd=0;
00064 int ido2db_socket_type=IDO_SINK_UNIXSOCKET;
00065 char *ido2db_socket_name=NULL;
00066 
00067 int ido2db_tcp_port=IDO_DEFAULT_TCP_PORT;
00068 int ido2db_use_inetd=IDO_FALSE;
00069 
00070 int ido2db_show_version=IDO_FALSE;
00071 int ido2db_show_license=IDO_FALSE;
00072 int ido2db_show_help=IDO_FALSE;
00073 
00074 int ido2db_run_foreground=IDO_FALSE;
00075 
00076 ido2db_dbconfig ido2db_db_settings;
00077 ido2db_idi thread_idi;
00078 pthread_t thread_pool[IDO2DB_NR_OF_THREADS];
00079 
00080 time_t ido2db_db_last_checkin_time=0L;
00081 
00082 char *ido2db_debug_file=NULL;
00083 int ido2db_debug_level=IDO2DB_DEBUGL_NONE;
00084 int ido2db_debug_verbosity=IDO2DB_DEBUGV_BASIC;
00085 FILE *ido2db_debug_file_fp=NULL;
00086 unsigned long ido2db_max_debug_file_size=0L;
00087 
00088 int stop_signal_detected=IDO_FALSE;
00089 
00090 char *sigs[35]={"EXIT","HUP","INT","QUIT","ILL","TRAP","ABRT","BUS","FPE","KILL","USR1","SEGV","USR2","PIPE","ALRM","TERM","STKFLT","CHLD","CONT","STOP","TSTP","TTIN","TTOU","URG","XCPU","XFSZ","VTALRM","PROF","WINCH","IO","PWR","UNUSED","ZERR","DEBUG",(char *)NULL};
00091 
00092 
00093 int ido2db_open_debug_log(void);
00094 int ido2db_close_debug_log(void);
00095 
00096 
00097 int dummy;      /* reduce compiler warnings */
00098 
00099 
00100 int main(int argc, char **argv){
00101         int result=IDO_OK;
00102 
00103 #ifdef DEBUG_MEMORY
00104         mtrace();
00105 #endif
00106 #ifdef HAVE_SSL
00107         DH *dh;
00108         char seedfile[FILENAME_MAX];
00109         int i,c;
00110 #endif
00111 #ifdef USE_LIBDBI
00112         dbi_driver driver;
00113         int numdrivers;
00114 
00115         driver = NULL;
00116 #endif
00117         result=ido2db_process_arguments(argc,argv);
00118 
00119         if(result!=IDO_OK || ido2db_show_help==IDO_TRUE || ido2db_show_license==IDO_TRUE || ido2db_show_version==IDO_TRUE){
00120 
00121                 if(result!=IDO_OK)
00122                         printf("Incorrect command line arguments supplied\n");
00123 
00124                 printf("\n");
00125                 printf("%s %s\n",IDO2DB_NAME,IDO2DB_VERSION);
00126                 printf("Copyright(c) 2005-2008 Ethan Galstad (nagios@nagios.org)\n");
00127                 printf("Copyright(c) 2009-2011 Icinga Development Team (http://www.icinga.org)\n");
00128                 printf("Last Modified: %s\n",IDO2DB_DATE);
00129                 printf("License: GPL v2\n");
00130 #ifdef HAVE_SSL
00131                 printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
00132 #endif
00133                 printf("\n");
00134                 printf("Stores Icinga event and configuration data to a database for later retrieval\n");
00135                 printf("and processing.  Clients that are capable of sending data to the IDO2DB daemon\n");
00136                 printf("include the LOG2IDO utility and IDOMOD event broker module.\n");
00137                 printf("\n");
00138                 printf("Usage: %s -c <config_file> [-i] [-f]\n",argv[0]);
00139                 printf("\n");
00140                 printf("-i  = Run under INETD/XINETD.\n");
00141                 printf("-f  = Don't daemonize, run in foreground.\n");
00142                 printf("\n");
00143                 exit(1);
00144                 }
00145 
00146         /* initialize variables */
00147         ido2db_initialize_variables();
00148 
00149         /* process config file */
00150         if(ido2db_process_config_file(ido2db_config_file)!=IDO_OK){
00151                 printf("Error processing config file '%s'.\n",ido2db_config_file);
00152                 exit(1);
00153         }
00154 
00155         /* print starting info to syslog */
00156         syslog(LOG_USER | LOG_INFO, "%s %s (%s) Copyright (c) 2005-2008 Ethan Galstad (nagios@nagios.org), Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org))", IDO2DB_NAME, IDO2DB_VERSION, IDO2DB_DATE);
00157         syslog(LOG_USER | LOG_INFO, "%s %s starting... (PID=%d)\n", IDO2DB_NAME, IDO2DB_VERSION, (int)getpid() );
00158 
00159         if (ido2db_socket_type==IDO_SINK_UNIXSOCKET && use_ssl == IDO_TRUE){
00160                 printf("SSL is not allowed on socket_type=unix\n");
00161                 exit(1);
00162         }
00163 
00164 #ifdef HAVE_SSL
00165                 /* initialize SSL */
00166                 if(use_ssl==IDO_TRUE){
00167                         SSL_library_init();
00168                         SSLeay_add_ssl_algorithms();
00169                         meth=SSLv23_server_method();
00170                         SSL_load_error_strings();
00171 
00172                         /* use week random seed if necessary */
00173                         if(allow_weak_random_seed && (RAND_status()==0)){
00174 
00175                                 if(RAND_file_name(seedfile,sizeof(seedfile)-1))
00176                                         if(RAND_load_file(seedfile,-1))
00177                                                 RAND_write_file(seedfile);
00178 
00179                                 if(RAND_status()==0){
00180                                         syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged");
00181                                         srand(time(NULL));
00182                                         for(i=0;i<500 && RAND_status()==0;i++){
00183                                                 for(c=0;c<sizeof(seedfile);c+=sizeof(int)){
00184                                                         *((int *)(seedfile+c))=rand();
00185                                                         }
00186                                                 RAND_seed(seedfile,sizeof(seedfile));
00187                                                 }
00188                                         }
00189                                 }
00190                         if((ctx=SSL_CTX_new(meth))==NULL){
00191                                 syslog(LOG_ERR,"Error: could not create SSL context.\n");
00192                                 exit(1);
00193                                 }
00194 
00195                         /* ADDED 01/19/2004 */
00196                         /* use only TLSv1 protocol */
00197                         SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
00198 
00199                         /* use anonymous DH ciphers */
00200                         SSL_CTX_set_cipher_list(ctx,"ADH");
00201                         dh=get_dh512();
00202                         SSL_CTX_set_tmp_dh(ctx,dh);
00203                         DH_free(dh);
00204                         syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
00205                         }
00206                 else{
00207                         syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
00208                         }
00209                 /*Fin Hack SSL*/
00210 #endif
00211 
00212         /* make sure we're good to go */
00213         if(ido2db_check_init_reqs()!=IDO_OK){
00214                 printf("One or more required parameters is missing or incorrect.\n");
00215                 exit(1);
00216                 }
00217 
00218         /* make sure we support the db option chosen... */
00219 
00220 /******************************/
00221 #ifdef USE_LIBDBI /* everything else will be libdbi */
00222         if(ido2db_check_dbd_driver()==IDO_FALSE){
00223                 printf("Support for the specified database server is either not yet supported, or was not found on your system.\n");
00224 
00225                 numdrivers = dbi_initialize(NULL);
00226 
00227                 fprintf(stderr, "%d drivers available: ", numdrivers);
00228                 while ((driver = dbi_driver_list(driver)) != NULL) {
00229 
00230                         fprintf(stderr, "%s ", dbi_driver_get_name(driver));
00231                 }
00232                 fprintf(stderr, "\n");
00233 
00234 #ifdef HAVE_SSL
00235                 if(use_ssl==IDO_TRUE)
00236                         SSL_CTX_free(ctx);
00237 #endif
00238 
00239                 exit(1);
00240                 }
00241 
00242         /* 2009-10-16 Michael Friedrich: libdbi Oracle driver is not yet working, remains broken */
00243         if(ido2db_db_settings.server_type==IDO2DB_DBSERVER_ORACLE) {
00244                 printf("Support for libdbi Oracle driver is not yet working.\n");
00245                 exit(1);
00246         }
00247 #endif
00248 
00249 /******************************/
00250 #ifdef USE_PGSQL /* pgsql */
00251 
00252         /* we don't have a driver check here */
00253 #endif
00254 
00255 /******************************/
00256 #ifdef USE_ORACLE /* Oracle ocilib specific */
00257 
00258         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db with ocilib() driver check\n");
00259         if(OCI_GetOCIRuntimeVersion == OCI_UNKNOWN) {
00260                 printf("Unknown ocilib runtime version detected. Exiting...\n");
00261 
00262 #ifdef HAVE_SSL
00263                 if(use_ssl==IDO_TRUE)
00264                         SSL_CTX_free(ctx);
00265 #endif
00266 
00267                 exit(1);
00268         }
00269 
00270 #endif /* Oracle ocilib specific */
00271 /******************************/
00272 
00273         /* initialize signal handling */
00274         signal(SIGQUIT,ido2db_parent_sighandler);
00275         signal(SIGTERM,ido2db_parent_sighandler);
00276         signal(SIGINT,ido2db_parent_sighandler);
00277         signal(SIGSEGV,ido2db_parent_sighandler);
00278         signal(SIGFPE,ido2db_parent_sighandler);
00279         signal(SIGCHLD,ido2db_parent_sighandler);
00280 
00281         /* drop privileges */
00282         ido2db_drop_privileges(ido2db_user,ido2db_group);
00283 
00284         /* open debug log */
00285         ido2db_open_debug_log();
00286 
00287         /* if we're running under inetd... */
00288         if(ido2db_use_inetd==IDO_TRUE){
00289 
00290                 /* redirect STDERR to /dev/null */
00291                 close(2);
00292                 open("/dev/null",O_WRONLY);
00293 
00294                 /* handle the connection */
00295                 ido2db_handle_client_connection(0);
00296                 }
00297 
00298         /* standalone daemon... */
00299         else{
00300 
00301                 /* create socket and wait for clients to connect */
00302                 if(ido2db_wait_for_connections()==IDO_ERROR)
00303                         return 1;
00304                 }
00305 
00306         /* tell the log we're done */
00307         syslog(LOG_USER | LOG_INFO, "Successfully shutdown... (PID=%d)\n",(int)getpid());
00308 
00309         /* close debug log */
00310         ido2db_close_debug_log();
00311 
00312         /* free memory */
00313         ido2db_free_program_memory();
00314 
00315 #ifdef HAVE_SSL
00316         if(use_ssl==IDO_TRUE)
00317                 SSL_CTX_free(ctx);
00318 #endif
00319 
00320         return 0;
00321         }
00322 
00323 
00324 /* process command line arguments */
00325 int ido2db_process_arguments(int argc, char **argv){
00326         char optchars[32];
00327         int c=1;
00328 
00329 #ifdef HAVE_GETOPT_H
00330         int option_index=0;
00331         static struct option long_options[]={
00332                 {"configfile", required_argument, 0, 'c'},
00333                 {"inetd", no_argument, 0, 'i'},
00334                 {"foreground", no_argument, 0, 'f'},
00335                 {"help", no_argument, 0, 'h'},
00336                 {"license", no_argument, 0, 'l'},
00337                 {"version", no_argument, 0, 'V'},
00338                 {0, 0, 0, 0}
00339                 };
00340 #endif
00341 
00342         /* no options were supplied */
00343         if(argc<2){
00344                 ido2db_show_help=IDO_TRUE;
00345                 return IDO_OK;
00346                 }
00347 
00348         snprintf(optchars,sizeof(optchars),"c:ifhlV");
00349 
00350         while(1){
00351 #ifdef HAVE_GETOPT_H
00352                 c=getopt_long(argc,argv,optchars,long_options,&option_index);
00353 #else
00354                 c=getopt(argc,argv,optchars);
00355 #endif
00356                 if(c==-1 || c==EOF)
00357                         break;
00358 
00359                 /* process all arguments */
00360                 switch(c){
00361 
00362                 case '?':
00363                 case 'h':
00364                         ido2db_show_help=IDO_TRUE;
00365                         break;
00366                 case 'V':
00367                         ido2db_show_version=IDO_TRUE;
00368                         break;
00369                 case 'l':
00370                         ido2db_show_license=IDO_TRUE;
00371                         break;
00372                 case 'c':
00373                         ido2db_config_file=strdup(optarg);
00374                         break;
00375                 case 'i':
00376                         ido2db_use_inetd=IDO_TRUE;
00377                         break;
00378                 case 'f':
00379                         ido2db_run_foreground=IDO_TRUE;
00380                         break;
00381                 default:
00382                         return IDO_ERROR;
00383                         break;
00384                         }
00385                 }
00386 
00387         /* make sure required args were supplied */
00388         if((ido2db_config_file==NULL) && ido2db_show_help==IDO_FALSE && ido2db_show_version==IDO_FALSE  && ido2db_show_license==IDO_FALSE)
00389                 return IDO_ERROR;
00390 
00391         return IDO_OK;
00392         }
00393 
00394 
00395 
00396 /****************************************************************************/
00397 /* CONFIG FUNCTIONS                                                         */
00398 /****************************************************************************/
00399 
00400 /* process all config vars in a file */
00401 int ido2db_process_config_file(char *filename){
00402         ido_mmapfile *thefile=NULL;
00403         char *buf=NULL;
00404         int result=IDO_OK;
00405 
00406         /* open the file */
00407         if((thefile=ido_mmap_fopen(filename))==NULL){
00408                 syslog(LOG_ERR, "Error: Unable to open configuration file %s: %s\n", filename, strerror(errno));
00409                 return IDO_ERROR;
00410         }
00411 
00412         /* process each line of the file */
00413         while((buf=ido_mmap_fgets(thefile))){
00414 
00415                 /* skip comments */
00416                 if(buf[0]=='#'){
00417                         free(buf);
00418                         continue;
00419                         }
00420 
00421                 /* skip blank lines */
00422                 if(!strcmp(buf,"")){
00423                         free(buf);
00424                         continue;
00425                         }
00426 
00427                 /* process the variable */
00428                 result=ido2db_process_config_var(buf);
00429 
00430                 /* free memory */
00431                 free(buf);
00432 
00433                 if(result!=IDO_OK)
00434                         break;
00435                 }
00436 
00437         /* close the file */
00438         ido_mmap_fclose(thefile);
00439 
00440         return result;
00441         }
00442 
00443 
00444 /* process a single module config variable */
00445 int ido2db_process_config_var(char *arg){
00446         char *var=NULL;
00447         char *val=NULL;
00448 
00449         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_process_config_var() start\n");
00450 
00451         /* split var/val */
00452         var=strtok(arg,"=");
00453         val=strtok(NULL,"\n");
00454 
00455         /* skip incomplete var/val pairs */
00456         if(var==NULL || val==NULL)
00457                 return IDO_OK;
00458 
00459         /* process the variable... */
00460 
00461         if(!strcmp(var,"lock_file")){
00462                 if((lock_file=strdup(val))==NULL)
00463                         return IDO_ERROR;
00464                 }
00465         else if(!strcmp(var,"socket_type")){
00466                 if(!strcmp(val,"tcp"))
00467                         ido2db_socket_type=IDO_SINK_TCPSOCKET;
00468                 else
00469                         ido2db_socket_type=IDO_SINK_UNIXSOCKET;
00470                 }
00471         else if(!strcmp(var,"socket_name")){
00472                 if((ido2db_socket_name=strdup(val))==NULL)
00473                         return IDO_ERROR;
00474                 }
00475         else if(!strcmp(var,"tcp_port")){
00476                 ido2db_tcp_port=atoi(val);
00477                 }
00478         else if(!strcmp(var,"db_servertype")){
00479                 if(!strcmp(val,"mysql")) {
00480                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_MYSQL;
00481                         ido2db_db_settings.dbserver=strdup(val);
00482                 } else if(!strcmp(val,"pgsql")) {
00483                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_PGSQL;
00484                         ido2db_db_settings.dbserver=strdup(val);
00485                 } else if(!strcmp(val,"db2")) {
00486                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_DB2;
00487                         ido2db_db_settings.dbserver=strdup(val);
00488                 } else if(!strcmp(val,"firebird")) {
00489                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_FIREBIRD;
00490                         ido2db_db_settings.dbserver=strdup(val);
00491                 } else if(!strcmp(val,"freetds")) {
00492                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_FREETDS;
00493                         ido2db_db_settings.dbserver=strdup(val);
00494                 } else if(!strcmp(val,"ingres")) {
00495                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_INGRES;
00496                         ido2db_db_settings.dbserver=strdup(val);
00497                 } else if(!strcmp(val,"msql")) {
00498                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_MSQL;
00499                         ido2db_db_settings.dbserver=strdup(val);
00500                 } else if(!strcmp(val,"oracle")) {
00501                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_ORACLE;
00502                         ido2db_db_settings.dbserver=strdup(val);
00503                 } else if(!strcmp(val,"sqlite")) {
00504                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_SQLITE;
00505                         ido2db_db_settings.dbserver=strdup(val);
00506                 } else if(!strcmp(val,"sqlite3")) {
00507                         ido2db_db_settings.server_type=IDO2DB_DBSERVER_SQLITE3;
00508                         ido2db_db_settings.dbserver=strdup(val);
00509                 } else
00510                         return IDO_ERROR;
00511                 }
00512         else if(!strcmp(var,"db_host")){
00513                 if((ido2db_db_settings.host=strdup(val))==NULL)
00514                         return IDO_ERROR;
00515                 }
00516         else if(!strcmp(var,"db_port")){
00517                 ido2db_db_settings.port=atoi(val);
00518                 }
00519         else if(!strcmp(var,"db_user")){
00520                 if((ido2db_db_settings.username=strdup(val))==NULL)
00521                         return IDO_ERROR;
00522                 }
00523         else if(!strcmp(var,"db_pass")){
00524                 if((ido2db_db_settings.password=strdup(val))==NULL)
00525                         return IDO_ERROR;
00526                 }
00527         else if(!strcmp(var,"db_name")){
00528                 if((ido2db_db_settings.dbname=strdup(val))==NULL)
00529                         return IDO_ERROR;
00530                 }
00531         else if(!strcmp(var,"db_prefix")){
00532                 if((ido2db_db_settings.dbprefix=strdup(val))==NULL)
00533                         return IDO_ERROR;
00534                 }
00535         else if(!strcmp(var,"db_socket")){
00536                 if((ido2db_db_settings.dbsocket=strdup(val))==NULL)
00537                         return IDO_ERROR;
00538                 }
00539         else if(!strcmp(var,"max_timedevents_age"))
00540                 ido2db_db_settings.max_timedevents_age=strtoul(val,NULL,0)*60;
00541         else if(!strcmp(var,"max_systemcommands_age"))
00542                 ido2db_db_settings.max_systemcommands_age=strtoul(val,NULL,0)*60;
00543         else if(!strcmp(var,"max_servicechecks_age"))
00544                 ido2db_db_settings.max_servicechecks_age=strtoul(val,NULL,0)*60;
00545         else if(!strcmp(var,"max_hostchecks_age"))
00546                 ido2db_db_settings.max_hostchecks_age=strtoul(val,NULL,0)*60;
00547         else if(!strcmp(var,"max_eventhandlers_age"))
00548                 ido2db_db_settings.max_eventhandlers_age=strtoul(val,NULL,0)*60;
00549         else if(!strcmp(var,"max_externalcommands_age"))
00550                 ido2db_db_settings.max_externalcommands_age=strtoul(val,NULL,0)*60;
00551         else if(!strcmp(var,"max_logentries_age"))
00552                 ido2db_db_settings.max_logentries_age=strtoul(val,NULL,0)*60;
00553         else if(!strcmp(var,"max_acknowledgements_age"))
00554                 ido2db_db_settings.max_acknowledgements_age=strtoul(val,NULL,0)*60;
00555 
00556         else if(!strcmp(var,"trim_db_interval"))
00557                 ido2db_db_settings.trim_db_interval=strtoul(val,NULL,0);
00558 
00559         else if(!strcmp(var,"housekeeping_thread_startup_delay"))
00560                 ido2db_db_settings.housekeeping_thread_startup_delay=strtoul(val,NULL,0);
00561 
00562         else if((!strcmp(var,"ido2db_user"))||(!strcmp(var,"ido2db_user")))
00563                 ido2db_user=strdup(val);
00564         else if((!strcmp(var,"ido2db_group"))||(!strcmp(var,"ido2db_group")))
00565                 ido2db_group=strdup(val);
00566 
00567         else if(!strcmp(var,"debug_file")){
00568                 if((ido2db_debug_file=strdup(val))==NULL)
00569                         return IDO_ERROR;
00570                 }
00571         else if(!strcmp(var,"debug_level"))
00572                 ido2db_debug_level=atoi(val);
00573         else if(!strcmp(var,"debug_verbosity"))
00574                 ido2db_debug_verbosity=atoi(val);
00575         else if(!strcmp(var,"max_debug_file_size"))
00576                 ido2db_max_debug_file_size=strtoul(val,NULL,0);
00577         else if(!strcmp(var,"use_ssl")){
00578                 if (strlen(val) == 1) {
00579                         if (isdigit((int)val[strlen(val)-1]) != IDO_FALSE)
00580                                 use_ssl = atoi(val);
00581                         else
00582                                 use_ssl = 0;
00583                 }
00584         }
00585         else if(!strcmp(var, "clean_realtime_tables_on_core_startup")) {
00586                 if(strlen(val)!=1||val[0]<'0'||val[0]>'1'){
00587                         return IDO_ERROR;
00588                 }
00589                 ido2db_db_settings.clean_realtime_tables_on_core_startup=(atoi(val)>0)?IDO_TRUE:IDO_FALSE;
00590         }
00591         else if(!strcmp(var, "clean_config_tables_on_core_startup")) {
00592                 if(strlen(val)!=1||val[0]<'0'||val[0]>'1'){
00593                         return IDO_ERROR;
00594                 }
00595                 ido2db_db_settings.clean_config_tables_on_core_startup=(atoi(val)>0)?IDO_TRUE:IDO_FALSE;
00596         }
00597 
00598         else if(!strcmp(var,"oci_errors_to_syslog")){
00599                 ido2db_db_settings.oci_errors_to_syslog=(atoi(val)>0)?IDO_TRUE:IDO_FALSE;
00600         }
00601 
00602         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_process_config_var() end\n");
00603 
00604         return IDO_OK;
00605         }
00606 
00607 
00608 /* initialize variables */
00609 int ido2db_initialize_variables(void){
00610 
00611         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_initialize_variables() start\n");
00612 
00613         ido2db_db_settings.server_type=IDO2DB_DBSERVER_NONE;
00614         ido2db_db_settings.host=NULL;
00615         ido2db_db_settings.port=0;
00616         ido2db_db_settings.username=NULL;
00617         ido2db_db_settings.password=NULL;
00618         ido2db_db_settings.dbname=NULL;
00619         ido2db_db_settings.dbprefix=NULL;
00620         ido2db_db_settings.dbsocket=NULL;
00621         ido2db_db_settings.max_timedevents_age=0L;
00622         ido2db_db_settings.max_systemcommands_age=0L;
00623         ido2db_db_settings.max_servicechecks_age=0L;
00624         ido2db_db_settings.max_hostchecks_age=0L;
00625         ido2db_db_settings.max_eventhandlers_age=0L;
00626         ido2db_db_settings.max_externalcommands_age=0L;
00627         ido2db_db_settings.max_logentries_age=0L;
00628         ido2db_db_settings.max_acknowledgements_age=0L;
00629         ido2db_db_settings.trim_db_interval=(unsigned long)DEFAULT_TRIM_DB_INTERVAL; /* set the default if missing in ido2db.cfg */
00630         ido2db_db_settings.housekeeping_thread_startup_delay=(unsigned long)DEFAULT_HOUSEKEEPING_THREAD_STARTUP_DELAY; /* set the default if missing in ido2db.cfg */
00631         ido2db_db_settings.clean_realtime_tables_on_core_startup=IDO_TRUE; /* default is cleaning on startup */
00632         ido2db_db_settings.clean_config_tables_on_core_startup=IDO_TRUE;
00633         ido2db_db_settings.oci_errors_to_syslog=DEFAULT_OCI_ERRORS_TO_SYSLOG;
00634 
00635         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_initialize_variables() end\n");
00636         return IDO_OK;
00637         }
00638 
00639 
00640 
00641 /****************************************************************************/
00642 /* CLEANUP FUNCTIONS                                                       */
00643 /****************************************************************************/
00644 
00645 /* free program memory */
00646 int ido2db_free_program_memory(void){
00647 
00648         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_program_memory() start\n");
00649 
00650         if(ido2db_config_file){
00651                 free(ido2db_config_file);
00652                 ido2db_config_file=NULL;
00653                 }
00654         if(ido2db_user){
00655                 free(ido2db_user);
00656                 ido2db_user=NULL;
00657                 }
00658         if(ido2db_group){
00659                 free(ido2db_group);
00660                 ido2db_group=NULL;
00661                 }
00662         if(ido2db_socket_name){
00663                 free(ido2db_socket_name);
00664                 ido2db_socket_name=NULL;
00665                 }
00666         if(ido2db_db_settings.host){
00667                 free(ido2db_db_settings.host);
00668                 ido2db_db_settings.host=NULL;
00669                 }
00670         if(ido2db_db_settings.username){
00671                 free(ido2db_db_settings.username);
00672                 ido2db_db_settings.username=NULL;
00673                 }
00674         if(ido2db_db_settings.password){
00675                 free(ido2db_db_settings.password);
00676                 ido2db_db_settings.password=NULL;
00677                 }
00678         if(ido2db_db_settings.dbname){
00679                 free(ido2db_db_settings.dbname);
00680                 ido2db_db_settings.dbname=NULL;
00681                 }
00682         if(ido2db_db_settings.dbprefix){
00683                 free(ido2db_db_settings.dbprefix);
00684                 ido2db_db_settings.dbprefix=NULL;
00685                 }
00686         if(ido2db_db_settings.dbsocket){
00687                 free(ido2db_db_settings.dbsocket);
00688                 ido2db_db_settings.dbsocket=NULL;
00689                 }
00690         if(ido2db_debug_file){
00691                 free(ido2db_debug_file);
00692                 ido2db_debug_file=NULL;
00693                 }
00694 
00695         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_program_memory() end\n");
00696         return IDO_OK;
00697         }
00698 
00699 
00700 
00701 /****************************************************************************/
00702 /* UTILITY FUNCTIONS                                                        */
00703 /****************************************************************************/
00704 
00705 int ido2db_check_init_reqs(void){
00706 
00707         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_init_reqs() start\n");
00708 
00709         if(ido2db_socket_type==IDO_SINK_UNIXSOCKET){
00710                 if(ido2db_socket_name==NULL){
00711                         printf("No socket name specified.\n");
00712                         return IDO_ERROR;
00713                         }
00714                 }
00715         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_init_reqs() end\n");
00716         return IDO_OK;
00717         }
00718 
00719 
00720 
00721 /* drops privileges */
00722 int ido2db_drop_privileges(char *user, char *group){
00723         uid_t uid=-1;
00724         gid_t gid=-1;
00725         struct group *grp;
00726         struct passwd *pw;
00727 
00728         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_drop_privileges() start\n");
00729 
00730         /* set effective group ID */
00731         if(group!=NULL){
00732 
00733                 /* see if this is a group name */
00734                 if(strspn(group,"0123456789")<strlen(group)){
00735                         grp=(struct group *)getgrnam(group);
00736                         if(grp!=NULL)
00737                                 gid=(gid_t)(grp->gr_gid);
00738                         else
00739                                 syslog(LOG_ERR,"Warning: Could not get group entry for '%s'",group);
00740                         endgrent();
00741                         }
00742 
00743                 /* else we were passed the GID */
00744                 else
00745                         gid=(gid_t)atoi(group);
00746 
00747                 /* set effective group ID if other than current EGID */
00748                 if(gid!=getegid()){
00749 
00750                         if(setgid(gid)==-1)
00751                                 syslog(LOG_ERR,"Warning: Could not set effective GID=%d",(int)gid);
00752                         }
00753                 }
00754 
00755 
00756         /* set effective user ID */
00757         if(user!=NULL){
00758 
00759                 /* see if this is a user name */
00760                 if(strspn(user,"0123456789")<strlen(user)){
00761                         pw=(struct passwd *)getpwnam(user);
00762                         if(pw!=NULL)
00763                                 uid=(uid_t)(pw->pw_uid);
00764                         else
00765                                 syslog(LOG_ERR,"Warning: Could not get passwd entry for '%s'",user);
00766                         endpwent();
00767                         }
00768 
00769                 /* else we were passed the UID */
00770                 else
00771                         uid=(uid_t)atoi(user);
00772 
00773                 /* set effective user ID if other than current EUID */
00774                 if(uid!=geteuid()){
00775 
00776 #ifdef HAVE_INITGROUPS
00777                         /* initialize supplementary groups */
00778                         if(initgroups(user,gid)==-1){
00779                                 if(errno==EPERM)
00780                                         syslog(LOG_ERR,"Warning: Unable to change supplementary groups using initgroups()");
00781                                 else{
00782                                         syslog(LOG_ERR,"Warning: Possibly root user failed dropping privileges with initgroups()");
00783                                         return IDO_ERROR;
00784                                         }
00785                                 }
00786 #endif
00787 
00788                         if(setuid(uid)==-1)
00789                                 syslog(LOG_ERR,"Warning: Could not set effective UID=%d",(int)uid);
00790                         }
00791                 }
00792         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_drop_privileges() end\n");
00793         return IDO_OK;
00794         }
00795 
00796 
00797 int ido2db_daemonize(void){
00798         pid_t pid=-1;
00799         /* int pidno=0; */
00800         int lockfile=0;
00801         struct flock lock;
00802         int val=0;
00803         char buf[256];
00804         char *msg=NULL;
00805 
00806         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() start\n");
00807 
00808         umask(S_IWGRP|S_IWOTH);
00809 
00810         /* get a lock on the lockfile */
00811         if(lock_file){
00812                 lockfile=open(lock_file,O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
00813                 if(lockfile<0){
00814                         if(asprintf(&msg,"Failed to obtain lock on file %s: %s\n", lock_file, strerror(errno))==-1)
00815                                 msg=NULL;
00816                         perror(msg);
00817                         ido2db_cleanup_socket();
00818                         return IDO_ERROR;
00819                         }
00820 
00821                 /* see if we can read the contents of the lockfile */
00822                 if((val=read(lockfile,buf,(size_t)10))<0){
00823                         if(asprintf(&msg,"Lockfile exists but cannot be read")==-1)
00824                                 msg=NULL;
00825                         perror(msg);
00826                         ido2db_cleanup_socket();
00827                         return IDO_ERROR;
00828                         }
00829 
00830                 /* place a file lock on the lock file */
00831                 lock.l_type=F_WRLCK;
00832                 lock.l_start=0;
00833                 lock.l_whence=SEEK_SET;
00834                 lock.l_len=0;
00835                 if(fcntl(lockfile,F_SETLK,&lock)<0){
00836                         if(errno==EACCES || errno==EAGAIN){
00837                                 fcntl(lockfile,F_GETLK,&lock);
00838                                 if(asprintf(&msg,"Lockfile '%s' looks like its already held by another instance (%d).  Bailing out...",lock_file,(int)lock.l_pid)==-1)
00839                                         msg=NULL;
00840                         }
00841                         else  {
00842                                 if(asprintf(&msg,"Cannot lock lockfile '%s': %s. Bailing out...",lock_file,strerror(errno))==-1)
00843                                         msg=NULL;
00844                         }
00845                         perror(msg);
00846                         ido2db_cleanup_socket();
00847                         return IDO_ERROR;
00848                         }
00849                 }
00850 
00851         /* fork */
00852         if((pid=fork())<0){
00853                 perror("Fork error");
00854                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() parent fork error\n");
00855                 ido2db_cleanup_socket();
00856                 return IDO_ERROR;
00857                 }
00858 
00859         /* parent process goes away... */
00860         else if((int)pid!=0){
00861                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() parent process goes away\n");
00862                 ido2db_free_program_memory();
00863                 exit(0);
00864                 }
00865 
00866         /* child forks again... */
00867         else{
00868                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() child forks again\n");
00869 
00870                 if((pid=fork())<0){
00871                         perror("Fork error");
00872                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() child fork error\n");
00873                         ido2db_cleanup_socket();
00874                         return IDO_ERROR;
00875                         }
00876 
00877                 /* first child process goes away.. */
00878                 else if((int)pid!=0){
00879                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() first child process goes away\n");
00880                         ido2db_free_program_memory();
00881                         exit(0);
00882                         }
00883 
00884                 /* grandchild continues... */
00885                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() grandchild continues and  becomes session leader\n");
00886                 /* grandchild becomes session leader... */
00887                 setsid();
00888                 }
00889 
00890         if(lock_file){
00891                 /* write PID to lockfile... */
00892                 lseek(lockfile,0,SEEK_SET);
00893                 dummy=ftruncate(lockfile,0);
00894                 sprintf(buf,"%d\n",(int)getpid());
00895                 dummy=write(lockfile,buf,strlen(buf));
00896 
00897                 /* make sure lock file stays open while program is executing... */
00898                 val=fcntl(lockfile,F_GETFD,0);
00899                 val|=FD_CLOEXEC;
00900                 fcntl(lockfile,F_SETFD,val);
00901                 }
00902 
00903         /* close existing stdin, stdout, stderr */
00904         close(0);
00905         if(ido2db_run_foreground == IDO_FALSE)
00906                 close(1);
00907         close(2);
00908 
00909         /* re-open stdin, stdout, stderr with known values */
00910         open("/dev/null",O_RDONLY);
00911         if(ido2db_run_foreground == IDO_FALSE)
00912                 open("/dev/null",O_WRONLY);
00913         open("/dev/null",O_WRONLY);
00914 
00915         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_daemonize() end\n");
00916 
00917         return IDO_OK;
00918         }
00919 
00920 
00921 int ido2db_cleanup_socket(void){
00922 
00923         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_cleanup_socket() start\n");
00924 
00925         /* we're running under INETD */
00926         if(ido2db_use_inetd==IDO_TRUE)
00927                 return IDO_OK;
00928 
00929         /* close the socket */
00930         shutdown(ido2db_sd,2);
00931         close(ido2db_sd);
00932 
00933         /* unlink the file */
00934         if(ido2db_socket_type==IDO_SINK_UNIXSOCKET)
00935                 unlink(ido2db_socket_name);
00936 
00937         if(lock_file)
00938                 unlink(lock_file);
00939 
00940         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_cleanup_socket() end\n");
00941         return IDO_OK;
00942         }
00943 
00944 
00945 void ido2db_parent_sighandler(int sig){
00946 
00947         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_parent_sighandler() start\n");
00948         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "processing signal '%d'\n", sig);
00949 
00950         /* not possible as parent */
00951         /* syslog(LOG_USER | LOG_INFO, "Processing SIG%s...\n", sigs[sig]); */
00952 
00953         switch (sig){
00954         case SIGTERM:
00955         case SIGINT:
00956                 /* forward signal to all members of this group of processes */
00957                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "forward signal to all members of this group of processes\n");
00958                 kill(0, sig);
00959                 break;
00960         case SIGCHLD:
00961                 /* cleanup children that exit, so we don't have zombies */
00962                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "cleanup children that exit, so we don't have zombies\n");
00963                 while(waitpid(-1,NULL,WNOHANG)>0);
00964                 return;
00965 
00966         default:
00967                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 0, "Caught the Signal '%d' but don't care about this.\n", sig);
00968         }
00969 
00970         /* cleanup the socket */
00971         ido2db_cleanup_socket();
00972 
00973         /* free memory */
00974         ido2db_free_program_memory();
00975 
00976         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_parent_sighandler() end\n");
00977 
00978         exit(0);
00979 
00980         return;
00981         }
00982 
00983 
00984 void ido2db_child_sighandler(int sig){
00985 
00986         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_child_sighandler() start\n");
00987         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "Child caught signal '%d' exiting\n", sig);
00988         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_child_sighandler() end\n");
00989 
00990         /* don't run into a race condition */
00991         //syslog(LOG_USER | LOG_INFO, "Caught SIG%s, cleaning up and exiting...\n", sigs[sig]);
00992 
00993         if(ido2db_run_foreground == IDO_TRUE){
00994                 /* cleanup the socket */
00995                 ido2db_cleanup_socket();
00996 
00997                 /* free memory */
00998                 ido2db_free_program_memory();
00999         }
01000 
01001         /* terminate threads */
01002         ido2db_terminate_threads();
01003 
01004         _exit(0);
01005 
01006         return;
01007         }
01008 
01009 
01010 /****************************************************************************/
01011 /* UTILITY FUNCTIONS                                                        */
01012 /****************************************************************************/
01013 
01014 
01015 int ido2db_wait_for_connections(void){
01016         int sd_flag=1;
01017         int new_sd=0;
01018         pid_t new_pid=-1;
01019         struct sockaddr_un server_address_u;
01020         struct sockaddr_in server_address_i;
01021         struct sockaddr_un client_address_u;
01022         struct sockaddr_in client_address_i;
01023         socklen_t client_address_length;
01024 
01025         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_wait_for_connections() start\n");
01026 
01027         /* TCP socket */
01028         if(ido2db_socket_type==IDO_SINK_TCPSOCKET){
01029 
01030                 /* create a socket */
01031                 if(!(ido2db_sd=socket(PF_INET,SOCK_STREAM,0))){
01032                         perror("Cannot create socket");
01033                         return IDO_ERROR;
01034                         }
01035 
01036                 /* set the reuse address flag so we don't get errors when restarting */
01037                 sd_flag=1;
01038                 if(setsockopt(ido2db_sd,SOL_SOCKET,SO_REUSEADDR,(char *)&sd_flag,sizeof(sd_flag))<0){
01039                         printf("Could not set reuse address option on socket!\n");
01040                         return IDO_ERROR;
01041                         }
01042 
01043                 /* clear the address */
01044                 bzero((char *)&server_address_i,sizeof(server_address_i));
01045                 server_address_i.sin_family=AF_INET;
01046                 server_address_i.sin_addr.s_addr=INADDR_ANY;
01047                 server_address_i.sin_port=htons(ido2db_tcp_port);
01048 
01049                 /* bind the socket */
01050                 if((bind(ido2db_sd,(struct sockaddr *)&server_address_i,sizeof(server_address_i)))){
01051                         close(ido2db_sd);
01052                         perror("Could not bind socket");
01053                         return IDO_ERROR;
01054                         }
01055 
01056                 client_address_length=(socklen_t)sizeof(client_address_i);
01057                 }
01058 
01059         /* UNIX domain socket */
01060         else{
01061 
01062                 /* create a socket */
01063                 if(!(ido2db_sd=socket(AF_UNIX,SOCK_STREAM,0))){
01064                         perror("Cannot create socket");
01065                         return IDO_ERROR;
01066                         }
01067 
01068                 /* copy the socket path */
01069                 strncpy(server_address_u.sun_path,ido2db_socket_name,sizeof(server_address_u.sun_path));
01070                 server_address_u.sun_family=AF_UNIX;
01071 
01072                 /* bind the socket */
01073                 if((bind(ido2db_sd,(struct sockaddr *)&server_address_u,SUN_LEN(&server_address_u)))){
01074                         close(ido2db_sd);
01075                         perror("Could not bind socket");
01076                         return IDO_ERROR;
01077                         }
01078 
01079                 client_address_length=(socklen_t)sizeof(client_address_u);
01080                 }
01081 
01082         /* listen for connections */
01083         if((listen(ido2db_sd,1))){
01084                 perror("Cannot listen on socket");
01085                 ido2db_cleanup_socket();
01086                 return IDO_ERROR;
01087                 }
01088 
01089 
01090         /* daemonize */
01091         if(ido2db_run_foreground == IDO_FALSE) {
01092                 if(ido2db_daemonize()!=IDO_OK)
01093                 return IDO_ERROR;
01094                 syslog(LOG_USER | LOG_INFO, "Finished daemonizing... (New PID=%d)\n",(int)getpid());
01095         }
01096 
01097         /* accept connections... */
01098         while(1){
01099 
01100                 while(1){
01101 
01102                         new_sd=accept(ido2db_sd,(ido2db_socket_type==IDO_SINK_TCPSOCKET)?(struct sockaddr *)&client_address_i:(struct sockaddr *)&client_address_u,(socklen_t *)&client_address_length);
01103 
01104 
01105                         /* ToDo:  Hendrik 08/12/2009
01106                          * If both ends think differently about SSL encryption, data from a idomod will
01107                          * be lost forever (likewise on database errors/misconfiguration)
01108                          * This seems a good place to output some information from which client
01109                          * a possible misconfiguration comes from.
01110                          * Logging the ip address together with the idomod instance name might be
01111                          * a great hint for further error hunting
01112                          */
01113 
01114                         if(new_sd>=0)
01115                                 /* data available */
01116                                 syslog(LOG_USER | LOG_INFO, "Client connected, data available.\n");
01117                                 break;
01118                         if(errno == EINTR) {
01119                                 /* continue */
01120                         }
01121                         else {
01122                                 perror("Accept error");
01123                                 ido2db_cleanup_socket();
01124                                 return IDO_ERROR;
01125                         }
01126                 }
01127 
01128                 if(ido2db_run_foreground == IDO_FALSE) {
01129                         /* fork... */
01130                         new_pid=fork();
01131 
01132                         switch(new_pid){
01133                         case -1:
01134                                 /* parent simply prints an error message and keeps on going... */
01135                                 perror("Fork error");
01136                                 close(new_sd);
01137                                 break;
01138 
01139                         case 0:
01140                                 /* child processes data... */
01141                                 ido2db_handle_client_connection(new_sd);
01142 
01143                                 /* close socket when we're done */
01144                                 close(new_sd);
01145                                 return IDO_OK;
01146                                 break;
01147 
01148                         default:
01149                                 /* parent keeps on going... */
01150                                 close(new_sd);
01151                                 break;
01152                         }
01153                 }
01154                 else{
01155                         /* child processes data... */
01156                         ido2db_handle_client_connection(new_sd);
01157 
01158                         /* close socket when we're done */
01159                         close(new_sd);
01160                 }
01161 
01162 #ifdef DEBUG_IDO2DB_EXIT_AFTER_CONNECTION
01163                 break;
01164 #endif
01165                 }
01166 
01167         /* cleanup after ourselves */
01168         ido2db_cleanup_socket();
01169 
01170         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_wait_for_connections() end\n");
01171 
01172         return IDO_OK;
01173         }
01174 
01175 
01176 int ido2db_handle_client_connection(int sd){
01177         int dbuf_chunk=2048;
01178         ido2db_idi idi;
01179         char buf[512];
01180         int result=0;
01181         int error=IDO_FALSE;
01182 
01183         int pthread_ret=0;
01184         sigset_t newmask;
01185         pthread_attr_t attr;
01186 
01187 #ifdef HAVE_SSL
01188         SSL *ssl=NULL;
01189 #endif
01190 
01191         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_connection() start\n");
01192 
01193         /* open syslog facility */
01194         /*openlog("ido2db",0,LOG_DAEMON);*/
01195 
01196         syslog(LOG_USER | LOG_INFO, "Handling client connection...\n");
01197         /* re-open debug log */
01198         ido2db_close_debug_log();
01199         ido2db_open_debug_log();
01200 
01201         /* reset signal handling */
01202         signal(SIGQUIT,ido2db_child_sighandler);
01203         signal(SIGTERM,ido2db_child_sighandler);
01204         signal(SIGINT,ido2db_child_sighandler);
01205         signal(SIGSEGV,ido2db_child_sighandler);
01206         signal(SIGFPE,ido2db_child_sighandler);
01207 
01208         /* new thread should block all signals */
01209         sigfillset(&newmask);
01210         pthread_sigmask(SIG_BLOCK,&newmask,NULL);
01211 
01212         /* set stack size */
01213         pthread_attr_init(&attr);
01214         if(pthread_attr_setstacksize(&attr, IDO2DB_DEFAULT_THREAD_STACK_SIZE)!=0)
01215                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_connection() pthread_attr_setstacksize with %lu error\n", IDO2DB_DEFAULT_THREAD_STACK_SIZE);
01216 
01217         /* create cleanup thread */
01218         if ((pthread_ret = pthread_create(&thread_pool[IDO2DB_THREAD_POOL_CLEANER], &attr, ido2db_thread_cleanup, &idi)) != 0) {
01219                 syslog(LOG_ERR,"Could not create thread... exiting with error '%s'\n", strerror(errno));
01220                 exit(EXIT_FAILURE);
01221         }
01222 
01223         /* create worker thread */
01224         if ((pthread_ret = pthread_create(&thread_pool[IDO2DB_THREAD_POOL_WORKER], &attr, ido2db_thread_worker, &idi)) != 0) {
01225                 syslog(LOG_ERR,"Could not create thread... exiting with error '%s'\n", strerror(errno));
01226                 exit(EXIT_FAILURE);
01227         }
01228 
01229 
01230         /* main thread should unblock all signals */
01231         pthread_sigmask(SIG_UNBLOCK,&newmask,NULL);
01232         pthread_attr_destroy(&attr);
01233 
01234         /* initialize input data information */
01235         ido2db_idi_init(&idi);
01236 
01237         /* initialize dynamic buffer (2KB chunk size) */
01238         ido_dbuf_init(&dbuf,dbuf_chunk);
01239 
01240         /* initialize database connection */
01241         ido2db_db_init(&idi);
01242 
01243         /* check if connection to database was successful */
01244         if(ido2db_db_connect(&idi)==IDO_ERROR) {
01245                 if(idi.dbinfo.connected!=IDO_TRUE) {
01246 
01247                         /* we did not get a db connection and the client should be disconnected */
01248                         syslog(LOG_USER | LOG_INFO,"Error: database connection failed, forced client disconnect...\n");
01249                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_connection() idi.dbinfo.connected is '%d'\n", idi.dbinfo.connected);
01250 
01251                         /* terminate threads */
01252                         terminate_worker_thread();
01253                         terminate_cleanup_thread();
01254 
01255                         /* free memory allocated to dynamic buffer */
01256                         ido_dbuf_free(&dbuf);
01257 
01258                         /* reset db credentials */
01259                         ido2db_db_deinit(&idi);
01260 
01261                         /* free memory */
01262                         ido2db_free_input_memory(&idi);
01263                         ido2db_free_connection_memory(&idi);
01264 
01265                         /* return error signalling that child is terminating */
01266                         return IDO_ERROR;
01267                 }
01268         }
01269 
01270 #ifdef HAVE_SSL
01271         if(use_ssl==IDO_TRUE){
01272                 if((ssl=SSL_new(ctx))!=NULL){
01273 
01274                         SSL_set_fd(ssl,sd);
01275 
01276                         /* keep attempting the request if needed */
01277                         while(((result=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,result)==SSL_ERROR_WANT_READ));
01278 
01279                         if(result!=1){
01280                                 syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,result));
01281 
01282                                 return IDO_ERROR;
01283                         }
01284                 }
01285         }
01286 #endif
01287 
01288         /* read all data from client */
01289         while(1){
01290 #ifdef HAVE_SSL
01291                 if(use_ssl==IDO_FALSE)
01292                         result=read(sd,buf,sizeof(buf)-1);
01293                 else{
01294                         result=SSL_read(ssl,buf,sizeof(buf)-1);
01295                         if(result==-1 && (SSL_get_error(ssl,result)==SSL_ERROR_WANT_READ)){
01296                                 syslog(LOG_ERR,"SSL read error\n");
01297                         }
01298                 }
01299 #else
01300                 result=read(sd,buf,sizeof(buf)-1);
01301 #endif
01302 
01303                 /* bail out on hard errors */
01304                 if(result==-1) {
01305                                 /* EAGAIN and EINTR are soft errors, so try another read() */
01306                                 if (errno==EAGAIN || errno==EINTR)
01307                                         continue;
01308                                 else {
01309                                         error=IDO_TRUE;
01310 #ifdef HAVE_SSL
01311                                 if(ssl){
01312                                         SSL_shutdown(ssl);
01313                                         SSL_free(ssl);
01314                                         syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n");
01315                                 }
01316 #endif
01317                                         break;
01318                                 }
01319                 }
01320 
01321                 /* zero bytes read means we lost the connection with the client */
01322                 if(result==0){
01323 #ifdef HAVE_SSL
01324                         if(ssl){
01325                                 SSL_shutdown(ssl);
01326                                 SSL_free(ssl);
01327                                 syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n");
01328                         }
01329 #endif
01330 
01331                         /* gracefully back out of current operation... */
01332                         ido2db_db_goodbye(&idi);
01333 
01334                         break;
01335                         }
01336 
01337 #ifdef DEBUG_IDO2DB2
01338                 printf("BYTESREAD: %d\n",result);
01339 #endif
01340 
01341                 /* append data we just read to dynamic buffer */
01342                 buf[result]='\x0';
01343                 /* 2011-02-23 MF: lock dynamic buffer with a mutex when writing */
01344                 pthread_mutex_lock(&ido2db_dbuf_lock);
01345                 ido_dbuf_strcat(&dbuf,buf);
01346                 pthread_mutex_unlock(&ido2db_dbuf_lock);
01347 
01348                 /* check for completed lines of input */
01349                 /* 2011-02-23 MF: only do that in a worker thread */
01350                 /* 2011-05-02 MF: redo it the old way */
01351 
01352                 ido2db_check_for_client_input(&idi);
01353 
01354 
01355                 /* should we disconnect the client? */
01356                 if(idi.disconnect_client==IDO_TRUE){
01357 
01358                         /* gracefully back out of current operation... */
01359                         ido2db_db_goodbye(&idi);
01360 
01361                         break;
01362                         }
01363                 }
01364 
01365 #ifdef DEBUG_IDO2DB2
01366         printf("BYTES: %lu, LINES: %lu\n",idi.bytes_processed,idi.lines_processed);
01367 #endif
01368 
01369         /* terminate threads */
01370         terminate_worker_thread();
01371         terminate_cleanup_thread();
01372 
01373         /* free memory allocated to dynamic buffer */
01374         ido_dbuf_free(&dbuf);
01375 
01376         /* disconnect from database */
01377         ido2db_db_disconnect(&idi);
01378         ido2db_db_deinit(&idi);
01379 
01380         /* free memory */
01381         ido2db_free_input_memory(&idi);
01382         ido2db_free_connection_memory(&idi);
01383 
01384         /* close syslog facility */
01385         /*closelog();*/
01386 
01387         if(error==IDO_TRUE)
01388                 return IDO_ERROR;
01389 
01390         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_connection() end\n");
01391 
01392         return IDO_OK;
01393         }
01394 
01395 
01396 /* initializes structure for tracking data */
01397 int ido2db_idi_init(ido2db_idi *idi){
01398         int x=0;
01399 
01400         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_idi_init() start\n");
01401 
01402         if(idi==NULL)
01403                 return IDO_ERROR;
01404 
01405         idi->disconnect_client=IDO_FALSE;
01406         idi->ignore_client_data=IDO_FALSE;
01407         idi->protocol_version=0;
01408         idi->instance_name=NULL;
01409         idi->buffered_input=NULL;
01410         idi->agent_name=NULL;
01411         idi->agent_version=NULL;
01412         idi->disposition=NULL;
01413         idi->connect_source=NULL;
01414         idi->connect_type=NULL;
01415         idi->current_input_section=IDO2DB_INPUT_SECTION_NONE;
01416         idi->current_input_data=IDO2DB_INPUT_DATA_NONE;
01417         idi->bytes_processed=0L;
01418         idi->lines_processed=0L;
01419         idi->entries_processed=0L;
01420         idi->current_object_config_type=IDO2DB_CONFIGTYPE_ORIGINAL;
01421         idi->data_start_time=0L;
01422         idi->data_end_time=0L;
01423 
01424         /* initialize mbuf */
01425         for(x=0;x<IDO2DB_MAX_MBUF_ITEMS;x++){
01426                 idi->mbuf[x].used_lines=0;
01427                 idi->mbuf[x].allocated_lines=0;
01428                 idi->mbuf[x].buffer=NULL;
01429                 }
01430 
01431         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_idi_init() end\n");
01432 
01433         return IDO_OK;
01434         }
01435 
01436 
01437 /* checks for single lines of input from a client connection */
01438 /* 2011-02-23 MF: called in worker thread */
01439 /* 2011-05-02 MF: restructured sequential */
01440 int ido2db_check_for_client_input(ido2db_idi *idi){
01441         char *buf=NULL;
01442         register int x;
01443 
01444         //ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_for_client_input() start\n");
01445 
01446 /*      if(&dbuf==NULL)
01447                 return IDO_OK;*/
01448         if(dbuf.buf==NULL)
01449                 return IDO_OK;
01450         /* check if buffer full? bail out and tell main to disconnect the client! FIXME */
01451         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_for_client_input() dbuf.size=%lu\n", dbuf.used_size);
01452 
01453         //pthread_mutex_lock(&ido2db_dbuf_lock);
01454 
01455         //ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_for_client_input() ido2db_dbuf_lock start\n");
01456 
01457 #ifdef DEBUG_IDO2DB2
01458         printf("RAWBUF: %s\n",dbuf.buf);
01459         printf("  USED1: %lu, BYTES: %lu, LINES: %lu\n",dbuf->used_size,idi->bytes_processed,idi->lines_processed);
01460 #endif
01461 
01462         /* search for complete lines of input */
01463         for(x=0;dbuf.buf[x]!='\x0';x++){
01464 
01465                 /* we found the end of a line */
01466                 if(dbuf.buf[x]=='\n'){
01467 
01468 #ifdef DEBUG_IDO2DB2
01469                         printf("BUF[%d]='\\n'\n",x);
01470 #endif
01471 
01472                         /* handle this line of input */
01473                         dbuf.buf[x]='\x0';
01474 
01475                         if((buf=strdup(dbuf.buf))){
01476 
01477                                 ido2db_handle_client_input(idi,buf);
01478 
01479                                 free(buf);
01480                                 buf=NULL;
01481                                 idi->lines_processed++;
01482                                 idi->bytes_processed+=(x+1);
01483                         }
01484 
01485                         /* shift data back to front of buffer and adjust counters */
01486                         memmove((void *)&dbuf.buf[0],(void *)&dbuf.buf[x+1],(size_t)((int)dbuf.used_size-x-1));
01487                         dbuf.used_size-=(x+1);
01488                         dbuf.buf[dbuf.used_size]='\x0';
01489                         x=-1;
01490 #ifdef DEBUG_IDO2DB2
01491                         printf("  USED2: %lu, BYTES: %lu, LINES: %lu\n",dbuf.used_size,idi->bytes_processed,idi->lines_processed);
01492 #endif
01493                 }
01494         }
01495 
01496         //pthread_mutex_unlock(&ido2db_dbuf_lock);
01497 
01498         //ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_for_client_input() ido2db_dbuf_lock end\n");
01499 
01500         //ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_check_for_client_input() end\n");
01501 
01502         return IDO_OK;
01503 }
01504 
01505 
01506 /* handles a single line of input from a client connection */
01507 int ido2db_handle_client_input(ido2db_idi *idi, char *buf){
01508         char *var=NULL;
01509         char *val=NULL;
01510         unsigned long data_type_long=0L;
01511         int data_type=IDO_DATA_NONE;
01512         int input_type=IDO2DB_INPUT_DATA_NONE;
01513 
01514         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_input(instance_name=%s) start\n", idi->instance_name);
01515 
01516 #ifdef DEBUG_IDO2DB2
01517         printf("HANDLING: '%s'\n",buf);
01518 #endif
01519 
01520         if(buf==NULL || idi==NULL)
01521                 return IDO_ERROR;
01522 
01523         /* we're ignoring client data because of wrong protocol version, etc...  */
01524         if(idi->ignore_client_data==IDO_TRUE)
01525                 return IDO_ERROR;
01526 
01527         /* skip empty lines */
01528         if(buf[0]=='\x0')
01529                 return IDO_OK;
01530 
01531         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_input() input_section\n");
01532 
01533         switch(idi->current_input_section){
01534 
01535         case IDO2DB_INPUT_SECTION_NONE:
01536 
01537                 var=strtok(buf,":");
01538                 val=strtok(NULL,"\n");
01539 
01540                 if(!strcmp(var,IDO_API_HELLO)){
01541 
01542                         idi->current_input_section=IDO2DB_INPUT_SECTION_HEADER;
01543                         idi->current_input_data=IDO2DB_INPUT_DATA_NONE;
01544 
01545                         /* free old connection memory (necessary in some cases) */
01546                         ido2db_free_connection_memory(idi);
01547                         }
01548 
01549                 break;
01550 
01551         case IDO2DB_INPUT_SECTION_HEADER:
01552 
01553                 var=strtok(buf,":");
01554                 val=strtok(NULL,"\n");
01555 
01556                 if(!strcmp(var,IDO_API_STARTDATADUMP)){
01557 
01558                         /* client is using wrong protocol version, bail out here... */
01559                         if(idi->protocol_version!=IDO_API_PROTOVERSION){
01560                                 syslog(LOG_USER|LOG_INFO,"Error: Client protocol version %d is incompatible with server version %d.  Disconnecting client...",idi->protocol_version,IDO_API_PROTOVERSION);
01561                                 idi->disconnect_client=IDO_TRUE;
01562                                 idi->ignore_client_data=IDO_TRUE;
01563                                 return IDO_ERROR;
01564                                 }
01565 
01566                         idi->current_input_section=IDO2DB_INPUT_SECTION_DATA;
01567 
01568                         /* save connection info to DB */
01569                         ido2db_db_hello(idi);
01570 
01571                         }
01572 
01573                 else if(!strcmp(var,IDO_API_PROTOCOL))
01574                         ido2db_convert_string_to_int((val+1),&idi->protocol_version);
01575 
01576                 else if(!strcmp(var,IDO_API_INSTANCENAME))
01577                         idi->instance_name=strdup(val+1);
01578 
01579                 else if(!strcmp(var,IDO_API_AGENT))
01580                         idi->agent_name=strdup(val+1);
01581 
01582                 else if(!strcmp(var,IDO_API_AGENTVERSION))
01583                         idi->agent_version=strdup(val+1);
01584 
01585                 else if(!strcmp(var,IDO_API_DISPOSITION))
01586                         idi->disposition=strdup(val+1);
01587 
01588                 else if(!strcmp(var,IDO_API_CONNECTION))
01589                         idi->connect_source=strdup(val+1);
01590 
01591                 else if(!strcmp(var,IDO_API_CONNECTTYPE))
01592                         idi->connect_type=strdup(val+1);
01593 
01594                 else if(!strcmp(var,IDO_API_STARTTIME))
01595                         ido2db_convert_string_to_unsignedlong((val+1),&idi->data_start_time);
01596 
01597                 break;
01598 
01599         case IDO2DB_INPUT_SECTION_FOOTER:
01600 
01601                 var=strtok(buf,":");
01602                 val=strtok(NULL,"\n");
01603 
01604                 /* client is saying goodbye... */
01605                 if(!strcmp(var,IDO_API_GOODBYE))
01606                         idi->current_input_section=IDO2DB_INPUT_SECTION_NONE;
01607 
01608                 else if(!strcmp(var,IDO_API_ENDTIME))
01609                         ido2db_convert_string_to_unsignedlong((val+1),&idi->data_end_time);
01610 
01611                 break;
01612 
01613         case IDO2DB_INPUT_SECTION_DATA:
01614 
01615                 if(idi->current_input_data==IDO2DB_INPUT_DATA_NONE){
01616 
01617                         var=strtok(buf,":");
01618                         val=strtok(NULL,"\n");
01619 
01620                         input_type=atoi(var);
01621 
01622                         switch(input_type){
01623 
01624                         /* we're reached the end of all of the data... */
01625                         case IDO_API_ENDDATADUMP:
01626                                 idi->current_input_section=IDO2DB_INPUT_SECTION_FOOTER;
01627                                 idi->current_input_data=IDO2DB_INPUT_DATA_NONE;
01628                                 break;
01629 
01630                         /* config dumps */
01631                         case IDO_API_STARTCONFIGDUMP:
01632                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONFIGDUMPSTART;
01633                                 break;
01634                         case IDO_API_ENDCONFIGDUMP:
01635                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONFIGDUMPEND;
01636                                 break;
01637 
01638                         /* archived data */
01639                         case IDO_API_LOGENTRY:
01640                                 idi->current_input_data=IDO2DB_INPUT_DATA_LOGENTRY;
01641                                 break;
01642 
01643                         /* realtime data */
01644                         case IDO_API_PROCESSDATA:
01645                                 idi->current_input_data=IDO2DB_INPUT_DATA_PROCESSDATA;
01646                                 break;
01647                         case IDO_API_TIMEDEVENTDATA:
01648                                 idi->current_input_data=IDO2DB_INPUT_DATA_TIMEDEVENTDATA;
01649                                 break;
01650                         case IDO_API_LOGDATA:
01651                                 idi->current_input_data=IDO2DB_INPUT_DATA_LOGDATA;
01652                                 break;
01653                         case IDO_API_SYSTEMCOMMANDDATA:
01654                                 idi->current_input_data=IDO2DB_INPUT_DATA_SYSTEMCOMMANDDATA;
01655                                 break;
01656                         case IDO_API_EVENTHANDLERDATA:
01657                                 idi->current_input_data=IDO2DB_INPUT_DATA_EVENTHANDLERDATA;
01658                                 break;
01659                         case IDO_API_NOTIFICATIONDATA:
01660                                 idi->current_input_data=IDO2DB_INPUT_DATA_NOTIFICATIONDATA;
01661                                 break;
01662                         case IDO_API_SERVICECHECKDATA:
01663                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICECHECKDATA;
01664                                 break;
01665                         case IDO_API_HOSTCHECKDATA:
01666                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTCHECKDATA;
01667                                 break;
01668                         case IDO_API_COMMENTDATA:
01669                                 idi->current_input_data=IDO2DB_INPUT_DATA_COMMENTDATA;
01670                                 break;
01671                         case IDO_API_DOWNTIMEDATA:
01672                                 idi->current_input_data=IDO2DB_INPUT_DATA_DOWNTIMEDATA;
01673                                 break;
01674                         case IDO_API_FLAPPINGDATA:
01675                                 idi->current_input_data=IDO2DB_INPUT_DATA_FLAPPINGDATA;
01676                                 break;
01677                         case IDO_API_PROGRAMSTATUSDATA:
01678                                 idi->current_input_data=IDO2DB_INPUT_DATA_PROGRAMSTATUSDATA;
01679                                 break;
01680                         case IDO_API_HOSTSTATUSDATA:
01681                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTSTATUSDATA;
01682                                 break;
01683                         case IDO_API_SERVICESTATUSDATA:
01684                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICESTATUSDATA;
01685                                 break;
01686                         case IDO_API_CONTACTSTATUSDATA:
01687                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONTACTSTATUSDATA;
01688                                 break;
01689                         case IDO_API_ADAPTIVEPROGRAMDATA:
01690                                 idi->current_input_data=IDO2DB_INPUT_DATA_ADAPTIVEPROGRAMDATA;
01691                                 break;
01692                         case IDO_API_ADAPTIVEHOSTDATA:
01693                                 idi->current_input_data=IDO2DB_INPUT_DATA_ADAPTIVEHOSTDATA;
01694                                 break;
01695                         case IDO_API_ADAPTIVESERVICEDATA:
01696                                 idi->current_input_data=IDO2DB_INPUT_DATA_ADAPTIVESERVICEDATA;
01697                                 break;
01698                         case IDO_API_ADAPTIVECONTACTDATA:
01699                                 idi->current_input_data=IDO2DB_INPUT_DATA_ADAPTIVECONTACTDATA;
01700                                 break;
01701                         case IDO_API_EXTERNALCOMMANDDATA:
01702                                 idi->current_input_data=IDO2DB_INPUT_DATA_EXTERNALCOMMANDDATA;
01703                                 break;
01704                         case IDO_API_AGGREGATEDSTATUSDATA:
01705                                 idi->current_input_data=IDO2DB_INPUT_DATA_AGGREGATEDSTATUSDATA;
01706                                 break;
01707                         case IDO_API_RETENTIONDATA:
01708                                 idi->current_input_data=IDO2DB_INPUT_DATA_RETENTIONDATA;
01709                                 break;
01710                         case IDO_API_CONTACTNOTIFICATIONDATA:
01711                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONTACTNOTIFICATIONDATA;
01712                                 break;
01713                         case IDO_API_CONTACTNOTIFICATIONMETHODDATA:
01714                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONTACTNOTIFICATIONMETHODDATA;
01715                                 break;
01716                         case IDO_API_ACKNOWLEDGEMENTDATA:
01717                                 idi->current_input_data=IDO2DB_INPUT_DATA_ACKNOWLEDGEMENTDATA;
01718                                 break;
01719                         case IDO_API_STATECHANGEDATA:
01720                                 idi->current_input_data=IDO2DB_INPUT_DATA_STATECHANGEDATA;
01721                                 break;
01722 
01723                         /* config variables */
01724                         case IDO_API_MAINCONFIGFILEVARIABLES:
01725                                 idi->current_input_data=IDO2DB_INPUT_DATA_MAINCONFIGFILEVARIABLES;
01726                                 break;
01727                         case IDO_API_RESOURCECONFIGFILEVARIABLES:
01728                                 idi->current_input_data=IDO2DB_INPUT_DATA_RESOURCECONFIGFILEVARIABLES;
01729                                 break;
01730                         case IDO_API_CONFIGVARIABLES:
01731                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONFIGVARIABLES;
01732                                 break;
01733                         case IDO_API_RUNTIMEVARIABLES:
01734                                 idi->current_input_data=IDO2DB_INPUT_DATA_RUNTIMEVARIABLES;
01735                                 break;
01736 
01737                         /* object configuration */
01738                         case IDO_API_HOSTDEFINITION:
01739                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTDEFINITION;
01740                                 break;
01741                         case IDO_API_HOSTGROUPDEFINITION:
01742                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTGROUPDEFINITION;
01743                                 break;
01744                         case IDO_API_SERVICEDEFINITION:
01745                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICEDEFINITION;
01746                                 break;
01747                         case IDO_API_SERVICEGROUPDEFINITION:
01748                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICEGROUPDEFINITION;
01749                                 break;
01750                         case IDO_API_HOSTDEPENDENCYDEFINITION:
01751                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTDEPENDENCYDEFINITION;
01752                                 break;
01753                         case IDO_API_SERVICEDEPENDENCYDEFINITION:
01754                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICEDEPENDENCYDEFINITION;
01755                                 break;
01756                         case IDO_API_HOSTESCALATIONDEFINITION:
01757                                 idi->current_input_data=IDO2DB_INPUT_DATA_HOSTESCALATIONDEFINITION;
01758                                 break;
01759                         case IDO_API_SERVICEESCALATIONDEFINITION:
01760                                 idi->current_input_data=IDO2DB_INPUT_DATA_SERVICEESCALATIONDEFINITION;
01761                                 break;
01762                         case IDO_API_COMMANDDEFINITION:
01763                                 idi->current_input_data=IDO2DB_INPUT_DATA_COMMANDDEFINITION;
01764                                 break;
01765                         case IDO_API_TIMEPERIODDEFINITION:
01766                                 idi->current_input_data=IDO2DB_INPUT_DATA_TIMEPERIODDEFINITION;
01767                                 break;
01768                         case IDO_API_CONTACTDEFINITION:
01769                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONTACTDEFINITION;
01770                                 break;
01771                         case IDO_API_CONTACTGROUPDEFINITION:
01772                                 idi->current_input_data=IDO2DB_INPUT_DATA_CONTACTGROUPDEFINITION;
01773                                 break;
01774                         case IDO_API_HOSTEXTINFODEFINITION:
01775                                 /* deprecated - merged with host definitions */
01776                         case IDO_API_SERVICEEXTINFODEFINITION:
01777                                 /* deprecated - merged with service definitions */
01778                         default:
01779                                 break;
01780                                 }
01781 
01782                         /* initialize input data */
01783                         ido2db_start_input_data(idi);
01784                         }
01785 
01786                 /* we are processing some type of data already... */
01787                 else{
01788 
01789                         var=strtok(buf,"=");
01790                         val=strtok(NULL,"\n");
01791 
01792                         /* get the data type */
01793                         data_type_long=strtoul(var,NULL,0);
01794 
01795                         /* there was an error with the data type - throw it out */
01796                         if(data_type_long==ULONG_MAX && errno==ERANGE)
01797                                 break;
01798 
01799                         data_type=(int)data_type_long;
01800 
01801                         /* the current data section is ending... */
01802                         if(data_type==IDO_API_ENDDATA){
01803 
01804                                 /* finish current data processing */
01805                                 ido2db_end_input_data(idi);
01806 
01807                                 idi->current_input_data=IDO2DB_INPUT_DATA_NONE;
01808                                 }
01809 
01810                         /* add data for already existing data type... */
01811                         else{
01812 
01813                                 /* the data type is out of range - throw it out */
01814                                 if(data_type>IDO_MAX_DATA_TYPES){
01815                                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_input() line: %lu, type: %d, VAL: %s\n",idi->lines_processed,data_type,val);
01816 #ifdef DEBUG_IDO2DB2
01817                                         printf("## DISCARD! LINE: %lu, TYPE: %d, VAL: %s\n",idi->lines_processed,data_type,val);
01818 #endif
01819                                         break;
01820                                         }
01821 
01822                                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_input() line: %lu, type: %d, VAL: %s\n",idi->lines_processed,data_type,val);
01823 #ifdef DEBUG_IDO2DB2
01824                                 printf("LINE: %lu, TYPE: %d, VAL:%s\n",idi->lines_processed,data_type,val);
01825 #endif
01826                                 ido2db_add_input_data_item(idi,data_type,val);
01827                                 }
01828                         }
01829 
01830                 break;
01831 
01832         default:
01833                 break;
01834                 }
01835 
01836         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_handle_client_input() end\n");
01837         return IDO_OK;
01838         }
01839 
01840 
01841 int ido2db_start_input_data(ido2db_idi *idi){
01842         int x;
01843 
01844         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_start_input_data() start\n");
01845 
01846         if(idi==NULL)
01847                 return IDO_ERROR;
01848 
01849         /* sometimes ido2db_end_input_data() isn't called, so free memory if we find it */
01850         ido2db_free_input_memory(idi);
01851 
01852         /* allocate memory for holding buffered input */
01853         if((idi->buffered_input=(char **)malloc(sizeof(char *)*IDO_MAX_DATA_TYPES))==NULL)
01854                 return IDO_ERROR;
01855 
01856         /* initialize buffered input slots */
01857         for(x=0;x<IDO_MAX_DATA_TYPES;x++)
01858                 idi->buffered_input[x]=NULL;
01859 
01860         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_start_input_data() end\n");
01861 
01862         return IDO_OK;
01863         }
01864 
01865 
01866 int ido2db_add_input_data_item(ido2db_idi *idi, int type, char *buf){
01867         char *newbuf=NULL;
01868         int mbuf_used=IDO_TRUE;
01869 
01870         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_add_input_data_item() start\n");
01871 
01872         if(idi==NULL)
01873                 return IDO_ERROR;
01874 
01875         /* escape data if necessary */
01876         switch(type){
01877 
01878         case IDO_DATA_ACKAUTHOR:
01879         case IDO_DATA_ACKDATA:
01880         case IDO_DATA_AUTHORNAME:
01881         case IDO_DATA_CHECKCOMMAND:
01882         case IDO_DATA_COMMANDARGS:
01883         case IDO_DATA_COMMANDLINE:
01884         case IDO_DATA_COMMANDSTRING:
01885         case IDO_DATA_COMMENT:
01886         case IDO_DATA_EVENTHANDLER:
01887         case IDO_DATA_GLOBALHOSTEVENTHANDLER:
01888         case IDO_DATA_GLOBALSERVICEEVENTHANDLER:
01889         case IDO_DATA_HOST:
01890         case IDO_DATA_LOGENTRY:
01891         case IDO_DATA_OUTPUT:
01892         case IDO_DATA_LONGOUTPUT:
01893         case IDO_DATA_PERFDATA:
01894         case IDO_DATA_SERVICE:
01895         case IDO_DATA_PROGRAMNAME:
01896         case IDO_DATA_PROGRAMVERSION:
01897         case IDO_DATA_PROGRAMDATE:
01898 
01899         case IDO_DATA_COMMANDNAME:
01900         case IDO_DATA_CONTACTADDRESS:
01901         case IDO_DATA_CONTACTALIAS:
01902         case IDO_DATA_CONTACTGROUP:
01903         case IDO_DATA_CONTACTGROUPALIAS:
01904         case IDO_DATA_CONTACTGROUPMEMBER:
01905         case IDO_DATA_CONTACTGROUPNAME:
01906         case IDO_DATA_CONTACTNAME:
01907         case IDO_DATA_DEPENDENTHOSTNAME:
01908         case IDO_DATA_DEPENDENTSERVICEDESCRIPTION:
01909         case IDO_DATA_DISPLAYNAME:
01910         case IDO_DATA_EMAILADDRESS:
01911         case IDO_DATA_HOSTADDRESS:
01912         case IDO_DATA_HOSTADDRESS6:
01913         case IDO_DATA_HOSTALIAS:
01914         case IDO_DATA_HOSTCHECKCOMMAND:
01915         case IDO_DATA_HOSTCHECKPERIOD:
01916         case IDO_DATA_HOSTEVENTHANDLER:
01917         case IDO_DATA_HOSTFAILUREPREDICTIONOPTIONS:
01918         case IDO_DATA_HOSTGROUPALIAS:
01919         case IDO_DATA_HOSTGROUPMEMBER:
01920         case IDO_DATA_HOSTGROUPNAME:
01921         case IDO_DATA_HOSTNAME:
01922         case IDO_DATA_HOSTNOTIFICATIONCOMMAND:
01923         case IDO_DATA_HOSTNOTIFICATIONPERIOD:
01924         case IDO_DATA_PAGERADDRESS:
01925         case IDO_DATA_PARENTHOST:
01926         case IDO_DATA_SERVICECHECKCOMMAND:
01927         case IDO_DATA_SERVICECHECKPERIOD:
01928         case IDO_DATA_SERVICEDESCRIPTION:
01929         case IDO_DATA_SERVICEEVENTHANDLER:
01930         case IDO_DATA_SERVICEFAILUREPREDICTIONOPTIONS:
01931         case IDO_DATA_SERVICEGROUPALIAS:
01932         case IDO_DATA_SERVICEGROUPMEMBER:
01933         case IDO_DATA_SERVICEGROUPNAME:
01934         case IDO_DATA_SERVICENOTIFICATIONCOMMAND:
01935         case IDO_DATA_SERVICENOTIFICATIONPERIOD:
01936         case IDO_DATA_TIMEPERIODALIAS:
01937         case IDO_DATA_TIMEPERIODNAME:
01938         case IDO_DATA_TIMERANGE:
01939 
01940         case IDO_DATA_ACTIONURL:
01941         case IDO_DATA_ICONIMAGE:
01942         case IDO_DATA_ICONIMAGEALT:
01943         case IDO_DATA_NOTES:
01944         case IDO_DATA_NOTESURL:
01945         case IDO_DATA_CUSTOMVARIABLE:
01946         case IDO_DATA_CONTACT:
01947 
01948                 /* strings are escaped when they arrive */
01949                 if(buf==NULL)
01950                         newbuf=strdup("");
01951                 else
01952                         newbuf=strdup(buf);
01953                 ido_unescape_buffer(newbuf);
01954                 break;
01955 
01956         default:
01957 
01958                 /* data hasn't been escaped */
01959                 if(buf==NULL)
01960                         newbuf=strdup("");
01961                 else
01962                         newbuf=strdup(buf);
01963                 break;
01964                 }
01965 
01966         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_add_input_data_item(%s)\n", newbuf);
01967 
01968         /* check for errors */
01969         if(newbuf==NULL){
01970                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_add_input_data_item() allocation error\n");
01971 #ifdef DEBUG_IDO2DB
01972                 printf("ALLOCATION ERROR\n");
01973 #endif
01974                 return IDO_ERROR;
01975                 }
01976 
01977         /* store the buffered data */
01978         switch(type){
01979 
01980         /* special case for data items that may appear multiple times */
01981         case IDO_DATA_CONTACTGROUP:
01982                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONTACTGROUP,newbuf);
01983                 break;
01984         case IDO_DATA_CONTACTGROUPMEMBER:
01985                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONTACTGROUPMEMBER,newbuf);
01986                 break;
01987         case IDO_DATA_SERVICEGROUPMEMBER:
01988                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_SERVICEGROUPMEMBER,newbuf);
01989                 break;
01990         case IDO_DATA_HOSTGROUPMEMBER:
01991                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_HOSTGROUPMEMBER,newbuf);
01992                 break;
01993         case IDO_DATA_SERVICENOTIFICATIONCOMMAND:
01994                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_SERVICENOTIFICATIONCOMMAND,newbuf);
01995                 break;
01996         case IDO_DATA_HOSTNOTIFICATIONCOMMAND:
01997                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_HOSTNOTIFICATIONCOMMAND,newbuf);
01998                 break;
01999         case IDO_DATA_CONTACTADDRESS:
02000                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONTACTADDRESS,newbuf);
02001                 break;
02002         case IDO_DATA_TIMERANGE:
02003                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_TIMERANGE,newbuf);
02004                 break;
02005         case IDO_DATA_PARENTHOST:
02006                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_PARENTHOST,newbuf);
02007                 break;
02008         case IDO_DATA_CONFIGFILEVARIABLE:
02009                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONFIGFILEVARIABLE,newbuf);
02010                 break;
02011         case IDO_DATA_CONFIGVARIABLE:
02012                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONFIGVARIABLE,newbuf);
02013                 break;
02014         case IDO_DATA_RUNTIMEVARIABLE:
02015                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_RUNTIMEVARIABLE,newbuf);
02016                 break;
02017         case IDO_DATA_CUSTOMVARIABLE:
02018                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CUSTOMVARIABLE,newbuf);
02019                 break;
02020         case IDO_DATA_CONTACT:
02021                 ido2db_add_input_data_mbuf(idi,type,IDO2DB_MBUF_CONTACT,newbuf);
02022                 break;
02023 
02024         /* NORMAL DATA */
02025         /* normal data items appear only once per data type */
02026         default:
02027 
02028                 mbuf_used=IDO_FALSE;
02029 
02030                 /* if there was already a matching item, discard the old one */
02031                 if(idi->buffered_input[type]!=NULL){
02032                         free(idi->buffered_input[type]);
02033                         idi->buffered_input[type]=NULL;
02034                         }
02035 
02036                 /* save buffered item */
02037                 idi->buffered_input[type]=newbuf;
02038                 }
02039 
02040         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_start_input_data() end\n");
02041         return IDO_OK;
02042         }
02043 
02044 
02045 
02046 int ido2db_add_input_data_mbuf(ido2db_idi *idi, int type, int mbuf_slot, char *buf){
02047         int allocation_chunk=80;
02048         char **newbuffer=NULL;
02049 
02050         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_add_input_data_mbuf() start\n");
02051 
02052         if(idi==NULL || buf==NULL)
02053                 return IDO_ERROR;
02054 
02055         if(mbuf_slot>=IDO2DB_MAX_MBUF_ITEMS)
02056                 return IDO_ERROR;
02057 
02058         /* create buffer */
02059         if(idi->mbuf[mbuf_slot].buffer==NULL){
02060 #ifdef IDO2DB_DEBUG_MBUF
02061                 mbuf_bytes_allocated+=sizeof(char *)*allocation_chunk;
02062                 printf("MBUF INITIAL ALLOCATION (MBUF = %lu bytes)\n",mbuf_bytes_allocated);
02063 #endif
02064                 idi->mbuf[mbuf_slot].buffer=(char **)malloc(sizeof(char *)*allocation_chunk);
02065                 idi->mbuf[mbuf_slot].allocated_lines+=allocation_chunk;
02066                 }
02067 
02068         /* expand buffer */
02069         if(idi->mbuf[mbuf_slot].used_lines==idi->mbuf[mbuf_slot].allocated_lines){
02070                 newbuffer=(char **)realloc(idi->mbuf[mbuf_slot].buffer,sizeof(char *)*(idi->mbuf[mbuf_slot].allocated_lines+allocation_chunk));
02071                 if(newbuffer==NULL)
02072                         return IDO_ERROR;
02073 #ifdef IDO2DB_DEBUG_MBUF
02074                 mbuf_bytes_allocated+=sizeof(char *)*allocation_chunk;
02075                 printf("MBUF RESIZED (MBUF = %lu bytes)\n",mbuf_bytes_allocated);
02076 #endif
02077                 idi->mbuf[mbuf_slot].buffer=newbuffer;
02078                 idi->mbuf[mbuf_slot].allocated_lines+=allocation_chunk;
02079                 }
02080 
02081         /* store the data */
02082         if(idi->mbuf[mbuf_slot].buffer){
02083                 idi->mbuf[mbuf_slot].buffer[idi->mbuf[mbuf_slot].used_lines]=buf;
02084                 idi->mbuf[mbuf_slot].used_lines++;
02085                 }
02086         else
02087                 return IDO_ERROR;
02088 
02089         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_add_input_data_mbuf() end\n");
02090         return IDO_OK;
02091         }
02092 
02093 
02094 
02095 int ido2db_end_input_data(ido2db_idi *idi){
02096         int result=IDO_OK;
02097 
02098         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_end_input_data() start\n");
02099 
02100         if(idi==NULL)
02101                 return IDO_ERROR;
02102 
02103         /* update db stats occassionally */
02104         if(ido2db_db_last_checkin_time<(time(NULL)-60))
02105                 ido2db_db_checkin(idi);
02106 
02107 #ifdef DEBUG_IDO2DB2
02108         printf("HANDLING TYPE: %d\n",idi->current_input_data);
02109 #endif
02110 
02111         switch(idi->current_input_data){
02112 
02113         /* archived log entries */
02114         case IDO2DB_INPUT_DATA_LOGENTRY:
02115                 result=ido2db_handle_logentry(idi);
02116                 break;
02117 
02118         /* realtime Icinga data */
02119         case IDO2DB_INPUT_DATA_PROCESSDATA:
02120                 result=ido2db_handle_processdata(idi);
02121                 break;
02122         case IDO2DB_INPUT_DATA_TIMEDEVENTDATA:
02123                 result=ido2db_handle_timedeventdata(idi);
02124                 break;
02125         case IDO2DB_INPUT_DATA_LOGDATA:
02126                 result=ido2db_handle_logdata(idi);
02127                 break;
02128         case IDO2DB_INPUT_DATA_SYSTEMCOMMANDDATA:
02129                 result=ido2db_handle_systemcommanddata(idi);
02130                 break;
02131         case IDO2DB_INPUT_DATA_EVENTHANDLERDATA:
02132                 result=ido2db_handle_eventhandlerdata(idi);
02133                 break;
02134         case IDO2DB_INPUT_DATA_NOTIFICATIONDATA:
02135                 result=ido2db_handle_notificationdata(idi);
02136                 break;
02137         case IDO2DB_INPUT_DATA_SERVICECHECKDATA:
02138                 result=ido2db_handle_servicecheckdata(idi);
02139                 break;
02140         case IDO2DB_INPUT_DATA_HOSTCHECKDATA:
02141                 result=ido2db_handle_hostcheckdata(idi);
02142                 break;
02143         case IDO2DB_INPUT_DATA_COMMENTDATA:
02144                 result=ido2db_handle_commentdata(idi);
02145                 break;
02146         case IDO2DB_INPUT_DATA_DOWNTIMEDATA:
02147                 result=ido2db_handle_downtimedata(idi);
02148                 break;
02149         case IDO2DB_INPUT_DATA_FLAPPINGDATA:
02150                 result=ido2db_handle_flappingdata(idi);
02151                 break;
02152         case IDO2DB_INPUT_DATA_PROGRAMSTATUSDATA:
02153                 result=ido2db_handle_programstatusdata(idi);
02154                 break;
02155         case IDO2DB_INPUT_DATA_HOSTSTATUSDATA:
02156                 result=ido2db_handle_hoststatusdata(idi);
02157                 break;
02158         case IDO2DB_INPUT_DATA_SERVICESTATUSDATA:
02159                 result=ido2db_handle_servicestatusdata(idi);
02160                 break;
02161         case IDO2DB_INPUT_DATA_CONTACTSTATUSDATA:
02162                 result=ido2db_handle_contactstatusdata(idi);
02163                 break;
02164         case IDO2DB_INPUT_DATA_ADAPTIVEPROGRAMDATA:
02165                 result=ido2db_handle_adaptiveprogramdata(idi);
02166                 break;
02167         case IDO2DB_INPUT_DATA_ADAPTIVEHOSTDATA:
02168                 result=ido2db_handle_adaptivehostdata(idi);
02169                 break;
02170         case IDO2DB_INPUT_DATA_ADAPTIVESERVICEDATA:
02171                 result=ido2db_handle_adaptiveservicedata(idi);
02172                 break;
02173         case IDO2DB_INPUT_DATA_ADAPTIVECONTACTDATA:
02174                 result=ido2db_handle_adaptivecontactdata(idi);
02175                 break;
02176         case IDO2DB_INPUT_DATA_EXTERNALCOMMANDDATA:
02177                 result=ido2db_handle_externalcommanddata(idi);
02178                 break;
02179         case IDO2DB_INPUT_DATA_AGGREGATEDSTATUSDATA:
02180                 result=ido2db_handle_aggregatedstatusdata(idi);
02181                 break;
02182         case IDO2DB_INPUT_DATA_RETENTIONDATA:
02183                 result=ido2db_handle_retentiondata(idi);
02184                 break;
02185         case IDO2DB_INPUT_DATA_CONTACTNOTIFICATIONDATA:
02186                 result=ido2db_handle_contactnotificationdata(idi);
02187                 break;
02188         case IDO2DB_INPUT_DATA_CONTACTNOTIFICATIONMETHODDATA:
02189                 result=ido2db_handle_contactnotificationmethoddata(idi);
02190                 break;
02191         case IDO2DB_INPUT_DATA_ACKNOWLEDGEMENTDATA:
02192                 result=ido2db_handle_acknowledgementdata(idi);
02193                 break;
02194         case IDO2DB_INPUT_DATA_STATECHANGEDATA:
02195                 result=ido2db_handle_statechangedata(idi);
02196                 break;
02197 
02198         /* config file and variable dumps */
02199         case IDO2DB_INPUT_DATA_MAINCONFIGFILEVARIABLES:
02200                 result=ido2db_handle_configfilevariables(idi,0);
02201                 break;
02202         case IDO2DB_INPUT_DATA_RESOURCECONFIGFILEVARIABLES:
02203                 result=ido2db_handle_configfilevariables(idi,1);
02204                 break;
02205         case IDO2DB_INPUT_DATA_CONFIGVARIABLES:
02206                 result=ido2db_handle_configvariables(idi);
02207                 break;
02208         case IDO2DB_INPUT_DATA_RUNTIMEVARIABLES:
02209                 result=ido2db_handle_runtimevariables(idi);
02210                 break;
02211         case IDO2DB_INPUT_DATA_CONFIGDUMPSTART:
02212                 result=ido2db_handle_configdumpstart(idi);
02213                 break;
02214         case IDO2DB_INPUT_DATA_CONFIGDUMPEND:
02215                 result=ido2db_handle_configdumpend(idi);
02216                 break;
02217 
02218         /* config definitions */
02219         case IDO2DB_INPUT_DATA_HOSTDEFINITION:
02220                 result=ido2db_handle_hostdefinition(idi);
02221                 break;
02222         case IDO2DB_INPUT_DATA_HOSTGROUPDEFINITION:
02223                 result=ido2db_handle_hostgroupdefinition(idi);
02224                 break;
02225         case IDO2DB_INPUT_DATA_SERVICEDEFINITION:
02226                 result=ido2db_handle_servicedefinition(idi);
02227                 break;
02228         case IDO2DB_INPUT_DATA_SERVICEGROUPDEFINITION:
02229                 result=ido2db_handle_servicegroupdefinition(idi);
02230                 break;
02231         case IDO2DB_INPUT_DATA_HOSTDEPENDENCYDEFINITION:
02232                 result=ido2db_handle_hostdependencydefinition(idi);
02233                 break;
02234         case IDO2DB_INPUT_DATA_SERVICEDEPENDENCYDEFINITION:
02235                 result=ido2db_handle_servicedependencydefinition(idi);
02236                 break;
02237         case IDO2DB_INPUT_DATA_HOSTESCALATIONDEFINITION:
02238                 result=ido2db_handle_hostescalationdefinition(idi);
02239                 break;
02240         case IDO2DB_INPUT_DATA_SERVICEESCALATIONDEFINITION:
02241                 result=ido2db_handle_serviceescalationdefinition(idi);
02242                 break;
02243         case IDO2DB_INPUT_DATA_COMMANDDEFINITION:
02244                 result=ido2db_handle_commanddefinition(idi);
02245                 break;
02246         case IDO2DB_INPUT_DATA_TIMEPERIODDEFINITION:
02247                 result=ido2db_handle_timeperiodefinition(idi);
02248                 break;
02249         case IDO2DB_INPUT_DATA_CONTACTDEFINITION:
02250                 result=ido2db_handle_contactdefinition(idi);
02251                 break;
02252         case IDO2DB_INPUT_DATA_CONTACTGROUPDEFINITION:
02253                 result=ido2db_handle_contactgroupdefinition(idi);
02254                 break;
02255         case IDO2DB_INPUT_DATA_HOSTEXTINFODEFINITION:
02256                 /* deprecated - merged with host definitions */
02257                 break;
02258         case IDO2DB_INPUT_DATA_SERVICEEXTINFODEFINITION:
02259                 /* deprecated - merged with service definitions */
02260                 break;
02261 
02262         default:
02263                 break;
02264                 }
02265 
02266         /* free input memory */
02267         ido2db_free_input_memory(idi);
02268 
02269         /* adjust items processed */
02270         idi->entries_processed++;
02271 
02272         /* perform periodic maintenance... */
02273         //ido2db_db_perform_maintenance(idi);
02274 
02275         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_end_input_data() end\n");
02276         return result;
02277         }
02278 
02279 
02280 /* free memory allocated to data input */
02281 int ido2db_free_input_memory(ido2db_idi *idi){
02282         register int x=0;
02283         register int y=0;
02284 
02285         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_input_memory() start\n");
02286 
02287         if(idi==NULL)
02288                 return IDO_ERROR;
02289 
02290         /* free memory allocated to single-instance data buffers */
02291         if(idi->buffered_input){
02292 
02293                 for(x=0;x<IDO_MAX_DATA_TYPES;x++){
02294                         if(idi->buffered_input[x])
02295                                 free(idi->buffered_input[x]);
02296                         idi->buffered_input[x]=NULL;
02297                         }
02298 
02299                 free(idi->buffered_input);
02300                 idi->buffered_input=NULL;
02301                 }
02302 
02303         /* free memory allocated to multi-instance data buffers */
02304         if(idi->mbuf){
02305                 for(x=0;x<IDO2DB_MAX_MBUF_ITEMS;x++){
02306                         if(idi->mbuf[x].buffer){
02307                                 for(y=0;y<idi->mbuf[x].used_lines;y++){
02308                                         if(idi->mbuf[x].buffer[y]){
02309                                                 free(idi->mbuf[x].buffer[y]);
02310                                                 idi->mbuf[x].buffer[y]=NULL;
02311                                                 }
02312                                         }
02313                                 free(idi->mbuf[x].buffer);
02314                                 idi->mbuf[x].buffer=NULL;
02315                                 }
02316                         idi->mbuf[x].used_lines=0;
02317                         idi->mbuf[x].allocated_lines=0;
02318                         }
02319                 }
02320 
02321         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_input_memory() end\n");
02322         return IDO_OK;
02323         }
02324 
02325 
02326 /* free memory allocated to connection */
02327 int ido2db_free_connection_memory(ido2db_idi *idi){
02328 
02329         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_connection_memory() start\n");
02330 
02331         if(idi->instance_name){
02332                 free(idi->instance_name);
02333                 idi->instance_name=NULL;
02334                 }
02335         if(idi->agent_name){
02336                 free(idi->agent_name);
02337                 idi->agent_name=NULL;
02338                 }
02339         if(idi->agent_version){
02340                 free(idi->agent_version);
02341                 idi->agent_version=NULL;
02342                 }
02343         if(idi->disposition){
02344                 free(idi->disposition);
02345                 idi->disposition=NULL;
02346                 }
02347         if(idi->connect_source){
02348                 free(idi->connect_source);
02349                 idi->connect_source=NULL;
02350                 }
02351         if(idi->connect_type){
02352                 free(idi->connect_type);
02353                 idi->connect_type=NULL;
02354                 }
02355 
02356         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_free_connection_memory() end\n");
02357         return IDO_OK;
02358         }
02359 
02360 
02361 
02362 /****************************************************************************/
02363 /* DATA TYPE CONVERTION ROUTINES                                            */
02364 /****************************************************************************/
02365 
02366 int ido2db_convert_standard_data_elements(ido2db_idi *idi, int *type, int *flags, int *attr, struct timeval *tstamp){
02367         int result1=IDO_OK;
02368         int result2=IDO_OK;
02369         int result3=IDO_OK;
02370         int result4=IDO_OK;
02371 
02372         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_standard_data_elements() start\n");
02373 
02374         result1=ido2db_convert_string_to_int(idi->buffered_input[IDO_DATA_TYPE],type);
02375         result2=ido2db_convert_string_to_int(idi->buffered_input[IDO_DATA_FLAGS],flags);
02376         result3=ido2db_convert_string_to_int(idi->buffered_input[IDO_DATA_ATTRIBUTES],attr);
02377         result4=ido2db_convert_string_to_timeval(idi->buffered_input[IDO_DATA_TIMESTAMP],tstamp);
02378 
02379         if(result1==IDO_ERROR || result2==IDO_ERROR || result3==IDO_ERROR || result4==IDO_ERROR)
02380                 return IDO_ERROR;
02381 
02382 
02383         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_standard_data_elements() end\n");
02384         return IDO_OK;
02385         }
02386 
02387 
02388 int ido2db_convert_string_to_int(char *buf, int *i){
02389 
02390         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_int(%s) start\n", buf);
02391 
02392         if(buf==NULL)
02393                 return IDO_ERROR;
02394 
02395         *i=atoi(buf);
02396 
02397         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_int(%d) end\n", i);
02398         return IDO_OK;
02399         }
02400 
02401 
02402 int ido2db_convert_string_to_float(char *buf, float *f){
02403         char *endptr=NULL;
02404 
02405         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_float(%s) start\n", buf);
02406 
02407         if(buf==NULL)
02408                 return IDO_ERROR;
02409 
02410 #ifdef HAVE_STRTOF
02411         *f=strtof(buf,&endptr);
02412 #else
02413         /* Solaris 8 doesn't have strtof() */
02414         *f=(float)strtod(buf,&endptr);
02415 #endif
02416 
02417         if(*f==0 && (endptr==buf || errno==ERANGE))
02418                 return IDO_ERROR;
02419         if(errno==ERANGE)
02420                 return IDO_ERROR;
02421 
02422         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_float(%f) end\n", f);
02423         return IDO_OK;
02424         }
02425 
02426 
02427 int ido2db_convert_string_to_double(char *buf, double *d){
02428         char *endptr=NULL;
02429 
02430         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_double(%s) start\n", buf);
02431         if(buf==NULL)
02432                 return IDO_ERROR;
02433 
02434         *d=strtod(buf,&endptr);
02435 
02436         if(*d==0 && (endptr==buf || errno==ERANGE))
02437                 return IDO_ERROR;
02438         if(errno==ERANGE)
02439                 return IDO_ERROR;
02440 
02441         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_double(%lf) end\n", d);
02442         return IDO_OK;
02443         }
02444 
02445 
02446 int ido2db_convert_string_to_long(char *buf, long *l){
02447         char *endptr=NULL;
02448 
02449         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_long(%s) start\n", buf);
02450 
02451         if(buf==NULL)
02452                 return IDO_ERROR;
02453 
02454         *l=strtol(buf,&endptr,0);
02455 
02456         if(*l==LONG_MAX && errno==ERANGE)
02457                 return IDO_ERROR;
02458         if(*l==0L && endptr==buf)
02459                 return IDO_ERROR;
02460 
02461         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_long(%l) end\n", l);
02462         return IDO_OK;
02463         }
02464 
02465 
02466 int ido2db_convert_string_to_unsignedlong(char *buf, unsigned long *ul){
02467         char *endptr=NULL;
02468 
02469         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_unsignedlong(%s) start\n", buf);
02470 
02471         if(buf==NULL)
02472                 return IDO_ERROR;
02473 
02474         *ul=strtoul(buf,&endptr,0);
02475         if(*ul==ULONG_MAX && errno==ERANGE)
02476                 return IDO_ERROR;
02477         if(*ul==0L && endptr==buf)
02478                 return IDO_ERROR;
02479 
02480         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_unsignedlong(%lu) end\n", ul);
02481         return IDO_OK;
02482 }
02483 
02484 
02485 int ido2db_convert_string_to_timeval(char *buf, struct timeval *tv){
02486         char *newbuf=NULL;
02487         char *ptr=NULL;
02488         int result=IDO_OK;
02489 
02490         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_timeval(%s) start\n", buf);
02491 
02492         if(buf==NULL)
02493                 return IDO_ERROR;
02494 
02495         tv->tv_sec=(time_t)0L;
02496         tv->tv_usec=(suseconds_t)0L;
02497 
02498         if((newbuf=strdup(buf))==NULL)
02499                 return IDO_ERROR;
02500 
02501         ptr=strtok(newbuf,".");
02502         if((result=ido2db_convert_string_to_unsignedlong(ptr,(unsigned long *)&tv->tv_sec))==IDO_OK){
02503                 ptr=strtok(NULL,"\n");
02504                 result=ido2db_convert_string_to_unsignedlong(ptr,(unsigned long *)&tv->tv_usec);
02505                 }
02506 
02507         free(newbuf);
02508 
02509         if(result==IDO_ERROR)
02510                 return IDO_ERROR;
02511 
02512         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_convert_string_to_timeval() end\n");
02513         return IDO_OK;
02514         }
02515 
02516 
02517 
02518 /****************************************************************************/
02519 /* LOGGING ROUTINES                                                         */
02520 /****************************************************************************/
02521 
02522 /* opens the debug log for writing */
02523 int ido2db_open_debug_log(void){
02524 
02525         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_open_debug_log() start\n");
02526 
02527         /* don't do anything if we're not debugging */
02528         if(ido2db_debug_level==IDO2DB_DEBUGL_NONE)
02529                 return IDO_OK;
02530 
02531         if((ido2db_debug_file_fp=fopen(ido2db_debug_file,"a+"))==NULL) {
02532                 syslog(LOG_ERR, "Warning: Could not open debug file '%s' - '%s'", ido2db_debug_file, strerror(errno));
02533                 return IDO_ERROR;
02534         }
02535 
02536         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_open_debug_log() end\n");
02537 
02538         return IDO_OK;
02539         }
02540 
02541 
02542 /* closes the debug log */
02543 int ido2db_close_debug_log(void){
02544 
02545         if(ido2db_debug_file_fp!=NULL)
02546                 fclose(ido2db_debug_file_fp);
02547 
02548         ido2db_debug_file_fp=NULL;
02549 
02550         return IDO_OK;
02551         }
02552 
02553 
02554 /* write to the debug log */
02555 int ido2db_log_debug_info(int level, int verbosity, const char *fmt, ...){
02556         va_list ap;
02557         char *temp_path=NULL;
02558         struct timeval current_time;
02559 
02560         if(!(ido2db_debug_level==IDO2DB_DEBUGL_ALL || (level & ido2db_debug_level)))
02561                 return IDO_OK;
02562 
02563         if(verbosity>ido2db_debug_verbosity)
02564                 return IDO_OK;
02565 
02566         if(ido2db_debug_file_fp==NULL)
02567                 return IDO_ERROR;
02568 
02569         /* write the timestamp */
02570         gettimeofday(&current_time,NULL);
02571         fprintf(ido2db_debug_file_fp,"[%lu.%06lu] [%03d.%d] [pid=%lu] ",current_time.tv_sec,current_time.tv_usec,level,verbosity,(unsigned long)getpid());
02572 
02573         /* write the data */
02574         va_start(ap,fmt);
02575         vfprintf(ido2db_debug_file_fp,fmt,ap);
02576         va_end(ap);
02577 
02578         /* flush, so we don't have problems tailing or when fork()ing */
02579         fflush(ido2db_debug_file_fp);
02580 
02581         /* if file has grown beyond max, rotate it */
02582         if((unsigned long)ftell(ido2db_debug_file_fp)>ido2db_max_debug_file_size && ido2db_max_debug_file_size>0L){
02583 
02584                 /* close the file */
02585                 ido2db_close_debug_log();
02586 
02587                 /* rotate the log file */
02588                 if(asprintf(&temp_path,"%s.old",ido2db_debug_file)==-1)
02589                         temp_path=NULL; 
02590 
02591                 if(temp_path){
02592 
02593                         /* unlink the old debug file */
02594                         unlink(temp_path);
02595 
02596                         /* rotate the debug file */
02597                         my_rename(ido2db_debug_file,temp_path);
02598 
02599                         /* free memory */
02600                         my_free(temp_path);
02601                         }
02602 
02603                 /* open a new file */
02604                 ido2db_open_debug_log();
02605                 }
02606 
02607         return IDO_OK;
02608         }
02609 
02610 
02611 /********************************************************************
02612  *
02613  * working on dbuf - this is the function for the buffer reading thread
02614  *
02615  ********************************************************************/
02616 
02617 void * ido2db_thread_worker(void *data) {
02618 
02619         ido2db_idi *idi = (ido2db_idi*) data;
02620 
02621         struct timespec delay;
02622         delay.tv_sec = 5;
02623         delay.tv_nsec = 500000;
02624         nanosleep(&delay, NULL);
02625         delay.tv_sec = 0;
02626 
02627         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_worker() start\n");
02628 
02629         /* specify cleanup routine */
02630         pthread_cleanup_push((void *) &ido2db_thread_worker_exit_handler, NULL);
02631 
02632         /* set cancellation info */
02633         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
02634         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
02635 
02636         while(1){
02637 
02638                 /* should we shutdown? */
02639                 pthread_testcancel();
02640 
02641                 /* sleep a bit */
02642                 nanosleep(&delay, NULL);
02643 
02644                 if(idi->disconnect_client==IDO_TRUE){
02645                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_worker(): origin idi said we should disconnect the client\n");
02646                         break;
02647                 }
02648 
02649                 /* check for client input */
02650                 //ido2db_check_for_client_input(idi);
02651 
02652                 /* sleep a bit */
02653                 nanosleep(&delay, NULL);
02654 
02655                 /* should we shutdown? */
02656                 pthread_testcancel();
02657         }
02658 
02659         pthread_cleanup_pop(0);
02660 
02661         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_worker() end\n");
02662 
02663         pthread_exit((void *) pthread_self());
02664 }
02665 
02666 /* ******************************************************************
02667  *
02668  * exit_handler_mem is called as thread canceling
02669  *
02670  * ******************************************************************/
02671 
02672 static void *ido2db_thread_worker_exit_handler(void * arg) {
02673         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_worker() cleanup_exit_handler...\n");
02674         return 0;
02675 
02676 }
02677 
02678 
02679 /********************************************************************
02680  *
02681  * housekeeping - this is the function for the db trimming thread
02682  *
02683  ********************************************************************/
02684 
02685 void * ido2db_thread_cleanup(void *data) {
02686 
02687         ido2db_idi *idi = (ido2db_idi*) data;
02688 
02689         struct timespec delay;
02690         delay.tv_sec = 0;
02691         delay.tv_nsec = 500;
02692 
02693         /* it might happen that db connection comes to fast after main thread so sleep a while */
02694         //delay.tv_sec = 60;
02695         /* allowed to be set in config */
02696         delay.tv_sec = ido2db_db_settings.housekeeping_thread_startup_delay;
02697 
02698         /* the minimum is the default, otherwise overwrite */
02699         if(delay.tv_sec<DEFAULT_HOUSEKEEPING_THREAD_STARTUP_DELAY)
02700                 delay.tv_sec=DEFAULT_HOUSEKEEPING_THREAD_STARTUP_DELAY;
02701 
02702         nanosleep(&delay, NULL);
02703 
02704         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() start\n");
02705 
02706         /* initialize input data information */
02707         ido2db_idi_init(&thread_idi);
02708 
02709         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() initialize thread db connection\n");
02710 
02711         /* initialize database connection */
02712         ido2db_db_init(&thread_idi);
02713 
02714         if(ido2db_db_connect(&thread_idi)==IDO_ERROR){
02715 
02716                 /* tell main process to disconnect */
02717                 idi->disconnect_client=IDO_TRUE;
02718 
02719                 /* cleanup the thread */
02720                 ido2db_db_deinit(&thread_idi);
02721 
02722                 /* free memory */
02723                 ido2db_free_input_memory(&thread_idi);
02724                 ido2db_free_connection_memory(&thread_idi);
02725 
02726                 return (void*)IDO_ERROR;
02727         }
02728 
02729         /* specify cleanup routine */
02730         pthread_cleanup_push((void *) &ido2db_thread_cleanup_exit_handler, NULL);
02731 
02732         delay.tv_sec = 0;
02733         delay.tv_nsec = 500;
02734 
02735         /* keep on looping for an instance name from main thread */
02736         while(idi->instance_name==NULL) {
02737                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() nanosleeping cause missing instance_name...\n");
02738                 nanosleep(&delay, NULL);
02739         }
02740 
02741 
02742         /* copy needed idi information */
02743         thread_idi.instance_name = idi->instance_name;
02744         thread_idi.agent_name = "IDO2DB Trimming Thread";
02745         thread_idi.agent_version = idi->agent_version;
02746         thread_idi.disposition = idi->disposition;
02747         thread_idi.connect_source = idi->connect_source;
02748         thread_idi.connect_type = idi->connect_type;
02749 
02750         delay.tv_sec = 5;
02751 
02752         /* save connection info to DB */
02753         while(ido2db_thread_db_hello(&thread_idi) == IDO_ERROR) {
02754                 ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() no instance found, sleeping...\n");
02755                 nanosleep(&delay, NULL);
02756         }
02757 
02758         while(1){
02759 
02760                 /* should we shutdown? */
02761                 pthread_testcancel();
02762 
02763                 if(idi->disconnect_client==IDO_TRUE){
02764                         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup(): origin idi said we should disconnect the client\n");
02765                         break;
02766                 }
02767 
02768                 /* Perfom DB Maintenance */
02769                 ido2db_db_perform_maintenance(&thread_idi);
02770 
02771                 /* should we shutdown? */
02772                 pthread_testcancel();
02773 
02774                 sleep(thread_idi.dbinfo.trim_db_interval+1);
02775         }
02776 
02777         /* gracefully back out of current operation... */
02778         ido2db_db_goodbye(&thread_idi);
02779 
02780         /* disconnect from database */
02781         ido2db_db_disconnect(&thread_idi);
02782         ido2db_db_deinit(&thread_idi);
02783 
02784         /* free memory */
02785         ido2db_free_input_memory(&thread_idi);
02786         ido2db_free_connection_memory(&thread_idi);
02787 
02788         pthread_cleanup_pop(0);
02789 
02790         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() end\n");
02791 
02792         pthread_exit((void *) pthread_self());
02793 }
02794 
02795 /* ******************************************************************
02796  *
02797  * exit_handler_mem is called as thread canceling
02798  *
02799  * ******************************************************************/
02800 
02801 static void *ido2db_thread_cleanup_exit_handler(void * arg) {
02802         ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "ido2db_thread_cleanup() cleanup_exit_handler...\n");
02803         return 0;
02804 
02805 }
02806 
02807 int ido2db_terminate_threads(void){
02808 
02809         int result;
02810 
02811         /* from cleaner thread */
02812         ido2db_db_disconnect(&thread_idi);
02813         ido2db_db_deinit(&thread_idi);
02814 
02815         /* terminate each thread on its own */
02816         result=terminate_worker_thread();
02817         result=terminate_cleanup_thread();
02818 
02819         return IDO_OK;
02820 }
02821 
02822 int terminate_worker_thread(void){
02823 
02824         int result;
02825 
02826         result=pthread_cancel(thread_pool[IDO2DB_THREAD_POOL_WORKER]);
02827         /* wait for the worker thread to exit */
02828         if(result==0){
02829                 result=pthread_join(thread_pool[IDO2DB_THREAD_POOL_WORKER],NULL);
02830         } /* else only clean memory */
02831 
02832         return IDO_OK;
02833 
02834 }
02835 
02836 int terminate_cleanup_thread(void){
02837 
02838         int result;
02839 
02840         result=pthread_cancel(thread_pool[IDO2DB_THREAD_POOL_CLEANER]);
02841         /* wait for the cleaner thread to exit */
02842         if(result==0){
02843                 result=pthread_join(thread_pool[IDO2DB_THREAD_POOL_CLEANER],NULL);
02844         } /* else only clean memory */
02845 
02846         return IDO_OK;
02847 
02848 }
02849 
02850 
02851 
 All Data Structures Files Functions Variables Typedefs Defines