Code

fixes for using POSIX return codes
[nagiosplug.git] / plugins / check_pop.c
1 /******************************************************************************
2  *
3  * CHECK_POP.C
4  *
5  * Program: POP3 plugin for Nagios
6  * License: GPL
7  * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
8  *
9  * $Id$
10  *
11  * Description:
12  *
13  * This plugin will attempt to open an POP connection with the host.
14  * Successul connects return STATE_OK, refusals and timeouts return
15  * STATE_CRITICAL, other errors return STATE_UNKNOWN.  Successful
16  * connects, but incorrect reponse messages from the host result in
17  * STATE_WARNING return values.
18  *
19  * License Information:
20  *
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU General Public License as published by
23  * the Free Software Foundation; either version 2 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34  *
35  *****************************************************************************/
37 #include "config.h"
38 #include "common.h"
39 #include "netutils.h"
40 #include "utils.h"
42 #define PROGNAME "check_pop"
44 #define POP_PORT        110
45 #define POP_EXPECT     "+OK"
46 #define POP_QUIT        "QUIT\n"
48 int process_arguments (int, char **);
49 int call_getopt (int, char **);
50 int validate_arguments (void);
51 int check_disk (int usp, int free_disk);
52 void print_help (void);
53 void print_usage (void);
55 int server_port = POP_PORT;
56 char *server_address = NULL;
57 char *server_expect = NULL;
58 int warning_time = 0;
59 int check_warning_time = FALSE;
60 int critical_time = 0;
61 int check_critical_time = FALSE;
62 int verbose = FALSE;
64 int
65 main (int argc, char **argv)
66 {
67         int sd;
68         int result;
69         char buffer[MAX_INPUT_BUFFER];
71         if (process_arguments (argc, argv) != OK)
72                 usage ("Invalid command arguments supplied\n");
74         /* initialize alarm signal handling */
75         signal (SIGALRM, socket_timeout_alarm_handler);
77         /* set socket timeout */
78         alarm (socket_timeout);
80         /* try to connect to the host at the given port number */
81         time (&start_time);
82         result = my_tcp_connect (server_address, server_port, &sd);
84         /* we connected, so close connection before exiting */
85         if (result == STATE_OK) {
87                 /* watch for the SMTP connection string */
88                 result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
90                 /* strip the buffer of carriage returns */
91                 strip (buffer);
93                 /* return a WARNING status if we couldn't read any data */
94                 if (result == -1) {
95                         printf ("recv() failed\n");
96                         result = STATE_WARNING;
97                 }
99                 else {
101                         /* make sure we find the response we are looking for */
102                         if (!strstr (buffer, server_expect)) {
103                                 if (server_port == POP_PORT)
104                                         printf ("Invalid POP response received from host\n");
105                                 else
106                                         printf ("Invalid POP response received from host on port %d\n",
107                                                                         server_port);
108                                 result = STATE_WARNING;
109                         }
111                         else {
112                                 time (&end_time);
114                                 result = STATE_OK;
116                                 if (check_critical_time == TRUE
117                                                 && (end_time - start_time) > critical_time) result =
118                                                 STATE_CRITICAL;
119                                 else if (check_warning_time == TRUE
120                                                                  && (end_time - start_time) > warning_time) result =
121                                                 STATE_WARNING;
123                                 if (verbose == TRUE)
124                                         printf ("POP %s - %d sec. response time, %s\n",
125                                                                         (result == STATE_OK) ? "ok" : "problem",
126                                                                         (int) (end_time - start_time), buffer);
127                                 else
128                                         printf ("POP %s - %d second response time\n",
129                                                                         (result == STATE_OK) ? "ok" : "problem",
130                                                                         (int) (end_time - start_time));
131                         }
132                 }
134                 /* close the connection */
135                 send (sd, POP_QUIT, strlen (POP_QUIT), 0);
136                 close (sd);
137         }
139         /* reset the alarm */
140         alarm (0);
142         return result;
151 /* process command-line arguments */
152 int
153 process_arguments (int argc, char **argv)
155         int c;
157         if (argc < 2)
158                 return ERROR;
160         for (c = 1; c < argc; c++) {
161                 if (strcmp ("-to", argv[c]) == 0)
162                         strcpy (argv[c], "-t");
163                 else if (strcmp ("-wt", argv[c]) == 0)
164                         strcpy (argv[c], "-w");
165                 else if (strcmp ("-ct", argv[c]) == 0)
166                         strcpy (argv[c], "-c");
167         }
171         c = 0;
172         while ((c += (call_getopt (argc - c, &argv[c]))) < argc) {
174                 if (is_option (argv[c]))
175                         continue;
177                 if (server_address == NULL) {
178                         if (is_host (argv[c])) {
179                                 server_address = argv[c];
180                         }
181                         else {
182                                 usage ("Invalid host name");
183                         }
184                 }
185         }
187         if (server_address == NULL)
188                 server_address = strscpy (NULL, "127.0.0.1");
190         if (server_expect == NULL)
191                 server_expect = strscpy (NULL, POP_EXPECT);
193         return validate_arguments ();
201 int
202 call_getopt (int argc, char **argv)
204         int c, i = 0;
206 #ifdef HAVE_GETOPT_H
207         int option_index = 0;
208         static struct option long_options[] = {
209                 {"hostname", required_argument, 0, 'H'},
210                 {"expect", required_argument, 0, 'e'},
211                 {"critical", required_argument, 0, 'c'},
212                 {"warning", required_argument, 0, 'w'},
213                 {"port", required_argument, 0, 'P'},
214                 {"verbose", no_argument, 0, 'v'},
215                 {"version", no_argument, 0, 'V'},
216                 {"help", no_argument, 0, 'h'},
217                 {0, 0, 0, 0}
218         };
219 #endif
221         while (1) {
222 #ifdef HAVE_GETOPT_H
223                 c =
224                         getopt_long (argc, argv, "+hVvt:p:e:c:w:H:", long_options,
225                                                                          &option_index);
226 #else
227                 c = getopt (argc, argv, "+?hVvt:p:e:c:w:H:");
228 #endif
230                 i++;
232                 if (c == -1 || c == EOF || c == 1)
233                         break;
235                 switch (c) {
236                 case 't':
237                 case 'p':
238                 case 'e':
239                 case 'c':
240                 case 'w':
241                 case 'H':
242                         i++;
243                 }
245                 switch (c) {
246                 case 'H':                                                                       /* hostname */
247                         if (is_host (optarg)) {
248                                 server_address = optarg;
249                         }
250                         else {
251                                 usage ("Invalid host name\n");
252                         }
253                         break;
254                 case 'p':                                                                       /* port */
255                         if (is_intpos (optarg)) {
256                                 server_port = atoi (optarg);
257                         }
258                         else {
259                                 usage ("Server port must be a positive integer\n");
260                         }
261                         break;
262                 case 'e':                                                                       /* username */
263                         server_expect = optarg;
264                         break;
265                 case 'c':                                                                       /* critical time threshold */
266                         if (is_intnonneg (optarg)) {
267                                 critical_time = atoi (optarg);
268                                 check_critical_time = TRUE;
269                         }
270                         else {
271                                 usage ("Critical time must be a nonnegative integer\n");
272                         }
273                         break;
274                 case 'w':                                                                       /* warning time threshold */
275                         if (is_intnonneg (optarg)) {
276                                 warning_time = atoi (optarg);
277                                 check_warning_time = TRUE;
278                         }
279                         else {
280                                 usage ("Warning time must be a nonnegative integer\n");
281                         }
282                         break;
283                 case 'v':                                                                       /* verbose */
284                         verbose = TRUE;
285                         break;
286                 case 't':                                                                       /* timeout */
287                         if (is_intnonneg (optarg)) {
288                                 socket_timeout = atoi (optarg);
289                         }
290                         else {
291                                 usage ("Time interval must be a nonnegative integer\n");
292                         }
293                         break;
294                 case 'V':                                                                       /* version */
295                         print_revision (PROGNAME, "$Revision$");
296                         exit (STATE_OK);
297                 case 'h':                                                                       /* help */
298                         print_help ();
299                         exit (STATE_OK);
300                 case '?':                                                                       /* help */
301                         usage ("Invalid argument\n");
302                 }
303         }
304         return i;
311 int
312 validate_arguments (void)
314         return OK;
321 void
322 print_help (void)
324         print_revision (PROGNAME, "$Revision$");
325         printf
326                 ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n"
327                  "This plugin tests the POP service on the specified host.\n\n");
328         print_usage ();
329         printf
330                 ("\nOptions:\n"
331                  " -H, --hostname=STRING or IPADDRESS\n"
332                  "   Check server on the indicated host\n"
333                  " -p, --port=INTEGER\n"
334                  "   Make connection on the indicated port (default: %d)\n"
335                  " -e, --expect=STRING\n"
336                  "   String to expect in first line of server response (default: %s)\n"
337                  " -w, --warning=INTEGER\n"
338                  "   Seconds necessary to result in a warning status\n"
339                  " -c, --critical=INTEGER\n"
340                  "   Seconds necessary to result in a critical status\n"
341                  " -t, --timeout=INTEGER\n"
342                  "   Seconds before connection attempt times out (default: %d)\n"
343                  " -v, --verbose\n"
344                  "   Print extra information (command-line use only)\n"
345                  " -h, --help\n"
346                  "   Print detailed help screen\n"
347                  " -V, --version\n"
348                  "   Print version information\n\n",
349                  POP_PORT, POP_EXPECT, DEFAULT_SOCKET_TIMEOUT);
350         support ();
357 void
358 print_usage (void)
360         printf
361                 ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n"
362                  "       %s --help\n"
363                  "       %s --version\n", PROGNAME, PROGNAME, PROGNAME);