Code

Initial revision
[nagiosplug.git] / plugins / check_users.c
1 /******************************************************************************
2  *
3  * CHECK_USERS.C
4  *
5  * Program: Current users plugin for Nagios
6  * License: GPL
7  * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
8  *
9  * Last Modified: $Date$
10  * Modifications: 
11  *
12  * 1999-11-17 Karl DeBisschop
13  *  - check stderr and status from spoen/spclose
14  *  - reformat commenst to fit 80-cahr screen
15  *  - set default result to STATE_UNKNOWN
16  *  - initialize users at -1, eliminate 'found' variable
17  *
18  * Command line: CHECK_USERS <wusers> <cusers>
19  *
20  * Description:
21  *
22  * This plugin will use the /usr/bin/who command to check the number
23  * of users currently logged into the system.  If number of logged in
24  * user exceeds the number specified by the <cusers> option, a
25  * STATE_CRITICAL is return.  It it exceeds <wusers>, a STATE_WARNING
26  * is returned.  Errors reading the output from the who command result
27  * in a STATE_UNKNOWN error.
28  *
29  * License Information:
30  *
31  * This program is free software; you can redistribute it and/or modify
32  * it under the terms of the GNU General Public License as published by
33  * the Free Software Foundation; either version 2 of the License, or
34  * (at your option) any later version.
35  *
36  * This program is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39  * GNU General Public License for more details.
40  *
41  * You should have received a copy of the GNU General Public License
42  * along with this program; if not, write to the Free Software
43  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
44  *
45  *****************************************************************************/
47 #include "common.h"
48 #include "popen.h"
49 #include "utils.h"
51 #define PROGNAME "check_users"
53 #define possibly_set(a,b) ((a) == 0 ? (b) : 0)
55 int process_arguments (int, char **);
56 int call_getopt (int, char **);
57 void print_usage (void);
58 void print_help (void);
60 int wusers = -1;
61 int cusers = -1;
63 int
64 main (int argc, char **argv)
65 {
66         int users = -1;
67         int result = STATE_OK;
68         char input_buffer[MAX_INPUT_BUFFER];
70         if (process_arguments (argc, argv) == ERROR)
71                 usage ("Could not parse arguments\n");
73         /* run the command */
74         child_process = spopen (WHO_COMMAND);
75         if (child_process == NULL) {
76                 printf ("Could not open pipe: %s\n", WHO_COMMAND);
77                 return STATE_UNKNOWN;
78         }
80         child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
81         if (child_stderr == NULL)
82                 printf ("Could not open stderr for %s\n", WHO_COMMAND);
84         users = 0;
86         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
88                 /* increment 'users' on all lines except total user count */
89                 if (input_buffer[0] != '#') {
90                         users++;
91                         continue;
92                 }
94                 /* get total logged in users */
95                 if (sscanf (input_buffer, "# users=%d", &users) == 1)
96                         break;
98         }
100         /* check STDERR */
101         if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
102                 result = possibly_set (result, STATE_UNKNOWN);
103         (void) fclose (child_stderr);
105         /* close the pipe */
106         if (spclose (child_process))
107                 result = possibly_set (result, STATE_UNKNOWN);
109         /* else check the user count against warning and critical thresholds */
110         if (users >= cusers)
111                 result = STATE_CRITICAL;
112         else if (users >= wusers)
113                 result = STATE_WARNING;
114         else if (users >= 0)
115                 result = STATE_OK;
117         if (result == STATE_UNKNOWN)
118                 printf ("Unable to read output\n");
119         else
120                 printf ("USERS %s - %d users currently logged in\n", state_text (result),
121                                                 users);
123         return result;
130 /* process command-line arguments */
131 int
132 process_arguments (int argc, char **argv)
134         int c;
136         if (argc < 2)
137                 usage ("\n");
139         c = 0;
140         while ((c += call_getopt (argc - c, &argv[c])) < argc) {
142                 if (is_option (argv[c]))
143                         continue;
145                 if (wusers == -1 && argc > c) {
146                         if (is_intnonneg (argv[c]) == FALSE)
147                                 usage ("Warning threshold must be a nonnegative integer\n");
148                         wusers = atoi (argv[c]);
150                 }
151                 else if (cusers == -1 && argc > c) {
152                         if (is_intnonneg (argv[c]) == FALSE)
153                                 usage ("Warning threshold must be a nonnegative integer\n");
154                         cusers = atoi (argv[c]);
155                 }
156         }
158         return OK;
165 int
166 call_getopt (int argc, char **argv)
168         int c, i = 0;
170 #ifdef HAVE_GETOPT_H
171         int option_index = 0;
172         static struct option long_options[] = {
173                 {"critical", required_argument, 0, 'c'},
174                 {"warning", required_argument, 0, 'w'},
175                 {"version", no_argument, 0, 'V'},
176                 {"help", no_argument, 0, 'h'},
177                 {0, 0, 0, 0}
178         };
179 #endif
181         while (1) {
182 #ifdef HAVE_GETOPT_H
183                 c = getopt_long (argc, argv, "+hVvc:w:", long_options, &option_index);
184 #else
185                 c = getopt (argc, argv, "+hVvc:w:");
186 #endif
188                 i++;
190                 if (c == -1 || c == EOF || c == 1)
191                         break;
193                 switch (c) {
194                 case 'c':
195                 case 'w':
196                         i++;
197                 }
199                 switch (c) {
200                 case '?':                                                                       /* print short usage statement if args not parsable */
201                         printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg);
202                         print_usage ();
203                         exit (STATE_UNKNOWN);
204                 case 'h':                                                                       /* help */
205                         print_help ();
206                         exit (STATE_OK);
207                 case 'V':                                                                       /* version */
208                         print_revision (my_basename (argv[0]), "$Revision$");
209                         exit (STATE_OK);
210                 case 'c':                                                                       /* critical */
211                         if (!is_intnonneg (optarg))
212                                 usage ("Critical threshold must be a nonnegative integer\n");
213                         cusers = atoi (optarg);
214                         break;
215                 case 'w':                                                                       /* warning */
216                         if (!is_intnonneg (optarg))
217                                 usage ("Warning threshold must be a nonnegative integer\n");
218                         wusers = atoi (optarg);
219                         break;
220                 }
221         }
222         return i;
229 void
230 print_usage (void)
232         printf ("Usage: %s -w <users> -c <users>\n", PROGNAME);
239 void
240 print_help (void)
242         print_revision (PROGNAME, "$Revision$");
243         printf
244                 ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n"
245                  "This plugin checks the number of users currently logged in on the local\n"
246                  "system and generates an error if the number exceeds the thresholds specified.\n");
247         print_usage ();
248         printf
249                 ("Options:\n"
250                  " -w, --warning=INTEGER\n"
251                  "    Set WARNING status if more than INTEGER users are logged in\n"
252                  " -c, --critical=INTEGER\n"
253                  "    Set CRITICAL status if more than INTEGER users are logged in\n"
254                  " -h, --help\n"
255                  "    Print detailed help screen\n"
256                  " -V, --version\n" "    Print version information\n");