1 /*****************************************************************************
2 *
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.
7 *
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.
12 *
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.
16 *
17 *****************************************************************************/
19 #include "common.h"
20 #include "popen.h"
21 #include "utils.h"
23 const char *progname = "check_users";
24 const char *revision = "$Revision$";
25 const char *copyright = "2002-2003";
26 const char *authors = "Nagios Plugin Development Team";
27 const char *email = "nagiosplug-devel@lists.sourceforge.net";
29 const char *summary = "\
30 This plugin checks the number of users currently logged in on the local\n\
31 system and generates an error if the number exceeds the thresholds specified.\n";
33 const char *option_summary = "-w <users> -c <users>";
35 const char *options = "\
36 -w, --warning=INTEGER\n\
37 Set WARNING status if more than INTEGER users are logged in\n\
38 -c, --critical=INTEGER\n\
39 Set CRITICAL status if more than INTEGER users are logged in\n";
41 const char *standard_options = "\
42 -h, --help\n\
43 Print detailed help screen\n\
44 -V, --version\n\
45 Print version information\n\n";
47 #define possibly_set(a,b) ((a) == 0 ? (b) : 0)
49 int process_arguments (int, char **);
50 void print_usage (void);
51 void print_help (void);
53 int wusers = -1;
54 int cusers = -1;
56 int
57 main (int argc, char **argv)
58 {
59 int users = -1;
60 int result = STATE_OK;
61 char input_buffer[MAX_INPUT_BUFFER];
63 if (process_arguments (argc, argv) == ERROR)
64 usage ("Could not parse arguments\n");
66 /* run the command */
67 child_process = spopen (WHO_COMMAND);
68 if (child_process == NULL) {
69 printf ("Could not open pipe: %s\n", WHO_COMMAND);
70 return STATE_UNKNOWN;
71 }
73 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
74 if (child_stderr == NULL)
75 printf ("Could not open stderr for %s\n", WHO_COMMAND);
77 users = 0;
79 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
81 /* increment 'users' on all lines except total user count */
82 if (input_buffer[0] != '#') {
83 users++;
84 continue;
85 }
87 /* get total logged in users */
88 if (sscanf (input_buffer, "# users=%d", &users) == 1)
89 break;
91 }
93 /* check STDERR */
94 if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
95 result = possibly_set (result, STATE_UNKNOWN);
96 (void) fclose (child_stderr);
98 /* close the pipe */
99 if (spclose (child_process))
100 result = possibly_set (result, STATE_UNKNOWN);
102 /* else check the user count against warning and critical thresholds */
103 if (users >= cusers)
104 result = STATE_CRITICAL;
105 else if (users >= wusers)
106 result = STATE_WARNING;
107 else if (users >= 0)
108 result = STATE_OK;
110 if (result == STATE_UNKNOWN)
111 printf ("Unable to read output\n");
112 else
113 printf ("USERS %s - %d users currently logged in\n", state_text (result),
114 users);
116 return result;
117 }
123 /* process command-line arguments */
124 int
125 process_arguments (int argc, char **argv)
126 {
127 int c;
129 int option_index = 0;
130 static struct option long_options[] = {
131 {"critical", required_argument, 0, 'c'},
132 {"warning", required_argument, 0, 'w'},
133 {"version", no_argument, 0, 'V'},
134 {"help", no_argument, 0, 'h'},
135 {0, 0, 0, 0}
136 };
138 if (argc < 2)
139 usage ("\n");
141 while (1) {
142 c = getopt_long (argc, argv, "+hVvc:w:", long_options, &option_index);
144 if (c == -1 || c == EOF || c == 1)
145 break;
147 switch (c) {
148 case '?': /* print short usage statement if args not parsable */
149 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
150 print_usage ();
151 exit (STATE_UNKNOWN);
152 case 'h': /* help */
153 print_help ();
154 exit (STATE_OK);
155 case 'V': /* version */
156 print_revision (progname, revision);
157 exit (STATE_OK);
158 case 'c': /* critical */
159 if (!is_intnonneg (optarg))
160 usage ("Critical threshold must be a nonnegative integer\n");
161 cusers = atoi (optarg);
162 break;
163 case 'w': /* warning */
164 if (!is_intnonneg (optarg))
165 usage ("Warning threshold must be a nonnegative integer\n");
166 wusers = atoi (optarg);
167 break;
168 }
169 }
171 c = optind;
172 if (wusers == -1 && argc > c) {
173 if (is_intnonneg (argv[c]) == FALSE)
174 usage ("Warning threshold must be a nonnegative integer\n");
175 wusers = atoi (argv[c++]);
176 }
178 if (cusers == -1 && argc > c) {
179 if (is_intnonneg (argv[c]) == FALSE)
180 usage ("Warning threshold must be a nonnegative integer\n");
181 cusers = atoi (argv[c]);
182 }
184 return OK;
185 }
186 \f
191 void
192 print_help (void)
193 {
194 print_revision (progname, revision);
195 printf ("Copyright (c) %s %s\n\t<%s>\n\n", copyright, authors, email);
196 printf (summary);
197 print_usage ();
198 printf ("\nOptions:\n");
199 printf (options);
200 printf (standard_options);
201 support ();
202 }
208 void
209 print_usage (void)
210 {
211 printf ("Usage: %s %s\n", progname, option_summary);
212 printf (" %s (-h|--help)\n", progname);
213 printf (" %s (-V|--version)\n", progname);
214 }