summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/Makefile.am24
-rw-r--r--plugins/check_by_ssh.c150
-rw-r--r--plugins/check_dig.c168
-rw-r--r--plugins/check_dns.c119
-rw-r--r--plugins/check_game.c46
-rw-r--r--plugins/check_nagios.c80
-rw-r--r--plugins/netutils.c7
-rw-r--r--plugins/runcmd.c74
-rw-r--r--plugins/utils.c11
-rw-r--r--plugins/utils.h5
10 files changed, 293 insertions, 391 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 92227712..569199d8 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -26,7 +26,7 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \
26 26
27EXTRA_DIST = t utils.c netutils.c sslutils.c popen.c utils.h netutils.h \ 27EXTRA_DIST = t utils.c netutils.c sslutils.c popen.c utils.h netutils.h \
28 popen.h common.h getaddrinfo.c getaddrinfo.h \ 28 popen.h common.h getaddrinfo.c getaddrinfo.h \
29 gethostbyname.c gethostbyname.h 29 gethostbyname.c gethostbyname.h runcmd.c runcmd.h
30 30
31PLUGINHDRS = common.h 31PLUGINHDRS = common.h
32 32
@@ -47,12 +47,12 @@ AM_INSTALL_PROGRAM_FLAGS = @INSTALL_OPTS@
47############################################################################## 47##############################################################################
48# the actual targets 48# the actual targets
49 49
50check_dig_LDADD = $(NETLIBS) popen.o 50check_dig_LDADD = $(NETLIBS) runcmd.o
51check_disk_LDADD = $(BASEOBJS) popen.o 51check_disk_LDADD = $(BASEOBJS) popen.o
52check_dns_LDADD = $(NETLIBS) popen.o 52check_dns_LDADD = $(NETLIBS) runcmd.o
53check_dummy_LDADD = $(BASEOBJS) 53check_dummy_LDADD = $(BASEOBJS)
54check_fping_LDADD = $(NETLIBS) popen.o 54check_fping_LDADD = $(NETLIBS) popen.o
55check_game_LDADD = $(BASEOBJS) popen.o 55check_game_LDADD = $(BASEOBJS) runcmd.o
56check_http_LDADD = $(SSLOBJS) $(NETLIBS) 56check_http_LDADD = $(SSLOBJS) $(NETLIBS)
57check_hpjd_LDADD = $(NETLIBS) popen.o 57check_hpjd_LDADD = $(NETLIBS) popen.o
58check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) 58check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS)
@@ -60,7 +60,7 @@ check_load_LDADD = $(BASEOBJS) popen.o
60check_mrtg_LDADD = $(BASEOBJS) 60check_mrtg_LDADD = $(BASEOBJS)
61check_mrtgtraf_LDADD = $(BASEOBJS) 61check_mrtgtraf_LDADD = $(BASEOBJS)
62check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) 62check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS)
63check_nagios_LDADD = $(BASEOBJS) popen.o 63check_nagios_LDADD = $(BASEOBJS) runcmd.o
64check_nt_LDADD = $(NETLIBS) 64check_nt_LDADD = $(NETLIBS)
65check_nwstat_LDADD = $(NETLIBS) 65check_nwstat_LDADD = $(NETLIBS)
66check_overcr_LDADD = $(NETLIBS) 66check_overcr_LDADD = $(NETLIBS)
@@ -78,17 +78,17 @@ check_time_LDADD = $(NETLIBS)
78check_udp_LDADD = $(SSLOBJS) $(NETLIBS) 78check_udp_LDADD = $(SSLOBJS) $(NETLIBS)
79check_ups_LDADD = $(NETLIBS) 79check_ups_LDADD = $(NETLIBS)
80check_users_LDADD = $(BASEOBJS) popen.o 80check_users_LDADD = $(BASEOBJS) popen.o
81check_by_ssh_LDADD = $(NETLIBS) popen.o 81check_by_ssh_LDADD = $(NETLIBS) runcmd.o
82check_ide_smart_LDADD = $(BASEOBJS) 82check_ide_smart_LDADD = $(BASEOBJS)
83negate_LDADD = $(BASEOBJS) popen.o 83negate_LDADD = $(BASEOBJS) popen.o
84urlize_LDADD = $(BASEOBJS) popen.o 84urlize_LDADD = $(BASEOBJS) popen.o
85 85
86check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) popen.o $(DEPLIBS) 86check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) runcmd.o $(DEPLIBS)
87check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS) 87check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS)
88check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) popen.o $(DEPLIBS) 88check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) runcmd.o $(DEPLIBS)
89check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS) 89check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS)
90check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) popen.o $(DEPLIBS) 90check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) popen.o $(DEPLIBS)
91check_game_DEPENDENCIES = check_game.c $(DEPLIBS) 91check_game_DEPENDENCIES = check_game.c $(DEPLIBS) runcmd.o
92check_http_DEPENDENCIES = check_http.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS) 92check_http_DEPENDENCIES = check_http.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
93check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS) 93check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS)
94check_ide_smart_DEPENDENCIES = check_ide_smart.c $(BASEOBJS) $(DEPLIBS) 94check_ide_smart_DEPENDENCIES = check_ide_smart.c $(BASEOBJS) $(DEPLIBS)
@@ -97,7 +97,7 @@ check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS)
97check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS) 97check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS)
98check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS) 98check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS)
99check_mysql_DEPENDENCIES = check_mysql.c $(NETOBJS) $(DEPLIBS) 99check_mysql_DEPENDENCIES = check_mysql.c $(NETOBJS) $(DEPLIBS)
100check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS) 100check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) runcmd.o $(DEPLIBS)
101check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS) 101check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS)
102check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS) 102check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS)
103check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS) 103check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS)
@@ -115,7 +115,7 @@ check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS)
115check_udp_DEPENDENCIES = check_udp.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS) 115check_udp_DEPENDENCIES = check_udp.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
116check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) 116check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS)
117check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) 117check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS)
118check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS) 118check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) runcmd.o $(DEPLIBS)
119negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) 119negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS)
120urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) 120urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
121 121
@@ -124,6 +124,8 @@ urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
124 124
125popen.o: popen.c popen.h $(PLUGINHDRS) 125popen.o: popen.c popen.h $(PLUGINHDRS)
126 126
127runcmd.o: runcmd.c runcmd.h $(PLUGINHDRS)
128
127utils.o: utils.c utils.h $(PLUGINHDRS) 129utils.o: utils.c utils.h $(PLUGINHDRS)
128 130
129netutils.o: netutils.c netutils.h $(PLUGINHDRS) 131netutils.o: netutils.c netutils.h $(PLUGINHDRS)
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c
index 2ceee28f..b777b072 100644
--- a/plugins/check_by_ssh.c
+++ b/plugins/check_by_ssh.c
@@ -26,7 +26,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
26#include "common.h" 26#include "common.h"
27#include "netutils.h" 27#include "netutils.h"
28#include "utils.h" 28#include "utils.h"
29#include "popen.h" 29#include "runcmd.h"
30 30
31int process_arguments (int, char **); 31int process_arguments (int, char **);
32int validate_arguments (void); 32int validate_arguments (void);
@@ -35,7 +35,7 @@ void print_usage (void);
35 35
36int commands = 0; 36int commands = 0;
37int services = 0; 37int services = 0;
38int skip_lines = 0; 38int skip = 0;
39char *remotecmd = NULL; 39char *remotecmd = NULL;
40char *comm = NULL; 40char *comm = NULL;
41char *hostname = NULL; 41char *hostname = NULL;
@@ -49,19 +49,16 @@ int
49main (int argc, char **argv) 49main (int argc, char **argv)
50{ 50{
51 51
52 char input_buffer[MAX_INPUT_BUFFER];
53 char *result_text;
54 char *status_text; 52 char *status_text;
55 char *output;
56 char *eol = NULL;
57 int cresult; 53 int cresult;
58 int result = STATE_UNKNOWN; 54 int result = STATE_UNKNOWN;
55 int i;
59 time_t local_time; 56 time_t local_time;
60 FILE *fp = NULL; 57 FILE *fp = NULL;
58 struct output chld_out, chld_err;
61 59
62 remotecmd = strdup (""); 60 remotecmd = "";
63 comm = strdup (SSH_COMMAND); 61 comm = strdup (SSH_COMMAND);
64 result_text = strdup ("");
65 62
66 setlocale (LC_ALL, ""); 63 setlocale (LC_ALL, "");
67 bindtextdomain (PACKAGE, LOCALEDIR); 64 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -69,100 +66,62 @@ main (int argc, char **argv)
69 66
70 /* process arguments */ 67 /* process arguments */
71 if (process_arguments (argc, argv) == ERROR) 68 if (process_arguments (argc, argv) == ERROR)
72 usage4 (_("Could not parse arguments")); 69 usage_va(_("Could not parse arguments"));
73 70
74 /* Set signal handling and alarm timeout */ 71 /* Set signal handling and alarm timeout */
75 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { 72 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
76 usage4 (_("Cannot catch SIGALRM")); 73 usage_va(_("Cannot catch SIGALRM"));
77 } 74 }
78 alarm (timeout_interval); 75 alarm (timeout_interval);
79 76
80 /* run the command */ 77 /* run the command */
81
82 if (verbose) 78 if (verbose)
83 printf ("%s\n", comm); 79 printf ("%s\n", comm);
84 80
85 child_process = spopen (comm); 81 result = np_runcmd(comm, &chld_out, &chld_err, 0);
86 82 /* UNKNOWN if output found on stderr */
87 if (child_process == NULL) { 83 if(chld_err.buflen) {
88 printf (_("Could not open pipe: %s\n"), comm); 84 printf(_("Remote command execution failed: %s\n"),
85 chld_err.buflen ? chld_err.buf : _("Unknown error"));
89 return STATE_UNKNOWN; 86 return STATE_UNKNOWN;
90 } 87 }
91 88
92 89 /* this is simple if we're not supposed to be passive.
93 /* open STDERR for spopen */ 90 * Wrap up quickly and keep the tricks below */
94 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); 91 if(!passive) {
95 if (child_stderr == NULL) { 92 printf ("%s\n", skip < chld_out.lines ? chld_out.line[skip] : chld_out.buf);
96 printf (_("Could not open stderr for %s\n"), SSH_COMMAND); 93 return result; /* return error status from remote command */
97 } 94 }
98 95
99 96
100 /* build up results from remote command in result_text */ 97 /*
101 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) 98 * Passive mode
102 asprintf (&result_text, "%s%s", result_text, input_buffer); 99 */
103
104 /* WARNING if output found on stderr */
105 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
106 if (skip_lines > 0) {
107 if (input_buffer[strlen(input_buffer)-1] == '\n') {
108 skip_lines--;
109 }
110 } else {
111 printf ("%s", input_buffer);
112 result = STATE_WARNING;
113 }
114 }
115 (void) fclose (child_stderr);
116 if (result == STATE_WARNING)
117 return result;
118
119
120 /* close the pipe */
121 result = spclose (child_process);
122
123 100
124 /* process output */ 101 /* process output */
125 if (passive) { 102 if (!(fp = fopen (outputfile, "a"))) {
103 printf (_("SSH WARNING: could not open %s\n"), outputfile);
104 exit (STATE_UNKNOWN);
105 }
126 106
127 if (!(fp = fopen (outputfile, "a"))) { 107 local_time = time (NULL);
128 printf (_("SSH WARNING: could not open %s\n"), outputfile); 108 commands = 0;
129 exit (STATE_UNKNOWN); 109 for(i = skip; chld_out.line[i]; i++) {
110 status_text = strstr (chld_out.line[i], "STATUS CODE: ");
111 if (status_text == NULL) {
112 printf ("%s", chld_out.line[i]);
113 return result;
130 } 114 }
131 115 if (service[commands] && status_text
132 local_time = time (NULL); 116 && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1)
133 commands = 0; 117 {
134 while (result_text && strlen(result_text) > 0) { 118 fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
135 status_text = strstr (result_text, "STATUS CODE: "); 119 (int) local_time, host_shortname, service[commands++],
136 if (status_text == NULL) { 120 cresult, chld_out.line[i]);
137 printf ("%s", result_text);
138 return result;
139 }
140 asprintf (&output, "%s", result_text);
141 result_text = strnl (status_text);
142 eol = strpbrk (output, "\r\n");
143 if (eol != NULL)
144 eol[0] = 0;
145 if (service[commands] && status_text
146 && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) {
147 fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
148 (int) local_time, host_shortname, service[commands++], cresult,
149 output);
150 }
151 } 121 }
152
153 }
154
155
156 /* print the first line from the remote command */
157 else {
158 eol = strpbrk (result_text, "\r\n");
159 if (eol)
160 eol[0] = 0;
161 printf ("%s\n", result_text);
162 } 122 }
163 123
164 124 /* force an OK state */
165 /* return error status from remote command */
166 return result; 125 return result;
167} 126}
168 127
@@ -206,14 +165,12 @@ process_arguments (int argc, char **argv)
206 165
207 while (1) { 166 while (1) {
208 c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, 167 c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts,
209 &option); 168 &option);
210 169
211 if (c == -1 || c == EOF) 170 if (c == -1 || c == EOF)
212 break; 171 break;
213 172
214 switch (c) { 173 switch (c) {
215 case '?': /* help */
216 usage2 (_("Unknown argument"), optarg);
217 case 'V': /* version */ 174 case 'V': /* version */
218 print_revision (progname, revision); 175 print_revision (progname, revision);
219 exit (STATE_OK); 176 exit (STATE_OK);
@@ -225,18 +182,17 @@ process_arguments (int argc, char **argv)
225 break; 182 break;
226 case 't': /* timeout period */ 183 case 't': /* timeout period */
227 if (!is_integer (optarg)) 184 if (!is_integer (optarg))
228 usage2 (_("Timeout interval must be a positive integer"), optarg); 185 usage_va(_("Timeout interval must be a positive integer"));
229 else 186 else
230 timeout_interval = atoi (optarg); 187 timeout_interval = atoi (optarg);
231 break; 188 break;
232 case 'H': /* host */ 189 case 'H': /* host */
233 if (!is_host (optarg)) 190 host_or_die(optarg);
234 usage2 (_("Invalid hostname/address"), optarg);
235 hostname = optarg; 191 hostname = optarg;
236 break; 192 break;
237 case 'p': /* port number */ 193 case 'p': /* port number */
238 if (!is_integer (optarg)) 194 if (!is_integer (optarg))
239 usage2 (_("Port must be a positive integer"), optarg); 195 usage_va(_("Port must be a positive integer"));
240 asprintf (&comm,"%s -p %s", comm, optarg); 196 asprintf (&comm,"%s -p %s", comm, optarg);
241 break; 197 break;
242 case 'O': /* output file */ 198 case 'O': /* output file */
@@ -244,25 +200,27 @@ process_arguments (int argc, char **argv)
244 passive = TRUE; 200 passive = TRUE;
245 break; 201 break;
246 case 's': /* description of service to check */ 202 case 's': /* description of service to check */
247 service = realloc (service, (++services) * sizeof(char *));
248 p1 = optarg; 203 p1 = optarg;
204 service = realloc (service, (++services) * sizeof(char *));
249 while ((p2 = index (p1, ':'))) { 205 while ((p2 = index (p1, ':'))) {
250 *p2 = '\0'; 206 *p2 = '\0';
251 asprintf (&service[services-1], "%s", p1); 207 service[services - 1] = p1;
252 service = realloc (service, (++services) * sizeof(char *)); 208 service = realloc (service, (++services) * sizeof(char *));
253 p1 = p2 + 1; 209 p1 = p2 + 1;
254 } 210 }
255 asprintf (&service[services-1], "%s", p1); 211 service[services - 1] = p1;
256 break; 212 break;
257 case 'n': /* short name of host in nagios configuration */ 213 case 'n': /* short name of host in nagios configuration */
258 host_shortname = optarg; 214 host_shortname = optarg;
259 break; 215 break;
216
260 case 'u': 217 case 'u':
261 c = 'l'; 218 c = 'l';
262 case 'l': /* login name */ 219 case 'l': /* login name */
263 case 'i': /* identity */ 220 case 'i': /* identity */
264 asprintf (&comm, "%s -%c %s", comm, c, optarg); 221 asprintf (&comm, "%s -%c %s", comm, c, optarg);
265 break; 222 break;
223
266 case '1': /* Pass these switches directly to ssh */ 224 case '1': /* Pass these switches directly to ssh */
267 case '2': /* 1 to force version 1, 2 to force version 2 */ 225 case '2': /* 1 to force version 1, 2 to force version 2 */
268 case '4': /* -4 for IPv4 */ 226 case '4': /* -4 for IPv4 */
@@ -278,10 +236,12 @@ process_arguments (int argc, char **argv)
278 break; 236 break;
279 case 'S': /* Skip n lines in the output to ignore system banner */ 237 case 'S': /* Skip n lines in the output to ignore system banner */
280 if (!is_integer (optarg)) 238 if (!is_integer (optarg))
281 usage2 (_("skip lines must be an integer"), optarg); 239 usage_va(_("skip lines must be an integer"));
282 else 240 else
283 skip_lines = atoi (optarg); 241 skip = atoi (optarg);
284 break; 242 break;
243 default: /* help */
244 usage_va(_("Unknown argument - %s"), optarg);
285 } 245 }
286 } 246 }
287 247
@@ -289,8 +249,8 @@ process_arguments (int argc, char **argv)
289 if (hostname == NULL) { 249 if (hostname == NULL) {
290 if (c <= argc) { 250 if (c <= argc) {
291 die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); 251 die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
292 } else if (!is_host (argv[c])) 252 }
293 die (STATE_UNKNOWN, "%s: %s %s\n", progname, _("Invalid hostname/address"), argv[c]); 253 host_or_die(argv[c]);
294 hostname = argv[c++]; 254 hostname = argv[c++];
295 } 255 }
296 256
@@ -306,7 +266,7 @@ process_arguments (int argc, char **argv)
306 asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); 266 asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
307 267
308 if (remotecmd == NULL || strlen (remotecmd) <= 1) 268 if (remotecmd == NULL || strlen (remotecmd) <= 1)
309 usage4 (_("No remotecmd")); 269 usage_va(_("No remotecmd"));
310 270
311 asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd); 271 asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd);
312 272
diff --git a/plugins/check_dig.c b/plugins/check_dig.c
index 4394490e..bc4dcd5c 100644
--- a/plugins/check_dig.c
+++ b/plugins/check_dig.c
@@ -18,6 +18,12 @@
18 18
19*****************************************************************************/ 19*****************************************************************************/
20 20
21/* Hackers note:
22 * There are typecasts to (char *) from _("foo bar") in this file.
23 * They prevent compiler warnings. Never (ever), permute strings obtained
24 * that are typecast from (const char *) (which happens when --disable-nls)
25 * because on some architectures those strings are in non-writable memory */
26
21const char *progname = "check_dig"; 27const char *progname = "check_dig";
22const char *revision = "$Revision$"; 28const char *revision = "$Revision$";
23const char *copyright = "2002-2004"; 29const char *copyright = "2002-2004";
@@ -26,17 +32,15 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
26#include "common.h" 32#include "common.h"
27#include "netutils.h" 33#include "netutils.h"
28#include "utils.h" 34#include "utils.h"
29#include "popen.h" 35#include "runcmd.h"
30 36
31int process_arguments (int, char **); 37int process_arguments (int, char **);
32int validate_arguments (void); 38int validate_arguments (void);
33void print_help (void); 39void print_help (void);
34void print_usage (void); 40void print_usage (void);
35 41
36enum { 42#define UNDEFINED 0
37 UNDEFINED = 0, 43#define DEFAULT_PORT 53
38 DEFAULT_PORT = 53
39};
40 44
41char *query_address = NULL; 45char *query_address = NULL;
42char *record_type = "A"; 46char *record_type = "A";
@@ -51,26 +55,25 @@ struct timeval tv;
51int 55int
52main (int argc, char **argv) 56main (int argc, char **argv)
53{ 57{
54 char input_buffer[MAX_INPUT_BUFFER];
55 char *command_line; 58 char *command_line;
56 char *output; 59 output chld_out, chld_err;
60 char *msg = NULL;
61 size_t i;
57 char *t; 62 char *t;
58 long microsec; 63 long microsec;
59 double elapsed_time; 64 double elapsed_time;
60 int result = STATE_UNKNOWN; 65 int result = STATE_UNKNOWN;
61 66
62 output = strdup ("");
63
64 setlocale (LC_ALL, ""); 67 setlocale (LC_ALL, "");
65 bindtextdomain (PACKAGE, LOCALEDIR); 68 bindtextdomain (PACKAGE, LOCALEDIR);
66 textdomain (PACKAGE); 69 textdomain (PACKAGE);
67 70
68 /* Set signal handling and alarm */ 71 /* Set signal handling and alarm */
69 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) 72 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR)
70 usage4 (_("Cannot catch SIGALRM")); 73 usage_va(_("Cannot catch SIGALRM"));
71 74
72 if (process_arguments (argc, argv) == ERROR) 75 if (process_arguments (argc, argv) == ERROR)
73 usage4 (_("Could not parse arguments")); 76 usage_va(_("Could not parse arguments"));
74 77
75 /* get the command to run */ 78 /* get the command to run */
76 asprintf (&command_line, "%s @%s -p %d %s -t %s", 79 asprintf (&command_line, "%s @%s -p %d %s -t %s",
@@ -89,100 +92,75 @@ main (int argc, char **argv)
89 } 92 }
90 93
91 /* run the command */ 94 /* run the command */
92 child_process = spopen (command_line); 95 if(np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) {
93 if (child_process == NULL) { 96 result = STATE_WARNING;
94 printf (_("Could not open pipe: %s\n"), command_line); 97 msg = (char *)_("dig returned an error status");
95 return STATE_UNKNOWN;
96 } 98 }
97 99
98 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); 100 for(i = 0; i < chld_out.lines; i++) {
99 if (child_stderr == NULL)
100 printf (_("Could not open stderr for %s\n"), command_line);
101
102 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
103
104 /* the server is responding, we just got the host name... */ 101 /* the server is responding, we just got the host name... */
105 if (strstr (input_buffer, ";; ANSWER SECTION:")) { 102 if (strstr (chld_out.line[i], ";; ANSWER SECTION:")) {
106 103
107 /* loop through the whole 'ANSWER SECTION' */ 104 /* loop through the whole 'ANSWER SECTION' */
108 do { 105 for(; i < chld_out.lines; i++) {
109 /* get the host address */ 106 /* get the host address */
110 if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) 107 if (verbose)
111 break; 108 printf ("%s\n", chld_out.line[i]);
112
113 if (strpbrk (input_buffer, "\r\n"))
114 input_buffer[strcspn (input_buffer, "\r\n")] = '\0';
115 109
116 if (verbose && !strstr (input_buffer, ";; ")) 110 if (strstr (chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) {
117 printf ("%s\n", input_buffer); 111 msg = chld_out.line[i];
118
119 if (expected_address==NULL && strstr (input_buffer, query_address) != NULL) {
120 output = strdup(input_buffer);
121 result = STATE_OK; 112 result = STATE_OK;
122 }
123 else if (expected_address != NULL && strstr (input_buffer, expected_address) != NULL) {
124 output = strdup(input_buffer);
125 result = STATE_OK;
126 }
127
128 /* Translate output TAB -> SPACE */
129 t = output;
130 while ((t = index(t, '\t')) != NULL)
131 *t = ' ';
132 113
133 } while (!strstr (input_buffer, ";; ")); 114 /* Translate output TAB -> SPACE */
115 t = msg;
116 while ((t = strchr(t, '\t')) != NULL) *t = ' ';
117 break;
118 }
119 }
134 120
135 if (result == STATE_UNKNOWN) { 121 if (result == STATE_UNKNOWN) {
136 asprintf (&output, _("Server not found in ANSWER SECTION")); 122 msg = (char *)_("Server not found in ANSWER SECTION");
137 result = STATE_WARNING; 123 result = STATE_WARNING;
138 } 124 }
139 }
140
141 }
142
143 if (result == STATE_UNKNOWN) {
144 asprintf (&output, _("No ANSWER SECTION found"));
145 }
146 125
147 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 126 /* we found the answer section, so break out of the loop */
148 /* If we get anything on STDERR, at least set warning */ 127 break;
149 result = max_state (result, STATE_WARNING); 128 }
150 printf ("%s", input_buffer);
151 if (strlen (output) == 0)
152 output = strdup (1 + index (input_buffer, ':'));
153 } 129 }
154 130
155 (void) fclose (child_stderr); 131 if (result == STATE_UNKNOWN)
156 132 msg = (char *)_("No ANSWER SECTION found");
157 /* close the pipe */ 133
158 if (spclose (child_process)) { 134 /* If we get anything on STDERR, at least set warning */
159 result = max_state (result, STATE_WARNING); 135 if(chld_err.buflen > 0) {
160 if (strlen (output) == 0) 136 result = max_state(result, STATE_WARNING);
161 asprintf (&output, _("dig returned an error status")); 137 if(!msg) for(i = 0; i < chld_err.lines; i++) {
138 msg = strchr(chld_err.line[0], ':');
139 if(msg) {
140 msg++;
141 break;
142 }
143 }
162 } 144 }
163 145
164 microsec = deltime (tv); 146 microsec = deltime (tv);
165 elapsed_time = (double)microsec / 1.0e6; 147 elapsed_time = (double)microsec / 1.0e6;
166 148
167 if (output == NULL || strlen (output) == 0)
168 asprintf (&output, _(" Probably a non-existent host/domain"));
169
170 if (critical_interval > UNDEFINED && elapsed_time > critical_interval) 149 if (critical_interval > UNDEFINED && elapsed_time > critical_interval)
171 result = STATE_CRITICAL; 150 result = STATE_CRITICAL;
172 151
173 else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) 152 else if (warning_interval > UNDEFINED && elapsed_time > warning_interval)
174 result = STATE_WARNING; 153 result = STATE_WARNING;
175 154
176 asprintf (&output, _("%.3f seconds response time (%s)"), elapsed_time, output); 155 printf ("DNS %s - %.3f seconds response time (%s)|%s\n",
177 156 state_text (result), elapsed_time,
178 printf ("DNS %s - %s|%s\n", 157 msg ? msg : _("Probably a non-existent host/domain"),
179 state_text (result), output,
180 fperfdata("time", elapsed_time, "s", 158 fperfdata("time", elapsed_time, "s",
181 (warning_interval>UNDEFINED?TRUE:FALSE), 159 (warning_interval>UNDEFINED?TRUE:FALSE),
182 warning_interval, 160 warning_interval,
183 (critical_interval>UNDEFINED?TRUE:FALSE), 161 (critical_interval>UNDEFINED?TRUE:FALSE),
184 critical_interval, 162 critical_interval,
185 TRUE, 0, FALSE, 0)); 163 TRUE, 0, FALSE, 0));
186 return result; 164 return result;
187} 165}
188 166
@@ -219,8 +197,6 @@ process_arguments (int argc, char **argv)
219 break; 197 break;
220 198
221 switch (c) { 199 switch (c) {
222 case '?': /* help */
223 usage2 (_("Unknown argument"), optarg);
224 case 'h': /* help */ 200 case 'h': /* help */
225 print_help (); 201 print_help ();
226 exit (STATE_OK); 202 exit (STATE_OK);
@@ -228,19 +204,15 @@ process_arguments (int argc, char **argv)
228 print_revision (progname, revision); 204 print_revision (progname, revision);
229 exit (STATE_OK); 205 exit (STATE_OK);
230 case 'H': /* hostname */ 206 case 'H': /* hostname */
231 if (is_host (optarg)) { 207 host_or_die(optarg);
232 dns_server = optarg; 208 dns_server = optarg;
233 }
234 else {
235 usage2 (_("Invalid hostname/address"), optarg);
236 }
237 break; 209 break;
238 case 'p': /* server port */ 210 case 'p': /* server port */
239 if (is_intpos (optarg)) { 211 if (is_intpos (optarg)) {
240 server_port = atoi (optarg); 212 server_port = atoi (optarg);
241 } 213 }
242 else { 214 else {
243 usage2 (_("Port must be a positive integer"), optarg); 215 usage_va(_("Port must be a positive integer - %s"), optarg);
244 } 216 }
245 break; 217 break;
246 case 'l': /* address to lookup */ 218 case 'l': /* address to lookup */
@@ -251,7 +223,7 @@ process_arguments (int argc, char **argv)
251 warning_interval = strtod (optarg, NULL); 223 warning_interval = strtod (optarg, NULL);
252 } 224 }
253 else { 225 else {
254 usage2 (_("Warning interval must be a positive integer"), optarg); 226 usage_va(_("Warning interval must be a positive integer - %s"), optarg);
255 } 227 }
256 break; 228 break;
257 case 'c': /* critical */ 229 case 'c': /* critical */
@@ -259,7 +231,7 @@ process_arguments (int argc, char **argv)
259 critical_interval = strtod (optarg, NULL); 231 critical_interval = strtod (optarg, NULL);
260 } 232 }
261 else { 233 else {
262 usage2 (_("Critical interval must be a positive integer"), optarg); 234 usage_va(_("Critical interval must be a positive integer - %s"), optarg);
263 } 235 }
264 break; 236 break;
265 case 't': /* timeout */ 237 case 't': /* timeout */
@@ -267,7 +239,7 @@ process_arguments (int argc, char **argv)
267 timeout_interval = atoi (optarg); 239 timeout_interval = atoi (optarg);
268 } 240 }
269 else { 241 else {
270 usage2 (_("Timeout interval must be a positive integer"), optarg); 242 usage_va(_("Timeout interval must be a positive integer - %s"), optarg);
271 } 243 }
272 break; 244 break;
273 case 'v': /* verbose */ 245 case 'v': /* verbose */
@@ -279,18 +251,16 @@ process_arguments (int argc, char **argv)
279 case 'a': 251 case 'a':
280 expected_address = optarg; 252 expected_address = optarg;
281 break; 253 break;
254 default: /* usage_va */
255 usage_va(_("Unknown argument - %s"), optarg);
282 } 256 }
283 } 257 }
284 258
285 c = optind; 259 c = optind;
286 if (dns_server == NULL) { 260 if (dns_server == NULL) {
287 if (c < argc) { 261 if (c < argc) {
288 if (is_host (argv[c])) { 262 host_or_die(argv[c]);
289 dns_server = argv[c]; 263 dns_server = argv[c];
290 }
291 else {
292 usage2 (_("Invalid hostname/address"), argv[c]);
293 }
294 } 264 }
295 else { 265 else {
296 dns_server = strdup ("127.0.0.1"); 266 dns_server = strdup ("127.0.0.1");
@@ -359,6 +329,6 @@ print_usage (void)
359{ 329{
360 printf ("\ 330 printf ("\
361Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\ 331Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\
362 [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\ 332 [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\
363 [-a <expected answer address>] [-v]\n", progname); 333 [-a <expected answer address>] [-v]\n", progname);
364} 334}
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index 94d4300c..d6e8ca29 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -27,9 +27,9 @@ const char *copyright = "2000-2004";
27const char *email = "nagiosplug-devel@lists.sourceforge.net"; 27const char *email = "nagiosplug-devel@lists.sourceforge.net";
28 28
29#include "common.h" 29#include "common.h"
30#include "popen.h"
31#include "utils.h" 30#include "utils.h"
32#include "netutils.h" 31#include "netutils.h"
32#include "runcmd.h"
33 33
34int process_arguments (int, char **); 34int process_arguments (int, char **);
35int validate_arguments (void); 35int validate_arguments (void);
@@ -51,8 +51,8 @@ main (int argc, char **argv)
51{ 51{
52 char *command_line = NULL; 52 char *command_line = NULL;
53 char input_buffer[MAX_INPUT_BUFFER]; 53 char input_buffer[MAX_INPUT_BUFFER];
54 char *output = NULL;
55 char *address = NULL; 54 char *address = NULL;
55 char *msg = NULL;
56 char *temp_buffer = NULL; 56 char *temp_buffer = NULL;
57 int non_authoritative = FALSE; 57 int non_authoritative = FALSE;
58 int result = STATE_UNKNOWN; 58 int result = STATE_UNKNOWN;
@@ -61,6 +61,8 @@ main (int argc, char **argv)
61 struct timeval tv; 61 struct timeval tv;
62 int multi_address; 62 int multi_address;
63 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ 63 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */
64 output chld_out, chld_err;
65 size_t i;
64 66
65 setlocale (LC_ALL, ""); 67 setlocale (LC_ALL, "");
66 bindtextdomain (PACKAGE, LOCALEDIR); 68 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -68,11 +70,11 @@ main (int argc, char **argv)
68 70
69 /* Set signal handling and alarm */ 71 /* Set signal handling and alarm */
70 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { 72 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
71 usage4 (_("Cannot catch SIGALRM")); 73 usage_va(_("Cannot catch SIGALRM"));
72 } 74 }
73 75
74 if (process_arguments (argc, argv) == ERROR) { 76 if (process_arguments (argc, argv) == ERROR) {
75 usage4 (_("Could not parse arguments")); 77 usage_va(_("Could not parse arguments"));
76 } 78 }
77 79
78 /* get the command to run */ 80 /* get the command to run */
@@ -85,37 +87,31 @@ main (int argc, char **argv)
85 printf ("%s\n", command_line); 87 printf ("%s\n", command_line);
86 88
87 /* run the command */ 89 /* run the command */
88 child_process = spopen (command_line); 90 if((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) {
89 if (child_process == NULL) { 91 msg = (char *)_("nslookup returned error status");
90 printf (_("Could not open pipe: %s\n"), command_line); 92 result = STATE_WARNING;
91 return STATE_UNKNOWN;
92 } 93 }
93 94
94 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
95 if (child_stderr == NULL)
96 printf (_("Could not open stderr for %s\n"), command_line);
97
98 /* scan stdout */ 95 /* scan stdout */
99 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 96 for(i = 0; i < chld_out.lines; i++) {
100
101 if (verbose) 97 if (verbose)
102 printf ("%s", input_buffer); 98 puts(chld_out.line[i]);
103 99
104 if (strstr (input_buffer, ".in-addr.arpa")) { 100 if (strstr (chld_out.line[i], ".in-addr.arpa")) {
105 if ((temp_buffer = strstr (input_buffer, "name = "))) 101 if ((temp_buffer = strstr (chld_out.line[i], "name = ")))
106 address = strdup (temp_buffer + 7); 102 address = strdup (temp_buffer + 7);
107 else { 103 else {
108 output = strdup (_("Warning plugin error")); 104 msg = (char *)_("Warning plugin error");
109 result = STATE_WARNING; 105 result = STATE_WARNING;
110 } 106 }
111 } 107 }
112 108
113 /* the server is responding, we just got the host name... */ 109 /* the server is responding, we just got the host name... */
114 if (strstr (input_buffer, "Name:")) 110 if (strstr (chld_out.line[i], "Name:"))
115 parse_address = TRUE; 111 parse_address = TRUE;
116 else if (parse_address == TRUE && (strstr (input_buffer, "Address:") || 112 else if (parse_address == TRUE && (strstr (chld_out.line[i], "Address:") ||
117 strstr (input_buffer, "Addresses:"))) { 113 strstr (chld_out.line[i], "Addresses:"))) {
118 temp_buffer = index (input_buffer, ':'); 114 temp_buffer = index (chld_out.line[i], ':');
119 temp_buffer++; 115 temp_buffer++;
120 116
121 /* Strip leading spaces */ 117 /* Strip leading spaces */
@@ -135,59 +131,47 @@ main (int argc, char **argv)
135 asprintf(&address, "%s,%s", address, temp_buffer); 131 asprintf(&address, "%s,%s", address, temp_buffer);
136 } 132 }
137 133
138 else if (strstr (input_buffer, _("Non-authoritative answer:"))) { 134 else if (strstr (chld_out.line[i], _("Non-authoritative answer:"))) {
139 non_authoritative = TRUE; 135 non_authoritative = TRUE;
140 } 136 }
141 137
142 result = error_scan (input_buffer); 138 result = error_scan (chld_out.line[i]);
143 if (result != STATE_OK) { 139 if (result != STATE_OK) {
144 output = strdup (1 + index (input_buffer, ':')); 140 msg = strchr (chld_out.line[i], ':');
145 strip (output); 141 if(msg) msg++;
146 break; 142 break;
147 } 143 }
148
149 } 144 }
150 145
151 /* scan stderr */ 146 /* scan stderr */
152 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 147 for(i = 0; i < chld_err.lines; i++) {
153
154 if (verbose) 148 if (verbose)
155 printf ("%s", input_buffer); 149 puts(chld_err.line[i]);
156 150
157 if (error_scan (input_buffer) != STATE_OK) { 151 if (error_scan (chld_err.line[i]) != STATE_OK) {
158 result = max_state (result, error_scan (input_buffer)); 152 result = max_state (result, error_scan (chld_err.line[i]));
159 output = strdup (1 + index (input_buffer, ':')); 153 msg = strchr(input_buffer, ':');
160 strip (output); 154 if(msg) msg++;
161 } 155 }
162 } 156 }
163 157
164 /* close stderr */ 158 /* If we got here, we should have an address string,
165 (void) fclose (child_stderr); 159 * and we can segfault if we do not */
166
167 /* close stdout */
168 if (spclose (child_process)) {
169 result = max_state (result, STATE_WARNING);
170 if (output == NULL || !strcmp (output, ""))
171 output = strdup (_("nslookup returned error status"));
172 }
173
174 /* If we got here, we should have an address string,
175 and we can segfault if we do not */
176 if (address==NULL || strlen(address)==0) 160 if (address==NULL || strlen(address)==0)
177 die (STATE_CRITICAL, 161 die (STATE_CRITICAL,
178 _("DNS CRITICAL - '%s' output parsing exited with no address\n"), 162 _("DNS CRITICAL - '%s' msg parsing exited with no address\n"),
179 NSLOOKUP_COMMAND); 163 NSLOOKUP_COMMAND);
180 164
181 /* compare to expected address */ 165 /* compare to expected address */
182 if (result == STATE_OK && match_expected_address && strcmp(address, expected_address)) { 166 if (result == STATE_OK && match_expected_address && strcmp(address, expected_address)) {
183 result = STATE_CRITICAL; 167 result = STATE_CRITICAL;
184 asprintf(&output, _("expected %s but got %s"), expected_address, address); 168 asprintf(&msg, _("expected %s but got %s"), expected_address, address);
185 } 169 }
186 170
187 /* check if authoritative */ 171 /* check if authoritative */
188 if (result == STATE_OK && expect_authority && non_authoritative) { 172 if (result == STATE_OK && expect_authority && non_authoritative) {
189 result = STATE_CRITICAL; 173 result = STATE_CRITICAL;
190 asprintf(&output, _("server %s is not authoritative for %s"), dns_server, query_address); 174 asprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address);
191 } 175 }
192 176
193 microsec = deltime (tv); 177 microsec = deltime (tv);
@@ -200,19 +184,19 @@ main (int argc, char **argv)
200 multi_address = TRUE; 184 multi_address = TRUE;
201 185
202 printf ("DNS %s: ", _("OK")); 186 printf ("DNS %s: ", _("OK"));
203 printf (ngettext("%.3f second response time ", "%.3f seconds response time ", elapsed_time), elapsed_time); 187 printf (ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time);
204 printf (_("%s returns %s"), query_address, address); 188 printf (_(". %s returns %s"), query_address, address);
205 printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0)); 189 printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
206 } 190 }
207 else if (result == STATE_WARNING) 191 else if (result == STATE_WARNING)
208 printf (_("DNS WARNING - %s\n"), 192 printf (_("DNS WARNING - %s\n"),
209 !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); 193 !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg);
210 else if (result == STATE_CRITICAL) 194 else if (result == STATE_CRITICAL)
211 printf (_("DNS CRITICAL - %s\n"), 195 printf (_("DNS CRITICAL - %s\n"),
212 !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); 196 !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg);
213 else 197 else
214 printf (_("DNS UNKNOW - %s\n"), 198 printf (_("DNS UNKNOW - %s\n"),
215 !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); 199 !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg);
216 200
217 return result; 201 return result;
218} 202}
@@ -311,8 +295,6 @@ process_arguments (int argc, char **argv)
311 break; 295 break;
312 296
313 switch (c) { 297 switch (c) {
314 case '?': /* args not parsable */
315 usage2 (_("Unknown argument"), optarg);
316 case 'h': /* help */ 298 case 'h': /* help */
317 print_help (); 299 print_help ();
318 exit (STATE_OK); 300 exit (STATE_OK);
@@ -331,20 +313,16 @@ process_arguments (int argc, char **argv)
331 strcpy (query_address, optarg); 313 strcpy (query_address, optarg);
332 break; 314 break;
333 case 's': /* server name */ 315 case 's': /* server name */
334 /* TODO: this is_host check is probably unnecessary. */ 316 /* TODO: this host_or_die check is probably unnecessary.
335 /* Better to confirm nslookup response matches */ 317 * Better to confirm nslookup response matches */
336 if (is_host (optarg) == FALSE) { 318 host_or_die(optarg);
337 usage2 (_("Invalid hostname/address"), optarg);
338 }
339 if (strlen (optarg) >= ADDRESS_LENGTH) 319 if (strlen (optarg) >= ADDRESS_LENGTH)
340 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 320 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
341 strcpy (dns_server, optarg); 321 strcpy (dns_server, optarg);
342 break; 322 break;
343 case 'r': /* reverse server name */ 323 case 'r': /* reverse server name */
344 /* TODO: Is this is_host necessary? */ 324 /* TODO: Is this host_or_die necessary? */
345 if (is_host (optarg) == FALSE) { 325 host_or_die(optarg);
346 usage2 (_("Invalid hostname/address"), optarg);
347 }
348 if (strlen (optarg) >= ADDRESS_LENGTH) 326 if (strlen (optarg) >= ADDRESS_LENGTH)
349 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 327 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
350 strcpy (ptr_server, optarg); 328 strcpy (ptr_server, optarg);
@@ -358,6 +336,8 @@ process_arguments (int argc, char **argv)
358 case 'A': /* expect authority */ 336 case 'A': /* expect authority */
359 expect_authority = TRUE; 337 expect_authority = TRUE;
360 break; 338 break;
339 default: /* args not parsable */
340 usage_va(_("Unknown argument - %s"), optarg);
361 } 341 }
362 } 342 }
363 343
@@ -370,10 +350,7 @@ process_arguments (int argc, char **argv)
370 350
371 if (strlen(dns_server)==0 && c<argc) { 351 if (strlen(dns_server)==0 && c<argc) {
372 /* TODO: See -s option */ 352 /* TODO: See -s option */
373 if (is_host(argv[c]) == FALSE) { 353 host_or_die(argv[c]);
374 printf (_("Invalid hostname/address: %s\n\n"), argv[c]);
375 return ERROR;
376 }
377 if (strlen(argv[c]) >= ADDRESS_LENGTH) 354 if (strlen(argv[c]) >= ADDRESS_LENGTH)
378 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 355 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
379 strcpy (dns_server, argv[c++]); 356 strcpy (dns_server, argv[c++]);
@@ -388,8 +365,8 @@ validate_arguments ()
388{ 365{
389 if (query_address[0] == 0) 366 if (query_address[0] == 0)
390 return ERROR; 367 return ERROR;
391 else 368
392 return OK; 369 return OK;
393} 370}
394 371
395 372
diff --git a/plugins/check_game.c b/plugins/check_game.c
index 08b04d6d..912072c2 100644
--- a/plugins/check_game.c
+++ b/plugins/check_game.c
@@ -23,8 +23,8 @@ const char *copyright = "2002-2004";
23const char *email = "nagiosplug-devel@lists.sourceforge.net"; 23const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 24
25#include "common.h" 25#include "common.h"
26#include "popen.h"
27#include "utils.h" 26#include "utils.h"
27#include "runcmd.h"
28 28
29int process_arguments (int, char **); 29int process_arguments (int, char **);
30int validate_arguments (void); 30int validate_arguments (void);
@@ -57,16 +57,16 @@ main (int argc, char **argv)
57 char *command_line; 57 char *command_line;
58 int result = STATE_UNKNOWN; 58 int result = STATE_UNKNOWN;
59 FILE *fp; 59 FILE *fp;
60 char input_buffer[MAX_INPUT_BUFFER];
61 char *p, *ret[QSTAT_MAX_RETURN_ARGS]; 60 char *p, *ret[QSTAT_MAX_RETURN_ARGS];
62 int i; 61 size_t i = 0;
62 output chld_out;
63 63
64 setlocale (LC_ALL, ""); 64 setlocale (LC_ALL, "");
65 bindtextdomain (PACKAGE, LOCALEDIR); 65 bindtextdomain (PACKAGE, LOCALEDIR);
66 textdomain (PACKAGE); 66 textdomain (PACKAGE);
67 67
68 if (process_arguments (argc, argv) == ERROR) 68 if (process_arguments (argc, argv) == ERROR)
69 usage4 (_("Could not parse arguments")); 69 usage_va(_("Could not parse arguments"));
70 70
71 result = STATE_OK; 71 result = STATE_OK;
72 72
@@ -80,17 +80,9 @@ main (int argc, char **argv)
80 if (verbose > 0) 80 if (verbose > 0)
81 printf ("%s\n", command_line); 81 printf ("%s\n", command_line);
82 82
83 /* run the command */ 83 /* run the command. historically, this plugin ignores output on stderr,
84 fp = spopen (command_line); 84 * as well as return status of the qstat program */
85 if (fp == NULL) { 85 (void)np_runcmd(command_line, &chld_out, NULL, 0);
86 printf (_("Could not open pipe: %s\n"), command_line);
87 return STATE_UNKNOWN;
88 }
89
90 fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */
91
92 /* strip the newline character from the end of the input */
93 input_buffer[strlen (input_buffer) - 1] = 0;
94 86
95 /* sanity check */ 87 /* sanity check */
96 /* was thinking about running qstat without any options, capturing the 88 /* was thinking about running qstat without any options, capturing the
@@ -102,18 +94,13 @@ main (int argc, char **argv)
102 In the end, I figured I'd simply let an error occur & then trap it 94 In the end, I figured I'd simply let an error occur & then trap it
103 */ 95 */
104 96
105 if (!strncmp (input_buffer, "unknown option", 14)) { 97 if (!strncmp (chld_out.line[0], "unknown option", 14)) {
106 printf (_("CRITICAL - Host type parameter incorrect!\n")); 98 printf (_("CRITICAL - Host type parameter incorrect!\n"));
107 result = STATE_CRITICAL; 99 result = STATE_CRITICAL;
108 return result; 100 return result;
109 } 101 }
110 102
111 /* initialize the returned data buffer */ 103 p = (char *) strtok (chld_out.line[0], QSTAT_DATA_DELIMITER);
112 for (i = 0; i < QSTAT_MAX_RETURN_ARGS; i++)
113 ret[i] = strdup("");
114
115 i = 0;
116 p = (char *) strtok (input_buffer, QSTAT_DATA_DELIMITER);
117 while (p != NULL) { 104 while (p != NULL) {
118 ret[i] = p; 105 ret[i] = p;
119 p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER); 106 p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER);
@@ -141,17 +128,14 @@ main (int argc, char **argv)
141 ret[qstat_game_field], 128 ret[qstat_game_field],
142 ret[qstat_map_field], 129 ret[qstat_map_field],
143 ret[qstat_ping_field], 130 ret[qstat_ping_field],
144 perfdata ("players", atol(ret[qstat_game_players]), "", 131 perfdata ("players", atol(ret[qstat_game_players]), "",
145 FALSE, 0, FALSE, 0, 132 FALSE, 0, FALSE, 0,
146 TRUE, 0, TRUE, atol(ret[qstat_game_players_max])), 133 TRUE, 0, TRUE, atol(ret[qstat_game_players_max])),
147 fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "", 134 fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "",
148 FALSE, 0, FALSE, 0, 135 FALSE, 0, FALSE, 0,
149 TRUE, 0, FALSE, 0)); 136 TRUE, 0, FALSE, 0));
150 } 137 }
151 138
152 /* close the pipe */
153 spclose (fp);
154
155 return result; 139 return result;
156} 140}
157 141
@@ -197,8 +181,6 @@ process_arguments (int argc, char **argv)
197 break; 181 break;
198 182
199 switch (c) { 183 switch (c) {
200 case '?': /* args not parsable */
201 usage2 (_("Unknown argument"), optarg);
202 case 'h': /* help */ 184 case 'h': /* help */
203 print_help (); 185 print_help ();
204 exit (STATE_OK); 186 exit (STATE_OK);
@@ -251,6 +233,8 @@ process_arguments (int argc, char **argv)
251 if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) 233 if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
252 return ERROR; 234 return ERROR;
253 break; 235 break;
236 default: /* args not parsable */
237 usage_va(_("Unknown argument - %s"), optarg);
254 } 238 }
255 } 239 }
256 240
@@ -328,8 +312,8 @@ void
328print_usage (void) 312print_usage (void)
329{ 313{
330 printf ("\ 314 printf ("\
331Usage: %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field]\n\ 315Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field]\n\
332 [-p ping_field] [-G game-time] [-H hostname] <game> <ip_address>\n", progname); 316 [-pf ping_field]\n", progname);
333} 317}
334 318
335/****************************************************************************** 319/******************************************************************************
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c
index 089ff669..0ae488ff 100644
--- a/plugins/check_nagios.c
+++ b/plugins/check_nagios.c
@@ -24,7 +24,7 @@ const char *copyright = "1999-2004";
24const char *email = "nagiosplug-devel@lists.sourceforge.net"; 24const char *email = "nagiosplug-devel@lists.sourceforge.net";
25 25
26#include "common.h" 26#include "common.h"
27#include "popen.h" 27#include "runcmd.h"
28#include "utils.h" 28#include "utils.h"
29 29
30int process_arguments (int, char **); 30int process_arguments (int, char **);
@@ -55,6 +55,8 @@ main (int argc, char **argv)
55 int procrss = 0; 55 int procrss = 0;
56 float procpcpu = 0; 56 float procpcpu = 0;
57 char procstat[8]; 57 char procstat[8];
58 /* procetime is unused in most configurations, but may be in PS_VAR_LIST
59 * so it must be here in spite of it producing compiler warnings */
58 char procetime[MAX_INPUT_BUFFER]; 60 char procetime[MAX_INPUT_BUFFER];
59 char procprog[MAX_INPUT_BUFFER]; 61 char procprog[MAX_INPUT_BUFFER];
60 char *procargs; 62 char *procargs;
@@ -62,17 +64,19 @@ main (int argc, char **argv)
62 int expected_cols = PS_COLS - 1; 64 int expected_cols = PS_COLS - 1;
63 const char *zombie = "Z"; 65 const char *zombie = "Z";
64 char *temp_string; 66 char *temp_string;
67 output chld_out, chld_err;
68 size_t i;
65 69
66 setlocale (LC_ALL, ""); 70 setlocale (LC_ALL, "");
67 bindtextdomain (PACKAGE, LOCALEDIR); 71 bindtextdomain (PACKAGE, LOCALEDIR);
68 textdomain (PACKAGE); 72 textdomain (PACKAGE);
69 73
70 if (process_arguments (argc, argv) == ERROR) 74 if (process_arguments (argc, argv) == ERROR)
71 usage4 (_("Could not parse arguments")); 75 usage_va(_("Could not parse arguments"));
72 76
73 /* Set signal handling and alarm timeout */ 77 /* Set signal handling and alarm timeout */
74 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 78 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
75 usage4 (_("Cannot catch SIGALRM")); 79 usage_va(_("Cannot catch SIGALRM"));
76 } 80 }
77 81
78 /* handle timeouts gracefully... */ 82 /* handle timeouts gracefully... */
@@ -99,40 +103,30 @@ main (int argc, char **argv)
99 printf(_("command: %s\n"), PS_COMMAND); 103 printf(_("command: %s\n"), PS_COMMAND);
100 104
101 /* run the command to check for the Nagios process.. */ 105 /* run the command to check for the Nagios process.. */
102 child_process = spopen (PS_COMMAND); 106 if((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
103 if (child_process == NULL) { 107 result = STATE_WARNING;
104 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
105 return STATE_UNKNOWN;
106 }
107
108 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
109 if (child_stderr == NULL) {
110 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
111 }
112
113 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
114 108
115 /* count the number of matching Nagios processes... */ 109 /* count the number of matching Nagios processes... */
116 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 110 for(i = 0; i < chld_out.lines; i++) {
117 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST); 111 cols = sscanf (chld_out.line[i], PS_FORMAT, PS_VARLIST);
118 /* Zombie processes do not give a procprog command */ 112 /* Zombie processes do not give a procprog command */
119 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) { 113 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
120 cols = expected_cols; 114 cols = expected_cols;
121 /* Set some value for procargs for the strip command further below 115 /* Set some value for procargs for the strip command further below
122 Seen to be a problem on some Solaris 7 and 8 systems */ 116 * Seen to be a problem on some Solaris 7 and 8 systems */
123 input_buffer[pos] = '\n'; 117 chld_out.line[i][pos] = '\n';
124 input_buffer[pos+1] = 0x0; 118 chld_out.line[i][pos+1] = 0x0;
125 } 119 }
126 if ( cols >= expected_cols ) { 120 if ( cols >= expected_cols ) {
127 asprintf (&procargs, "%s", input_buffer + pos); 121 asprintf (&procargs, "%s", chld_out.line[i] + pos);
128 strip (procargs); 122 strip (procargs);
129 123
130 /* Some ps return full pathname for command. This removes path */ 124 /* Some ps return full pathname for command. This removes path */
131 temp_string = strtok ((char *)procprog, "/"); 125 temp_string = strtok ((char *)procprog, "/");
132 while (temp_string) { 126 while (temp_string) {
133 strcpy(procprog, temp_string); 127 strcpy(procprog, temp_string);
134 temp_string = strtok (NULL, "/"); 128 temp_string = strtok (NULL, "/");
135 } 129 }
136 130
137 /* May get empty procargs */ 131 /* May get empty procargs */
138 if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) { 132 if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) {
@@ -145,14 +139,7 @@ main (int argc, char **argv)
145 } 139 }
146 140
147 /* If we get anything on stderr, at least set warning */ 141 /* If we get anything on stderr, at least set warning */
148 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) 142 if(chld_err.buflen)
149 result = max_state (result, STATE_WARNING);
150
151 /* close stderr */
152 (void) fclose (child_stderr);
153
154 /* close the pipe */
155 if (spclose (child_process))
156 result = max_state (result, STATE_WARNING); 143 result = max_state (result, STATE_WARNING);
157 144
158 /* reset the alarm handler */ 145 /* reset the alarm handler */
@@ -219,8 +206,6 @@ process_arguments (int argc, char **argv)
219 break; 206 break;
220 207
221 switch (c) { 208 switch (c) {
222 case '?': /* print short usage statement if args not parsable */
223 usage2 (_("Unknown argument"), optarg);
224 case 'h': /* help */ 209 case 'h': /* help */
225 print_help (); 210 print_help ();
226 exit (STATE_OK); 211 exit (STATE_OK);
@@ -243,16 +228,17 @@ process_arguments (int argc, char **argv)
243 case 'v': 228 case 'v':
244 verbose++; 229 verbose++;
245 break; 230 break;
231 default: /* print short usage_va statement if args not parsable */
232 usage_va(_("Unknown argument - %s"), optarg);
246 } 233 }
247 } 234 }
248 235
249 236
250 if (status_log == NULL) 237 if (status_log == NULL)
251 die (STATE_UNKNOWN, 238 die (STATE_UNKNOWN, _("You must provide the status_log\n"));
252 _("You must provide the status_log\n")); 239
253 else if (process_string == NULL) 240 if (process_string == NULL)
254 die (STATE_UNKNOWN, 241 die (STATE_UNKNOWN, _("You must provide a process string\n"));
255 _("You must provide a process string\n"));
256 242
257 return OK; 243 return OK;
258} 244}
diff --git a/plugins/netutils.c b/plugins/netutils.c
index db64ef09..08245276 100644
--- a/plugins/netutils.c
+++ b/plugins/netutils.c
@@ -291,6 +291,13 @@ is_host (const char *address)
291 return (FALSE); 291 return (FALSE);
292} 292}
293 293
294void
295host_or_die(const char *str)
296{
297 if(!str || (!is_addr(str) && !is_hostname(str)))
298 usage_va(_("Invalid hostname/address - %s"), str);
299}
300
294int 301int
295is_addr (const char *address) 302is_addr (const char *address)
296{ 303{
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index 14300ee5..4155796c 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -16,6 +16,8 @@
16 * 16 *
17 */ 17 */
18 18
19#define NAGIOSPLUG_API_C 1
20
19/** includes **/ 21/** includes **/
20#include "runcmd.h" 22#include "runcmd.h"
21#ifdef HAVE_SYS_WAIT_H 23#ifdef HAVE_SYS_WAIT_H
@@ -45,20 +47,17 @@
45 * occur in any number of threads simultaneously. */ 47 * occur in any number of threads simultaneously. */
46static pid_t *np_pids = NULL; 48static pid_t *np_pids = NULL;
47 49
48/* If OPEN_MAX isn't defined, we try the sysconf syscall first. 50/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
49 * If that fails, we fall back to an educated guess which is accurate 51 * If that fails and the macro isn't defined, we fall back to an educated
50 * on Linux and some other systems. There's no guarantee that our guess is 52 * guess. There's no guarantee that our guess is adequate and the program
51 * adequate and the program will die with SIGSEGV if it isn't and the 53 * will die with SIGSEGV if it isn't and the upper boundary is breached. */
52 * upper boundary is breached. */ 54#ifdef _SC_OPEN_MAX
53#ifdef OPEN_MAX 55static long maxfd = 0;
56#elif defined(OPEN_MAX)
54# define maxfd OPEN_MAX 57# define maxfd OPEN_MAX
55#else 58#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
56# ifndef _SC_OPEN_MAX /* sysconf macro unavailable, so guess */ 59# define maxfd 256
57# define maxfd 256 60#endif
58# else
59static int maxfd = 0;
60# endif /* _SC_OPEN_MAX */
61#endif /* OPEN_MAX */
62 61
63 62
64/** prototypes **/ 63/** prototypes **/
@@ -70,7 +69,7 @@ static int np_fetch_output(int, output *, int)
70 69
71static int np_runcmd_close(int); 70static int np_runcmd_close(int);
72 71
73/* imported from utils.h */ 72/* prototype imported from utils.h */
74extern void die (int, const char *, ...) 73extern void die (int, const char *, ...)
75 __attribute__((__noreturn__,__format__(__printf__, 2, 3))); 74 __attribute__((__noreturn__,__format__(__printf__, 2, 3)));
76 75
@@ -80,13 +79,11 @@ extern void die (int, const char *, ...)
80 * through this api and thus achieve async-safeness throughout the api */ 79 * through this api and thus achieve async-safeness throughout the api */
81void np_runcmd_init(void) 80void np_runcmd_init(void)
82{ 81{
83#if !defined(OPEN_MAX) && defined(_SC_OPEN_MAX) 82#ifndef maxfd
84 if(!maxfd) { 83 if(!maxfd && (maxfd = sysconf(_SC_OPEN_MAX)) < 0) {
85 if((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { 84 /* possibly log or emit a warning here, since there's no
86 /* possibly log or emit a warning here, since there's no 85 * guarantee that our guess at maxfd will be adequate */
87 * guarantee that our guess at maxfd will be adequate */ 86 maxfd = 256;
88 maxfd = 256;
89 }
90 } 87 }
91#endif 88#endif
92 89
@@ -123,9 +120,9 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
123 /* make copy of command string so strtok() doesn't silently modify it */ 120 /* make copy of command string so strtok() doesn't silently modify it */
124 /* (the calling program may want to access it later) */ 121 /* (the calling program may want to access it later) */
125 cmdlen = strlen(cmdstring); 122 cmdlen = strlen(cmdstring);
126 cmd = malloc(cmdlen + 1); 123 if((cmd = malloc(cmdlen + 1)) == NULL) return -1;
127 if (cmd == NULL) return -1;
128 memcpy(cmd, cmdstring, cmdlen); 124 memcpy(cmd, cmdstring, cmdlen);
125 cmd[cmdlen] = '\0';
129 126
130 /* This is not a shell, so we don't handle "???" */ 127 /* This is not a shell, so we don't handle "???" */
131 if (strstr (cmdstring, "\"")) return -1; 128 if (strstr (cmdstring, "\"")) return -1;
@@ -257,7 +254,7 @@ popen_timeout_alarm_handler (int signo)
257static int 254static int
258np_fetch_output(int fd, output *op, int flags) 255np_fetch_output(int fd, output *op, int flags)
259{ 256{
260 size_t len = 0, i = 0; 257 size_t len = 0, i = 0, lineno = 0;
261 size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ 258 size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */
262 char *buf = NULL; 259 char *buf = NULL;
263 int ret; 260 int ret;
@@ -278,13 +275,12 @@ np_fetch_output(int fd, output *op, int flags)
278 return ret; 275 return ret;
279 } 276 }
280 277
281 if(!op->buf || !op->buflen) return 0; 278 /* some plugins may want to keep output unbroken, and some commands
282 279 * will yield no output, so return here for those */
283 /* some plugins may want to keep output unbroken */ 280 if(flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen)
284 if(flags & RUNCMD_NO_ARRAYS)
285 return op->buflen; 281 return op->buflen;
286 282
287 /* and some may want both (*sigh*) */ 283 /* and some may want both */
288 if(flags & RUNCMD_NO_ASSOC) { 284 if(flags & RUNCMD_NO_ASSOC) {
289 buf = malloc(op->buflen); 285 buf = malloc(op->buflen);
290 memcpy(buf, op->buf, op->buflen); 286 memcpy(buf, op->buf, op->buflen);
@@ -293,30 +289,34 @@ np_fetch_output(int fd, output *op, int flags)
293 289
294 op->line = NULL; 290 op->line = NULL;
295 op->lens = NULL; 291 op->lens = NULL;
296 len = i = 0; 292 i = 0;
297 while(i < op->buflen) { 293 while(i < op->buflen) {
298 /* make sure we have enough memory */ 294 /* make sure we have enough memory */
299 if(len >= ary_size) { 295 if(lineno >= ary_size) {
300 ary_size = op->buflen >> --rsf; 296 /* ary_size must never be zero */
297 do {
298 ary_size = op->buflen >> --rsf;
299 } while(!ary_size);
300
301 op->line = realloc(op->line, ary_size * sizeof(char *)); 301 op->line = realloc(op->line, ary_size * sizeof(char *));
302 op->lens = realloc(op->lens, ary_size * sizeof(size_t)); 302 op->lens = realloc(op->lens, ary_size * sizeof(size_t));
303 } 303 }
304 304
305 /* set the pointer to the string */ 305 /* set the pointer to the string */
306 op->line[len] = &buf[i]; 306 op->line[lineno] = &buf[i];
307 307
308 /* hop to next newline or end of buffer */ 308 /* hop to next newline or end of buffer */
309 while(buf[i] != '\n' && i < op->buflen) i++; 309 while(buf[i] != '\n' && i < op->buflen) i++;
310 buf[i] = '\0'; 310 buf[i] = '\0';
311 311
312 /* calculate the string length using pointer difference */ 312 /* calculate the string length using pointer difference */
313 op->lens[len] = (size_t)&buf[i] - (size_t)op->line[len]; 313 op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno];
314 314
315 len++; 315 lineno++;
316 i++; 316 i++;
317 } 317 }
318 318
319 return len; 319 return lineno;
320} 320}
321 321
322 322
diff --git a/plugins/utils.c b/plugins/utils.c
index b9a19d3f..8b31c5a2 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -58,6 +58,17 @@ void usage (const char *msg)
58 exit (STATE_UNKNOWN); 58 exit (STATE_UNKNOWN);
59} 59}
60 60
61void usage_va (const char *fmt, ...)
62{
63 va_list ap;
64 printf("%s: ", progname);
65 va_start(ap, fmt);
66 vprintf(fmt, ap);
67 va_end(ap);
68 printf("\n");
69 exit (STATE_UNKNOWN);
70}
71
61void usage2(const char *msg, const char *arg) 72void usage2(const char *msg, const char *arg)
62{ 73{
63 printf ("%s: %s - %s\n",progname,msg,arg); 74 printf ("%s: %s - %s\n",progname,msg,arg);
diff --git a/plugins/utils.h b/plugins/utils.h
index bdf1ee1f..ffdb5457 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -1,3 +1,5 @@
1#ifndef NP_UTILS_H
2#define NP_UTILS_H
1/* Header file for nagios plugins utils.c */ 3/* Header file for nagios plugins utils.c */
2 4
3/* This file should be included in all plugins */ 5/* This file should be included in all plugins */
@@ -77,6 +79,7 @@ void usage (const char *) __attribute__((noreturn));
77void usage2(const char *, const char *) __attribute__((noreturn)); 79void usage2(const char *, const char *) __attribute__((noreturn));
78void usage3(const char *, int) __attribute__((noreturn)); 80void usage3(const char *, int) __attribute__((noreturn));
79void usage4(const char *); 81void usage4(const char *);
82void usage_va(const char *fmt, ...);
80 83
81const char *state_text (int); 84const char *state_text (int);
82 85
@@ -169,3 +172,5 @@ send email to nagiosplug-devel@lists.sourceforge.net\n"
169The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ 172The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
170copies of the plugins under the terms of the GNU General Public License.\n\ 173copies of the plugins under the terms of the GNU General Public License.\n\
171For more information about these matters, see the file named COPYING.\n" 174For more information about these matters, see the file named COPYING.\n"
175
176#endif /* NP_UTILS_H */