Code

5dbde9cedb8824995b9ec75768f78f863fe84c7f
[nagiosplug.git] / plugins / check_nwstat.c
1 /******************************************************************************
2  *
3  * Program: NetWare statistics plugin for Nagios
4  * License: GPL
5  *
6  * License Information:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  *
24  *****************************************************************************/
26 const char *progname = "check_nwstat";
27 #define REVISION "$Revision$"
28 #define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad"
30 #define SUMMARY "\
31 This plugin attempts to contact the MRTGEXT NLM running on a Novell server\n\
32 to gather the requested system information.\n"
34 #define OPTIONS "\
35 -H host [-v variable] [-w warning] [-c critical]\n\
36               [-p port] [-t timeout]"
38 #define LONGOPTIONS "\
39 -H, --hostname=HOST\n\
40   Name of the host to check\n\
41 -v, --variable=STRING\n\
42   Variable to check.  Valid variables include:\n\
43      LOAD1    = 1 minute average CPU load\n\
44      LOAD5    = 5 minute average CPU load\n\
45      LOAD15   = 15 minute average CPU load\n\
46      CONNS    = number of currently licensed connections\n\
47      VPF<vol> = percent free space on volume <vol>\n\
48      VKF<vol> = KB of free space on volume <vol>\n\
49      LTCH     = percent long term cache hits\n\
50      CBUFF    = current number of cache buffers\n\
51      CDBUFF   = current number of dirty cache buffers\n\
52      LRUM     = LRU sitting time in minutes\n\
53      DSDB     = check to see if DS Database is open\n\
54      DSVER    = NDS version\n\
55      LOGINS   = check to see if logins are enabled\n\
56      UPRB     = used packet receive buffers\n\
57      PUPRB    = percent (of max) used packet receive buffers\n\
58      SAPENTRIES = number of entries in the SAP table\n\
59      SAPENTRIES<n> = number of entries in the SAP table for SAP type <n>\n\
60      OFILES   = number of open files\n\
61      VPP<vol> = percent purgeable space on volume <vol>\n\
62      VKP<vol> = KB of purgeable space on volume <vol>\n\
63      VPNP<vol> = percent not yet purgeable space on volume <vol>\n\
64      VKNP<vol> = KB of not yet purgeable space on volume <vol>\n\
65      ABENDS   = number of abended threads (NW 5.x only)\n\
66      CSPROCS  = number of current service processes (NW 5.x only)\n\
67      TSYNC    = timesync status \n\
68      LRUS     = LRU sitting time in seconds\n\
69      DCB      = dirty cache buffers as a percentage of the total\n\
70      TCB      = dirty cache buffers as a percentage of the original\n\
71      UPTIME   = server uptime\n\
72      NLM:<nlm> = check if NLM is loaded and report version (e.g. \"NLM:TSANDS.NLM\")\n\
73 -w, --warning=INTEGER\n\
74   Threshold which will result in a warning status\n\
75 -c, --critical=INTEGER\n\
76   Threshold which will result in a critical status\n\
77 -p, --port=INTEGER\n\
78   Optional port number (default: %d)\n\
79 -t, --timeout=INTEGER\n\
80   Seconds before connection attempt times out (default: %d)\n\
81 -o, --osversion\n\
82   Include server version string in results\n\
83 -h, --help\n\
84   Print this help screen\n\
85 -V, --version\n\
86   Print version information\n"
88 #define DESCRIPTION "\
89 Notes:\n\
90 - This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\
91   extension for NetWare be loaded on the Novell servers you wish to check.\n\
92   (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\
93 - Values for critical thresholds should be lower than warning thresholds\n\
94   when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, \n\
95   TCB, LRUS and LRUM.\n"
97 #include "config.h"
98 #include "common.h"
99 #include "netutils.h"
100 #include "utils.h"
102 #define CHECK_NONE           0
103 #define CHECK_LOAD1          1 /* check 1 minute CPU load */
104 #define CHECK_LOAD5          2 /* check 5 minute CPU load */
105 #define CHECK_LOAD15         3 /* check 15 minute CPU load */
106 #define CHECK_CONNS          4 /* check number of connections */
107 #define CHECK_VPF            5 /* check % free space on volume */
108 #define CHECK_VKF            6 /* check KB free space on volume */
109 #define CHECK_LTCH           7 /* check long-term cache hit percentage */
110 #define CHECK_CBUFF          8 /* check total cache buffers */
111 #define CHECK_CDBUFF         9 /* check dirty cache buffers */
112 #define CHECK_LRUM          10 /* check LRU sitting time in minutes */
113 #define CHECK_DSDB          11 /* check to see if DS Database is open */
114 #define CHECK_LOGINS        12 /* check to see if logins are enabled */
115 #define CHECK_PUPRB         13 /* check % of used packet receive buffers */
116 #define CHECK_UPRB          14 /* check used packet receive buffers */
117 #define CHECK_SAPENTRIES    15 /* check SAP entries */
118 #define CHECK_OFILES        16 /* check number of open files */
119 #define CHECK_VKP           17 /* check KB purgeable space on volume */
120 #define CHECK_VPP           18 /* check % purgeable space on volume */
121 #define CHECK_VKNP          19 /* check KB not yet purgeable space on volume */
122 #define CHECK_VPNP          20 /* check % not yet purgeable space on volume */
123 #define CHECK_ABENDS        21 /* check abended thread count */
124 #define CHECK_CSPROCS       22 /* check number of current service processes */
125 #define CHECK_TSYNC         23 /* check timesync status 0=no 1=yes in sync to the network */
126 #define CHECK_LRUS          24 /* check LRU sitting time in seconds */
127 #define CHECK_DCB           25 /* check dirty cache buffers as a percentage of the total */
128 #define CHECK_TCB           26 /* check total cache buffers as a percentage of the original */
129 #define CHECK_DSVER         27 /* check NDS version */
130 #define CHECK_UPTIME        28 /* check server uptime */
131 #define CHECK_NLM           29 /* check NLM loaded */
133 #define PORT 9999
135 char *server_address=NULL;
136 char *volume_name=NULL;
137 char *nlm_name=NULL;
138 int server_port=PORT;
139 unsigned long warning_value=0L;
140 unsigned long critical_value=0L;
141 int check_warning_value=FALSE;
142 int check_critical_value=FALSE;
143 int check_netware_version=FALSE;
144 unsigned long vars_to_check=CHECK_NONE;
145 int sap_number=-1;
147 int process_arguments(int, char **);
148 void print_usage(void);
149 void print_help(void);
151 int main(int argc, char **argv){
152         int result;
153         char *send_buffer=NULL;
154         char recv_buffer[MAX_INPUT_BUFFER];
155         char *output_message=NULL;
156         char *temp_buffer=NULL;
157         char *netware_version=NULL;
159         int total_cache_buffers=0;
160         int dirty_cache_buffers=0;
161         int time_sync_status=0;
162         int open_files=0;
163         int abended_threads=0;
164         int max_service_processes=0;
165         int current_service_processes=0;
166         unsigned long free_disk_space=0L;
167         unsigned long total_disk_space=0L;
168         unsigned long purgeable_disk_space=0L;
169         unsigned long non_purgeable_disk_space=0L;
170         int percent_free_space=0;
171         int percent_purgeable_space=0;
172         int percent_non_purgeable_space=0;
173         unsigned long current_connections=0L;
174         unsigned long utilization=0L;
175         int cache_hits=0;
176         unsigned long cache_buffers=0L;
177         unsigned long lru_time=0L;
178         char uptime[MAX_INPUT_BUFFER];
179         int max_packet_receive_buffers=0;
180         int used_packet_receive_buffers=0;
181         unsigned long percent_used_packet_receive_buffers=0L;
182         int sap_entries=0;
184         if(process_arguments(argc,argv)==ERROR)
185                 usage("Could not parse arguments\n");
187         /* initialize alarm signal handling */
188         signal(SIGALRM,socket_timeout_alarm_handler);
190         /* set socket timeout */
191         alarm(socket_timeout);
192         
193         /* get OS version string */
194         if (check_netware_version==TRUE) {
195                 send_buffer = strscpy(send_buffer,"S19\r\n");
196                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
197                 if(result!=STATE_OK)
198                         return result;
199                 if(!strcmp(recv_buffer,"-1\n"))
200                         asprintf(&netware_version,"");
201                 else {
202                         recv_buffer[strlen(recv_buffer)-1]=0;
203                         asprintf(&netware_version,"NetWare %s: ",recv_buffer);
204                 }
205         } else
206                 asprintf(&netware_version,"");
209         /* check CPU load */
210         if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) {
211                         
212                 switch(vars_to_check){
213                 case CHECK_LOAD1:
214                         temp_buffer = strscpy(temp_buffer,"1");
215                         break;
216                 case CHECK_LOAD5:
217                         temp_buffer = strscpy(temp_buffer,"5");
218                         break;
219                 default:
220                         temp_buffer = strscpy(temp_buffer,"15");
221                         break;
222                 }
224                 asprintf(&send_buffer,"UTIL%s\r\n",temp_buffer);
225                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
226                 if(result!=STATE_OK)
227                         return result;
228                 utilization=strtoul(recv_buffer,NULL,10);
229                 send_buffer = strscpy(send_buffer,"UPTIME\r\n");
230                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
231                 if(result!=STATE_OK)
232                         return result;
233                 recv_buffer[strlen(recv_buffer)-1]=0;
234                 sprintf(uptime,"Up %s,",recv_buffer);
236                 if(check_critical_value==TRUE && utilization >= critical_value)
237                         result=STATE_CRITICAL;
238                 else if(check_warning_value==TRUE && utilization >= warning_value)
239                         result=STATE_WARNING;
241                 asprintf(&output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization);
243         /* check number of user connections */
244         } else if (vars_to_check==CHECK_CONNS) {
246                 send_buffer = strscpy(send_buffer,"CONNECT\r\n");
247                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
248                 if(result!=STATE_OK)
249                         return result;
250                 current_connections=strtoul(recv_buffer,NULL,10);
252                 if(check_critical_value==TRUE && current_connections >= critical_value)
253                         result=STATE_CRITICAL;
254                 else if(check_warning_value==TRUE && current_connections >= warning_value)
255                         result=STATE_WARNING;
256                 asprintf(&output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections);
258         /* check % long term cache hits */
259         } else if (vars_to_check==CHECK_LTCH) {
261                 send_buffer = strscpy(send_buffer,"S1\r\n");
262                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
263                 if(result!=STATE_OK)
264                         return result;
265                 cache_hits=atoi(recv_buffer);
267                 if(check_critical_value==TRUE && cache_hits <= critical_value)
268                         result=STATE_CRITICAL;
269                 else if(check_warning_value==TRUE && cache_hits <= warning_value)
270                         result=STATE_WARNING;
271                 asprintf(&output_message,"Long term cache hits = %d%%",cache_hits);
273         /* check cache buffers */
274         } else if (vars_to_check==CHECK_CBUFF) {
276                 send_buffer = strscpy(send_buffer,"S2\r\n");
277                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
278                 if(result!=STATE_OK)
279                         return result;
280                 cache_buffers=strtoul(recv_buffer,NULL,10);
282                 if(check_critical_value==TRUE && cache_buffers <= critical_value)
283                         result=STATE_CRITICAL;
284                 else if(check_warning_value==TRUE && cache_buffers <= warning_value)
285                         result=STATE_WARNING;
286                 asprintf(&output_message,"Total cache buffers = %lu",cache_buffers);
288         /* check dirty cache buffers */
289         } else if (vars_to_check==CHECK_CDBUFF) {
291                 send_buffer = strscpy(send_buffer,"S3\r\n");
292                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
293                 if(result!=STATE_OK)
294                         return result;
295                 cache_buffers=strtoul(recv_buffer,NULL,10);
297                 if(check_critical_value==TRUE && cache_buffers >= critical_value)
298                         result=STATE_CRITICAL;
299                 else if(check_warning_value==TRUE && cache_buffers >= warning_value)
300                         result=STATE_WARNING;
301                 asprintf(&output_message,"Dirty cache buffers = %lu",cache_buffers);
303         /* check LRU sitting time in minutes */
304         } else if (vars_to_check==CHECK_LRUM) {
306                 send_buffer = strscpy(send_buffer,"S5\r\n");
307                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
308                 if(result!=STATE_OK)
309                         return result;
310                 lru_time=strtoul(recv_buffer,NULL,10);
312                 if(check_critical_value==TRUE && lru_time <= critical_value)
313                         result=STATE_CRITICAL;
314                 else if(check_warning_value==TRUE && lru_time <= warning_value)
315                         result=STATE_WARNING;
316                 asprintf(&output_message,"LRU sitting time = %lu minutes",lru_time);
319         /* check KB free space on volume */
320         } else if (vars_to_check==CHECK_VKF) {
322                 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
323                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
324                 if(result!=STATE_OK)
325                         return result;
327                 if (!strcmp(recv_buffer,"-1\n")) {
328                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
329                         result=STATE_CRITICAL;
330                 }       else {
331                         free_disk_space=strtoul(recv_buffer,NULL,10);
332                         if(check_critical_value==TRUE && free_disk_space <= critical_value)
333                                 result=STATE_CRITICAL;
334                         else if(check_warning_value==TRUE && free_disk_space <= warning_value)
335                                 result=STATE_WARNING;
336                         asprintf(&output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name);
337                 }
339         /* check % free space on volume */
340         } else if (vars_to_check==CHECK_VPF) {
342                 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
343                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
344                 if(result!=STATE_OK)
345                         return result;
347                 if(!strcmp(recv_buffer,"-1\n")){
349                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
350                         result=STATE_CRITICAL;
352                 } else {
354                         free_disk_space=strtoul(recv_buffer,NULL,10);
356                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
357                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
358                         if(result!=STATE_OK)
359                                 return result;
360                         total_disk_space=strtoul(recv_buffer,NULL,10);
362                         percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0);
364                         if(check_critical_value==TRUE && percent_free_space <= critical_value)
365                                 result=STATE_CRITICAL;
366                         else if(check_warning_value==TRUE && percent_free_space <= warning_value)
367                                 result=STATE_WARNING;
368                         free_disk_space/=1024;
369                         asprintf(&output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name);
370                 }
372         /* check to see if DS Database is open or closed */
373         } else if(vars_to_check==CHECK_DSDB) {
375                 send_buffer = strscpy(send_buffer,"S11\r\n");
376                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
377                 if(result!=STATE_OK)
378                         return result;
379                 if(atoi(recv_buffer)==1)
380                         result=STATE_OK;
381                 else
382                         result=STATE_WARNING;
383  
384                 send_buffer = strscpy(send_buffer,"S13\r\n");
385                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
386                 temp_buffer=strtok(recv_buffer,"\r\n");
387  
388                 asprintf(&output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer);
390         /* check to see if logins are enabled */
391         } else if (vars_to_check==CHECK_LOGINS) {
393                 send_buffer = strscpy(send_buffer,"S12\r\n");
394                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
395                 if(result!=STATE_OK)
396                         return result;
397                 if(atoi(recv_buffer)==1)
398                         result=STATE_OK;
399                 else
400                         result=STATE_WARNING;
401  
402                 asprintf(&output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled");
404         /* check packet receive buffers */
405         } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) {
406  
407                 asprintf(&send_buffer,"S15\r\n",volume_name);
408                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
409                 if(result!=STATE_OK)
410                         return result;
412                 used_packet_receive_buffers=atoi(recv_buffer);
414                 asprintf(&send_buffer,"S16\r\n",volume_name);
415                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
416                 if(result!=STATE_OK)
417                         return result;
419                 max_packet_receive_buffers=atoi(recv_buffer);
420  
421                 percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0);
423                 if(vars_to_check==CHECK_UPRB){
424                         if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value)
425                                 result=STATE_CRITICAL;
426                         else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value)
427                                 result=STATE_WARNING;
428                 } else {
429                         if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value)
430                                 result=STATE_CRITICAL;
431                         else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value)
432                                 result=STATE_WARNING;
433                 }
434  
435                 asprintf(&output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers);
437         /* check SAP table entries */
438         } else if (vars_to_check==CHECK_SAPENTRIES) {
440                 if(sap_number==-1)
441                         asprintf(&send_buffer,"S9\r\n");
442                 else
443                         asprintf(&send_buffer,"S9.%d\r\n",sap_number);
444                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
445                 if(result!=STATE_OK)
446                         return result;
447  
448                 sap_entries=atoi(recv_buffer);
449  
450                 if(check_critical_value==TRUE && sap_entries >= critical_value)
451                         result=STATE_CRITICAL;
452                 else if(check_warning_value==TRUE && sap_entries >= warning_value)
453                         result=STATE_WARNING;
455                 if(sap_number==-1)
456                         asprintf(&output_message,"%d entries in SAP table",sap_entries);
457                 else
458                         asprintf(&output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number);
460         /* check KB purgeable space on volume */
461         } else if (vars_to_check==CHECK_VKP) {
463                 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
464                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
465                 if(result!=STATE_OK)
466                         return result;
468                 if (!strcmp(recv_buffer,"-1\n")) {
469                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
470                         result=STATE_CRITICAL;
471                 } else {
472                         purgeable_disk_space=strtoul(recv_buffer,NULL,10);
473                         if(check_critical_value==TRUE && purgeable_disk_space >= critical_value)
474                                 result=STATE_CRITICAL;
475                         else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value)
476                                 result=STATE_WARNING;
477                         asprintf(&output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name);
478                 }
480         /* check % purgeable space on volume */
481         } else if (vars_to_check==CHECK_VPP) {
483                 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
484                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
485                 if(result!=STATE_OK)
486                         return result;
488                 if(!strcmp(recv_buffer,"-1\n")){
490                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
491                         result=STATE_CRITICAL;
493                 } else {
495                         purgeable_disk_space=strtoul(recv_buffer,NULL,10);
497                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
498                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
499                         if(result!=STATE_OK)
500                                 return result;
501                         total_disk_space=strtoul(recv_buffer,NULL,10);
503                         percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0);
505                         if(check_critical_value==TRUE && percent_purgeable_space >= critical_value)
506                                 result=STATE_CRITICAL;
507                         else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value)
508                                 result=STATE_WARNING;
509                         purgeable_disk_space/=1024;
510                         asprintf(&output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name);
511                 }
513         /* check KB not yet purgeable space on volume */
514         } else if (vars_to_check==CHECK_VKNP) {
516                 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
517                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
518                 if(result!=STATE_OK)
519                         return result;
521                 if (!strcmp(recv_buffer,"-1\n")) {
522                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
523                         result=STATE_CRITICAL;
524                 } else {
525                         non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
526                         if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value)
527                                 result=STATE_CRITICAL;
528                         else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value)
529                                 result=STATE_WARNING;
530                         asprintf(&output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name);
531                 }
533         /* check % not yet purgeable space on volume */
534         } else if (vars_to_check==CHECK_VPNP) {
536                 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
537                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
538                 if(result!=STATE_OK)
539                         return result;
541                 if(!strcmp(recv_buffer,"-1\n")){
543                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
544                         result=STATE_CRITICAL;
546                 } else {
548                         non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
550                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
551                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
552                         if(result!=STATE_OK)
553                                 return result;
554                         total_disk_space=strtoul(recv_buffer,NULL,10);
556                         percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0);
558                         if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value)
559                                 result=STATE_CRITICAL;
560                         else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value)
561                                 result=STATE_WARNING;
562                         purgeable_disk_space/=1024;
563                         asprintf(&output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name);
564                 }
566         /* check # of open files */
567         } else if (vars_to_check==CHECK_OFILES) {
569                 asprintf(&send_buffer,"S18\r\n");
570                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
571                 if(result!=STATE_OK)
572                         return result;
573  
574                 open_files=atoi(recv_buffer);
575  
576                 if(check_critical_value==TRUE && open_files >= critical_value)
577                         result=STATE_CRITICAL;
578                 else if(check_warning_value==TRUE && open_files >= warning_value)
579                         result=STATE_WARNING;
581                 asprintf(&output_message,"%d open files",open_files);
583         /* check # of abended threads (Netware 5.x only) */
584         } else if (vars_to_check==CHECK_ABENDS) {
586                 asprintf(&send_buffer,"S17\r\n");
587                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
588                 if(result!=STATE_OK)
589                         return result;
590  
591                 abended_threads=atoi(recv_buffer);
592  
593                 if(check_critical_value==TRUE && abended_threads >= critical_value)
594                         result=STATE_CRITICAL;
595                 else if(check_warning_value==TRUE && abended_threads >= warning_value)
596                         result=STATE_WARNING;
598                 asprintf(&output_message,"%d abended threads",abended_threads);
600         /* check # of current service processes (Netware 5.x only) */
601         } else if (vars_to_check==CHECK_CSPROCS) {
603                 asprintf(&send_buffer,"S20\r\n");
604                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
605                 if(result!=STATE_OK)
606                         return result;
607  
608                 max_service_processes=atoi(recv_buffer);
609  
610                 asprintf(&send_buffer,"S21\r\n");
611                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
612                 if(result!=STATE_OK)
613                         return result;
614  
615                 current_service_processes=atoi(recv_buffer);
616  
617                 if(check_critical_value==TRUE && current_service_processes >= critical_value)
618                         result=STATE_CRITICAL;
619                 else if(check_warning_value==TRUE && current_service_processes >= warning_value)
620                         result=STATE_WARNING;
622                 asprintf(&output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes);
624         /* check # Timesync Status */
625         } else if (vars_to_check==CHECK_TSYNC) {
627                 asprintf(&send_buffer,"S22\r\n");
628                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
629                 if(result!=STATE_OK)
630                         return result;
632                 time_sync_status=atoi(recv_buffer);
634                 if(time_sync_status==0) {
635                         result=STATE_CRITICAL;
636                         asprintf(&output_message,"Critical: Time not in sync with network!");
637                 }
638                 else {
639                         asprintf(&output_message,"OK! Time in sync with network!");
640                 }
642         /* check LRU sitting time in secondss */
643         } else if (vars_to_check==CHECK_LRUS) {
645                 send_buffer = strscpy(send_buffer,"S4\r\n");
646                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
647                 if(result!=STATE_OK)
648                         return result;
649                 lru_time=strtoul(recv_buffer,NULL,10);
651                 if(check_critical_value==TRUE && lru_time <= critical_value)
652                         result=STATE_CRITICAL;
653                 else if(check_warning_value==TRUE && lru_time <= warning_value)
654                         result=STATE_WARNING;
655                 asprintf(&output_message,"LRU sitting time = %lu seconds",lru_time);
658         /* check % dirty cache buffers as a percentage of the total*/
659         } else if (vars_to_check==CHECK_DCB) {
661                 send_buffer = strscpy(send_buffer,"S6\r\n");
662                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
663                 if(result!=STATE_OK)
664                         return result;
665                 dirty_cache_buffers=atoi(recv_buffer);
667                 if(check_critical_value==TRUE && dirty_cache_buffers <= critical_value)
668                         result=STATE_CRITICAL;
669                 else if(check_warning_value==TRUE && dirty_cache_buffers <= warning_value)
670                         result=STATE_WARNING;
671                 asprintf(&output_message,"dirty cache buffers = %d%% of the total",dirty_cache_buffers);
673         /* check % total cache buffers as a percentage of the original*/
674         } else if (vars_to_check==CHECK_TCB) {
676                 send_buffer = strscpy(send_buffer,"S7\r\n");
677                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
678                 if(result!=STATE_OK)
679                         return result;
680                 total_cache_buffers=atoi(recv_buffer);
682                 if(check_critical_value==TRUE && total_cache_buffers <= critical_value)
683                         result=STATE_CRITICAL;
684                 else if(check_warning_value==TRUE && total_cache_buffers <= warning_value)
685                         result=STATE_WARNING;
686                 asprintf(&output_message,"total cache buffers = %d%% of the original",total_cache_buffers);
687                 
688         } else if (vars_to_check==CHECK_DSVER) {
689                 asprintf(&send_buffer,"S13\r\n");
690                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
691                 if(result!=STATE_OK)
692                         return result;
694                 recv_buffer[strlen(recv_buffer)-1]=0;
696                 asprintf(&output_message,"NDS Version %s",recv_buffer);
698         } else if (vars_to_check==CHECK_UPTIME) {
699                 asprintf(&send_buffer,"UPTIME\r\n");
700                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
701                 if(result!=STATE_OK)
702                         return result;
704                 recv_buffer[strlen(recv_buffer)-1]=0;
706                 asprintf(&output_message,"Up %s",recv_buffer);
708         } else if (vars_to_check==CHECK_NLM) {
709                 asprintf(&send_buffer,"S24:%s\r\n",nlm_name);
710                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
711                 if(result!=STATE_OK)
712                         return result;
714                 recv_buffer[strlen(recv_buffer)-1]=0;
715                 if(strcmp(recv_buffer,"-1")) {
716                         asprintf(&output_message,"Module %s version %s is loaded",nlm_name,recv_buffer);
717                 } else {
718                         result=STATE_CRITICAL;
719                         asprintf(&output_message,"Module %s is not loaded",nlm_name);
720                 }
722         } else {
724                 output_message = strscpy(output_message,"Nothing to check!\n");
725                 result=STATE_UNKNOWN;
727         }
729         /* reset timeout */
730         alarm(0);
732         printf("%s%s\n",netware_version,output_message);
734         return result;
738 /* process command-line arguments */
739 int process_arguments(int argc, char **argv){
740         int c;
742         int option_index = 0;
743         static struct option long_options[] =
744         { 
745                 {"port",     required_argument,0,'p'},
746                 {"timeout",  required_argument,0,'t'},
747                 {"critical", required_argument,0,'c'},
748                 {"warning",  required_argument,0,'w'},
749                 {"variable", required_argument,0,'v'},
750                 {"hostname", required_argument,0,'H'},
751                 {"osversion",no_argument,      0,'o'},
752                 {"version",  no_argument,      0,'V'},
753                 {"help",     no_argument,      0,'h'},
754                 {0,0,0,0}
755         };
757         /* no options were supplied */
758         if(argc<2) return ERROR;
760         /* backwards compatibility */
761         if (! is_option(argv[1])) {
762                 server_address=argv[1];
763                 argv[1]=argv[0];
764                 argv=&argv[1];
765                 argc--;
766         }
768   for (c=1;c<argc;c++) {
769     if(strcmp("-to",argv[c])==0)
770       strcpy(argv[c],"-t");
771     else if (strcmp("-wv",argv[c])==0)
772       strcpy(argv[c],"-w");
773     else if (strcmp("-cv",argv[c])==0)
774       strcpy(argv[c],"-c");
775         }
777         while (1){
778                 c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index);
780                 if (c==-1||c==EOF||c==1)
781                         break;
783                 switch (c)
784                         {
785                         case '?': /* print short usage statement if args not parsable */
786                                 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
787                                 print_usage();
788                                 exit(STATE_UNKNOWN);
789                         case 'h': /* help */
790                                 print_help();
791                                 exit(STATE_OK);
792                         case 'V': /* version */
793                                 print_revision(progname,"$Revision$");
794                                 exit(STATE_OK);
795                         case 'H': /* hostname */
796                                 server_address=optarg;
797                                 break;
798                         case 'o': /* display nos version */
799                                 check_netware_version=TRUE;
800                                 break;
801                         case 'p': /* port */
802                                 if (is_intnonneg(optarg))
803                                         server_port=atoi(optarg);
804                                 else
805                                         terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",progname);
806                                 break;
807                         case 'v':
808                                 if(strlen(optarg)<3)
809                                         return ERROR;
810                                 if(!strcmp(optarg,"LOAD1"))
811                                         vars_to_check=CHECK_LOAD1;
812                                 else if(!strcmp(optarg,"LOAD5"))
813                                         vars_to_check=CHECK_LOAD5;
814                                 else if(!strcmp(optarg,"LOAD15"))
815                                         vars_to_check=CHECK_LOAD15;
816                                 else if(!strcmp(optarg,"CONNS"))
817                                         vars_to_check=CHECK_CONNS;
818                                 else if(!strcmp(optarg,"LTCH"))
819                                         vars_to_check=CHECK_LTCH;
820                                 else if(!strcmp(optarg,"DCB"))
821                                         vars_to_check=CHECK_DCB;
822                                 else if(!strcmp(optarg,"TCB"))
823                                         vars_to_check=CHECK_TCB;
824                                 else if(!strcmp(optarg,"CBUFF"))
825                                         vars_to_check=CHECK_CBUFF;
826                                 else if(!strcmp(optarg,"CDBUFF"))
827                                         vars_to_check=CHECK_CDBUFF;
828                                 else if(!strcmp(optarg,"LRUM"))
829                                         vars_to_check=CHECK_LRUM;
830                                 else if(!strcmp(optarg,"LRUS"))
831                                         vars_to_check=CHECK_LRUS;
832                                 else if(strncmp(optarg,"VPF",3)==0){
833                                         vars_to_check=CHECK_VPF;
834                                         volume_name = strscpy(volume_name,optarg+3);
835                                         if(!strcmp(volume_name,""))
836                                                 volume_name = strscpy(volume_name,"SYS");
837                                 }
838                                 else if(strncmp(optarg,"VKF",3)==0){
839                                         vars_to_check=CHECK_VKF;
840                                         volume_name = strscpy(volume_name,optarg+3);
841                                         if(!strcmp(volume_name,""))
842                                                 volume_name = strscpy(volume_name,"SYS");
843                                 }
844                                 else if(!strcmp(optarg,"DSDB"))
845                                         vars_to_check=CHECK_DSDB;
846                                 else if(!strcmp(optarg,"LOGINS"))
847                                         vars_to_check=CHECK_LOGINS;
848                                 else if(!strcmp(optarg,"UPRB"))
849                                         vars_to_check=CHECK_UPRB;
850                                 else if(!strcmp(optarg,"PUPRB"))
851                                         vars_to_check=CHECK_PUPRB;
852                                 else if(!strncmp(optarg,"SAPENTRIES",10)){
853                                         vars_to_check=CHECK_SAPENTRIES;
854                                         if(strlen(optarg)>10)
855                                                 sap_number=atoi(optarg+10);
856                                         else
857                                                 sap_number=-1;
858                                 }
859                                 else if(!strcmp(optarg,"OFILES"))
860                                         vars_to_check=CHECK_OFILES;
861                                 else if(strncmp(optarg,"VKP",3)==0){
862                                         vars_to_check=CHECK_VKP;
863                                         volume_name = strscpy(volume_name,optarg+3);
864                                         if(!strcmp(volume_name,""))
865                                                 volume_name = strscpy(volume_name,"SYS");
866                                 }
867                                 else if(strncmp(optarg,"VPP",3)==0){
868                                         vars_to_check=CHECK_VPP;
869                                         volume_name = strscpy(volume_name,optarg+3);
870                                         if(!strcmp(volume_name,""))
871                                                 volume_name = strscpy(volume_name,"SYS");
872                                 }
873                                 else if(strncmp(optarg,"VKNP",4)==0){
874                                         vars_to_check=CHECK_VKNP;
875                                         volume_name = strscpy(volume_name,optarg+4);
876                                         if(!strcmp(volume_name,""))
877                                                 volume_name = strscpy(volume_name,"SYS");
878                                 }
879                                 else if(strncmp(optarg,"VPNP",4)==0){
880                                         vars_to_check=CHECK_VPNP;
881                                         volume_name = strscpy(volume_name,optarg+4);
882                                         if(!strcmp(volume_name,""))
883                                                 volume_name = strscpy(volume_name,"SYS");
884                                 }
885                                 else if(!strcmp(optarg,"ABENDS"))
886                                         vars_to_check=CHECK_ABENDS;
887                                 else if(!strcmp(optarg,"CSPROCS"))
888                                         vars_to_check=CHECK_CSPROCS;
889                                 else if(!strcmp(optarg,"TSYNC"))
890                                         vars_to_check=CHECK_TSYNC;
891                                 else if(!strcmp(optarg,"DSVER"))
892                                         vars_to_check=CHECK_DSVER;
893                                 else if(!strcmp(optarg,"UPTIME"))
894                                         vars_to_check=CHECK_UPTIME;
895                                 else if(strncmp(optarg,"NLM:",4)==0) {
896                                         vars_to_check=CHECK_NLM;
897                                         nlm_name=strscpy(nlm_name,optarg+4);
898                                 }
899                                 else
900                                         return ERROR;
901                                 break;
902                         case 'w': /* warning threshold */
903                                 warning_value=strtoul(optarg,NULL,10);
904                                 check_warning_value=TRUE;
905                                 break;
906                         case 'c': /* critical threshold */
907                                 critical_value=strtoul(optarg,NULL,10);
908                                 check_critical_value=TRUE;
909                                 break;
910                         case 't': /* timeout */
911                                 socket_timeout=atoi(optarg);
912                                 if(socket_timeout<=0)
913                                         return ERROR;
914                         }
916         }
918         return OK;
922 void print_usage(void)
924         printf
925                 ("Usage:\n"
926                  " %s %s\n"
927                  " %s (-h | --help) for detailed help\n"
928                  " %s (-V | --version) for version information\n",
929                  progname, OPTIONS, progname, progname);
932 void print_help(void)
934         print_revision (progname, REVISION);
935         printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
936         print_usage();
937         printf
938                 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
939                  PORT, DEFAULT_SOCKET_TIMEOUT);
940         support ();