utils_base.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*****************************************************************************
  2. *
  3. * utils_base.c
  4. *
  5. * License: GPL
  6. * Copyright (c) 2006 Nagios Plugins Development Team
  7. *
  8. * Library of useful functions for plugins
  9. *
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation, either version 3 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. *
  25. *****************************************************************************/
  26. #include "common.h"
  27. #include <stdarg.h>
  28. #include "utils_base.h"
  29. void
  30. die (int result, const char *fmt, ...)
  31. {
  32. va_list ap;
  33. va_start (ap, fmt);
  34. vprintf (fmt, ap);
  35. va_end (ap);
  36. exit (result);
  37. }
  38. void set_range_start (range *this, double value) {
  39. this->start = value;
  40. this->start_infinity = FALSE;
  41. }
  42. void set_range_end (range *this, double value) {
  43. this->end = value;
  44. this->end_infinity = FALSE;
  45. }
  46. range
  47. *parse_range_string (char *str) {
  48. range *temp_range;
  49. double start;
  50. double end;
  51. char *end_str;
  52. temp_range = (range *) malloc(sizeof(range));
  53. /* Set defaults */
  54. temp_range->start = 0;
  55. temp_range->start_infinity = FALSE;
  56. temp_range->end = 0;
  57. temp_range->end_infinity = TRUE;
  58. temp_range->alert_on = OUTSIDE;
  59. if (str[0] == '@') {
  60. temp_range->alert_on = INSIDE;
  61. str++;
  62. }
  63. end_str = index(str, ':');
  64. if (end_str != NULL) {
  65. if (str[0] == '~') {
  66. temp_range->start_infinity = TRUE;
  67. } else {
  68. start = strtod(str, NULL); /* Will stop at the ':' */
  69. set_range_start(temp_range, start);
  70. }
  71. end_str++; /* Move past the ':' */
  72. } else {
  73. end_str = str;
  74. }
  75. end = strtod(end_str, NULL);
  76. if (strcmp(end_str, "") != 0) {
  77. set_range_end(temp_range, end);
  78. }
  79. if (temp_range->start_infinity == TRUE ||
  80. temp_range->end_infinity == TRUE ||
  81. temp_range->start <= temp_range->end) {
  82. return temp_range;
  83. }
  84. free(temp_range);
  85. return NULL;
  86. }
  87. /* returns 0 if okay, otherwise 1 */
  88. int
  89. _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
  90. {
  91. thresholds *temp_thresholds = NULL;
  92. if ((temp_thresholds = malloc(sizeof(thresholds))) == NULL)
  93. die(STATE_UNKNOWN, _("Cannot allocate memory: %s\n"),
  94. strerror(errno));
  95. temp_thresholds->warning = NULL;
  96. temp_thresholds->critical = NULL;
  97. if (warn_string != NULL) {
  98. if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) {
  99. return NP_RANGE_UNPARSEABLE;
  100. }
  101. }
  102. if (critical_string != NULL) {
  103. if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
  104. return NP_RANGE_UNPARSEABLE;
  105. }
  106. }
  107. *my_thresholds = temp_thresholds;
  108. return 0;
  109. }
  110. void
  111. set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
  112. {
  113. switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
  114. case 0:
  115. return;
  116. case NP_RANGE_UNPARSEABLE:
  117. die(STATE_UNKNOWN, _("Range format incorrect"));
  118. case NP_WARN_WITHIN_CRIT:
  119. die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted"));
  120. break;
  121. }
  122. }
  123. void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
  124. printf("%s - ", threshold_name);
  125. if (! my_threshold) {
  126. printf("Threshold not set");
  127. } else {
  128. if (my_threshold->warning) {
  129. printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
  130. } else {
  131. printf("Warning not set; ");
  132. }
  133. if (my_threshold->critical) {
  134. printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
  135. } else {
  136. printf("Critical not set");
  137. }
  138. }
  139. printf("\n");
  140. }
  141. /* Returns TRUE if alert should be raised based on the range */
  142. int
  143. check_range(double value, range *my_range)
  144. {
  145. int no = FALSE;
  146. int yes = TRUE;
  147. if (my_range->alert_on == INSIDE) {
  148. no = TRUE;
  149. yes = FALSE;
  150. }
  151. if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
  152. if ((my_range->start <= value) && (value <= my_range->end)) {
  153. return no;
  154. } else {
  155. return yes;
  156. }
  157. } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
  158. if (my_range->start <= value) {
  159. return no;
  160. } else {
  161. return yes;
  162. }
  163. } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
  164. if (value <= my_range->end) {
  165. return no;
  166. } else {
  167. return yes;
  168. }
  169. } else {
  170. return no;
  171. }
  172. }
  173. /* Returns status */
  174. int
  175. get_status(double value, thresholds *my_thresholds)
  176. {
  177. if (my_thresholds->critical != NULL) {
  178. if (check_range(value, my_thresholds->critical) == TRUE) {
  179. return STATE_CRITICAL;
  180. }
  181. }
  182. if (my_thresholds->warning != NULL) {
  183. if (check_range(value, my_thresholds->warning) == TRUE) {
  184. return STATE_WARNING;
  185. }
  186. }
  187. return STATE_OK;
  188. }
  189. char *np_escaped_string (const char *string) {
  190. char *data;
  191. int i, j=0;
  192. data = strdup(string);
  193. for (i=0; data[i]; i++) {
  194. if (data[i] == '\\') {
  195. switch(data[++i]) {
  196. case 'n':
  197. data[j++] = '\n';
  198. break;
  199. case 'r':
  200. data[j++] = '\r';
  201. break;
  202. case 't':
  203. data[j++] = '\t';
  204. break;
  205. case '\\':
  206. data[j++] = '\\';
  207. break;
  208. default:
  209. data[j++] = data[i];
  210. }
  211. } else {
  212. data[j++] = data[i];
  213. }
  214. }
  215. data[j] = '\0';
  216. return data;
  217. }
  218. int np_check_if_root(void) { return (geteuid() == 0); }
  219. int np_warn_if_not_root(void) {
  220. int status = np_check_if_root();
  221. if(!status) {
  222. printf(_("Warning: "));
  223. printf(_("This plugin must be either run as root or setuid root.\n"));
  224. printf(_("To run as root, you can use a tool like sudo.\n"));
  225. printf(_("To set the setuid permissions, use the command:\n"));
  226. /* XXX could we use something like progname? */
  227. printf("\tchmod u+s yourpluginfile\n");
  228. }
  229. return status;
  230. }
  231. /*
  232. * Extract the value from key/value pairs, or return NULL. The value returned
  233. * can be free()ed.
  234. * This function can be used to parse NTP control packet data and performance
  235. * data strings.
  236. */
  237. char *np_extract_value(const char *varlist, const char *name, char sep) {
  238. char *tmp=NULL, *value=NULL;
  239. int i;
  240. while (1) {
  241. /* Strip any leading space */
  242. for (varlist; isspace(varlist[0]); varlist++);
  243. if (strncmp(name, varlist, strlen(name)) == 0) {
  244. varlist += strlen(name);
  245. /* strip trailing spaces */
  246. for (varlist; isspace(varlist[0]); varlist++);
  247. if (varlist[0] == '=') {
  248. /* We matched the key, go past the = sign */
  249. varlist++;
  250. /* strip leading spaces */
  251. for (varlist; isspace(varlist[0]); varlist++);
  252. if (tmp = index(varlist, sep)) {
  253. /* Value is delimited by a comma */
  254. if (tmp-varlist == 0) continue;
  255. value = (char *)malloc(tmp-varlist+1);
  256. strncpy(value, varlist, tmp-varlist);
  257. value[tmp-varlist] = '\0';
  258. } else {
  259. /* Value is delimited by a \0 */
  260. if (strlen(varlist) == 0) continue;
  261. value = (char *)malloc(strlen(varlist) + 1);
  262. strncpy(value, varlist, strlen(varlist));
  263. value[strlen(varlist)] = '\0';
  264. }
  265. break;
  266. }
  267. }
  268. if (tmp = index(varlist, sep)) {
  269. /* More keys, keep going... */
  270. varlist = tmp + 1;
  271. } else {
  272. /* We're done */
  273. break;
  274. }
  275. }
  276. /* Clean-up trailing spaces/newlines */
  277. if (value) for (i=strlen(value)-1; isspace(value[i]); i--) value[i] = '\0';
  278. return value;
  279. }