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 LOGINS = check to see if logins are enabled\n\
55 UPRB = used packet receive buffers\n\
56 PUPRB = percent (of max) used packet receive buffers\n\
57 SAPENTRIES = number of entries in the SAP table\n\
58 SAPENTRIES<n> = number of entries in the SAP table for SAP type <n>\n\
59 OFILES = number of open files\n\
60 VPP<vol> = percent purgeable space on volume <vol>\n\
61 VKP<vol> = KB of purgeable space on volume <vol>\n\
62 VPNP<vol> = percent not yet purgeable space on volume <vol>\n\
63 VKNP<vol> = KB of not yet purgeable space on volume <vol>\n\
64 ABENDS = number of abended threads (NW 5.x only)\n\
65 CSPROCS = number of current service processes (NW 5.x only)\n\
66 TSYNC = timesync status \n\
67 LRUS = LRU sitting time in seconds\n\
68 DCB = dirty cache buffers as a percentage of the total\n\
69 TCB = dirty cache buffers as a percentage of the original\n\
70 -w, --warning=INTEGER\n\
71 Threshold which will result in a warning status\n\
72 -c, --critical=INTEGER\n\
73 Threshold which will result in a critical status\n\
74 -p, --port=INTEGER\n\
75 Optional port number (default: %d)\n\
76 -t, --timeout=INTEGER\n\
77 Seconds before connection attempt times out (default: %d)\n\
78 -o, --osversion\n\
79 Include server version string in results\n\
80 -h, --help\n\
81 Print this help screen\n\
82 -V, --version\n\
83 Print version information\n"
85 #define DESCRIPTION "\
86 Notes:\n\
87 - This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\
88 extension for NetWare be loaded on the Novell servers you wish to check.\n\
89 (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\
90 - Values for critical thresholds should be lower than warning thresholds\n\
91 when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, \n\
92 TCB, LRUS and LRUM.\n"
94 #include "config.h"
95 #include "common.h"
96 #include "netutils.h"
97 #include "utils.h"
99 #define CHECK_NONE 0
100 #define CHECK_LOAD1 1 /* check 1 minute CPU load */
101 #define CHECK_LOAD5 2 /* check 5 minute CPU load */
102 #define CHECK_LOAD15 3 /* check 15 minute CPU load */
103 #define CHECK_CONNS 4 /* check number of connections */
104 #define CHECK_VPF 5 /* check % free space on volume */
105 #define CHECK_VKF 6 /* check KB free space on volume */
106 #define CHECK_LTCH 7 /* check long-term cache hit percentage */
107 #define CHECK_CBUFF 8 /* check total cache buffers */
108 #define CHECK_CDBUFF 9 /* check dirty cache buffers */
109 #define CHECK_LRUM 10 /* check LRU sitting time in minutes */
110 #define CHECK_DSDB 11 /* check to see if DS Database is open */
111 #define CHECK_LOGINS 12 /* check to see if logins are enabled */
112 #define CHECK_PUPRB 13 /* check % of used packet receive buffers */
113 #define CHECK_UPRB 14 /* check used packet receive buffers */
114 #define CHECK_SAPENTRIES 15 /* check SAP entries */
115 #define CHECK_OFILES 16 /* check number of open files */
116 #define CHECK_VKP 17 /* check KB purgeable space on volume */
117 #define CHECK_VPP 18 /* check % purgeable space on volume */
118 #define CHECK_VKNP 19 /* check KB not yet purgeable space on volume */
119 #define CHECK_VPNP 20 /* check % not yet purgeable space on volume */
120 #define CHECK_ABENDS 21 /* check abended thread count */
121 #define CHECK_CSPROCS 22 /* check number of current service processes */
122 #define CHECK_TSYNC 23 /* check timesync status 0=no 1=yes in sync to the network */
123 #define CHECK_LRUS 24 /* check LRU sitting time in seconds */
124 #define CHECK_DCB 25 /* check dirty cache buffers as a percentage of the total */
125 #define CHECK_TCB 26 /* check total cache buffers as a percentage of the original */
127 #define PORT 9999
129 char *server_address=NULL;
130 char *volume_name=NULL;
131 int server_port=PORT;
132 unsigned long warning_value=0L;
133 unsigned long critical_value=0L;
134 int check_warning_value=FALSE;
135 int check_critical_value=FALSE;
136 int check_netware_version=FALSE;
137 unsigned long vars_to_check=CHECK_NONE;
138 int sap_number=-1;
140 int process_arguments(int, char **);
141 void print_usage(void);
142 void print_help(void);
144 int main(int argc, char **argv){
145 int result;
146 char *send_buffer=NULL;
147 char recv_buffer[MAX_INPUT_BUFFER];
148 char *output_message=NULL;
149 char *temp_buffer=NULL;
150 char *netware_version=NULL;
152 int total_cache_buffers=0;
153 int dirty_cache_buffers=0;
154 int time_sync_status=0;
155 int open_files=0;
156 int abended_threads=0;
157 int max_service_processes=0;
158 int current_service_processes=0;
159 unsigned long free_disk_space=0L;
160 unsigned long total_disk_space=0L;
161 unsigned long purgeable_disk_space=0L;
162 unsigned long non_purgeable_disk_space=0L;
163 int percent_free_space=0;
164 int percent_purgeable_space=0;
165 int percent_non_purgeable_space=0;
166 unsigned long current_connections=0L;
167 unsigned long utilization=0L;
168 int cache_hits=0;
169 unsigned long cache_buffers=0L;
170 unsigned long lru_time=0L;
171 char uptime[MAX_INPUT_BUFFER];
172 int max_packet_receive_buffers=0;
173 int used_packet_receive_buffers=0;
174 unsigned long percent_used_packet_receive_buffers=0L;
175 int sap_entries=0;
177 if(process_arguments(argc,argv)==ERROR)
178 usage("Could not parse arguments\n");
180 /* initialize alarm signal handling */
181 signal(SIGALRM,socket_timeout_alarm_handler);
183 /* set socket timeout */
184 alarm(socket_timeout);
186 /* get OS version string */
187 if (check_netware_version==TRUE) {
188 send_buffer = strscpy(send_buffer,"S19\r\n");
189 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
190 if(result!=STATE_OK)
191 return result;
192 if(!strcmp(recv_buffer,"-1\n"))
193 asprintf(&netware_version,"");
194 else {
195 recv_buffer[strlen(recv_buffer)-1]=0;
196 asprintf(&netware_version,"NetWare %s: ",recv_buffer);
197 }
198 } else
199 asprintf(&netware_version,"");
202 /* check CPU load */
203 if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) {
205 switch(vars_to_check){
206 case CHECK_LOAD1:
207 temp_buffer = strscpy(temp_buffer,"1");
208 break;
209 case CHECK_LOAD5:
210 temp_buffer = strscpy(temp_buffer,"5");
211 break;
212 default:
213 temp_buffer = strscpy(temp_buffer,"15");
214 break;
215 }
217 asprintf(&send_buffer,"UTIL%s\r\n",temp_buffer);
218 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
219 if(result!=STATE_OK)
220 return result;
221 utilization=strtoul(recv_buffer,NULL,10);
222 send_buffer = strscpy(send_buffer,"UPTIME\r\n");
223 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
224 if(result!=STATE_OK)
225 return result;
226 recv_buffer[strlen(recv_buffer)-1]=0;
227 sprintf(uptime,"Up %s,",recv_buffer);
229 if(check_critical_value==TRUE && utilization >= critical_value)
230 result=STATE_CRITICAL;
231 else if(check_warning_value==TRUE && utilization >= warning_value)
232 result=STATE_WARNING;
234 asprintf(&output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization);
236 /* check number of user connections */
237 } else if (vars_to_check==CHECK_CONNS) {
239 send_buffer = strscpy(send_buffer,"CONNECT\r\n");
240 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
241 if(result!=STATE_OK)
242 return result;
243 current_connections=strtoul(recv_buffer,NULL,10);
245 if(check_critical_value==TRUE && current_connections >= critical_value)
246 result=STATE_CRITICAL;
247 else if(check_warning_value==TRUE && current_connections >= warning_value)
248 result=STATE_WARNING;
249 asprintf(&output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections);
251 /* check % long term cache hits */
252 } else if (vars_to_check==CHECK_LTCH) {
254 send_buffer = strscpy(send_buffer,"S1\r\n");
255 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
256 if(result!=STATE_OK)
257 return result;
258 cache_hits=atoi(recv_buffer);
260 if(check_critical_value==TRUE && cache_hits <= critical_value)
261 result=STATE_CRITICAL;
262 else if(check_warning_value==TRUE && cache_hits <= warning_value)
263 result=STATE_WARNING;
264 asprintf(&output_message,"Long term cache hits = %d%%",cache_hits);
266 /* check cache buffers */
267 } else if (vars_to_check==CHECK_CBUFF) {
269 send_buffer = strscpy(send_buffer,"S2\r\n");
270 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
271 if(result!=STATE_OK)
272 return result;
273 cache_buffers=strtoul(recv_buffer,NULL,10);
275 if(check_critical_value==TRUE && cache_buffers <= critical_value)
276 result=STATE_CRITICAL;
277 else if(check_warning_value==TRUE && cache_buffers <= warning_value)
278 result=STATE_WARNING;
279 asprintf(&output_message,"Total cache buffers = %lu",cache_buffers);
281 /* check dirty cache buffers */
282 } else if (vars_to_check==CHECK_CDBUFF) {
284 send_buffer = strscpy(send_buffer,"S3\r\n");
285 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
286 if(result!=STATE_OK)
287 return result;
288 cache_buffers=strtoul(recv_buffer,NULL,10);
290 if(check_critical_value==TRUE && cache_buffers >= critical_value)
291 result=STATE_CRITICAL;
292 else if(check_warning_value==TRUE && cache_buffers >= warning_value)
293 result=STATE_WARNING;
294 asprintf(&output_message,"Dirty cache buffers = %lu",cache_buffers);
296 /* check LRU sitting time in minutes */
297 } else if (vars_to_check==CHECK_LRUM) {
299 send_buffer = strscpy(send_buffer,"S5\r\n");
300 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
301 if(result!=STATE_OK)
302 return result;
303 lru_time=strtoul(recv_buffer,NULL,10);
305 if(check_critical_value==TRUE && lru_time <= critical_value)
306 result=STATE_CRITICAL;
307 else if(check_warning_value==TRUE && lru_time <= warning_value)
308 result=STATE_WARNING;
309 asprintf(&output_message,"LRU sitting time = %lu minutes",lru_time);
312 /* check KB free space on volume */
313 } else if (vars_to_check==CHECK_VKF) {
315 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
316 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
317 if(result!=STATE_OK)
318 return result;
320 if (!strcmp(recv_buffer,"-1\n")) {
321 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
322 result=STATE_CRITICAL;
323 } else {
324 free_disk_space=strtoul(recv_buffer,NULL,10);
325 if(check_critical_value==TRUE && free_disk_space <= critical_value)
326 result=STATE_CRITICAL;
327 else if(check_warning_value==TRUE && free_disk_space <= warning_value)
328 result=STATE_WARNING;
329 asprintf(&output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name);
330 }
332 /* check % free space on volume */
333 } else if (vars_to_check==CHECK_VPF) {
335 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
336 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
337 if(result!=STATE_OK)
338 return result;
340 if(!strcmp(recv_buffer,"-1\n")){
342 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
343 result=STATE_CRITICAL;
345 } else {
347 free_disk_space=strtoul(recv_buffer,NULL,10);
349 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
350 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
351 if(result!=STATE_OK)
352 return result;
353 total_disk_space=strtoul(recv_buffer,NULL,10);
355 percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0);
357 if(check_critical_value==TRUE && percent_free_space <= critical_value)
358 result=STATE_CRITICAL;
359 else if(check_warning_value==TRUE && percent_free_space <= warning_value)
360 result=STATE_WARNING;
361 free_disk_space/=1024;
362 asprintf(&output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name);
363 }
365 /* check to see if DS Database is open or closed */
366 } else if(vars_to_check==CHECK_DSDB) {
368 send_buffer = strscpy(send_buffer,"S11\r\n");
369 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
370 if(result!=STATE_OK)
371 return result;
372 if(atoi(recv_buffer)==1)
373 result=STATE_OK;
374 else
375 result=STATE_WARNING;
377 send_buffer = strscpy(send_buffer,"S13\r\n");
378 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
379 temp_buffer=strtok(recv_buffer,"\r\n");
381 asprintf(&output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer);
383 /* check to see if logins are enabled */
384 } else if (vars_to_check==CHECK_LOGINS) {
386 send_buffer = strscpy(send_buffer,"S12\r\n");
387 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
388 if(result!=STATE_OK)
389 return result;
390 if(atoi(recv_buffer)==1)
391 result=STATE_OK;
392 else
393 result=STATE_WARNING;
395 asprintf(&output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled");
397 /* check packet receive buffers */
398 } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) {
400 asprintf(&send_buffer,"S15\r\n",volume_name);
401 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
402 if(result!=STATE_OK)
403 return result;
405 used_packet_receive_buffers=atoi(recv_buffer);
407 asprintf(&send_buffer,"S16\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 max_packet_receive_buffers=atoi(recv_buffer);
414 percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0);
416 if(vars_to_check==CHECK_UPRB){
417 if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value)
418 result=STATE_CRITICAL;
419 else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value)
420 result=STATE_WARNING;
421 } else {
422 if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value)
423 result=STATE_CRITICAL;
424 else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value)
425 result=STATE_WARNING;
426 }
428 asprintf(&output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers);
430 /* check SAP table entries */
431 } else if (vars_to_check==CHECK_SAPENTRIES) {
433 if(sap_number==-1)
434 asprintf(&send_buffer,"S9\r\n");
435 else
436 asprintf(&send_buffer,"S9.%d\r\n",sap_number);
437 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
438 if(result!=STATE_OK)
439 return result;
441 sap_entries=atoi(recv_buffer);
443 if(check_critical_value==TRUE && sap_entries >= critical_value)
444 result=STATE_CRITICAL;
445 else if(check_warning_value==TRUE && sap_entries >= warning_value)
446 result=STATE_WARNING;
448 if(sap_number==-1)
449 asprintf(&output_message,"%d entries in SAP table",sap_entries);
450 else
451 asprintf(&output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number);
453 /* check KB purgeable space on volume */
454 } else if (vars_to_check==CHECK_VKP) {
456 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
457 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
458 if(result!=STATE_OK)
459 return result;
461 if (!strcmp(recv_buffer,"-1\n")) {
462 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
463 result=STATE_CRITICAL;
464 } else {
465 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
466 if(check_critical_value==TRUE && purgeable_disk_space >= critical_value)
467 result=STATE_CRITICAL;
468 else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value)
469 result=STATE_WARNING;
470 asprintf(&output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name);
471 }
473 /* check % purgeable space on volume */
474 } else if (vars_to_check==CHECK_VPP) {
476 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
477 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
478 if(result!=STATE_OK)
479 return result;
481 if(!strcmp(recv_buffer,"-1\n")){
483 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
484 result=STATE_CRITICAL;
486 } else {
488 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
490 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
491 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
492 if(result!=STATE_OK)
493 return result;
494 total_disk_space=strtoul(recv_buffer,NULL,10);
496 percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0);
498 if(check_critical_value==TRUE && percent_purgeable_space >= critical_value)
499 result=STATE_CRITICAL;
500 else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value)
501 result=STATE_WARNING;
502 purgeable_disk_space/=1024;
503 asprintf(&output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name);
504 }
506 /* check KB not yet purgeable space on volume */
507 } else if (vars_to_check==CHECK_VKNP) {
509 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
510 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
511 if(result!=STATE_OK)
512 return result;
514 if (!strcmp(recv_buffer,"-1\n")) {
515 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
516 result=STATE_CRITICAL;
517 } else {
518 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
519 if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value)
520 result=STATE_CRITICAL;
521 else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value)
522 result=STATE_WARNING;
523 asprintf(&output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name);
524 }
526 /* check % not yet purgeable space on volume */
527 } else if (vars_to_check==CHECK_VPNP) {
529 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
530 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
531 if(result!=STATE_OK)
532 return result;
534 if(!strcmp(recv_buffer,"-1\n")){
536 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
537 result=STATE_CRITICAL;
539 } else {
541 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
543 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
544 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
545 if(result!=STATE_OK)
546 return result;
547 total_disk_space=strtoul(recv_buffer,NULL,10);
549 percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0);
551 if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value)
552 result=STATE_CRITICAL;
553 else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value)
554 result=STATE_WARNING;
555 purgeable_disk_space/=1024;
556 asprintf(&output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name);
557 }
559 /* check # of open files */
560 } else if (vars_to_check==CHECK_OFILES) {
562 asprintf(&send_buffer,"S18\r\n");
563 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
564 if(result!=STATE_OK)
565 return result;
567 open_files=atoi(recv_buffer);
569 if(check_critical_value==TRUE && open_files >= critical_value)
570 result=STATE_CRITICAL;
571 else if(check_warning_value==TRUE && open_files >= warning_value)
572 result=STATE_WARNING;
574 asprintf(&output_message,"%d open files",open_files);
576 /* check # of abended threads (Netware 5.x only) */
577 } else if (vars_to_check==CHECK_ABENDS) {
579 asprintf(&send_buffer,"S17\r\n");
580 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
581 if(result!=STATE_OK)
582 return result;
584 abended_threads=atoi(recv_buffer);
586 if(check_critical_value==TRUE && abended_threads >= critical_value)
587 result=STATE_CRITICAL;
588 else if(check_warning_value==TRUE && abended_threads >= warning_value)
589 result=STATE_WARNING;
591 asprintf(&output_message,"%d abended threads",abended_threads);
593 /* check # of current service processes (Netware 5.x only) */
594 } else if (vars_to_check==CHECK_CSPROCS) {
596 asprintf(&send_buffer,"S20\r\n");
597 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
598 if(result!=STATE_OK)
599 return result;
601 max_service_processes=atoi(recv_buffer);
603 asprintf(&send_buffer,"S21\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;
608 current_service_processes=atoi(recv_buffer);
610 if(check_critical_value==TRUE && current_service_processes >= critical_value)
611 result=STATE_CRITICAL;
612 else if(check_warning_value==TRUE && current_service_processes >= warning_value)
613 result=STATE_WARNING;
615 asprintf(&output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes);
617 /* check # Timesync Status */
618 } else if (vars_to_check==CHECK_TSYNC) {
620 asprintf(&send_buffer,"S22\r\n");
621 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
622 if(result!=STATE_OK)
623 return result;
625 time_sync_status=atoi(recv_buffer);
627 if(time_sync_status==0) {
628 result=STATE_CRITICAL;
629 asprintf(&output_message,"Critical: Time not in sync with network!");
630 }
631 else {
632 asprintf(&output_message,"OK! Time in sync with network!");
633 }
635 /* check LRU sitting time in secondss */
636 } else if (vars_to_check==CHECK_LRUS) {
638 send_buffer = strscpy(send_buffer,"S4\r\n");
639 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
640 if(result!=STATE_OK)
641 return result;
642 lru_time=strtoul(recv_buffer,NULL,10);
644 if(check_critical_value==TRUE && lru_time <= critical_value)
645 result=STATE_CRITICAL;
646 else if(check_warning_value==TRUE && lru_time <= warning_value)
647 result=STATE_WARNING;
648 asprintf(&output_message,"LRU sitting time = %lu seconds",lru_time);
651 /* check % dirty cache buffers as a percentage of the total*/
652 } else if (vars_to_check==CHECK_DCB) {
654 send_buffer = strscpy(send_buffer,"S6\r\n");
655 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
656 if(result!=STATE_OK)
657 return result;
658 dirty_cache_buffers=atoi(recv_buffer);
660 if(check_critical_value==TRUE && dirty_cache_buffers <= critical_value)
661 result=STATE_CRITICAL;
662 else if(check_warning_value==TRUE && dirty_cache_buffers <= warning_value)
663 result=STATE_WARNING;
664 asprintf(&output_message,"dirty cache buffers = %d%% of the total",dirty_cache_buffers);
666 /* check % total cache buffers as a percentage of the original*/
667 } else if (vars_to_check==CHECK_TCB) {
669 send_buffer = strscpy(send_buffer,"S7\r\n");
670 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
671 if(result!=STATE_OK)
672 return result;
673 total_cache_buffers=atoi(recv_buffer);
675 if(check_critical_value==TRUE && total_cache_buffers <= critical_value)
676 result=STATE_CRITICAL;
677 else if(check_warning_value==TRUE && total_cache_buffers <= warning_value)
678 result=STATE_WARNING;
679 asprintf(&output_message,"total cache buffers = %d%% of the original",total_cache_buffers);
681 } else {
683 output_message = strscpy(output_message,"Nothing to check!\n");
684 result=STATE_UNKNOWN;
686 }
688 /* reset timeout */
689 alarm(0);
691 printf("%s%s\n",netware_version,output_message);
693 return result;
694 }
697 /* process command-line arguments */
698 int process_arguments(int argc, char **argv){
699 int c;
701 int option_index = 0;
702 static struct option long_options[] =
703 {
704 {"port", required_argument,0,'p'},
705 {"timeout", required_argument,0,'t'},
706 {"critical", required_argument,0,'c'},
707 {"warning", required_argument,0,'w'},
708 {"variable", required_argument,0,'v'},
709 {"hostname", required_argument,0,'H'},
710 {"osversion",no_argument, 0,'o'},
711 {"version", no_argument, 0,'V'},
712 {"help", no_argument, 0,'h'},
713 {0,0,0,0}
714 };
716 /* no options were supplied */
717 if(argc<2) return ERROR;
719 /* backwards compatibility */
720 if (! is_option(argv[1])) {
721 server_address=argv[1];
722 argv[1]=argv[0];
723 argv=&argv[1];
724 argc--;
725 }
727 for (c=1;c<argc;c++) {
728 if(strcmp("-to",argv[c])==0)
729 strcpy(argv[c],"-t");
730 else if (strcmp("-wv",argv[c])==0)
731 strcpy(argv[c],"-w");
732 else if (strcmp("-cv",argv[c])==0)
733 strcpy(argv[c],"-c");
734 }
736 while (1){
737 c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index);
739 if (c==-1||c==EOF||c==1)
740 break;
742 switch (c)
743 {
744 case '?': /* print short usage statement if args not parsable */
745 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
746 print_usage();
747 exit(STATE_UNKNOWN);
748 case 'h': /* help */
749 print_help();
750 exit(STATE_OK);
751 case 'V': /* version */
752 print_revision(progname,"$Revision$");
753 exit(STATE_OK);
754 case 'H': /* hostname */
755 server_address=optarg;
756 break;
757 case 'o': /* display nos version */
758 check_netware_version=TRUE;
759 break;
760 case 'p': /* port */
761 if (is_intnonneg(optarg))
762 server_port=atoi(optarg);
763 else
764 terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",progname);
765 break;
766 case 'v':
767 if(strlen(optarg)<3)
768 return ERROR;
769 if(!strcmp(optarg,"LOAD1"))
770 vars_to_check=CHECK_LOAD1;
771 else if(!strcmp(optarg,"LOAD5"))
772 vars_to_check=CHECK_LOAD5;
773 else if(!strcmp(optarg,"LOAD15"))
774 vars_to_check=CHECK_LOAD15;
775 else if(!strcmp(optarg,"CONNS"))
776 vars_to_check=CHECK_CONNS;
777 else if(!strcmp(optarg,"LTCH"))
778 vars_to_check=CHECK_LTCH;
779 else if(!strcmp(optarg,"DCB"))
780 vars_to_check=CHECK_DCB;
781 else if(!strcmp(optarg,"TCB"))
782 vars_to_check=CHECK_TCB;
783 else if(!strcmp(optarg,"CBUFF"))
784 vars_to_check=CHECK_CBUFF;
785 else if(!strcmp(optarg,"CDBUFF"))
786 vars_to_check=CHECK_CDBUFF;
787 else if(!strcmp(optarg,"LRUM"))
788 vars_to_check=CHECK_LRUM;
789 else if(!strcmp(optarg,"LRUS"))
790 vars_to_check=CHECK_LRUS;
791 else if(strncmp(optarg,"VPF",3)==0){
792 vars_to_check=CHECK_VPF;
793 volume_name = strscpy(volume_name,optarg+3);
794 if(!strcmp(volume_name,""))
795 volume_name = strscpy(volume_name,"SYS");
796 }
797 else if(strncmp(optarg,"VKF",3)==0){
798 vars_to_check=CHECK_VKF;
799 volume_name = strscpy(volume_name,optarg+3);
800 if(!strcmp(volume_name,""))
801 volume_name = strscpy(volume_name,"SYS");
802 }
803 else if(!strcmp(optarg,"DSDB"))
804 vars_to_check=CHECK_DSDB;
805 else if(!strcmp(optarg,"LOGINS"))
806 vars_to_check=CHECK_LOGINS;
807 else if(!strcmp(optarg,"UPRB"))
808 vars_to_check=CHECK_UPRB;
809 else if(!strcmp(optarg,"PUPRB"))
810 vars_to_check=CHECK_PUPRB;
811 else if(!strncmp(optarg,"SAPENTRIES",10)){
812 vars_to_check=CHECK_SAPENTRIES;
813 if(strlen(optarg)>10)
814 sap_number=atoi(optarg+10);
815 else
816 sap_number=-1;
817 }
818 else if(!strcmp(optarg,"OFILES"))
819 vars_to_check=CHECK_OFILES;
820 else if(strncmp(optarg,"VKP",3)==0){
821 vars_to_check=CHECK_VKP;
822 volume_name = strscpy(volume_name,optarg+3);
823 if(!strcmp(volume_name,""))
824 volume_name = strscpy(volume_name,"SYS");
825 }
826 else if(strncmp(optarg,"VPP",3)==0){
827 vars_to_check=CHECK_VPP;
828 volume_name = strscpy(volume_name,optarg+3);
829 if(!strcmp(volume_name,""))
830 volume_name = strscpy(volume_name,"SYS");
831 }
832 else if(strncmp(optarg,"VKNP",4)==0){
833 vars_to_check=CHECK_VKNP;
834 volume_name = strscpy(volume_name,optarg+4);
835 if(!strcmp(volume_name,""))
836 volume_name = strscpy(volume_name,"SYS");
837 }
838 else if(strncmp(optarg,"VPNP",4)==0){
839 vars_to_check=CHECK_VPNP;
840 volume_name = strscpy(volume_name,optarg+4);
841 if(!strcmp(volume_name,""))
842 volume_name = strscpy(volume_name,"SYS");
843 }
844 else if(!strcmp(optarg,"ABENDS"))
845 vars_to_check=CHECK_ABENDS;
846 else if(!strcmp(optarg,"CSPROCS"))
847 vars_to_check=CHECK_CSPROCS;
848 else if(!strcmp(optarg,"TSYNC"))
849 vars_to_check=CHECK_TSYNC;
850 else
851 return ERROR;
852 break;
853 case 'w': /* warning threshold */
854 warning_value=strtoul(optarg,NULL,10);
855 check_warning_value=TRUE;
856 break;
857 case 'c': /* critical threshold */
858 critical_value=strtoul(optarg,NULL,10);
859 check_critical_value=TRUE;
860 break;
861 case 't': /* timeout */
862 socket_timeout=atoi(optarg);
863 if(socket_timeout<=0)
864 return ERROR;
865 }
867 }
869 return OK;
870 }
873 void print_usage(void)
874 {
875 printf
876 ("Usage:\n"
877 " %s %s\n"
878 " %s (-h | --help) for detailed help\n"
879 " %s (-V | --version) for version information\n",
880 progname, OPTIONS, progname, progname);
881 }
883 void print_help(void)
884 {
885 print_revision (progname, REVISION);
886 printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
887 print_usage();
888 printf
889 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
890 PORT, DEFAULT_SOCKET_TIMEOUT);
891 support ();
892 }