Code

Fix for regex input of '|', being output causing problems with Nagios' parsing of
[nagiosplug.git] / contrib / check_cluster.c
1 /*****************************************************************************
2  *
3  * CHECK_CLUSTER.C - Host and Service Cluster Plugin for NetSaint
4  *
5  * Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)
6  * License: GPL
7  * Last Modified:   07-08-2000
8  *
9  * License:
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *****************************************************************************/
28 #include <stdio.h>
29 #include <stdlib.h>
31 #define OK              0
32 #define ERROR           -1
34 #define TRUE            1
35 #define FALSE           0
37 #define CHECK_SERVICES  1
38 #define CHECK_HOSTS     2
40 #define MAX_INPUT_BUFFER        1024
42 #define STATE_OK        0
43 #define STATE_WARNING   1
44 #define STATE_CRITICAL  2
45 #define STATE_UNKNOWN   3
47 typedef struct clustermember_struct{
48         char *host_name;
49         char *svc_description;
50         struct clustermember_struct *next;
51         }clustermember;
54 int check_cluster_status(void);
55 int add_clustermember(char *,char *);
56 void free_memory(void);
58 clustermember *clustermember_list=NULL;
60 int total_services_ok=0;
61 int total_services_warning=0;
62 int total_services_unknown=0;
63 int total_services_critical=0;
65 int total_hosts_up=0;
66 int total_hosts_down=0;
67 int total_hosts_unreachable=0;
69 char status_log[MAX_INPUT_BUFFER]="";
70 int warning_threshold=0;
71 int critical_threshold=0;
73 int check_type=CHECK_SERVICES;
76 int main(int argc, char **argv){
77         char input_buffer[MAX_INPUT_BUFFER];
78         char *host_name;
79         char *svc_description;
80         int return_code=STATE_OK;
81         int error=FALSE;
83         if(argc!=5){
85                 printf("Invalid arguments supplied\n");
86                 printf("\n");
88                 printf("Host/Service Cluster Plugin for NetSaint\n");
89                 printf("Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)\n");
90                 printf("Last Modified: 07-08-2000\n");
91                 printf("License: GPL\n");
92                 printf("\n");
93                 printf("Usage: %s <--service | --host> <status_log> <warn_threshold> <crit_threshold>\n",argv[0]);
94                 printf("\n");
95                 printf("Options:\n");
96                 printf("   --service        = Check service cluster status\n");
97                 printf("   --host           = Check host cluster status\n");
98                 printf("   <status_log>     = This is the location of the NetSaint status log\n");
99                 printf("   <warn_threshold> = This is the number of hosts or services in\n");
100                 printf("                      the cluster that must be in a non-OK state\n");
101                 printf("                      in order to result in a warning status level\n");
102                 printf("   <crit_threshold> = This is the number of hosts or services in\n");
103                 printf("                      the cluster that must be in a non-OK state\n");
104                 printf("                      in order to result in a critical status level\n");
105                 printf("\n");
106                 printf("Notes:\n");
107                 printf("Members of the host or service cluster are read from STDIN.\n");
108                 printf("One host or service can be specified per line, services must\n");
109                 printf("be in the format of <host_name>;<svc_description>\n");
110                 printf("\n");
112                 return STATE_UNKNOWN;
113                 }
115         /* see if we're checking a host or service clust */
116         if(!strcmp(argv[1],"--host"))
117                 check_type=CHECK_HOSTS;
118         else
119                 check_type=CHECK_SERVICES;
121         /* get the status log */
122         strncpy(status_log,argv[2],sizeof(status_log)-1);
123         status_log[sizeof(status_log)-1]='\x0';
125         /* get the warning and critical thresholds */
126         warning_threshold=atoi(argv[3]);
127         critical_threshold=atoi(argv[4]);
130         /* read all data from STDIN until there isn't anymore */
131         while(fgets(input_buffer,sizeof(input_buffer)-1,stdin)){
133                 if(feof(stdin))
134                         break;
136                 /*strip(input_buffer);*/
138                 if(!strcmp(input_buffer,""))
139                         continue;
141                 if(!strcmp(input_buffer,"\n"))
142                         continue;
144                 /* get the host name */
145                 if(check_type==CHECK_SERVICES)
146                         host_name=(char *)strtok(input_buffer,";");
147                 else
148                         host_name=(char *)strtok(input_buffer,"\n");
149                 if(host_name==NULL || !strcmp(host_name,"")){
150                         printf("Error: Host name is NULL!\n");
151                         continue;
152                         }
154                 if(check_type==CHECK_SERVICES){
156                         /* get the service description */
157                         svc_description=(char *)strtok(NULL,"\n");
158                         if(svc_description==NULL || !strcmp(svc_description,"")){
159                                 printf("Error: Service description is NULL!\n");
160                                 continue;
161                                 }
162                         }
164                 /* add the cluster member to the list in memory */
165                 if(add_clustermember(host_name,svc_description)!=OK)
166                         printf("Error: Could not add cluster member\n");
167 #ifdef DEBUG
168                 else
169                         printf("Added cluster member\n");
170 #endif
171                 }
174         /* check the status of the cluster */
175         if(check_cluster_status()==OK){
176         
177                 if(check_type==CHECK_SERVICES){
178                         if((total_services_warning+total_services_unknown+total_services_critical) >= critical_threshold)
179                                 return_code=STATE_CRITICAL;
180                         else if((total_services_warning+total_services_unknown+total_services_critical) >= warning_threshold)
181                                 return_code=STATE_WARNING;
182                         else
183                                 return_code=STATE_OK;
184                 
185                         printf("Service cluster %s: %d ok, %d warning, %d unknown, %d critical\n",(return_code==STATE_OK)?"ok":"problem",total_services_ok,total_services_warning,total_services_unknown,total_services_critical);
186                         }
187                 else{
188                         if((total_hosts_down+total_hosts_unreachable) >= critical_threshold)
189                                 return_code=STATE_CRITICAL;
190                         else if((total_hosts_down+total_hosts_unreachable) >= warning_threshold)
191                                 return_code=STATE_WARNING;
192                         else
193                                 return_code=STATE_OK;
195                         printf("Host cluster %s: %d up, %d down, %d unreachable\n",(return_code==STATE_OK)?"ok":"problem",total_hosts_up,total_hosts_down,total_hosts_unreachable);
196                         }
197                 }
198         else
199                 return_code=STATE_UNKNOWN;
201         free_memory();
203         return return_code;
204         }
208 int add_clustermember(char *hst,char *svc){
209         clustermember *new_clustermember;
211         new_clustermember=(clustermember *)malloc(sizeof(clustermember));
212         if(new_clustermember==NULL)
213                 return ERROR;
215         new_clustermember->host_name=NULL;
216         new_clustermember->svc_description=NULL;
218         if(hst!=NULL){
219                 new_clustermember->host_name=(char *)malloc(strlen(hst)+1);
220                 if(new_clustermember->host_name==NULL){
221                         free(new_clustermember);
222                         return ERROR;
223                         }
224                 strcpy(new_clustermember->host_name,hst);
225                 }
227         if(svc!=NULL){
228                 new_clustermember->svc_description=(char *)malloc(strlen(svc)+1);
229                 if(new_clustermember->svc_description==NULL){
230                         if(new_clustermember->host_name!=NULL)
231                                 free(new_clustermember->host_name);
232                         free(new_clustermember);
233                         return ERROR;
234                         }
235                 strcpy(new_clustermember->svc_description,svc);
236                 }
238         new_clustermember->next=clustermember_list;
239         clustermember_list=new_clustermember;
241         return OK;
242         }
245 void free_memory(void){
246         clustermember *this_clustermember;
247         clustermember *next_clustermember;
249         for(this_clustermember=clustermember_list;this_clustermember!=NULL;this_clustermember=next_clustermember){
250                 next_clustermember=this_clustermember->next;
251                 if(this_clustermember->host_name!=NULL)
252                         free(this_clustermember->host_name);            
253                 if(this_clustermember->svc_description!=NULL)
254                         free(this_clustermember->svc_description);
255                 free(this_clustermember);
256                 }
258         return;
259         }
263 int check_cluster_status(void){
264         FILE *fp;
265         clustermember *temp_clustermember;
266         char input_buffer[MAX_INPUT_BUFFER];
267         char matching_entry[MAX_INPUT_BUFFER];
269         fp=fopen(status_log,"r");
270         if(fp==NULL){
271                 printf("Error: Could not open status log '%s' for reading\n",status_log);
272                 return ERROR;
273                 }
275 #ifdef DEBUG
276         for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
277                 if(check_type==CHECK_HOSTS)
278                         printf("Cluster member: '%s'\n",temp_clustermember->host_name);
279                 else
280                         printf("Cluster member: '%s'/'%s'\n",temp_clustermember->host_name,temp_clustermember->svc_description);
281                 }
282 #endif
284         for(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp);!feof(fp);fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){
286                 /* this is a host entry */
287                 if(strstr(input_buffer,"] HOST;") && check_type==CHECK_HOSTS){
289                         /* this this a match? */
290                         for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
292                                 snprintf(matching_entry,sizeof(matching_entry)-1,";%s;",temp_clustermember->host_name);
294                                 if(strstr(input_buffer,matching_entry)){
295                                         if(strstr(input_buffer,";DOWN;"))
296                                                 total_hosts_down++;
297                                         else if(strstr(input_buffer,";UNREACHABLE;"))
298                                                 total_hosts_unreachable++;
299                                         else if(strstr(input_buffer,";UP;"))
300                                                 total_hosts_up++;
301                                         }
302                                 }
303                         
304                         }
306                 /* this is a service entry */
307                 else if(strstr(input_buffer,"] SERVICE;") && check_type==CHECK_SERVICES){
309                         /* this this a match? */
310                         for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
312                                 snprintf(matching_entry,sizeof(matching_entry)-1,";%s;%s;",temp_clustermember->host_name,temp_clustermember->svc_description);
314                                 if(strstr(input_buffer,matching_entry)){
315                                         if(strstr(input_buffer,";HOST DOWN;") || strstr(input_buffer,";UNREACHABLE;") || strstr(input_buffer,";CRITICAL;"))
316                                                 total_services_critical++;
317                                         else if(strstr(input_buffer,";WARNING;"))
318                                                 total_services_warning++;
319                                         else if(strstr(input_buffer,";UNKNOWN;"))
320                                                 total_services_unknown++;
321                                         else if(strstr(input_buffer,";OK;") || strstr(input_buffer,";RECOVERY;"))
322                                                 total_services_ok++;
323                                         }
324                                 }
325                 
326                         }
327                 }
329         fclose(fp);
331         return OK;
332         }