1 /*****************************************************************************
2 *
3 * Nagios check_users plugin
4 *
5 * License: GPL
6 * Copyright (c) 2000-2007 Nagios Plugins Development Team
7 *
8 * Description:
9 *
10 * This file contains the check_users plugin
11 *
12 * This plugin checks the number of users currently logged in on the local
13 * system and generates an error if the number exceeds the thresholds
14 * specified.
15 *
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 *
31 *****************************************************************************/
33 const char *progname = "check_users";
34 const char *copyright = "2000-2007";
35 const char *email = "nagiosplug-devel@lists.sourceforge.net";
37 #include "common.h"
38 #include "popen.h"
39 #include "utils.h"
41 #define possibly_set(a,b) ((a) == 0 ? (b) : 0)
43 int process_arguments (int, char **);
44 void print_help (void);
45 void print_usage (void);
47 int wusers = -1;
48 int cusers = -1;
50 int
51 main (int argc, char **argv)
52 {
53 int users = -1;
54 int result = STATE_UNKNOWN;
55 char input_buffer[MAX_INPUT_BUFFER];
56 char *perf;
58 setlocale (LC_ALL, "");
59 bindtextdomain (PACKAGE, LOCALEDIR);
60 textdomain (PACKAGE);
62 perf = strdup("");
64 /* Parse extra opts if any */
65 argv=np_extra_opts (&argc, argv, progname);
67 if (process_arguments (argc, argv) == ERROR)
68 usage4 (_("Could not parse arguments"));
70 /* run the command */
71 child_process = spopen (WHO_COMMAND);
72 if (child_process == NULL) {
73 printf (_("Could not open pipe: %s\n"), WHO_COMMAND);
74 return STATE_UNKNOWN;
75 }
77 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
78 if (child_stderr == NULL)
79 printf (_("Could not open stderr for %s\n"), WHO_COMMAND);
81 users = 0;
83 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
85 /* increment 'users' on all lines except total user count */
86 if (input_buffer[0] != '#') {
87 users++;
88 continue;
89 }
91 /* get total logged in users */
92 if (sscanf (input_buffer, _("# users=%d"), &users) == 1)
93 break;
95 }
97 /* check STDERR */
98 if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
99 result = possibly_set (result, STATE_UNKNOWN);
100 (void) fclose (child_stderr);
102 /* close the pipe */
103 if (spclose (child_process))
104 result = possibly_set (result, STATE_UNKNOWN);
106 /* else check the user count against warning and critical thresholds */
107 if (users > cusers)
108 result = STATE_CRITICAL;
109 else if (users > wusers)
110 result = STATE_WARNING;
111 else if (users >= 0)
112 result = STATE_OK;
114 if (result == STATE_UNKNOWN)
115 printf ("%s\n", _("Unable to read output"));
116 else {
117 asprintf(&perf, "%s", perfdata ("users", users, "",
118 TRUE, wusers,
119 TRUE, cusers,
120 TRUE, 0,
121 FALSE, 0));
122 printf (_("USERS %s - %d users currently logged in |%s\n"), state_text (result),
123 users, perf);
124 }
126 return result;
127 }
131 /* process command-line arguments */
132 int
133 process_arguments (int argc, char **argv)
134 {
135 int c;
137 int option = 0;
138 static struct option longopts[] = {
139 {"critical", required_argument, 0, 'c'},
140 {"warning", required_argument, 0, 'w'},
141 {"version", no_argument, 0, 'V'},
142 {"help", no_argument, 0, 'h'},
143 {0, 0, 0, 0}
144 };
146 if (argc < 2)
147 usage ("\n");
149 while (1) {
150 c = getopt_long (argc, argv, "+hVvc:w:", longopts, &option);
152 if (c == -1 || c == EOF || c == 1)
153 break;
155 switch (c) {
156 case '?': /* print short usage statement if args not parsable */
157 usage5 ();
158 case 'h': /* help */
159 print_help ();
160 exit (STATE_OK);
161 case 'V': /* version */
162 print_revision (progname, NP_VERSION);
163 exit (STATE_OK);
164 case 'c': /* critical */
165 if (!is_intnonneg (optarg))
166 usage4 (_("Critical threshold must be a positive integer"));
167 else
168 cusers = atoi (optarg);
169 break;
170 case 'w': /* warning */
171 if (!is_intnonneg (optarg))
172 usage4 (_("Warning threshold must be a positive integer"));
173 else
174 wusers = atoi (optarg);
175 break;
176 }
177 }
179 c = optind;
180 if (wusers == -1 && argc > c) {
181 if (is_intnonneg (argv[c]) == FALSE)
182 usage4 (_("Warning threshold must be a positive integer"));
183 else
184 wusers = atoi (argv[c++]);
185 }
187 if (cusers == -1 && argc > c) {
188 if (is_intnonneg (argv[c]) == FALSE)
189 usage4 (_("Warning threshold must be a positive integer"));
190 else
191 cusers = atoi (argv[c]);
192 }
194 return OK;
195 }
199 void
200 print_help (void)
201 {
202 print_revision (progname, NP_VERSION);
204 printf ("Copyright (c) 1999 Ethan Galstad\n");
205 printf (COPYRIGHT, copyright, email);
207 printf ("%s\n", _("This plugin checks the number of users currently logged in on the local"));
208 printf ("%s\n", _("system and generates an error if the number exceeds the thresholds specified."));
210 printf ("\n\n");
212 print_usage ();
214 printf (_(UT_HELP_VRSN));
215 printf (_(UT_EXTRA_OPTS));
217 printf (" %s\n", "-w, --warning=INTEGER");
218 printf (" %s\n", _("Set WARNING status if more than INTEGER users are logged in"));
219 printf (" %s\n", "-c, --critical=INTEGER");
220 printf (" %s\n", _("Set CRITICAL status if more than INTEGER users are logged in"));
222 #ifdef NP_EXTRA_OPTS
223 printf ("\n");
224 printf ("%s\n", _("Notes:"));
225 printf (_(UT_EXTRA_OPTS_NOTES));
226 #endif
228 printf (_(UT_SUPPORT));
229 }
232 void
233 print_usage (void)
234 {
235 printf (_("Usage:"));
236 printf ("%s -w <users> -c <users>\n", progname);
237 }