1 /*****************************************************************************
3 * Monitoring check_users plugin
6 * Copyright (c) 2000-2012 Monitoring Plugins Development Team
10 * This file contains the check_users plugin
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
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.
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.
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/>.
31 *****************************************************************************/
33 const char *progname
= "check_users";
34 const char *copyright
= "2000-2007";
35 const char *email
= "devel@monitoring-plugins.org";
42 # include <wtsapi32.h>
51 #ifdef HAVE_LIBSYSTEMD
52 #include <systemd/sd-daemon.h>
53 #include <systemd/sd-login.h>
56 #define possibly_set(a,b) ((a) == 0 ? (b) : 0)
58 int process_arguments (int, char **);
59 void print_help (void);
60 void print_usage (void);
62 char *warning_range
= NULL
;
63 char *critical_range
= NULL
;
64 thresholds
*thlds
= NULL
;
67 main (int argc
, char **argv
)
70 int result
= STATE_UNKNOWN
;
72 WTS_SESSION_INFO
*wtsinfo
;
78 char input_buffer
[MAX_INPUT_BUFFER
];
81 setlocale (LC_ALL
, "");
82 bindtextdomain (PACKAGE
, LOCALEDIR
);
85 /* Parse extra opts if any */
86 argv
= np_extra_opts (&argc
, argv
, progname
);
88 if (process_arguments (argc
, argv
) == ERROR
)
89 usage4 (_("Could not parse arguments"));
93 #ifdef HAVE_LIBSYSTEMD
95 users
= sd_get_sessions (NULL
);
99 if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE
,
100 0, 1, &wtsinfo
, &wtscount
)) {
101 printf(_("Could not enumerate RD sessions: %d\n"), GetLastError());
102 return STATE_UNKNOWN
;
105 for (index
= 0; index
< wtscount
; index
++) {
110 if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE
,
111 wtsinfo
[index
].SessionId
, WTSUserName
, &username
, &size
))
114 len
= lstrlen(username
);
116 WTSFreeMemory(username
);
121 if (wtsinfo
[index
].State
== WTSActive
||
122 wtsinfo
[index
].State
== WTSDisconnected
)
126 WTSFreeMemory(wtsinfo
);
128 /* get currently logged users from utmpx */
131 while ((putmpx
= getutxent ()) != NULL
)
132 if (putmpx
->ut_type
== USER_PROCESS
)
137 /* run the command */
138 child_process
= spopen (WHO_COMMAND
);
139 if (child_process
== NULL
) {
140 printf (_("Could not open pipe: %s\n"), WHO_COMMAND
);
141 return STATE_UNKNOWN
;
144 child_stderr
= fdopen (child_stderr_array
[fileno (child_process
)], "r");
145 if (child_stderr
== NULL
)
146 printf (_("Could not open stderr for %s\n"), WHO_COMMAND
);
148 while (fgets (input_buffer
, MAX_INPUT_BUFFER
- 1, child_process
)) {
149 /* increment 'users' on all lines except total user count */
150 if (input_buffer
[0] != '#') {
155 /* get total logged in users */
156 if (sscanf (input_buffer
, _("# users=%d"), &users
) == 1)
161 if (fgets (input_buffer
, MAX_INPUT_BUFFER
- 1, child_stderr
))
162 result
= possibly_set (result
, STATE_UNKNOWN
);
163 (void) fclose (child_stderr
);
166 if (spclose (child_process
))
167 result
= possibly_set (result
, STATE_UNKNOWN
);
169 #ifdef HAVE_LIBSYSTEMD
173 /* check the user count against warning and critical thresholds */
174 result
= get_status((double)users
, thlds
);
176 if (result
== STATE_UNKNOWN
)
177 printf ("%s\n", _("Unable to read output"));
179 printf (_("USERS %s - %d users currently logged in |%s\n"),
180 state_text(result
), users
,
181 sperfdata_int("users", users
, "", warning_range
,
182 critical_range
, true, 0, false, 0));
188 /* process command-line arguments */
190 process_arguments (int argc
, char **argv
)
194 static struct option longopts
[] = {
195 {"critical", required_argument
, 0, 'c'},
196 {"warning", required_argument
, 0, 'w'},
197 {"version", no_argument
, 0, 'V'},
198 {"help", no_argument
, 0, 'h'},
206 c
= getopt_long (argc
, argv
, "+hVvc:w:", longopts
, &option
);
208 if (c
== -1 || c
== EOF
|| c
== 1)
212 case '?': /* print short usage statement if args not parsable */
216 exit (STATE_UNKNOWN
);
217 case 'V': /* version */
218 print_revision (progname
, NP_VERSION
);
219 exit (STATE_UNKNOWN
);
220 case 'c': /* critical */
221 critical_range
= optarg
;
223 case 'w': /* warning */
224 warning_range
= optarg
;
231 if (warning_range
== NULL
&& argc
> c
)
232 warning_range
= argv
[c
++];
234 if (critical_range
== NULL
&& argc
> c
)
235 critical_range
= argv
[c
++];
237 /* this will abort in case of invalid ranges */
238 set_thresholds (&thlds
, warning_range
, critical_range
);
240 if (!thlds
->warning
) {
241 usage4 (_("Warning threshold must be a valid range expression"));
244 if (!thlds
->critical
) {
245 usage4 (_("Critical threshold must be a valid range expression"));
254 print_revision (progname
, NP_VERSION
);
256 printf ("Copyright (c) 1999 Ethan Galstad\n");
257 printf (COPYRIGHT
, copyright
, email
);
259 printf ("%s\n", _("This plugin checks the number of users currently logged in on the local"));
260 printf ("%s\n", _("system and generates an error if the number exceeds the thresholds specified."));
266 printf (UT_HELP_VRSN
);
267 printf (UT_EXTRA_OPTS
);
269 printf (" %s\n", "-w, --warning=RANGE_EXPRESSION");
270 printf (" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION"));
271 printf (" %s\n", "-c, --critical=RANGE_EXPRESSION");
272 printf (" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION"));
280 printf ("%s\n", _("Usage:"));
281 printf ("%s -w <users> -c <users>\n", progname
);