Code

Added DSVER and UPTIME checks (Phil Randal - 737617)
[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 -w, --warning=INTEGER\n\
73   Threshold which will result in a warning status\n\
74 -c, --critical=INTEGER\n\
75   Threshold which will result in a critical status\n\
76 -p, --port=INTEGER\n\
77   Optional port number (default: %d)\n\
78 -t, --timeout=INTEGER\n\
79   Seconds before connection attempt times out (default: %d)\n\
80 -o, --osversion\n\
81   Include server version string in results\n\
82 -h, --help\n\
83   Print this help screen\n\
84 -V, --version\n\
85   Print version information\n"
87 #define DESCRIPTION "\
88 Notes:\n\
89 - This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\
90   extension for NetWare be loaded on the Novell servers you wish to check.\n\
91   (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\
92 - Values for critical thresholds should be lower than warning thresholds\n\
93   when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, \n\
94   TCB, LRUS and LRUM.\n"
96 #include "config.h"
97 #include "common.h"
98 #include "netutils.h"
99 #include "utils.h"
101 #define CHECK_NONE           0
102 #define CHECK_LOAD1          1 /* check 1 minute CPU load */
103 #define CHECK_LOAD5          2 /* check 5 minute CPU load */
104 #define CHECK_LOAD15         3 /* check 15 minute CPU load */
105 #define CHECK_CONNS          4 /* check number of connections */
106 #define CHECK_VPF            5 /* check % free space on volume */
107 #define CHECK_VKF            6 /* check KB free space on volume */
108 #define CHECK_LTCH           7 /* check long-term cache hit percentage */
109 #define CHECK_CBUFF          8 /* check total cache buffers */
110 #define CHECK_CDBUFF         9 /* check dirty cache buffers */
111 #define CHECK_LRUM          10 /* check LRU sitting time in minutes */
112 #define CHECK_DSDB          11 /* check to see if DS Database is open */
113 #define CHECK_LOGINS        12 /* check to see if logins are enabled */
114 #define CHECK_PUPRB         13 /* check % of used packet receive buffers */
115 #define CHECK_UPRB          14 /* check used packet receive buffers */
116 #define CHECK_SAPENTRIES    15 /* check SAP entries */
117 #define CHECK_OFILES        16 /* check number of open files */
118 #define CHECK_VKP           17 /* check KB purgeable space on volume */
119 #define CHECK_VPP           18 /* check % purgeable space on volume */
120 #define CHECK_VKNP          19 /* check KB not yet purgeable space on volume */
121 #define CHECK_VPNP          20 /* check % not yet purgeable space on volume */
122 #define CHECK_ABENDS        21 /* check abended thread count */
123 #define CHECK_CSPROCS       22 /* check number of current service processes */
124 #define CHECK_TSYNC         23 /* check timesync status 0=no 1=yes in sync to the network */
125 #define CHECK_LRUS          24 /* check LRU sitting time in seconds */
126 #define CHECK_DCB           25 /* check dirty cache buffers as a percentage of the total */
127 #define CHECK_TCB           26 /* check total cache buffers as a percentage of the original */
128 #define CHECK_DSVER         27 /* check NDS version */
129 #define CHECK_UPTIME        28 /* check server uptime */
131 #define PORT 9999
133 char *server_address=NULL;
134 char *volume_name=NULL;
135 int server_port=PORT;
136 unsigned long warning_value=0L;
137 unsigned long critical_value=0L;
138 int check_warning_value=FALSE;
139 int check_critical_value=FALSE;
140 int check_netware_version=FALSE;
141 unsigned long vars_to_check=CHECK_NONE;
142 int sap_number=-1;
144 int process_arguments(int, char **);
145 void print_usage(void);
146 void print_help(void);
148 int main(int argc, char **argv){
149         int result;
150         char *send_buffer=NULL;
151         char recv_buffer[MAX_INPUT_BUFFER];
152         char *output_message=NULL;
153         char *temp_buffer=NULL;
154         char *netware_version=NULL;
156         int total_cache_buffers=0;
157         int dirty_cache_buffers=0;
158         int time_sync_status=0;
159         int open_files=0;
160         int abended_threads=0;
161         int max_service_processes=0;
162         int current_service_processes=0;
163         unsigned long free_disk_space=0L;
164         unsigned long total_disk_space=0L;
165         unsigned long purgeable_disk_space=0L;
166         unsigned long non_purgeable_disk_space=0L;
167         int percent_free_space=0;
168         int percent_purgeable_space=0;
169         int percent_non_purgeable_space=0;
170         unsigned long current_connections=0L;
171         unsigned long utilization=0L;
172         int cache_hits=0;
173         unsigned long cache_buffers=0L;
174         unsigned long lru_time=0L;
175         char uptime[MAX_INPUT_BUFFER];
176         int max_packet_receive_buffers=0;
177         int used_packet_receive_buffers=0;
178         unsigned long percent_used_packet_receive_buffers=0L;
179         int sap_entries=0;
181         if(process_arguments(argc,argv)==ERROR)
182                 usage("Could not parse arguments\n");
184         /* initialize alarm signal handling */
185         signal(SIGALRM,socket_timeout_alarm_handler);
187         /* set socket timeout */
188         alarm(socket_timeout);
189         
190         /* get OS version string */
191         if (check_netware_version==TRUE) {
192                 send_buffer = strscpy(send_buffer,"S19\r\n");
193                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
194                 if(result!=STATE_OK)
195                         return result;
196                 if(!strcmp(recv_buffer,"-1\n"))
197                         asprintf(&netware_version,"");
198                 else {
199                         recv_buffer[strlen(recv_buffer)-1]=0;
200                         asprintf(&netware_version,"NetWare %s: ",recv_buffer);
201                 }
202         } else
203                 asprintf(&netware_version,"");
206         /* check CPU load */
207         if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) {
208                         
209                 switch(vars_to_check){
210                 case CHECK_LOAD1:
211                         temp_buffer = strscpy(temp_buffer,"1");
212                         break;
213                 case CHECK_LOAD5:
214                         temp_buffer = strscpy(temp_buffer,"5");
215                         break;
216                 default:
217                         temp_buffer = strscpy(temp_buffer,"15");
218                         break;
219                 }
221                 asprintf(&send_buffer,"UTIL%s\r\n",temp_buffer);
222                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
223                 if(result!=STATE_OK)
224                         return result;
225                 utilization=strtoul(recv_buffer,NULL,10);
226                 send_buffer = strscpy(send_buffer,"UPTIME\r\n");
227                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
228                 if(result!=STATE_OK)
229                         return result;
230                 recv_buffer[strlen(recv_buffer)-1]=0;
231                 sprintf(uptime,"Up %s,",recv_buffer);
233                 if(check_critical_value==TRUE && utilization >= critical_value)
234                         result=STATE_CRITICAL;
235                 else if(check_warning_value==TRUE && utilization >= warning_value)
236                         result=STATE_WARNING;
238                 asprintf(&output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization);
240         /* check number of user connections */
241         } else if (vars_to_check==CHECK_CONNS) {
243                 send_buffer = strscpy(send_buffer,"CONNECT\r\n");
244                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
245                 if(result!=STATE_OK)
246                         return result;
247                 current_connections=strtoul(recv_buffer,NULL,10);
249                 if(check_critical_value==TRUE && current_connections >= critical_value)
250                         result=STATE_CRITICAL;
251                 else if(check_warning_value==TRUE && current_connections >= warning_value)
252                         result=STATE_WARNING;
253                 asprintf(&output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections);
255         /* check % long term cache hits */
256         } else if (vars_to_check==CHECK_LTCH) {
258                 send_buffer = strscpy(send_buffer,"S1\r\n");
259                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
260                 if(result!=STATE_OK)
261                         return result;
262                 cache_hits=atoi(recv_buffer);
264                 if(check_critical_value==TRUE && cache_hits <= critical_value)
265                         result=STATE_CRITICAL;
266                 else if(check_warning_value==TRUE && cache_hits <= warning_value)
267                         result=STATE_WARNING;
268                 asprintf(&output_message,"Long term cache hits = %d%%",cache_hits);
270         /* check cache buffers */
271         } else if (vars_to_check==CHECK_CBUFF) {
273                 send_buffer = strscpy(send_buffer,"S2\r\n");
274                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
275                 if(result!=STATE_OK)
276                         return result;
277                 cache_buffers=strtoul(recv_buffer,NULL,10);
279                 if(check_critical_value==TRUE && cache_buffers <= critical_value)
280                         result=STATE_CRITICAL;
281                 else if(check_warning_value==TRUE && cache_buffers <= warning_value)
282                         result=STATE_WARNING;
283                 asprintf(&output_message,"Total cache buffers = %lu",cache_buffers);
285         /* check dirty cache buffers */
286         } else if (vars_to_check==CHECK_CDBUFF) {
288                 send_buffer = strscpy(send_buffer,"S3\r\n");
289                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
290                 if(result!=STATE_OK)
291                         return result;
292                 cache_buffers=strtoul(recv_buffer,NULL,10);
294                 if(check_critical_value==TRUE && cache_buffers >= critical_value)
295                         result=STATE_CRITICAL;
296                 else if(check_warning_value==TRUE && cache_buffers >= warning_value)
297                         result=STATE_WARNING;
298                 asprintf(&output_message,"Dirty cache buffers = %lu",cache_buffers);
300         /* check LRU sitting time in minutes */
301         } else if (vars_to_check==CHECK_LRUM) {
303                 send_buffer = strscpy(send_buffer,"S5\r\n");
304                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
305                 if(result!=STATE_OK)
306                         return result;
307                 lru_time=strtoul(recv_buffer,NULL,10);
309                 if(check_critical_value==TRUE && lru_time <= critical_value)
310                         result=STATE_CRITICAL;
311                 else if(check_warning_value==TRUE && lru_time <= warning_value)
312                         result=STATE_WARNING;
313                 asprintf(&output_message,"LRU sitting time = %lu minutes",lru_time);
316         /* check KB free space on volume */
317         } else if (vars_to_check==CHECK_VKF) {
319                 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
320                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
321                 if(result!=STATE_OK)
322                         return result;
324                 if (!strcmp(recv_buffer,"-1\n")) {
325                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
326                         result=STATE_CRITICAL;
327                 }       else {
328                         free_disk_space=strtoul(recv_buffer,NULL,10);
329                         if(check_critical_value==TRUE && free_disk_space <= critical_value)
330                                 result=STATE_CRITICAL;
331                         else if(check_warning_value==TRUE && free_disk_space <= warning_value)
332                                 result=STATE_WARNING;
333                         asprintf(&output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name);
334                 }
336         /* check % free space on volume */
337         } else if (vars_to_check==CHECK_VPF) {
339                 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
340                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
341                 if(result!=STATE_OK)
342                         return result;
344                 if(!strcmp(recv_buffer,"-1\n")){
346                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
347                         result=STATE_CRITICAL;
349                 } else {
351                         free_disk_space=strtoul(recv_buffer,NULL,10);
353                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
354                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
355                         if(result!=STATE_OK)
356                                 return result;
357                         total_disk_space=strtoul(recv_buffer,NULL,10);
359                         percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0);
361                         if(check_critical_value==TRUE && percent_free_space <= critical_value)
362                                 result=STATE_CRITICAL;
363                         else if(check_warning_value==TRUE && percent_free_space <= warning_value)
364                                 result=STATE_WARNING;
365                         free_disk_space/=1024;
366                         asprintf(&output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name);
367                 }
369         /* check to see if DS Database is open or closed */
370         } else if(vars_to_check==CHECK_DSDB) {
372                 send_buffer = strscpy(send_buffer,"S11\r\n");
373                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
374                 if(result!=STATE_OK)
375                         return result;
376                 if(atoi(recv_buffer)==1)
377                         result=STATE_OK;
378                 else
379                         result=STATE_WARNING;
380  
381                 send_buffer = strscpy(send_buffer,"S13\r\n");
382                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
383                 temp_buffer=strtok(recv_buffer,"\r\n");
384  
385                 asprintf(&output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer);
387         /* check to see if logins are enabled */
388         } else if (vars_to_check==CHECK_LOGINS) {
390                 send_buffer = strscpy(send_buffer,"S12\r\n");
391                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
392                 if(result!=STATE_OK)
393                         return result;
394                 if(atoi(recv_buffer)==1)
395                         result=STATE_OK;
396                 else
397                         result=STATE_WARNING;
398  
399                 asprintf(&output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled");
401         /* check packet receive buffers */
402         } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) {
403  
404                 asprintf(&send_buffer,"S15\r\n",volume_name);
405                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
406                 if(result!=STATE_OK)
407                         return result;
409                 used_packet_receive_buffers=atoi(recv_buffer);
411                 asprintf(&send_buffer,"S16\r\n",volume_name);
412                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
413                 if(result!=STATE_OK)
414                         return result;
416                 max_packet_receive_buffers=atoi(recv_buffer);
417  
418                 percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0);
420                 if(vars_to_check==CHECK_UPRB){
421                         if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value)
422                                 result=STATE_CRITICAL;
423                         else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value)
424                                 result=STATE_WARNING;
425                 } else {
426                         if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value)
427                                 result=STATE_CRITICAL;
428                         else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value)
429                                 result=STATE_WARNING;
430                 }
431  
432                 asprintf(&output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers);
434         /* check SAP table entries */
435         } else if (vars_to_check==CHECK_SAPENTRIES) {
437                 if(sap_number==-1)
438                         asprintf(&send_buffer,"S9\r\n");
439                 else
440                         asprintf(&send_buffer,"S9.%d\r\n",sap_number);
441                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
442                 if(result!=STATE_OK)
443                         return result;
444  
445                 sap_entries=atoi(recv_buffer);
446  
447                 if(check_critical_value==TRUE && sap_entries >= critical_value)
448                         result=STATE_CRITICAL;
449                 else if(check_warning_value==TRUE && sap_entries >= warning_value)
450                         result=STATE_WARNING;
452                 if(sap_number==-1)
453                         asprintf(&output_message,"%d entries in SAP table",sap_entries);
454                 else
455                         asprintf(&output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number);
457         /* check KB purgeable space on volume */
458         } else if (vars_to_check==CHECK_VKP) {
460                 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
461                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
462                 if(result!=STATE_OK)
463                         return result;
465                 if (!strcmp(recv_buffer,"-1\n")) {
466                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
467                         result=STATE_CRITICAL;
468                 } else {
469                         purgeable_disk_space=strtoul(recv_buffer,NULL,10);
470                         if(check_critical_value==TRUE && purgeable_disk_space >= critical_value)
471                                 result=STATE_CRITICAL;
472                         else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value)
473                                 result=STATE_WARNING;
474                         asprintf(&output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name);
475                 }
477         /* check % purgeable space on volume */
478         } else if (vars_to_check==CHECK_VPP) {
480                 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
481                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
482                 if(result!=STATE_OK)
483                         return result;
485                 if(!strcmp(recv_buffer,"-1\n")){
487                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
488                         result=STATE_CRITICAL;
490                 } else {
492                         purgeable_disk_space=strtoul(recv_buffer,NULL,10);
494                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
495                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
496                         if(result!=STATE_OK)
497                                 return result;
498                         total_disk_space=strtoul(recv_buffer,NULL,10);
500                         percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0);
502                         if(check_critical_value==TRUE && percent_purgeable_space >= critical_value)
503                                 result=STATE_CRITICAL;
504                         else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value)
505                                 result=STATE_WARNING;
506                         purgeable_disk_space/=1024;
507                         asprintf(&output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name);
508                 }
510         /* check KB not yet purgeable space on volume */
511         } else if (vars_to_check==CHECK_VKNP) {
513                 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
514                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
515                 if(result!=STATE_OK)
516                         return result;
518                 if (!strcmp(recv_buffer,"-1\n")) {
519                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
520                         result=STATE_CRITICAL;
521                 } else {
522                         non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
523                         if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value)
524                                 result=STATE_CRITICAL;
525                         else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value)
526                                 result=STATE_WARNING;
527                         asprintf(&output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name);
528                 }
530         /* check % not yet purgeable space on volume */
531         } else if (vars_to_check==CHECK_VPNP) {
533                 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
534                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
535                 if(result!=STATE_OK)
536                         return result;
538                 if(!strcmp(recv_buffer,"-1\n")){
540                         asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
541                         result=STATE_CRITICAL;
543                 } else {
545                         non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
547                         asprintf(&send_buffer,"VKS%s\r\n",volume_name);
548                         result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
549                         if(result!=STATE_OK)
550                                 return result;
551                         total_disk_space=strtoul(recv_buffer,NULL,10);
553                         percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0);
555                         if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value)
556                                 result=STATE_CRITICAL;
557                         else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value)
558                                 result=STATE_WARNING;
559                         purgeable_disk_space/=1024;
560                         asprintf(&output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name);
561                 }
563         /* check # of open files */
564         } else if (vars_to_check==CHECK_OFILES) {
566                 asprintf(&send_buffer,"S18\r\n");
567                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
568                 if(result!=STATE_OK)
569                         return result;
570  
571                 open_files=atoi(recv_buffer);
572  
573                 if(check_critical_value==TRUE && open_files >= critical_value)
574                         result=STATE_CRITICAL;
575                 else if(check_warning_value==TRUE && open_files >= warning_value)
576                         result=STATE_WARNING;
578                 asprintf(&output_message,"%d open files",open_files);
580         /* check # of abended threads (Netware 5.x only) */
581         } else if (vars_to_check==CHECK_ABENDS) {
583                 asprintf(&send_buffer,"S17\r\n");
584                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
585                 if(result!=STATE_OK)
586                         return result;
587  
588                 abended_threads=atoi(recv_buffer);
589  
590                 if(check_critical_value==TRUE && abended_threads >= critical_value)
591                         result=STATE_CRITICAL;
592                 else if(check_warning_value==TRUE && abended_threads >= warning_value)
593                         result=STATE_WARNING;
595                 asprintf(&output_message,"%d abended threads",abended_threads);
597         /* check # of current service processes (Netware 5.x only) */
598         } else if (vars_to_check==CHECK_CSPROCS) {
600                 asprintf(&send_buffer,"S20\r\n");
601                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
602                 if(result!=STATE_OK)
603                         return result;
604  
605                 max_service_processes=atoi(recv_buffer);
606  
607                 asprintf(&send_buffer,"S21\r\n");
608                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
609                 if(result!=STATE_OK)
610                         return result;
611  
612                 current_service_processes=atoi(recv_buffer);
613  
614                 if(check_critical_value==TRUE && current_service_processes >= critical_value)
615                         result=STATE_CRITICAL;
616                 else if(check_warning_value==TRUE && current_service_processes >= warning_value)
617                         result=STATE_WARNING;
619                 asprintf(&output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes);
621         /* check # Timesync Status */
622         } else if (vars_to_check==CHECK_TSYNC) {
624                 asprintf(&send_buffer,"S22\r\n");
625                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
626                 if(result!=STATE_OK)
627                         return result;
629                 time_sync_status=atoi(recv_buffer);
631                 if(time_sync_status==0) {
632                         result=STATE_CRITICAL;
633                         asprintf(&output_message,"Critical: Time not in sync with network!");
634                 }
635                 else {
636                         asprintf(&output_message,"OK! Time in sync with network!");
637                 }
639         /* check LRU sitting time in secondss */
640         } else if (vars_to_check==CHECK_LRUS) {
642                 send_buffer = strscpy(send_buffer,"S4\r\n");
643                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
644                 if(result!=STATE_OK)
645                         return result;
646                 lru_time=strtoul(recv_buffer,NULL,10);
648                 if(check_critical_value==TRUE && lru_time <= critical_value)
649                         result=STATE_CRITICAL;
650                 else if(check_warning_value==TRUE && lru_time <= warning_value)
651                         result=STATE_WARNING;
652                 asprintf(&output_message,"LRU sitting time = %lu seconds",lru_time);
655         /* check % dirty cache buffers as a percentage of the total*/
656         } else if (vars_to_check==CHECK_DCB) {
658                 send_buffer = strscpy(send_buffer,"S6\r\n");
659                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
660                 if(result!=STATE_OK)
661                         return result;
662                 dirty_cache_buffers=atoi(recv_buffer);
664                 if(check_critical_value==TRUE && dirty_cache_buffers <= critical_value)
665                         result=STATE_CRITICAL;
666                 else if(check_warning_value==TRUE && dirty_cache_buffers <= warning_value)
667                         result=STATE_WARNING;
668                 asprintf(&output_message,"dirty cache buffers = %d%% of the total",dirty_cache_buffers);
670         /* check % total cache buffers as a percentage of the original*/
671         } else if (vars_to_check==CHECK_TCB) {
673                 send_buffer = strscpy(send_buffer,"S7\r\n");
674                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
675                 if(result!=STATE_OK)
676                         return result;
677                 total_cache_buffers=atoi(recv_buffer);
679                 if(check_critical_value==TRUE && total_cache_buffers <= critical_value)
680                         result=STATE_CRITICAL;
681                 else if(check_warning_value==TRUE && total_cache_buffers <= warning_value)
682                         result=STATE_WARNING;
683                 asprintf(&output_message,"total cache buffers = %d%% of the original",total_cache_buffers);
684                 
685         } else if (vars_to_check==CHECK_DSVER) {
686                 asprintf(&send_buffer,"S13\r\n");
687                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
688                 if(result!=STATE_OK)
689                         return result;
691                 recv_buffer[strlen(recv_buffer)-1]=0;
693                 asprintf(&output_message,"NDS Version %s",recv_buffer);
695         } else if (vars_to_check==CHECK_UPTIME) {
696                 asprintf(&send_buffer,"UPTIME\r\n");
697                 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
698                 if(result!=STATE_OK)
699                         return result;
701                 recv_buffer[strlen(recv_buffer)-1]=0;
703                 asprintf(&output_message,"Up %s",recv_buffer);
705         } else {
707                 output_message = strscpy(output_message,"Nothing to check!\n");
708                 result=STATE_UNKNOWN;
710         }
712         /* reset timeout */
713         alarm(0);
715         printf("%s%s\n",netware_version,output_message);
717         return result;
721 /* process command-line arguments */
722 int process_arguments(int argc, char **argv){
723         int c;
725         int option_index = 0;
726         static struct option long_options[] =
727         { 
728                 {"port",     required_argument,0,'p'},
729                 {"timeout",  required_argument,0,'t'},
730                 {"critical", required_argument,0,'c'},
731                 {"warning",  required_argument,0,'w'},
732                 {"variable", required_argument,0,'v'},
733                 {"hostname", required_argument,0,'H'},
734                 {"osversion",no_argument,      0,'o'},
735                 {"version",  no_argument,      0,'V'},
736                 {"help",     no_argument,      0,'h'},
737                 {0,0,0,0}
738         };
740         /* no options were supplied */
741         if(argc<2) return ERROR;
743         /* backwards compatibility */
744         if (! is_option(argv[1])) {
745                 server_address=argv[1];
746                 argv[1]=argv[0];
747                 argv=&argv[1];
748                 argc--;
749         }
751   for (c=1;c<argc;c++) {
752     if(strcmp("-to",argv[c])==0)
753       strcpy(argv[c],"-t");
754     else if (strcmp("-wv",argv[c])==0)
755       strcpy(argv[c],"-w");
756     else if (strcmp("-cv",argv[c])==0)
757       strcpy(argv[c],"-c");
758         }
760         while (1){
761                 c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index);
763                 if (c==-1||c==EOF||c==1)
764                         break;
766                 switch (c)
767                         {
768                         case '?': /* print short usage statement if args not parsable */
769                                 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
770                                 print_usage();
771                                 exit(STATE_UNKNOWN);
772                         case 'h': /* help */
773                                 print_help();
774                                 exit(STATE_OK);
775                         case 'V': /* version */
776                                 print_revision(progname,"$Revision$");
777                                 exit(STATE_OK);
778                         case 'H': /* hostname */
779                                 server_address=optarg;
780                                 break;
781                         case 'o': /* display nos version */
782                                 check_netware_version=TRUE;
783                                 break;
784                         case 'p': /* port */
785                                 if (is_intnonneg(optarg))
786                                         server_port=atoi(optarg);
787                                 else
788                                         terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",progname);
789                                 break;
790                         case 'v':
791                                 if(strlen(optarg)<3)
792                                         return ERROR;
793                                 if(!strcmp(optarg,"LOAD1"))
794                                         vars_to_check=CHECK_LOAD1;
795                                 else if(!strcmp(optarg,"LOAD5"))
796                                         vars_to_check=CHECK_LOAD5;
797                                 else if(!strcmp(optarg,"LOAD15"))
798                                         vars_to_check=CHECK_LOAD15;
799                                 else if(!strcmp(optarg,"CONNS"))
800                                         vars_to_check=CHECK_CONNS;
801                                 else if(!strcmp(optarg,"LTCH"))
802                                         vars_to_check=CHECK_LTCH;
803                                 else if(!strcmp(optarg,"DCB"))
804                                         vars_to_check=CHECK_DCB;
805                                 else if(!strcmp(optarg,"TCB"))
806                                         vars_to_check=CHECK_TCB;
807                                 else if(!strcmp(optarg,"CBUFF"))
808                                         vars_to_check=CHECK_CBUFF;
809                                 else if(!strcmp(optarg,"CDBUFF"))
810                                         vars_to_check=CHECK_CDBUFF;
811                                 else if(!strcmp(optarg,"LRUM"))
812                                         vars_to_check=CHECK_LRUM;
813                                 else if(!strcmp(optarg,"LRUS"))
814                                         vars_to_check=CHECK_LRUS;
815                                 else if(strncmp(optarg,"VPF",3)==0){
816                                         vars_to_check=CHECK_VPF;
817                                         volume_name = strscpy(volume_name,optarg+3);
818                                         if(!strcmp(volume_name,""))
819                                                 volume_name = strscpy(volume_name,"SYS");
820                                 }
821                                 else if(strncmp(optarg,"VKF",3)==0){
822                                         vars_to_check=CHECK_VKF;
823                                         volume_name = strscpy(volume_name,optarg+3);
824                                         if(!strcmp(volume_name,""))
825                                                 volume_name = strscpy(volume_name,"SYS");
826                                 }
827                                 else if(!strcmp(optarg,"DSDB"))
828                                         vars_to_check=CHECK_DSDB;
829                                 else if(!strcmp(optarg,"LOGINS"))
830                                         vars_to_check=CHECK_LOGINS;
831                                 else if(!strcmp(optarg,"UPRB"))
832                                         vars_to_check=CHECK_UPRB;
833                                 else if(!strcmp(optarg,"PUPRB"))
834                                         vars_to_check=CHECK_PUPRB;
835                                 else if(!strncmp(optarg,"SAPENTRIES",10)){
836                                         vars_to_check=CHECK_SAPENTRIES;
837                                         if(strlen(optarg)>10)
838                                                 sap_number=atoi(optarg+10);
839                                         else
840                                                 sap_number=-1;
841                                 }
842                                 else if(!strcmp(optarg,"OFILES"))
843                                         vars_to_check=CHECK_OFILES;
844                                 else if(strncmp(optarg,"VKP",3)==0){
845                                         vars_to_check=CHECK_VKP;
846                                         volume_name = strscpy(volume_name,optarg+3);
847                                         if(!strcmp(volume_name,""))
848                                                 volume_name = strscpy(volume_name,"SYS");
849                                 }
850                                 else if(strncmp(optarg,"VPP",3)==0){
851                                         vars_to_check=CHECK_VPP;
852                                         volume_name = strscpy(volume_name,optarg+3);
853                                         if(!strcmp(volume_name,""))
854                                                 volume_name = strscpy(volume_name,"SYS");
855                                 }
856                                 else if(strncmp(optarg,"VKNP",4)==0){
857                                         vars_to_check=CHECK_VKNP;
858                                         volume_name = strscpy(volume_name,optarg+4);
859                                         if(!strcmp(volume_name,""))
860                                                 volume_name = strscpy(volume_name,"SYS");
861                                 }
862                                 else if(strncmp(optarg,"VPNP",4)==0){
863                                         vars_to_check=CHECK_VPNP;
864                                         volume_name = strscpy(volume_name,optarg+4);
865                                         if(!strcmp(volume_name,""))
866                                                 volume_name = strscpy(volume_name,"SYS");
867                                 }
868                                 else if(!strcmp(optarg,"ABENDS"))
869                                         vars_to_check=CHECK_ABENDS;
870                                 else if(!strcmp(optarg,"CSPROCS"))
871                                         vars_to_check=CHECK_CSPROCS;
872                                 else if(!strcmp(optarg,"TSYNC"))
873                                         vars_to_check=CHECK_TSYNC;
874                                 else if(!strcmp(optarg,"DSVER"))
875                                         vars_to_check=CHECK_DSVER;
876                                 else if(!strcmp(optarg,"UPTIME"))
877                                         vars_to_check=CHECK_UPTIME;
878                                 else
879                                         return ERROR;
880                                 break;
881                         case 'w': /* warning threshold */
882                                 warning_value=strtoul(optarg,NULL,10);
883                                 check_warning_value=TRUE;
884                                 break;
885                         case 'c': /* critical threshold */
886                                 critical_value=strtoul(optarg,NULL,10);
887                                 check_critical_value=TRUE;
888                                 break;
889                         case 't': /* timeout */
890                                 socket_timeout=atoi(optarg);
891                                 if(socket_timeout<=0)
892                                         return ERROR;
893                         }
895         }
897         return OK;
901 void print_usage(void)
903         printf
904                 ("Usage:\n"
905                  " %s %s\n"
906                  " %s (-h | --help) for detailed help\n"
907                  " %s (-V | --version) for version information\n",
908                  progname, OPTIONS, progname, progname);
911 void print_help(void)
913         print_revision (progname, REVISION);
914         printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
915         print_usage();
916         printf
917                 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
918                  PORT, DEFAULT_SOCKET_TIMEOUT);
919         support ();