Control: tags -1 + patch Please find a patch which I've been testing for a while with no ill effects AFAICT. However, I'm not familiar at all with this package so it's possible that I've missed something. I also couldn't test all available functionality.
Unfortunately the patch does not apply cleanly to the latest upstream release (4.4-alpha) but I am ready and willing to rebase it, whenever you decide to package it. Just let me know.
>From d626686d8e004bbb9e1f5f0074ff825f27d1c2e5 Mon Sep 17 00:00:00 2001 From: Yavor Doganov <ya...@gnu.org> Date: Thu, 21 Dec 2023 18:44:44 +0200 Subject: [PATCH] Port to PCRE2 (#999921). --- debian/changelog | 5 + debian/control | 2 +- debian/patches/93_pcre2.patch | 2167 +++++++++++++++++++++++++++++++++ debian/patches/series | 1 + debian/rules | 2 +- 5 files changed, 2175 insertions(+), 2 deletions(-) create mode 100644 debian/patches/93_pcre2.patch diff --git a/debian/changelog b/debian/changelog index b406ada..1c01d47 100644 --- a/debian/changelog +++ b/debian/changelog @@ -37,6 +37,11 @@ xymon (4.3.30-2) UNRELEASED; urgency=medium * xymon: update xymonserver.cfg: ntpdate obsoleted the "-p" option. (Closes: #1057044) + [ Yavor Doganov ] + * debian/patches/93_pcre2.patch: New; port to PCRE2 (Closes: #999921). + * debian/control (Build-Depends): Replace libpcre3-dev with libpcre2-dev. + * debian/rules (override_dh_auto_configure): Use pcre2-config. + -- Axel Beckert <a...@debian.org> Mon, 10 Aug 2020 04:39:28 +0200 xymon (4.3.30-1) unstable; urgency=medium diff --git a/debian/control b/debian/control index 6766762..aaa40b3 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 13), imagemagick, libc-ares-dev, libldap2-dev, - libpcre3-dev, + libpcre2-dev, librrd-dev, libssl-dev, libtirpc-dev, diff --git a/debian/patches/93_pcre2.patch b/debian/patches/93_pcre2.patch new file mode 100644 index 0000000..7c163fd --- /dev/null +++ b/debian/patches/93_pcre2.patch @@ -0,0 +1,2167 @@ +Description: Port to PCRE2. +Bug-Debian: https://bugs.debian.org/999921 +Author: Yavor Doganov <ya...@gnu.org> +Forwarded: no +Last-Update: 2023-12-21 +--- + +--- xymon.orig/lib/acknowledgementslog.c ++++ xymon/lib/acknowledgementslog.c +@@ -26,7 +26,8 @@ + #include <errno.h> + #include <time.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -103,16 +104,17 @@ + char title[200]; + + /* For the PCRE matching */ +- const char *errmsg = NULL; +- int errofs = 0; +- pcre *pageregexp = NULL; +- pcre *expageregexp = NULL; +- pcre *hostregexp = NULL; +- pcre *exhostregexp = NULL; +- pcre *testregexp = NULL; +- pcre *extestregexp = NULL; +- pcre *rcptregexp = NULL; +- pcre *exrcptregexp = NULL; ++ int err; ++ PCRE2_SIZE errofs; ++ pcre2_code *pageregexp = NULL; ++ pcre2_code *expageregexp = NULL; ++ pcre2_code *hostregexp = NULL; ++ pcre2_code *exhostregexp = NULL; ++ pcre2_code *testregexp = NULL; ++ pcre2_code *extestregexp = NULL; ++ pcre2_code *rcptregexp = NULL; ++ pcre2_code *exrcptregexp = NULL; ++ pcre2_match_data *ovector; + + if (maxminutes && (fromtime || totime)) { + fprintf(output, "<B>Only one time interval type is allowed!</B>"); +@@ -147,14 +149,14 @@ + + if (!maxcount) maxcount = 100; + +- if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (rcptregex && *rcptregex) rcptregexp = pcre_compile(rcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (exrcptregex && *exrcptregex) exrcptregexp = pcre_compile(exrcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ if (pageregex && *pageregex) pageregexp = pcre2_compile(pageregex, strlen(pageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (expageregex && *expageregex) expageregexp = pcre2_compile(expageregex, strlen(expageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (hostregex && *hostregex) hostregexp = pcre2_compile(hostregex, strlen(hostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (exhostregex && *exhostregex) exhostregexp = pcre2_compile(exhostregex, strlen(exhostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (testregex && *testregex) testregexp = pcre2_compile(testregex, strlen(testregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (extestregex && *extestregex) extestregexp = pcre2_compile(extestregex, strlen(extestregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (rcptregex && *rcptregex) rcptregexp = pcre2_compile(rcptregex, strlen(rcptregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (exrcptregex && *exrcptregex) exrcptregexp = pcre2_compile(exrcptregex, strlen(exrcptregex), PCRE2_CASELESS, &err, &errofs, NULL); + + snprintf(acknowledgementslogfilename, sizeof(acknowledgementslogfilename), "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS")); + acknowledgementslog = fopen(acknowledgementslogfilename, "r"); +@@ -194,6 +196,7 @@ + } + + head = NULL; ++ ovector = pcre2_match_data_create(30, NULL); + + while (acknowledgementslog && (fgets(l, sizeof(l), acknowledgementslog))) { + +@@ -211,7 +214,6 @@ + acknowledgements_t *newrec; + void *eventhost; + struct htnames_t *eventcolumn; +- int ovector[30]; + + /* 2015-03-07 18:17:03 myserver disk andy 1 1425724570 1425752223 1425838623 testing message */ + itemsfound = sscanf(l, "%*u-%*u-%*u %*u:%*u:%*u %s %s %s %*u %*u %u %u %[^\t\n]", host, svc, recipient, &etim, &valid, message); +@@ -254,8 +256,8 @@ + pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(pageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } +@@ -269,8 +271,8 @@ + pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(expageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } +@@ -279,43 +281,43 @@ + if (pagematch) continue; + + if (hostregexp) +- hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(hostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 1; + if (!hostmatch) continue; + + if (exhostregexp) +- hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(exhostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 0; + if (hostmatch) continue; + + if (testregexp) +- testmatch = (pcre_exec(testregexp, NULL, svcname, strlen(svcname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(testregexp, svcname, strlen(svcname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 1; + if (!testmatch) continue; + + if (extestregexp) +- testmatch = (pcre_exec(extestregexp, NULL, svcname, strlen(svcname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(extestregexp, svcname, strlen(svcname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 0; + if (testmatch) continue; + + if (rcptregexp) +- rcptmatch = (pcre_exec(rcptregexp, NULL, recipient, strlen(recipient), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ rcptmatch = (pcre2_match(rcptregexp, recipient, strlen(recipient), 0, 0, ++ ovector, NULL) >= 0); + else + rcptmatch = 1; + if (!rcptmatch) continue; + + if (exrcptregexp) +- rcptmatch = (pcre_exec(exrcptregexp, NULL, recipient, strlen(recipient), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ rcptmatch = (pcre2_match(exrcptregexp, recipient, strlen(recipient), 0, 0, ++ ovector, NULL) >= 0); + else + rcptmatch = 0; + if (rcptmatch) continue; +@@ -405,13 +407,14 @@ + + if (acknowledgementslog) fclose(acknowledgementslog); + +- if (pageregexp) pcre_free(pageregexp); +- if (expageregexp) pcre_free(expageregexp); +- if (hostregexp) pcre_free(hostregexp); +- if (exhostregexp) pcre_free(exhostregexp); +- if (testregexp) pcre_free(testregexp); +- if (extestregexp) pcre_free(extestregexp); +- if (rcptregexp) pcre_free(rcptregexp); +- if (exrcptregexp) pcre_free(exrcptregexp); ++ if (pageregexp) pcre2_code_free(pageregexp); ++ if (expageregexp) pcre2_code_free(expageregexp); ++ if (hostregexp) pcre2_code_free(hostregexp); ++ if (exhostregexp) pcre2_code_free(exhostregexp); ++ if (testregexp) pcre2_code_free(testregexp); ++ if (extestregexp) pcre2_code_free(extestregexp); ++ if (rcptregexp) pcre2_code_free(rcptregexp); ++ if (exrcptregexp) pcre2_code_free(exrcptregexp); ++ pcre2_match_data_free(ovector); + } + +--- xymon.orig/lib/eventlog.c ++++ xymon/lib/eventlog.c +@@ -28,7 +28,8 @@ + #include <errno.h> + #include <time.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -176,32 +177,36 @@ + } + + static int eventfilter(void *hinfo, char *testname, +- pcre *pageregexp, pcre *expageregexp, +- pcre *hostregexp, pcre *exhostregexp, +- pcre *testregexp, pcre *extestregexp, ++ pcre2_code *pageregexp, pcre2_code *expageregexp, ++ pcre2_code *hostregexp, pcre2_code *exhostregexp, ++ pcre2_code *testregexp, pcre2_code *extestregexp, + int ignoredialups, f_hostcheck hostcheck) + { + int pagematch, hostmatch, testmatch; + char *hostname = xmh_item(hinfo, XMH_HOSTNAME); +- int ovector[30]; ++ pcre2_match_data *ovector; + + if (ignoredialups && xmh_item(hinfo, XMH_FLAG_DIALUP)) return 0; + if (hostcheck && (hostcheck(hostname) == 0)) return 0; + ++ ovector = pcre2_match_data_create(30, NULL); + if (pageregexp) { + char *pagename; + + pagename = xmh_item_multi(hinfo, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(pageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } + else + pagematch = 1; +- if (!pagematch) return 0; ++ if (!pagematch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + if (expageregexp) { + char *pagename; +@@ -209,51 +214,67 @@ + pagename = xmh_item_multi(hinfo, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(expageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } + else + pagematch = 0; +- if (pagematch) return 0; ++ if (pagematch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + if (hostregexp) +- hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(hostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 1; +- if (!hostmatch) return 0; ++ if (!hostmatch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + if (exhostregexp) +- hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(exhostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 0; +- if (hostmatch) return 0; ++ if (hostmatch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + if (testregexp) +- testmatch = (pcre_exec(testregexp, NULL, testname, strlen(testname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(testregexp, testname, strlen(testname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 1; +- if (!testmatch) return 0; ++ if (!testmatch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + if (extestregexp) +- testmatch = (pcre_exec(extestregexp, NULL, testname, strlen(testname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(extestregexp, testname, strlen(testname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 0; +- if (testmatch) return 0; ++ if (testmatch) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } ++ pcre2_match_data_free(ovector); + + return 1; + } + + + static void count_duration(time_t fromtime, time_t totime, +- pcre *pageregexp, pcre *expageregexp, +- pcre *hostregexp, pcre *exhostregexp, +- pcre *testregexp, pcre *extestregexp, ++ pcre2_code *pageregexp, pcre2_code *expageregexp, ++ pcre2_code *hostregexp, pcre2_code *exhostregexp, ++ pcre2_code *testregexp, pcre2_code *extestregexp, + int ignoredialups, f_hostcheck hostcheck, + event_t *eventhead, countlist_t **hostcounthead, countlist_t **svccounthead) + { +@@ -515,15 +536,16 @@ + char title[200]; + + /* For the PCRE matching */ +- const char *errmsg = NULL; +- int errofs = 0; +- pcre *pageregexp = NULL; +- pcre *expageregexp = NULL; +- pcre *hostregexp = NULL; +- pcre *exhostregexp = NULL; +- pcre *testregexp = NULL; +- pcre *extestregexp = NULL; +- pcre *colrregexp = NULL; ++ int err; ++ PCRE2_SIZE errofs; ++ pcre2_code *pageregexp = NULL; ++ pcre2_code *expageregexp = NULL; ++ pcre2_code *hostregexp = NULL; ++ pcre2_code *exhostregexp = NULL; ++ pcre2_code *testregexp = NULL; ++ pcre2_code *extestregexp = NULL; ++ pcre2_code *colrregexp = NULL; ++ pcre2_match_data *ovector; + countlist_t *hostcounthead = NULL, *svccounthead = NULL; + + if (eventlist) *eventlist = NULL; +@@ -569,13 +591,13 @@ + + if (!maxcount) maxcount = 100; + +- if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (colrregex && *colrregex) colrregexp = pcre_compile(colrregex, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ if (pageregex && *pageregex) pageregexp = pcre2_compile(pageregex, strlen(pageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (expageregex && *expageregex) expageregexp = pcre2_compile(expageregex, strlen(expageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (hostregex && *hostregex) hostregexp = pcre2_compile(hostregex, strlen(hostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (exhostregex && *exhostregex) exhostregexp = pcre2_compile(exhostregex, strlen(exhostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (testregex && *testregex) testregexp = pcre2_compile(testregex, strlen(testregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (extestregex && *extestregex) extestregexp = pcre2_compile(extestregex, strlen(extestregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (colrregex && *colrregex) colrregexp = pcre2_compile(colrregex, strlen(colrregex), PCRE2_CASELESS, &err, &errofs, NULL); + + snprintf(eventlogfilename, sizeof(eventlogfilename), "%s/allevents", xgetenv("XYMONHISTDIR")); + eventlog = fopen(eventlogfilename, "r"); +@@ -618,6 +640,7 @@ + } + + eventhead = NULL; ++ ovector = pcre2_match_data_create(30, NULL); + + while (eventlog && (fgets(l, sizeof(l), eventlog))) { + +@@ -629,7 +652,6 @@ + event_t *newevent; + void *eventhost; + struct htnames_t *eventcolumn; +- int ovector[30]; + eventcount_t *countrec; + + itemsfound = sscanf(l, "%s %s %u %u %u %s %s %d", +@@ -657,10 +679,10 @@ + + /* For duration counts, record all events. We'll filter out the colors later. */ + if (colrregexp && (counttype != XYMON_COUNT_DURATION)) { +- colrmatch = ( (pcre_exec(colrregexp, NULL, newcolname, strlen(newcolname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0) || +- (pcre_exec(colrregexp, NULL, oldcolname, strlen(oldcolname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0) ); ++ colrmatch = ( (pcre2_match(colrregexp, newcolname, strlen(newcolname), 0, 0, ++ ovector, NULL) >= 0) || ++ (pcre2_match(colrregexp, oldcolname, strlen(oldcolname), 0, 0, ++ ovector, NULL) >= 0) ); + } + else + colrmatch = 1; +@@ -842,10 +864,11 @@ + + if (eventlog) fclose(eventlog); + +- if (pageregexp) pcre_free(pageregexp); +- if (hostregexp) pcre_free(hostregexp); +- if (testregexp) pcre_free(testregexp); +- if (colrregexp) pcre_free(colrregexp); ++ if (pageregexp) pcre2_code_free(pageregexp); ++ if (hostregexp) pcre2_code_free(hostregexp); ++ if (testregexp) pcre2_code_free(testregexp); ++ if (colrregexp) pcre2_code_free(colrregexp); ++ pcre2_match_data_free(ovector); + + /* Return the event- and count-lists, if wanted - or clean them up */ + if (eventlist) { +--- xymon.orig/lib/headfoot.c ++++ xymon/lib/headfoot.c +@@ -22,7 +22,8 @@ + #include <stdio.h> + #include <string.h> + #include <fcntl.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + #include "version.h" +@@ -50,13 +51,13 @@ + static char *scheduleboard = NULL; + + static char *hostpattern_text = NULL; +-static pcre *hostpattern = NULL; ++static pcre2_code *hostpattern = NULL; + static char *pagepattern_text = NULL; +-static pcre *pagepattern = NULL; ++static pcre2_code *pagepattern = NULL; + static char *ippattern_text = NULL; +-static pcre *ippattern = NULL; ++static pcre2_code *ippattern = NULL; + static char *classpattern_text = NULL; +-static pcre *classpattern = NULL; ++static pcre2_code *classpattern = NULL; + static void * hostnames; + static void * testnames; + +@@ -158,34 +159,34 @@ + + void sethostenv_filter(char *hostptn, char *pageptn, char *ipptn, char *classptn) + { +- const char *errmsg; +- int errofs; ++ int err; ++ PCRE2_SIZE errofs; + + if (hostpattern_text) xfree(hostpattern_text); +- if (hostpattern) { pcre_free(hostpattern); hostpattern = NULL; } ++ if (hostpattern) { pcre2_code_free(hostpattern); hostpattern = NULL; } + if (pagepattern_text) xfree(pagepattern_text); +- if (pagepattern) { pcre_free(pagepattern); pagepattern = NULL; } ++ if (pagepattern) { pcre2_code_free(pagepattern); pagepattern = NULL; } + if (ippattern_text) xfree(ippattern_text); +- if (ippattern) { pcre_free(ippattern); ippattern = NULL; } ++ if (ippattern) { pcre2_code_free(ippattern); ippattern = NULL; } + if (classpattern_text) xfree(classpattern_text); +- if (classpattern) { pcre_free(classpattern); classpattern = NULL; } ++ if (classpattern) { pcre2_code_free(classpattern); classpattern = NULL; } + + /* Setup the pattern to match names against */ + if (hostptn) { + hostpattern_text = strdup(hostptn); +- hostpattern = pcre_compile(hostptn, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ hostpattern = pcre2_compile(hostptn, strlen(hostptn), PCRE2_CASELESS, &err, &errofs, NULL); + } + if (pageptn) { + pagepattern_text = strdup(pageptn); +- pagepattern = pcre_compile(pageptn, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ pagepattern = pcre2_compile(pageptn, strlen(pageptn), PCRE2_CASELESS, &err, &errofs, NULL); + } + if (ipptn) { + ippattern_text = strdup(ipptn); +- ippattern = pcre_compile(ipptn, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ ippattern = pcre2_compile(ipptn, strlen(ipptn), PCRE2_CASELESS, &err, &errofs, NULL); + } + if (classptn) { + classpattern_text = strdup(classptn); +- classpattern = pcre_compile(classptn, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ classpattern = pcre2_compile(classptn, strlen(classptn), PCRE2_CASELESS, &err, &errofs, NULL); + } + } + +@@ -371,38 +372,53 @@ + static void *wanted_host(char *hostname) + { + void *hinfo = hostinfo(hostname); +- int result, ovector[30]; ++ int result; ++ pcre2_match_data *ovector; + + if (!hinfo) return NULL; + ++ ovector = pcre2_match_data_create(30, NULL); + if (hostpattern) { +- result = pcre_exec(hostpattern, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); +- if (result < 0) return NULL; ++ result = pcre2_match(hostpattern, hostname, strlen(hostname), 0, 0, ++ ovector, NULL); ++ if (result < 0) { ++ pcre2_match_data_free(ovector); ++ return NULL; ++ } + } + + if (pagepattern && hinfo) { + char *pname = xmh_item(hinfo, XMH_PAGEPATH); +- result = pcre_exec(pagepattern, NULL, pname, strlen(pname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); +- if (result < 0) return NULL; ++ result = pcre2_match(pagepattern, pname, strlen(pname), 0, 0, ++ ovector, NULL); ++ if (result < 0) { ++ pcre2_match_data_free(ovector); ++ return NULL; ++ } + } + + if (ippattern && hinfo) { + char *hostip = xmh_item(hinfo, XMH_IP); +- result = pcre_exec(ippattern, NULL, hostip, strlen(hostip), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); +- if (result < 0) return NULL; ++ result = pcre2_match(ippattern, hostip, strlen(hostip), 0, 0, ++ ovector, NULL); ++ if (result < 0) { ++ pcre2_match_data_free(ovector); ++ return NULL; ++ } + } + + if (classpattern && hinfo) { + char *hostclass = xmh_item(hinfo, XMH_CLASS); + if (!hostclass) return NULL; + +- result = pcre_exec(classpattern, NULL, hostclass, strlen(hostclass), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); +- if (result < 0) return NULL; ++ result = pcre2_match(classpattern, hostclass, strlen(hostclass), 0, 0, ++ ovector, NULL); ++ if (result < 0) { ++ pcre2_match_data_free(ovector); ++ return NULL; ++ } + } ++ pcre2_match_data_free(ovector); + + return hinfo; + } +--- xymon.orig/lib/loadalerts.c ++++ xymon/lib/loadalerts.c +@@ -25,7 +25,8 @@ + #include <limits.h> + #include <errno.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -164,29 +165,29 @@ + { + if (crit->cfline) xfree(crit->cfline); + if (crit->pagespec) xfree(crit->pagespec); +- if (crit->pagespecre) pcre_free(crit->pagespecre); ++ if (crit->pagespecre) pcre2_code_free(crit->pagespecre); + if (crit->expagespec) xfree(crit->expagespec); +- if (crit->expagespecre) pcre_free(crit->expagespecre); ++ if (crit->expagespecre) pcre2_code_free(crit->expagespecre); + if (crit->dgspec) xfree(crit->dgspec); +- if (crit->dgspecre) pcre_free(crit->dgspecre); ++ if (crit->dgspecre) pcre2_code_free(crit->dgspecre); + if (crit->exdgspec) xfree(crit->exdgspec); +- if (crit->exdgspecre) pcre_free(crit->exdgspecre); ++ if (crit->exdgspecre) pcre2_code_free(crit->exdgspecre); + if (crit->hostspec) xfree(crit->hostspec); +- if (crit->hostspecre) pcre_free(crit->hostspecre); ++ if (crit->hostspecre) pcre2_code_free(crit->hostspecre); + if (crit->exhostspec) xfree(crit->exhostspec); +- if (crit->exhostspecre) pcre_free(crit->exhostspecre); ++ if (crit->exhostspecre) pcre2_code_free(crit->exhostspecre); + if (crit->svcspec) xfree(crit->svcspec); +- if (crit->svcspecre) pcre_free(crit->svcspecre); ++ if (crit->svcspecre) pcre2_code_free(crit->svcspecre); + if (crit->exsvcspec) xfree(crit->exsvcspec); +- if (crit->exsvcspecre) pcre_free(crit->exsvcspecre); ++ if (crit->exsvcspecre) pcre2_code_free(crit->exsvcspecre); + if (crit->classspec) xfree(crit->classspec); +- if (crit->classspecre) pcre_free(crit->classspecre); ++ if (crit->classspecre) pcre2_code_free(crit->classspecre); + if (crit->exclassspec) xfree(crit->exclassspec); +- if (crit->exclassspecre) pcre_free(crit->exclassspecre); ++ if (crit->exclassspecre) pcre2_code_free(crit->exclassspecre); + if (crit->groupspec) xfree(crit->groupspec); +- if (crit->groupspecre) pcre_free(crit->groupspecre); ++ if (crit->groupspecre) pcre2_code_free(crit->groupspecre); + if (crit->exgroupspec) xfree(crit->exgroupspec); +- if (crit->exgroupspecre) pcre_free(crit->exgroupspecre); ++ if (crit->exgroupspecre) pcre2_code_free(crit->exgroupspecre); + if (crit->timespec) xfree(crit->timespec); + if (crit->extimespec) xfree(crit->extimespec); + } +--- xymon.orig/lib/matching.c ++++ xymon/lib/matching.c +@@ -18,55 +18,60 @@ + #include <string.h> + #include <stdlib.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +-pcre *compileregex_opts(const char *pattern, int flags) ++pcre2_code *compileregex_opts(const char *pattern, uint32_t flags) + { +- pcre *result; +- const char *errmsg; +- int errofs; ++ pcre2_code *result; ++ char errmsg[120]; ++ int err; ++ PCRE2_SIZE errofs; + + dbgprintf("Compiling regex %s\n", pattern); +- result = pcre_compile(pattern, flags, &errmsg, &errofs, NULL); ++ result = pcre2_compile(pattern, strlen(pattern), flags, &err, &errofs, NULL); + if (result == NULL) { +- errprintf("pcre compile '%s' failed (offset %d): %s\n", pattern, errofs, errmsg); ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("pcre compile '%s' failed (offset %zu): %s\n", pattern, errofs, errmsg); + return NULL; + } + + return result; + } + +-pcre *compileregex(const char *pattern) ++pcre2_code *compileregex(const char *pattern) + { +- return compileregex_opts(pattern, PCRE_CASELESS); ++ return compileregex_opts(pattern, PCRE2_CASELESS); + } + +-pcre *multilineregex(const char *pattern) ++pcre2_code *multilineregex(const char *pattern) + { +- return compileregex_opts(pattern, PCRE_CASELESS|PCRE_MULTILINE); ++ return compileregex_opts(pattern, PCRE2_CASELESS|PCRE2_MULTILINE); + } + +-int matchregex(const char *needle, pcre *pcrecode) ++int matchregex(const char *needle, pcre2_code *pcrecode) + { +- int ovector[30]; ++ pcre2_match_data *ovector; + int result; + + if (!needle || !pcrecode) return 0; + +- result = pcre_exec(pcrecode, NULL, needle, strlen(needle), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ ovector = pcre2_match_data_create(30, NULL); ++ result = pcre2_match(pcrecode, needle, strlen(needle), 0, 0, ovector, NULL); ++ pcre2_match_data_free(ovector); + return (result >= 0); + } + +-void freeregex(pcre *pcrecode) ++void freeregex(pcre2_code *pcrecode) + { + if (!pcrecode) return; + +- pcre_free(pcrecode); ++ pcre2_code_free(pcrecode); + } + +-int namematch(const char *needle, char *haystack, pcre *pcrecode) ++int namematch(const char *needle, char *haystack, pcre2_code *pcrecode) + { + char *xhay; + char *tokbuf = NULL, *tok; +@@ -118,7 +123,7 @@ + return result; + } + +-int patternmatch(char *datatosearch, char *pattern, pcre *pcrecode) ++int patternmatch(char *datatosearch, char *pattern, pcre2_code *pcrecode) + { + if (pcrecode) { + /* Do regex matching. The regex has already been compiled for us. */ +@@ -133,17 +138,17 @@ + return (strstr(datatosearch, pattern) != NULL); + } + +-pcre **compile_exprs(char *id, const char **patterns, int count) ++pcre2_code **compile_exprs(char *id, const char **patterns, int count) + { +- pcre **result = NULL; ++ pcre2_code **result = NULL; + int i; + +- result = (pcre **)calloc(count, sizeof(pcre *)); ++ result = (pcre2_code **)calloc(count, sizeof(pcre2_code *)); + for (i=0; (i < count); i++) { + result[i] = compileregex(patterns[i]); + if (!result[i]) { + errprintf("Internal error: %s pickdata PCRE-compile failed\n", id); +- for (i=0; (i < count); i++) if (result[i]) pcre_free(result[i]); ++ for (i=0; (i < count); i++) if (result[i]) pcre2_code_free(result[i]); + xfree(result); + return NULL; + } +@@ -152,24 +157,30 @@ + return result; + } + +-int pickdata(char *buf, pcre *expr, int dupok, ...) ++int pickdata(char *buf, pcre2_code *expr, int dupok, ...) + { + int res, i; +- int ovector[30]; ++ pcre2_match_data *ovector; + va_list ap; + char **ptr; + char w[100]; ++ PCRE2_SIZE l; + + if (!expr) return 0; + +- res = pcre_exec(expr, NULL, buf, strlen(buf), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); +- if (res < 0) return 0; ++ ovector = pcre2_match_data_create(30, NULL); ++ res = pcre2_match(expr, buf, strlen(buf), 0, 0, ovector, NULL); ++ if (res < 0) { ++ pcre2_match_data_free(ovector); ++ return 0; ++ } + + va_start(ap, dupok); + + for (i=1; (i < res); i++) { + *w = '\0'; +- pcre_copy_substring(buf, ovector, res, i, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, i, w, &l); + ptr = va_arg(ap, char **); + if (dupok) { + if (*ptr) xfree(*ptr); +@@ -186,6 +197,7 @@ + } + + va_end(ap); ++ pcre2_match_data_free(ovector); + + return 1; + } +--- xymon.orig/lib/matching.h ++++ xymon/lib/matching.h +@@ -13,11 +13,12 @@ + + /* The clients probably don't have the pcre headers */ + #if defined(LOCALCLIENT) || !defined(CLIENTONLY) +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + #include <stdarg.h> + +-extern pcre *compileregex(const char *pattern); +-extern pcre *compileregex_opts(const char *pattern, int flags); ++extern pcre2_code *compileregex(const char *pattern); ++extern pcre2_code *compileregex_opts(const char *pattern, uint32_t flags); + #ifdef PCRE_FIRSTLINE + #define firstlineregex(P) compileregex_opts(P, PCRE_FIRSTLINE); + #define firstlineregexnocase(P) compileregex_opts(P, PCRE_CASELESS|PCRE_FIRSTLINE); +@@ -25,13 +26,13 @@ + #define firstlineregex(P) compileregex_opts(P, 0); + #define firstlineregexnocase(P) compileregex_opts(P, PCRE_CASELESS); + #endif +-extern pcre *multilineregex(const char *pattern); +-extern int matchregex(const char *needle, pcre *pcrecode); +-extern void freeregex(pcre *pcrecode); +-extern int namematch(const char *needle, char *haystack, pcre *pcrecode); +-extern int patternmatch(char *datatosearch, char *pattern, pcre *pcrecode); +-extern pcre **compile_exprs(char *id, const char **patterns, int count); +-extern int pickdata(char *buf, pcre *expr, int dupok, ...); ++extern pcre2_code *multilineregex(const char *pattern); ++extern int matchregex(const char *needle, pcre2_code *pcrecode); ++extern void freeregex(pcre2_code *pcrecode); ++extern int namematch(const char *needle, char *haystack, pcre2_code *pcrecode); ++extern int patternmatch(char *datatosearch, char *pattern, pcre2_code *pcrecode); ++extern pcre2_code **compile_exprs(char *id, const char **patterns, int count); ++extern int pickdata(char *buf, pcre2_code *expr, int dupok, ...); + extern int timematch(char *holidaykey, char *tspec); + #endif + +--- xymon.orig/lib/notifylog.c ++++ xymon/lib/notifylog.c +@@ -26,7 +26,8 @@ + #include <errno.h> + #include <time.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -101,16 +102,17 @@ + char title[200]; + + /* For the PCRE matching */ +- const char *errmsg = NULL; +- int errofs = 0; +- pcre *pageregexp = NULL; +- pcre *expageregexp = NULL; +- pcre *hostregexp = NULL; +- pcre *exhostregexp = NULL; +- pcre *testregexp = NULL; +- pcre *extestregexp = NULL; +- pcre *rcptregexp = NULL; +- pcre *exrcptregexp = NULL; ++ int err; ++ PCRE2_SIZE errofs; ++ pcre2_code *pageregexp = NULL; ++ pcre2_code *expageregexp = NULL; ++ pcre2_code *hostregexp = NULL; ++ pcre2_code *exhostregexp = NULL; ++ pcre2_code *testregexp = NULL; ++ pcre2_code *extestregexp = NULL; ++ pcre2_code *rcptregexp = NULL; ++ pcre2_code *exrcptregexp = NULL; ++ pcre2_match_data *ovector; + + if (maxminutes && (fromtime || totime)) { + fprintf(output, "<B>Only one time interval type is allowed!</B>"); +@@ -145,14 +147,14 @@ + + if (!maxcount) maxcount = 100; + +- if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (rcptregex && *rcptregex) rcptregexp = pcre_compile(rcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (exrcptregex && *exrcptregex) exrcptregexp = pcre_compile(exrcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ if (pageregex && *pageregex) pageregexp = pcre2_compile(pageregex, strlen(pageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (expageregex && *expageregex) expageregexp = pcre2_compile(expageregex, strlen(expageregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (hostregex && *hostregex) hostregexp = pcre2_compile(hostregex, strlen(hostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (exhostregex && *exhostregex) exhostregexp = pcre2_compile(exhostregex, strlen(exhostregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (testregex && *testregex) testregexp = pcre2_compile(testregex, strlen(testregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (extestregex && *extestregex) extestregexp = pcre2_compile(extestregex, strlen(extestregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (rcptregex && *rcptregex) rcptregexp = pcre2_compile(rcptregex, strlen(rcptregex), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (exrcptregex && *exrcptregex) exrcptregexp = pcre2_compile(exrcptregex, strlen(exrcptregex), PCRE2_CASELESS, &err, &errofs, NULL); + + snprintf(notifylogfilename, sizeof(notifylogfilename), "%s/notifications.log", xgetenv("XYMONSERVERLOGS")); + notifylog = fopen(notifylogfilename, "r"); +@@ -188,6 +190,7 @@ + } + + head = NULL; ++ ovector = pcre2_match_data_create(30, NULL); + + while (notifylog && (fgets(l, sizeof(l), notifylog))) { + +@@ -200,7 +203,6 @@ + notification_t *newrec; + void *eventhost; + struct htnames_t *eventcolumn; +- int ovector[30]; + + itemsfound = sscanf(l, "%*s %*s %*u %*u:%*u:%*u %*u %s %*s %s %u %*d", hostsvc, recipient, &etim); + eventtime = etim; +@@ -221,8 +223,8 @@ + pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(pageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } +@@ -236,8 +238,8 @@ + pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); + pagematch = 0; + while (!pagematch && pagename) { +- pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ pagematch = (pcre2_match(expageregexp, pagename, strlen(pagename), 0, 0, ++ ovector, NULL) >= 0); + pagename = xmh_item_multi(NULL, XMH_PAGEPATH); + } + } +@@ -246,43 +248,43 @@ + if (pagematch) continue; + + if (hostregexp) +- hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(hostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 1; + if (!hostmatch) continue; + + if (exhostregexp) +- hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ hostmatch = (pcre2_match(exhostregexp, hostname, strlen(hostname), 0, 0, ++ ovector, NULL) >= 0); + else + hostmatch = 0; + if (hostmatch) continue; + + if (testregexp) +- testmatch = (pcre_exec(testregexp, NULL, svcname, strlen(svcname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(testregexp, svcname, strlen(svcname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 1; + if (!testmatch) continue; + + if (extestregexp) +- testmatch = (pcre_exec(extestregexp, NULL, svcname, strlen(svcname), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ testmatch = (pcre2_match(extestregexp, svcname, strlen(svcname), 0, 0, ++ ovector, NULL) >= 0); + else + testmatch = 0; + if (testmatch) continue; + + if (rcptregexp) +- rcptmatch = (pcre_exec(rcptregexp, NULL, recipient, strlen(recipient), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ rcptmatch = (pcre2_match(rcptregexp, recipient, strlen(recipient), 0, 0, ++ ovector, NULL) >= 0); + else + rcptmatch = 1; + if (!rcptmatch) continue; + + if (exrcptregexp) +- rcptmatch = (pcre_exec(exrcptregexp, NULL, recipient, strlen(recipient), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ rcptmatch = (pcre2_match(exrcptregexp, recipient, strlen(recipient), 0, 0, ++ ovector, NULL) >= 0); + else + rcptmatch = 0; + if (rcptmatch) continue; +@@ -367,13 +369,14 @@ + + if (notifylog) fclose(notifylog); + +- if (pageregexp) pcre_free(pageregexp); +- if (expageregexp) pcre_free(expageregexp); +- if (hostregexp) pcre_free(hostregexp); +- if (exhostregexp) pcre_free(exhostregexp); +- if (testregexp) pcre_free(testregexp); +- if (extestregexp) pcre_free(extestregexp); +- if (rcptregexp) pcre_free(rcptregexp); +- if (exrcptregexp) pcre_free(exrcptregexp); ++ if (pageregexp) pcre2_code_free(pageregexp); ++ if (expageregexp) pcre2_code_free(expageregexp); ++ if (hostregexp) pcre2_code_free(hostregexp); ++ if (exhostregexp) pcre2_code_free(exhostregexp); ++ if (testregexp) pcre2_code_free(testregexp); ++ if (extestregexp) pcre2_code_free(extestregexp); ++ if (rcptregexp) pcre2_code_free(rcptregexp); ++ if (exrcptregexp) pcre2_code_free(exrcptregexp); ++ pcre2_match_data_free(ovector); + } + +--- xymon.orig/web/showgraph.c ++++ xymon/web/showgraph.c +@@ -27,7 +27,8 @@ + #include <sys/un.h> + #include <fcntl.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + #include <rrd.h> + + #include "libxymon.h" +@@ -950,10 +951,11 @@ + } + else { + struct dirent *d; +- pcre *pat, *expat = NULL; +- const char *errmsg; +- int errofs, result; +- int ovector[30]; ++ pcre2_code *pat, *expat = NULL; ++ char errmsg[120]; ++ int err, result; ++ PCRE2_SIZE errofs; ++ pcre2_match_data *ovector; + struct stat st; + time_t now = getcurrenttime(NULL); + +@@ -961,21 +963,23 @@ + dir = opendir("."); if (dir == NULL) errormsg("Unexpected error while accessing RRD directory"); + + /* Setup the pattern to match filenames against */ +- pat = pcre_compile(gdef->fnpat, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ pat = pcre2_compile(gdef->fnpat, strlen(gdef->fnpat), PCRE2_CASELESS, &err, &errofs, NULL); + if (!pat) { + char msg[8192]; + +- snprintf(msg, sizeof(msg), "graphs.cfg error, PCRE pattern %s invalid: %s, offset %d\n", ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ snprintf(msg, sizeof(msg), "graphs.cfg error, PCRE pattern %s invalid: %s, offset %zu\n", + htmlquoted(gdef->fnpat), errmsg, errofs); + errormsg(msg); + } + if (gdef->exfnpat) { +- expat = pcre_compile(gdef->exfnpat, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ expat = pcre2_compile(gdef->exfnpat, strlen(gdef->exfnpat), PCRE2_CASELESS, &err, &errofs, NULL); + if (!expat) { + char msg[8192]; + ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); + snprintf(msg, sizeof(msg), +- "graphs.cfg error, PCRE pattern %s invalid: %s, offset %d\n", ++ "graphs.cfg error, PCRE pattern %s invalid: %s, offset %zu\n", + htmlquoted(gdef->exfnpat), errmsg, errofs); + errormsg(msg); + } +@@ -985,9 +989,11 @@ + rrddbsize = 5; + rrddbs = (rrddb_t *) malloc((rrddbsize+1) * sizeof(rrddb_t)); + ++ ovector = pcre2_match_data_create(30, NULL); + while ((d = readdir(dir)) != NULL) { + char *ext; + char param[PATH_MAX]; ++ PCRE2_SIZE l = sizeof(param); + + /* Ignore dot-files and files with names shorter than ".rrd" */ + if (*(d->d_name) == '.') continue; +@@ -996,14 +1002,14 @@ + + /* First check the exclude pattern. */ + if (expat) { +- result = pcre_exec(expat, NULL, d->d_name, strlen(d->d_name), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(expat, d->d_name, strlen(d->d_name), 0, 0, ++ ovector, NULL); + if (result >= 0) continue; + } + + /* Then see if the include pattern matches. */ +- result = pcre_exec(pat, NULL, d->d_name, strlen(d->d_name), 0, 0, +- ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(pat, d->d_name, strlen(d->d_name), 0, 0, ++ ovector, NULL); + if (result < 0) continue; + + if (wantsingle) { +@@ -1021,7 +1027,7 @@ + + /* We have a matching file! */ + rrddbs[rrddbcount].rrdfn = strdup(d->d_name); +- if (pcre_copy_substring(d->d_name, ovector, result, 1, param, sizeof(param)) > 0) { ++ if (pcre2_substring_copy_bynumber(ovector, 1, param, &l) > 0) { + /* + * This is ugly, but I cannot find a pretty way of un-mangling + * the disk- and http-data that has been molested by the back-end. +@@ -1059,8 +1065,9 @@ + rrddbs = (rrddb_t *)realloc(rrddbs, (rrddbsize+1) * sizeof(rrddb_t)); + } + } +- pcre_free(pat); +- if (expat) pcre_free(expat); ++ pcre2_code_free(pat); ++ if (expat) pcre2_code_free(expat); ++ pcre2_match_data_free(ovector); + closedir(dir); + } + rrddbs[rrddbcount].key = rrddbs[rrddbcount].rrdfn = rrddbs[rrddbcount].rrdparam = NULL; +--- xymon.orig/xymond/client_config.c ++++ xymon/xymond/client_config.c +@@ -28,14 +28,15 @@ + #include <limits.h> + #include <errno.h> + +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + #include "client_config.h" + + typedef struct exprlist_t { + char *pattern; +- pcre *exp; ++ pcre2_code *exp; + struct exprlist_t *next; + } exprlist_t; + +@@ -592,7 +593,7 @@ + exprlist_t *tmp = exprhead; + exprhead = exprhead->next; + if (tmp->pattern) xfree(tmp->pattern); +- if (tmp->exp) pcre_free(tmp->exp); ++ if (tmp->exp) pcre2_code_free(tmp->exp); + xfree(tmp); + } + exprhead = NULL; +--- xymon.orig/xymond/do_rrd.c ++++ xymon/xymond/do_rrd.c +@@ -23,7 +23,8 @@ + #include <utime.h> + + #include <rrd.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +--- xymon.orig/xymond/rrd/do_netstat.c ++++ xymon/xymond/rrd/do_netstat.c +@@ -65,7 +65,7 @@ + outp += sprintf(outp, ":%s", (tcpretranspackets ? tcpretranspackets : "U")); if (tcpretranspackets) xfree(tcpretranspackets); + } + +-static int handle_pcre_netstat(char *msg, pcre **pcreset, char *outp) ++static int handle_pcre_netstat(char *msg, pcre2_code **pcreset, char *outp) + { + enum { AT_NONE, AT_TCP, AT_UDP } sect = AT_NONE; + int havedata = 0; +@@ -432,12 +432,12 @@ + int do_netstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) + { + static int pcres_compiled = 0; +- static pcre **netstat_osf_pcres = NULL; +- static pcre **netstat_aix_pcres = NULL; +- static pcre **netstat_irix_pcres = NULL; +- static pcre **netstat_hpux_pcres = NULL; +- static pcre **netstat_bsd_pcres = NULL; +- static pcre **netstat_sco_sv_pcres = NULL; ++ static pcre2_code **netstat_osf_pcres = NULL; ++ static pcre2_code **netstat_aix_pcres = NULL; ++ static pcre2_code **netstat_irix_pcres = NULL; ++ static pcre2_code **netstat_hpux_pcres = NULL; ++ static pcre2_code **netstat_bsd_pcres = NULL; ++ static pcre2_code **netstat_sco_sv_pcres = NULL; + + enum ostype_t ostype; + char *datapart = msg; +--- xymon.orig/xymond/xymon-mailack.c ++++ xymon/xymond/xymon-mailack.c +@@ -17,7 +17,8 @@ + #include <ctype.h> + #include <stdio.h> + #include <string.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -31,11 +32,12 @@ + char *firsttxtline = NULL; + int inheaders = 1; + char *p; +- pcre *subjexp; +- const char *errmsg; +- int errofs, result; +- int ovector[30]; ++ pcre2_code *subjexp; ++ int err, result; ++ PCRE2_SIZE errofs; ++ pcre2_match_data *ovector; + char cookie[10]; ++ PCRE2_SIZE l = sizeof(cookie); + int duration = 0; + int argi; + char *envarea = NULL; +@@ -96,51 +98,58 @@ + } + + /* Get the alert cookie */ +- subjexp = pcre_compile(".*(Xymon|Hobbit|BB)[ -]* \\[*(-*[0-9]+)[\\]!]*", PCRE_CASELESS, &errmsg, &errofs, NULL); ++ subjexp = pcre2_compile(".*(Xymon|Hobbit|BB)[ -]* \\[*(-*[0-9]+)[\\]!]*", PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + if (subjexp == NULL) { + dbgprintf("pcre compile failed - 1\n"); + return 2; + } +- result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ ovector = pcre2_match_data_create(30, NULL); ++ result = pcre2_match(subjexp, subjectline, strlen(subjectline), 0, 0, ovector, NULL); + if (result < 0) { ++ pcre2_match_data_free(ovector); + dbgprintf("Subject line did not match pattern\n"); + return 3; /* Subject did not match what we expected */ + } +- if (pcre_copy_substring(subjectline, ovector, result, 2, cookie, sizeof(cookie)) <= 0) { ++ if (pcre2_substring_copy_bynumber(ovector, 2, cookie, &l) <= 0) { ++ pcre2_match_data_free(ovector); + dbgprintf("Could not find cookie value\n"); + return 4; /* No cookie */ + } +- pcre_free(subjexp); ++ pcre2_code_free(subjexp); + + /* See if there's a "DELAY=" delay-value also */ +- subjexp = pcre_compile(".*DELAY[ =]+([0-9]+[mhdw]*)", PCRE_CASELESS, &errmsg, &errofs, NULL); ++ subjexp = pcre2_compile(".*DELAY[ =]+([0-9]+[mhdw]*)", PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + if (subjexp == NULL) { ++ pcre2_match_data_free(ovector); + dbgprintf("pcre compile failed - 2\n"); + return 2; + } +- result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(subjexp, subjectline, strlen(subjectline), 0, 0, ovector, NULL); + if (result >= 0) { + char delaytxt[4096]; +- if (pcre_copy_substring(subjectline, ovector, result, 1, delaytxt, sizeof(delaytxt)) > 0) { ++ l = sizeof(delaytxt); ++ if (pcre2_substring_copy_bynumber(ovector, 1, delaytxt, &l) > 0) { + duration = durationvalue(delaytxt); + } + } +- pcre_free(subjexp); ++ pcre2_code_free(subjexp); + + /* See if there's a "msg" text also */ +- subjexp = pcre_compile(".*MSG[ =]+(.*)", PCRE_CASELESS, &errmsg, &errofs, NULL); ++ subjexp = pcre2_compile(".*MSG[ =]+(.*)", PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + if (subjexp == NULL) { ++ pcre2_match_data_free(ovector); + dbgprintf("pcre compile failed - 3\n"); + return 2; + } +- result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(subjexp, subjectline, strlen(subjectline), 0, 0, ovector, NULL); + if (result >= 0) { + char msgtxt[4096]; +- if (pcre_copy_substring(subjectline, ovector, result, 1, msgtxt, sizeof(msgtxt)) > 0) { ++ l = sizeof(msgtxt); ++ if (pcre2_substring_copy_bynumber(ovector, 1, msgtxt, &l) > 0) { + firsttxtline = strdup(msgtxt); + } + } +- pcre_free(subjexp); ++ pcre2_code_free(subjexp); + + /* Use the "return-path:" header if we didn't see a From: line */ + if ((fromline == NULL) && returnpathline) fromline = returnpathline; +--- xymon.orig/xymond/xymond_capture.c ++++ xymon/xymond/xymond_capture.c +@@ -34,13 +34,14 @@ + int running; + int argi, seq; + struct timespec *timeout = NULL; +- pcre *hostexp = NULL; +- pcre *exhostexp = NULL; +- pcre *testexp = NULL; +- pcre *extestexp = NULL; +- pcre *colorexp = NULL; +- const char *errmsg = NULL; +- int errofs = 0; ++ pcre2_code *hostexp = NULL; ++ pcre2_code *exhostexp = NULL; ++ pcre2_code *testexp = NULL; ++ pcre2_code *extestexp = NULL; ++ pcre2_code *colorexp = NULL; ++ pcre2_match_data *ovector; ++ int err; ++ PCRE2_SIZE errofs; + FILE *logfd = stdout; + int batchtimeout = 30; + char *batchcmd = NULL; +@@ -75,27 +76,27 @@ + } + else if (argnmatch(argv[argi], "--hosts=")) { + char *exp = strchr(argv[argi], '=') + 1; +- hostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ hostexp = pcre2_compile(exp, strlen(exp), PCRE2_CASELESS, &err, &errofs, NULL); + if (hostexp == NULL) printf("Invalid expression '%s'\n", exp); + } + else if (argnmatch(argv[argi], "--exhosts=")) { + char *exp = strchr(argv[argi], '=') + 1; +- exhostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ exhostexp = pcre2_compile(exp, strlen(exp), PCRE2_CASELESS, &err, &errofs, NULL); + if (exhostexp == NULL) printf("Invalid expression '%s'\n", exp); + } + else if (argnmatch(argv[argi], "--tests=")) { + char *exp = strchr(argv[argi], '=') + 1; +- testexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ testexp = pcre2_compile(exp, strlen(exp), PCRE2_CASELESS, &err, &errofs, NULL); + if (testexp == NULL) printf("Invalid expression '%s'\n", exp); + } + else if (argnmatch(argv[argi], "--extests=")) { + char *exp = strchr(argv[argi], '=') + 1; +- extestexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ extestexp = pcre2_compile(exp, strlen(exp), PCRE2_CASELESS, &err, &errofs, NULL); + if (extestexp == NULL) printf("Invalid expression '%s'\n", exp); + } + else if (argnmatch(argv[argi], "--colors=")) { + char *exp = strchr(argv[argi], '=') + 1; +- colorexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); ++ colorexp = pcre2_compile(exp, strlen(exp), PCRE2_CASELESS, &err, &errofs, NULL); + if (colorexp == NULL) printf("Invalid expression '%s'\n", exp); + } + else if (argnmatch(argv[argi], "--outfile=")) { +@@ -127,6 +128,7 @@ + + signal(SIGCHLD, SIG_IGN); + ++ ovector = pcre2_match_data_create(30, NULL); + running = 1; + while (running) { + char *eoln, *restofmsg, *p; +@@ -245,7 +247,6 @@ + * Process this message. + */ + else { +- int ovector[30]; + int match, i; + char *hostname = metadata[hostnameitem]; + char *testname = metadata[testnameitem]; +@@ -298,23 +299,23 @@ + + + if (hostexp) { +- match = (pcre_exec(hostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ match = (pcre2_match(hostexp, hostname, strlen(hostname), 0, 0, ovector, NULL) >= 0); + if (!match) continue; + } + if (exhostexp) { +- match = (pcre_exec(exhostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ match = (pcre2_match(exhostexp, hostname, strlen(hostname), 0, 0, ovector, NULL) >= 0); + if (match) continue; + } + if (testexp) { +- match = (pcre_exec(testexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ match = (pcre2_match(testexp, testname, strlen(testname), 0, 0, ovector, NULL) >= 0); + if (!match) continue; + } + if (extestexp) { +- match = (pcre_exec(extestexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ match = (pcre2_match(extestexp, testname, strlen(testname), 0, 0, ovector, NULL) >= 0); + if (match) continue; + } + if (colorexp) { +- match = (pcre_exec(colorexp, NULL, color, strlen(color), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); ++ match = (pcre2_match(colorexp, color, strlen(color), 0, 0, ovector, NULL) >= 0); + if (!match) continue; + } + +@@ -338,6 +339,7 @@ + } + } + } ++ pcre2_match_data_free(ovector); + + return 0; + } +--- xymon.orig/build/test-pcre.c ++++ xymon/build/test-pcre.c +@@ -1,11 +1,12 @@ +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + int main(int argc, char *argv[]) + { +- pcre *result; +- const char *errmsg; +- int errofs; +- result = pcre_compile("xymon.*", PCRE_CASELESS, &errmsg, &errofs, NULL); ++ pcre2_code *result; ++ int err; ++ PCRE2_SIZE errofs; ++ result = pcre2_compile("xymon.*", PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + + return 0; + } +--- xymon.orig/build/Makefile.test-pcre ++++ xymon/build/Makefile.test-pcre +@@ -4,7 +4,7 @@ + @$(CC) $(CFLAGS) $(PCREINC) -o test-pcre.o -c test-pcre.c + + test-link: +- @$(CC) $(CFLAGS) $(PCRELIB) -o test-pcre test-pcre.o -lpcre ++ @$(CC) $(CFLAGS) $(PCRELIB) -o test-pcre test-pcre.o -lpcre2-8 + + clean: + @rm -f test-pcre.o test-pcre +--- xymon.orig/lib/loadalerts.h ++++ xymon/lib/loadalerts.h +@@ -16,7 +16,8 @@ + + /* The clients probably don't have the pcre headers */ + #if defined(LOCALCLIENT) || !defined(CLIENTONLY) +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + typedef enum { A_PAGING, A_NORECIP, A_ACKED, A_RECOVERED, A_DISABLED, A_NOTIFY, A_DEAD } astate_t; + +@@ -50,29 +51,29 @@ + int cfid; + char *cfline; + char *pagespec; /* Pages to include */ +- pcre *pagespecre; ++ pcre2_code *pagespecre; + char *expagespec; /* Pages to exclude */ +- pcre *expagespecre; ++ pcre2_code *expagespecre; + char *dgspec; /* Display groups to include */ +- pcre *dgspecre; ++ pcre2_code *dgspecre; + char *exdgspec; /* Display groups to exclude */ +- pcre *exdgspecre; ++ pcre2_code *exdgspecre; + char *hostspec; /* Hosts to include */ +- pcre *hostspecre; ++ pcre2_code *hostspecre; + char *exhostspec; /* Hosts to exclude */ +- pcre *exhostspecre; ++ pcre2_code *exhostspecre; + char *svcspec; /* Services to include */ +- pcre *svcspecre; ++ pcre2_code *svcspecre; + char *exsvcspec; /* Services to exclude */ +- pcre *exsvcspecre; ++ pcre2_code *exsvcspecre; + char *classspec; +- pcre *classspecre; ++ pcre2_code *classspecre; + char *exclassspec; +- pcre *exclassspecre; ++ pcre2_code *exclassspecre; + char *groupspec; +- pcre *groupspecre; ++ pcre2_code *groupspecre; + char *exgroupspec; +- pcre *exgroupspecre; ++ pcre2_code *exgroupspecre; + int colors; + char *timespec; + char *extimespec; +--- xymon.orig/lib/clientlocal.c ++++ xymon/lib/clientlocal.c +@@ -16,11 +16,13 @@ + #include <unistd.h> + #include <stdlib.h> + #include <string.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + + typedef struct clientconfig_t { +- pcre *hostptn, *classptn, *osptn; ++ pcre2_code *hostptn, *classptn, *osptn; + strbuffer_t *config; + struct clientconfig_t *next; + } clientconfig_t; +@@ -117,7 +119,7 @@ + + if (!insection) { + if (*STRBUF(buf) == '[') { +- pcre *hostptn = NULL, *classptn = NULL, *osptn = NULL; ++ pcre2_code *hostptn = NULL, *classptn = NULL, *osptn = NULL; + clientconfig_t *newrec; + + p = STRBUF(buf) + strcspn(STRBUF(buf), "\r\n"); +--- xymon.orig/configure.server ++++ xymon/configure.server +@@ -470,10 +470,10 @@ + echo "PCREINCDIR = -I$PCREINC" >>Makefile + fi + if test "$PCRELIB" != ""; then +- echo "PCRELIBS = -L$PCRELIB -lpcre" >>Makefile ++ echo "PCRELIBS = -L$PCRELIB -lpcre2-8" >>Makefile + echo "RPATHVAL += ${PCRELIB}" >>Makefile + else +- echo "PCRELIBS = -lpcre" >>Makefile ++ echo "PCRELIBS = -lpcre2-8" >>Makefile + fi + fi + echo "" >>Makefile +--- xymon.orig/xymonnet/httpresult.c ++++ xymon/xymonnet/httpresult.c +@@ -80,7 +80,7 @@ + { + int result = -1; + char codestr[15]; +- pcre *ptn; ++ pcre2_code *ptn; + + /* Use code 999 to indicate we could not fetch the URL */ + snprintf(codestr, sizeof(codestr), "%d", (status ? status : 999)); +--- xymon.orig/xymonnet/beastat.c ++++ xymon/xymonnet/beastat.c +@@ -22,8 +22,6 @@ + #include <sys/types.h> + #include <sys/stat.h> + +-#include <pcre.h> +- + #include "libxymon.h" + #include "version.h" + +--- xymon.orig/xymond/xymond.c ++++ xymon/xymond/xymond.c +@@ -361,7 +361,7 @@ + + typedef struct hostfilter_rec_t { + enum filtertype_t filtertype; +- pcre *wantedptn; int wantedvalue; ++ pcre2_code *wantedptn; int wantedvalue; + struct hostfilter_rec_t *next; + enum xmh_item_t field; /* Only for filtertype == FILTER_XMH */ + enum boardfield_t boardfield; /* Only for filtertype == FILTER_FIELD(TIME) */ +@@ -2870,7 +2870,7 @@ + { + char *tok; + hostfilter_rec_t *filterhead = NULL, *filtertail = NULL; +- static pcre *xmhptn = NULL; ++ static pcre2_code *xmhptn = NULL; + + dbgprintf("-> setup_filter: %s\n", buf); + +--- xymon.orig/xymond/xymond_channel.c ++++ xymon/xymond/xymond_channel.c +@@ -426,8 +426,8 @@ + char *pidfile = NULL; + char *envarea = NULL; + int cnid = -1; +- pcre *msgfilter = NULL; +- pcre *stdfilter = NULL; ++ pcre2_code *msgfilter = NULL; ++ pcre2_code *stdfilter = NULL; + + int argi; + struct sigaction sa; +--- xymon.orig/xymond/do_alert.c ++++ xymon/xymond/do_alert.c +@@ -27,8 +27,6 @@ + #include <errno.h> + #include <sys/wait.h> + +-#include <pcre.h> +- + #include "libxymon.h" + + /* +--- xymon.orig/xymond/client/irix.c ++++ xymon/xymond/client/irix.c +@@ -16,7 +16,7 @@ + void *hinfo, char *sender, time_t timestamp, + char *clientdata) + { +- static pcre *memptn = NULL; ++ static pcre2_code *memptn = NULL; + char *timestr; + char *uptimestr; + char *clockstr; +@@ -69,8 +69,9 @@ + if (topstr) { + char *memline, *eoln = NULL; + int res; +- int ovector[20]; ++ pcre2_match_data *ovector; + char w[20]; ++ PCRE2_SIZE l; + long memphystotal = -1, memphysused = -1, memphysfree = 0, + memacttotal = -1, memactused = -1, memactfree = -1, + memswaptotal = -1, memswapused = -1, memswapfree = 0; +@@ -79,40 +80,47 @@ + memptn = compileregex("^Memory: (\\d+)M max, (\\d+)M avail, (\\d+)M free, (\\d+)M swap, (\\d+)M free swap"); + } + ++ ovector = pcre2_match_data_create(20, NULL); + memline = strstr(topstr, "\nMemory:"); + if (memline) { + memline++; + eoln = strchr(memline, '\n'); if (eoln) *eoln = '\0'; + +- res = pcre_exec(memptn, NULL, memline, strlen(memline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ res = pcre2_match(memptn, memline, strlen(memline), 0, 0, ovector, NULL); + } + else res = -1; + + if (res > 1) { +- pcre_copy_substring(memline, ovector, res, 1, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, 1, w, &l); + memphystotal = atol(w); + } + if (res > 2) { +- pcre_copy_substring(memline, ovector, res, 2, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, 2, w, &l); + memactfree = atol(w); + memacttotal = memphystotal; + memactused = memphystotal - memactfree; + } + if (res > 3) { +- pcre_copy_substring(memline, ovector, res, 3, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, 3, w, &l); + memphysfree = atol(w); + memphysused = memphystotal - memphysfree; + } + + if (res > 4) { +- pcre_copy_substring(memline, ovector, res, 4, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, 4, w, &l); + memswaptotal = atol(w); + } + if (res > 5) { +- pcre_copy_substring(memline, ovector, res, 5, w, sizeof(w)); ++ l = sizeof(w); ++ pcre2_substring_copy_bynumber(ovector, 5, w, &l); + memswapfree = atol(w); + } + memswapused = memswaptotal - memswapfree; ++ pcre2_match_data_free(ovector); + + if (eoln) *eoln = '\n'; + +--- xymon.orig/xymond/rrd/do_ifstat.c ++++ xymon/xymond/rrd/do_ifstat.c +@@ -120,17 +120,17 @@ + int do_ifstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) + { + static int pcres_compiled = 0; +- static pcre **ifstat_linux_pcres = NULL; +- static pcre **ifstat_freebsd_pcres = NULL; +- static pcre **ifstat_freebsdV8_pcres = NULL; +- static pcre **ifstat_openbsd_pcres = NULL; +- static pcre **ifstat_netbsd_pcres = NULL; +- static pcre **ifstat_darwin_pcres = NULL; +- static pcre **ifstat_solaris_pcres = NULL; +- static pcre **ifstat_aix_pcres = NULL; +- static pcre **ifstat_hpux_pcres = NULL; +- static pcre **ifstat_sco_sv_pcres = NULL; +- static pcre **ifstat_bbwin_pcres = NULL; ++ static pcre2_code **ifstat_linux_pcres = NULL; ++ static pcre2_code **ifstat_freebsd_pcres = NULL; ++ static pcre2_code **ifstat_freebsdV8_pcres = NULL; ++ static pcre2_code **ifstat_openbsd_pcres = NULL; ++ static pcre2_code **ifstat_netbsd_pcres = NULL; ++ static pcre2_code **ifstat_darwin_pcres = NULL; ++ static pcre2_code **ifstat_solaris_pcres = NULL; ++ static pcre2_code **ifstat_aix_pcres = NULL; ++ static pcre2_code **ifstat_hpux_pcres = NULL; ++ static pcre2_code **ifstat_sco_sv_pcres = NULL; ++ static pcre2_code **ifstat_bbwin_pcres = NULL; + + enum ostype_t ostype; + char *datapart = msg; +@@ -138,7 +138,7 @@ + int dmatch; + + void *xmh; +- pcre *ifname_filter_pcre = NULL; ++ pcre2_code *ifname_filter_pcre = NULL; + + xmh = hostinfo(hostname); + if (xmh) { +--- xymon.orig/xymond/rrd/do_dbcheck.c ++++ xymon/xymond/rrd/do_dbcheck.c +@@ -223,28 +223,36 @@ + + char *eoln, *curline; + static int ptnsetup = 0; +- static pcre *inclpattern = NULL; +- static pcre *exclpattern = NULL; ++ static pcre2_code *inclpattern = NULL; ++ static pcre2_code *exclpattern = NULL; ++ pcre2_match_data *ovector; + + if (tablespace_tpl == NULL) tablespace_tpl = setup_template(tablespace_params); + + if (!ptnsetup) { +- const char *errmsg; +- int errofs; ++ char errmsg[120]; ++ int err; ++ PCRE2_SIZE errofs; + char *ptn; + + ptnsetup = 1; + ptn = getenv("RRDDISKS"); + if (ptn && strlen(ptn)) { +- inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ++ inclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!inclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + ptn = getenv("NORRDDISKS"); + if (ptn && strlen(ptn)) { +- exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ++ exclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!exclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + } + +@@ -261,6 +269,7 @@ + eoln = strchr(curline, '\n'); + curline = (eoln ? (eoln+1) : NULL); + } ++ ovector = pcre2_match_data_create(30, NULL); + + while (curline) { + char *fsline, *p; +@@ -307,20 +316,18 @@ + /* Check include/exclude patterns */ + wanteddisk = 1; + if (exclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(exclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result < 0); + } + if (wanteddisk && inclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(inclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result >= 0); + } +@@ -350,6 +357,7 @@ + nextline: + curline = (eoln ? (eoln+1) : NULL); + } ++ pcre2_match_data_free(ovector); + + return 0; + } +--- xymon.orig/xymond/rrd/do_devmon.c ++++ xymon/xymond/rrd/do_devmon.c +@@ -18,8 +18,8 @@ + + char *eoln, *curline; + static int ptnsetup = 0; +- static pcre *inclpattern = NULL; +- static pcre *exclpattern = NULL; ++ static pcre2_code *inclpattern = NULL; ++ static pcre2_code *exclpattern = NULL; + int in_devmon = 1; + int numds = 0; + char *rrdbasename; +--- xymon.orig/xymond/rrd/do_disk.c ++++ xymon/xymond/rrd/do_disk.c +@@ -18,8 +18,9 @@ + enum { DT_IRIX, DT_AS400, DT_NT, DT_UNIX, DT_NETAPP, DT_NETWARE, DT_BBWIN } dsystype; + char *eoln, *curline; + static int ptnsetup = 0; +- static pcre *inclpattern = NULL; +- static pcre *exclpattern = NULL; ++ static pcre2_code *inclpattern = NULL; ++ static pcre2_code *exclpattern = NULL; ++ pcre2_match_data *ovector; + int seen_root_fs = 0; + + if (strstr(msg, "netapp.pl")) return do_netapp_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); +@@ -28,22 +29,29 @@ + if (disk_tpl == NULL) disk_tpl = setup_template(disk_params); + + if (!ptnsetup) { +- const char *errmsg; +- int errofs; ++ char errmsg[120]; ++ int err; ++ PCRE2_SIZE errofs; + char *ptn; + + ptnsetup = 1; + ptn = getenv("RRDDISKS"); + if (ptn && strlen(ptn)) { +- inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ++ inclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!inclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + ptn = getenv("NORRDDISKS"); + if (ptn && strlen(ptn)) { +- exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ++ exclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!exclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + } + +@@ -72,6 +80,7 @@ + * line - we never have any disk reports there anyway. + */ + curline = strchr(msg, '\n'); if (curline) curline++; ++ ovector = pcre2_match_data_create(30, NULL); + while (curline) { + char *fsline, *p; + char *columns[20]; +@@ -178,20 +187,18 @@ + seen_root_fs = 1; + } + if (exclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(exclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result < 0); + } + if (wanteddisk && inclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(inclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result >= 0); + } +@@ -221,6 +228,7 @@ + nextline: + curline = (eoln ? (eoln+1) : NULL); + } ++ pcre2_match_data_free(ovector); + + return 0; + } +--- xymon.orig/xymond/rrd/do_la.c ++++ xymon/xymond/rrd/do_la.c +@@ -17,8 +17,8 @@ + static char *clock_params[] = { "DS:la:GAUGE:600:U:U", NULL }; /* "la" is a misnomer, but to stay compatiable with existing RRD files */ + static void *clock_tpl = NULL; + +- static pcre *as400_exp = NULL; +- static pcre *zVM_exp = NULL; ++ static pcre2_code *as400_exp = NULL; ++ static pcre2_code *zVM_exp = NULL; + static time_t starttime = 0; + + char *p, *eoln = NULL; +@@ -66,25 +66,28 @@ + * the operating system name is part of the message (as in the tests above). + */ + +- int ovector[30]; ++ pcre2_match_data *ovector; + char w[100]; ++ PCRE2_SIZE l = sizeof(w); + int res; + + if (zVM_exp == NULL) { +- const char *errmsg = NULL; +- int errofs = 0; ++ int err; ++ PCRE2_SIZE errofs; + +- zVM_exp = pcre_compile(".* CPU Utilization *([0-9]+)%", PCRE_CASELESS, &errmsg, &errofs, NULL); ++ zVM_exp = pcre2_compile(".* CPU Utilization *([0-9]+)%", PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + } + +- res = pcre_exec(zVM_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ ovector = pcre2_match_data_create(30, NULL); ++ res = pcre2_match(zVM_exp, msg, strlen(msg), 0, 0, ovector, NULL); + if (res >= 0) { + /* We have a match - pick up the data. */ +- *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); ++ *w = '\0'; if (res > 0) pcre2_substring_copy_bynumber(ovector, 1, w, &l); + if (strlen(w)) { + load = atoi(w); gotload = 1; + } + } ++ pcre2_match_data_free(ovector); + + goto done_parsing; + } +@@ -139,31 +142,34 @@ + * No "uptime" in message - could be from an AS/400. They look like this: + * green March 21, 2005 12:33:24 PM EST deltacdc 108 users 45525 jobs(126 batch,0 waiting for message), load=26% + */ +- int ovector[30]; ++ pcre2_match_data *ovector; + char w[100]; ++ PCRE2_SIZE l = sizeof(w); + int res; + + if (as400_exp == NULL) { +- const char *errmsg = NULL; +- int errofs = 0; ++ int err; ++ PCRE2_SIZE errofs; + +- as400_exp = pcre_compile(".* ([0-9]+) users ([0-9]+) jobs.* load=([0-9]+)\\%", +- PCRE_CASELESS, &errmsg, &errofs, NULL); ++ as400_exp = pcre2_compile(".* ([0-9]+) users ([0-9]+) jobs.* load=([0-9]+)\\%", ++ PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &err, &errofs, NULL); + } + +- res = pcre_exec(as400_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ ovector = pcre2_match_data_create(30, NULL); ++ res = pcre2_match(as400_exp, msg, strlen(msg), 0, 0, ovector, NULL); + if (res >= 0) { + /* We have a match - pick up the AS/400 data. */ +- *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); ++ *w = '\0'; if (res > 0) pcre2_substring_copy_bynumber(ovector, 1, w, &l); + if (strlen(w)) { + users = atoi(w); gotusers = 1; + } + +- *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 3, w, sizeof(w)); ++ *w = '\0'; l = sizeof(w); if (res > 0) pcre2_substring_copy_bynumber(ovector, 3, w, &l); + if (strlen(w)) { + load = atoi(w); gotload = 1; + } + } ++ pcre2_match_data_free(ovector); + } + + done_parsing: +--- xymon.orig/xymond/rrd/do_netapp.c ++++ xymon/xymond/rrd/do_netapp.c +@@ -492,8 +492,9 @@ + + char *eoln, *curline; + static int ptnsetup = 0; +- static pcre *inclpattern = NULL; +- static pcre *exclpattern = NULL; ++ static pcre2_code *inclpattern = NULL; ++ static pcre2_code *exclpattern = NULL; ++ pcre2_match_data *ovector; + int newdfreport; + + newdfreport = (strstr(msg,"netappnewdf") != NULL); +@@ -501,22 +502,29 @@ + if (netapp_disk_tpl == NULL) netapp_disk_tpl = setup_template(netapp_disk_params); + + if (!ptnsetup) { +- const char *errmsg; +- int errofs; ++ char errmsg[120]; ++ int err; ++ PCRE2_SIZE errofs; + char *ptn; + + ptnsetup = 1; + ptn = getenv("RRDDISKS"); + if (ptn && strlen(ptn)) { +- inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ++ inclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!inclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + ptn = getenv("NORRDDISKS"); + if (ptn && strlen(ptn)) { +- exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); +- if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ++ exclpattern = pcre2_compile(ptn, strlen(ptn), PCRE2_CASELESS, &err, &errofs, NULL); ++ if (!exclpattern) { ++ pcre2_get_error_message(err, errmsg, sizeof(errmsg)); ++ errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %zu\n", + ptn, errmsg, errofs); ++ } + } + } + +@@ -527,6 +535,7 @@ + * line - we never have any disk reports there anyway. + */ + curline = strchr(msg, '\n'); if (curline) curline++; ++ ovector = pcre2_match_data_create(30, NULL); + + while (curline) { + char *fsline, *p; +@@ -592,20 +601,18 @@ + /* Check include/exclude patterns */ + wanteddisk = 1; + if (exclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(exclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result < 0); + } + if (wanteddisk && inclpattern) { +- int ovector[30]; + int result; + +- result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), +- 0, 0, ovector, (sizeof(ovector)/sizeof(int))); ++ result = pcre2_match(inclpattern, diskname, strlen(diskname), ++ 0, 0, ovector, NULL); + + wanteddisk = (result >= 0); + } +@@ -635,6 +642,7 @@ + nextline: + curline = (eoln ? (eoln+1) : NULL); + } ++ pcre2_match_data_free(ovector); + + return 0; + } +--- xymon.orig/web/acknowledge.c ++++ xymon/web/acknowledge.c +@@ -264,7 +264,7 @@ + + if (obeycookies && !gotfilter && ((hostname = get_cookie("host")) != NULL)) { + if (*hostname) { +- pcre *dummy; ++ pcre2_code *dummy; + SBUF_DEFINE(re); + + SBUF_MALLOC(re, 3+strlen(hostname)); +@@ -286,7 +286,7 @@ + + if (obeycookies && !gotfilter && ((pagename = get_cookie("pagepath")) != NULL)) { + if (*pagename) { +- pcre *dummy; ++ pcre2_code *dummy; + SBUF_DEFINE(re); + + SBUF_MALLOC(re, 8 + strlen(pagename)*2); +--- xymon.orig/web/svcstatus.c ++++ xymon/web/svcstatus.c +@@ -359,7 +359,7 @@ + + /* We need not check that hostname is valid, has already been done with loadhostdata() */ + if (!complist) { +- pcre *dummy = NULL; ++ pcre2_code *dummy = NULL; + + /* Check service as a pcre pattern. And no spaces in servicenames */ + if (strchr(service, ' ') == NULL) dummy = compileregex(service); +@@ -373,7 +373,7 @@ + snprintf(xymondreq, xymondreq_buflen, "xymondlog host=%s test=%s fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,ackmsg,dismsg,client,acklist,XMH_IP,XMH_DISPLAYNAME,clntstamp,flapinfo,modifiers", hostname, service); + } + else { +- pcre *dummy = NULL; ++ pcre2_code *dummy = NULL; + SBUF_DEFINE(re); + + SBUF_MALLOC(re, 5 + strlen(complist)); +--- xymon.orig/web/confreport.c ++++ xymon/web/confreport.c +@@ -693,7 +693,7 @@ + + /* Fetch the list of host+test statuses we currently know about */ + if (pagepattern) { +- pcre *dummy; ++ pcre2_code *dummy; + SBUF_DEFINE(re); + + SBUF_MALLOC(re, 8 + 2*strlen(pagepattern)); +@@ -716,7 +716,7 @@ + xfree(re); + } + else if (hostpattern) { +- pcre *dummy; ++ pcre2_code *dummy; + SBUF_DEFINE(re); + + SBUF_MALLOC(re,3 + strlen(hostpattern)); +--- xymon.orig/web/statusreport.c ++++ xymon/web/statusreport.c +@@ -128,7 +128,7 @@ + /* Setup the filter we use for the report */ + cookie = get_cookie("pagepath"); + if (cookie && *cookie) { +- pcre *dummy; ++ pcre2_code *dummy; + SBUF_DEFINE(re); + + SBUF_MALLOC(re, 8 + 2*strlen(cookie)); +--- xymon.orig/web/hostlist.c ++++ xymon/web/hostlist.c +@@ -71,7 +71,7 @@ + int argi, res; + sendreturn_t *sres; + char *cookie; +- pcre *dummy; ++ pcre2_code *dummy; + + init_timestamp(); + for (argi=1; (argi < argc); argi++) { +--- xymon.orig/web/perfdata.c ++++ xymon/web/perfdata.c +@@ -21,7 +21,8 @@ + #include <dirent.h> + + #include <rrd.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + + #include "libxymon.h" + +@@ -314,7 +315,7 @@ + + int main(int argc, char **argv) + { +- pcre *hostptn, *exhostptn, *pageptn, *expageptn; ++ pcre2_code *hostptn, *exhostptn, *pageptn, *expageptn; + void *hwalk; + char *hostname, *pagename; + diff --git a/debian/patches/series b/debian/patches/series index f4b45ff..2601d36 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -16,3 +16,4 @@ 87_fix_logfetch_FTBFS_with_glibc_2.26.patch 90_reproducible-build.patch 92_ntpdate_obsoleted_-p_option +93_pcre2.patch diff --git a/debian/rules b/debian/rules index 2813fd2..0af02c2 100755 --- a/debian/rules +++ b/debian/rules @@ -37,7 +37,7 @@ override_dh_auto_configure: INSTALLTMPDIR=/var/lib/xymon/tmp \ INSTALLWWWDIR=/var/lib/xymon/www \ ./configure --server \ - --pcrelib $(shell pcre-config --libs) \ + --pcrelib $(shell pcre2-config --libs8) \ --ssllib /usr/lib/$(DEB_HOST_MULTIARCH) \ --ldaplib /usr/lib/$(DEB_HOST_MULTIARCH) -- 2.43.0