From 0b6423f9c99d9edf8c96fefd0f6c453859395aa1 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Mon, 30 Sep 2013 00:03:24 +0200 Subject: Import Nagios Plugins site Import the Nagios Plugins web site, Cronjobs, infrastructure scripts, and configuration files. --- web/attachments/86330-check_http.patch | 353 +++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 web/attachments/86330-check_http.patch (limited to 'web/attachments/86330-check_http.patch') diff --git a/web/attachments/86330-check_http.patch b/web/attachments/86330-check_http.patch new file mode 100644 index 0000000..df817d1 --- /dev/null +++ b/web/attachments/86330-check_http.patch @@ -0,0 +1,353 @@ +--- /tmp/check_http.c 2004-04-13 20:09:38.000000000 -0700 ++++ check_http.c 2004-04-13 20:25:40.000000000 -0700 +@@ -21,6 +21,8 @@ + * + * $Id: check_http.c,v 1.24.2.4 2003/06/21 05:31:23 kdebisschop Exp $ + * ++ * 13-Apr-2004 -- jwz -- added "--no-body" and "--max-age" options ++ * + *****************************************************************************/ + + const char *progname = "check_http"; +@@ -45,7 +47,7 @@ + [-w ] [-c ] [-t ] [-L]\n\ + [-a auth] [-f ] [-e ]\n\ + [-s string] [-l] [-r | -R ]\n\ +- [-P string]" ++ [-P string] [-N] [-M ]" + + #define LONGOPTIONS "\ + -H, --hostname=ADDRESS\n\ +@@ -63,6 +65,13 @@ + Port number (default: %d)\n\ + -P, --post=STRING\n\ + URL encoded http POST data\n\ ++ -N, --no-body\n\ ++ Don't wait for document body: stop reading after headers.\n\ ++ (Note that this still does an HTTP GET or POST, not a HEAD.)\n\ ++ -M, --max-age=SECONDS\n\ ++ Warn if the document is more than SECONDS old. The number can\n\ ++ also be of the form \"10m\" for minutes, \"10h\" for hours, or\n\ ++ \"10d\" for days.\n\ + -w, --warning=INTEGER\n\ + Response time to result in warning status (seconds)\n\ + -c, --critical=INTEGER\n\ +@@ -159,6 +168,10 @@ + int check_certificate (X509 **); + #endif + ++/* jwz */ ++int no_body = FALSE; ++int maximum_age = -1; ++ + #ifdef HAVE_REGEX_H + enum { + REGS = 2, +@@ -311,6 +324,10 @@ + {"linespan", no_argument, 0, 'l'}, + {"onredirect", required_argument, 0, 'f'}, + {"certificate", required_argument, 0, 'C'}, ++ ++ /* jwz */ ++ {"no-body", no_argument, 0, 'N'}, ++ {"max-age", required_argument, 0, 'M'}, + {0, 0, 0, 0} + }; + #endif +@@ -331,7 +348,8 @@ + strcpy (argv[c], "-n"); + } + +-#define OPTCHARS "Vvht:c:w:H:P:I:a:e:p:s:R:r:u:f:C:nlLS" ++/*#define OPTCHARS "Vvht:c:w:H:P:I:a:e:p:s:R:r:u:f:C:nlLS"*/ ++#define OPTCHARS "Vvht:c:w:H:P:I:a:e:p:s:R:r:u:f:C:M:nlLSN" /* jwz */ + + while (1) { + #ifdef HAVE_GETOPT_H +@@ -469,6 +487,27 @@ + case 'v': /* verbose */ + verbose = TRUE; + break; ++ case 'N': /* no-body (jwz) */ ++ no_body = TRUE; ++ break; ++ case 'M': /* max-age (jwz) */ ++ { ++ int L = strlen(optarg); ++ if (L && optarg[L-1] == 'm') ++ maximum_age = atoi (optarg) * 60; ++ else if (L && optarg[L-1] == 'h') ++ maximum_age = atoi (optarg) * 60 * 60; ++ else if (L && optarg[L-1] == 'd') ++ maximum_age = atoi (optarg) * 60 * 60 * 24; ++ else if (L && (optarg[L-1] == 's' || ++ isdigit (optarg[L-1]))) ++ maximum_age = atoi (optarg); ++ else { ++ fprintf (stderr, "unparsable max-age: %s\n", optarg); ++ exit (1); ++ } ++ } ++ break; + } + } + +@@ -534,6 +573,223 @@ + + + ++/* Returns 1 if we're done processing the document body; 0 to keep going. ++ (jwz) ++ */ ++static int ++document_headers_done (char *full_page) ++{ ++ const char *body, *s; ++ const char *end; ++ ++ for (body = full_page; *body; body++) { ++ if (!strncmp (body, "\n\n", 2) || ++ !strncmp (body, "\n\r\n", 3)) ++ break; ++ } ++ ++ if (!*body) ++ return 0; /* haven't read end of headers yet */ ++ ++ full_page[body - full_page] = 0; ++ return 1; ++} ++ ++ ++/* jwz */ ++static time_t ++parse_time_string (const char *string) ++{ ++ struct tm tm; ++ time_t t; ++ memset (&tm, 0, sizeof(tm)); ++ ++ /* Like this: Tue, 25 Dec 2001 02:59:03 GMT */ ++ ++ if (isupper (string[0]) && /* Tue */ ++ islower (string[1]) && ++ islower (string[2]) && ++ ',' == string[3] && ++ ' ' == string[4] && ++ (isdigit(string[5]) || string[5] == ' ') && /* 25 */ ++ isdigit (string[6]) && ++ ' ' == string[7] && ++ isupper (string[8]) && /* Dec */ ++ islower (string[9]) && ++ islower (string[10]) && ++ ' ' == string[11] && ++ isdigit (string[12]) && /* 2001 */ ++ isdigit (string[13]) && ++ isdigit (string[14]) && ++ isdigit (string[15]) && ++ ' ' == string[16] && ++ isdigit (string[17]) && /* 02: */ ++ isdigit (string[18]) && ++ ':' == string[19] && ++ isdigit (string[20]) && /* 59: */ ++ isdigit (string[21]) && ++ ':' == string[22] && ++ isdigit (string[23]) && /* 03 */ ++ isdigit (string[24]) && ++ ' ' == string[25] && ++ 'G' == string[26] && /* GMT */ ++ 'M' == string[27] && /* GMT */ ++ 'T' == string[28]) { ++ ++ tm.tm_sec = 10 * (string[23]-'0') + (string[24]-'0'); ++ tm.tm_min = 10 * (string[20]-'0') + (string[21]-'0'); ++ tm.tm_hour = 10 * (string[17]-'0') + (string[18]-'0'); ++ tm.tm_mday = 10 * (string[5] == ' ' ? 0 : string[5]-'0') + (string[6]-'0'); ++ tm.tm_mon = (!strncmp (string+8, "Jan", 3) ? 0 : ++ !strncmp (string+8, "Feb", 3) ? 1 : ++ !strncmp (string+8, "Mar", 3) ? 2 : ++ !strncmp (string+8, "Apr", 3) ? 3 : ++ !strncmp (string+8, "May", 3) ? 4 : ++ !strncmp (string+8, "Jun", 3) ? 5 : ++ !strncmp (string+8, "Jul", 3) ? 6 : ++ !strncmp (string+8, "Aug", 3) ? 7 : ++ !strncmp (string+8, "Sep", 3) ? 8 : ++ !strncmp (string+8, "Oct", 3) ? 9 : ++ !strncmp (string+8, "Nov", 3) ? 10 : ++ !strncmp (string+8, "Dec", 3) ? 11 : ++ -1); ++ tm.tm_year = ((1000 * (string[12]-'0') + ++ 100 * (string[13]-'0') + ++ 10 * (string[14]-'0') + ++ (string[15]-'0')) ++ - 1900); ++ ++ tm.tm_isdst = 0; /* GMT is never in DST, right? */ ++ ++ if (tm.tm_mon < 0 || ++ tm.tm_mday < 1 || ++ tm.tm_mday > 31) ++ return 0; ++ ++ /* #### This is actually wrong: we need to subtract the local timezone ++ offset from GMT from this value. But, that's ok in this usage, ++ because we only comparing these two GMT dates against each other, ++ so it doesn't matter what time zone we parse them in. ++ */ ++ ++ t = mktime (&tm); ++ if (t == (time_t) -1) t = 0; ++ ++ if (verbose) { ++ const char *s = string; ++ while (*s && *s != '\r' && *s != '\n') ++ fputc (*s++, stdout); ++ printf (" ==> %lu\n", (unsigned long) t); ++ } ++ ++ return t; ++ ++ } else { ++ return 0; ++ } ++} ++ ++ ++/* jwz */ ++static void ++check_document_dates (const char *headers) ++{ ++ const char *s; ++ char *server_date = 0; ++ char *document_date = 0; ++ ++ s = headers; ++ while (*s) { ++ const char *field = s; ++ const char *value = 0; ++ ++ /* Find the end of the header field */ ++ while (*s && !isspace(*s) && *s != ':') ++ s++; ++ ++ /* Remember the header value, if any. */ ++ if (*s == ':') ++ value = ++s; ++ ++ /* Skip to the end of the header, including continuation lines. */ ++ while (*s && ++ !(*s == '\n' && (s[1] != ' ' && s[1] != '\t'))) ++ s++; ++ s++; ++ ++ /* Process this header. */ ++ if (value && value > field+2) { ++ char *ff = (char *) malloc (value-field); ++ char *ss = ff; ++ while (field < value-1) ++ *ss++ = tolower(*field++); ++ *ss++ = 0; ++ ++ if (!strcmp (ff, "date") || ++ !strcmp (ff, "last-modified")) { ++ const char *e; ++ while (*value && isspace (*value)) ++ value++; ++ for (e = value; *e && *e != '\r' && *e != '\n'; e++) ++ ; ++ ss = (char *) malloc (e - value + 1); ++ strncpy (ss, value, e - value); ++ ss[e - value] = 0; ++ if (!strcmp (ff, "date")) { ++ if (server_date) free (server_date); ++ server_date = ss; ++ } else { ++ if (document_date) free (document_date); ++ document_date = ss; ++ } ++ } ++ free (ff); ++ } ++ } ++ ++ /* Done parsing the body. Now check the dates we (hopefully) parsed. ++ */ ++ if (!server_date || !*server_date) { ++ terminate (STATE_UNKNOWN, "server date unknown\n"); ++ } else if (!document_date || !*document_date) { ++ terminate (STATE_CRITICAL, "document modification date unknown\n"); ++ } else { ++ time_t sd = parse_time_string (server_date); ++ time_t dd = parse_time_string (document_date); ++ char buf [255]; ++ ++ if (sd <= 0) { ++ sprintf (buf, "server date \"%100s\" unparsable", server_date); ++ terminate (STATE_CRITICAL, buf); ++ ++ } else if (dd <= 0) { ++ sprintf (buf, "document date \"%100s\" unparsable", document_date); ++ terminate (STATE_CRITICAL, buf); ++ ++ } else if (dd > sd + 30) { ++ char buf[200]; ++ sprintf (buf, "document is %d seconds in the future\n", dd - sd); ++ terminate (STATE_CRITICAL, buf); ++ ++ } else if (dd < sd - maximum_age) { ++ char buf[200]; ++ int n = (sd - dd); ++ if (n > (60 * 60 * 24 * 2)) ++ sprintf (buf, "last modified %.1f days ago\n", ++ ((float) n) / (60 * 60 * 24)); ++ else ++ sprintf (buf, "last modified %d:%02d:%02d ago\n", ++ n / (60 * 60), (n / 60) % 60, n % 60); ++ terminate (STATE_CRITICAL, buf); ++ } ++ ++ free (server_date); ++ free (document_date); ++ } ++} ++ ++ ++ + int + check_http (void) + { +@@ -625,6 +881,12 @@ + buffer[i] = '\0'; + asprintf (&full_page, "%s%s", full_page, buffer); + pagesize += i; ++ ++ /* jwz */ ++ if (no_body && document_headers_done (full_page)) { ++ i = 0; ++ break; ++ } + } + + if (i < 0 && errno != ECONNRESET) { +@@ -685,7 +947,8 @@ + page += (size_t) strspn (page, "\r\n"); + header[pos - header] = 0; + if (verbose) +- printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, page); ++ printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, ++ (no_body ? " [[ skipped ]]" : page)); /* jwz */ + + /* make sure the status line matches the response we are looking for */ + if (!strstr (status_line, server_expect)) { +@@ -810,6 +1073,11 @@ + } /* end else (server_expect_yn) */ + + ++ /* jwz */ ++ if (maximum_age >= 0) { ++ check_document_dates (header); ++ } ++ + /* check elapsed time */ + elapsed_time = delta_time (tv); + asprintf (&msg, "HTTP problem: %s - %7.3f second response time %s%s|time=%7.3f\n", -- cgit v1.2.3-74-g34f1