Code

49e7c87daf4d7d2d2a7e041f8806eda67dfa210f
[nagiosplug.git] / plugins / check_time.c
1 /******************************************************************************
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; either version 2 of the License, or
6  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 ******************************************************************************/
19 #include "common.h"
20 #include "netutils.h"
21 #include "utils.h"
23 const char *progname = "check_time";
24 const char *revision = "$Revision$";
25 const char *copyright = "1999-2003";
26 const char *email = "nagiosplug-devel@lists.sourceforge.net";
28 enum {
29         TIME_PORT = 37
30 };
32 #define UNIX_EPOCH 2208988800UL
34 unsigned long server_time, raw_server_time;
35 time_t diff_time;
36 int warning_time = 0;
37 int check_warning_time = FALSE;
38 int critical_time = 0;
39 int check_critical_time = FALSE;
40 unsigned long warning_diff = 0;
41 int check_warning_diff = FALSE;
42 unsigned long critical_diff = 0;
43 int check_critical_diff = FALSE;
44 int server_port = TIME_PORT;
45 char *server_address = NULL;
47 int process_arguments (int, char **);
48 void print_help (void);
49 void print_usage (void);
51 int
52 main (int argc, char **argv)
53 {
54         int sd;
55         int result;
57         if (process_arguments (argc, argv) != OK)
58                 usage (_("Invalid command arguments supplied\n"));
60         /* initialize alarm signal handling */
61         signal (SIGALRM, socket_timeout_alarm_handler);
63         /* set socket timeout */
64         alarm (socket_timeout);
65         time (&start_time);
67         /* try to connect to the host at the given port number */
68         if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) {
69                 if (check_critical_time == TRUE)
70                         result = STATE_CRITICAL;
71                 else if (check_warning_time == TRUE)
72                         result = STATE_WARNING;
73                 else
74                         result = STATE_UNKNOWN;
75                 die (result,
76                            _("TIME UNKNOWN - could not connect to server %s, port %d\n"),
77                            server_address, server_port);
78         }
80         /* watch for the connection string */
81         result = recv (sd, (void *)&raw_server_time, sizeof (raw_server_time), 0);
83         /* close the connection */
84         close (sd);
86         /* reset the alarm */
87         time (&end_time);
88         alarm (0);
90         /* return a WARNING status if we couldn't read any data */
91         if (result <= 0) {
92                 if (check_critical_time == TRUE)
93                         result = STATE_CRITICAL;
94                 else if (check_warning_time == TRUE)
95                         result = STATE_WARNING;
96                 else
97                         result = STATE_UNKNOWN;
98                 die (result,
99                                                          _("TIME UNKNOWN - no data on recv() from server %s, port %d\n"),
100                                                          server_address, server_port);
101         }
103         result = STATE_OK;
105         if (check_critical_time == TRUE && (end_time - start_time) > critical_time)
106                 result = STATE_CRITICAL;
107         else if (check_warning_time == TRUE
108                                          && (end_time - start_time) > warning_time) result = STATE_WARNING;
110         if (result != STATE_OK)
111                 die (result, _("TIME %s - %d second response time\n"),
112                                                          state_text (result), (int) (end_time - start_time));
114         server_time = ntohl (raw_server_time) - UNIX_EPOCH;
115         if (server_time > (unsigned long)end_time)
116                 diff_time = server_time - (unsigned long)end_time;
117         else
118                 diff_time = (unsigned long)end_time - server_time;
120         if (check_critical_diff == TRUE && diff_time > (time_t)critical_diff)
121                 result = STATE_CRITICAL;
122         else if (check_warning_diff == TRUE && diff_time > (time_t)warning_diff)
123                 result = STATE_WARNING;
125         printf (_("TIME %s - %lu second time difference\n"), state_text (result),
126                                         diff_time);
127         return result;
135 /* process command-line arguments */
136 int
137 process_arguments (int argc, char **argv)
139         int c;
141         int option = 0;
142         static struct option longopts[] = {
143                 {"hostname", required_argument, 0, 'H'},
144                 {"warning-variance", required_argument, 0, 'w'},
145                 {"critical-variance", required_argument, 0, 'c'},
146                 {"warning-connect", required_argument, 0, 'W'},
147                 {"critical-connect", required_argument, 0, 'C'},
148                 {"port", required_argument, 0, 'p'},
149                 {"timeout", required_argument, 0, 't'},
150                 {"version", no_argument, 0, 'V'},
151                 {"help", no_argument, 0, 'h'},
152                 {0, 0, 0, 0}
153         };
155         if (argc < 2)
156                 usage ("\n");
158         for (c = 1; c < argc; c++) {
159                 if (strcmp ("-to", argv[c]) == 0)
160                         strcpy (argv[c], "-t");
161                 else if (strcmp ("-wd", argv[c]) == 0)
162                         strcpy (argv[c], "-w");
163                 else if (strcmp ("-cd", argv[c]) == 0)
164                         strcpy (argv[c], "-c");
165                 else if (strcmp ("-wt", argv[c]) == 0)
166                         strcpy (argv[c], "-W");
167                 else if (strcmp ("-ct", argv[c]) == 0)
168                         strcpy (argv[c], "-C");
169         }
171         while (1) {
172                 c = getopt_long (argc, argv, "hVH:w:c:W:C:p:t:", longopts,
173                                                                          &option);
175                 if (c == -1 || c == EOF)
176                         break;
178                 switch (c) {
179                 case '?':                                                                       /* print short usage statement if args not parsable */
180                         usage3 (_("Unknown argument"), optopt);
181                 case 'h':                                                                       /* help */
182                         print_help ();
183                         exit (STATE_OK);
184                 case 'V':                                                                       /* version */
185                         print_revision (progname, revision);
186                         exit (STATE_OK);
187                 case 'H':                                                                       /* hostname */
188                         if (is_host (optarg) == FALSE)
189                                 usage (_("Invalid host name/address\n"));
190                         server_address = optarg;
191                         break;
192                 case 'w':                                                                       /* warning-variance */
193                         if (is_intnonneg (optarg)) {
194                                 warning_diff = strtoul (optarg, NULL, 10);
195                                 check_warning_diff = TRUE;
196                         }
197                         else if (strspn (optarg, "0123456789:,") > 0) {
198                                 if (sscanf (optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) {
199                                         check_warning_diff = TRUE;
200                                         check_warning_time = TRUE;
201                                 }
202                                 else {
203                                         usage (_("Warning thresholds must be a nonnegative integer\n"));
204                                 }
205                         }
206                         else {
207                                 usage (_("Warning threshold must be a nonnegative integer\n"));
208                         }
209                         break;
210                 case 'c':                                                                       /* critical-variance */
211                         if (is_intnonneg (optarg)) {
212                                 critical_diff = strtoul (optarg, NULL, 10);
213                                 check_critical_diff = TRUE;
214                         }
215                         else if (strspn (optarg, "0123456789:,") > 0) {
216                                 if (sscanf (optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) ==
217                                                 2) {
218                                         check_critical_diff = TRUE;
219                                         check_critical_time = TRUE;
220                                 }
221                                 else {
222                                         usage (_("Critical thresholds must be a nonnegative integer\n"));
223                                 }
224                         }
225                         else {
226                                 usage (_("Critical threshold must be a nonnegative integer\n"));
227                         }
228                         break;
229                 case 'W':                                                                       /* warning-connect */
230                         if (!is_intnonneg (optarg))
231                                 usage (_("Warning threshold must be a nonnegative integer\n"));
232                         else
233                                 warning_time = atoi (optarg);
234                         check_warning_time = TRUE;
235                         break;
236                 case 'C':                                                                       /* critical-connect */
237                         if (!is_intnonneg (optarg))
238                                 usage (_("Critical threshold must be a nonnegative integer\n"));
239                         else
240                                 critical_time = atoi (optarg);
241                         check_critical_time = TRUE;
242                         break;
243                 case 'p':                                                                       /* port */
244                         if (!is_intnonneg (optarg))
245                                 usage (_("Server port must be a nonnegative integer\n"));
246                         else
247                                 server_port = atoi (optarg);
248                         break;
249                 case 't':                                                                       /* timeout */
250                         if (!is_intnonneg (optarg))
251                                 usage (_("Timeout interval must be a nonnegative integer\n"));
252                         else
253                                 socket_timeout = atoi (optarg);
254                         break;
255                 }
256         }
258         c = optind;
259         if (server_address == NULL) {
260                 if (argc > c) {
261                         if (is_host (argv[c]) == FALSE)
262                                 usage (_("Invalid host name/address\n"));
263                         server_address = argv[c];
264                 }
265                 else {
266                         usage (_("Host name was not supplied\n"));
267                 }
268         }
270         return OK;
277 \f
278 void
279 print_help (void)
281         char *myport;
282         asprintf (&myport, "%d", TIME_PORT);
284         print_revision (progname, revision);
286         printf (_("Copyright (c) 1999 Ethan Galstad\n"));
287         printf (_(COPYRIGHT), copyright, email);
289         printf (_("\
290 This plugin will check the time on the specified host.\n\n"));
292         print_usage ();
294         printf (_(UT_HELP_VRSN));
296         printf (_(UT_HOST_PORT), 'p', myport);
298         printf (_("\
299  -w, --warning-variance=INTEGER\n\
300     Time difference (sec.) necessary to result in a warning status\n\
301  -c, --critical-variance=INTEGER\n\
302     Time difference (sec.) necessary to result in a critical status\n\
303  -W, --warning-connect=INTEGER\n\
304     Response time (sec.) necessary to result in warning status\n\
305  -C, --critical-connect=INTEGER\n\
306     Response time (sec.) necessary to result in critical status\n"));
308         printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
310         printf (_(UT_SUPPORT));
316 void
317 print_usage (void)
319         printf (_("\
320 Usage: %s -H <host_address> [-p port] [-w variance] [-c variance]\n\
321     [-W connect_time] [-C connect_time] [-t timeout]\n"), progname);
322         printf (_(UT_HLP_VRS), progname, progname);