check_users.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. #include "common.h"
  47. #include "popen.h"
  48. #include "utils.h"
  49. const char *progname = "check_users";
  50. #define REVISION "$Revision$"
  51. #define COPYRIGHT "1999-2002"
  52. #define AUTHOR "Ethan Galstad"
  53. #define EMAIL "nagios@nagios.org"
  54. #define possibly_set(a,b) ((a) == 0 ? (b) : 0)
  55. int process_arguments (int, char **);
  56. void print_usage (void);
  57. void print_help (void);
  58. int wusers = -1;
  59. int cusers = -1;
  60. int
  61. main (int argc, char **argv)
  62. {
  63. int users = -1;
  64. int result = STATE_OK;
  65. char input_buffer[MAX_INPUT_BUFFER];
  66. if (process_arguments (argc, argv) == ERROR)
  67. usage ("Could not parse arguments\n");
  68. /* run the command */
  69. child_process = spopen (WHO_COMMAND);
  70. if (child_process == NULL) {
  71. printf ("Could not open pipe: %s\n", WHO_COMMAND);
  72. return STATE_UNKNOWN;
  73. }
  74. child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
  75. if (child_stderr == NULL)
  76. printf ("Could not open stderr for %s\n", WHO_COMMAND);
  77. users = 0;
  78. while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
  79. /* increment 'users' on all lines except total user count */
  80. if (input_buffer[0] != '#') {
  81. users++;
  82. continue;
  83. }
  84. /* get total logged in users */
  85. if (sscanf (input_buffer, "# users=%d", &users) == 1)
  86. break;
  87. }
  88. /* check STDERR */
  89. if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
  90. result = possibly_set (result, STATE_UNKNOWN);
  91. (void) fclose (child_stderr);
  92. /* close the pipe */
  93. if (spclose (child_process))
  94. result = possibly_set (result, STATE_UNKNOWN);
  95. /* else check the user count against warning and critical thresholds */
  96. if (users >= cusers)
  97. result = STATE_CRITICAL;
  98. else if (users >= wusers)
  99. result = STATE_WARNING;
  100. else if (users >= 0)
  101. result = STATE_OK;
  102. if (result == STATE_UNKNOWN)
  103. printf ("Unable to read output\n");
  104. else
  105. printf ("USERS %s - %d users currently logged in\n", state_text (result),
  106. users);
  107. return result;
  108. }
  109. /* process command-line arguments */
  110. int
  111. process_arguments (int argc, char **argv)
  112. {
  113. int c;
  114. #ifdef HAVE_GETOPT_H
  115. int option_index = 0;
  116. static struct option long_options[] = {
  117. {"critical", required_argument, 0, 'c'},
  118. {"warning", required_argument, 0, 'w'},
  119. {"version", no_argument, 0, 'V'},
  120. {"help", no_argument, 0, 'h'},
  121. {0, 0, 0, 0}
  122. };
  123. #endif
  124. if (argc < 2)
  125. usage ("\n");
  126. while (1) {
  127. #ifdef HAVE_GETOPT_H
  128. c = getopt_long (argc, argv, "+hVvc:w:", long_options, &option_index);
  129. #else
  130. c = getopt (argc, argv, "+hVvc:w:");
  131. #endif
  132. if (c == -1 || c == EOF || c == 1)
  133. break;
  134. switch (c) {
  135. case '?': /* print short usage statement if args not parsable */
  136. printf ("%s: Unknown argument: %s\n\n", progname, optarg);
  137. print_usage ();
  138. exit (STATE_UNKNOWN);
  139. case 'h': /* help */
  140. print_help ();
  141. exit (STATE_OK);
  142. case 'V': /* version */
  143. print_revision (progname, REVISION);
  144. exit (STATE_OK);
  145. case 'c': /* critical */
  146. if (!is_intnonneg (optarg))
  147. usage ("Critical threshold must be a nonnegative integer\n");
  148. cusers = atoi (optarg);
  149. break;
  150. case 'w': /* warning */
  151. if (!is_intnonneg (optarg))
  152. usage ("Warning threshold must be a nonnegative integer\n");
  153. wusers = atoi (optarg);
  154. break;
  155. }
  156. }
  157. c = optind;
  158. if (wusers == -1 && argc > c) {
  159. if (is_intnonneg (argv[c]) == FALSE)
  160. usage ("Warning threshold must be a nonnegative integer\n");
  161. wusers = atoi (argv[c++]);
  162. }
  163. if (cusers == -1 && argc > c) {
  164. if (is_intnonneg (argv[c]) == FALSE)
  165. usage ("Warning threshold must be a nonnegative integer\n");
  166. cusers = atoi (argv[c]);
  167. }
  168. return OK;
  169. }
  170. void
  171. print_usage (void)
  172. {
  173. printf ("Usage: %s -w <users> -c <users>\n", progname);
  174. }
  175. void
  176. print_help (void)
  177. {
  178. print_revision (progname, REVISION);
  179. printf
  180. ("Copyright (c) " COPYRIGHT " " AUTHOR "(" EMAIL ")\n\n"
  181. "This plugin checks the number of users currently logged in on the local\n"
  182. "system and generates an error if the number exceeds the thresholds specified.\n");
  183. print_usage ();
  184. printf
  185. ("Options:\n"
  186. " -w, --warning=INTEGER\n"
  187. " Set WARNING status if more than INTEGER users are logged in\n"
  188. " -c, --critical=INTEGER\n"
  189. " Set CRITICAL status if more than INTEGER users are logged in\n"
  190. " -h, --help\n"
  191. " Print detailed help screen\n"
  192. " -V, --version\n" " Print version information\n");
  193. }