utils_base.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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. temp_thresholds = malloc(sizeof(temp_thresholds));
  93. temp_thresholds->warning = NULL;
  94. temp_thresholds->critical = NULL;
  95. if (warn_string != NULL) {
  96. if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) {
  97. return NP_RANGE_UNPARSEABLE;
  98. }
  99. }
  100. if (critical_string != NULL) {
  101. if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
  102. return NP_RANGE_UNPARSEABLE;
  103. }
  104. }
  105. *my_thresholds = temp_thresholds;
  106. return 0;
  107. }
  108. void
  109. set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
  110. {
  111. switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
  112. case 0:
  113. return;
  114. case NP_RANGE_UNPARSEABLE:
  115. die(STATE_UNKNOWN, _("Range format incorrect"));
  116. case NP_WARN_WITHIN_CRIT:
  117. die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted"));
  118. break;
  119. }
  120. }
  121. void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
  122. printf("%s - ", threshold_name);
  123. if (! my_threshold) {
  124. printf("Threshold not set");
  125. } else {
  126. if (my_threshold->warning) {
  127. printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
  128. } else {
  129. printf("Warning not set; ");
  130. }
  131. if (my_threshold->critical) {
  132. printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
  133. } else {
  134. printf("Critical not set");
  135. }
  136. }
  137. printf("\n");
  138. }
  139. /* Returns TRUE if alert should be raised based on the range */
  140. int
  141. check_range(double value, range *my_range)
  142. {
  143. int no = FALSE;
  144. int yes = TRUE;
  145. if (my_range->alert_on == INSIDE) {
  146. no = TRUE;
  147. yes = FALSE;
  148. }
  149. if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
  150. if ((my_range->start <= value) && (value <= my_range->end)) {
  151. return no;
  152. } else {
  153. return yes;
  154. }
  155. } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
  156. if (my_range->start <= value) {
  157. return no;
  158. } else {
  159. return yes;
  160. }
  161. } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
  162. if (value <= my_range->end) {
  163. return no;
  164. } else {
  165. return yes;
  166. }
  167. } else {
  168. return no;
  169. }
  170. }
  171. /* Returns status */
  172. int
  173. get_status(double value, thresholds *my_thresholds)
  174. {
  175. if (my_thresholds->critical != NULL) {
  176. if (check_range(value, my_thresholds->critical) == TRUE) {
  177. return STATE_CRITICAL;
  178. }
  179. }
  180. if (my_thresholds->warning != NULL) {
  181. if (check_range(value, my_thresholds->warning) == TRUE) {
  182. return STATE_WARNING;
  183. }
  184. }
  185. return STATE_OK;
  186. }
  187. char *np_escaped_string (const char *string) {
  188. char *data;
  189. int i, j=0;
  190. data = strdup(string);
  191. for (i=0; data[i]; i++) {
  192. if (data[i] == '\\') {
  193. switch(data[++i]) {
  194. case 'n':
  195. data[j++] = '\n';
  196. break;
  197. case 'r':
  198. data[j++] = '\r';
  199. break;
  200. case 't':
  201. data[j++] = '\t';
  202. break;
  203. case '\\':
  204. data[j++] = '\\';
  205. break;
  206. default:
  207. data[j++] = data[i];
  208. }
  209. } else {
  210. data[j++] = data[i];
  211. }
  212. }
  213. data[j] = '\0';
  214. return data;
  215. }
  216. int np_check_if_root(void) { return (geteuid() == 0); }
  217. int np_warn_if_not_root(void) {
  218. int status = np_check_if_root();
  219. if(!status) {
  220. printf(_("Warning: "));
  221. printf(_("This plugin must be either run as root or setuid root.\n"));
  222. printf(_("To run as root, you can use a tool like sudo.\n"));
  223. printf(_("To set the setuid permissions, use the command:\n"));
  224. /* XXX could we use something like progname? */
  225. printf("\tchmod u+s yourpluginfile\n");
  226. }
  227. return status;
  228. }
  229. /*
  230. * Extract the value from key/value pairs, or return NULL. The value returned
  231. * can be free()ed.
  232. * This function can be used to parse NTP control packet data and performance
  233. * data strings.
  234. */
  235. char *np_extract_value(const char *varlist, const char *name, char sep) {
  236. char *tmp=NULL, *value=NULL;
  237. int i;
  238. while (1) {
  239. /* Strip any leading space */
  240. for (varlist; isspace(varlist[0]); varlist++);
  241. if (strncmp(name, varlist, strlen(name)) == 0) {
  242. varlist += strlen(name);
  243. /* strip trailing spaces */
  244. for (varlist; isspace(varlist[0]); varlist++);
  245. if (varlist[0] == '=') {
  246. /* We matched the key, go past the = sign */
  247. varlist++;
  248. /* strip leading spaces */
  249. for (varlist; isspace(varlist[0]); varlist++);
  250. if (tmp = index(varlist, sep)) {
  251. /* Value is delimited by a comma */
  252. if (tmp-varlist == 0) continue;
  253. value = (char *)malloc(tmp-varlist+1);
  254. strncpy(value, varlist, tmp-varlist);
  255. value[tmp-varlist] = '\0';
  256. } else {
  257. /* Value is delimited by a \0 */
  258. if (strlen(varlist) == 0) continue;
  259. value = (char *)malloc(strlen(varlist) + 1);
  260. strncpy(value, varlist, strlen(varlist));
  261. value[strlen(varlist)] = '\0';
  262. }
  263. break;
  264. }
  265. }
  266. if (tmp = index(varlist, sep)) {
  267. /* More keys, keep going... */
  268. varlist = tmp + 1;
  269. } else {
  270. /* We're done */
  271. break;
  272. }
  273. }
  274. /* Clean-up trailing spaces/newlines */
  275. if (value) for (i=strlen(value)-1; isspace(value[i]); i--) value[i] = '\0';
  276. return value;
  277. }