Code

Initial revision
[nagiosplug.git] / plugins / check_ftp.c
1 /******************************************************************************
2  *
3  * CHECK_FTP.C
4  *
5  * Program: FTP 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 FTP 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_ftp"
44 #define FTP_PORT        21
45 #define FTP_EXPECT      "220"
46 #define FTP_QUIT        "QUIT\n"
48 int process_arguments (int, char **);
49 int call_getopt (int, char **);
50 void print_usage (void);
51 void print_help (void);
53 time_t start_time, end_time;
54 int server_port = FTP_PORT;
55 char *server_address = NULL;
56 char *server_expect = NULL;
57 int warning_time = 0;
58 int check_warning_time = FALSE;
59 int critical_time = 0;
60 int check_critical_time = FALSE;
61 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) == ERROR)
72                 usage ("Could not parse arguments\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 FTP 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)) {
104                                 if (server_port == FTP_PORT)
105                                         printf ("Invalid FTP response received from host\n");
106                                 else
107                                         printf ("Invalid FTP response received from host on port %d\n",
108                                                                         server_port);
109                                 result = STATE_WARNING;
110                         }
112                         else {
113                                 time (&end_time);
115                                 result = STATE_OK;
117                                 if (check_critical_time == TRUE
118                                                 && (end_time - start_time) > critical_time) result =
119                                                 STATE_CRITICAL;
120                                 else if (check_warning_time == TRUE
121                                                                  && (end_time - start_time) > warning_time) result =
122                                                 STATE_WARNING;
124                                 if (verbose == TRUE)
125                                         printf ("FTP %s - %d sec. response time, %s\n",
126                                                                         (result == STATE_OK) ? "ok" : "problem",
127                                                                         (int) (end_time - start_time), buffer);
128                                 else
129                                         printf ("FTP %s - %d second response time\n",
130                                                                         (result == STATE_OK) ? "ok" : "problem",
131                                                                         (int) (end_time - start_time));
132                         }
133                 }
135                 /* close the connection */
136                 send (sd, FTP_QUIT, strlen (FTP_QUIT), 0);
137                 close (sd);
138         }
140         /* reset the alarm */
141         alarm (0);
143         return result;
151 /* process command-line arguments */
152 int
153 process_arguments (int argc, char **argv)
155         int c;
157         if (argc < 2)
158                 usage ("\n");
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         }
169         c = 0;
170         while ((c += call_getopt (argc - c, &argv[c])) < argc) {
172                 if (is_option (argv[c]))
173                         continue;
175                 if (server_address == NULL) {
176                         if (argc > c) {
177                                 if (is_host (argv[c]) == FALSE)
178                                         usage ("Invalid host name/address\n");
179                                 server_address = argv[c];
180                         }
181                         else {
182                                 usage ("Host name was not supplied\n");
183                         }
184                 }
185         }
187         if (server_expect == NULL)
188                 server_expect = strscpy (NULL, FTP_EXPECT);
190         return OK;
197 int
198 call_getopt (int argc, char **argv)
200         int c, i = 0;
202 #ifdef HAVE_GETOPT_H
203         int option_index = 0;
204         static struct option long_options[] = {
205                 {"hostname", required_argument, 0, 'H'},
206                 {"expect", required_argument, 0, 'e'},
207                 {"critical", required_argument, 0, 'c'},
208                 {"warning", required_argument, 0, 'w'},
209                 {"timeout", required_argument, 0, 'w'},
210                 {"port", required_argument, 0, 'p'},
211                 {"verbose", no_argument, 0, 'v'},
212                 {"version", no_argument, 0, 'V'},
213                 {"help", no_argument, 0, 'h'},
214                 {0, 0, 0, 0}
215         };
216 #endif
218         while (1) {
219 #ifdef HAVE_GETOPT_H
220                 c =
221                         getopt_long (argc, argv, "+hVvH:e:c:w:t:p:", long_options,
222                                                                          &option_index);
223 #else
224                 c = getopt (argc, argv, "+hVvH:e:c:w:t:p:");
225 #endif
227                 i++;
229                 if (c == -1 || c == EOF || c == 1)
230                         break;
232                 switch (c) {
233                 case 'H':
234                 case 'e':
235                 case 'c':
236                 case 'w':
237                 case 't':
238                 case 'p':
239                         i++;
240                 }
242                 switch (c) {
243                 case '?':                                                                       /* print short usage statement if args not parsable */
244                         printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg);
245                         print_usage ();
246                         exit (STATE_UNKNOWN);
247                 case 'h':                                                                       /* help */
248                         print_help ();
249                         exit (STATE_OK);
250                 case 'V':                                                                       /* version */
251                         print_revision (my_basename (argv[0]), "$Revision$");
252                         exit (STATE_OK);
253                 case 'v':                                                                       /* verbose mode */
254                         verbose = TRUE;
255                         break;
256                 case 'H':                                                                       /* hostname */
257                         if (is_host (optarg) == FALSE)
258                                 usage ("Invalid host name/address\n");
259                         server_address = optarg;
260                         break;
261                 case 'e':                                                                       /* expect */
262                         server_expect = optarg;
263                         break;
264                 case 'c':                                                                       /* critical */
265                         if (!is_intnonneg (optarg))
266                                 usage ("Critical threshold must be a nonnegative integer\n");
267                         critical_time = atoi (optarg);
268                         check_critical_time = TRUE;
269                         break;
270                 case 'w':                                                                       /* warning */
271                         if (!is_intnonneg (optarg))
272                                 usage ("Warning threshold must be a nonnegative integer\n");
273                         warning_time = atoi (optarg);
274                         check_warning_time = TRUE;
275                         break;
276                 case 't':                                                                       /* timeout */
277                         if (!is_intnonneg (optarg))
278                                 usage ("Timeout interval must be a nonnegative integer\n");
279                         socket_timeout = atoi (optarg);
280                         break;
281                 case 'p':                                                                       /* port */
282                         if (!is_intnonneg (optarg))
283                                 usage ("Serevr port must be a nonnegative integer\n");
284                         server_port = atoi (optarg);
285                         break;
286                 }
287         }
288         return i;
295 void
296 print_usage (void)
298         printf
299                 ("Usage: %s -H <host_address> [-e expect] [-p port] [-w warn_time]\n"
300                  "         [-c crit_time] [-t to_sec] [-v]\n", PROGNAME);
307 void
308 print_help (void)
310         print_revision (PROGNAME, "$Revision$");
311         printf
312                 ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n"
313                  "This plugin tests an FTP connection with the specified host.\n\n");
314         print_usage ();
315         printf
316                 ("Options:\n"
317                  " -H, --hostname=ADDRESS\n"
318                  "    Host name argument for servers using host headers (use numeric\n"
319                  "    address if possible to bypass DNS lookup).\n"
320                  " -e, --expect=STRING\n"
321                  "    String to expect in first line of server response (default: %s)\n"
322                  " -p, --port=INTEGER\n"
323                  "    Port number (default: %d)\n"
324                  " -w, --warning=INTEGER\n"
325                  "    Response time to result in warning status (seconds)\n"
326                  " -c, --critical=INTEGER\n"
327                  "    Response time to result in critical status (seconds)\n"
328                  " -t, --timeout=INTEGER\n"
329                  "    Seconds before connection times out (default: %d)\n"
330                  " -v"
331                  "    Show details for command-line debugging (do not use with nagios server)\n"
332                  " -h, --help\n"
333                  "    Print detailed help screen\n"
334                  " -V, --version\n"
335                  "    Print version information\n",
336                  FTP_EXPECT, FTP_PORT, DEFAULT_SOCKET_TIMEOUT);