diff options
Diffstat (limited to 'plugins/check_users.c')
-rw-r--r-- | plugins/check_users.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/plugins/check_users.c b/plugins/check_users.c new file mode 100644 index 00000000..2b8fa15b --- /dev/null +++ b/plugins/check_users.c | |||
@@ -0,0 +1,257 @@ | |||
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 | *****************************************************************************/ | ||
46 | |||
47 | #include "common.h" | ||
48 | #include "popen.h" | ||
49 | #include "utils.h" | ||
50 | |||
51 | #define PROGNAME "check_users" | ||
52 | |||
53 | #define possibly_set(a,b) ((a) == 0 ? (b) : 0) | ||
54 | |||
55 | int process_arguments (int, char **); | ||
56 | int call_getopt (int, char **); | ||
57 | void print_usage (void); | ||
58 | void print_help (void); | ||
59 | |||
60 | int wusers = -1; | ||
61 | int cusers = -1; | ||
62 | |||
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]; | ||
69 | |||
70 | if (process_arguments (argc, argv) == ERROR) | ||
71 | usage ("Could not parse arguments\n"); | ||
72 | |||
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 | } | ||
79 | |||
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); | ||
83 | |||
84 | users = 0; | ||
85 | |||
86 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
87 | |||
88 | /* increment 'users' on all lines except total user count */ | ||
89 | if (input_buffer[0] != '#') { | ||
90 | users++; | ||
91 | continue; | ||
92 | } | ||
93 | |||
94 | /* get total logged in users */ | ||
95 | if (sscanf (input_buffer, "# users=%d", &users) == 1) | ||
96 | break; | ||
97 | |||
98 | } | ||
99 | |||
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); | ||
104 | |||
105 | /* close the pipe */ | ||
106 | if (spclose (child_process)) | ||
107 | result = possibly_set (result, STATE_UNKNOWN); | ||
108 | |||
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; | ||
116 | |||
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); | ||
122 | |||
123 | return result; | ||
124 | } | ||
125 | |||
126 | |||
127 | |||
128 | |||
129 | |||
130 | /* process command-line arguments */ | ||
131 | int | ||
132 | process_arguments (int argc, char **argv) | ||
133 | { | ||
134 | int c; | ||
135 | |||
136 | if (argc < 2) | ||
137 | usage ("\n"); | ||
138 | |||
139 | c = 0; | ||
140 | while ((c += call_getopt (argc - c, &argv[c])) < argc) { | ||
141 | |||
142 | if (is_option (argv[c])) | ||
143 | continue; | ||
144 | |||
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]); | ||
149 | |||
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 | } | ||
157 | |||
158 | return OK; | ||
159 | } | ||
160 | |||
161 | |||
162 | |||
163 | |||
164 | |||
165 | int | ||
166 | call_getopt (int argc, char **argv) | ||
167 | { | ||
168 | int c, i = 0; | ||
169 | |||
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 | ||
180 | |||
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 | ||
187 | |||
188 | i++; | ||
189 | |||
190 | if (c == -1 || c == EOF || c == 1) | ||
191 | break; | ||
192 | |||
193 | switch (c) { | ||
194 | case 'c': | ||
195 | case 'w': | ||
196 | i++; | ||
197 | } | ||
198 | |||
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; | ||
223 | } | ||
224 | |||
225 | |||
226 | |||
227 | |||
228 | |||
229 | void | ||
230 | print_usage (void) | ||
231 | { | ||
232 | printf ("Usage: %s -w <users> -c <users>\n", PROGNAME); | ||
233 | } | ||
234 | |||
235 | |||
236 | |||
237 | |||
238 | |||
239 | void | ||
240 | print_help (void) | ||
241 | { | ||
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"); | ||
257 | } | ||