Code

Standardising translation texts
[nagiosplug.git] / plugins / check_nagios.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 const char *progname = "check_nagios";
20 const char *revision = "$Revision$";
21 const char *copyright = "1999-2003";
22 const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 #include "common.h"
25 #include "popen.h"
26 #include "utils.h"
28 int process_arguments (int, char **);
29 void print_help (void);
30 void print_usage (void);
32 char *status_log = NULL;
33 char *process_string = NULL;
34 int expire_minutes = 0;
36 int verbose = 0;
38 int
39 main (int argc, char **argv)
40 {
41         int result = STATE_UNKNOWN;
42         char input_buffer[MAX_INPUT_BUFFER];
43         unsigned long latest_entry_time = 0L;
44         unsigned long temp_entry_time = 0L;
45         int proc_entries = 0;
46         time_t current_time;
47         char *temp_ptr;
48         FILE *fp;
49         int procuid = 0;
50         int procppid = 0;
51         int procvsz = 0;
52         int procrss = 0;
53         float procpcpu = 0;
54         char procstat[8];
55         char procprog[MAX_INPUT_BUFFER];
56         char *procargs;
57         int pos, cols;
58         int expected_cols = PS_COLS - 1;
59         const char *zombie = "Z";
60         char *temp_string;
62         setlocale (LC_ALL, "");
63         bindtextdomain (PACKAGE, LOCALEDIR);
64         textdomain (PACKAGE);
66         if (process_arguments (argc, argv) == ERROR)
67                 usage (_("Could not parse arguments\n"));
69         /* Set signal handling and alarm */
70         if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
71                 printf (_("Cannot catch SIGALRM"));
72                 return STATE_UNKNOWN;
73         }
75         /* handle timeouts gracefully... */
76         alarm (timeout_interval);
78         /* open the status log */
79         fp = fopen (status_log, "r");
80         if (fp == NULL) {
81                 printf (_("Error: Cannot open status log for reading!\n"));
82                 return STATE_CRITICAL;
83         }
85         /* get the date/time of the last item updated in the log */
86         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
87                 temp_ptr = strtok (input_buffer, "]");
88                 temp_entry_time =
89                         (temp_ptr == NULL) ? 0L : strtoul (temp_ptr + 1, NULL, 10);
90                 if (temp_entry_time > latest_entry_time)
91                         latest_entry_time = temp_entry_time;
92         }
93         fclose (fp);
95         if (verbose >= 2)
96                 printf("command: %s\n", PS_COMMAND);
98         /* run the command to check for the Nagios process.. */
99         child_process = spopen (PS_COMMAND);
100         if (child_process == NULL) {
101                 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
102                 return STATE_UNKNOWN;
103         }
105         child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
106         if (child_stderr == NULL) {
107                 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
108         }
110         fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
112         /* count the number of matching Nagios processes... */
113         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
114                 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST);
115                 /* Zombie processes do not give a procprog command */
116                 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
117                         cols = expected_cols;
118                         /* Set some value for procargs for the strip command further below
119                         Seen to be a problem on some Solaris 7 and 8 systems */
120                         input_buffer[pos] = '\n';
121                         input_buffer[pos+1] = 0x0;
122                 }
123                 if ( cols >= expected_cols ) {
124                         asprintf (&procargs, "%s", input_buffer + pos);
125                         strip (procargs);
126                         
127                         /* Some ps return full pathname for command. This removes path */
128                         temp_string = strtok ((char *)procprog, "/");
129                         while (temp_string) {
130                                 strcpy(procprog, temp_string);
131                                 temp_string = strtok (NULL, "/");
132                         }
134                         /* May get empty procargs */
135                         if (!strstr(procargs, argv[0]) && strstr(procprog, process_string) && strcmp(procargs,"")) {
136                                 proc_entries++;
137                                 if (verbose >= 2) {
138                                         printf (_("Found process: %s %s\n"), procprog, procargs);
139                                 }
140                         }
141                 }
142         }
144         /* If we get anything on stderr, at least set warning */
145         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
146                 result = max_state (result, STATE_WARNING);
148         /* close stderr */
149         (void) fclose (child_stderr);
151         /* close the pipe */
152         if (spclose (child_process))
153                 result = max_state (result, STATE_WARNING);
155         /* reset the alarm handler */
156         alarm (0);
158         if (proc_entries == 0) {
159                 printf (_("Could not locate a running Nagios process!\n"));
160                 return STATE_CRITICAL;
161         }
163         result = STATE_OK;
165         time (&current_time);
166         if ((int)(current_time - latest_entry_time) > (expire_minutes * 60))
167                 result = STATE_WARNING;
169         printf
170                 (_("Nagios %s: located %d process%s, status log updated %d second%s ago\n"),
171                  (result == STATE_OK) ? "ok" : "problem", proc_entries,
172                  (proc_entries == 1) ? "" : "es",
173                  (int) (current_time - latest_entry_time),
174                  ((int) (current_time - latest_entry_time) == 1) ? "" : "s");
176         return result;
183 /* process command-line arguments */
184 int
185 process_arguments (int argc, char **argv)
187         int c;
189         int option = 0;
190         static struct option longopts[] = {
191                 {"filename", required_argument, 0, 'F'},
192                 {"expires", required_argument, 0, 'e'},
193                 {"command", required_argument, 0, 'C'},
194                 {"version", no_argument, 0, 'V'},
195                 {"help", no_argument, 0, 'h'},
196                 {"verbose", no_argument, 0, 'v'},
197                 {0, 0, 0, 0}
198         };
200         if (argc < 2)
201                 return ERROR;
203         if (!is_option (argv[1])) {
204                 status_log = argv[1];
205                 if (is_intnonneg (argv[2]))
206                         expire_minutes = atoi (argv[2]);
207                 else
208                         die (STATE_UNKNOWN,
209                                                                  _("Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n"),
210                                                                  progname);
211                 process_string = argv[3];
212                 return OK;
213         }
215         while (1) {
216                 c = getopt_long (argc, argv, "+hVvF:C:e:", longopts, &option);
218                 if (c == -1 || c == EOF || c == 1)
219                         break;
221                 switch (c) {
222                 case '?':                                                                       /* print short usage statement if args not parsable */
223                         printf (_("%s: Unknown argument: %c\n\n"), progname, optopt);
224                         print_usage ();
225                         exit (STATE_UNKNOWN);
226                 case 'h':                                                                       /* help */
227                         print_help ();
228                         exit (STATE_OK);
229                 case 'V':                                                                       /* version */
230                         print_revision (progname, "$Revision$");
231                         exit (STATE_OK);
232                 case 'F':                                                                       /* status log */
233                         status_log = optarg;
234                         break;
235                 case 'C':                                                                       /* command */
236                         process_string = optarg;
237                         break;
238                 case 'e':                                                                       /* expiry time */
239                         if (is_intnonneg (optarg))
240                                 expire_minutes = atoi (optarg);
241                         else
242                                 die (STATE_UNKNOWN,
243                                      _("Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n"),
244                                      progname);
245                         break;
246                 case 'v':
247                         verbose++;
248                         break;
249                 }
250         }
253         if (status_log == NULL)
254                 die (STATE_UNKNOWN,
255                      _("You must provide the status_log\nType '%s -h' for additional help\n"),
256                      progname);
257         else if (process_string == NULL)
258                 die (STATE_UNKNOWN,
259                                                          _("You must provide a process string\nType '%s -h' for additional help\n"),
260                                                          progname);
262         return OK;
269 \f
270 void
271 print_help (void)
273         print_revision (progname, revision);
275         printf (_(COPYRIGHT), copyright, email);
277         printf (_("\
278 This plugin attempts to check the status of the Nagios process on the local\n\
279 machine. The plugin will check to make sure the Nagios status log is no older\n\
280 than the number of minutes specified by the <expire_minutes> option.  It also\n\
281 uses the /bin/ps command to check for a process matching whatever you specify\n\
282 by the <process_string> argument.\n"));
284         print_usage ();
286         printf (_(UT_HELP_VRSN));
288         printf (_("\
289 -F, --filename=FILE\n\
290    Name of the log file to check\n\
291 -e, --expires=INTEGER\n\
292    Seconds aging afterwhich logfile is condsidered stale\n\
293 -C, --command=STRING\n\
294    Command to search for in process table\n"));
296         printf (_("\
297 Example:\n\
298    ./check_nagios -e 5 \\\
299    -F /usr/local/nagios/var/status.log \\\
300    -C /usr/local/nagios/bin/nagios\n"));
306 void
307 print_usage (void)
309         printf (_("\
310 Usage: %s -F <status log file> -e <expire_minutes> -C <process_string>\n"),
311                 progname);