Icinga-core 1.4.0
next gen monitoring
common/macros.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * MACROS.C - Common macro functions for Icinga
00004  *
00005  * Copyright (c) 1999-2009 Ethan Galstad (egalstad@nagios.org)
00006  * Copyright (c) 2009-2011 Nagios Core Development Team and Community Contributors
00007  * Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org)
00008  *
00009  * License:
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License version 2 as
00013  * published by the Free Software Foundation.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023  *
00024  *****************************************************************************/
00025 
00026 #include "../include/macros.h"
00027 #include "../include/config.h"
00028 #include "../include/common.h"
00029 #include "../include/objects.h"
00030 #include "../include/statusdata.h"
00031 #include "../include/comments.h"
00032 #ifdef NSCORE
00033 #include "../include/icinga.h"
00034 #else
00035 #include "../include/cgiutils.h"
00036 #endif
00037 
00038 #ifdef NSCORE
00039 extern int      use_large_installation_tweaks;
00040 extern int      enable_environment_macros;
00041 #endif
00042 
00043 int dummy;      /* reduce compiler warnings */
00044 
00045 extern char     *illegal_output_chars;
00046 
00047 extern contact          *contact_list;
00048 extern contactgroup     *contactgroup_list;
00049 extern host             *host_list;
00050 extern hostgroup        *hostgroup_list;
00051 extern service          *service_list;
00052 extern servicegroup     *servicegroup_list;
00053 extern command          *command_list;
00054 extern timeperiod       *timeperiod_list;
00055 
00056 char *macro_x_names[MACRO_X_COUNT]; /* the macro names */
00057 char *macro_user[MAX_USER_MACROS]; /* $USERx$ macros */
00058 
00068 char **macro_x = NULL;
00069 
00074 static icinga_macros global_macros;
00075 
00076 
00077 icinga_macros *get_global_macros(void){
00078         return &global_macros;
00079 }
00080 
00081 
00082 /******************************************************************/
00083 /************************ MACRO FUNCTIONS *************************/
00084 /******************************************************************/
00085 
00090 int process_macros_r(icinga_macros *mac, char *input_buffer, char **output_buffer, int options){
00091         char *temp_buffer=NULL;
00092         char *save_buffer=NULL;
00093         char *buf_ptr=NULL;
00094         char *delim_ptr=NULL;
00095         int in_macro=FALSE;
00096         int x=0;
00097         char *selected_macro=NULL;
00098         char *original_macro=NULL;
00099         char *cleaned_macro=NULL;
00100         int clean_macro=FALSE;
00101         int found_macro_x=FALSE;
00102         int result=OK;
00103         int clean_options=0;
00104         int free_macro=FALSE;
00105         int macro_options=0;
00106 
00107 
00108         log_debug_info(DEBUGL_FUNCTIONS,0,"process_macros_r()\n");
00109 
00110         if(output_buffer==NULL)
00111                 return ERROR;
00112 
00113         *output_buffer=(char *)strdup("");
00114 
00115         if(input_buffer==NULL)
00116                 return ERROR;
00117 
00118         in_macro=FALSE;
00119 
00120         log_debug_info(DEBUGL_MACROS,1,"**** BEGIN MACRO PROCESSING ***********\n");
00121         log_debug_info(DEBUGL_MACROS,1,"Processing: '%s'\n",input_buffer);
00122 
00123         /* save original input_buffer ptr for later free'ing */
00124         save_buffer=buf_ptr=(input_buffer?strdup(input_buffer):NULL);
00125 
00126         while(buf_ptr){
00127 
00128                 /* save pointer to this working part of buffer */
00129                 temp_buffer=buf_ptr;
00130 
00131                 /* find the next delimiter - terminate preceding string and advance buffer pointer for next run */
00132                 if((delim_ptr=strchr(buf_ptr,'$'))){
00133                            delim_ptr[0]='\x0';
00134                            buf_ptr=(char *)delim_ptr+1;
00135                            }
00136                 /* no delimiter found - we already have the last of the buffer */
00137                 else
00138                         buf_ptr=NULL;
00139 
00140                 log_debug_info(DEBUGL_MACROS,2,"  Processing part: '%s'\n",temp_buffer);
00141 
00142                 selected_macro=NULL;
00143                 found_macro_x=FALSE;
00144                 clean_macro=FALSE;
00145 
00146                 /* we're in plain text... */
00147                 if(in_macro==FALSE){
00148 
00149                         /* add the plain text to the end of the already processed buffer */
00150                         *output_buffer=(char *)realloc(*output_buffer,strlen(*output_buffer)+strlen(temp_buffer)+1);
00151                         strcat(*output_buffer,temp_buffer);
00152 
00153                         log_debug_info(DEBUGL_MACROS,2,"  Not currently in macro.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00154 
00155                         in_macro=TRUE;
00156                         }
00157 
00158                 /* looks like we're in a macro, so process it... */
00159                 else{
00160 
00161                         /* reset clean options */
00162                         clean_options=0;
00163 
00164                         /* grab the macro value */
00165                         result=grab_macro_value_r(mac, temp_buffer,&selected_macro,&clean_options,&free_macro);
00166                         log_debug_info(DEBUGL_MACROS,2,"  Processed '%s', Clean Options: %d, Free: %d\n",temp_buffer,clean_options,free_macro);
00167 
00168                         /* an error occurred - we couldn't parse the macro, so continue on */
00169                         if(result==ERROR){
00170                                 log_debug_info(DEBUGL_MACROS,0," WARNING: An error occurred processing macro '%s'!\n",temp_buffer);
00171                                 if(free_macro==TRUE)
00172                                         my_free(selected_macro);
00173                                 }
00174 
00175                         /* we already have a macro... */
00176                         if(result==OK)
00177                                 x=0;
00178 
00179                         /* an escaped $ is done by specifying two $$ next to each other */
00180                         else if(!strcmp(temp_buffer,"")){
00181 
00182                                 log_debug_info(DEBUGL_MACROS,2,"  Escaped $.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00183 
00184                                 *output_buffer=(char *)realloc(*output_buffer,strlen(*output_buffer)+2);
00185                                 strcat(*output_buffer,"$");
00186                                 }
00187 
00188                         /* a non-macro, just some user-defined string between two $s */
00189                         else{
00190 
00191                                 log_debug_info(DEBUGL_MACROS,2,"  Non-macro.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00192 
00193                                 /* add the plain text to the end of the already processed buffer */
00194                                 *output_buffer=(char *)realloc(*output_buffer,strlen(*output_buffer)+strlen(temp_buffer)+3);
00195                                 strcat(*output_buffer,"$");
00196                                 strcat(*output_buffer,temp_buffer);
00197                                 if (buf_ptr!=NULL)
00198                                         strcat(*output_buffer,"$");
00199                                 }
00200 
00201                         /* insert macro */
00202                         if(selected_macro!=NULL){
00203 
00204                                 log_debug_info(DEBUGL_MACROS,2,"  Processed '%s', Clean Options: %d, Free: %d\n",temp_buffer,clean_options,free_macro);
00205 
00206                                 /* include any cleaning options passed back to us */
00207                                 macro_options=(options | clean_options);
00208 
00209                                 log_debug_info(DEBUGL_MACROS,2,"  Cleaning options: global=%d, local=%d, effective=%d\n",options,clean_options,macro_options);
00210 
00211                                 /* URL encode the macro if requested - this allocates new memory */
00212                                 if(macro_options & URL_ENCODE_MACRO_CHARS){
00213                                         original_macro=selected_macro;
00214                                         selected_macro=get_url_encoded_string(selected_macro);
00215                                         if(free_macro==TRUE){
00216                                                 my_free(original_macro);
00217                                                 }
00218                                         free_macro=TRUE;
00219                                         }
00220 
00221                                 /* some macros are cleaned... */
00222                                 if(clean_macro==TRUE || ((macro_options & STRIP_ILLEGAL_MACRO_CHARS) || (macro_options & ESCAPE_MACRO_CHARS))){
00223 
00224                                         /* add the (cleaned) processed macro to the end of the already processed buffer */
00225                                         if(selected_macro!=NULL && (cleaned_macro=clean_macro_chars(selected_macro,macro_options))!=NULL){
00226                                                 *output_buffer=(char *)realloc(*output_buffer,strlen(*output_buffer)+strlen(cleaned_macro)+1);
00227                                                 strcat(*output_buffer,cleaned_macro);
00228 
00229                                                 log_debug_info(DEBUGL_MACROS,2,"  Cleaned macro.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00230                                                 }
00231                                         }
00232 
00233                                 /* others are not cleaned */
00234                                 else{
00235                                         /* add the processed macro to the end of the already processed buffer */
00236                                         if(selected_macro!=NULL){
00237                                                 *output_buffer=(char *)realloc(*output_buffer,strlen(*output_buffer)+strlen(selected_macro)+1);
00238                                                 strcat(*output_buffer,selected_macro);
00239 
00240                                                 log_debug_info(DEBUGL_MACROS,2,"  Uncleaned macro.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00241                                                 }
00242                                         }
00243 
00244                                 /* free memory if necessary (if we URL encoded the macro or we were told to do so by grab_macro_value()) */
00245                                 if(free_macro==TRUE)
00246                                         my_free(selected_macro);
00247 
00248                                 log_debug_info(DEBUGL_MACROS,2,"  Just finished macro.  Running output (%lu): '%s'\n",(unsigned long)strlen(*output_buffer),*output_buffer);
00249                                 }
00250 
00251                         in_macro=FALSE;
00252                         }
00253                 }
00254 
00255         log_debug_info(DEBUGL_MACROS,1,"  Done.  Final output: '%s'\n",*output_buffer);
00256         log_debug_info(DEBUGL_MACROS,1,"**** END MACRO PROCESSING *************\n");
00257 
00258         if (save_buffer)
00259                 free(save_buffer);
00260 
00261         return OK;
00262 }
00263 
00264 int process_macros(char *input_buffer, char **output_buffer, int options){
00265         return process_macros_r(&global_macros, input_buffer, output_buffer, options);
00266 }
00267 
00268 
00269 /******************************************************************/
00270 /********************** MACRO GRAB FUNCTIONS **********************/
00271 /******************************************************************/
00272 
00276 int grab_host_macros_r(icinga_macros *mac, host *hst){
00277 
00278         /* clear host-related macros */
00279         clear_host_macros_r(mac);
00280         clear_hostgroup_macros_r(mac);
00281 
00282         /* save pointer to host */
00283         mac->host_ptr=hst;
00284         mac->hostgroup_ptr=NULL;
00285 
00286         if(hst==NULL)
00287                 return ERROR;
00288 
00289 #ifdef NSCORE
00290         /* save pointer to host's first/primary hostgroup */
00291         if(hst->hostgroups_ptr)
00292                 mac->hostgroup_ptr=(hostgroup *)hst->hostgroups_ptr->object_ptr;
00293 #endif
00294 
00295         return OK;
00296 }
00297 
00298 int grab_host_macros(host *hst){
00299         return grab_host_macros_r(&global_macros, hst);
00300 }
00301 
00302 
00306 int grab_hostgroup_macros_r(icinga_macros *mac, hostgroup *hg){
00307 
00308         /* clear hostgroup macros */
00309         clear_hostgroup_macros_r(mac);
00310 
00311         /* save the hostgroup pointer for later */
00312         mac->hostgroup_ptr=hg;
00313 
00314         if(hg==NULL)
00315                 return ERROR;
00316 
00317         return OK;
00318 }
00319 
00320 int grab_hostgroup_macros(hostgroup *hg){
00321         return grab_hostgroup_macros_r(&global_macros, hg);
00322 }
00323 
00324 
00328 int grab_service_macros_r(icinga_macros *mac, service *svc){
00329 
00330         /* clear service-related macros */
00331         clear_service_macros_r(mac);
00332         clear_servicegroup_macros_r(mac);
00333 
00334         /* save pointer for later */
00335         mac->service_ptr=svc;
00336         mac->servicegroup_ptr=NULL;
00337 
00338         if(svc==NULL)
00339                 return ERROR;
00340 
00341 #ifdef NSCORE
00342         /* save first/primary servicegroup pointer for later */
00343         if(svc->servicegroups_ptr)
00344                 mac->servicegroup_ptr=(servicegroup *)svc->servicegroups_ptr->object_ptr;
00345 #endif
00346 
00347         return OK;
00348 }
00349 
00350 int grab_service_macros(service *svc){
00351         return grab_service_macros_r(&global_macros, svc);
00352 }
00353 
00354 
00355 
00359 int grab_servicegroup_macros_r(icinga_macros *mac, servicegroup *sg){
00360 
00361         /* clear servicegroup macros */
00362         clear_servicegroup_macros_r(mac);
00363 
00364         /* save the pointer for later */
00365         mac->servicegroup_ptr=sg;
00366 
00367         if(sg==NULL)
00368                 return ERROR;
00369 
00370         return OK;
00371 }
00372 
00373 int grab_servicegroup_macros(servicegroup *sg){
00374         return grab_servicegroup_macros_r(&global_macros, sg);
00375 }
00376 
00377 
00378 
00382 int grab_contact_macros_r(icinga_macros *mac, contact *cntct){
00383 
00384         /* clear contact-related macros */
00385         clear_contact_macros_r(mac);
00386         clear_contactgroup_macros_r(mac);
00387 
00388         /* save pointer to contact for later */
00389         mac->contact_ptr=cntct;
00390         mac->contactgroup_ptr=NULL;
00391 
00392         if(cntct==NULL)
00393                 return ERROR;
00394 
00395 #ifdef NSCORE
00396         /* save pointer to first/primary contactgroup for later */
00397         if(cntct->contactgroups_ptr)
00398                 mac->contactgroup_ptr=(contactgroup *)cntct->contactgroups_ptr->object_ptr;
00399 #endif
00400 
00401         return OK;
00402 }
00403 
00404 int grab_contact_macros(contact *cntct){
00405         return grab_contact_macros_r(&global_macros, cntct);
00406 }
00407 
00408 
00409 
00413 int grab_contactgroup_macros_r(icinga_macros *mac, contactgroup *cg){
00414 
00415         /* clear contactgroup macros */
00416         clear_contactgroup_macros_r(mac);
00417 
00418         /* save pointer to contactgroup for later */
00419         mac->contactgroup_ptr=cg;
00420 
00421         if(cg==NULL)
00422                 return ERROR;
00423 
00424         return OK;
00425 }
00426 
00427 int grab_contactgroup_macros(contactgroup *cg){
00428         return grab_contactgroup_macros_r(&global_macros, cg);
00429 }
00430 
00431 
00432 /******************************************************************/
00433 /******************* MACRO GENERATION FUNCTIONS *******************/
00434 /******************************************************************/
00435 
00439 int grab_macro_value_r(icinga_macros *mac, char *macro_buffer, char **output, int *clean_options, int *free_macro){
00440         char *buf=NULL;
00441         char *ptr=NULL;
00442         char *macro_name=NULL;
00443         char *arg[2]={NULL,NULL};
00444         contact *temp_contact=NULL;
00445         contactgroup *temp_contactgroup=NULL;
00446         contactsmember *temp_contactsmember=NULL;
00447         char *temp_buffer=NULL;
00448         int delimiter_len=0;
00449         register int x;
00450         int result=OK;
00451 
00452         if(output==NULL)
00453                 return ERROR;
00454 
00455         /* clear the old macro value */
00456         my_free(*output);
00457 
00458         if(macro_buffer==NULL || clean_options==NULL || free_macro==NULL)
00459                 return ERROR;
00460 
00461         /* work with a copy of the original buffer */
00462         if((buf=(char *)strdup(macro_buffer))==NULL)
00463                 return ERROR;
00464 
00465         /* BY DEFAULT, TELL CALLER TO FREE MACRO BUFFER WHEN DONE */
00466         *free_macro=TRUE;
00467 
00468         /* macro name is at start of buffer */
00469         macro_name=buf;
00470 
00471         /* see if there's an argument - if so, this is most likely an on-demand macro */
00472         if((ptr=strchr(buf,':'))){
00473 
00474                 ptr[0]='\x0';
00475                 ptr++;
00476 
00477                 /* save the first argument - host name, hostgroup name, etc. */
00478                 arg[0]=ptr;
00479 
00480                 /* try and find a second argument */
00481                 if((ptr=strchr(ptr,':'))){
00482 
00483                         ptr[0]='\x0';
00484                         ptr++;
00485 
00486                         /* save second argument - service description or delimiter */
00487                         arg[1]=ptr;
00488                         }
00489                 }
00490 
00491         /***** X MACROS *****/
00492         /* see if this is an x macro */
00493         for(x=0;x<MACRO_X_COUNT;x++){
00494 
00495                 if(macro_x_names[x]==NULL)
00496                         continue;
00497 
00498                 if(!strcmp(macro_name,macro_x_names[x])){
00499 
00500                         log_debug_info(DEBUGL_MACROS,2,"  macros[%d] (%s) match.\n",x,macro_x_names[x]);
00501 
00502                         /* get the macro value */
00503                         result=grab_macrox_value_r(mac, x,arg[0],arg[1],output,free_macro);
00504 
00505                         /* post-processing */
00506                         /* host/service output/perfdata and author/comment macros should get cleaned */
00507                         if((x>=16 && x<=19) ||(x>=49 && x<=52) || (x>=99 && x<=100) || (x>=124 && x<=127)){
00508                                 *clean_options|=(STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);
00509                                 log_debug_info(DEBUGL_MACROS,2,"  New clean options: %d\n",*clean_options);
00510                                 }
00511                         /* url macros should get cleaned */
00512                         if((x>=125 && x<=126) ||(x>=128 && x<=129) || (x>=77 && x<=78) || (x>=74 && x<=75)){
00513                                 *clean_options|=URL_ENCODE_MACRO_CHARS;
00514                                 log_debug_info(DEBUGL_MACROS,2,"  New clean options: %d\n",*clean_options);
00515                                 }
00516 
00517 
00518 
00519 
00520                         break;
00521                         }
00522                 }
00523 
00524         /* we already found the macro... */
00525         if(x<MACRO_X_COUNT)
00526                 x=x;
00527 
00528         /***** ARGV MACROS *****/
00529         else if(strstr(macro_name,"ARG")==macro_name){
00530 
00531                 /* which arg do we want? */
00532                 x=atoi(macro_name+3);
00533 
00534                 if(x<=0 || x>MAX_COMMAND_ARGUMENTS){
00535                         my_free(buf);
00536                         return ERROR;
00537                         }
00538 
00539                 /* use a pre-computed macro value */
00540                 *output=mac->argv[x-1];
00541                 *free_macro=FALSE;
00542                 }
00543 
00544         /***** USER MACROS *****/
00545         else if(strstr(macro_name,"USER")==macro_name){
00546 
00547                 /* which macro do we want? */
00548                 x=atoi(macro_name+4);
00549 
00550                 if(x<=0 || x>MAX_USER_MACROS){
00551                         my_free(buf);
00552                         return ERROR;
00553                         }
00554 
00555                 /* use a pre-computed macro value */
00556                 *output=macro_user[x-1];
00557                 *free_macro=FALSE;
00558                 }
00559 
00560         /***** CONTACT ADDRESS MACROS *****/
00561         /* NOTE: the code below should be broken out into a separate function */
00562         else if(strstr(macro_name,"CONTACTADDRESS")==macro_name){
00563 
00564                 /* which address do we want? */
00565                 x=atoi(macro_name+14)-1;
00566 
00567                 /* regular macro */
00568                 if(arg[0]==NULL){
00569 
00570                         /* use the saved pointer */
00571                         if((temp_contact=mac->contact_ptr)==NULL){
00572                                 my_free(buf);
00573                                 return ERROR;
00574                                 }
00575 
00576                         /* get the macro value */
00577                         result=grab_contact_address_macro_r(mac, x,temp_contact,output);
00578                         }
00579 
00580                 /* on-demand macro */
00581                 else{
00582 
00583                         /* on-demand contact macro with a contactgroup and a delimiter */
00584                         if(arg[1]!=NULL){
00585 
00586                                 if((temp_contactgroup=find_contactgroup(arg[0]))==NULL)
00587                                         return ERROR;
00588 
00589                                 delimiter_len=strlen(arg[1]);
00590 
00591                                 /* concatenate macro values for all contactgroup members */
00592                                 for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
00593 
00594 #ifdef NSCORE
00595                                         if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
00596                                                 continue;
00597                                         if((temp_contact=find_contact(temp_contactsmember->contact_name))==NULL)
00598                                                 continue;
00599 #endif
00600 
00601                                         /* get the macro value for this contact */
00602                                         grab_contact_address_macro_r(mac, x,temp_contact,&temp_buffer);
00603 
00604                                         if(temp_buffer==NULL)
00605                                                 continue;
00606 
00607                                         /* add macro value to already running macro */
00608                                         if(*output==NULL)
00609                                                 *output=(char *)strdup(temp_buffer);
00610                                         else{
00611                                                 if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
00612                                                         continue;
00613                                                 strcat(*output,arg[1]);
00614                                                 strcat(*output,temp_buffer);
00615                                                 }
00616                                         my_free(temp_buffer);
00617                                         }
00618                                 }
00619 
00620                         /* else on-demand contact macro */
00621                         else{
00622 
00623                                 /* find the contact */
00624                                 if((temp_contact=find_contact(arg[0]))==NULL){
00625                                         my_free(buf);
00626                                         return ERROR;
00627                                         }
00628 
00629                                 /* get the macro value */
00630                                 result=grab_contact_address_macro_r(mac, x,temp_contact,output);
00631                                 }
00632                         }
00633                 }
00634 
00635         /***** CUSTOM VARIABLE MACROS *****/
00636         else if(macro_name[0]=='_'){
00637 
00638                 /* get the macro value */
00639                 result=grab_custom_macro_value_r(mac, macro_name,arg[0],arg[1],output);
00640 
00641                 }
00642 
00643         /* no macro matched... */
00644         else{
00645                 log_debug_info(DEBUGL_MACROS,0," WARNING: Could not find a macro matching '%s'!\n",macro_name);
00646                 result=ERROR;
00647                 }
00648 
00649         /* free memory */
00650         my_free(buf);
00651 
00652         return result;
00653 }
00654 
00655 int grab_macro_value(char *macro_buffer, char **output, int *clean_options, int *free_macro){
00656         return grab_macro_value_r(&global_macros, macro_buffer, output, clean_options, free_macro);
00657 }
00658 
00659 
00663 int grab_macrox_value_r(icinga_macros *mac, int macro_type, char *arg1, char *arg2, char **output, int *free_macro){
00664         host *temp_host=NULL;
00665         hostgroup *temp_hostgroup=NULL;
00666         hostsmember *temp_hostsmember=NULL;
00667         service *temp_service=NULL;
00668         servicegroup *temp_servicegroup=NULL;
00669         servicesmember *temp_servicesmember=NULL;
00670         contact *temp_contact=NULL;
00671         contactgroup *temp_contactgroup=NULL;
00672         contactsmember *temp_contactsmember=NULL;
00673         char *temp_buffer=NULL;
00674         int result=OK;
00675         int delimiter_len=0;
00676         int free_sub_macro=FALSE;
00677 #ifdef NSCORE
00678         register int x;
00679         int authorized=TRUE;
00680         int problem=TRUE;
00681         int hosts_up=0;
00682         int hosts_down=0;
00683         int hosts_unreachable=0;
00684         int hosts_down_unhandled=0;
00685         int hosts_unreachable_unhandled=0;
00686         int host_problems=0;
00687         int host_problems_unhandled=0;
00688         int services_ok=0;
00689         int services_warning=0;
00690         int services_unknown=0;
00691         int services_critical=0;
00692         int services_warning_unhandled=0;
00693         int services_unknown_unhandled=0;
00694         int services_critical_unhandled=0;
00695         int service_problems=0;
00696         int service_problems_unhandled=0;
00697 #endif
00698 
00699 
00700         if(output==NULL || free_macro==NULL)
00701                 return ERROR;
00702 
00703         /* BY DEFAULT, TELL CALLER TO FREE MACRO BUFFER WHEN DONE */
00704         *free_macro=TRUE;
00705 
00706         /* handle the macro */
00707         switch(macro_type){
00708 
00709                 /***************/
00710                 /* HOST MACROS */
00711                 /***************/
00712         case MACRO_HOSTNAME:
00713         case MACRO_HOSTALIAS:
00714         case MACRO_HOSTADDRESS:
00715         case MACRO_HOSTADDRESS6:
00716         case MACRO_LASTHOSTCHECK:
00717         case MACRO_LASTHOSTSTATECHANGE:
00718         case MACRO_HOSTOUTPUT:
00719         case MACRO_HOSTPERFDATA:
00720         case MACRO_HOSTSTATE:
00721         case MACRO_HOSTSTATEID:
00722         case MACRO_HOSTATTEMPT:
00723         case MACRO_HOSTEXECUTIONTIME:
00724         case MACRO_HOSTLATENCY:
00725         case MACRO_HOSTDURATION:
00726         case MACRO_HOSTDURATIONSEC:
00727         case MACRO_HOSTDOWNTIME:
00728         case MACRO_HOSTSTATETYPE:
00729         case MACRO_HOSTPERCENTCHANGE:
00730         case MACRO_HOSTACKAUTHOR:
00731         case MACRO_HOSTACKCOMMENT:
00732         case MACRO_LASTHOSTUP:
00733         case MACRO_LASTHOSTDOWN:
00734         case MACRO_LASTHOSTUNREACHABLE:
00735         case MACRO_HOSTCHECKCOMMAND:
00736         case MACRO_HOSTDISPLAYNAME:
00737         case MACRO_HOSTACTIONURL:
00738         case MACRO_HOSTNOTESURL:
00739         case MACRO_HOSTNOTES:
00740         case MACRO_HOSTCHECKTYPE:
00741         case MACRO_LONGHOSTOUTPUT:
00742         case MACRO_HOSTNOTIFICATIONNUMBER:
00743         case MACRO_HOSTNOTIFICATIONID:
00744         case MACRO_HOSTEVENTID:
00745         case MACRO_LASTHOSTEVENTID:
00746         case MACRO_HOSTGROUPNAMES:
00747         case MACRO_HOSTACKAUTHORNAME:
00748         case MACRO_HOSTACKAUTHORALIAS:
00749         case MACRO_MAXHOSTATTEMPTS:
00750         case MACRO_TOTALHOSTSERVICES:
00751         case MACRO_TOTALHOSTSERVICESOK:
00752         case MACRO_TOTALHOSTSERVICESWARNING:
00753         case MACRO_TOTALHOSTSERVICESUNKNOWN:
00754         case MACRO_TOTALHOSTSERVICESCRITICAL:
00755         case MACRO_HOSTPROBLEMID:
00756         case MACRO_LASTHOSTPROBLEMID:
00757         case MACRO_LASTHOSTSTATE:
00758         case MACRO_LASTHOSTSTATEID:
00759 
00760                 /* a standard host macro */
00761                 if(arg2==NULL){
00762 
00763                         /* find the host for on-demand macros */
00764                         if(arg1){
00765                                 if((temp_host=find_host(arg1))==NULL)
00766                                         return ERROR;
00767                                 }
00768 
00769                         /* else use saved host pointer */
00770                         else if((temp_host=mac->host_ptr)==NULL)
00771                                 return ERROR;
00772 
00773                         /* get the host macro value */
00774                         result=grab_standard_host_macro_r(mac, macro_type,temp_host,output,free_macro);
00775                         }
00776 
00777                 /* a host macro with a hostgroup name and delimiter */
00778                 else{
00779 
00780                         if((temp_hostgroup=find_hostgroup(arg1))==NULL)
00781                                 return ERROR;
00782 
00783                         delimiter_len=strlen(arg2);
00784 
00785                         /* concatenate macro values for all hostgroup members */
00786                         for(temp_hostsmember=temp_hostgroup->members;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
00787 
00788 #ifdef NSCORE
00789                                 if((temp_host=temp_hostsmember->host_ptr)==NULL)
00790                                         continue;
00791 #else
00792                                 if((temp_host=find_host(temp_hostsmember->host_name))==NULL)
00793                                         continue;
00794 #endif
00795 
00796                                 /* get the macro value for this host */
00797                                 grab_standard_host_macro_r(mac, macro_type,temp_host,&temp_buffer,&free_sub_macro);
00798 
00799                                 if(temp_buffer==NULL)
00800                                         continue;
00801 
00802                                 /* add macro value to already running macro */
00803                                 if(*output==NULL)
00804                                         *output=(char *)strdup(temp_buffer);
00805                                 else{
00806                                         if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
00807                                                 continue;
00808                                         strcat(*output,arg2);
00809                                         strcat(*output,temp_buffer);
00810                                         }
00811                                 if(free_sub_macro==TRUE)
00812                                         my_free(temp_buffer);
00813                                 }
00814                         }
00815                 break;
00816 
00817                 /********************/
00818                 /* HOSTGROUP MACROS */
00819                 /********************/
00820         case MACRO_HOSTGROUPNAME:
00821         case MACRO_HOSTGROUPALIAS:
00822         case MACRO_HOSTGROUPNOTES:
00823         case MACRO_HOSTGROUPNOTESURL:
00824         case MACRO_HOSTGROUPACTIONURL:
00825         case MACRO_HOSTGROUPMEMBERS:
00826 
00827                 /* a standard hostgroup macro */
00828                 /* use the saved hostgroup pointer */
00829                 if(arg1==NULL){
00830                         if((temp_hostgroup=mac->hostgroup_ptr)==NULL)
00831                                 return ERROR;
00832                         }
00833 
00834                 /* else find the hostgroup for on-demand macros */
00835                 else{
00836                         if((temp_hostgroup=find_hostgroup(arg1))==NULL)
00837                                 return ERROR;
00838                         }
00839 
00840                 /* get the hostgroup macro value */
00841                 result=grab_standard_hostgroup_macro_r(mac, macro_type,temp_hostgroup,output);
00842                 break;
00843 
00844                 /******************/
00845                 /* SERVICE MACROS */
00846                 /******************/
00847         case MACRO_SERVICEDESC:
00848         case MACRO_SERVICESTATE:
00849         case MACRO_SERVICESTATEID:
00850         case MACRO_SERVICEATTEMPT:
00851         case MACRO_LASTSERVICECHECK:
00852         case MACRO_LASTSERVICESTATECHANGE:
00853         case MACRO_SERVICEOUTPUT:
00854         case MACRO_SERVICEPERFDATA:
00855         case MACRO_SERVICEEXECUTIONTIME:
00856         case MACRO_SERVICELATENCY:
00857         case MACRO_SERVICEDURATION:
00858         case MACRO_SERVICEDURATIONSEC:
00859         case MACRO_SERVICEDOWNTIME:
00860         case MACRO_SERVICESTATETYPE:
00861         case MACRO_SERVICEPERCENTCHANGE:
00862         case MACRO_SERVICEACKAUTHOR:
00863         case MACRO_SERVICEACKCOMMENT:
00864         case MACRO_LASTSERVICEOK:
00865         case MACRO_LASTSERVICEWARNING:
00866         case MACRO_LASTSERVICEUNKNOWN:
00867         case MACRO_LASTSERVICECRITICAL:
00868         case MACRO_SERVICECHECKCOMMAND:
00869         case MACRO_SERVICEDISPLAYNAME:
00870         case MACRO_SERVICEACTIONURL:
00871         case MACRO_SERVICENOTESURL:
00872         case MACRO_SERVICENOTES:
00873         case MACRO_SERVICECHECKTYPE:
00874         case MACRO_LONGSERVICEOUTPUT:
00875         case MACRO_SERVICENOTIFICATIONNUMBER:
00876         case MACRO_SERVICENOTIFICATIONID:
00877         case MACRO_SERVICEEVENTID:
00878         case MACRO_LASTSERVICEEVENTID:
00879         case MACRO_SERVICEGROUPNAMES:
00880         case MACRO_SERVICEACKAUTHORNAME:
00881         case MACRO_SERVICEACKAUTHORALIAS:
00882         case MACRO_MAXSERVICEATTEMPTS:
00883         case MACRO_SERVICEISVOLATILE:
00884         case MACRO_SERVICEPROBLEMID:
00885         case MACRO_LASTSERVICEPROBLEMID:
00886         case MACRO_LASTSERVICESTATE:
00887         case MACRO_LASTSERVICESTATEID:
00888 
00889                 /* use saved service pointer */
00890                 if(arg1==NULL && arg2==NULL){
00891 
00892                         if((temp_service=mac->service_ptr)==NULL)
00893                                 return ERROR;
00894 
00895                         result=grab_standard_service_macro_r(mac, macro_type,temp_service,output,free_macro);
00896                         }
00897 
00898                 /* else and ondemand macro... */
00899                 else{
00900 
00901                         /* if first arg is blank, it means use the current host name */
00902                         if(arg1==NULL || arg1[0]=='\x0'){
00903 
00904                                 if(mac->host_ptr==NULL)
00905                                         return ERROR;
00906 
00907                                 if((temp_service=find_service(mac->host_ptr->name,arg2))){
00908 
00909                                         /* get the service macro value */
00910                                         result=grab_standard_service_macro_r(mac, macro_type,temp_service,output,free_macro);
00911                                         }
00912                                 }
00913 
00914                         /* on-demand macro with both host and service name */
00915                         else if((temp_service=find_service(arg1,arg2))){
00916 
00917                                 /* get the service macro value */
00918                                 result=grab_standard_service_macro_r(mac, macro_type,temp_service,output,free_macro);
00919                                 }
00920 
00921                         /* else we have a service macro with a servicegroup name and a delimiter... */
00922                         else if(arg1 && arg2){
00923 
00924                                 if((temp_servicegroup=find_servicegroup(arg1))==NULL)
00925                                         return ERROR;
00926 
00927                                 delimiter_len=strlen(arg2);
00928 
00929                                 /* concatenate macro values for all servicegroup members */
00930                                 for(temp_servicesmember=temp_servicegroup->members;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
00931 
00932 #ifdef NSCORE
00933                                         if((temp_service=temp_servicesmember->service_ptr)==NULL)
00934                                                 continue;
00935 #else
00936                                         if((temp_service=find_service(temp_servicesmember->host_name,temp_servicesmember->service_description))==NULL)
00937                                                 continue;
00938 #endif
00939 
00940                                         /* get the macro value for this service */
00941                                         grab_standard_service_macro_r(mac, macro_type,temp_service,&temp_buffer,&free_sub_macro);
00942 
00943                                         if(temp_buffer==NULL)
00944                                                 continue;
00945 
00946                                         /* add macro value to already running macro */
00947                                         if(*output==NULL)
00948                                                 *output=(char *)strdup(temp_buffer);
00949                                         else{
00950                                                 if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
00951                                                         continue;
00952                                                 strcat(*output,arg2);
00953                                                 strcat(*output,temp_buffer);
00954                                                 }
00955                                         if(free_sub_macro==TRUE)
00956                                                 my_free(temp_buffer);
00957                                         }
00958                                 }
00959                         else
00960                                 return ERROR;
00961                         }
00962                 break;
00963 
00964                 /***********************/
00965                 /* SERVICEGROUP MACROS */
00966                 /***********************/
00967         case MACRO_SERVICEGROUPNAME:
00968         case MACRO_SERVICEGROUPALIAS:
00969         case MACRO_SERVICEGROUPNOTES:
00970         case MACRO_SERVICEGROUPNOTESURL:
00971         case MACRO_SERVICEGROUPACTIONURL:
00972         case MACRO_SERVICEGROUPMEMBERS:
00973                 /* a standard servicegroup macro */
00974                 /* use the saved servicegroup pointer */
00975                 if(arg1==NULL){
00976                         if((temp_servicegroup=mac->servicegroup_ptr)==NULL)
00977                                 return ERROR;
00978                         }
00979 
00980                 /* else find the servicegroup for on-demand macros */
00981                 else{
00982                         if((temp_servicegroup=find_servicegroup(arg1))==NULL)
00983                                 return ERROR;
00984                         }
00985 
00986                 /* get the servicegroup macro value */
00987                 result=grab_standard_servicegroup_macro_r(mac, macro_type,temp_servicegroup,output);
00988                 break;
00989 
00990                 /******************/
00991                 /* CONTACT MACROS */
00992                 /******************/
00993         case MACRO_CONTACTNAME:
00994         case MACRO_CONTACTALIAS:
00995         case MACRO_CONTACTEMAIL:
00996         case MACRO_CONTACTPAGER:
00997         case MACRO_CONTACTGROUPNAMES:
00998                 /* a standard contact macro */
00999                 if(arg2==NULL){
01000 
01001                         /* find the contact for on-demand macros */
01002                         if(arg1){
01003                                 if((temp_contact=find_contact(arg1))==NULL)
01004                                         return ERROR;
01005                                 }
01006 
01007                         /* else use saved contact pointer */
01008                         else if((temp_contact=mac->contact_ptr)==NULL)
01009                                 return ERROR;
01010 
01011                         /* get the contact macro value */
01012                         result=grab_standard_contact_macro_r(mac, macro_type,temp_contact,output);
01013                         }
01014 
01015                 /* a contact macro with a contactgroup name and delimiter */
01016                 else{
01017 
01018                         if((temp_contactgroup=find_contactgroup(arg1))==NULL)
01019                                 return ERROR;
01020 
01021                         delimiter_len=strlen(arg2);
01022 
01023                         /* concatenate macro values for all contactgroup members */
01024                         for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
01025 
01026 #ifdef NSCORE
01027                                 if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
01028                                         continue;
01029 #else
01030                                 if((temp_contact=find_contact(temp_contactsmember->contact_name))==NULL)
01031                                         continue;
01032 #endif
01033 
01034                                 /* get the macro value for this contact */
01035                                 grab_standard_contact_macro_r(mac, macro_type,temp_contact,&temp_buffer);
01036 
01037                                 if(temp_buffer==NULL)
01038                                         continue;
01039 
01040                                 /* add macro value to already running macro */
01041                                 if(*output==NULL)
01042                                         *output=(char *)strdup(temp_buffer);
01043                                 else{
01044                                         if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
01045                                                 continue;
01046                                         strcat(*output,arg2);
01047                                         strcat(*output,temp_buffer);
01048                                         }
01049                                 my_free(temp_buffer);
01050                                 }
01051                         }
01052                 break;
01053 
01054                 /***********************/
01055                 /* CONTACTGROUP MACROS */
01056                 /***********************/
01057         case MACRO_CONTACTGROUPNAME:
01058         case MACRO_CONTACTGROUPALIAS:
01059         case MACRO_CONTACTGROUPMEMBERS:
01060                 /* a standard contactgroup macro */
01061                 /* use the saved contactgroup pointer */
01062                 if(arg1==NULL){
01063                         if((temp_contactgroup=mac->contactgroup_ptr)==NULL)
01064                                 return ERROR;
01065                         }
01066 
01067                 /* else find the contactgroup for on-demand macros */
01068                 else{
01069                         if((temp_contactgroup=find_contactgroup(arg1))==NULL)
01070                                 return ERROR;
01071                         }
01072 
01073                 /* get the contactgroup macro value */
01074                 result=grab_standard_contactgroup_macro_r(mac, macro_type,temp_contactgroup,output);
01075                 break;
01076 
01077                 /***********************/
01078                 /* NOTIFICATION MACROS */
01079                 /***********************/
01080         case MACRO_NOTIFICATIONTYPE:
01081         case MACRO_NOTIFICATIONNUMBER:
01082         case MACRO_NOTIFICATIONRECIPIENTS:
01083         case MACRO_NOTIFICATIONISESCALATED:
01084         case MACRO_NOTIFICATIONAUTHOR:
01085         case MACRO_NOTIFICATIONAUTHORNAME:
01086         case MACRO_NOTIFICATIONAUTHORALIAS:
01087         case MACRO_NOTIFICATIONCOMMENT:
01088 
01089                 /* notification macros have already been pre-computed */
01090                 *output=mac->x[macro_type];
01091                 *free_macro=FALSE;
01092                 break;
01093 
01094                 /********************/
01095                 /* DATE/TIME MACROS */
01096                 /********************/
01097         case MACRO_LONGDATETIME:
01098         case MACRO_SHORTDATETIME:
01099         case MACRO_DATE:
01100         case MACRO_TIME:
01101         case MACRO_TIMET:
01102         case MACRO_ISVALIDTIME:
01103         case MACRO_NEXTVALIDTIME:
01104 
01105                 /* calculate macros */
01106                 result=grab_datetime_macro_r(mac, macro_type,arg1,arg2,output);
01107                 break;
01108 
01109                 /*****************/
01110                 /* STATIC MACROS */
01111                 /*****************/
01112         case MACRO_ADMINEMAIL:
01113         case MACRO_ADMINPAGER:
01114         case MACRO_MAINCONFIGFILE:
01115         case MACRO_STATUSDATAFILE:
01116         case MACRO_RETENTIONDATAFILE:
01117         case MACRO_OBJECTCACHEFILE:
01118         case MACRO_TEMPFILE:
01119         case MACRO_LOGFILE:
01120         case MACRO_RESOURCEFILE:
01121         case MACRO_COMMANDFILE:
01122         case MACRO_HOSTPERFDATAFILE:
01123         case MACRO_SERVICEPERFDATAFILE:
01124         case MACRO_PROCESSSTARTTIME:
01125         case MACRO_TEMPPATH:
01126         case MACRO_EVENTSTARTTIME:
01127 
01128                 /* no need to do any more work - these are already precomputed for us */
01129                 *output=global_macros.x[macro_type];
01130                 *free_macro=FALSE;
01131                 break;
01132 
01133                 /******************/
01134                 /* SUMMARY MACROS */
01135                 /******************/
01136         case MACRO_TOTALHOSTSUP:
01137         case MACRO_TOTALHOSTSDOWN:
01138         case MACRO_TOTALHOSTSUNREACHABLE:
01139         case MACRO_TOTALHOSTSDOWNUNHANDLED:
01140         case MACRO_TOTALHOSTSUNREACHABLEUNHANDLED:
01141         case MACRO_TOTALHOSTPROBLEMS:
01142         case MACRO_TOTALHOSTPROBLEMSUNHANDLED:
01143         case MACRO_TOTALSERVICESOK:
01144         case MACRO_TOTALSERVICESWARNING:
01145         case MACRO_TOTALSERVICESCRITICAL:
01146         case MACRO_TOTALSERVICESUNKNOWN:
01147         case MACRO_TOTALSERVICESWARNINGUNHANDLED:
01148         case MACRO_TOTALSERVICESCRITICALUNHANDLED:
01149         case MACRO_TOTALSERVICESUNKNOWNUNHANDLED:
01150         case MACRO_TOTALSERVICEPROBLEMS:
01151         case MACRO_TOTALSERVICEPROBLEMSUNHANDLED:
01152 
01153 #ifdef NSCORE
01154                 /* generate summary macros if needed */
01155                 if(mac->x[MACRO_TOTALHOSTSUP]==NULL){
01156 
01157                         /* get host totals */
01158                         for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
01159 
01160                                 /* filter totals based on contact if necessary */
01161                                 if(mac->contact_ptr!=NULL)
01162                                         authorized=is_contact_for_host(temp_host,mac->contact_ptr);
01163 
01164                                 if(authorized==TRUE){
01165                                         problem=TRUE;
01166 
01167                                         if(temp_host->current_state==HOST_UP && temp_host->has_been_checked==TRUE)
01168                                                 hosts_up++;
01169                                         else if(temp_host->current_state==HOST_DOWN){
01170                                                 if(temp_host->scheduled_downtime_depth>0)
01171                                                         problem=FALSE;
01172                                                 if(temp_host->problem_has_been_acknowledged==TRUE)
01173                                                         problem=FALSE;
01174                                                 if(temp_host->checks_enabled==FALSE)
01175                                                         problem=FALSE;
01176                                                 if(problem==TRUE)
01177                                                         hosts_down_unhandled++;
01178                                                 hosts_down++;
01179                                                 }
01180                                         else if(temp_host->current_state==HOST_UNREACHABLE){
01181                                                 if(temp_host->scheduled_downtime_depth>0)
01182                                                         problem=FALSE;
01183                                                 if(temp_host->problem_has_been_acknowledged==TRUE)
01184                                                         problem=FALSE;
01185                                                 if(temp_host->checks_enabled==FALSE)
01186                                                         problem=FALSE;
01187                                                 if(problem==TRUE)
01188                                                         hosts_down_unhandled++;
01189                                                 hosts_unreachable++;
01190                                                 }
01191                                         }
01192                                 }
01193 
01194                         host_problems=hosts_down+hosts_unreachable;
01195                         host_problems_unhandled=hosts_down_unhandled+hosts_unreachable_unhandled;
01196 
01197                         /* get service totals */
01198                         for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
01199 
01200                                 /* filter totals based on contact if necessary */
01201                                 if(mac->contact_ptr!=NULL)
01202                                         authorized=is_contact_for_service(temp_service,mac->contact_ptr);
01203 
01204                                 if(authorized==TRUE){
01205                                         problem=TRUE;
01206 
01207                                         if(temp_service->current_state==STATE_OK && temp_service->has_been_checked==TRUE)
01208                                                 services_ok++;
01209                                         else if(temp_service->current_state==STATE_WARNING){
01210                                                 temp_host=find_host(temp_service->host_name);
01211                                                 if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE))
01212                                                         problem=FALSE;
01213                                                 if(temp_service->scheduled_downtime_depth>0)
01214                                                         problem=FALSE;
01215                                                 if(temp_service->problem_has_been_acknowledged==TRUE)
01216                                                         problem=FALSE;
01217                                                 if(temp_service->checks_enabled==FALSE)
01218                                                         problem=FALSE;
01219                                                 if(problem==TRUE)
01220                                                         services_warning_unhandled++;
01221                                                 services_warning++;
01222                                                 }
01223                                         else if(temp_service->current_state==STATE_UNKNOWN){
01224                                                 temp_host=find_host(temp_service->host_name);
01225                                                 if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE))
01226                                                         problem=FALSE;
01227                                                 if(temp_service->scheduled_downtime_depth>0)
01228                                                         problem=FALSE;
01229                                                 if(temp_service->problem_has_been_acknowledged==TRUE)
01230                                                         problem=FALSE;
01231                                                 if(temp_service->checks_enabled==FALSE)
01232                                                         problem=FALSE;
01233                                                 if(problem==TRUE)
01234                                                         services_unknown_unhandled++;
01235                                                 services_unknown++;
01236                                                 }
01237                                         else if(temp_service->current_state==STATE_CRITICAL){
01238                                                 temp_host=find_host(temp_service->host_name);
01239                                                 if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE))
01240                                                         problem=FALSE;
01241                                                 if(temp_service->scheduled_downtime_depth>0)
01242                                                         problem=FALSE;
01243                                                 if(temp_service->problem_has_been_acknowledged==TRUE)
01244                                                         problem=FALSE;
01245                                                 if(temp_service->checks_enabled==FALSE)
01246                                                         problem=FALSE;
01247                                                 if(problem==TRUE)
01248                                                         services_critical_unhandled++;
01249                                                 services_critical++;
01250                                                 }
01251                                         }
01252                                 }
01253 
01254                         service_problems=services_warning+services_critical+services_unknown;
01255                         service_problems_unhandled=services_warning_unhandled+services_critical_unhandled+services_unknown_unhandled;
01256 
01257                         /* these macros are time-intensive to compute, and will likely be used together, so save them all for future use */
01258                         for(x=MACRO_TOTALHOSTSUP;x<=MACRO_TOTALSERVICEPROBLEMSUNHANDLED;x++)
01259                                 my_free(mac->x[x]);
01260                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSUP],"%d",hosts_up);
01261                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSDOWN],"%d",hosts_down);
01262                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSUNREACHABLE],"%d",hosts_unreachable);
01263                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSDOWNUNHANDLED],"%d",hosts_down_unhandled);
01264                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED],"%d",hosts_unreachable_unhandled);
01265                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTPROBLEMS],"%d",host_problems);
01266                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTPROBLEMSUNHANDLED],"%d",host_problems_unhandled);
01267                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESOK],"%d",services_ok);
01268                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESWARNING],"%d",services_warning);
01269                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESCRITICAL],"%d",services_critical);
01270                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESUNKNOWN],"%d",services_unknown);
01271                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESWARNINGUNHANDLED],"%d",services_warning_unhandled);
01272                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESCRITICALUNHANDLED],"%d",services_critical_unhandled);
01273                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED],"%d",services_unknown_unhandled);
01274                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICEPROBLEMS],"%d",service_problems);
01275                         dummy=asprintf(&mac->x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED],"%d",service_problems_unhandled);
01276                         }
01277 
01278                 /* return only the macro the user requested */
01279                 *output=mac->x[macro_type];
01280 
01281                 /* tell caller to NOT free memory when done */
01282                 *free_macro=FALSE;
01283 #endif
01284                 break;
01285 
01286         default:
01287                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED MACRO #%d! THIS IS A BUG!\n",macro_type);
01288                 return ERROR;
01289                 }
01290 
01291         return result;
01292 }
01293 
01294 int grab_macrox_value(int macro_type, char *arg1, char *arg2, char **output, int *free_macro){
01295         return grab_macrox_value_r(&global_macros, macro_type, arg1, arg2, output, free_macro);
01296 }
01297 
01298 
01299 
01303 int grab_custom_macro_value_r(icinga_macros *mac, char *macro_name, char *arg1, char *arg2, char **output){
01304         host *temp_host=NULL;
01305         hostgroup *temp_hostgroup=NULL;
01306         hostsmember *temp_hostsmember=NULL;
01307         service *temp_service=NULL;
01308         servicegroup *temp_servicegroup=NULL;
01309         servicesmember *temp_servicesmember=NULL;
01310         contact *temp_contact=NULL;
01311         contactgroup *temp_contactgroup=NULL;
01312         contactsmember *temp_contactsmember=NULL;
01313         int delimiter_len=0;
01314         char *temp_buffer=NULL;
01315         int result=OK;
01316 
01317         if(macro_name==NULL || output==NULL)
01318                 return ERROR;
01319 
01320         /***** CUSTOM HOST MACRO *****/
01321         if(strstr(macro_name,"_HOST")==macro_name){
01322 
01323                 /* a standard host macro */
01324                 if(arg2==NULL){
01325 
01326                         /* find the host for on-demand macros */
01327                         if(arg1){
01328                                 if((temp_host=find_host(arg1))==NULL)
01329                                         return ERROR;
01330                                 }
01331 
01332                         /* else use saved host pointer */
01333                         else if((temp_host=mac->host_ptr)==NULL)
01334                                 return ERROR;
01335 
01336                         /* get the host macro value */
01337                         result=grab_custom_object_macro_r(mac, macro_name+5,temp_host->custom_variables,output);
01338                         }
01339 
01340                 /* a host macro with a hostgroup name and delimiter */
01341                 else{
01342                         if((temp_hostgroup=find_hostgroup(arg1))==NULL)
01343                                 return ERROR;
01344 
01345                         delimiter_len=strlen(arg2);
01346 
01347                         /* concatenate macro values for all hostgroup members */
01348                         for(temp_hostsmember=temp_hostgroup->members;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
01349 
01350 #ifdef NSCORE
01351                                 if((temp_host=temp_hostsmember->host_ptr)==NULL)
01352                                         continue;
01353 #else
01354                                 if((temp_host=find_host(temp_hostsmember->host_name))==NULL)
01355                                         continue;
01356 #endif
01357 
01358                                 /* get the macro value for this host */
01359                                 grab_custom_macro_value_r(mac, macro_name,temp_host->name,NULL,&temp_buffer);
01360 
01361                                 if(temp_buffer==NULL)
01362                                         continue;
01363 
01364                                 /* add macro value to already running macro */
01365                                 if(*output==NULL)
01366                                         *output=(char *)strdup(temp_buffer);
01367                                 else{
01368                                         if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
01369                                                 continue;
01370                                         strcat(*output,arg2);
01371                                         strcat(*output,temp_buffer);
01372                                         }
01373                                 my_free(temp_buffer);
01374                                 }
01375                         }
01376                 }
01377 
01378         /***** CUSTOM SERVICE MACRO *****/
01379         else if(strstr(macro_name,"_SERVICE")==macro_name){
01380 
01381                 /* use saved service pointer */
01382                 if(arg1==NULL && arg2==NULL){
01383 
01384                         if((temp_service=mac->service_ptr)==NULL)
01385                                 return ERROR;
01386 
01387                         /* get the service macro value */
01388                         result=grab_custom_object_macro_r(mac, macro_name+8,temp_service->custom_variables,output);
01389                         }
01390 
01391                 /* else and ondemand macro... */
01392                 else{
01393 
01394                         /* if first arg is blank, it means use the current host name */
01395                         if(mac->host_ptr==NULL)
01396                                 return ERROR;
01397                         if((temp_service=find_service((mac->host_ptr)?mac->host_ptr->name:NULL,arg2))){
01398 
01399                                 /* get the service macro value */
01400                                 result=grab_custom_object_macro_r(mac, macro_name+8,temp_service->custom_variables,output);
01401                                 }
01402 
01403                         /* else we have a service macro with a servicegroup name and a delimiter... */
01404                         else{
01405 
01406                                 if((temp_servicegroup=find_servicegroup(arg1))==NULL)
01407                                         return ERROR;
01408 
01409                                 delimiter_len=strlen(arg2);
01410 
01411                                 /* concatenate macro values for all servicegroup members */
01412                                 for(temp_servicesmember=temp_servicegroup->members;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
01413 
01414 #ifdef NSCORE
01415                                         if((temp_service=temp_servicesmember->service_ptr)==NULL)
01416                                                 continue;
01417 #else
01418                                         if((temp_service=find_service(temp_servicesmember->host_name,temp_servicesmember->service_description))==NULL)
01419                                                 continue;
01420 #endif
01421 
01422                                         /* get the macro value for this service */
01423                                         grab_custom_macro_value_r(mac, macro_name,temp_service->host_name,temp_service->description,&temp_buffer);
01424 
01425                                         if(temp_buffer==NULL)
01426                                                 continue;
01427 
01428                                         /* add macro value to already running macro */
01429                                         if(*output==NULL)
01430                                                 *output=(char *)strdup(temp_buffer);
01431                                         else{
01432                                                 if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
01433                                                         continue;
01434                                                 strcat(*output,arg2);
01435                                                 strcat(*output,temp_buffer);
01436                                                 }
01437                                         my_free(temp_buffer);
01438                                         }
01439                                 }
01440                         }
01441                 }
01442 
01443         /***** CUSTOM CONTACT VARIABLE *****/
01444         else if(strstr(macro_name,"_CONTACT")==macro_name){
01445 
01446                 /* a standard contact macro */
01447                 if(arg2==NULL){
01448 
01449                         /* find the contact for on-demand macros */
01450                         if(arg1){
01451                                 if((temp_contact=find_contact(arg1))==NULL)
01452                                         return ERROR;
01453                                 }
01454 
01455                         /* else use saved contact pointer */
01456                         else if((temp_contact=mac->contact_ptr)==NULL)
01457                                 return ERROR;
01458 
01459                         /* get the contact macro value */
01460                         result=grab_custom_object_macro_r(mac, macro_name+8,temp_contact->custom_variables,output);
01461                         }
01462 
01463                 /* a contact macro with a contactgroup name and delimiter */
01464                 else{
01465 
01466                         if((temp_contactgroup=find_contactgroup(arg1))==NULL)
01467                                 return ERROR;
01468 
01469                         delimiter_len=strlen(arg2);
01470 
01471                         /* concatenate macro values for all contactgroup members */
01472                         for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
01473 
01474 #ifdef NSCORE
01475                                 if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
01476                                         continue;
01477 #else
01478                                 if((temp_contact=find_contact(temp_contactsmember->contact_name))==NULL)
01479                                         continue;
01480 #endif
01481 
01482                                 /* get the macro value for this contact */
01483                                 grab_custom_macro_value_r(mac, macro_name,temp_contact->name,NULL,&temp_buffer);
01484 
01485                                 if(temp_buffer==NULL)
01486                                         continue;
01487 
01488                                 /* add macro value to already running macro */
01489                                 if(*output==NULL)
01490                                         *output=(char *)strdup(temp_buffer);
01491                                 else{
01492                                         if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_buffer)+delimiter_len+1))==NULL)
01493                                                 continue;
01494                                         strcat(*output,arg2);
01495                                         strcat(*output,temp_buffer);
01496                                         }
01497                                 my_free(temp_buffer);
01498                                 }
01499                         }
01500                 }
01501 
01502         else
01503                 return ERROR;
01504 
01505         return result;
01506 }
01507 
01508 int grab_custom_macro_value(char *macro_name, char *arg1, char *arg2, char **output){
01509         return grab_custom_macro_value_r(&global_macros, macro_name, arg1, arg2, output);
01510 }
01511 
01512 
01516 int grab_datetime_macro_r(icinga_macros *mac, int macro_type, char *arg1, char *arg2, char **output){
01517         time_t current_time=0L;
01518         timeperiod *temp_timeperiod=NULL;
01519         time_t test_time=0L;
01520 #ifdef NSCORE
01521         time_t next_valid_time=0L;
01522 #endif
01523 
01524         if(output==NULL)
01525                 return ERROR;
01526 
01527         /* get the current time */
01528         time(&current_time);
01529 
01530         /* parse args, do prep work */
01531         switch(macro_type){
01532 
01533         case MACRO_ISVALIDTIME:
01534         case MACRO_NEXTVALIDTIME:
01535 
01536                 /* find the timeperiod */
01537                 if((temp_timeperiod=find_timeperiod(arg1))==NULL)
01538                         return ERROR;
01539 
01540                 /* what timestamp should we use? */
01541                 if(arg2)
01542                         test_time=(time_t)strtoul(arg2,NULL,0);
01543                 else
01544                         test_time=current_time;
01545                 break;
01546 
01547         default:
01548                 break;
01549                 }
01550 
01551         /* calculate the value */
01552         switch(macro_type){
01553 
01554         case MACRO_LONGDATETIME:
01555                 if(*output==NULL)
01556                         *output=(char *)malloc(MAX_DATETIME_LENGTH);
01557                 if(*output)
01558                         get_datetime_string(&current_time,*output,MAX_DATETIME_LENGTH,LONG_DATE_TIME);
01559                 break;
01560 
01561         case MACRO_SHORTDATETIME:
01562                 if(*output==NULL)
01563                         *output=(char *)malloc(MAX_DATETIME_LENGTH);
01564                 if(*output)
01565                         get_datetime_string(&current_time,*output,MAX_DATETIME_LENGTH,SHORT_DATE_TIME);
01566                 break;
01567 
01568         case MACRO_DATE:
01569                 if(*output==NULL)
01570                         *output=(char *)malloc(MAX_DATETIME_LENGTH);
01571                 if(*output)
01572                         get_datetime_string(&current_time,*output,MAX_DATETIME_LENGTH,SHORT_DATE);
01573                 break;
01574 
01575         case MACRO_TIME:
01576                 if(*output==NULL)
01577                         *output=(char *)malloc(MAX_DATETIME_LENGTH);
01578                 if(*output)
01579                         get_datetime_string(&current_time,*output,MAX_DATETIME_LENGTH,SHORT_TIME);
01580                 break;
01581 
01582         case MACRO_TIMET:
01583                 dummy=asprintf(output,"%lu",(unsigned long)current_time);
01584                 break;
01585 
01586 #ifdef NSCORE
01587         case MACRO_ISVALIDTIME:
01588                 dummy=asprintf(output,"%d",(check_time_against_period(test_time,temp_timeperiod)==OK)?1:0);
01589                 break;
01590 
01591         case MACRO_NEXTVALIDTIME:
01592                 get_next_valid_time(test_time,&next_valid_time,temp_timeperiod);
01593                 if(next_valid_time==test_time && check_time_against_period(test_time,temp_timeperiod)==ERROR)
01594                         next_valid_time=(time_t)0L;
01595                 dummy=asprintf(output,"%lu",(unsigned long)next_valid_time);
01596                 break;
01597 #endif
01598 
01599         default:
01600                 return ERROR;
01601                 break;
01602                 }
01603 
01604         return OK;
01605 }
01606 
01607 int grab_datetime_macro(int macro_type, char *arg1, char *arg2, char **output){
01608         return grab_datetime_macro_r(&global_macros, macro_type, arg1, arg2, output);
01609 }
01610 
01611 
01615 int grab_standard_host_macro_r(icinga_macros *mac, int macro_type, host *temp_host, char **output, int *free_macro){
01616         char *temp_buffer=NULL;
01617 #ifdef NSCORE
01618         hostgroup *temp_hostgroup=NULL;
01619         servicesmember *temp_servicesmember=NULL;
01620         service *temp_service=NULL;
01621         objectlist *temp_objectlist=NULL;
01622         time_t current_time=0L;
01623         unsigned long duration=0L;
01624         int days=0;
01625         int hours=0;
01626         int minutes=0;
01627         int seconds=0;
01628         char *buf1=NULL;
01629         char *buf2=NULL;
01630         int total_host_services=0;
01631         int total_host_services_ok=0;
01632         int total_host_services_warning=0;
01633         int total_host_services_unknown=0;
01634         int total_host_services_critical=0;
01635 #endif
01636 
01637         if(temp_host==NULL || output==NULL || free_macro==NULL)
01638                 return ERROR;
01639 
01640         /* BY DEFAULT TELL CALLER TO FREE MACRO BUFFER WHEN DONE */
01641         *free_macro=TRUE;
01642 
01643         /* get the macro */
01644         switch(macro_type){
01645 
01646         case MACRO_HOSTNAME:
01647                 *output=(char *)strdup(temp_host->name);
01648                 break;
01649         case MACRO_HOSTDISPLAYNAME:
01650                 if(temp_host->display_name)
01651                         *output=(char *)strdup(temp_host->display_name);
01652                 break;
01653         case MACRO_HOSTALIAS:
01654                 *output=(char *)strdup(temp_host->alias);
01655                 break;
01656         case MACRO_HOSTADDRESS:
01657                 *output=(char *)strdup(temp_host->address);
01658                 break;
01659         case MACRO_HOSTADDRESS6:
01660                 *output=(char *)strdup(temp_host->address6);
01661                 break;
01662 #ifdef NSCORE
01663         case MACRO_HOSTSTATE:
01664                 if(temp_host->current_state==HOST_DOWN)
01665                         *output=(char *)strdup("DOWN");
01666                 else if(temp_host->current_state==HOST_UNREACHABLE)
01667                         *output=(char *)strdup("UNREACHABLE");
01668                 else
01669                         *output=(char *)strdup("UP");
01670                 break;
01671         case MACRO_HOSTSTATEID:
01672                 dummy=asprintf(output,"%d",temp_host->current_state);
01673                 break;
01674         case MACRO_LASTHOSTSTATE:
01675                 if(temp_host->last_state==HOST_DOWN)
01676                         *output=(char *)strdup("DOWN");
01677                 else if(temp_host->last_state==HOST_UNREACHABLE)
01678                         *output=(char *)strdup("UNREACHABLE");
01679                 else
01680                         *output=(char *)strdup("UP");
01681                 break;
01682         case MACRO_LASTHOSTSTATEID:
01683                 dummy=asprintf(output,"%d",temp_host->last_state);
01684                 break;
01685         case MACRO_HOSTCHECKTYPE:
01686                 dummy=asprintf(output,"%s",(temp_host->check_type==HOST_CHECK_PASSIVE)?"PASSIVE":"ACTIVE");
01687                 break;
01688         case MACRO_HOSTSTATETYPE:
01689                 dummy=asprintf(output,"%s",(temp_host->state_type==HARD_STATE)?"HARD":"SOFT");
01690                 break;
01691         case MACRO_HOSTOUTPUT:
01692                 if(temp_host->plugin_output)
01693                         *output=(char *)strdup(temp_host->plugin_output);
01694                 break;
01695         case MACRO_LONGHOSTOUTPUT:
01696                 if(temp_host->long_plugin_output)
01697                         *output=(char *)strdup(temp_host->long_plugin_output);
01698                 break;
01699         case MACRO_HOSTPERFDATA:
01700                 if(temp_host->perf_data)
01701                         *output=(char *)strdup(temp_host->perf_data);
01702                 break;
01703 #endif
01704         case MACRO_HOSTCHECKCOMMAND:
01705                 if(temp_host->host_check_command)
01706                         *output=(char *)strdup(temp_host->host_check_command);
01707                 break;
01708 #ifdef NSCORE
01709         case MACRO_HOSTATTEMPT:
01710                 dummy=asprintf(output,"%d",temp_host->current_attempt);
01711                 break;
01712         case MACRO_MAXHOSTATTEMPTS:
01713                 dummy=asprintf(output,"%d",temp_host->max_attempts);
01714                 break;
01715         case MACRO_HOSTDOWNTIME:
01716                 dummy=asprintf(output,"%d",temp_host->scheduled_downtime_depth);
01717                 break;
01718         case MACRO_HOSTPERCENTCHANGE:
01719                 dummy=asprintf(output,"%.2f",temp_host->percent_state_change);
01720                 break;
01721         case MACRO_HOSTDURATIONSEC:
01722         case MACRO_HOSTDURATION:
01723                 time(&current_time);
01724                 duration=(unsigned long)(current_time-temp_host->last_state_change);
01725 
01726                 if(macro_type==MACRO_HOSTDURATIONSEC)
01727                         dummy=asprintf(output,"%lu",duration);
01728                 else{
01729 
01730                         days=duration/86400;
01731                         duration-=(days*86400);
01732                         hours=duration/3600;
01733                         duration-=(hours*3600);
01734                         minutes=duration/60;
01735                         duration-=(minutes*60);
01736                         seconds=duration;
01737                         dummy=asprintf(output,"%dd %dh %dm %ds",days,hours,minutes,seconds);
01738                         }
01739                 break;
01740         case MACRO_HOSTEXECUTIONTIME:
01741                 dummy=asprintf(output,"%.3f",temp_host->execution_time);
01742                 break;
01743         case MACRO_HOSTLATENCY:
01744                 dummy=asprintf(output,"%.3f",temp_host->latency);
01745                 break;
01746         case MACRO_LASTHOSTCHECK:
01747                 dummy=asprintf(output,"%lu",(unsigned long)temp_host->last_check);
01748                 break;
01749         case MACRO_LASTHOSTSTATECHANGE:
01750                 dummy=asprintf(output,"%lu",(unsigned long)temp_host->last_state_change);
01751                 break;
01752         case MACRO_LASTHOSTUP:
01753                 dummy=asprintf(output,"%lu",(unsigned long)temp_host->last_time_up);
01754                 break;
01755         case MACRO_LASTHOSTDOWN:
01756                 dummy=asprintf(output,"%lu",(unsigned long)temp_host->last_time_down);
01757                 break;
01758         case MACRO_LASTHOSTUNREACHABLE:
01759                 dummy=asprintf(output,"%lu",(unsigned long)temp_host->last_time_unreachable);
01760                 break;
01761         case MACRO_HOSTNOTIFICATIONNUMBER:
01762                 dummy=asprintf(output,"%d",temp_host->current_notification_number);
01763                 break;
01764         case MACRO_HOSTNOTIFICATIONID:
01765                 dummy=asprintf(output,"%lu",temp_host->current_notification_id);
01766                 break;
01767         case MACRO_HOSTEVENTID:
01768                 dummy=asprintf(output,"%lu",temp_host->current_event_id);
01769                 break;
01770         case MACRO_LASTHOSTEVENTID:
01771                 dummy=asprintf(output,"%lu",temp_host->last_event_id);
01772                 break;
01773         case MACRO_HOSTPROBLEMID:
01774                 dummy=asprintf(output,"%lu",temp_host->current_problem_id);
01775                 break;
01776         case MACRO_LASTHOSTPROBLEMID:
01777                 dummy=asprintf(output,"%lu",temp_host->last_problem_id);
01778                 break;
01779 #endif
01780         case MACRO_HOSTACTIONURL:
01781                 if(temp_host->action_url)
01782                         *output=(char *)strdup(temp_host->action_url);
01783                 break;
01784         case MACRO_HOSTNOTESURL:
01785                 if(temp_host->notes_url)
01786                         *output=(char *)strdup(temp_host->notes_url);
01787                 break;
01788         case MACRO_HOSTNOTES:
01789                 if(temp_host->notes)
01790                         *output=(char *)strdup(temp_host->notes);
01791                 break;
01792 #ifdef NSCORE
01793         case MACRO_HOSTGROUPNAMES:
01794                 /* find all hostgroups this host is associated with */
01795                 for(temp_objectlist=temp_host->hostgroups_ptr;temp_objectlist!=NULL;temp_objectlist=temp_objectlist->next){
01796 
01797                         if((temp_hostgroup=(hostgroup *)temp_objectlist->object_ptr)==NULL)
01798                                 continue;
01799 
01800                         dummy=asprintf(&buf1,"%s%s%s",(buf2)?buf2:"",(buf2)?",":"",temp_hostgroup->group_name);
01801                         my_free(buf2);
01802                         buf2=buf1;
01803                         }
01804                 if(buf2){
01805                         *output=(char *)strdup(buf2);
01806                         my_free(buf2);
01807                         }
01808                 break;
01809         case MACRO_TOTALHOSTSERVICES:
01810         case MACRO_TOTALHOSTSERVICESOK:
01811         case MACRO_TOTALHOSTSERVICESWARNING:
01812         case MACRO_TOTALHOSTSERVICESUNKNOWN:
01813         case MACRO_TOTALHOSTSERVICESCRITICAL:
01814 
01815                 /* generate host service summary macros (if they haven't already been computed) */
01816                 if(mac->x[MACRO_TOTALHOSTSERVICES]==NULL){
01817 
01818                         for(temp_servicesmember=temp_host->services;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
01819                                 if((temp_service=temp_servicesmember->service_ptr)==NULL)
01820                                         continue;
01821 
01822                                 total_host_services++;
01823 
01824                                 switch(temp_service->current_state){
01825                                 case STATE_OK:
01826                                         total_host_services_ok++;
01827                                         break;
01828                                 case STATE_WARNING:
01829                                         total_host_services_warning++;
01830                                         break;
01831                                 case STATE_UNKNOWN:
01832                                         total_host_services_unknown++;
01833                                         break;
01834                                 case STATE_CRITICAL:
01835                                         total_host_services_critical++;
01836                                         break;
01837                                 default:
01838                                         break;
01839                                         }
01840                                 }
01841 
01842                         /* these macros are time-intensive to compute, and will likely be used together, so save them all for future use */
01843                         my_free(mac->x[MACRO_TOTALHOSTSERVICES]);
01844                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSERVICES],"%d",total_host_services);
01845                         my_free(mac->x[MACRO_TOTALHOSTSERVICESOK]);
01846                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSERVICESOK],"%d",total_host_services_ok);
01847                         my_free(mac->x[MACRO_TOTALHOSTSERVICESWARNING]);
01848                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSERVICESWARNING],"%d",total_host_services_warning);
01849                         my_free(mac->x[MACRO_TOTALHOSTSERVICESUNKNOWN]);
01850                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSERVICESUNKNOWN],"%d",total_host_services_unknown);
01851                         my_free(mac->x[MACRO_TOTALHOSTSERVICESCRITICAL]);
01852                         dummy=asprintf(&mac->x[MACRO_TOTALHOSTSERVICESCRITICAL],"%d",total_host_services_critical);
01853                         }
01854 
01855                 /* return only the macro the user requested */
01856                 *output=mac->x[macro_type];
01857 
01858                 /* tell caller to NOT free memory when done */
01859                 *free_macro=FALSE;
01860                 break;
01861 #endif
01862                 /***************/
01863                 /* MISC MACROS */
01864                 /***************/
01865         case MACRO_HOSTACKAUTHOR:
01866         case MACRO_HOSTACKAUTHORNAME:
01867         case MACRO_HOSTACKAUTHORALIAS:
01868         case MACRO_HOSTACKCOMMENT:
01869                 /* no need to do any more work - these are already precomputed elsewhere */
01870                 /* NOTE: these macros won't work as on-demand macros */
01871                 *output=mac->x[macro_type];
01872                 *free_macro=FALSE;
01873                 break;
01874 
01875         default:
01876                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED HOST MACRO #%d! THIS IS A BUG!\n",macro_type);
01877                 return ERROR;
01878                 }
01879 
01880         /* post-processing */
01881         /* notes, notes URL and action URL macros may themselves contain macros, so process them... */
01882         switch(macro_type){
01883         case MACRO_HOSTACTIONURL:
01884         case MACRO_HOSTNOTESURL:
01885                 process_macros_r(mac, *output,&temp_buffer,URL_ENCODE_MACRO_CHARS);
01886                 my_free(*output);
01887                 *output=temp_buffer;
01888                 break;
01889         case MACRO_HOSTNOTES:
01890                 process_macros_r(mac, *output,&temp_buffer,0);
01891                 my_free(*output);
01892                 *output=temp_buffer;
01893                 break;
01894         default:
01895                 break;
01896                 }
01897 
01898         return OK;
01899 }
01900 
01901 int grab_standard_host_macro(int macro_type, host *temp_host, char **output, int *free_macro){
01902         return grab_standard_host_macro_r(&global_macros, macro_type, temp_host, output, free_macro);
01903 }
01904 
01905 
01909 int grab_standard_hostgroup_macro_r(icinga_macros *mac, int macro_type, hostgroup *temp_hostgroup, char **output){
01910         hostsmember *temp_hostsmember=NULL;
01911         char *temp_buffer=NULL;
01912         unsigned int temp_len=0;
01913         unsigned int init_len=0;
01914 
01915         if(temp_hostgroup==NULL || output==NULL)
01916                 return ERROR;
01917 
01918         /* get the macro value */
01919         switch(macro_type){
01920         case MACRO_HOSTGROUPNAME:
01921                 *output=(char *)strdup(temp_hostgroup->group_name);
01922                 break;
01923         case MACRO_HOSTGROUPALIAS:
01924                 if(temp_hostgroup->alias)
01925                         *output=(char *)strdup(temp_hostgroup->alias);
01926                 break;
01927         case MACRO_HOSTGROUPMEMBERS:
01928                 /* make the calculations for total string length */
01929                 for(temp_hostsmember=temp_hostgroup->members;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
01930                         if(temp_hostsmember->host_name==NULL)
01931                                 continue;
01932                         if (temp_len==0){
01933                                 temp_len+=strlen(temp_hostsmember->host_name)+1;
01934                         } else {
01935                                 temp_len+=strlen(temp_hostsmember->host_name)+2;
01936                                 }
01937                         }
01938                 /* allocate or reallocate the memory buffer */
01939                 if (*output==NULL) {
01940                         *output=(char *)malloc(temp_len);
01941                 } else {
01942                         init_len = strlen(*output);
01943                         temp_len += init_len;
01944                         *output=(char *)realloc(*output,temp_len);
01945                 }
01946                 /* now fill in the string with the member names */
01947                 for(temp_hostsmember=temp_hostgroup->members;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
01948                         if(temp_hostsmember->host_name==NULL)
01949                                 continue;
01950                         temp_buffer = *output + init_len;
01951                         if (init_len == 0) { /* If our buffer didn't contain anything, we just need to write "%s,%s" */
01952                                 init_len += sprintf(temp_buffer, "%s", temp_hostsmember->host_name);
01953                         } else {
01954                                 init_len += sprintf(temp_buffer, ",%s", temp_hostsmember->host_name);
01955                                 }
01956                         }
01957                 break;
01958         case MACRO_HOSTGROUPACTIONURL:
01959                 if(temp_hostgroup->action_url)
01960                         *output=(char *)strdup(temp_hostgroup->action_url);
01961                 break;
01962         case MACRO_HOSTGROUPNOTESURL:
01963                 if(temp_hostgroup->notes_url)
01964                         *output=(char *)strdup(temp_hostgroup->notes_url);
01965                 break;
01966         case MACRO_HOSTGROUPNOTES:
01967                 if(temp_hostgroup->notes)
01968                         *output=(char *)strdup(temp_hostgroup->notes);
01969                 break;
01970         default:
01971                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED HOSTGROUP MACRO #%d! THIS IS A BUG!\n",macro_type);
01972                 return ERROR;
01973                 }
01974 
01975         /* post-processing */
01976         /* notes, notes URL and action URL macros may themselves contain macros, so process them... */
01977         switch(macro_type){
01978         case MACRO_HOSTGROUPACTIONURL:
01979         case MACRO_HOSTGROUPNOTESURL:
01980                 process_macros_r(mac, *output,&temp_buffer,URL_ENCODE_MACRO_CHARS);
01981                 my_free(*output);
01982                 *output=temp_buffer;
01983                 break;
01984         case MACRO_HOSTGROUPNOTES:
01985                 process_macros_r(mac, *output,&temp_buffer,0);
01986                 my_free(*output);
01987                 *output=temp_buffer;
01988                 break;
01989         default:
01990                 break;
01991                 }
01992 
01993         return OK;
01994 }
01995 
01996 int grab_standard_hostgroup_macro(int macro_type, hostgroup *temp_hostgroup, char **output){
01997         return grab_standard_hostgroup_macro_r(&global_macros, macro_type, temp_hostgroup, output);
01998 }
01999 
02000 
02004 int grab_standard_service_macro_r(icinga_macros *mac, int macro_type, service *temp_service, char **output, int *free_macro){
02005         char *temp_buffer=NULL;
02006 #ifdef NSCORE
02007         servicegroup *temp_servicegroup=NULL;
02008         objectlist *temp_objectlist=NULL;
02009         time_t current_time=0L;
02010         unsigned long duration=0L;
02011         int days=0;
02012         int hours=0;
02013         int minutes=0;
02014         int seconds=0;
02015         char *buf1=NULL;
02016         char *buf2=NULL;
02017 #endif
02018 
02019         if(temp_service==NULL || output==NULL)
02020                 return ERROR;
02021 
02022         /* BY DEFAULT TELL CALLER TO FREE MACRO BUFFER WHEN DONE */
02023         *free_macro=TRUE;
02024 
02025         /* get the macro value */
02026         switch(macro_type){
02027         case MACRO_SERVICEDESC:
02028                 *output=(char *)strdup(temp_service->description);
02029                 break;
02030         case MACRO_SERVICEDISPLAYNAME:
02031                 if(temp_service->display_name)
02032                         *output=(char *)strdup(temp_service->display_name);
02033                 break;
02034 #ifdef NSCORE
02035         case MACRO_SERVICEOUTPUT:
02036                 if(temp_service->plugin_output)
02037                         *output=(char *)strdup(temp_service->plugin_output);
02038                 break;
02039         case MACRO_LONGSERVICEOUTPUT:
02040                 if(temp_service->long_plugin_output)
02041                         *output=(char *)strdup(temp_service->long_plugin_output);
02042                 break;
02043         case MACRO_SERVICEPERFDATA:
02044                 if(temp_service->perf_data)
02045                         *output=(char *)strdup(temp_service->perf_data);
02046                 break;
02047 #endif
02048         case MACRO_SERVICECHECKCOMMAND:
02049                 if(temp_service->service_check_command)
02050                         *output=(char *)strdup(temp_service->service_check_command);
02051                 break;
02052 #ifdef NSCORE
02053         case MACRO_SERVICECHECKTYPE:
02054                 *output=(char *)strdup((temp_service->check_type==SERVICE_CHECK_PASSIVE)?"PASSIVE":"ACTIVE");
02055                 break;
02056         case MACRO_SERVICESTATETYPE:
02057                 *output=(char *)strdup((temp_service->state_type==HARD_STATE)?"HARD":"SOFT");
02058                 break;
02059         case MACRO_SERVICESTATE:
02060                 if(temp_service->current_state==STATE_OK)
02061                         *output=(char *)strdup("OK");
02062                 else if(temp_service->current_state==STATE_WARNING)
02063                         *output=(char *)strdup("WARNING");
02064                 else if(temp_service->current_state==STATE_CRITICAL)
02065                         *output=(char *)strdup("CRITICAL");
02066                 else
02067                         *output=(char *)strdup("UNKNOWN");
02068                 break;
02069         case MACRO_SERVICESTATEID:
02070                 dummy=asprintf(output,"%d",temp_service->current_state);
02071                 break;
02072         case MACRO_LASTSERVICESTATE:
02073                 if(temp_service->last_state==STATE_OK)
02074                         *output=(char *)strdup("OK");
02075                 else if(temp_service->last_state==STATE_WARNING)
02076                         *output=(char *)strdup("WARNING");
02077                 else if(temp_service->last_state==STATE_CRITICAL)
02078                         *output=(char *)strdup("CRITICAL");
02079                 else
02080                         *output=(char *)strdup("UNKNOWN");
02081                 break;
02082         case MACRO_LASTSERVICESTATEID:
02083                 dummy=asprintf(output,"%d",temp_service->last_state);
02084                 break;
02085 #endif
02086         case MACRO_SERVICEISVOLATILE:
02087                 dummy=asprintf(output,"%d",temp_service->is_volatile);
02088                 break;
02089 #ifdef NSCORE
02090         case MACRO_SERVICEATTEMPT:
02091                 dummy=asprintf(output,"%d",temp_service->current_attempt);
02092                 break;
02093         case MACRO_MAXSERVICEATTEMPTS:
02094                 dummy=asprintf(output,"%d",temp_service->max_attempts);
02095                 break;
02096         case MACRO_SERVICEEXECUTIONTIME:
02097                 dummy=asprintf(output,"%.3f",temp_service->execution_time);
02098                 break;
02099         case MACRO_SERVICELATENCY:
02100                 dummy=asprintf(output,"%.3f",temp_service->latency);
02101                 break;
02102         case MACRO_LASTSERVICECHECK:
02103                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_check);
02104                 break;
02105         case MACRO_LASTSERVICESTATECHANGE:
02106                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_state_change);
02107                 break;
02108         case MACRO_LASTSERVICEOK:
02109                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_time_ok);
02110                 break;
02111         case MACRO_LASTSERVICEWARNING:
02112                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_time_warning);
02113                 break;
02114         case MACRO_LASTSERVICEUNKNOWN:
02115                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_time_unknown);
02116                 break;
02117         case MACRO_LASTSERVICECRITICAL:
02118                 dummy=asprintf(output,"%lu",(unsigned long)temp_service->last_time_critical);
02119                 break;
02120         case MACRO_SERVICEDOWNTIME:
02121                 dummy=asprintf(output,"%d",temp_service->scheduled_downtime_depth);
02122                 break;
02123         case MACRO_SERVICEPERCENTCHANGE:
02124                 dummy=asprintf(output,"%.2f",temp_service->percent_state_change);
02125                 break;
02126         case MACRO_SERVICEDURATIONSEC:
02127         case MACRO_SERVICEDURATION:
02128 
02129                 time(&current_time);
02130                 duration=(unsigned long)(current_time-temp_service->last_state_change);
02131 
02132                 /* get the state duration in seconds */
02133                 if(macro_type==MACRO_SERVICEDURATIONSEC)
02134                         dummy=asprintf(output,"%lu",duration);
02135 
02136                 /* get the state duration */
02137                 else{
02138                         days=duration/86400;
02139                         duration-=(days*86400);
02140                         hours=duration/3600;
02141                         duration-=(hours*3600);
02142                         minutes=duration/60;
02143                         duration-=(minutes*60);
02144                         seconds=duration;
02145                         dummy=asprintf(output,"%dd %dh %dm %ds",days,hours,minutes,seconds);
02146                         }
02147                 break;
02148         case MACRO_SERVICENOTIFICATIONNUMBER:
02149                 dummy=asprintf(output,"%d",temp_service->current_notification_number);
02150                 break;
02151         case MACRO_SERVICENOTIFICATIONID:
02152                 dummy=asprintf(output,"%lu",temp_service->current_notification_id);
02153                 break;
02154         case MACRO_SERVICEEVENTID:
02155                 dummy=asprintf(output,"%lu",temp_service->current_event_id);
02156                 break;
02157         case MACRO_LASTSERVICEEVENTID:
02158                 dummy=asprintf(output,"%lu",temp_service->last_event_id);
02159                 break;
02160         case MACRO_SERVICEPROBLEMID:
02161                 dummy=asprintf(output,"%lu",temp_service->current_problem_id);
02162                 break;
02163         case MACRO_LASTSERVICEPROBLEMID:
02164                 dummy=asprintf(output,"%lu",temp_service->last_problem_id);
02165                 break;
02166 #endif
02167         case MACRO_SERVICEACTIONURL:
02168                 if(temp_service->action_url)
02169                         *output=(char *)strdup(temp_service->action_url);
02170                 break;
02171         case MACRO_SERVICENOTESURL:
02172                 if(temp_service->notes_url)
02173                         *output=(char *)strdup(temp_service->notes_url);
02174                 break;
02175         case MACRO_SERVICENOTES:
02176                 if(temp_service->notes)
02177                         *output=(char *)strdup(temp_service->notes);
02178                 break;
02179 #ifdef NSCORE
02180         case MACRO_SERVICEGROUPNAMES:
02181                 /* find all servicegroups this service is associated with */
02182                 for(temp_objectlist=temp_service->servicegroups_ptr;temp_objectlist!=NULL;temp_objectlist=temp_objectlist->next){
02183 
02184                         if((temp_servicegroup=(servicegroup *)temp_objectlist->object_ptr)==NULL)
02185                                 continue;
02186 
02187                         dummy=asprintf(&buf1,"%s%s%s",(buf2)?buf2:"",(buf2)?",":"",temp_servicegroup->group_name);
02188                         my_free(buf2);
02189                         buf2=buf1;
02190                         }
02191                 if(buf2){
02192                         *output=(char *)strdup(buf2);
02193                         my_free(buf2);
02194                         }
02195                 break;
02196 #endif
02197                 /***************/
02198                 /* MISC MACROS */
02199                 /***************/
02200         case MACRO_SERVICEACKAUTHOR:
02201         case MACRO_SERVICEACKAUTHORNAME:
02202         case MACRO_SERVICEACKAUTHORALIAS:
02203         case MACRO_SERVICEACKCOMMENT:
02204                 /* no need to do any more work - these are already precomputed elsewhere */
02205                 /* NOTE: these macros won't work as on-demand macros */
02206                 *output=mac->x[macro_type];
02207                 *free_macro=FALSE;
02208                 break;
02209 
02210         default:
02211                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED SERVICE MACRO #%d! THIS IS A BUG!\n",macro_type);
02212                 return ERROR;
02213                 }
02214 
02215         /* post-processing */
02216         /* notes, notes URL and action URL macros may themselves contain macros, so process them... */
02217         switch(macro_type){
02218         case MACRO_SERVICEACTIONURL:
02219         case MACRO_SERVICENOTESURL:
02220                 process_macros_r(mac, *output,&temp_buffer,URL_ENCODE_MACRO_CHARS);
02221                 my_free(*output);
02222                 *output=temp_buffer;
02223                 break;
02224         case MACRO_SERVICENOTES:
02225                 process_macros_r(mac, *output,&temp_buffer,0);
02226                 my_free(*output);
02227                 *output=temp_buffer;
02228                 break;
02229         default:
02230                 break;
02231                 }
02232 
02233         return OK;
02234 }
02235 
02236 int grab_standard_service_macro(int macro_type, service *temp_service, char **output, int *free_macro){
02237         return grab_standard_service_macro_r(&global_macros, macro_type, temp_service, output, free_macro);
02238 }
02239 
02240 
02244 int grab_standard_servicegroup_macro_r(icinga_macros *mac, int macro_type, servicegroup *temp_servicegroup, char **output){
02245         servicesmember *temp_servicesmember=NULL;
02246         char *temp_buffer=NULL;
02247         unsigned int temp_len=0;
02248         unsigned int init_len=0;
02249 
02250         if(temp_servicegroup==NULL || output==NULL)
02251                 return ERROR;
02252 
02253         /* get the macro value */
02254         switch(macro_type){
02255         case MACRO_SERVICEGROUPNAME:
02256                 *output=(char *)strdup(temp_servicegroup->group_name);
02257                 break;
02258         case MACRO_SERVICEGROUPALIAS:
02259                 if(temp_servicegroup->alias)
02260                         *output=(char *)strdup(temp_servicegroup->alias);
02261                 break;
02262         case MACRO_SERVICEGROUPMEMBERS:
02263                 /* make the calculations for total string length */
02264                 for(temp_servicesmember=temp_servicegroup->members;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
02265                         if(temp_servicesmember->host_name==NULL || temp_servicesmember->service_description==NULL)
02266                                 continue;
02267                         if (temp_len == 0) {
02268                                 temp_len+=strlen(temp_servicesmember->host_name)+strlen(temp_servicesmember->service_description)+2;
02269                         } else {
02270                                 temp_len+=strlen(temp_servicesmember->host_name)+strlen(temp_servicesmember->service_description)+3;
02271                                 }
02272                         }
02273                 /* allocate or reallocate the memory buffer */
02274                 if (*output==NULL) {
02275                         *output=(char *)malloc(temp_len);
02276                         }
02277                 else {
02278                         init_len = strlen(*output);
02279                         temp_len += init_len;
02280                         *output=(char *)realloc(*output,temp_len);
02281                         }
02282                 /* now fill in the string with the group members */
02283                 for(temp_servicesmember=temp_servicegroup->members;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
02284                         if(temp_servicesmember->host_name==NULL || temp_servicesmember->service_description==NULL)
02285                                 continue;
02286                         temp_buffer = *output + init_len;
02287                         if (init_len == 0) { /* If our buffer didn't contain anything, we just need to write "%s,%s" */
02288                                 init_len += sprintf(temp_buffer, "%s,%s",temp_servicesmember->host_name,temp_servicesmember->service_description);
02289                         } else { /* Now we need to write ",%s,%s" */
02290                                 init_len += sprintf(temp_buffer, ",%s,%s",temp_servicesmember->host_name,temp_servicesmember->service_description);
02291                                 }
02292                         }
02293                 break;
02294         case MACRO_SERVICEGROUPACTIONURL:
02295                 if(temp_servicegroup->action_url)
02296                         *output=(char *)strdup(temp_servicegroup->action_url);
02297                 break;
02298         case MACRO_SERVICEGROUPNOTESURL:
02299                 if(temp_servicegroup->notes_url)
02300                         *output=(char *)strdup(temp_servicegroup->notes_url);
02301                 break;
02302         case MACRO_SERVICEGROUPNOTES:
02303                 if(temp_servicegroup->notes)
02304                         *output=(char *)strdup(temp_servicegroup->notes);
02305                 break;
02306         default:
02307                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED SERVICEGROUP MACRO #%d! THIS IS A BUG!\n",macro_type);
02308                 return ERROR;
02309                 }
02310 
02311         /* post-processing */
02312         /* notes, notes URL and action URL macros may themselves contain macros, so process them... */
02313         switch(macro_type){
02314         case MACRO_SERVICEGROUPACTIONURL:
02315         case MACRO_SERVICEGROUPNOTESURL:
02316                 process_macros_r(mac, *output,&temp_buffer,URL_ENCODE_MACRO_CHARS);
02317                 my_free(*output);
02318                 *output=temp_buffer;
02319                 break;
02320         case MACRO_SERVICEGROUPNOTES:
02321                 process_macros_r(mac, *output,&temp_buffer,0);
02322                 my_free(*output);
02323                 *output=temp_buffer;
02324                 break;
02325         default:
02326                 break;
02327                 }
02328 
02329         return OK;
02330 }
02331 
02332 int grab_standard_servicegroup_macro(int macro_type, servicegroup *temp_servicegroup, char **output){
02333         return grab_standard_servicegroup_macro_r(&global_macros, macro_type, temp_servicegroup, output);
02334 }
02335 
02336 
02340 int grab_standard_contact_macro_r(icinga_macros *mac, int macro_type, contact *temp_contact, char **output){
02341 #ifdef NSCORE
02342         contactgroup *temp_contactgroup=NULL;
02343         objectlist *temp_objectlist=NULL;
02344         char *buf1=NULL;
02345         char *buf2=NULL;
02346 #endif
02347 
02348         if(temp_contact==NULL || output==NULL)
02349                 return ERROR;
02350 
02351         /* get the macro value */
02352         switch(macro_type){
02353         case MACRO_CONTACTNAME:
02354                 *output=(char *)strdup(temp_contact->name);
02355                 break;
02356         case MACRO_CONTACTALIAS:
02357                 *output=(char *)strdup(temp_contact->alias);
02358                 break;
02359         case MACRO_CONTACTEMAIL:
02360                 if(temp_contact->email)
02361                         *output=(char *)strdup(temp_contact->email);
02362                 break;
02363         case MACRO_CONTACTPAGER:
02364                 if(temp_contact->pager)
02365                         *output=(char *)strdup(temp_contact->pager);
02366                 break;
02367 #ifdef NSCORE
02368         case MACRO_CONTACTGROUPNAMES:
02369                 /* get the contactgroup names */
02370                 /* find all contactgroups this contact is a member of */
02371                 for(temp_objectlist=temp_contact->contactgroups_ptr;temp_objectlist!=NULL;temp_objectlist=temp_objectlist->next){
02372 
02373                         if((temp_contactgroup=(contactgroup *)temp_objectlist->object_ptr)==NULL)
02374                                 continue;
02375 
02376                         dummy=asprintf(&buf1,"%s%s%s",(buf2)?buf2:"",(buf2)?",":"",temp_contactgroup->group_name);
02377                         my_free(buf2);
02378                         buf2=buf1;
02379                         }
02380                 if(buf2){
02381                         *output=(char *)strdup(buf2);
02382                         my_free(buf2);
02383                         }
02384                 break;
02385 #endif
02386         default:
02387                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED CONTACT MACRO #%d! THIS IS A BUG!\n",macro_type);
02388                 return ERROR;
02389                 }
02390 
02391         return OK;
02392 }
02393 
02394 int grab_standard_contact_macro(int macro_type, contact *temp_contact, char **output){
02395         return grab_standard_contact_macro_r(&global_macros, macro_type, temp_contact, output);
02396 }
02397 
02398 
02402 int grab_contact_address_macro_r(icinga_macros *mac, int macro_num, contact *temp_contact, char **output){
02403 
02404         if(macro_num<0 || macro_num>=MAX_CONTACT_ADDRESSES)
02405                 return ERROR;
02406 
02407         if(temp_contact==NULL || output==NULL)
02408                 return ERROR;
02409 
02410         /* get the macro */
02411         if(temp_contact->address[macro_num])
02412                 *output=(char *)strdup(temp_contact->address[macro_num]);
02413 
02414         return OK;
02415 }
02416 
02417 int grab_contact_address_macro(int macro_num, contact *temp_contact, char **output){
02418         return grab_contact_address_macro_r(&global_macros, macro_num, temp_contact, output);
02419 }
02420 
02421 
02425 int grab_standard_contactgroup_macro_r(icinga_macros *mac, int macro_type, contactgroup *temp_contactgroup, char **output){
02426         contactsmember *temp_contactsmember=NULL;
02427 
02428         if(temp_contactgroup==NULL || output==NULL)
02429                 return ERROR;
02430 
02431         /* get the macro value */
02432         switch(macro_type){
02433         case MACRO_CONTACTGROUPNAME:
02434                 *output=(char *)strdup(temp_contactgroup->group_name);
02435                 break;
02436         case MACRO_CONTACTGROUPALIAS:
02437                 if(temp_contactgroup->alias)
02438                         *output=(char *)strdup(temp_contactgroup->alias);
02439                 break;
02440         case MACRO_CONTACTGROUPMEMBERS:
02441                 /* get the member list */
02442                 for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
02443                         if(temp_contactsmember->contact_name==NULL)
02444                                 continue;
02445                         if(*output==NULL)
02446                                 *output=(char *)strdup(temp_contactsmember->contact_name);
02447                         else if((*output=(char *)realloc(*output,strlen(*output)+strlen(temp_contactsmember->contact_name)+2))){
02448                                 strcat(*output,",");
02449                                 strcat(*output,temp_contactsmember->contact_name);
02450                                 }
02451                         }
02452                 break;
02453         default:
02454                 log_debug_info(DEBUGL_MACROS,0,"UNHANDLED CONTACTGROUP MACRO #%d! THIS IS A BUG!\n",macro_type);
02455                 return ERROR;
02456                 }
02457 
02458         return OK;
02459 }
02460 
02461 int grab_standard_contactgroup_macro(int macro_type, contactgroup *temp_contactgroup, char **output){
02462         return grab_standard_contactgroup_macro_r(&global_macros, macro_type, temp_contactgroup, output);
02463 }
02464 
02465 
02466 
02470 int grab_custom_object_macro_r(icinga_macros *mac, char *macro_name, customvariablesmember *vars, char **output){
02471         customvariablesmember *temp_customvariablesmember=NULL;
02472         int result=ERROR;
02473 
02474         if(macro_name==NULL || vars==NULL || output==NULL)
02475                 return ERROR;
02476 
02477         /* get the custom variable */
02478         for(temp_customvariablesmember=vars;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next){
02479 
02480                 if(temp_customvariablesmember->variable_name==NULL)
02481                         continue;
02482 
02483                 if(!strcmp(macro_name,temp_customvariablesmember->variable_name)){
02484                         if(temp_customvariablesmember->variable_value)
02485                                 *output=(char *)strdup(temp_customvariablesmember->variable_value);
02486                         result=OK;
02487                         break;
02488                         }
02489                 }
02490 
02491         return result;
02492 }
02493 
02494 int grab_custom_object_macro(char *macro_name, customvariablesmember *vars, char **output){
02495         return grab_custom_object_macro_r(&global_macros, macro_name, vars, output);
02496 }
02497 
02498 
02499 /******************************************************************/
02500 /********************* MACRO STRING FUNCTIONS *********************/
02501 /******************************************************************/
02502 
02506 char *clean_macro_chars(char *macro,int options){
02507         register int x=0;
02508         register int y=0;
02509         register int z=0;
02510         register int ch=0;
02511         register int len=0;
02512         register int illegal_char=0;
02513 
02514         if(macro==NULL)
02515                 return "";
02516 
02517         len=(int)strlen(macro);
02518 
02519         /* strip illegal characters out of macro */
02520         if(options & STRIP_ILLEGAL_MACRO_CHARS){
02521 
02522                 for(y=0,x=0;x<len;x++){
02523 
02524                         /*ch=(int)macro[x];*/
02525                         /* allow non-ASCII characters (Japanese, etc) */
02526                         ch=macro[x] & 0xff;
02527 
02528                         /* illegal ASCII characters */
02529                         if(ch<32 || ch==127)
02530                                 continue;
02531 
02532                         /* illegal user-specified characters */
02533                         illegal_char=FALSE;
02534                         if(illegal_output_chars!=NULL){
02535                                 for(z=0;illegal_output_chars[z]!='\x0';z++){
02536                                         if(ch==(int)illegal_output_chars[z]){
02537                                                 illegal_char=TRUE;
02538                                                 break;
02539                                                 }
02540                                         }
02541                                 }
02542 
02543                         if(illegal_char==FALSE)
02544                                 macro[y++]=macro[x];
02545                         }
02546 
02547                 macro[y++]='\x0';
02548                 }
02549 
02550 #ifdef ON_HOLD_FOR_NOW
02551         /* escape nasty character in macro */
02552         if(options & ESCAPE_MACRO_CHARS){
02553                 }
02554 #endif
02555 
02556         return macro;
02557 }
02558 
02559 
02560 
02564 char *get_url_encoded_string(char *input){
02565         register int x=0;
02566         register int y=0;
02567         char *encoded_url_string=NULL;
02568         char temp_expansion[6]="";
02569 
02570 
02571         /* bail if no input */
02572         if(input==NULL)
02573                 return NULL;
02574 
02575         /* allocate enough memory to escape all characters if necessary */
02576         if((encoded_url_string=(char *)malloc((strlen(input)*3)+1))==NULL)
02577                 return NULL;
02578 
02579         /* check/encode all characters */
02580         for(x=0,y=0;input[x]!=(char)'\x0';x++){
02581 
02582                 /* alpha-numeric characters and a few other characters don't get encoded */
02583                 if(((char)input[x]>='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z') || (char)input[x]==(char)'.' || (char)input[x]==(char)'-' || (char)input[x]==(char)'_' || (char)input[x]==(char)':' || (char)input[x]==(char)'/' || (char)input[x]==(char)'?' || (char)input[x]==(char)'=' || (char)input[x]==(char)'&'){
02584                         encoded_url_string[y]=input[x];
02585                         y++;
02586                         }
02587 
02588                 /* spaces are pluses */
02589                 else if((char)input[x]<=(char)' '){
02590                         encoded_url_string[y]='+';
02591                         y++;
02592                         }
02593 
02594                 /* anything else gets represented by its hex value */
02595                 else{
02596                         encoded_url_string[y]='\x0';
02597                         sprintf(temp_expansion,"%%%02X",(unsigned int)(input[x] & 0xFF));
02598                         strcat(encoded_url_string,temp_expansion);
02599                         y+=3;
02600                         }
02601                 }
02602 
02603         /* terminate encoded string */
02604         encoded_url_string[y]='\x0';
02605 
02606         return encoded_url_string;
02607 }
02608 
02609 
02610 
02611 /******************************************************************/
02612 /***************** MACRO INITIALIZATION FUNCTIONS *****************/
02613 /******************************************************************/
02614 
02618 int init_macros(void){
02619 
02620         init_macrox_names();
02621 
02622         /*
02623          * non-volatile macros are free()'d when they're set.
02624          * We must do this in order to not lose the constant
02625          * ones when we get SIGHUP or a RESTART_PROGRAM event
02626          * from the command fifo. Otherwise a memset() would
02627          * have been better.
02628          */
02629         clear_volatile_macros_r(&global_macros);
02630 
02631         /* backwards compatibility hack */
02632         macro_x = global_macros.x;
02633 
02634         return OK;
02635 }
02636 
02637 
02638 
02644 #define add_macrox_name(name) macro_x_names[MACRO_##name] = strdup(#name)
02645 int init_macrox_names(void){
02646         register int x=0;
02647 
02648         /* initialize macro names */
02649         for(x=0;x<MACRO_X_COUNT;x++)
02650                 macro_x_names[x]=NULL;
02651 
02652         /* initialize each macro name */
02653         add_macrox_name(HOSTNAME);
02654         add_macrox_name(HOSTALIAS);
02655         add_macrox_name(HOSTADDRESS);
02656         add_macrox_name(HOSTADDRESS6);
02657         add_macrox_name(SERVICEDESC);
02658         add_macrox_name(SERVICESTATE);
02659         add_macrox_name(SERVICESTATEID);
02660         add_macrox_name(SERVICEATTEMPT);
02661         add_macrox_name(SERVICEISVOLATILE);
02662         add_macrox_name(LONGDATETIME);
02663         add_macrox_name(SHORTDATETIME);
02664         add_macrox_name(DATE);
02665         add_macrox_name(TIME);
02666         add_macrox_name(TIMET);
02667         add_macrox_name(LASTHOSTCHECK);
02668         add_macrox_name(LASTSERVICECHECK);
02669         add_macrox_name(LASTHOSTSTATECHANGE);
02670         add_macrox_name(LASTSERVICESTATECHANGE);
02671         add_macrox_name(HOSTOUTPUT);
02672         add_macrox_name(SERVICEOUTPUT);
02673         add_macrox_name(HOSTPERFDATA);
02674         add_macrox_name(SERVICEPERFDATA);
02675         add_macrox_name(CONTACTNAME);
02676         add_macrox_name(CONTACTALIAS);
02677         add_macrox_name(CONTACTEMAIL);
02678         add_macrox_name(CONTACTPAGER);
02679         add_macrox_name(ADMINEMAIL);
02680         add_macrox_name(ADMINPAGER);
02681         add_macrox_name(HOSTSTATE);
02682         add_macrox_name(HOSTSTATEID);
02683         add_macrox_name(HOSTATTEMPT);
02684         add_macrox_name(NOTIFICATIONTYPE);
02685         add_macrox_name(NOTIFICATIONNUMBER);
02686         add_macrox_name(NOTIFICATIONISESCALATED);
02687         add_macrox_name(HOSTEXECUTIONTIME);
02688         add_macrox_name(SERVICEEXECUTIONTIME);
02689         add_macrox_name(HOSTLATENCY);
02690         add_macrox_name(SERVICELATENCY);
02691         add_macrox_name(HOSTDURATION);
02692         add_macrox_name(SERVICEDURATION);
02693         add_macrox_name(HOSTDURATIONSEC);
02694         add_macrox_name(SERVICEDURATIONSEC);
02695         add_macrox_name(HOSTDOWNTIME);
02696         add_macrox_name(SERVICEDOWNTIME);
02697         add_macrox_name(HOSTSTATETYPE);
02698         add_macrox_name(SERVICESTATETYPE);
02699         add_macrox_name(HOSTPERCENTCHANGE);
02700         add_macrox_name(SERVICEPERCENTCHANGE);
02701         add_macrox_name(HOSTGROUPNAME);
02702         add_macrox_name(HOSTGROUPALIAS);
02703         add_macrox_name(SERVICEGROUPNAME);
02704         add_macrox_name(SERVICEGROUPALIAS);
02705         add_macrox_name(HOSTACKAUTHOR);
02706         add_macrox_name(HOSTACKCOMMENT);
02707         add_macrox_name(SERVICEACKAUTHOR);
02708         add_macrox_name(SERVICEACKCOMMENT);
02709         add_macrox_name(LASTSERVICEOK);
02710         add_macrox_name(LASTSERVICEWARNING);
02711         add_macrox_name(LASTSERVICEUNKNOWN);
02712         add_macrox_name(LASTSERVICECRITICAL);
02713         add_macrox_name(LASTHOSTUP);
02714         add_macrox_name(LASTHOSTDOWN);
02715         add_macrox_name(LASTHOSTUNREACHABLE);
02716         add_macrox_name(SERVICECHECKCOMMAND);
02717         add_macrox_name(HOSTCHECKCOMMAND);
02718         add_macrox_name(MAINCONFIGFILE);
02719         add_macrox_name(STATUSDATAFILE);
02720         add_macrox_name(HOSTDISPLAYNAME);
02721         add_macrox_name(SERVICEDISPLAYNAME);
02722         add_macrox_name(RETENTIONDATAFILE);
02723         add_macrox_name(OBJECTCACHEFILE);
02724         add_macrox_name(TEMPFILE);
02725         add_macrox_name(LOGFILE);
02726         add_macrox_name(RESOURCEFILE);
02727         add_macrox_name(COMMANDFILE);
02728         add_macrox_name(HOSTPERFDATAFILE);
02729         add_macrox_name(SERVICEPERFDATAFILE);
02730         add_macrox_name(HOSTACTIONURL);
02731         add_macrox_name(HOSTNOTESURL);
02732         add_macrox_name(HOSTNOTES);
02733         add_macrox_name(SERVICEACTIONURL);
02734         add_macrox_name(SERVICENOTESURL);
02735         add_macrox_name(SERVICENOTES);
02736         add_macrox_name(TOTALHOSTSUP);
02737         add_macrox_name(TOTALHOSTSDOWN);
02738         add_macrox_name(TOTALHOSTSUNREACHABLE);
02739         add_macrox_name(TOTALHOSTSDOWNUNHANDLED);
02740         add_macrox_name(TOTALHOSTSUNREACHABLEUNHANDLED);
02741         add_macrox_name(TOTALHOSTPROBLEMS);
02742         add_macrox_name(TOTALHOSTPROBLEMSUNHANDLED);
02743         add_macrox_name(TOTALSERVICESOK);
02744         add_macrox_name(TOTALSERVICESWARNING);
02745         add_macrox_name(TOTALSERVICESCRITICAL);
02746         add_macrox_name(TOTALSERVICESUNKNOWN);
02747         add_macrox_name(TOTALSERVICESWARNINGUNHANDLED);
02748         add_macrox_name(TOTALSERVICESCRITICALUNHANDLED);
02749         add_macrox_name(TOTALSERVICESUNKNOWNUNHANDLED);
02750         add_macrox_name(TOTALSERVICEPROBLEMS);
02751         add_macrox_name(TOTALSERVICEPROBLEMSUNHANDLED);
02752         add_macrox_name(PROCESSSTARTTIME);
02753         add_macrox_name(HOSTCHECKTYPE);
02754         add_macrox_name(SERVICECHECKTYPE);
02755         add_macrox_name(LONGHOSTOUTPUT);
02756         add_macrox_name(LONGSERVICEOUTPUT);
02757         add_macrox_name(TEMPPATH);
02758         add_macrox_name(HOSTNOTIFICATIONNUMBER);
02759         add_macrox_name(SERVICENOTIFICATIONNUMBER);
02760         add_macrox_name(HOSTNOTIFICATIONID);
02761         add_macrox_name(SERVICENOTIFICATIONID);
02762         add_macrox_name(HOSTEVENTID);
02763         add_macrox_name(LASTHOSTEVENTID);
02764         add_macrox_name(SERVICEEVENTID);
02765         add_macrox_name(LASTSERVICEEVENTID);
02766         add_macrox_name(HOSTGROUPNAMES);
02767         add_macrox_name(SERVICEGROUPNAMES);
02768         add_macrox_name(HOSTACKAUTHORNAME);
02769         add_macrox_name(HOSTACKAUTHORALIAS);
02770         add_macrox_name(SERVICEACKAUTHORNAME);
02771         add_macrox_name(SERVICEACKAUTHORALIAS);
02772         add_macrox_name(MAXHOSTATTEMPTS);
02773         add_macrox_name(MAXSERVICEATTEMPTS);
02774         add_macrox_name(TOTALHOSTSERVICES);
02775         add_macrox_name(TOTALHOSTSERVICESOK);
02776         add_macrox_name(TOTALHOSTSERVICESWARNING);
02777         add_macrox_name(TOTALHOSTSERVICESUNKNOWN);
02778         add_macrox_name(TOTALHOSTSERVICESCRITICAL);
02779         add_macrox_name(HOSTGROUPNOTES);
02780         add_macrox_name(HOSTGROUPNOTESURL);
02781         add_macrox_name(HOSTGROUPACTIONURL);
02782         add_macrox_name(SERVICEGROUPNOTES);
02783         add_macrox_name(SERVICEGROUPNOTESURL);
02784         add_macrox_name(SERVICEGROUPACTIONURL);
02785         add_macrox_name(HOSTGROUPMEMBERS);
02786         add_macrox_name(SERVICEGROUPMEMBERS);
02787         add_macrox_name(CONTACTGROUPNAME);
02788         add_macrox_name(CONTACTGROUPALIAS);
02789         add_macrox_name(CONTACTGROUPMEMBERS);
02790         add_macrox_name(CONTACTGROUPNAMES);
02791         add_macrox_name(NOTIFICATIONRECIPIENTS);
02792         add_macrox_name(NOTIFICATIONAUTHOR);
02793         add_macrox_name(NOTIFICATIONAUTHORNAME);
02794         add_macrox_name(NOTIFICATIONAUTHORALIAS);
02795         add_macrox_name(NOTIFICATIONCOMMENT);
02796         add_macrox_name(EVENTSTARTTIME);
02797         add_macrox_name(HOSTPROBLEMID);
02798         add_macrox_name(LASTHOSTPROBLEMID);
02799         add_macrox_name(SERVICEPROBLEMID);
02800         add_macrox_name(LASTSERVICEPROBLEMID);
02801         add_macrox_name(ISVALIDTIME);
02802         add_macrox_name(NEXTVALIDTIME);
02803         add_macrox_name(LASTHOSTSTATE);
02804         add_macrox_name(LASTHOSTSTATEID);
02805         add_macrox_name(LASTSERVICESTATE);
02806         add_macrox_name(LASTSERVICESTATEID);
02807 
02808         return OK;
02809 }
02810 
02811 
02812 /******************************************************************/
02813 /********************* MACRO CLEANUP FUNCTIONS ********************/
02814 /******************************************************************/
02815 
02819 int free_macrox_names(void){
02820         register int x=0;
02821 
02822         /* free each macro name */
02823         for(x=0;x<MACRO_X_COUNT;x++)
02824                 my_free(macro_x_names[x]);
02825 
02826         return OK;
02827 }
02828 
02829 
02830 
02834 int clear_argv_macros_r(icinga_macros *mac){
02835         register int x=0;
02836 
02837         /* command argument macros */
02838         for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
02839                 my_free(mac->argv[x]);
02840 
02841         return OK;
02842 }
02843 
02844 int clear_argv_macros(void){
02845         return clear_argv_macros_r(&global_macros);
02846 }
02847 
02848 
02854 #define cp_macro(name) dest[MACRO_##name] = global_macros.x[MACRO_##name]
02855 void copy_constant_macros(char **dest){
02856         cp_macro(ADMINEMAIL);
02857         cp_macro(ADMINPAGER);
02858         cp_macro(MAINCONFIGFILE);
02859         cp_macro(STATUSDATAFILE);
02860         cp_macro(RETENTIONDATAFILE);
02861         cp_macro(OBJECTCACHEFILE);
02862         cp_macro(TEMPFILE);
02863         cp_macro(LOGFILE);
02864         cp_macro(RESOURCEFILE);
02865         cp_macro(COMMANDFILE);
02866         cp_macro(HOSTPERFDATAFILE);
02867         cp_macro(SERVICEPERFDATAFILE);
02868         cp_macro(PROCESSSTARTTIME);
02869         cp_macro(TEMPPATH);
02870         cp_macro(EVENTSTARTTIME);
02871 }
02872 #undef cp_macro
02873 
02878 int clear_volatile_macros_r(icinga_macros *mac){
02879         customvariablesmember *this_customvariablesmember=NULL;
02880         customvariablesmember *next_customvariablesmember=NULL;
02881         register int x=0;
02882 
02883         for(x=0;x<MACRO_X_COUNT;x++){
02884                 switch(x){
02885 
02886                 case MACRO_ADMINEMAIL:
02887                 case MACRO_ADMINPAGER:
02888                 case MACRO_MAINCONFIGFILE:
02889                 case MACRO_STATUSDATAFILE:
02890                 case MACRO_RETENTIONDATAFILE:
02891                 case MACRO_OBJECTCACHEFILE:
02892                 case MACRO_TEMPFILE:
02893                 case MACRO_LOGFILE:
02894                 case MACRO_RESOURCEFILE:
02895                 case MACRO_COMMANDFILE:
02896                 case MACRO_HOSTPERFDATAFILE:
02897                 case MACRO_SERVICEPERFDATAFILE:
02898                 case MACRO_PROCESSSTARTTIME:
02899                 case MACRO_TEMPPATH:
02900                 case MACRO_EVENTSTARTTIME:
02901                         /* these don't change during the course of monitoring, so no need to free them */
02902                         break;
02903                 default:
02904                         my_free(mac->x[x]);
02905                         break;
02906                         }
02907                 }
02908 
02909         /* contact address macros */
02910         for(x=0;x<MAX_CONTACT_ADDRESSES;x++)
02911                 my_free(mac->contactaddress[x]);
02912 
02913         /* clear macro pointers */
02914         mac->host_ptr=NULL;
02915         mac->hostgroup_ptr=NULL;
02916         mac->service_ptr=NULL;
02917         mac->servicegroup_ptr=NULL;
02918         mac->contact_ptr=NULL;
02919         mac->contactgroup_ptr=NULL;
02920 
02921         /* clear on-demand macro */
02922         my_free(mac->ondemand);
02923 
02924         /* clear ARGx macros */
02925         clear_argv_macros_r(mac);
02926 
02927         /* clear custom host variables */
02928         for(this_customvariablesmember=mac->custom_host_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
02929                 next_customvariablesmember=this_customvariablesmember->next;
02930                 my_free(this_customvariablesmember->variable_name);
02931                 my_free(this_customvariablesmember->variable_value);
02932                 my_free(this_customvariablesmember);
02933                 }
02934         mac->custom_host_vars=NULL;
02935 
02936         /* clear custom service variables */
02937         for(this_customvariablesmember=mac->custom_service_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
02938                 next_customvariablesmember=this_customvariablesmember->next;
02939                 my_free(this_customvariablesmember->variable_name);
02940                 my_free(this_customvariablesmember->variable_value);
02941                 my_free(this_customvariablesmember);
02942                 }
02943         mac->custom_service_vars=NULL;
02944 
02945         /* clear custom contact variables */
02946         for(this_customvariablesmember=mac->custom_contact_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
02947                 next_customvariablesmember=this_customvariablesmember->next;
02948                 my_free(this_customvariablesmember->variable_name);
02949                 my_free(this_customvariablesmember->variable_value);
02950                 my_free(this_customvariablesmember);
02951                 }
02952         mac->custom_contact_vars=NULL;
02953 
02954         return OK;
02955 }
02956 
02957 int clear_volatile_macros(void){
02958         return clear_volatile_macros_r(&global_macros);
02959 }
02960 
02961 
02966 int clear_service_macros_r(icinga_macros *mac){
02967         register int x;
02968         customvariablesmember *this_customvariablesmember=NULL;
02969         customvariablesmember *next_customvariablesmember=NULL;
02970 
02971         for(x=0;x<MACRO_X_COUNT;x++){
02972                 switch(x){
02973                 case MACRO_SERVICEDESC:
02974                 case MACRO_SERVICEDISPLAYNAME:
02975                 case MACRO_SERVICEOUTPUT:
02976                 case MACRO_LONGSERVICEOUTPUT:
02977                 case MACRO_SERVICEPERFDATA:
02978                 case MACRO_SERVICECHECKCOMMAND:
02979                 case MACRO_SERVICECHECKTYPE:
02980                 case MACRO_SERVICESTATETYPE:
02981                 case MACRO_SERVICESTATE:
02982                 case MACRO_SERVICEISVOLATILE:
02983                 case MACRO_SERVICESTATEID:
02984                 case MACRO_SERVICEATTEMPT:
02985                 case MACRO_MAXSERVICEATTEMPTS:
02986                 case MACRO_SERVICEEXECUTIONTIME:
02987                 case MACRO_SERVICELATENCY:
02988                 case MACRO_LASTSERVICECHECK:
02989                 case MACRO_LASTSERVICESTATECHANGE:
02990                 case MACRO_LASTSERVICEOK:
02991                 case MACRO_LASTSERVICEWARNING:
02992                 case MACRO_LASTSERVICEUNKNOWN:
02993                 case MACRO_LASTSERVICECRITICAL:
02994                 case MACRO_SERVICEDOWNTIME:
02995                 case MACRO_SERVICEPERCENTCHANGE:
02996                 case MACRO_SERVICEDURATIONSEC:
02997                 case MACRO_SERVICEDURATION:
02998                 case MACRO_SERVICENOTIFICATIONNUMBER:
02999                 case MACRO_SERVICENOTIFICATIONID:
03000                 case MACRO_SERVICEEVENTID:
03001                 case MACRO_LASTSERVICEEVENTID:
03002                 case MACRO_SERVICEACTIONURL:
03003                 case MACRO_SERVICENOTESURL:
03004                 case MACRO_SERVICENOTES:
03005                 case MACRO_SERVICEGROUPNAMES:
03006                 case MACRO_SERVICEPROBLEMID:
03007                 case MACRO_LASTSERVICEPROBLEMID:
03008 
03009                         my_free(mac->x[x]);
03010                         break;
03011                 default:
03012                         break;
03013                         }
03014                 }
03015 
03016         /* clear custom service variables */
03017         for(this_customvariablesmember=mac->custom_service_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
03018                 next_customvariablesmember=this_customvariablesmember->next;
03019                 my_free(this_customvariablesmember->variable_name);
03020                 my_free(this_customvariablesmember->variable_value);
03021                 my_free(this_customvariablesmember);
03022                 }
03023         mac->custom_service_vars=NULL;
03024 
03025         /* clear pointers */
03026         mac->service_ptr=NULL;
03027 
03028         return OK;
03029 }
03030 
03031 int clear_service_macros(void){
03032         return clear_service_macros_r(&global_macros);
03033 }
03034 
03035 
03040 int clear_host_macros_r(icinga_macros *mac){
03041         register int x;
03042         customvariablesmember *this_customvariablesmember=NULL;
03043         customvariablesmember *next_customvariablesmember=NULL;
03044 
03045         for(x=0;x<MACRO_X_COUNT;x++){
03046                 switch(x){
03047                 case MACRO_HOSTNAME:
03048                 case MACRO_HOSTDISPLAYNAME:
03049                 case MACRO_HOSTALIAS:
03050                 case MACRO_HOSTADDRESS:
03051                 case MACRO_HOSTADDRESS6:
03052                 case MACRO_HOSTSTATE:
03053                 case MACRO_HOSTSTATEID:
03054                 case MACRO_HOSTCHECKTYPE:
03055                 case MACRO_HOSTSTATETYPE:
03056                 case MACRO_HOSTOUTPUT:
03057                 case MACRO_LONGHOSTOUTPUT:
03058                 case MACRO_HOSTPERFDATA:
03059                 case MACRO_HOSTCHECKCOMMAND:
03060                 case MACRO_HOSTATTEMPT:
03061                 case MACRO_MAXHOSTATTEMPTS:
03062                 case MACRO_HOSTDOWNTIME:
03063                 case MACRO_HOSTPERCENTCHANGE:
03064                 case MACRO_HOSTDURATIONSEC:
03065                 case MACRO_HOSTDURATION:
03066                 case MACRO_HOSTEXECUTIONTIME:
03067                 case MACRO_HOSTLATENCY:
03068                 case MACRO_LASTHOSTCHECK:
03069                 case MACRO_LASTHOSTSTATECHANGE:
03070                 case MACRO_LASTHOSTUP:
03071                 case MACRO_LASTHOSTDOWN:
03072                 case MACRO_LASTHOSTUNREACHABLE:
03073                 case MACRO_HOSTNOTIFICATIONNUMBER:
03074                 case MACRO_HOSTNOTIFICATIONID:
03075                 case MACRO_HOSTEVENTID:
03076                 case MACRO_LASTHOSTEVENTID:
03077                 case MACRO_HOSTACTIONURL:
03078                 case MACRO_HOSTNOTESURL:
03079                 case MACRO_HOSTNOTES:
03080                 case MACRO_HOSTGROUPNAMES:
03081                 case MACRO_TOTALHOSTSERVICES:
03082                 case MACRO_TOTALHOSTSERVICESOK:
03083                 case MACRO_TOTALHOSTSERVICESWARNING:
03084                 case MACRO_TOTALHOSTSERVICESUNKNOWN:
03085                 case MACRO_TOTALHOSTSERVICESCRITICAL:
03086                 case MACRO_HOSTPROBLEMID:
03087                 case MACRO_LASTHOSTPROBLEMID:
03088 
03089                         my_free(mac->x[x]);
03090                         break;
03091                 default:
03092                         break;
03093                         }
03094                 }
03095 
03096         /* clear custom host variables */
03097         for(this_customvariablesmember=mac->custom_host_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
03098                 next_customvariablesmember=this_customvariablesmember->next;
03099                 my_free(this_customvariablesmember->variable_name);
03100                 my_free(this_customvariablesmember->variable_value);
03101                 my_free(this_customvariablesmember);
03102                 }
03103         mac->custom_host_vars=NULL;
03104 
03105         /* clear pointers */
03106         mac->host_ptr=NULL;
03107 
03108         return OK;
03109 }
03110 
03111 int clear_host_macros(void){
03112         return clear_host_macros_r(&global_macros);
03113 }
03114 
03115 
03120 int clear_hostgroup_macros_r(icinga_macros *mac){
03121         register int x;
03122 
03123         for(x=0;x<MACRO_X_COUNT;x++){
03124                 switch(x){
03125                 case MACRO_HOSTGROUPNAME:
03126                 case MACRO_HOSTGROUPALIAS:
03127                 case MACRO_HOSTGROUPMEMBERS:
03128                 case MACRO_HOSTGROUPACTIONURL:
03129                 case MACRO_HOSTGROUPNOTESURL:
03130                 case MACRO_HOSTGROUPNOTES:
03131                         my_free(mac->x[x]);
03132                         break;
03133                 default:
03134                         break;
03135                         }
03136                 }
03137 
03138         /* clear pointers */
03139         mac->hostgroup_ptr=NULL;
03140 
03141         return OK;
03142 }
03143 
03144 int clear_hostgroup_macros(void){
03145         return clear_hostgroup_macros_r(&global_macros);
03146 }
03147 
03148 
03153 int clear_servicegroup_macros_r(icinga_macros *mac){
03154         register int x;
03155 
03156         for(x=0;x<MACRO_X_COUNT;x++){
03157                 switch(x){
03158                 case MACRO_SERVICEGROUPNAME:
03159                 case MACRO_SERVICEGROUPALIAS:
03160                 case MACRO_SERVICEGROUPMEMBERS:
03161                 case MACRO_SERVICEGROUPACTIONURL:
03162                 case MACRO_SERVICEGROUPNOTESURL:
03163                 case MACRO_SERVICEGROUPNOTES:
03164                         my_free(mac->x[x]);
03165                         break;
03166                 default:
03167                         break;
03168                         }
03169                 }
03170 
03171         /* clear pointers */
03172         mac->servicegroup_ptr=NULL;
03173 
03174         return OK;
03175 }
03176 
03177 int clear_servicegroup_macros(void){
03178         return clear_servicegroup_macros_r(&global_macros);
03179 }
03180 
03181 
03186 int clear_contact_macros_r(icinga_macros *mac){
03187         register int x;
03188         customvariablesmember *this_customvariablesmember=NULL;
03189         customvariablesmember *next_customvariablesmember=NULL;
03190 
03191         for(x=0;x<MACRO_X_COUNT;x++){
03192                 switch(x){
03193                 case MACRO_CONTACTNAME:
03194                 case MACRO_CONTACTALIAS:
03195                 case MACRO_CONTACTEMAIL:
03196                 case MACRO_CONTACTPAGER:
03197                 case MACRO_CONTACTGROUPNAMES:
03198                         my_free(mac->x[x]);
03199                         break;
03200                 default:
03201                         break;
03202                         }
03203                 }
03204 
03205         /* clear contact addresses */
03206         for(x=0;x<MAX_CONTACT_ADDRESSES;x++)
03207                 my_free(mac->contactaddress[x]);
03208 
03209         /* clear custom contact variables */
03210         for(this_customvariablesmember=mac->custom_contact_vars;this_customvariablesmember!=NULL;this_customvariablesmember=next_customvariablesmember){
03211                 next_customvariablesmember=this_customvariablesmember->next;
03212                 my_free(this_customvariablesmember->variable_name);
03213                 my_free(this_customvariablesmember->variable_value);
03214                 my_free(this_customvariablesmember);
03215                 }
03216         mac->custom_contact_vars=NULL;
03217 
03218         /* clear pointers */
03219         mac->contact_ptr=NULL;
03220 
03221         return OK;
03222 }
03223 
03224 int clear_contact_macros(void){
03225         return clear_contact_macros_r(&global_macros);
03226 }
03227 
03228 
03233 int clear_contactgroup_macros_r(icinga_macros *mac){
03234         register int x;
03235 
03236         for(x=0;x<MACRO_X_COUNT;x++){
03237                 switch(x){
03238                 case MACRO_CONTACTGROUPNAME:
03239                 case MACRO_CONTACTGROUPALIAS:
03240                 case MACRO_CONTACTGROUPMEMBERS:
03241                         my_free(mac->x[x]);
03242                         break;
03243                 default:
03244                         break;
03245                         }
03246                 }
03247 
03248         /* clear pointers */
03249         mac->contactgroup_ptr=NULL;
03250 
03251         return OK;
03252 }
03253 
03254 int clear_contactgroup_macros(void){
03255         return clear_contactgroup_macros_r(&global_macros);
03256 }
03257 
03258 
03259 
03264 int clear_summary_macros_r(icinga_macros *mac){
03265         register int x;
03266 
03267         for(x=MACRO_TOTALHOSTSUP;x<=MACRO_TOTALSERVICEPROBLEMSUNHANDLED;x++)
03268                 my_free(mac->x[x]);
03269 
03270         return OK;
03271 }
03272 
03273 int clear_summary_macros(void){
03274         return clear_summary_macros_r(&global_macros);
03275 }
03276 
03277 
03278 /******************************************************************/
03279 /****************** ENVIRONMENT MACRO FUNCTIONS *******************/
03280 /******************************************************************/
03281 
03282 #ifdef NSCORE
03283 
03287 int set_all_macro_environment_vars_r(icinga_macros *mac, int set){
03288 
03289 
03290         if(enable_environment_macros==FALSE)
03291                 return ERROR;
03292 
03293         set_macrox_environment_vars_r(mac, set);
03294         set_argv_macro_environment_vars_r(mac, set);
03295         set_custom_macro_environment_vars_r(mac, set);
03296         set_contact_address_environment_vars_r(mac, set);
03297 
03298         return OK;
03299 }
03300 
03301 int set_all_macro_environment_vars(int set){
03302         return set_all_macro_environment_vars_r(&global_macros, set);
03303 }
03304 
03305 
03309 int set_macrox_environment_vars_r(icinga_macros *mac, int set){
03310         register int x=0;
03311         int free_macro=FALSE;
03312         int generate_macro=TRUE;
03313 
03314         /* set each of the macrox environment variables */
03315         for(x=0;x<MACRO_X_COUNT;x++){
03316 
03317                 free_macro=FALSE;
03318 
03319                 /* generate the macro value if it hasn't already been done */
03320                 /* THIS IS EXPENSIVE */
03321                 if(set==TRUE){
03322 
03323                         generate_macro=TRUE;
03324 
03325                         /* skip summary macro generation if lage installation tweaks are enabled */
03326                         if((x>=MACRO_TOTALHOSTSUP && x<=MACRO_TOTALSERVICEPROBLEMSUNHANDLED) && use_large_installation_tweaks==TRUE)
03327                                 generate_macro=FALSE;
03328 
03329                         if(mac->x[x]==NULL && generate_macro==TRUE)
03330                                 grab_macrox_value_r(mac,x,NULL,NULL,&mac->x[x],&free_macro);
03331                         }
03332 
03333                 /* set the value */
03334                 set_macro_environment_var(macro_x_names[x],mac->x[x],set);
03335                 }
03336 
03337         return OK;
03338 }
03339 
03340 int set_macrox_environment_vars(int set){
03341         return set_macrox_environment_vars_r(&global_macros, set);
03342 }
03343 
03344 
03348 int set_argv_macro_environment_vars_r(icinga_macros *mac, int set){
03349         char *macro_name=NULL;
03350         register int x=0;
03351 
03352         /* set each of the argv macro environment variables */
03353         for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
03354                 dummy=asprintf(&macro_name,"ARG%d",x+1);
03355                 set_macro_environment_var(macro_name,mac->argv[x],set);
03356                 my_free(macro_name);
03357                 }
03358 
03359         return OK;
03360 }
03361 
03362 int set_argv_macro_environment_vars(int set){
03363         return set_argv_macro_environment_vars_r(&global_macros, set);
03364 }
03365 
03369 int set_custom_macro_environment_vars_r(icinga_macros *mac, int set){
03370         customvariablesmember *temp_customvariablesmember=NULL;
03371         host *temp_host=NULL;
03372         service *temp_service=NULL;
03373         contact *temp_contact=NULL;
03374         char *customvarname=NULL;
03375 
03376         /***** CUSTOM HOST VARIABLES *****/
03377         /* generate variables and save them for later */
03378         if((temp_host=mac->host_ptr) && set==TRUE){
03379                 for(temp_customvariablesmember=temp_host->custom_variables;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next){
03380                         dummy=asprintf(&customvarname,"_HOST%s",temp_customvariablesmember->variable_name);
03381                         add_custom_variable_to_object(&mac->custom_host_vars,customvarname,temp_customvariablesmember->variable_value);
03382                         my_free(customvarname);
03383                         }
03384                 }
03385         /* set variables */
03386         for(temp_customvariablesmember=mac->custom_host_vars;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next){
03387                 set_macro_environment_var(temp_customvariablesmember->variable_name,clean_macro_chars(temp_customvariablesmember->variable_value,STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS),set);
03388                 }
03389 
03390         /***** CUSTOM SERVICE VARIABLES *****/
03391         /* generate variables and save them for later */
03392         if((temp_service=mac->service_ptr) && set==TRUE){
03393                 for(temp_customvariablesmember=temp_service->custom_variables;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next){
03394                         dummy=asprintf(&customvarname,"_SERVICE%s",temp_customvariablesmember->variable_name);
03395                         add_custom_variable_to_object(&mac->custom_service_vars,customvarname,temp_customvariablesmember->variable_value);
03396                         my_free(customvarname);
03397                         }
03398                 }
03399         /* set variables */
03400         for(temp_customvariablesmember=mac->custom_service_vars;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next)
03401                 set_macro_environment_var(temp_customvariablesmember->variable_name,clean_macro_chars(temp_customvariablesmember->variable_value,STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS),set);
03402 
03403         /***** CUSTOM CONTACT VARIABLES *****/
03404         /* generate variables and save them for later */
03405         if((temp_contact=mac->contact_ptr) && set==TRUE){
03406                 for(temp_customvariablesmember=temp_contact->custom_variables;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next){
03407                         dummy=asprintf(&customvarname,"_CONTACT%s",temp_customvariablesmember->variable_name);
03408                         add_custom_variable_to_object(&mac->custom_contact_vars,customvarname,temp_customvariablesmember->variable_value);
03409                         my_free(customvarname);
03410                         }
03411                 }
03412         /* set variables */
03413         for(temp_customvariablesmember=mac->custom_contact_vars;temp_customvariablesmember!=NULL;temp_customvariablesmember=temp_customvariablesmember->next)
03414                 set_macro_environment_var(temp_customvariablesmember->variable_name,clean_macro_chars(temp_customvariablesmember->variable_value,STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS),set);
03415 
03416         return OK;
03417 }
03418 
03419 int set_custom_macro_environment_vars(int set){
03420         return set_custom_macro_environment_vars_r(&global_macros, set);
03421 }
03422 
03423 
03427 int set_contact_address_environment_vars_r(icinga_macros *mac, int set){
03428         char *varname=NULL;
03429         register int x;
03430 
03431         /* these only get set during notifications */
03432         if(mac->contact_ptr==NULL)
03433                 return OK;
03434 
03435         for(x=0;x<MAX_CONTACT_ADDRESSES;x++){
03436                 dummy=asprintf(&varname,"CONTACTADDRESS%d",x);
03437                 set_macro_environment_var(varname,mac->contact_ptr->address[x],set);
03438                 my_free(varname);
03439                 }
03440 
03441         return OK;
03442 }
03443 
03444 int set_contact_address_environment_vars(int set){
03445         return set_contact_address_environment_vars_r(&global_macros, set);
03446 }
03447 
03448 
03452 int set_macro_environment_var(char *name, char *value, int set){
03453         char *env_macro_name=NULL;
03454 
03455         /* we won't mess with null variable names */
03456         if(name==NULL)
03457                 return ERROR;
03458 
03459         /* create environment var name */
03460         dummy=asprintf(&env_macro_name,"%s%s",MACRO_ENV_VAR_PREFIX,name);
03461 
03462         /* set or unset the environment variable */
03463         set_environment_var(env_macro_name,value,set);
03464 
03465         /* free allocated memory */
03466         my_free(env_macro_name);
03467 
03468         return OK;
03469 }
03470 
03471 #endif
03472 
03473 
 All Data Structures Files Functions Variables Typedefs Defines