Re: [PATCH] rteval: Remove XML-RPC server

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Wed, 20 Mar 2024, tglozar@xxxxxxxxxx wrote:

> From: Tomas Glozar <tglozar@xxxxxxxxxx>
> 
> Remove code for rteval XML-RPC server and client as well as associated
> modules (rtevalMailer). The code was disabled in 2d547eb6 ("rteval:
> Disable options for remote xmlrpc server").
> 
> Also remove all references to the functionality in documentation except
> for author credits.
> 
> Signed-off-by: Tomas Glozar <tglozar@xxxxxxxxxx>
> ---
>  .gitignore                             |    5 -
>  Makefile                               |   15 +-
>  doc/rteval.8                           |    6 -
>  doc/rteval.txt                         |   18 +-
>  rteval-cmd                             |    6 -
>  rteval/__init__.py                     |   25 -
>  rteval/rtevalConfig.py                 |    1 -
>  rteval/rtevalMailer.py                 |   51 --
>  rteval/rtevalXMLRPC.py                 |   97 ---
>  rteval/rtevalclient.py                 |   60 --
>  server/COPYING                         |  339 --------
>  server/INSTALL                         |  302 -------
>  server/Logger.py                       |   19 -
>  server/Makefile.am                     |   38 -
>  server/README.xmlrpc                   |  201 -----
>  server/apache-rteval-wsgi.conf.tpl     |   22 -
>  server/apache-rteval.conf.tpl          |   18 -
>  server/configure.ac                    |  130 ---
>  server/database.py                     |  238 ------
>  server/gen_config.sh                   |   14 -
>  server/parser/Makefile.am              |   30 -
>  server/parser/README.parser            |  204 -----
>  server/parser/argparser.c              |  140 ---
>  server/parser/argparser.h              |   21 -
>  server/parser/configparser.c           |  171 ----
>  server/parser/configparser.h           |   25 -
>  server/parser/eurephia_nullsafe.c      |   54 --
>  server/parser/eurephia_nullsafe.h      |  103 ---
>  server/parser/eurephia_values.c        |  301 -------
>  server/parser/eurephia_values.h        |   48 --
>  server/parser/eurephia_values_struct.h |   38 -
>  server/parser/eurephia_xml.c           |  147 ----
>  server/parser/eurephia_xml.h           |   43 -
>  server/parser/log.c                    |  228 -----
>  server/parser/log.h                    |   43 -
>  server/parser/parsethread.c            |  370 --------
>  server/parser/parsethread.h            |   38 -
>  server/parser/pgsql.c                  | 1093 ------------------------
>  server/parser/pgsql.h                  |   58 --
>  server/parser/rteval-parserd.c         |  533 ------------
>  server/parser/rteval-parserd.init      |  126 ---
>  server/parser/rteval-parserd.sysconfig |   23 -
>  server/parser/sha1.c                   |  615 -------------
>  server/parser/sha1.h                   |   66 --
>  server/parser/statuses.h               |   33 -
>  server/parser/threadinfo.h             |   38 -
>  server/parser/xmlparser.c              |  620 --------------
>  server/parser/xmlparser.h              |   75 --
>  server/parser/xmlparser.xsl            |  607 -------------
>  server/remove_rtevalrun                |   65 --
>  server/rteval-parser.spec              |  133 ---
>  server/rteval_testserver.py            |  107 ---
>  server/rteval_xmlrpc.py                |   71 --
>  server/rteval_xmlrpc.wsgi              |   94 --
>  server/rtevaldb.py                     |   57 --
>  server/sql/delta-1.0_1.1.sql           |   15 -
>  server/sql/delta-1.1_1.2.sql           |    9 -
>  server/sql/delta-1.2_1.3.sql           |    6 -
>  server/sql/delta-1.3_1.4.sql           |    6 -
>  server/sql/delta-1.4_1.5.sql           |   31 -
>  server/sql/rteval-1.0.sql              |  189 ----
>  server/sql/rteval-1.1.sql              |  203 -----
>  server/sql/rteval-1.2.sql              |  207 -----
>  server/sql/rteval-1.3.sql              |  208 -----
>  server/sql/rteval-1.4.sql              |  209 -----
>  server/sql/rteval-1.5.sql              |  235 -----
>  server/testclient.py                   |   37 -
>  server/testclient_sendreportfile       |   36 -
>  server/unittest.py                     |   91 --
>  server/xmlrpc_API1.py                  |  100 ---
>  unit-tests/unittest.py                 |    1 -
>  71 files changed, 2 insertions(+), 9604 deletions(-)
>  delete mode 100644 rteval/rtevalMailer.py
>  delete mode 100644 rteval/rtevalXMLRPC.py
>  delete mode 100644 rteval/rtevalclient.py
>  delete mode 100644 server/COPYING
>  delete mode 100644 server/INSTALL
>  delete mode 100644 server/Logger.py
>  delete mode 100644 server/Makefile.am
>  delete mode 100644 server/README.xmlrpc
>  delete mode 100644 server/apache-rteval-wsgi.conf.tpl
>  delete mode 100644 server/apache-rteval.conf.tpl
>  delete mode 100644 server/configure.ac
>  delete mode 100644 server/database.py
>  delete mode 100755 server/gen_config.sh
>  delete mode 100644 server/parser/Makefile.am
>  delete mode 100644 server/parser/README.parser
>  delete mode 100644 server/parser/argparser.c
>  delete mode 100644 server/parser/argparser.h
>  delete mode 100644 server/parser/configparser.c
>  delete mode 100644 server/parser/configparser.h
>  delete mode 100644 server/parser/eurephia_nullsafe.c
>  delete mode 100644 server/parser/eurephia_nullsafe.h
>  delete mode 100644 server/parser/eurephia_values.c
>  delete mode 100644 server/parser/eurephia_values.h
>  delete mode 100644 server/parser/eurephia_values_struct.h
>  delete mode 100644 server/parser/eurephia_xml.c
>  delete mode 100644 server/parser/eurephia_xml.h
>  delete mode 100644 server/parser/log.c
>  delete mode 100644 server/parser/log.h
>  delete mode 100644 server/parser/parsethread.c
>  delete mode 100644 server/parser/parsethread.h
>  delete mode 100644 server/parser/pgsql.c
>  delete mode 100644 server/parser/pgsql.h
>  delete mode 100644 server/parser/rteval-parserd.c
>  delete mode 100755 server/parser/rteval-parserd.init
>  delete mode 100644 server/parser/rteval-parserd.sysconfig
>  delete mode 100644 server/parser/sha1.c
>  delete mode 100644 server/parser/sha1.h
>  delete mode 100644 server/parser/statuses.h
>  delete mode 100644 server/parser/threadinfo.h
>  delete mode 100644 server/parser/xmlparser.c
>  delete mode 100644 server/parser/xmlparser.h
>  delete mode 100644 server/parser/xmlparser.xsl
>  delete mode 100755 server/remove_rtevalrun
>  delete mode 100644 server/rteval-parser.spec
>  delete mode 100644 server/rteval_testserver.py
>  delete mode 100644 server/rteval_xmlrpc.py
>  delete mode 100644 server/rteval_xmlrpc.wsgi
>  delete mode 100644 server/rtevaldb.py
>  delete mode 100644 server/sql/delta-1.0_1.1.sql
>  delete mode 100644 server/sql/delta-1.1_1.2.sql
>  delete mode 100644 server/sql/delta-1.2_1.3.sql
>  delete mode 100644 server/sql/delta-1.3_1.4.sql
>  delete mode 100644 server/sql/delta-1.4_1.5.sql
>  delete mode 100644 server/sql/rteval-1.0.sql
>  delete mode 100644 server/sql/rteval-1.1.sql
>  delete mode 100644 server/sql/rteval-1.2.sql
>  delete mode 100644 server/sql/rteval-1.3.sql
>  delete mode 100644 server/sql/rteval-1.4.sql
>  delete mode 100644 server/sql/rteval-1.5.sql
>  delete mode 100644 server/testclient.py
>  delete mode 100755 server/testclient_sendreportfile
>  delete mode 100644 server/unittest.py
>  delete mode 100644 server/xmlrpc_API1.py
> 
> diff --git a/.gitignore b/.gitignore
> index 4043947..a6e9401 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -27,9 +27,4 @@ MANIFEST
>  .deps
>  stamp-h1
>  autom4te.cache/
> -server/Makefile
> -server/config.log
> -server/config.status
> -server/parser/Makefile
> -server/parser/config.h
>  rteval-[0-9]*
> diff --git a/Makefile b/Makefile
> index b8bed64..d9a6b9f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -9,10 +9,6 @@ PACKAGE :=	rteval
>  VERSION :=      $(shell $(PYTHON) -c "from rteval import RTEVAL_VERSION; print(RTEVAL_VERSION)")
>  D	:=	10
>  
> -# XML-RPC related files
> -XMLRPCVER := 1.6
> -XMLRPCDIR := server
> -
>  DESTDIR	:=
>  PREFIX  :=      /usr
>  DATADIR	:=	$(DESTDIR)/$(PREFIX)/share
> @@ -35,11 +31,9 @@ sysreport:
>  	$(PYTHON) rteval-cmd -D -v --workdir=$(HERE)/run --loaddir=$(HERE)/loadsource --duration=$(D) -i $(HERE)/rteval --sysreport
>  
>  clean:
> -	[ -f $(XMLRPCDIR)/Makefile ] && make -C $(XMLRPCDIR) clean || echo -n
> -	rm -f *~ rteval/*~ rteval/*.py[co] *.tar.bz2 *.tar.gz doc/*~ server/rteval-xmlrpc-*.tar.gz
> +	rm -f *~ rteval/*~ rteval/*.py[co] *.tar.bz2 *.tar.gz doc/*~
>  
>  realclean: clean
> -	[ -f $(XMLRPCDIR)/Makefile ] && make -C $(XMLRPCDIR) maintainer-clean || echo -n
>  	rm -rf run
>  
>  install: install_loads install_rteval
> @@ -67,13 +61,6 @@ rteval-$(VERSION).tar.bz2:
>  	mv dist/rteval-$(VERSION).tar.bz2 .
>  	rmdir dist
>  
> -rteval-xmlrpc-$(XMLRPCVER).tar.gz :
> -	cd $(XMLRPCDIR) ;             \
> -	autoreconf --install ;           \
> -	./configure --prefix=$(PREFIX) ; \
> -	make distcheck
> -	cp $(XMLRPCDIR)/rteval-xmlrpc-$(XMLRPCVER).tar.gz $(HERE)/
> -
>  help:
>  	@echo ""
>  	@echo "rteval Makefile targets:"
> diff --git a/doc/rteval.8 b/doc/rteval.8
> index a8129f1..578de37 100644
> --- a/doc/rteval.8
> +++ b/doc/rteval.8
> @@ -84,12 +84,6 @@ information on the running system.
>  .B \-D, \-\-debug
>  Turn on debugging prints during run
>  .TP
> -.B \-X HOST, \-\-xmprpc-submit=HOST
> -Have rteval send report data to HOST following the run, using XML-RPC
> -.TP
> -.B \-P, \-\-xmlrpc-no-abort
> -Do not abort if XML-RPC server do not respond to ping  request
> -.TP
>  .B \-Z, \-\-summarize
>  Have rteval summarize an existing report. This will not cause loads or
>  meausurement utilities to be run.
> diff --git a/doc/rteval.txt b/doc/rteval.txt
> index 569168e..95d501b 100644
> --- a/doc/rteval.txt
> +++ b/doc/rteval.txt
> @@ -33,8 +33,7 @@ boost the system load.
>  Rteval runs for a specified length of time (typically 12 hours). When
>  an rteval run is completed, a statisical analysis of the results is
>  done, an XML file is generated, containing system state, raw result
> -data and statistical analysis results and optionally the XML is sent
> -by XML-RPC to a database for reporting.
> +data and statistical analysis results.
>  
>  The Load Applications
>  ---------------------
> @@ -228,18 +227,3 @@ A --numa option was added to the cyclictest program to use the libnuma
>  library to bind threads to local memory nodes and allocate memory on
>  the closest memory node, so to minimize the time required to access
>  memory. 
> -
> -Further Development
> --------------------
> -
> -Once we started getting rteval run information it was natural that we
> -would want to store it in a database for further analysis (especially
> -watching for performance regressions). David Sommerseth created a set
> -of tables for a PostgreSQL database and then added an option to rteval
> -to ship the results back to a database server using XML-RPC. This
> -option is currently used internally at Red Hat do ship rteval run data
> -back to our internal DB server. There are no plans to open this data
> -up to the public, but the XML-RPC code is there if someone else wants
> -to use the facility. (No, there are no backdoors in the code that ship
> -run data back to Red Hat; it's Python code, look and see!). 
> -
> diff --git a/rteval-cmd b/rteval-cmd
> index a5e8746..b242aa4 100755
> --- a/rteval-cmd
> +++ b/rteval-cmd
> @@ -122,12 +122,6 @@ def parse_options(cfg, parser, cmdargs):
>      parser.add_argument("-D", '--debug', dest='rteval___debugging',
>                        action='store_true', default=rtevcfg.debugging,
>                        help=f'turn on debug prints (default: {rtevcfg.debugging})')
> -    #parser.add_option("-X", '--xmlrpc-submit', dest='rteval___xmlrpc',
> -    #                  action='store', default=rtevcfg.xmlrpc, metavar='HOST',
> -    #                  help='Hostname to XML-RPC server to submit reports')
> -    #parser.add_option("-P", "--xmlrpc-no-abort", dest="rteval___xmlrpc_noabort",
> -    #                  action='store_true', default=False,
> -    #                  help="Do not abort if XML-RPC server do not respond to ping request");
>      parser.add_argument("-Z", '--summarize', dest='rteval___summarize',
>                        action='store_true', default=False,
>                        help='summarize an already existing XML report')
> diff --git a/rteval/__init__.py b/rteval/__init__.py
> index ca018f6..b5db3b3 100644
> --- a/rteval/__init__.py
> +++ b/rteval/__init__.py
> @@ -22,10 +22,8 @@ import sysconfig
>  from rteval.modules.loads import LoadModules
>  from rteval.modules.measurement import MeasurementModules, MeasurementProfile
>  from rteval.rtevalReport import rtevalReport
> -from rteval.rtevalXMLRPC import rtevalXMLRPC
>  from rteval.Log import Log
>  from rteval import rtevalConfig
> -from rteval import rtevalMailer
>  from rteval import version
>  
>  RTEVAL_VERSION = version.RTEVAL_VERSION
> @@ -70,12 +68,6 @@ class RtEval(rtevalReport):
>          from .sysinfo import SystemInfo
>          self._sysinfo = SystemInfo(self.__rtevcfg, logger=self.__logger)
>  
> -        # prepare a mailer, if that's configured
> -        if self.__cfg.HasSection('smtp'):
> -            self.__mailer = rtevalMailer.rtevalMailer(self.__cfg.GetSection('smtp'))
> -        else:
> -            self.__mailer = None
> -
>          if not os.path.exists(self.__rtevcfg.xslt_report):
>              raise RuntimeError(f"can't find XSL template ({self.__rtevcfg.xslt_report})!")
>  
> @@ -91,19 +83,6 @@ class RtEval(rtevalReport):
>          rtevalReport.__init__(self, self.__version,
>                                self.__rtevcfg.installdir, self.__rtevcfg.annotate)
>  
> -        # If --xmlrpc-submit is given, check that we can access the server
> -        if self.__rtevcfg.xmlrpc:
> -            self.__xmlrpc = rtevalXMLRPC(self.__rtevcfg.xmlrpc, self.__logger, self.__mailer)
> -            if not self.__xmlrpc.Ping():
> -                if not self.__rtevcfg.xmlrpc_noabort:
> -                    print(f"ERROR: Could not reach XML-RPC server '{self.__rtevcfg.xmlrpc}'.  Aborting.")
> -                    sys.exit(2)
> -                else:
> -                    print("WARNING: Could not ping the XML-RPC server.  Will continue anyway.")
> -        else:
> -            self.__xmlrpc = None
> -
> -
>      @staticmethod
>      def __show_remaining_time(remaining):
>          secs = int(remaining)
> @@ -271,10 +250,6 @@ class RtEval(rtevalReport):
>          if self.__rtevcfg.sysreport:
>              self._sysinfo.run_sysreport(self.__reportdir)
>  
> -        # if --xmlrpc-submit | -X was given, send our report to the given host
> -        if self.__xmlrpc:
> -            rtevalres = self.__xmlrpc.SendReport(self.GetXMLreport())
> -
>          if earlystop:
>              rtevalres = 1
>          self._sysinfo.copy_dmesg(self.__reportdir)
> diff --git a/rteval/rtevalConfig.py b/rteval/rtevalConfig.py
> index 030d420..2c0436a 100644
> --- a/rteval/rtevalConfig.py
> +++ b/rteval/rtevalConfig.py
> @@ -73,7 +73,6 @@ default_config = {
>          'workdir'    : os.getcwd(),
>          'installdir' : installdir,
>          'srcdir'     : default_config_search(['loadsource']),
> -        'xmlrpc'     : None,
>          'xslt_report': default_config_search(['rteval_text.xsl'], os.path.isfile),
>          'xslt_histogram': default_config_search(['rteval_histogram_raw.xsl'], os.path.isfile),
>          'report_interval': '600',
> diff --git a/rteval/rtevalMailer.py b/rteval/rtevalMailer.py
> deleted file mode 100644
> index ef3b571..0000000
> --- a/rteval/rtevalMailer.py
> +++ /dev/null
> @@ -1,51 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rtevalmailer.py - module for sending e-mails
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import smtplib
> -import email
> -
> -
> -class rtevalMailer(object):
> -    "rteval mailer - sends messages via an SMTP server to designated e-mail addresses"
> -
> -    def __init__(self, cfg):
> -        # this configuration object needs to have the following attributes set:
> -        # * smtp_server
> -        # * from_address
> -        # * to_address
> -        #
> -        errmsg = ""
> -        if 'smtp_server' not in cfg:
> -            errmsg = "\n** Missing smtp_server in config"
> -        if 'from_address' not in cfg:
> -            errmsg += "\n** Missing from_address in config"
> -        if 'to_address' not in cfg:
> -            errmsg += "\n** Missing to_address in config"
> -
> -        if not errmsg == "":
> -            raise LookupError(errmsg)
> -
> -        self.config = cfg
> -
> -
> -    def __prepare_msg(self, subj, body):
> -        msg = email.MIMEText.MIMEText(body)
> -        msg['subject'] = subj;
> -        msg['From'] = "rteval mailer <" + self.config.from_address+">"
> -        msg['To'] = self.config.to_address
> -        return msg
> -
> -
> -    def SendMessage(self, subject, body):
> -        "Sends an e-mail to the configured mail server and recipient"
> -
> -        msg = self.__prepare_msg(subject, body)
> -        srv = smtplib.SMTP()
> -        srv.connect(self.config.smtp_server)
> -        srv.sendmail(self.config.from_address, self.config.to_address, str(msg))
> -        srv.close()
> -
> diff --git a/rteval/rtevalXMLRPC.py b/rteval/rtevalXMLRPC.py
> deleted file mode 100644
> index 6b31653..0000000
> --- a/rteval/rtevalXMLRPC.py
> +++ /dev/null
> @@ -1,97 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -# rtevalXMLRPC.py - main rteval XML-RPC class
> -#
> -#   Copyright 2009 - 2013   Clark Williams <williams@xxxxxxxxxx>
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import socket
> -import time
> -import xmlrpc.client
> -from .rtevalclient import rtevalclient
> -from .Log import Log
> -
> -class rtevalXMLRPC:
> -    def __init__(self, host, logger, mailer=None):
> -        self.__host = host
> -        self.__url = f"http://{self.__host}/rteval/API1/";
> -        self.__logger = logger
> -        self.__mailer = mailer
> -        self.__client = rtevalclient.rtevalclient(self.__url)
> -
> -
> -    def Ping(self):
> -        res = None
> -        self.__logger.log(Log.DEBUG, f"Checking if XML-RPC server '{self.__host}' is reachable")
> -        attempt = 0
> -        ping_success = False
> -        warning_sent = False
> -        while attempt < 6:
> -            try:
> -                res = self.__client.Hello()
> -                attempt = 10
> -                ping_success = True
> -            except xmlrpc.client.ProtocolError:
> -                # Server do not support Hello(), but is reachable
> -                self.__logger.log(Log.INFO, f"Got XML-RPC connection with {self.__host} but it did not support Hello()")
> -                res = None
> -            except socket.error as err:
> -                self.__logger.log(Log.INFO, f"Could not establish XML-RPC contact with {self.__host}\n{str(err)}")
> -
> -                # Do attempts handling
> -                attempt += 1
> -                if attempt > 5:
> -                    break # To avoid sleeping before we abort
> -
> -                if (self.__mailer is not None) and (not warning_sent):
> -                    self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to ping XML-RPC server", f"Server {self.__host} did not respond.")
> -                    warning_sent = True
> -
> -                print(f"Failed pinging XML-RPC server.  Doing another attempt({attempt}) ")
> -                time.sleep(attempt) #*15) # Incremental sleep - sleep attempts*15 seconds
> -                ping_success = False
> -
> -        if res:
> -            self.__logger.log(Log.INFO, f'Verified XML-RPC connection with {res["server"]} (XML-RPC API version: {res["APIversion"]})')
> -            self.__logger.log(Log.DEBUG, f"Recieved greeting: {res['greeting']}")
> -        return ping_success
> -
> -
> -    def SendReport(self, xmlreport):
> -        "Sends the report to a given XML-RPC host.  Returns 0 on success or 2 on submission failure."
> -
> -        attempt = 0
> -        exitcode = 2   # Presume failure
> -        warning_sent = False
> -        while attempt < 6:
> -            try:
> -                print(f"Submitting report to {self.__url}")
> -                rterid = self.__client.SendReport(xmlreport)
> -                print(f"Report registered with submission id {rterid}")
> -                attempt = 10
> -                exitcode = 0 # Success
> -            except socket.error:
> -                attempt += 1
> -                if attempt > 5:
> -                    break # To avoid sleeping before we abort
> -
> -                if (self.__mailer is not None) and (not warning_sent):
> -                    self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to submit report to XML-RPC server", f"Server {self.__host} did not respond.  Not giving up yet.")
> -                    warning_sent = True
> -
> -                print(f"Failed sending report. Making another attempt({attempt}) ")
> -                time.sleep(attempt) #*5*60) # Incremental sleep - sleep attempts*5 minutes
> -
> -            except Exception as err:
> -                raise err
> -
> -
> -        if self.__mailer is not None:
> -            # Send final result messages
> -            if exitcode == 2:
> -                self.__mailer.SendMessage("[RTEVAL:FAILURE] Failed to submit report to XML-RPC server", f"Server {self.__host} did not respond at all after {attempt - 1} attempts.")
> -            elif (exitcode == 0) and warning_sent:
> -                self.__mailer.SendMessage("[RTEVAL:SUCCESS] XML-RPC server available again",
> -                                          f"Succeeded to submit the report to {self.__host}")
> -
> -        return exitcode
> diff --git a/rteval/rtevalclient.py b/rteval/rtevalclient.py
> deleted file mode 100644
> index 8f48129..0000000
> --- a/rteval/rtevalclient.py
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rtevalclient.py
> -#   XML-RPC client for sending data to a central rteval result server
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import xmlrpc.client
> -import libxml2
> -import io
> -import bz2
> -import base64
> -import platform
> -
> -class rtevalclient:
> -    """
> -    rtevalclient is a library for sending rteval reports to an rteval server via XML-RPC.
> -    """
> -    def __init__(self, url="http://rtserver.farm.hsv.redhat.com/rteval/API1/";, hostn = None):
> -        self.srv = xmlrpc.client.ServerProxy(url)
> -        if hostn is None:
> -            self.hostname = platform.node()
> -        else:
> -            self.hostname = hostn
> -
> -    def Hello(self):
> -        return self.srv.Hello(self.hostname)
> -
> -    def DatabaseStatus(self):
> -        return self.srv.DatabaseStatus()
> -
> -    def SendReport(self, xmldoc):
> -        if xmldoc.type != 'document_xml':
> -            raise Exception("Input is not XML document")
> -
> -        fbuf = io.StringIO()
> -        xmlbuf = libxml2.createOutputBuffer(fbuf, 'UTF-8')
> -        doclen = xmldoc.saveFileTo(xmlbuf, 'UTF-8')
> -
> -        compr = bz2.BZ2Compressor(9)
> -        cmpr = compr.compress(fbuf.getvalue())
> -        data = base64.b64encode(cmpr + compr.flush())
> -        ret = self.srv.SendReport(self.hostname, data)
> -        print(f"rtevalclient::SendReport() - Sent {len(data)} bytes (XML document length: {doclen} bytes, compression ratio: {(1-(float(len(data)) / float(doclen)))*100}:.2f)")
> -        return ret
> -
> -    def SendDataAsFile(self, fname, data, decompr = False):
> -        compr = bz2.BZ2Compressor(9)
> -        cmprdata = compr.compress(data)
> -        b64data = base64.b64encode(cmprdata + compr.flush())
> -        return self.srv.StoreRawFile(self.hostname, fname, b64data, decompr)
> -
> -
> -    def SendFile(self, fname, decompr = False):
> -        f = open(fname, "r")
> -        srvname = self.SendDataAsFile(fname, f.read(), decompr)
> -        f.close()
> -        return srvname
> -
> diff --git a/server/COPYING b/server/COPYING
> deleted file mode 100644
> index d159169..0000000
> --- a/server/COPYING
> +++ /dev/null
> @@ -1,339 +0,0 @@
> -                    GNU GENERAL PUBLIC LICENSE
> -                       Version 2, June 1991
> -
> - Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
> - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> - Everyone is permitted to copy and distribute verbatim copies
> - of this license document, but changing it is not allowed.
> -
> -                            Preamble
> -
> -  The licenses for most software are designed to take away your
> -freedom to share and change it.  By contrast, the GNU General Public
> -License is intended to guarantee your freedom to share and change free
> -software--to make sure the software is free for all its users.  This
> -General Public License applies to most of the Free Software
> -Foundation's software and to any other program whose authors commit to
> -using it.  (Some other Free Software Foundation software is covered by
> -the GNU Lesser General Public License instead.)  You can apply it to
> -your programs, too.
> -
> -  When we speak of free software, we are referring to freedom, not
> -price.  Our General Public Licenses are designed to make sure that you
> -have the freedom to distribute copies of free software (and charge for
> -this service if you wish), that you receive source code or can get it
> -if you want it, that you can change the software or use pieces of it
> -in new free programs; and that you know you can do these things.
> -
> -  To protect your rights, we need to make restrictions that forbid
> -anyone to deny you these rights or to ask you to surrender the rights.
> -These restrictions translate to certain responsibilities for you if you
> -distribute copies of the software, or if you modify it.
> -
> -  For example, if you distribute copies of such a program, whether
> -gratis or for a fee, you must give the recipients all the rights that
> -you have.  You must make sure that they, too, receive or can get the
> -source code.  And you must show them these terms so they know their
> -rights.
> -
> -  We protect your rights with two steps: (1) copyright the software, and
> -(2) offer you this license which gives you legal permission to copy,
> -distribute and/or modify the software.
> -
> -  Also, for each author's protection and ours, we want to make certain
> -that everyone understands that there is no warranty for this free
> -software.  If the software is modified by someone else and passed on, we
> -want its recipients to know that what they have is not the original, so
> -that any problems introduced by others will not reflect on the original
> -authors' reputations.
> -
> -  Finally, any free program is threatened constantly by software
> -patents.  We wish to avoid the danger that redistributors of a free
> -program will individually obtain patent licenses, in effect making the
> -program proprietary.  To prevent this, we have made it clear that any
> -patent must be licensed for everyone's free use or not licensed at all.
> -
> -  The precise terms and conditions for copying, distribution and
> -modification follow.
> -
> -                    GNU GENERAL PUBLIC LICENSE
> -   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
> -
> -  0. This License applies to any program or other work which contains
> -a notice placed by the copyright holder saying it may be distributed
> -under the terms of this General Public License.  The "Program", below,
> -refers to any such program or work, and a "work based on the Program"
> -means either the Program or any derivative work under copyright law:
> -that is to say, a work containing the Program or a portion of it,
> -either verbatim or with modifications and/or translated into another
> -language.  (Hereinafter, translation is included without limitation in
> -the term "modification".)  Each licensee is addressed as "you".
> -
> -Activities other than copying, distribution and modification are not
> -covered by this License; they are outside its scope.  The act of
> -running the Program is not restricted, and the output from the Program
> -is covered only if its contents constitute a work based on the
> -Program (independent of having been made by running the Program).
> -Whether that is true depends on what the Program does.
> -
> -  1. You may copy and distribute verbatim copies of the Program's
> -source code as you receive it, in any medium, provided that you
> -conspicuously and appropriately publish on each copy an appropriate
> -copyright notice and disclaimer of warranty; keep intact all the
> -notices that refer to this License and to the absence of any warranty;
> -and give any other recipients of the Program a copy of this License
> -along with the Program.
> -
> -You may charge a fee for the physical act of transferring a copy, and
> -you may at your option offer warranty protection in exchange for a fee.
> -
> -  2. You may modify your copy or copies of the Program or any portion
> -of it, thus forming a work based on the Program, and copy and
> -distribute such modifications or work under the terms of Section 1
> -above, provided that you also meet all of these conditions:
> -
> -    a) You must cause the modified files to carry prominent notices
> -    stating that you changed the files and the date of any change.
> -
> -    b) You must cause any work that you distribute or publish, that in
> -    whole or in part contains or is derived from the Program or any
> -    part thereof, to be licensed as a whole at no charge to all third
> -    parties under the terms of this License.
> -
> -    c) If the modified program normally reads commands interactively
> -    when run, you must cause it, when started running for such
> -    interactive use in the most ordinary way, to print or display an
> -    announcement including an appropriate copyright notice and a
> -    notice that there is no warranty (or else, saying that you provide
> -    a warranty) and that users may redistribute the program under
> -    these conditions, and telling the user how to view a copy of this
> -    License.  (Exception: if the Program itself is interactive but
> -    does not normally print such an announcement, your work based on
> -    the Program is not required to print an announcement.)
> -
> -These requirements apply to the modified work as a whole.  If
> -identifiable sections of that work are not derived from the Program,
> -and can be reasonably considered independent and separate works in
> -themselves, then this License, and its terms, do not apply to those
> -sections when you distribute them as separate works.  But when you
> -distribute the same sections as part of a whole which is a work based
> -on the Program, the distribution of the whole must be on the terms of
> -this License, whose permissions for other licensees extend to the
> -entire whole, and thus to each and every part regardless of who wrote it.
> -
> -Thus, it is not the intent of this section to claim rights or contest
> -your rights to work written entirely by you; rather, the intent is to
> -exercise the right to control the distribution of derivative or
> -collective works based on the Program.
> -
> -In addition, mere aggregation of another work not based on the Program
> -with the Program (or with a work based on the Program) on a volume of
> -a storage or distribution medium does not bring the other work under
> -the scope of this License.
> -
> -  3. You may copy and distribute the Program (or a work based on it,
> -under Section 2) in object code or executable form under the terms of
> -Sections 1 and 2 above provided that you also do one of the following:
> -
> -    a) Accompany it with the complete corresponding machine-readable
> -    source code, which must be distributed under the terms of Sections
> -    1 and 2 above on a medium customarily used for software interchange; or,
> -
> -    b) Accompany it with a written offer, valid for at least three
> -    years, to give any third party, for a charge no more than your
> -    cost of physically performing source distribution, a complete
> -    machine-readable copy of the corresponding source code, to be
> -    distributed under the terms of Sections 1 and 2 above on a medium
> -    customarily used for software interchange; or,
> -
> -    c) Accompany it with the information you received as to the offer
> -    to distribute corresponding source code.  (This alternative is
> -    allowed only for noncommercial distribution and only if you
> -    received the program in object code or executable form with such
> -    an offer, in accord with Subsection b above.)
> -
> -The source code for a work means the preferred form of the work for
> -making modifications to it.  For an executable work, complete source
> -code means all the source code for all modules it contains, plus any
> -associated interface definition files, plus the scripts used to
> -control compilation and installation of the executable.  However, as a
> -special exception, the source code distributed need not include
> -anything that is normally distributed (in either source or binary
> -form) with the major components (compiler, kernel, and so on) of the
> -operating system on which the executable runs, unless that component
> -itself accompanies the executable.
> -
> -If distribution of executable or object code is made by offering
> -access to copy from a designated place, then offering equivalent
> -access to copy the source code from the same place counts as
> -distribution of the source code, even though third parties are not
> -compelled to copy the source along with the object code.
> -
> -  4. You may not copy, modify, sublicense, or distribute the Program
> -except as expressly provided under this License.  Any attempt
> -otherwise to copy, modify, sublicense or distribute the Program is
> -void, and will automatically terminate your rights under this License.
> -However, parties who have received copies, or rights, from you under
> -this License will not have their licenses terminated so long as such
> -parties remain in full compliance.
> -
> -  5. You are not required to accept this License, since you have not
> -signed it.  However, nothing else grants you permission to modify or
> -distribute the Program or its derivative works.  These actions are
> -prohibited by law if you do not accept this License.  Therefore, by
> -modifying or distributing the Program (or any work based on the
> -Program), you indicate your acceptance of this License to do so, and
> -all its terms and conditions for copying, distributing or modifying
> -the Program or works based on it.
> -
> -  6. Each time you redistribute the Program (or any work based on the
> -Program), the recipient automatically receives a license from the
> -original licensor to copy, distribute or modify the Program subject to
> -these terms and conditions.  You may not impose any further
> -restrictions on the recipients' exercise of the rights granted herein.
> -You are not responsible for enforcing compliance by third parties to
> -this License.
> -
> -  7. If, as a consequence of a court judgment or allegation of patent
> -infringement or for any other reason (not limited to patent issues),
> -conditions are imposed on you (whether by court order, agreement or
> -otherwise) that contradict the conditions of this License, they do not
> -excuse you from the conditions of this License.  If you cannot
> -distribute so as to satisfy simultaneously your obligations under this
> -License and any other pertinent obligations, then as a consequence you
> -may not distribute the Program at all.  For example, if a patent
> -license would not permit royalty-free redistribution of the Program by
> -all those who receive copies directly or indirectly through you, then
> -the only way you could satisfy both it and this License would be to
> -refrain entirely from distribution of the Program.
> -
> -If any portion of this section is held invalid or unenforceable under
> -any particular circumstance, the balance of the section is intended to
> -apply and the section as a whole is intended to apply in other
> -circumstances.
> -
> -It is not the purpose of this section to induce you to infringe any
> -patents or other property right claims or to contest validity of any
> -such claims; this section has the sole purpose of protecting the
> -integrity of the free software distribution system, which is
> -implemented by public license practices.  Many people have made
> -generous contributions to the wide range of software distributed
> -through that system in reliance on consistent application of that
> -system; it is up to the author/donor to decide if he or she is willing
> -to distribute software through any other system and a licensee cannot
> -impose that choice.
> -
> -This section is intended to make thoroughly clear what is believed to
> -be a consequence of the rest of this License.
> -
> -  8. If the distribution and/or use of the Program is restricted in
> -certain countries either by patents or by copyrighted interfaces, the
> -original copyright holder who places the Program under this License
> -may add an explicit geographical distribution limitation excluding
> -those countries, so that distribution is permitted only in or among
> -countries not thus excluded.  In such case, this License incorporates
> -the limitation as if written in the body of this License.
> -
> -  9. The Free Software Foundation may publish revised and/or new versions
> -of the General Public License from time to time.  Such new versions will
> -be similar in spirit to the present version, but may differ in detail to
> -address new problems or concerns.
> -
> -Each version is given a distinguishing version number.  If the Program
> -specifies a version number of this License which applies to it and "any
> -later version", you have the option of following the terms and conditions
> -either of that version or of any later version published by the Free
> -Software Foundation.  If the Program does not specify a version number of
> -this License, you may choose any version ever published by the Free Software
> -Foundation.
> -
> -  10. If you wish to incorporate parts of the Program into other free
> -programs whose distribution conditions are different, write to the author
> -to ask for permission.  For software which is copyrighted by the Free
> -Software Foundation, write to the Free Software Foundation; we sometimes
> -make exceptions for this.  Our decision will be guided by the two goals
> -of preserving the free status of all derivatives of our free software and
> -of promoting the sharing and reuse of software generally.
> -
> -                            NO WARRANTY
> -
> -  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
> -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
> -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
> -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
> -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
> -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
> -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
> -REPAIR OR CORRECTION.
> -
> -  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
> -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
> -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
> -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
> -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
> -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
> -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
> -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
> -POSSIBILITY OF SUCH DAMAGES.
> -
> -                     END OF TERMS AND CONDITIONS
> -
> -            How to Apply These Terms to Your New Programs
> -
> -  If you develop a new program, and you want it to be of the greatest
> -possible use to the public, the best way to achieve this is to make it
> -free software which everyone can redistribute and change under these terms.
> -
> -  To do so, attach the following notices to the program.  It is safest
> -to attach them to the start of each source file to most effectively
> -convey the exclusion of warranty; and each file should have at least
> -the "copyright" line and a pointer to where the full notice is found.
> -
> -    <one line to give the program's name and a brief idea of what it does.>
> -    Copyright (C) <year>  <name of author>
> -
> -    This program is free software; you can redistribute it and/or modify
> -    it under the terms of the GNU General Public License as published by
> -    the Free Software Foundation; either version 2 of the License, or
> -    (at your option) any later version.
> -
> -    This program is distributed in the hope that it will be useful,
> -    but WITHOUT ANY WARRANTY; without even the implied warranty of
> -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -    GNU General Public License for more details.
> -
> -    You should have received a copy of the GNU General Public License along
> -    with this program; if not, write to the Free Software Foundation, Inc.,
> -    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> -
> -Also add information on how to contact you by electronic and paper mail.
> -
> -If the program is interactive, make it output a short notice like this
> -when it starts in an interactive mode:
> -
> -    Gnomovision version 69, Copyright (C) year name of author
> -    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
> -    This is free software, and you are welcome to redistribute it
> -    under certain conditions; type `show c' for details.
> -
> -The hypothetical commands `show w' and `show c' should show the appropriate
> -parts of the General Public License.  Of course, the commands you use may
> -be called something other than `show w' and `show c'; they could even be
> -mouse-clicks or menu items--whatever suits your program.
> -
> -You should also get your employer (if you work as a programmer) or your
> -school, if any, to sign a "copyright disclaimer" for the program, if
> -necessary.  Here is a sample; alter the names:
> -
> -  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
> -  `Gnomovision' (which makes passes at compilers) written by James Hacker.
> -
> -  <signature of Ty Coon>, 1 April 1989
> -  Ty Coon, President of Vice
> -
> -This General Public License does not permit incorporating your program into
> -proprietary programs.  If your program is a subroutine library, you may
> -consider it more useful to permit linking proprietary applications with the
> -library.  If this is what you want to do, use the GNU Lesser General
> -Public License instead of this License.
> diff --git a/server/INSTALL b/server/INSTALL
> deleted file mode 100644
> index 2550dab..0000000
> --- a/server/INSTALL
> +++ /dev/null
> @@ -1,302 +0,0 @@
> -Installation Instructions
> -*************************
> -
> -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
> -2006, 2007, 2008, 2009 Free Software Foundation, Inc.
> -
> -   This file is free documentation; the Free Software Foundation gives
> -unlimited permission to copy, distribute and modify it.
> -
> -Basic Installation
> -==================
> -
> -   Briefly, the shell commands `./configure; make; make install' should
> -configure, build, and install this package.  The following
> -more-detailed instructions are generic; see the `README' file for
> -instructions specific to this package.
> -
> -   The `configure' shell script attempts to guess correct values for
> -various system-dependent variables used during compilation.  It uses
> -those values to create a `Makefile' in each directory of the package.
> -It may also create one or more `.h' files containing system-dependent
> -definitions.  Finally, it creates a shell script `config.status' that
> -you can run in the future to recreate the current configuration, and a
> -file `config.log' containing compiler output (useful mainly for
> -debugging `configure').
> -
> -   It can also use an optional file (typically called `config.cache'
> -and enabled with `--cache-file=config.cache' or simply `-C') that saves
> -the results of its tests to speed up reconfiguring.  Caching is
> -disabled by default to prevent problems with accidental use of stale
> -cache files.
> -
> -   If you need to do unusual things to compile the package, please try
> -to figure out how `configure' could check whether to do them, and mail
> -diffs or instructions to the address given in the `README' so they can
> -be considered for the next release.  If you are using the cache, and at
> -some point `config.cache' contains results you don't want to keep, you
> -may remove or edit it.
> -
> -   The file `configure.ac' (or `configure.in') is used to create
> -`configure' by a program called `autoconf'.  You need `configure.ac' if
> -you want to change it or regenerate `configure' using a newer version
> -of `autoconf'.
> -
> -The simplest way to compile this package is:
> -
> -  1. `cd' to the directory containing the package's source code and type
> -     `./configure' to configure the package for your system.
> -
> -     Running `configure' might take a while.  While running, it prints
> -     some messages telling which features it is checking for.
> -
> -  2. Type `make' to compile the package.
> -
> -  3. Optionally, type `make check' to run any self-tests that come with
> -     the package.
> -
> -  4. Type `make install' to install the programs and any data files and
> -     documentation.
> -
> -  5. You can remove the program binaries and object files from the
> -     source code directory by typing `make clean'.  To also remove the
> -     files that `configure' created (so you can compile the package for
> -     a different kind of computer), type `make distclean'.  There is
> -     also a `make maintainer-clean' target, but that is intended mainly
> -     for the package's developers.  If you use it, you may have to get
> -     all sorts of other programs in order to regenerate files that came
> -     with the distribution.
> -
> -  6. Often, you can also type `make uninstall' to remove the installed
> -     files again.
> -
> -Compilers and Options
> -=====================
> -
> -   Some systems require unusual options for compilation or linking that
> -the `configure' script does not know about.  Run `./configure --help'
> -for details on some of the pertinent environment variables.
> -
> -   You can give `configure' initial values for configuration parameters
> -by setting variables in the command line or in the environment.  Here
> -is an example:
> -
> -     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
> -
> -   *Note Defining Variables::, for more details.
> -
> -Compiling For Multiple Architectures
> -====================================
> -
> -   You can compile the package for more than one kind of computer at the
> -same time, by placing the object files for each architecture in their
> -own directory.  To do this, you can use GNU `make'.  `cd' to the
> -directory where you want the object files and executables to go and run
> -the `configure' script.  `configure' automatically checks for the
> -source code in the directory that `configure' is in and in `..'.
> -
> -   With a non-GNU `make', it is safer to compile the package for one
> -architecture at a time in the source code directory.  After you have
> -installed the package for one architecture, use `make distclean' before
> -reconfiguring for another architecture.
> -
> -   On MacOS X 10.5 and later systems, you can create libraries and
> -executables that work on multiple system types--known as "fat" or
> -"universal" binaries--by specifying multiple `-arch' options to the
> -compiler but only a single `-arch' option to the preprocessor.  Like
> -this:
> -
> -     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
> -                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
> -                 CPP="gcc -E" CXXCPP="g++ -E"
> -
> -   This is not guaranteed to produce working output in all cases, you
> -may have to build one architecture at a time and combine the results
> -using the `lipo' tool if you have problems.
> -
> -Installation Names
> -==================
> -
> -   By default, `make install' installs the package's commands under
> -`/usr/local/bin', include files under `/usr/local/include', etc.  You
> -can specify an installation prefix other than `/usr/local' by giving
> -`configure' the option `--prefix=PREFIX'.
> -
> -   You can specify separate installation prefixes for
> -architecture-specific files and architecture-independent files.  If you
> -pass the option `--exec-prefix=PREFIX' to `configure', the package uses
> -PREFIX as the prefix for installing programs and libraries.
> -Documentation and other data files still use the regular prefix.
> -
> -   In addition, if you use an unusual directory layout you can give
> -options like `--bindir=DIR' to specify different values for particular
> -kinds of files.  Run `configure --help' for a list of the directories
> -you can set and what kinds of files go in them.
> -
> -   If the package supports it, you can cause programs to be installed
> -with an extra prefix or suffix on their names by giving `configure' the
> -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
> -
> -Optional Features
> -=================
> -
> -   Some packages pay attention to `--enable-FEATURE' options to
> -`configure', where FEATURE indicates an optional part of the package.
> -They may also pay attention to `--with-PACKAGE' options, where PACKAGE
> -is something like `gnu-as' or `x' (for the X Window System).  The
> -`README' should mention any `--enable-' and `--with-' options that the
> -package recognizes.
> -
> -   For packages that use the X Window System, `configure' can usually
> -find the X include and library files automatically, but if it doesn't,
> -you can use the `configure' options `--x-includes=DIR' and
> -`--x-libraries=DIR' to specify their locations.
> -
> -Particular systems
> -==================
> -
> -   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
> -CC is not installed, it is recommended to use the following options in
> -order to use an ANSI C compiler:
> -
> -     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
> -
> -and if that doesn't work, install pre-built binaries of GCC for HP-UX.
> -
> -   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
> -parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
> -a workaround.  If GNU CC is not installed, it is therefore recommended
> -to try
> -
> -     ./configure CC="cc"
> -
> -and if that doesn't work, try
> -
> -     ./configure CC="cc -nodtk"
> -
> -   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
> -directory contains several dysfunctional programs; working variants of
> -these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
> -in your `PATH', put it _after_ `/usr/bin'.
> -
> -   On Haiku, software installed for all users goes in `/boot/common',
> -not `/usr/local'.  It is recommended to use the following options:
> -
> -     ./configure --prefix=/boot/common
> -
> -Specifying the System Type
> -==========================
> -
> -   There may be some features `configure' cannot figure out
> -automatically, but needs to determine by the type of machine the package
> -will run on.  Usually, assuming the package is built to be run on the
> -_same_ architectures, `configure' can figure that out, but if it prints
> -a message saying it cannot guess the machine type, give it the
> -`--build=TYPE' option.  TYPE can either be a short name for the system
> -type, such as `sun4', or a canonical name which has the form:
> -
> -     CPU-COMPANY-SYSTEM
> -
> -where SYSTEM can have one of these forms:
> -
> -     OS
> -     KERNEL-OS
> -
> -   See the file `config.sub' for the possible values of each field.  If
> -`config.sub' isn't included in this package, then this package doesn't
> -need to know the machine type.
> -
> -   If you are _building_ compiler tools for cross-compiling, you should
> -use the option `--target=TYPE' to select the type of system they will
> -produce code for.
> -
> -   If you want to _use_ a cross compiler, that generates code for a
> -platform different from the build platform, you should specify the
> -"host" platform (i.e., that on which the generated programs will
> -eventually be run) with `--host=TYPE'.
> -
> -Sharing Defaults
> -================
> -
> -   If you want to set default values for `configure' scripts to share,
> -you can create a site shell script called `config.site' that gives
> -default values for variables like `CC', `cache_file', and `prefix'.
> -`configure' looks for `PREFIX/share/config.site' if it exists, then
> -`PREFIX/etc/config.site' if it exists.  Or, you can set the
> -`CONFIG_SITE' environment variable to the location of the site script.
> -A warning: not all `configure' scripts look for a site script.
> -
> -Defining Variables
> -==================
> -
> -   Variables not defined in a site shell script can be set in the
> -environment passed to `configure'.  However, some packages may run
> -configure again during the build, and the customized values of these
> -variables may be lost.  In order to avoid this problem, you should set
> -them in the `configure' command line, using `VAR=value'.  For example:
> -
> -     ./configure CC=/usr/local2/bin/gcc
> -
> -causes the specified `gcc' to be used as the C compiler (unless it is
> -overridden in the site shell script).
> -
> -Unfortunately, this technique does not work for `CONFIG_SHELL' due to
> -an Autoconf bug.  Until the bug is fixed you can use this workaround:
> -
> -     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
> -
> -`configure' Invocation
> -======================
> -
> -   `configure' recognizes the following options to control how it
> -operates.
> -
> -`--help'
> -`-h'
> -     Print a summary of all of the options to `configure', and exit.
> -
> -`--help=short'
> -`--help=recursive'
> -     Print a summary of the options unique to this package's
> -     `configure', and exit.  The `short' variant lists options used
> -     only in the top level, while the `recursive' variant lists options
> -     also present in any nested packages.
> -
> -`--version'
> -`-V'
> -     Print the version of Autoconf used to generate the `configure'
> -     script, and exit.
> -
> -`--cache-file=FILE'
> -     Enable the cache: use and save the results of the tests in FILE,
> -     traditionally `config.cache'.  FILE defaults to `/dev/null' to
> -     disable caching.
> -
> -`--config-cache'
> -`-C'
> -     Alias for `--cache-file=config.cache'.
> -
> -`--quiet'
> -`--silent'
> -`-q'
> -     Do not print messages saying which checks are being made.  To
> -     suppress all normal output, redirect it to `/dev/null' (any error
> -     messages will still be shown).
> -
> -`--srcdir=DIR'
> -     Look for the package's source code in directory DIR.  Usually
> -     `configure' can determine that directory automatically.
> -
> -`--prefix=DIR'
> -     Use DIR as the installation prefix.  *Note Installation Names::
> -     for more details, including other options available for fine-tuning
> -     the installation locations.
> -
> -`--no-create'
> -`-n'
> -     Run the configure checks, but stop before creating any output
> -     files.
> -
> -`configure' also accepts some other, not widely useful, options.  Run
> -`configure --help' for more details.
> -
> diff --git a/server/Logger.py b/server/Logger.py
> deleted file mode 100644
> index e10ad25..0000000
> --- a/server/Logger.py
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -import sys
> -from datetime import datetime
> -
> -class Logger():
> -    def __init__(self, logfile, prefix):
> -        self.log = sys.stdout
> -        self.logopen = True
> -        self.prefix = prefix
> -
> -    def Log(self, grp, msg):
> -        if self.logopen == True:
> -            tstmp = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
> -            self.log.write("%s [%s::%s]: %s\n" % (tstmp, self.prefix, grp, msg))
> -            self.log.flush()
> -
> -    def LogFD(self):
> -        return self.log.fileno()
> -
> diff --git a/server/Makefile.am b/server/Makefile.am
> deleted file mode 100644
> index fa53684..0000000
> --- a/server/Makefile.am
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#   Makefile.am - autotools configuration file
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -SUBDIRS = parser
> -dist_doc_DATA = parser/README.parser 	\
> -	sql/delta-1.0_1.1.sql 		\
> -	sql/delta-1.1_1.2.sql 		\
> -	sql/delta-1.2_1.3.sql 		\
> -	sql/delta-1.3_1.4.sql 		\
> -	sql/rteval-$(SQLSCHEMAVER).sql
> -
> -apache-rteval.conf:
> -if ENAB_MODPYTHON
> -	[ -n $(XMLRPCROOT) ] && $(srcdir)/gen_config.sh apache-rteval.conf $(XMLRPCROOT)/API1
> -else
> -	[ -n $(XMLRPCROOT) ] && $(srcdir)/gen_config.sh apache-rteval-wsgi.conf $(XMLRPCROOT)/API1
> -endif
> -
> -clean-local:
> -	-rm -f apache-rteval.conf *~
> -
> -dist-hook:
> -	cp $(srcdir)/gen_config.sh $(srcdir)/apache-rteval.conf.tpl $(srcdir)/apache-rteval-wsgi.conf.tpl $(distdir)/
> -	-rm -f $(distdir)/apache-rteval.conf
> -
> -if ENAB_XMLRPC
> -    xmlrpcdir = $(XMLRPCROOT)/API1
> -    BUILT_SOURCES = apache-rteval.conf
> -    dist_doc_DATA += README.xmlrpc apache-rteval.conf
> -    dist_xmlrpc_DATA = xmlrpc_API1.py rtevaldb.py database.py
> -if ENAB_MODPYTHON
> -    dist_xmlrpc_DATA += rteval_xmlrpc.py
> -else
> -    dist_xmlrpc_DATA += rteval_xmlrpc.wsgi
> -endif
> -endif
> diff --git a/server/README.xmlrpc b/server/README.xmlrpc
> deleted file mode 100644
> index 20bade2..0000000
> --- a/server/README.xmlrpc
> +++ /dev/null
> @@ -1,201 +0,0 @@
> -**
> -** Setting up a rteval XML-RPC server
> -**
> -
> -The XML-RPC server has the purpose of collecting information from
> -several rteval clients.  All the data in the summary.xml produced by the
> -rteval script is sent over to the XML-RPC server and registered in a
> -submission queue.  The XML-RPC server will then send back a submission
> -ID to the client.
> -
> -A parser daemon needs to run as well.  This daemon is connected to the
> -same database as the XML-RPC service and it will wait for new reports in
> -the submission queue to be parsed.  Look into the README.parser file
> -for more information on setting up the rteval_parserd process.
> -
> -Each parsed report will get a unique system ID which then can be used to
> -track how each system changes behaviour on different kernels.
> -
> -
> -**
> -** Requirements
> -**
> -   - Apache web server
> -   - mod_python-3.3.x OR mod_wsgi-3.2 or newer.
> -   - PostgreSQL v8.3 or later
> -   - rteval 1.12 or later
> -
> -
> -**
> -** Apache preparations
> -**
> -
> -The default path used for the rteval client is
> -
> -    http://{server hostname}/rteval/API1/
> -
> -If you have a HTTP setup which will follow this scheme, you do not
> -need to change any URLs at all.
> -
> -When installing the rteval-xmlrpc-1.4 RPM on a Fedora/RHEL based box,
> -Apache will be automatically configured.  But the Apache web server
> -will need to be restarted when you have setup the database.
> -
> -     # server httpd restart
> -
> -For manual installations, see the instructions under "Building and
> -installing from source" further down in this file.
> -
> -
> -**
> -** Database preparations
> -**
> -
> -** Setting up a new database
> -All reports are saved in a database.  If you have not used the
> -rteval-xmlrpc interface before, you need to create the needed database
> -user and database, execute the following command line:
> -
> -   # psql < /usr/share/doc/rteval-xmlrpc-1.5/rteval-1.4.sql
> -
> -This script will first create a database user called 'rtevxmlrpc' and
> -'rtevparser', assign default password before creating the database called
> -'rteval'.  The database will be populated with the needed tables and the
> -'rtevxmlrpc' and 'rtevparser' users will get the needed privileges to do
> -their job.
> -
> -Remember to also update the pg_hba.conf file in the PostgreSQL data
> -directory.  You need to allow the xmlrpc user access from the web
> -server.
> -
> -pg_hba.conf entry example:
> ------------------------------------------------------------------
> -# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
> -hostssl rteval	    rtevxmlrpc	127.0.0.1/32	      md5
> -hostssl rteval	    rtevparser	127.0.0.1/32	      md5
> ------------------------------------------------------------------
> -
> -The XML-RPC database connector will always try to connect via SSL.  To
> -modify the default password, connect to the database with psql and
> -issue this SQL command:
> -
> -   rteval=# ALTER USER rtevxmlrpc WITH ENCRYPTED PASSWORD '<newpassword>';
> -   rteval=# ALTER USER rtevparser WITH ENCRYPTED PASSWORD '<newpassword>';
> -
> -Or you can use the "safe mode" via the psql command:
> -
> -   rteval=# \password rtevxmlrpc
> -   Enter new password:
> -   Enter it again:
> -   rteval=# \password rtevparser
> -   Enter new password:
> -   Enter it again:
> -
> -
> -** Update an already existing database
> -If you already have an rteval database setup, you can run the delta
> -scripts to only do the pure database schema changes.
> -
> -To find out which schema version you using, do the following:
> -
> -   psql rteval -c "SELECT value FROM rteval_info WHERE key='sql_schema_ver'"
> -   value
> -   -------
> -     1.1
> -   (1 row)
> -
> -This indicates that the database is at the schema version 1.1.  If you do not
> -have the rteval_info table, you are for sure on schema version 1.0.
> -
> -* Update from SQL schema version 1.0 to 1.1
> -   psql rteval < /usr/share/doc/rteval-xmlrpc-1.1/delta-1.0_1.1.sql
> -
> -* Update from SQL schema version 1.1 to 1.2
> -   psql rteval < /usr/share/doc/rteval-xmlrpc-1.1/delta-1.1_1.2.sql
> -
> -* Update from SQL schema version 1.2 to 1.3
> -   psql rteval < /usr/share/doc/rteval-xmlrpc-1.1/delta-1.2_1.3.sql
> -
> -* Update from SQL schema version 1.3 to 1.4
> -   psql rteval < /usr/share/doc/rteval-xmlrpc-1.1/delta-1.3_1.4.sql
> -
> -You need to upgrade to the latest SQL schema available, and you must upgrade
> -sequentially through all the version in between your version and the latest.
> -
> -
> -**
> -** Building an installing from source
> -**
> -
> -The rteval-xmlrpc uses autotools to configure and build the
> -rteval-xmlrpc server and parser.
> -
> -   ./configure [--with-xmlrpc-webroot=<full path>]
> -
> -If the --with-xmlrpc-webroot is not provided, the mod_python files
> -needed for the XML-RPC server will not be installed, and only the
> -report parser will be built and installed.
> -
> -The path to the --with-xmlrpc-webroot must be a directory which the
> -Apache web server can access and serve files from (htdocs dir).  On
> -Fedora/RHEL this path should be:
> -
> -     ./configure --with-xmlrpc-webroot=/var/www/html/rteval
> -
> -With this done, you can now do the traditional 'make' and 'make
> -install'.  The default install prefix is /usr/local, unless you
> -changed it with --prefix=<path>.  You will then find the
> -rteval_parserd installed under /usr/local/bin/rteval_parserd and
> -README files, the SQL scripts and an Apache config file will be found
> -under /usr/local/share/doc/rteval-parser-1.5/
> -
> -The Apache configuration file can be copied into the configuration
> -directory Apache uses for its modules.  On RHEL/Fedora based
> -distributions, the apache-rteval.conf can be copied into
> -/etc/httpd/conf.d/
> -
> -For more information about the report parser (rteval-parserd), please
> -have a look at the README.parser file.
> -
> -
> -**
> -**  Configuration
> -**
> -
> -If you are not using any of the default values for
> -the database configuration, you need to create or modify the
> -/etc/rteval.conf file.  The XML-RPC service will read the
> -[xmlrpc_server] section in this file.
> -
> -This is the default values, if the xmlrpc_server section is not found
> -or parameters is not set.
> -
> -     # Paths
> -     datadir:     /var/lib/rteval
> -
> -     # Database parameters
> -     db_server:   localhost
> -     db_port:     5432
> -     database:    rteval
> -     db_username: xmlrpc
> -     db_password: rtevaldb
> -
> -The directory the datadir parameter points at must be writable to the
> -apache process.  Here copies of the received summary.xml files will be
> -saved before the rteval-parserd process parses the reports.
> -
> -
> -**
> -** Testing the setup
> -**
> -
> -For a quick test, dig up a summary.xml file from an earlier rteval run and
> -try sending it to the XML-RPC server by using the testclient_sendreportfile
> -script:
> -
> -     ./testclient_sendreportfile --report=summary.xml \
> -                                 --xmlrpc-submit=localhost
> -
> -See --help for more info on this utility.  Usually the log files of Apache and
> -PostgreSQL provides pretty good information if something goes wrong.
> -
> diff --git a/server/apache-rteval-wsgi.conf.tpl b/server/apache-rteval-wsgi.conf.tpl
> deleted file mode 100644
> index c6cf00f..0000000
> --- a/server/apache-rteval-wsgi.conf.tpl
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -# File: apache-rteval.conf
> -#
> -# Apache config entry to enable the rteval XML-RPC server
> -#
> -#   Copyright 2011 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -WSGISocketPrefix /var/run/wsgi
> -WSGIDaemonProcess rtevalxmlrpc processes=3 threads=15 python-path={_INSTALLDIR_}
> -WSGIScriptAlias /rteval/API1 {_INSTALLDIR_}/rteval_xmlrpc.wsgi
> -
> -<Directory "{_INSTALLDIR_}">
> -    Options Indexes FollowSymLinks
> -    AllowOverride None
> -    Order allow,deny
> -    Allow from all
> -
> -    WSGIProcessGroup rtevalxmlrpc
> -    WSGICallableObject rtevalXMLRPC_handler
> -</Directory>
> -
> diff --git a/server/apache-rteval.conf.tpl b/server/apache-rteval.conf.tpl
> deleted file mode 100644
> index f52754c..0000000
> --- a/server/apache-rteval.conf.tpl
> +++ /dev/null
> @@ -1,18 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -# File: apache-rteval.conf
> -#
> -# Apache config entry to enable the rteval XML-RPC server
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -<Directory "{_INSTALLDIR_}">
> -    Options Indexes FollowSymLinks
> -    AllowOverride None
> -    Order allow,deny
> -    Allow from all
> -
> -    SetHandler python-program
> -    PythonHandler rteval_xmlrpc
> -    PythonDebug On
> -</Directory>
> -
> diff --git a/server/configure.ac b/server/configure.ac
> deleted file mode 100644
> index 504efbf..0000000
> --- a/server/configure.ac
> +++ /dev/null
> @@ -1,130 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#   configure.ac - autotools configuration file
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -#
> -#
> -#   To create the ./configure script you need to run 'autoreconf --install'
> -#
> -
> -AC_INIT([rteval-xmlrpc], [1.6], [davids@xxxxxxxxxx])
> -SQLSCHEMAVER=1.5
> -AC_SUBST(SQLSCHEMAVER)
> -
> -AM_INIT_AUTOMAKE([-Wall -Werror foreign])
> -AC_PROG_CC
> -
> -AC_ARG_WITH([xmlrpc-webroot],
> -	[AS_HELP_STRING([--with-xmlrpc-webroot],
> -			[Location where to install the XML-RPC mod_python files])],
> -	[XMLRPCROOT="$withval"]
> -)
> -AC_SUBST(XMLRPCROOT)
> -AM_CONDITIONAL([ENAB_XMLRPC], [test ! -z $XMLRPCROOT])
> -
> -AC_ARG_ENABLE([mod-python],
> -        [AS_HELP_STRING([--with-mod-python],
> -                        [Enable the older mod_python support instead of mod_wsgi])],
> -        [MODPYTHON="$enableval"]
> -)
> -AC_SUBST(MODPYTHON)
> -AM_CONDITIONAL([ENAB_MODPYTHON], [test ! -z $MODPYTHON])
> -
> -# Simple macro to abort on missing functions in libraries
> -AC_DEFUN([AX_msgMISSINGFUNC], AC_MSG_ERROR([Could not find function in library.  Aborting]))
> -
> -# Save original CPPFLAGS
> -save_CPPFLAGS="$CPPFLAGS"
> -
> -# Check for libxml2
> -AC_CHECK_PROGS([XML2CFG], [xml2-config], [:])
> -if test "$XML2CFG" = :; then
> -   AC_MSG_ERROR([This package needs xml2-config from libxml2])
> -else
> -   AC_SUBST([LIBXML2_INC], [$(xml2-config --cflags)])
> -   CPPFLAGS="$CPPFLAGS $LIBXML2_INC"
> -fi
> -AC_CHECK_HEADERS([libxml/tree.h])
> -AC_CHECK_HEADERS([libxml/xmlsave.h])
> -AC_CHECK_HEADERS([libxml/xmlstring.h])
> -AC_CHECK_HEADERS([libxml/parser.h])
> -AC_CHECK_LIB([xml2],[xmlInitParser], [], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlCleanupParser], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlStrcmp], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlFreeDoc], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlSaveToBuffer], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlSaveTree], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlSaveClose], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlBufferFree], [DUMMY=], AX_msgMISSINGFUNC)
> -AC_CHECK_LIB([xml2],[xmlParseFile], [DUMMY=], AX_msgMISSINGFUNC)
> -
> -# Check for libxslt
> -AC_CHECK_PROGS([XSLTCFG], [xslt-config], [:])
> -if test "$XSLTCFG" = :; then
> -   AC_MSG_ERROR([This package needs xslt-config from libxslt])
> -else
> -   AC_SUBST([LIBXSLT_INC], [$(xslt-config --cflags)])
> -   CPPFLAGS="$CPPFLAGS $LIBXSLT_INC"
> -   LDFLAGS="$LDFLAGS -lexslt"
> -fi
> -AC_CHECK_HEADERS([libxslt/xsltInternals.h])
> -AC_CHECK_HEADERS([libxslt/transform.h])
> -AC_CHECK_HEADERS([libxslt/xsltutils.h])
> -AC_CHECK_LIB([xslt], [xsltInit], [], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([xslt], [xsltCleanupGlobals], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([xslt], [xsltParseStylesheetFile], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([xslt], [xsltApplyStylesheet], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([xslt], [xsltFreeStylesheet], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([exslt], [exsltRegisterAll], [DUMMY=], AX_msgMISSINGFUNC())
> -
> -# Check for libpq
> -AC_CHECK_PROGS([PGSQLCFG], [pg_config], [:])
> -if test "$PGSQLCFG" = :; then
> -   AC_MSG_ERROR([This package needs pg_config from PostgreSQL])
> -else
> -   AC_SUBST([LIBPQ_INC], [-I$(pg_config --includedir)])
> -   CPPFLAGS="$CPPFLAGS $LIBPQ_INC"
> -fi
> -AC_CHECK_HEADERS([libpq-fe.h])
> -AC_CHECK_LIB([pq], [PQsetdbLogin], [], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQstatus], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQexec], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQreset], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQfinish], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQprepare], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQexecPrepared], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQresultStatus], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQclear], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQconsumeInput], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQnotifies], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pq], [PQntuples], [DUMMY=], AX_msgMISSINGFUNC())
> -
> -# Restore the original CPPFLAGS
> -CPPFLAGS="$save_CPPFLAGS"
> -
> -# Check for POSIX features
> -AC_CHECK_HEADERS([mq.h])
> -AC_CHECK_LIB([rt], [mq_open], [], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([rt], [mq_close], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([rt], [mq_unlink], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([rt], [mq_send], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([rt], [mq_receive], [DUMMY=], AX_msgMISSINGFUNC())
> -
> -AC_CHECK_HEADERS([pthread.h])
> -AC_CHECK_LIB([pthread], [pthread_attr_init], [], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_attr_setdetachstate], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_attr_destroy], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_create], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_join], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_mutex_lock], [DUMMY=], AX_msgMISSINGFUNC())
> -AC_CHECK_LIB([pthread], [pthread_mutex_unlock], [DUMMY=], AX_msgMISSINGFUNC())
> -
> -# Back to needed autotools stuff
> -AC_CONFIG_SRCDIR([parser/rteval-parserd.c])
> -AC_CONFIG_HEADERS([parser/config.h])
> -AC_CONFIG_FILES([Makefile parser/Makefile])
> -AC_SUBST([AM_CXXFLAGS], [$CFLAGS])
> -AC_SUBST([AM_LDFLAGS], [$LDFLAGS])
> -
> -AC_OUTPUT
> diff --git a/server/database.py b/server/database.py
> deleted file mode 100644
> index 684f5ab..0000000
> --- a/server/database.py
> +++ /dev/null
> @@ -1,238 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   database.py
> -#   Library for processing results from XMLSQLparser and
> -#   query a PostgreSQL database based on the input data
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import psycopg2
> -import types
> -
> -class Database(object):
> -    def __init__(self, host=None, port=None, user=None, password=None, database=None,
> -                 noaction=False, debug=False):
> -        self.noaction = noaction
> -        self.debug = debug
> -
> -        dsnd = {}
> -        if host is not None:
> -            dsnd['host'] = host
> -            dsnd['sslmode'] = 'require'
> -        if port is not None:
> -            dsnd['port'] = str(port)
> -            dsnd['sslmode'] = 'require'
> -        if user is not None:
> -            dsnd['user'] = user
> -        if password is not None:
> -            dsnd['password'] = password
> -        if database is not None:
> -            dsnd['dbname'] = database
> -
> -        dsn = " ".join(["%s='%s'" %(k,v) for (k,v) in list(dsnd.items())])
> -        self.conn = not self.noaction and psycopg2.connect(dsn) or None
> -
> -
> -    def INSERT(self, sqlvars):
> -        #
> -        # Validate input data
> -        #
> -        if type(sqlvars) is not dict:
> -            raise AttributeError('Input parameter is not a Python dict')
> -
> -        try:
> -            sqlvars['table']
> -            sqlvars['fields']
> -            sqlvars['records']
> -        except KeyError as err:
> -            raise KeyError("Input dictionary do not contain a required element: %s").with_traceback(str(err))
> -
> -        if type(sqlvars['fields']) is not list:
> -            raise AttributeError("The 'fields' element is not a list of fields")
> -
> -        if type(sqlvars['records']) is not list:
> -            raise AttributeError("The 'records' element is not a list of fields")
> -
> -        if len(sqlvars['records']) == 0:
> -            return True
> -
> -        try:
> -            sqlvars['returning']
> -        except:
> -            sqlvars['returning'] = None
> -
> -        #
> -        # Build SQL template
> -        #
> -        sqlstub = "INSERT INTO %s (%s) VALUES (%s)" % (
> -            sqlvars['table'],
> -            ",".join(sqlvars['fields']),
> -            ",".join(["%%(%s)s" % f for f in sqlvars['fields']])
> -            )
> -
> -        # Get a database cursor
> -        curs = not self.noaction and self.conn.cursor() or None
> -
> -        #
> -        # Loop through all records and insert them into the database
> -        #
> -        results = []
> -        for rec in sqlvars['records']:
> -            if type(rec) is not list:
> -                raise AttributeError("The field values inside the 'records' list must be in a list")
> -
> -            # Create a dictionary, which will be used for the SQL operation
> -            values = {}
> -            for i in range(0, len(sqlvars['fields'])):
> -                values[sqlvars['fields'][i]] = rec[i]
> -
> -            if self.debug:
> -                print("SQL QUERY: ==> %s" % (sqlstub % values))
> -
> -            # Do the INSERT query
> -            if not self.noaction:
> -                curs.execute(sqlstub, values)
> -
> -            # If a return value for the INSERT is defined, catch that one
> -            if not self.noaction and sqlvars['returning']:
> -                # The psycopg2 do not handle INSERT INTO ... RETURNING column queries, so we can only use
> -                # this on tables with oid and do the look up that way
> -                vls = {"table": sqlvars['table'], 'colname': sqlvars['returning'], 'oid': str(curs.lastrowid)}
> -                curs.execute("SELECT %(colname)s FROM %(table)s WHERE oid='%(oid)s'" % vls)
> -                results.append(curs.fetchone()[0])
> -            else:
> -                results.append(True)
> -
> -        if not self.noaction:
> -            curs.close()
> -        return results
> -
> -
> -    def DELETE(self, table, where):
> -        try:
> -            sql = "DELETE FROM %s WHERE %s" % (
> -                table,
> -                " AND ".join(["%s = %%(%s)s" % (k,k) for (k,v) in list(where.items())])
> -                )
> -
> -            if self.debug:
> -                print("SQL QUERY ==> %s" % (sql % where))
> -
> -            if not self.noaction:
> -                curs = self.conn.cursor()
> -                curs.execute(sql, where)
> -                delrows = curs.rowcount
> -                curs.close()
> -                return delrows
> -            else:
> -                return 0
> -        except Exception as err:
> -            raise Exception("** SQL ERROR ** %s\n** SQL ERROR ** Message: %s" % ((sql % where), str(err)))
> -
> -    def SELECT(self, table, fields, joins=None, where=None):
> -        curs = not self.noaction and self.conn.cursor() or None
> -
> -        # Query
> -        try:
> -            sql = "SELECT %s FROM %s %s %s" % (
> -                ",".join(fields),
> -                table,
> -                joins and "%s" % joins or "",
> -                where and "WHERE %s" % " AND ".join(["%s = %%(%s)s" % (k,k) for (k,v) in list(where.items())] or "")
> -                )
> -            if self.debug:
> -                print("SQL QUERY: ==> %s" % (sql % where))
> -            if not self.noaction:
> -                curs.execute(sql, where)
> -            else:
> -                # If no action is setup (mainly for debugging), return empty result set
> -                return {"table": table, "fields": [], "records": []}
> -        except Exception as err:
> -            raise Exception("** SQL ERROR *** %s\n** SQL ERROR ** Message: %s" % (where and (sql % where) or sql, str(err)))
> -
> -        # Extract field names
> -        fields = []
> -        for fn in curs.description:
> -            fields.append(fn[0])
> -
> -        # Extract records
> -        records = []
> -        for dbrec in curs.fetchall():
> -            values = []
> -            for val in dbrec:
> -                values.append(val)
> -            records.append(values)
> -
> -        curs.close()
> -        if self.debug:
> -            print("database::SELECT() result ** Fields: %s\nRecords: %s" % (fields, records))
> -        return {"table": table, "fields": fields, "records": records}
> -
> -    def COMMIT(self):
> -        # Commit the work
> -        if not self.noaction:
> -            self.conn.commit()
> -
> -    def ROLLBACK(self):
> -        # Abort / rollback the current work
> -        if not self.noaction:
> -            self.conn.rollback()
> -
> -
> -    def GetValue(self, dbres, recidx, field):
> -        "Helper function to easy extract a field from a record set"
> -
> -        # Check that input data good
> -        if type(dbres) is not dict:
> -            raise AttributeError('Database result parameter is not a Python dict')
> -
> -        try:
> -            dbres['table']
> -            dbres['fields']
> -            dbres['records']
> -        except KeyError as err:
> -            raise KeyError("Database result parameter do not contain a required element: %s").with_traceback(str(err))
> -
> -        if type(dbres['fields']) is not list:
> -            raise AttributeError("The 'fields' element is not a list of fields")
> -
> -        if type(dbres['records']) is not list:
> -            raise AttributeError("The 'records' element is not a list of fields")
> -
> -        # Return None when we're going out of boundaries
> -        if recidx >= len(dbres['records']):
> -            return None
> -
> -        if type(field) == bytes:
> -            # Find the field index of the field name in the records set
> -            try:
> -                fidx = dbres['fields'].index(field)
> -            except ValueError:
> -                raise Exception("Field '%s' is not found in the database result" % field)
> -        elif type(field) == int:
> -            # If the field value is integer, assume it is the numeric field id
> -            if field >= len(dbres['fields']):
> -                raise Exception("Field id '%i' is too high.  No field available" % field)
> -            fidx = field
> -
> -        # Return the value
> -        return dbres['records'][recidx][fidx]
> -
> -
> -    def NumTuples(self, dbres):
> -        # Check that input data good
> -        if type(dbres) is not dict:
> -            raise AttributeError('Database result parameter is not a Python dict')
> -
> -        try:
> -            dbres['table']
> -            dbres['fields']
> -            dbres['records']
> -        except KeyError as err:
> -            raise KeyError("Database result parameter do not contain a required element: %s").with_traceback(str(err))
> -
> -        if type(dbres['records']) is not list:
> -            raise AttributeError("The 'records' element is not a list of fields")
> -
> -        return len(dbres['records'])
> diff --git a/server/gen_config.sh b/server/gen_config.sh
> deleted file mode 100755
> index 335176f..0000000
> --- a/server/gen_config.sh
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -#/bin/sh
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -
> -APACHECONF="$1"
> -INSTALLDIR="$2"
> -
> -echo "Creating Apache config file: apache-rteval.conf"
> -escinstpath="$(echo ${INSTALLDIR} | sed -e 's/\//\\\\\//g')"
> -expr=$(echo "s/{_INSTALLDIR_}/${escinstpath}/")
> -eval "sed -e ${expr} ${APACHECONF}.tpl" > apache-rteval.conf
> -echo "Copy the apache apache-rteval.conf into your Apache configuration"
> -echo "directory and restart your web server"
> -echo
> -
> diff --git a/server/parser/Makefile.am b/server/parser/Makefile.am
> deleted file mode 100644
> index 02b3326..0000000
> --- a/server/parser/Makefile.am
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#   Makefile.am - autotools configuration file
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -# Generic include files, found by ./configure
> -AM_CPPFLAGS = $(LIBXML2_INC) $(LIBXSLT_INC) $(LIBPQ_INC) -std=gnu89
> -
> -# What is required to build rteval_parserd
> -bin_PROGRAMS = rteval-parserd
> -rteval_parserd_SOURCES = argparser.c argparser.h 			 \
> -	configparser.c configparser.h 					 \
> -	eurephia_nullsafe.c eurephia_nullsafe.h eurephia_values_struct.h \
> -	eurephia_values.c eurephia_values.h 				 \
> -	eurephia_xml.c eurephia_xml.h 					 \
> -	log.c log.h  							 \
> -	parsethread.c parsethread.h threadinfo.h			 \
> -	pgsql.c pgsql.h 						 \
> -	sha1.c sha1.h							 \
> -	xmlparser.c xmlparser.h	             				 \
> -	rteval-parserd.c statuses.h
> -
> -# Don't build, only install
> -xsltdir=$(datadir)/rteval
> -dist_xslt_DATA = xmlparser.xsl
> -
> -# Copy init script and config file example to the docs dir
> -initscriptdir=$(docdir)/initscripts
> -dist_initscript_DATA = rteval-parserd.init rteval-parserd.sysconfig
> diff --git a/server/parser/README.parser b/server/parser/README.parser
> deleted file mode 100644
> index 2618552..0000000
> --- a/server/parser/README.parser
> +++ /dev/null
> @@ -1,204 +0,0 @@
> -**
> -**  rteval-parsed - the rteval XML report parser
> -**
> -
> -The purpose of the daemon is to off load the web server from the heavy duty
> -work of parsing and processing the rteval XML reports.  The XML-RPC server
> -will receive the reports and put the files in a queue directory on the
> -file system and register the the submission in the database.  This will notify
> -the rteval-parsed that a new report has been received and it will start
> -processing that file independently of the web/XML-RPC server.
> -
> -
> -** Installing the software
> -
> -  !! Please install also the rteval-xmlrpc package and read the !!
> -  !! README.xmlrpc file also for setting up and preparing the   !!
> -  !! database which the rteval-parserd program will be using.   !!
> -  !! This file will also contain information regardingupgrading !!
> -  !! the database.                                              !!
> -
> -When installing this application from a binary package, like RPM
> -files on Fedora/RHEL based boxes, you should have the rteval-parserd
> -in your $PATH.  Otherwise, when installing from sources, the configure
> -script defines the default paths.
> -
> -
> -** Configure rteval-parsed
> -
> -When starting the rteval-parserd via the init.d script (or via the 'service'
> -command on RHEL/Fedora distributions) it will use the values configured in
> -/etc/sysconfig/rteval-parserd.
> -
> -The available parameters are:
> -
> -    - NUM_THREADS
> -      When this is not defined, the default behaviour is to use the number
> -      of available CPU cores.  The init.d script will detect this
> -      automatically.
> -
> -    - LOG
> -      This defines how logging will be done.  See the rteval-parserd
> -      arguments description further down in the document for more
> -      information.
> -
> -    - LOGLEVEL
> -      Defines how verbose the logging will be.  See the rteval-parserd
> -      arguments description further down in the document for more
> -      information.
> -
> -    - CONFIGFILE
> -      The default configuration file rteval-parserd will try to read is
> -      /etc/rteval.conf.  See the next paragraph for more information about
> -      this file.  This argument let you override the default config file.
> -
> -    - PIDFILE
> -      Defines where the init.d script will put the PID file for the
> -      rteval-parserd process.  The default is /var/run/rteval-parserd.pid
> -
> -This daemon uses the same configuration file as the rest of the rteval program
> -suite, /etc/rteval.conf.  It will parse the section named 'xmlrpc_parser'.
> -
> -The default values are:
> -
> -  - xsltpath: /usr/share/rteval
> -    Defines where it can find the xmlparser.xsl XSLT template
> -
> -  - db_server: localhost
> -    Which database server to connect to
> -
> -  - db_port: 5432
> -    Which port to use for the database connection
> -
> -  - database: rteval
> -    Which database to make use of.
> -
> -  - db_username: rtevparser
> -    Which user name to use for the connection
> -
> -  - db_password: rtevaldb_parser
> -    Which password to use for the authentication
> -
> -  - reportdir: /var/lib/rteval/report
> -    Where to save the parsed reports
> -
> -  - threads: 4
> -    Number of worker threads.  This defines how many reports you will
> -    process in parallel.  The recommended number here is the number
> -    of available CPU cores, as having a higher thread number often
> -    punishes the performance.  The default value is 4 when rteval-parserd
> -    is started directly.  When started via the init.d script, the default
> -    is to start one thread per CPU core.
> -
> -  - max_report_size: 2097152
> -    Maximum file size of reports which the parser will process.  The
> -    default value is 2MB.  The value must be given in bytes.  Remember
> -    that this value is per thread, and that XML and XSLT processing can
> -    be quite memory hungry.  If this value is set too high or you have too
> -    many worker threads, your system might become unresponsive for a while
> -    and the parser might be killed by the kernel (OOM).
> -
> -  - measurement_tables: cyclic_statistics, cyclic_histogram, hwlatdetect_summary, hwlatdetect_samples
> -    Declares which measurement results will be parsed and stored in the
> -    database.  These names are referring to table definitions in the
> -    xmlparser.xsl XSLT template.  The definitions in this template tells
> -    rteval-parsed which data to extract from the rteval summary.xml report
> -    and where and how to store it in the database.
> -
> -
> -** rteval-parserd arguments
> -
> -  -d | --daemon                    Run as a daemon
> -  -l | --log        <log dest>     Where to put log data
> -  -L | --log-level  <verbosity>    What to log
> -  -f | --config     <config file>  Which configuration file to use
> -  -t | --threads    <num. threads> How many worker threads to start (def: 4)
> -  -h | --help                      This help screen
> -
> -- Configuration file
> -By default the program will look for /etc/rteval.conf.  This can be
> -overridden by using --config <config file>.
> -
> -- Logging
> -When the program is started as a daemon, it will log to syslog by default.
> -The default log level is 'info'.  When not started as a daemon, all logging
> -will go to stderr by default.
> -
> -The --log argument takes either 'destination' or a file name.  Unknown
> -destinations are treated as filenames.  Valid 'destinations' are:
> -
> -    stderr:             - Log to stderr
> -    stdout:             - Log to stdout
> -    syslog:[facility]   - Log to syslog
> -    <file name>         - Log to given file
> -
> -For syslog the default facility is 'daemon', but can be overridden by using
> -one of the following facility values:
> -    daemon, user and local0 to local7
> -
> -Log verbosity is set by the --log-level.  The valid values here are:
> -
> -    emerg, emergency    - Only log errors which causes the program to stop
> -    alert               - Incidents which needs immediate attention
> -    crit, critical      - Unexpected incidents which is not urgent
> -    err, error          - Parsing errors.  Issues with input data
> -    warn, warning       - Incidents which may influence performance
> -    notice              - Less important warnings
> -    info                - General run information
> -    debug               - Detailed run information, incl. thread operation
> -
> -- Threads
> -By default, the daemon will use five threads.  One for the main threads which
> -processes the submission queue and notifies the working threads.  The four
> -other threads are worker threads, which will process the received reports.
> -
> -Each of the worker threads will have its own connection to the database.  This
> -connection will be connected to the database as long as the daemon is running.
> -It is therefore important that you do not have more worker threads than
> -available database connections.
> -
> -
> -** POSIX Message Queue
> -
> -The daemon makes use of POSIX MQ for distributing work to the worker threads.
> -Each thread lives independently and polls the queue regularly for more work.
> -As the POSIX MQ has a pretty safe mechanism of not duplicating messages in the
> -implementation, no other locking facility is needed.
> -
> -On Linux, the default value for maximum messages in the queue are set to 10.
> -If you receive a lot of reports and the threads do not process the queue
> -quickly enough, it will fill up pretty quickly.  If the queue is filled up,
> -the main thread which populates the message queue will politely go to sleep
> -for one minute before attempting to send new messages.  To avoid this, consider
> -to increase the queue size by modifying /proc/sys/fs/mqueue/msg_max.
> -
> -When the daemon initialises itself, it will read this file to make sure it
> -uses the queue to the maximum, but not beyond that.
> -
> -
> -** PostgreSQL features
> -
> -The daemon depends on the PostgreSQL database.  It is written with an
> -abstraction layer so it should, in theory, be possible to easily adopt it to
> -different database implementation.
> -
> -In the current implementation, it makes use of PostgreSQL's LISTEN, NOTIFY and
> -UNLISTEN features.  A trigger is enabled on the submission queue table, which
> -sends a NOTIFY whenever a record is inserted into the table.  The rteval-parser
> -daemon listens for these notifications, and will immediately poll the table
> -upon such a notification.
> -
> -Whenever a notification is received, it will always parse all unprocessed
> -reports.  In addition it will also only listen for notifications when there
> -are no unprocessed reports.
> -
> -The core PostgreSQL implementation is only done in pgsql.[ch], which provides an
> -abstract API layer for the rest of the parser daemon.
> -
> -
> -** Submission queue status codes
> -
> -In the rteval database's submissionqueue table there is a status field.  The
> -daemon will only consider records with status == 0 for processing.  It do not
> -consider any other fields.  For a better understanding of the different status
> -codes, look into the file statuses.h.
> diff --git a/server/parser/argparser.c b/server/parser/argparser.c
> deleted file mode 100644
> index 70d6961..0000000
> --- a/server/parser/argparser.c
> +++ /dev/null
> @@ -1,140 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   argparser.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 22 13:58:46 2009
> - *
> - * @brief  Generic argument parser
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <getopt.h>
> -#include <eurephia_values.h>
> -#include <eurephia_nullsafe.h>
> -
> -
> -/**
> - * Print a help screen to stdout
> - */
> -void usage() {
> -	printf("rteval-parserd:  Parses new reports recieved via XML-RPC\n"
> -	       "\n"
> -	       "This program will wait for changes to the rteval 'submissionqueue' table.\n"
> -	       "When a new report is registered here, it will send this report to one of\n"
> -	       "the worker threads which will insert the parsed result into the database.\n"
> -	       "\n"
> -	       "** Program arguments:\n"
> -	       "  -d | --daemon                    Run as a daemon\n"
> -	       "  -l | --log        <log dest>     Where to put log data\n"
> -	       "  -L | --log-level  <verbosity>    What to log\n"
> -	       "  -f | --config     <config file>  Which configuration file to use\n"
> -	       "  -t | --threads    <num. threads> How many worker threads to start (def: 4)\n"
> -	       "  -h | --help                      This help screen\n"
> -	       "\n"
> -	       "** Configuration file\n"
> -	       "By default the program will look for /etc/rteval.conf.  This can be\n"
> -	       "overriden by using --config <config file>.\n"
> -	       "\n"
> -	       "** Logging\n"
> -	       "When the program is started as a daemon, it will log to syslog by default.\n"
> -	       "The default log level is 'info'.  When not started as a daemon, all logging\n"
> -	       "will go to stderr by default.\n"
> -	       "\n"
> -	       "The --log argument takes either 'destination' or a file name.  Unknown\n"
> -	       "destinations are treated as filenames.  Valid 'destinations' are:\n"
> -	       "\n"
> -	       "    stderr:             - Log to stderr\n"
> -	       "    stdout:             - Log to stdout\n"
> -	       "    syslog:[facility]   - Log to syslog\n"
> -	       "    <file name>         - Log to given file\n"
> -	       "\n"
> -	       "For syslog the default facility is 'daemon', but can be overriden by using\n"
> -	       "one of the following facility values:\n"
> -	       "    daemon, user and local0 to local7\n"
> -	       "\n"
> -	       "Log verbosity is set by the --log-level.  The valid values here are:\n"
> -	       "\n"
> -	       "    emerg, emergency    - Only log errors which causes the program to stop\n"
> -	       "    alert               - Incidents which needs immediate attention\n"
> -	       "    crit, critical      - Unexpected incidents which is not urgent\n"
> -	       "    err, error          - Parsing errors.  Issues with input data\n"
> -	       "    warn, warning       - Incidents which may influence performance\n"
> -	       "    notice              - Less important warnings\n"
> -	       "    info                - General run information\n"
> -	       "    debug               - Detailed run information, incl. thread operations\n"
> -	       "\n"
> -	       );
> -}
> -
> -
> -/**
> - * Parses program arguments and puts the recognised arguments into an eurephiaVALUES struct.
> - *
> - * @param argc   argument counter
> - * @param argv   argument string table
> - *
> - * @return Returns a pointer to an eurephiaVALUES struct.  On failure, the program halts.
> - */
> -eurephiaVALUES *parse_arguments(int argc, char **argv) {
> -	eurephiaVALUES *args = NULL;
> -	int optidx, c;
> -	static struct option long_opts[] = {
> -		{"log", 1, 0, 'l'},
> -		{"log-level", 1, 0, 'L'},
> -		{"config", 1, 0, 'f'},
> -		{"threads", 1, 0, 't'},
> -		{"daemon", 0, 0, 'd'},
> -		{"help", 0, 0, 'h'},
> -		{0, 0, 0, 0}
> -	};
> -
> -	args = eCreate_value_space(NULL, 21);
> -	eAdd_value(args, "daemon", "0");
> -	eAdd_value(args, "configfile", "/etc/rteval.conf");
> -	eAdd_value(args, "threads", "4");
> -
> -	while( 1 ) {
> -		optidx = 0;
> -		c = getopt_long(argc, argv, "l:L:f:t:dh", long_opts, &optidx);
> -		if( c == -1 ) {
> -			break;
> -		}
> -
> -		switch( c ) {
> -		case 'l':
> -			eUpdate_value(args, "log", optarg, 1);
> -			break;
> -		case 'L':
> -			eUpdate_value(args, "loglevel", optarg, 1);
> -			break;
> -		case 'f':
> -			eUpdate_value(args, "configfile", optarg, 0);
> -			break;
> -		case 't':
> -			eUpdate_value(args, "threads", optarg, 0);
> -			break;
> -		case 'd':
> -			eUpdate_value(args, "daemon", "1", 0);
> -			break;
> -		case 'h':
> -			usage();
> -			exit(0);
> -		}
> -	}
> -
> -	// If logging is not configured, and it is not run as a daemon
> -	// -> log to stderr:
> -	if( (eGet_value(args, "log") == NULL)
> -	    && (atoi_nullsafe(eGet_value(args, "daemon")) == 0) ) {
> -		eAdd_value(args, "log", "stderr:");
> -	}
> -
> -	return args;
> -}
> diff --git a/server/parser/argparser.h b/server/parser/argparser.h
> deleted file mode 100644
> index 5325505..0000000
> --- a/server/parser/argparser.h
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   argparser.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 22 13:58:46 2009
> - *
> - * @brief  Generic argument parser
> - *
> - */
> -
> -#ifndef _RTEVAL_ARGPARSER_h
> -#define _RTEVAL_ARGPARSER_h
> -
> -eurephiaVALUES *parse_arguments(int argc, char **argv);
> -
> -#endif
> diff --git a/server/parser/configparser.c b/server/parser/configparser.c
> deleted file mode 100644
> index 4eaf318..0000000
> --- a/server/parser/configparser.c
> +++ /dev/null
> @@ -1,171 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*  configparser.c - Read and parse config files
> - *
> - *  This code is based on the fragments from the eurephia project.
> - *
> - *  GPLv2 Copyright (C) 2009
> - *  David Sommerseth <davids@xxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   configparser.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   2009-10-01
> - *
> - * @brief  Config file parser
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <sys/stat.h>
> -#include <assert.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <eurephia_values.h>
> -#include <configparser.h>
> -#include <log.h>
> -
> -/**
> - * Parse one single configuration line into a eurephiaVALUES key/value pair.  It will also ignore
> - * comment lines, and also remove the comments on the line of the configuration line so that only
> - * the key/value information is extracted.
> - *
> - * @param line Input configuration line
> - *
> - * @return eurephiaVALUES pointer containing the parsed result.  On error or if no valid config
> - * line was found, NULL is returned.
> - */
> -static inline eurephiaVALUES *parse_config_line(LogContext *log, const char *line) {
> -        char *cp = NULL, *key = NULL, *val = NULL, *ptr = NULL;;
> -        eurephiaVALUES *ret = NULL;
> -
> -        if( *line == '#' ) {
> -                return NULL;
> -        }
> -
> -        cp = strdup(line);
> -        key = cp;
> -        val = strpbrk(cp, "=:");
> -        if( val == NULL ) {
> -                free_nullsafe(cp);
> -                return NULL;
> -        }
> -        *val = '\0'; val++;
> -
> -        // Discard comments at the end of a line
> -        if( (ptr = strpbrk(val, "#")) != NULL ) {
> -                *ptr = '\0';
> -        }
> -
> -        // Left trim
> -        while( ((*key == 0x20) || (*key == 0x0A) || (*key == 0x0D)) ) {
> -                key++;
> -        }
> -        while( ((*val == 0x20) || (*val == 0x0A) || (*val == 0x0D)) ) {
> -                val++;
> -        }
> -
> -        // Right trim
> -        ptr = key + strlen_nullsafe(key) - 1;
> -        while( ((*ptr == 0x20) || (*ptr == 0x0A) || (*ptr == 0x0D)) && (ptr > key) ) {
> -                ptr--;
> -        }
> -        ptr++;
> -        *ptr = '\0';
> -
> -        ptr = val + strlen_nullsafe(val) - 1;
> -        while( ((*ptr == 0x20) || (*ptr == 0x0A) || (*ptr == 0x0D)) && (ptr > val) ) {
> -                ptr--;
> -        }
> -        ptr++;
> -        *ptr = '\0';
> -
> -        // Put key/value into a eurephiaVALUES struct and return it
> -        ret = eCreate_value_space(log, 20);
> -        ret->key = strdup(key);
> -        ret->val = strdup(val);
> -
> -        free_nullsafe(cp);
> -        return ret;
> -}
> -
> -
> -static inline eurephiaVALUES *default_cfg_values(LogContext *log, eurephiaVALUES *prgargs) {
> -	eurephiaVALUES *cfg = NULL, *ptr = NULL;
> -
> -	cfg = eCreate_value_space(log, 20);
> -	eAdd_value(cfg, "datadir", "/var/lib/rteval");
> -	eAdd_value(cfg, "xsltpath", "/usr/share/rteval");
> -	eAdd_value(cfg, "db_server", "localhost");
> -	eAdd_value(cfg, "db_port", "5432");
> -	eAdd_value(cfg, "database", "rteval");
> -	eAdd_value(cfg, "db_username", "rtevparser");
> -	eAdd_value(cfg, "db_password", "rtevaldb_parser");
> -	eAdd_value(cfg, "reportdir", "/var/lib/rteval/reports");
> -	eAdd_value(cfg, "max_report_size", "2097152"); // 2MB
> -	eAdd_value(cfg, "measurement_tables", "cyclic_statistics, cyclic_histogram, hwlatdetect_summary, hwlatdetect_samples");
> -
> -	// Copy over the arguments to the config, update existing settings
> -	for( ptr = prgargs; ptr; ptr = ptr->next ) {
> -		eUpdate_value(cfg, ptr->key, ptr->val, 1);
> -	}
> -
> -	return cfg;
> -}
> -
> -/**
> - * Parses a section of a config file and puts it into an eurephiaVALUES key/value stack
> - *
> - * @param log     Initialised log context
> - * @param prgargs Parsed command line arguments (see parse_arguments())
> - * @param section Section to read from the config file
> - *
> - * @return Returns a pointer to an eurephiaVALUES stack containing the configuration on success,
> - *         otherwise NULL.
> - */
> -eurephiaVALUES *read_config(LogContext *log, eurephiaVALUES *prgargs, const char *section) {
> -        FILE *fp = NULL;
> -        char  *buf = NULL, *sectmatch = NULL, *cfgname = NULL;
> -	int sectfound = 0;
> -        eurephiaVALUES *cfg = NULL;
> -        struct stat fi;
> -
> -	cfgname = eGet_value(prgargs, "configfile");
> -        if( stat(cfgname, &fi) == -1 ) {
> -		writelog(log, LOG_EMERG, "Could not open the config file: %s", cfgname);
> -                return NULL;
> -        }
> -
> -        if( (fp = fopen(cfgname, "r")) == NULL ) {
> -                writelog(log, LOG_EMERG, "Could not open the config file: %s", cfgname);
> -                return NULL;
> -        }
> -
> -        buf = (char *) malloc_nullsafe(log, fi.st_size+2);
> -	sectmatch = (char *) malloc_nullsafe(log, strlen_nullsafe(section)+4);
> -	sprintf(sectmatch, "[%s]", section);
> -
> -        cfg = default_cfg_values(log, prgargs);
> -	writelog(log, LOG_DEBUG, "Reading config file: %s", cfgname);
> -        while( fgets(buf, fi.st_size, fp) != NULL ) {
> -		if( strncmp(buf, "[", 1) == 0 ) {
> -			sectfound = (!sectfound && (strncmp(buf, sectmatch, strlen(sectmatch)) == 0));
> -			continue;
> -		}
> -
> -		if( sectfound ) {
> -			eurephiaVALUES *prm = parse_config_line(log, buf);
> -			if( prm != NULL ) {
> -				cfg = eUpdate_valuestruct(cfg, prm, 1);
> -			}
> -		}
> -        };
> -        free_nullsafe(buf);
> -	free_nullsafe(sectmatch);
> -        fclose(fp); fp = NULL;
> -
> -        return cfg;
> -}
> diff --git a/server/parser/configparser.h b/server/parser/configparser.h
> deleted file mode 100644
> index 033ae26..0000000
> --- a/server/parser/configparser.h
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*  configparser.h - Read and parse config files
> - *
> - *  This code is based on the fragments from the eurephia project.
> - *
> - *  GPLv2 Copyright (C) 2009
> - *  David Sommerseth <davids@xxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   configparser.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   2009-10-01
> - *
> - * @brief  Config file parser
> - *
> - */
> -
> -#ifndef _CONFIGPARSER_H
> -#define _CONFIGPARSER_H
> -
> -eurephiaVALUES *read_config(LogContext *log, eurephiaVALUES *prgargs, const char *section);
> -
> -#endif
> diff --git a/server/parser/eurephia_nullsafe.c b/server/parser/eurephia_nullsafe.c
> deleted file mode 100644
> index 5abda69..0000000
> --- a/server/parser/eurephia_nullsafe.c
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/* eurephia_nullsafe.c
> - *
> - *  standard C string functions, which is made NULL safe by checking
> - *  if input value is NULL before performing the action.
> - *
> - *  This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2009
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_nullsafe.c
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2009-09-07
> - *
> - * @brief standard C string functions, which is made NULL safe by checking
> - *        if input value is NULL before performing the action.
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -
> -#include <log.h>
> -
> -#if __GNUC__ >= 3
> -#define __malloc__ __attribute__((malloc))
> -#else /* If not GCC 3 or newer, disable optimisations */
> -#define __malloc__
> -#endif
> -
> -/**
> - * This replaces the use of malloc() and memset().  This function uses calloc
> - * internally, which results in the memory region being zero'd by the kernel
> - * on memory allocation.
> - *
> - * @param log   Log context
> - * @param sz    size of the memory region being allocated
> - *
> - * @return Returns a void pointer to the memory region on success, otherwise NULL
> - */
> -__malloc__ void *malloc_nullsafe(LogContext *log, size_t sz) {
> -        void *buf = NULL;
> -
> -        buf = calloc(1, sz);    /* Using calloc, also gives a zero'd memory region */
> -        if( !buf ) {
> -		writelog(log, LOG_EMERG, "Could not allocate memory region for %ld bytes", sz);
> -		exit(9);
> -        }
> -        return buf;
> -}
> diff --git a/server/parser/eurephia_nullsafe.h b/server/parser/eurephia_nullsafe.h
> deleted file mode 100644
> index 00e6188..0000000
> --- a/server/parser/eurephia_nullsafe.h
> +++ /dev/null
> @@ -1,103 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/* eurephia_nullsafe.h
> - *
> - *  standard C string functions, which is made NULL safe by checking
> - *  if input value is NULL before performing the action.
> - *
> - *  This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2008, 2009
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_nullsafe.h
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-08-06
> - *
> - * @brief standard C string functions, which is made NULL safe by checking
> - *        if input value is NULL before performing the action.
> - *
> - */
> -
> -#ifndef   	EUREPHIA_NULLSAFE_H_
> -#define    	EUREPHIA_NULLSAFE_H_
> -
> -#include <log.h>
> -
> -/**
> - * atoi() wrapper.  Converts any string into a integer
> - *
> - * @param str Input string
> - *
> - * @return Returns integer
> - */
> -#define atoi_nullsafe(str) (str != NULL ? atoi(str) : 0)
> -
> -
> -/**
> - * strdup() wrapper.  Duplicates the input string.
> - *
> - * @param str Input string to be duplicated
> - *
> - * @return Returns a pointer to the duplicate (char *) on success, NULL otherwise.
> - * If input was NULL, NULL is returned.
> - */
> -#define strdup_nullsafe(str) (str != NULL ? strdup(str) : NULL)
> -
> -
> -/**
> - * Wrapper macro, which appends a string to a destination string without exceeding the size
> - * of the destination buffer.
> - *
> - * @param dest Pointer to the destination buffer
> - * @param src  Pointer to the value being concatenated to the destination string.
> - * @param size Size of the destination buffer
> - */
> -#define append_str(dest, src, size) strncat(dest, src, (size - strlen_nullsafe(dest)))
> -
> -
> -/**
> - * strlen() wrapper.  Returns the length of a string
> - *
> - * @param str Input string
> - *
> - * @return Returns int with length of string.  If input is NULL, it returns 0.
> - */
> -#define strlen_nullsafe(str) (str != NULL ? strlen(str) : 0)
> -
> -
> -void *malloc_nullsafe(LogContext *, size_t);
> -
> -/**
> - * Null safe free().  It will not attempt to free a pointer which is NULL.
> - *
> - * @param ptr Pointer to the memory region being freed.
> - *
> - */
> -#define free_nullsafe(ptr) if( ptr ) { free(ptr); ptr = NULL; }
> -
> -
> -/**
> - * Function which will return a default string value if no input data was provided.
> - *
> - * @param str     Input string
> - * @param defstr  Default string
> - *
> - * @return Returns the pointer to the input string if the string length > 0.  Otherwise it
> - * will return a pointer to the default string.
> - */
> -#define defaultValue(str, defstr) (strlen_nullsafe(str) == 0 ? defstr : str)
> -
> -
> -/**
> - * Function which will return a default integer value if no input data was provided.
> - *
> - * @param ival   input integer value
> - * @param defval default integer value
> - *
> - * @return Returns the ival value if it is > 0, otherwise defval value is returned.
> - */
> -#define defaultIntValue(ival, defval) (ival == 0 ? defval : ival)
> -#endif 	    /* !EUREPHIA_NULLSAFE_H_ */
> diff --git a/server/parser/eurephia_values.c b/server/parser/eurephia_values.c
> deleted file mode 100644
> index 8f3645a..0000000
> --- a/server/parser/eurephia_values.c
> +++ /dev/null
> @@ -1,301 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/* eurephia_values.c  --  Generic interface for processing key->value pairs
> - *
> - * This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2008
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_values.c
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-08-06
> - *
> - * @brief  Generic interface for handling key->value pairs
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <assert.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <eurephia_values_struct.h>
> -
> -
> -
> -/**
> - * Function for freeing up an eurephiaVALUES stack.  This function is normally not called
> - * directly, but usually via the eFree_values(...) macro.
> - *
> - * @param vls  Pointer to a eurephiaVALUES stack to be freed.
> - */
> -void eFree_values_func(eurephiaVALUES *vls) {
> -	eurephiaVALUES *ptr = NULL, *ptr_next = NULL;
> -
> -	ptr = vls;
> -	while( ptr ) {
> -		free_nullsafe(ptr->key);
> -		free_nullsafe(ptr->val);
> -
> -		ptr_next = ptr->next;
> -		free_nullsafe(ptr);
> -		ptr = ptr_next;
> -	}
> -}
> -
> -
> -/**
> - * Retrieve an eurephiaVALUES element for a given value key
> - *
> - * @param vls  Pointer to the eurephiaVALUES stack where to search for the element
> - * @param key  String containing the key name of the value requested.
> - *
> - * @return Returns an eurephiaVALUES element on success, otherwise NULL.
> - */
> -eurephiaVALUES *eGet_valuestruct(eurephiaVALUES *vls, const char *key)
> -{
> -        eurephiaVALUES *ptr = NULL;
> -
> -        if( (vls == NULL) || (key == NULL) ) {
> -                return NULL;
> -        }
> -
> -        ptr = vls;
> -        while( ptr != NULL ) {
> -                if( (ptr->key != NULL) && (strcmp(key, ptr->key) == 0) ) {
> -                        return ptr;
> -                }
> -                ptr = ptr->next;
> -        }
> -        return NULL;
> -}
> -
> -
> -/**
> - * Retrieves the value of a given key from an eurephiaVALUES stack.
> - *
> - * @param vls  Pointer to an eurephiaVALUES stack where to search for the value
> - * @param key  String containing the key name of the value requested
> - *
> - * @return Returns a string (char *) with the requested value if found, otherwise NULL.
> - */
> -char *eGet_value(eurephiaVALUES *vls, const char *key)
> -{
> -        eurephiaVALUES *ptr = NULL;
> -
> -        ptr = eGet_valuestruct(vls, key);
> -        return (ptr != NULL ? ptr->val : NULL);
> -}
> -
> -
> -/**
> - * Creates a new eurephiaVALUES stack
> - *
> - * @param log   Log context
> - * @param evgid  int value, giving the stack an ID number.  Useful when looking through log files later on.
> - *
> - * @return Returns an empty eurephiaVALUES struct on success, otherwise NULL.
> - */
> -eurephiaVALUES *eCreate_value_space(LogContext *log, int evgid)
> -{
> -        eurephiaVALUES *ptr = NULL;
> -
> -        ptr = (eurephiaVALUES *) malloc_nullsafe(log, sizeof(eurephiaVALUES) + 2);
> -	ptr->log = log;
> -        ptr->evgid = evgid;
> -        return ptr;
> -}
> -
> -
> -/**
> - * Adds a new eurephiaVALUES stack to another eurephiaVALUES stack.  If the evgid value differs, it will
> - * be overwritten with the value of the destination stack.
> - *
> - * @param vls    Destination eurephiaVALUES stack
> - * @param newval Source eurephiaVALUES stack
> - */
> -void eAdd_valuestruct(eurephiaVALUES *vls, eurephiaVALUES *newval) {
> -        eurephiaVALUES *ptr = NULL;
> -        int vid = 0;
> -
> -        assert(vls != NULL);
> -
> -        if( (vls->key == NULL) && (vls->val == NULL) && (vls->next == NULL) && (vls->evid == 0)) {
> -                // Update header record if it is empty, by copying newval record.  Free newval afterwards
> -                vls->key  = strdup(newval->key);
> -                vls->val  = strdup(newval->val);
> -                vls->evid = 0;
> -                vls->next = NULL;
> -                eFree_values_func(newval);
> -        } else {
> -                // Add values to the value chain, loop to the end and append it
> -                ptr = vls;
> -                while( ptr->next != NULL ) {
> -                        ptr = ptr->next;
> -                        vid = (vid > ptr->evid ? vid : ptr->evid);
> -                }
> -                newval->evid = vid+1;     // Increase the value counter
> -                newval->evgid = ptr->evgid;
> -                ptr->next = newval;
> -        }
> -}
> -
> -
> -/**
> - * Adds a new key/value pair to an eurephiaVALUES stack
> - *
> - * @param vls  Destination eurephiaVALUES stack
> - * @param key  Key name for the value being stored
> - * @param val  Value to be stored
> - */
> -void eAdd_value(eurephiaVALUES *vls, const char *key, const char *val)
> -{
> -        eurephiaVALUES *ptr = NULL;
> -
> -        assert(vls != NULL);
> -
> -        // Allocate buffer and save values
> -        ptr = eCreate_value_space(vls->log, vls->evid);
> -        if( ptr == NULL ) {
> -		writelog(vls->log, LOG_EMERG, "Failed to add value to the value chain");
> -		exit(9);
> -        }
> -        ptr->key = strdup_nullsafe(key);
> -        ptr->val = strdup_nullsafe(val);
> -        ptr->evgid = vls->evgid;
> -
> -        // Add value struct to the chain
> -        eAdd_valuestruct(vls, ptr);
> -}
> -
> -
> -/**
> - * Updates the value of a key in a values stack
> - *
> - * @param vls      eurephiaVALUES key/value stack to update
> - * @param key      String with key name to update
> - * @param newval   String with the new value
> - * @param addunkn  Add unknown keys.  If set to 1, if the key is not found it will add a new key
> - */
> -void eUpdate_value(eurephiaVALUES *vls, const char *key, const char *newval, const int addunkn) {
> -	eurephiaVALUES *ptr = NULL;
> -
> -	assert( (vls != NULL) && (key != NULL) );
> -
> -	ptr = eGet_valuestruct(vls, key);
> -	if( ptr ) {
> -		free_nullsafe(ptr->val);
> -		ptr->val = strdup_nullsafe(newval);
> -	} else if( addunkn == 1 ) {
> -		eAdd_value(vls, key, newval);
> -	}
> -}
> -
> -
> -/**
> - * Updates a value struct element based on another value struct element contents (key/value)
> - *
> - * @param vls      eurephiaVALUES key/value stack to update
> - * @param newval   eurephiaVALUES element with the new value
> - * @param addunkn  Add unknown keys.  If set to 1, if the key is not found it will add a new key
> - *
> - * @return Returns a pointer to the first element in the chain.  If the element being updated
> - *         was the first element in the old chain, the first element will be a new element with a
> - *         new address.
> - */
> -eurephiaVALUES *eUpdate_valuestruct(eurephiaVALUES *vls, eurephiaVALUES *newval, const int addunkn) {
> -	eurephiaVALUES *ptr = NULL, *prevptr = NULL;
> -
> -	assert( (vls != NULL) && (newval != NULL) && (newval->key != NULL) );
> -
> -	prevptr = vls;
> -	for( ptr = vls; ptr != NULL; ptr = ptr->next ) {
> -                if( (ptr->key != NULL) && (strcmp(newval->key, ptr->key) == 0) ) {
> -			newval->evgid = ptr->evgid;
> -			newval->evid = ptr->evid;
> -			newval->next = ptr->next;
> -			ptr->next = NULL;
> -			if( ptr == vls ) {
> -				// If the element found is the first one, do special treatment
> -				eFree_values_func(ptr);
> -				return newval;
> -			} else {
> -				prevptr->next = newval;
> -				eFree_values_func(ptr);
> -				return vls;
> -			}
> -                }
> -		prevptr = ptr;
> -	}
> -
> -	if( addunkn == 1 ) {
> -		eAdd_valuestruct(vls, newval);
> -	}
> -	return vls;
> -}
> -
> -
> -/**
> - * Removes the key/value pair identified by evgid and evid from the given eurephiaVALUES chain
> - *
> - * @param vls    Pointer to an eurephiaVALUES chain with the data
> - * @param evgid  Group ID of the chain
> - * @param evid   Element ID of the chain element to be removed
> - *
> - * @return Returns a pointer to the chain.  The pointer is only changed if the first element in the
> - *         chain is deleted
> - */
> -eurephiaVALUES *eRemove_value(eurephiaVALUES *vls, unsigned int evgid, unsigned int evid) {
> -        eurephiaVALUES *ptr = NULL, *prev_ptr = NULL;
> -        int found = 0;
> -
> -        // Find the value element
> -        for( ptr = vls; ptr != NULL; ptr = ptr->next ) {
> -                if( (ptr->evgid == evgid) && (ptr->evid == evid) ) {
> -                        found = 1;
> -                        break;
> -                }
> -                prev_ptr = ptr;
> -        }
> -
> -        if( !found ) {
> -                return vls;
> -        }
> -
> -        if( ptr != vls ) {
> -                prev_ptr->next = ptr->next;
> -                ptr->next = NULL;
> -                eFree_values_func(ptr);
> -                return vls;
> -        } else {
> -                prev_ptr = ptr->next;
> -                ptr->next = NULL;
> -                eFree_values_func(ptr);
> -                return prev_ptr;
> -        }
> -}
> -
> -
> -/**
> - * Counts number of elements in an eurephiaVALUES chain.
> - *
> - * @param vls eurephiaVALUES pointer to be counted
> - *
> - * @return Returns number of elements found.
> - */
> -unsigned int eCount(eurephiaVALUES *vls) {
> -	eurephiaVALUES *ptr = NULL;
> -	unsigned int c = 0;
> -
> -	if( vls == NULL ) {
> -		return 0;
> -	}
> -	for(ptr = vls; ptr != NULL; ptr = ptr->next ) {
> -		c++;
> -	}
> -	return c;
> -}
> diff --git a/server/parser/eurephia_values.h b/server/parser/eurephia_values.h
> deleted file mode 100644
> index 0daba4a..0000000
> --- a/server/parser/eurephia_values.h
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/* eurephia_values.h  --  Generic interface for processing key->value pairs
> - *
> - * This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2008
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_values.h
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-08-06
> - *
> - * @brief  Generic interface for handling key->value pairs
> - *
> - */
> -
> -#include <eurephia_values_struct.h>
> -
> -#ifndef         EUREPHIA_VALUES_H_
> -#define         EUREPHIA_VALUES_H_
> -
> -
> -eurephiaVALUES *eGet_valuestruct(eurephiaVALUES *vls, const char *key);
> -char *eGet_value(eurephiaVALUES *vls, const char *key);
> -
> -eurephiaVALUES *eCreate_value_space(LogContext *log, int evid);
> -
> -void eAdd_valuestruct(eurephiaVALUES *vls, eurephiaVALUES *newval);
> -void eAdd_value(eurephiaVALUES *vls, const char *key, const char *val);
> -void eUpdate_value(eurephiaVALUES *vls, const char *key, const char *newval, const int addunkn);
> -eurephiaVALUES *eUpdate_valuestruct(eurephiaVALUES *vls, eurephiaVALUES *newval, const int addunkn);
> -eurephiaVALUES *eRemove_value(eurephiaVALUES *vls, unsigned int evgid, unsigned int evid);
> -unsigned int eCount(eurephiaVALUES *vls);
> -
> -/**
> - * Front-end function for eFree_values_func().  Frees eurephiaVALUES pointer chain and
> - * sets the pointer to NULL.
> - *
> - * @param v eurephiaVALUES pointer which is being freed.
> - *
> - */
> -#define eFree_values(v) { eFree_values_func(v); v = NULL; }
> -void eFree_values_func(eurephiaVALUES *vls);
> -
> -#endif      /* !EUREPHIA_VALUES_H_ */
> diff --git a/server/parser/eurephia_values_struct.h b/server/parser/eurephia_values_struct.h
> deleted file mode 100644
> index 6ea530a..0000000
> --- a/server/parser/eurephia_values_struct.h
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/* eurephia_values.h  --  eurephiaVALUES struct typedef
> - *
> - *  GPLv2 only - Copyright (C) 2008
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_values_struct.h
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-11-05
> - *
> - * @brief  Definition of the eurephiaVALUES struct
> - *
> - */
> -
> -#ifndef   	EUREPHIA_VALUES_STRUCT_H_
> -# define   	EUREPHIA_VALUES_STRUCT_H_
> -
> -#include <log.h>
> -
> -/**
> - * eurephiaVALUES is a pointer chain with key/value pairs.  If having several
> - * such pointer chains, they can be given different group IDs to separate them,
> - * which is especially useful during debugging.
> - *
> - */
> -typedef struct __eurephiaVALUES {
> -	LogContext *log;        /**< Pointer to an established log context, used for logging */
> -        unsigned int evgid;	/**< Group ID, all elements in the same chain should have the same value */
> -        unsigned int evid;	/**< Unique ID per element in a pointer chain */
> -        char *key;		/**< The key name of a value */
> -        char *val;		/**< The value itself */
> -        struct __eurephiaVALUES *next; /**< Pointer to the next element in the chain. NULL == end of chain */
> -} eurephiaVALUES;
> -
> -#endif 	    /* !EUREPHIA_VALUES_STRUCT_H_ */
> diff --git a/server/parser/eurephia_xml.c b/server/parser/eurephia_xml.c
> deleted file mode 100644
> index 0679956..0000000
> --- a/server/parser/eurephia_xml.c
> +++ /dev/null
> @@ -1,147 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/* eurephia_xml.c  --  Generic helper functions for XML parsing
> - *
> - * This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2008, 2009
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_xml.c
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-12-15
> - *
> - * @brief  Generic XML parser functions
> - *
> - *
> - */
> -
> -#include <stdarg.h>
> -#include <string.h>
> -#include <assert.h>
> -
> -#include <libxml/tree.h>
> -#include <libxml/xmlsave.h>
> -#include <libxml/xmlstring.h>
> -
> -#include <eurephia_nullsafe.h>
> -
> -
> -/**
> - * Retrieves a given XML node attribute/property
> - *
> - * @param attr xmlAttr pointer from an xmlNode pointer.
> - * @param key  The attribute name to search for
> - *
> - * @return The value of the found attribute.  If not found, NULL is returned.
> - */
> -char *xmlGetAttrValue(xmlAttr *attr, const char *key) {
> -        xmlAttr *aptr;
> -        xmlChar *x_key = NULL;
> -
> -        x_key = xmlCharStrdup(key);
> -        assert( x_key != NULL );
> -
> -        for( aptr = attr; aptr != NULL; aptr = aptr->next ) {
> -                if( xmlStrcmp(aptr->name, x_key) == 0 ) {
> -                        free_nullsafe(x_key);
> -                        return (char *)(aptr->children != NULL ? aptr->children->content : NULL);
> -                }
> -        }
> -        free_nullsafe(x_key);
> -        return NULL;
> -}
> -
> -
> -/**
> - * Loops through a xmlNode chain to look for a given tag.  The search is not recursive.
> - *
> - * @param node xmlNode pointer where to look
> - * @param key  the name of the XML tag to find
> - *
> - * @return xmlNode pointer to the found xmlNode.  NULL is returned if not found.
> - */
> -xmlNode *xmlFindNode(xmlNode *node, const char *key) {
> -        xmlNode *nptr = NULL;
> -        xmlChar *x_key = NULL;
> -
> -        if( (node == NULL) || (node->children == NULL) ) {
> -                return NULL;
> -        }
> -
> -        x_key = xmlCharStrdup(key);
> -        assert( x_key != NULL );
> -
> -        for( nptr = node->children; nptr != NULL; nptr = nptr->next ) {
> -                if( xmlStrcmp(nptr->name, x_key) == 0 ) {
> -                        free_nullsafe(x_key);
> -                        return nptr;
> -                }
> -        }
> -        free_nullsafe(x_key);
> -        return NULL;
> -}
> -
> -
> -/**
> - * Return the text content of a given xmlNode
> - *
> - * @param n xmlNode to extract the value from.
> - *
> - * @return returns a char pointer with the text contents of an xmlNode.
> - */
> -inline char *xmlExtractContent(xmlNode *n) {
> -        return (char *) (((n != NULL) && (n->children != NULL)) ? n->children->content : NULL);
> -}
> -
> -
> -/**
> - * Get the text contents of a given xmlNode
> - *
> - * @param node An xmlNode pointer where to look for the contents
> - * @param key  Name of the tag to retrieve the content of.
> - *
> - * @return Returns a string with the text content, if the node is found.  Otherwise, NULL is returned.
> - */
> -inline char *xmlGetNodeContent(xmlNode *node, const char *key) {
> -        return xmlExtractContent(xmlFindNode(node, key));
> -}
> -
> -
> -/**
> - * Serialises an xmlNode to a string
> - *
> - * @param log   Log context
> - * @param node Input XML node to be serialised
> - *
> - * @return Returns a pointer to a new buffer containing the serialised data.  This buffer must be freed
> - *         after usage
> - */
> -char *xmlNodeToString(LogContext *log, xmlNode *node) {
> -	xmlBuffer *buf = NULL;
> -	xmlSaveCtxt *serctx = NULL;
> -	char *ret = NULL;
> -
> -	if( node == NULL ) {
> -		writelog(log, LOG_ALERT, "xmlNodeToString: Input data is NULL");
> -		return NULL;
> -	}
> -
> -	buf = xmlBufferCreate();
> -	assert( buf != NULL );
> -
> -	serctx = xmlSaveToBuffer(buf, "UTF-8", XML_SAVE_NO_EMPTY|XML_SAVE_NO_DECL);
> -	assert( serctx != NULL );
> -
> -	if( xmlSaveTree(serctx, node) < 0 ) {
> -		writelog(log, LOG_ALERT, "xmlNodeToString: Failed to serialise xmlNode");
> -		return NULL;
> -	}
> -	xmlSaveClose(serctx);
> -
> -	ret = strdup_nullsafe((char *) xmlBufferContent(buf));
> -	xmlBufferFree(buf);
> -	return ret;
> -}
> diff --git a/server/parser/eurephia_xml.h b/server/parser/eurephia_xml.h
> deleted file mode 100644
> index 7bfffe8..0000000
> --- a/server/parser/eurephia_xml.h
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/* eurephia_xml.h  --  Generic helper functions for XML parsing
> - *
> - * This version is modified to work outside the eurephia project.
> - *
> - *  GPLv2 only - Copyright (C) 2008
> - *               David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - *
> - */
> -
> -/**
> - * @file   eurephia_xml.h
> - * @author David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx>
> - * @date   2008-12-15
> - *
> - * @brief  Generic XML parser functions
> - *
> - */
> -
> -
> -#ifndef   	EUREPHIA_XML_H_
> -#define   	EUREPHIA_XML_H_
> -
> -#include <stdarg.h>
> -
> -#include <libxml/tree.h>
> -
> -/**
> - * Simple iterator macro for iterating xmlNode pointers
> - *
> - * @param start  Pointer to an xmlNode where to start iterating
> - * @param itn    An xmlNode pointer which will be used for the iteration.
> - */
> -#define foreach_xmlnode(start, itn)  for( itn = start; itn != NULL; itn = itn->next )
> -
> -char *xmlGetAttrValue(xmlAttr *properties, const char *key);
> -xmlNode *xmlFindNode(xmlNode *node, const char *key);
> -
> -inline char *xmlExtractContent(xmlNode *n);
> -inline char *xmlGetNodeContent(xmlNode *node, const char *key);
> -char *xmlNodeToString(LogContext *log, xmlNode *node);
> -
> -#endif 	    /* !EUREPHIA_XML_H_ */
> diff --git a/server/parser/log.c b/server/parser/log.c
> deleted file mode 100644
> index 9a21326..0000000
> --- a/server/parser/log.c
> +++ /dev/null
> @@ -1,228 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   log.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 21 11:38:51 2009
> - *
> - * @brief  Generic log functions
> - *
> - */
> -
> -#include <stdio.h>
> -#include <string.h>
> -#include <stdlib.h>
> -#include <errno.h>
> -#include <assert.h>
> -#include <stdarg.h>
> -#include <pthread.h>
> -#include <syslog.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <log.h>
> -
> -/**
> - * Maps defined log level strings into syslog
> - * compatible LOG_* integer values
> - */
> -static struct {
> -	const char *priority_str;
> -	const int prio_level;
> -} syslog_prio_map[] = {
> -	{"emerg",     LOG_EMERG},
> -	{"emergency", LOG_EMERG},
> -	{"alert",     LOG_ALERT},
> -	{"crit",      LOG_CRIT},
> -	{"critical",  LOG_CRIT},
> -	{"err",       LOG_ERR},
> -	{"error",     LOG_ERR},
> -	{"warning",   LOG_WARNING},
> -	{"warn",      LOG_WARNING},
> -	{"notice",    LOG_NOTICE},
> -	{"info",      LOG_INFO},
> -	{"debug",     LOG_DEBUG},
> -	{NULL, 0}
> -};
> -
> -
> -/**
> - * Initialises a log context.  It parses the log destination and log level and
> - * prepares a context which can be used by writelog()
> - *
> - * @param logdest  String containing either syslog:[facility], stderr: or stdout:, or a file name.
> - * @param loglvl   Defines the log level.  Can be one of the values defined in syslog_prio_map.
> - *
> - * @return Returns a pointer to a log context on success, otherwise NULL.
> - */
> -LogContext *init_log(const char *logdest, const char *loglvl) {
> -	LogContext *logctx = NULL;
> -	int i;
> -
> -	logctx = (LogContext *) calloc(1, sizeof(LogContext)+2);
> -	assert( logctx != NULL);
> -
> -	logctx->logfp = NULL;
> -
> -	// Get the int value of the log level string
> -	logctx->verbosity = -1;
> -	if( loglvl ) {
> -		for( i = 0; syslog_prio_map[i].priority_str; i++ ) {
> -			if( strcasecmp(loglvl, syslog_prio_map[i].priority_str) == 0 ) {
> -				logctx->verbosity = syslog_prio_map[i].prio_level;
> -				break;
> -			}
> -		}
> -	}
> -
> -	// If log level is not set, set LOG_INFo as default
> -	if( logctx->verbosity == -1 ) {
> -		logctx->verbosity = LOG_INFO;
> -	}
> -
> -	if( logdest == NULL ) {
> -		logctx->logtype = ltSYSLOG;
> -		openlog("rteval-parserd", LOG_PID, LOG_DAEMON);
> -	} else {
> -		if( strncmp(logdest, "syslog:", 7) == 0 ) {
> -			const char *fac = logdest+7;
> -			int facid = LOG_DAEMON;
> -
> -			if( strcasecmp(fac, "local0") == 0 ) {
> -				facid = LOG_LOCAL0;
> -			} else if( strcasecmp(fac, "local1") == 0 ) {
> -				facid = LOG_LOCAL1;
> -			} else if( strcasecmp(fac, "local2") == 0 ) {
> -				facid = LOG_LOCAL2;
> -			} else if( strcasecmp(fac, "local3") == 0 ) {
> -				facid = LOG_LOCAL3;
> -			} else if( strcasecmp(fac, "local4") == 0 ) {
> -				facid = LOG_LOCAL4;
> -			} else if( strcasecmp(fac, "local5") == 0 ) {
> -				facid = LOG_LOCAL5;
> -			} else if( strcasecmp(fac, "local6") == 0 ) {
> -				facid = LOG_LOCAL6;
> -			} else if( strcasecmp(fac, "local7") == 0 ) {
> -				facid = LOG_LOCAL7;
> -			} else if( strcasecmp(fac, "user") == 0 ) {
> -				facid = LOG_USER;
> -			}
> -			logctx->logtype = ltSYSLOG;
> -			openlog("rteval-parserd", LOG_PID, facid);
> -		} else if( strcmp(logdest, "stderr:") == 0 ) {
> -			logctx->logtype = ltCONSOLE;
> -			logctx->logfp = stderr;
> -		} else if( strcmp(logdest, "stdout:") == 0 ) {
> -			logctx->logtype = ltCONSOLE;
> -			logctx->logfp = stdout;
> -		} else {
> -			logctx->logtype = ltFILE;
> -			logctx->logfp = fopen(logdest, "a");
> -			if( logctx->logfp == NULL ) {
> -				fprintf(stderr, "** ERROR **  Failed to open log file %s: %s\n",
> -					logdest, strerror(errno));
> -				free_nullsafe(logctx);
> -				return NULL;
> -			}
> -		}
> -	}
> -
> -	if( logctx->logtype != ltSYSLOG ) {
> -		static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
> -		logctx->mtx_log = &mtx;
> -	}
> -	return logctx;
> -}
> -
> -
> -/**
> - * Tears down a log context.  Closes log files and releases memory used by the log context.
> - *
> - * @param lctx  Log context to close
> - */
> -void close_log(LogContext *lctx) {
> -	if( !lctx ) {
> -		return;
> -	}
> -
> -	switch( lctx->logtype ) {
> -	case ltFILE:
> -		fclose(lctx->logfp);
> -		break;
> -
> -	case ltSYSLOG:
> -		closelog();
> -		break;
> -
> -	case ltCONSOLE:
> -		break;
> -	}
> -	free_nullsafe(lctx);
> -}
> -
> -
> -/**
> - * Write data to the log.
> - *
> - * @param lctx    Log context, where the data will be logged
> - * @param loglvl  Log level.  See the priorities for syslog(3) for valid values.
> - * @param fmt     Data to be logged (stdarg)
> - */
> -void writelog(LogContext *lctx, unsigned int loglvl, const char *fmt, ... ) {
> -	if( !lctx || !fmt ) {
> -		return;
> -	}
> -
> -	if( lctx->verbosity >= loglvl ) {
> -		va_list ap;
> -
> -		va_start(ap, fmt);
> -		switch( lctx->logtype ) {
> -		case ltSYSLOG:
> -			vsyslog(loglvl, fmt, ap);
> -			break;
> -
> -		case ltCONSOLE:
> -		case ltFILE:
> -			pthread_mutex_lock(lctx->mtx_log);
> -			switch( loglvl ) {
> -			case LOG_EMERG:
> -				fprintf(lctx->logfp, "**  EMERG  ERROR  ** ");
> -				break;
> -			case LOG_ALERT:
> -				fprintf(lctx->logfp, "**  ALERT  ERROR  ** ");
> -				break;
> -			case LOG_CRIT:
> -				fprintf(lctx->logfp, "** CRITICAL ERROR ** ");
> -				break;
> -			case LOG_ERR:
> -				fprintf(lctx->logfp, "** ERROR ** ");
> -				break;
> -			case LOG_WARNING:
> -				fprintf(lctx->logfp, "*WARNING* ");
> -				break;
> -			case LOG_NOTICE:
> -				fprintf(lctx->logfp, "[NOTICE] ");
> -				break;
> -			case LOG_INFO:
> -				fprintf(lctx->logfp, "[INFO]   ");
> -				break;
> -			case LOG_DEBUG:
> -				fprintf(lctx->logfp, "[DEBUG]  ");
> -				break;
> -			}
> -			vfprintf(lctx->logfp, fmt, ap);
> -			fprintf(lctx->logfp, "\n");
> -			pthread_mutex_unlock(lctx->mtx_log);
> -
> -			if( lctx->logtype == ltFILE ) {
> -				fflush(lctx->logfp);
> -			}
> -			break;
> -		}
> -		va_end(ap);
> -	}
> -}
> diff --git a/server/parser/log.h b/server/parser/log.h
> deleted file mode 100644
> index deeb784..0000000
> --- a/server/parser/log.h
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   log.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 21 11:38:51 2009
> - *
> - * @brief  Generic log functions
> - *
> - */
> -
> -#ifndef _RTEVAL_LOG_H
> -#define _RTEVAL_LOG_H
> -
> -#include <pthread.h>
> -#include <syslog.h>
> -
> -/**
> - * Supported log types
> - */
> -typedef enum { ltSYSLOG, ltFILE, ltCONSOLE } LogType;
> -
> -/**
> - * The log context structure.  Keeps needed information for
> - * a flawless logging experience :-P
> - */
> -typedef struct {
> -	LogType logtype;           /**<  What kind of log "device" will be used */
> -	FILE *logfp;               /**<  Only used if logging to stderr, stdout or a file */
> -	unsigned int verbosity;    /**<  Defines which log level the user wants to log */
> -	pthread_mutex_t *mtx_log;  /**<  Mutex to threads to write to a file based log in parallel */
> -} LogContext;
> -
> -
> -LogContext *init_log(const char *fname, const char *loglvl);
> -void close_log(LogContext *lctx);
> -void writelog(LogContext *lctx, unsigned int loglvl, const char *fmt, ... );
> -
> -#endif
> diff --git a/server/parser/parsethread.c b/server/parser/parsethread.c
> deleted file mode 100644
> index b327e2d..0000000
> --- a/server/parser/parsethread.c
> +++ /dev/null
> @@ -1,370 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   parsethread.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 15 11:52:10 2009
> - *
> - * @brief  Contains the "main" function which a parser threads runs
> - *
> - *
> - */
> -
> -#include <stdio.h>
> -#include <string.h>
> -#include <unistd.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -#include <signal.h>
> -#include <pthread.h>
> -#include <libgen.h>
> -#include <errno.h>
> -#include <assert.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <parsethread.h>
> -#include <pgsql.h>
> -#include <log.h>
> -#include <threadinfo.h>
> -#include <statuses.h>
> -
> -
> -/**
> - * Does the same job as 'mkdir -p', but it expects a complete filename as input, and it will
> - * extract the directory path from that filename
> - *
> - * @param fname  Full filename containing the directory the report will reside.
> - *
> - * @return Returns 1 on success, otherwise -1
> - */
> -static int make_report_dir(LogContext *log, const char *fname) {
> -	char *fname_cp = NULL, *dname = NULL, *chkdir = NULL;
> -	char *tok = NULL, *saveptr = NULL;
> -	int ret = 0;
> -	struct stat info;
> -
> -	if( !fname ) {
> -		return 0;
> -	}
> -
> -	fname_cp = strdup(fname);
> -	assert( fname_cp != NULL );
> -	dname = dirname(fname_cp);
> -	chkdir = malloc_nullsafe(log, strlen(dname)+8);
> -
> -	if( dname[0] == '/' ) {
> -		chkdir[0] = '/';
> -	}
> -
> -	// Traverse the directory path, and make sure the directory exists
> -	tok = strtok_r(dname, "/", &saveptr);
> -	while( tok ) {
> -		strcat(chkdir, tok);
> -		strcat(chkdir, "/");
> -
> -		errno = 0;
> -		// Check if directory exists
> -		if( (stat(chkdir, &info) < 0) ) {
> -			switch( errno ) {
> -			case ENOENT: // If the directory do not exist, create it
> -				if( mkdir(chkdir, 0755) < 0 ) {
> -					// If creating dir failed, report error
> -					writelog(log, LOG_ALERT,
> -						 "Could not create directory: %s (%s)",
> -						 chkdir, strerror(errno));
> -					ret = -1;
> -					goto exit;
> -				}
> -				break;
> -			default: // If other failure, report that and exit
> -				writelog(log, LOG_ALERT,
> -					 "Could not access directory: %s (%s)",
> -					 chkdir, strerror(errno));
> -				ret = -1;
> -				goto exit;
> -			}
> -		}
> -		// Goto next path element
> -		tok = strtok_r(NULL, "/", &saveptr);
> -	}
> -	ret = 1;
> - exit:
> -	free_nullsafe(fname_cp);
> -	free_nullsafe(chkdir);
> -
> -	return ret;
> -}
> -
> -
> -/**
> - * Builds up a proper full path of where to save the report.
> - *
> - * @param destdir   Destination directory for all reports
> - * @param fname     Report filename, containing hostname of the reporter
> - * @param rterid    rteval run ID
> - *
> - * @return Returns a pointer to a string with the new full path filename on success, otherwise NULL.
> - */
> -static char *get_destination_path(LogContext *log, const char *destdir,
> -				  parseJob_t *job, const int rterid)
> -{
> -        char *newfname = NULL;
> -        int retlen = 0;
> -
> -        if( !job || rterid < 0 ) {
> -                return NULL;
> -        }
> -
> -        retlen = strlen_nullsafe(job->clientid) + strlen(destdir) + 24;
> -        newfname = malloc_nullsafe(log, retlen+2);
> -
> -        snprintf(newfname, retlen, "%s/%s/report-%i.xml", destdir, job->clientid, rterid);
> -
> -        return newfname;
> -}
> -
> -
> -/**
> - * Checks if the file size of the given file is below the given max size value.
> - *
> - * @param thrdata  Pointer to a threadData_t structure with log context and max_report_size setting
> - * @param fname    Filename of the file to check
> - *
> - * @return Returns 1 if file is within the limit, otherwise 0.  On errors -1 is returned.
> - */
> -inline int check_filesize(threadData_t *thrdata, const char *fname) {
> -	struct stat info;
> -
> -	if( !fname ) {
> -		return 0;
> -	}
> -
> -	errno = 0;
> -	if( (stat(fname, &info) < 0) ) {
> -		writelog(thrdata->dbc->log, LOG_ERR, "Failed to check report file '%s': %s",
> -			 fname, strerror(errno));
> -		return -1;
> -	}
> -
> -	return (info.st_size <= thrdata->max_report_size);
> -}
> -
> -
> -/**
> - * The core parse function.  Parses an XML file and stores it in the database according to
> - * the xmlparser.xsl template.
> - *
> - * @param thrdata  Pointer to a threadData_t structure with database connection, log context, settings, etc
> - * @param job      Pointer to a parseJob_t structure containing the job information
> - *
> - * @return Return values:
> - * @code
> - *          STAT_SUCCESS  : Successfully registered report
> - *          STAT_FTOOBIG  : XML report file is too big
> - *          STAT_XMLFAIL  : Could not parse the XML report file
> - *          STAT_SYSREG   : Failed to register the system into the systems or systems_hostname tables
> - *          STAT_RTERIDREG: Failed to get a new rterid value
> - *          STAT_GENDB    : Failed to start an SQL transaction (BEGIN)
> - *          STAT_RTEVRUNS : Failed to register the rteval run into rtevalruns or rtevalruns_details
> - *          STAT_MEASURE  : Failed to register the measurement data into tables their corresponding tables
> - *          STAT_REPMOVE  : Failed to move the report file
> - * @endcode
> - */
> -inline int parse_report(threadData_t *thrdata, parseJob_t *job)
> -{
> -	int syskey = -1, rterid = -1;
> -	int rc = -1;
> -	xmlDoc *repxml = NULL;
> -	char *destfname;
> -
> -	// Check file size - and reject too big files
> -	if( check_filesize(thrdata, job->filename) == 0 ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] (submid: %i) Report file '%s' is too big, rejected",
> -			 thrdata->id, job->submid, job->filename);
> -		return STAT_FTOOBIG;
> -	}
> -
> -
> -	repxml = xmlParseFile(job->filename);
> -	if( !repxml ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] (submid: %i) Could not parse XML file: %s",
> -			 thrdata->id, job->submid, job->filename);
> -	        return STAT_XMLFAIL;
> -	}
> -
> -	pthread_mutex_lock(thrdata->mtx_sysreg);
> -	syskey = db_register_system(thrdata->dbc, thrdata->xslt, repxml);
> -	if( syskey < 0 ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] Failed to register system (submid: %i, XML file: %s)",
> -			 thrdata->id, job->submid, job->filename);
> -		rc = STAT_SYSREG;
> -		pthread_mutex_unlock(thrdata->mtx_sysreg);
> -		goto exit;
> -
> -	}
> -
> -	rterid = db_get_new_rterid(thrdata->dbc);
> -	if( rterid < 0 ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] Failed to register rteval run (submid: %i, XML file: %s)",
> -			 thrdata->id, job->submid, job->filename);
> -		rc = STAT_RTERIDREG;
> -		pthread_mutex_unlock(thrdata->mtx_sysreg);
> -		goto exit;
> -	}
> -	pthread_mutex_unlock(thrdata->mtx_sysreg);
> -
> -	if( db_begin(thrdata->dbc) < 1 ) {
> -		rc = STAT_GENDB;
> -		goto exit;
> -	}
> -
> -	// Create a new filename of where to save the report
> -	destfname = get_destination_path(thrdata->dbc->log, thrdata->destdir, job, rterid);
> -	if( !destfname ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] Failed to generate local report filename for (submid: %i) %s",
> -			 thrdata->id, job->submid, job->filename);
> -		db_rollback(thrdata->dbc);
> -		rc = STAT_UNKNFAIL;
> -		goto exit;
> -	}
> -
> -	if( db_register_rtevalrun(thrdata->dbc, thrdata->xslt, repxml, job->submid,
> -				  syskey, rterid, destfname) < 0 ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] Failed to register rteval run (submid: %i, XML file: %s)",
> -			 thrdata->id, job->submid, job->filename);
> -		db_rollback(thrdata->dbc);
> -		rc = STAT_RTEVRUNS;
> -		goto exit;
> -	}
> -
> -	if( db_register_measurements(thrdata->dbc, thrdata->xslt, repxml, rterid) != 1 ) {
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] Failed to register measurement data (submid: %i, XML file: %s)",
> -			 thrdata->id, job->submid, job->filename);
> -		db_rollback(thrdata->dbc);
> -		rc = STAT_MEASURE;
> -		goto exit;
> -	}
> -
> -	// When all database registrations are done, move the file to it's right place
> -	if( make_report_dir(thrdata->dbc->log, destfname) < 1 ) { // Make sure report directory exists
> -		db_rollback(thrdata->dbc);
> -		rc = STAT_REPMOVE;
> -		goto exit;
> -	}
> -
> -	if( rename(job->filename, destfname) < 0 ) { // Move the file
> -		writelog(thrdata->dbc->log, LOG_ERR,
> -			 "[Thread %i] (submid: %i) Failed to move report file from %s to %s (%s)",
> -			 thrdata->id, job->submid, job->filename, destfname, strerror(errno));
> -		db_rollback(thrdata->dbc);
> -		rc = STAT_REPMOVE;
> -		goto exit;
> -	}
> -	free_nullsafe(destfname);
> -
> -	rc = STAT_SUCCESS;
> -	db_commit(thrdata->dbc);
> -	writelog(thrdata->dbc->log, LOG_INFO,
> -		 "[Thread %i] Report parsed and stored (submid: %i, rterid: %i)",
> -		 thrdata->id, job->submid, rterid);
> - exit:
> -	xmlFreeDoc(repxml);
> -	return rc;
> -}
> -
> -
> -/**
> - * The parser thread.  This thread lives until a shutdown notification is received.  It pulls
> - * messages on a POSIX MQ based message queue containing submission ID and full path to an XML
> - * report to be parsed.
> - *
> - * @param thrargs Contains database connection, XSLT stylesheet, POSXI MQ descriptor, etc
> - *
> - * @return Returns 0 on successful operation, otherwise 1 on errors.
> - */
> -void *parsethread(void *thrargs) {
> -	threadData_t *args = (threadData_t *) thrargs;
> -	parseJob_t jobinfo;
> -	long exitcode = 0;
> -
> -	writelog(args->dbc->log, LOG_DEBUG, "[Thread %i] Starting", args->id);
> -	pthread_mutex_lock(args->mtx_thrcnt);
> -	(*(args->threadcount)) += 1;
> -	pthread_mutex_unlock(args->mtx_thrcnt);
> -
> -	// Polling loop
> -	while( *(args->shutdown) == 0 ) {
> -		int len = 0;
> -		unsigned int prio = 0;
> -
> -		// Check if the database connection is alive before pulling any messages
> -		if( db_ping(args->dbc) != 1 ) {
> -			writelog(args->dbc->log, LOG_EMERG,
> -				 "[Thread %i] Lost database conneciting: Shutting down thread.",
> -				 args->id);
> -
> -			if( *(args->threadcount) <= 1 ) {
> -				writelog(args->dbc->log, LOG_EMERG,
> -					 "No more worker threads available.  "
> -					 "Signaling for complete shutdown!");
> -				kill(getpid(), SIGUSR1);
> -			}
> -			exitcode = 1;
> -			goto exit;
> -		}
> -
> -		// Retrieve a parse job from the message queue
> -		memset(&jobinfo, 0, sizeof(parseJob_t));
> -		errno = 0;
> -		len = mq_receive(args->msgq, (char *)&jobinfo, sizeof(parseJob_t), &prio);
> -		if( (len < 0) && errno != EAGAIN ) {
> -			writelog(args->dbc->log, LOG_CRIT,
> -				 "Could not receive the message from queue: %s",
> -				 strerror(errno));
> -			pthread_exit((void *) 1);
> -		}
> -
> -		// Ignore whatever message if the shutdown flag is set.
> -		if( *(args->shutdown) != 0 ) {
> -			break;
> -		}
> -
> -		// If we have a message, then process the parse job
> -		if( (errno != EAGAIN) && (len > 0) ) {
> -			int res = 0;
> -
> -			writelog(args->dbc->log, LOG_INFO,
> -				 "[Thread %i] Job recieved, submid: %i - %s",
> -				 args->id, jobinfo.submid, jobinfo.filename);
> -
> -			// Mark the job as "in progress", if successful update, continue parsing it
> -			if( db_update_submissionqueue(args->dbc, jobinfo.submid, STAT_INPROG) ) {
> -				res = parse_report(args, &jobinfo);
> -				// Set the status for the submission
> -				db_update_submissionqueue(args->dbc, jobinfo.submid, res);
> -			} else {
> -				writelog(args->dbc->log, LOG_CRIT,
> -					 "Failed to mark submid %i as STAT_INPROG",
> -					 jobinfo.submid);
> -			}
> -		}
> -	}
> -	writelog(args->dbc->log, LOG_DEBUG, "[Thread %i] Shut down", args->id);
> - exit:
> -	pthread_mutex_lock(args->mtx_thrcnt);
> -	(*(args->threadcount)) -= 1;
> -	pthread_mutex_unlock(args->mtx_thrcnt);
> -
> -	pthread_exit((void *) exitcode);
> -}
> diff --git a/server/parser/parsethread.h b/server/parser/parsethread.h
> deleted file mode 100644
> index 90eb658..0000000
> --- a/server/parser/parsethread.h
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   parsethread.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 15 11:52:10 2009
> - *
> - * @brief  Contains the "main" function which a parser threads runs
> - *
> - */
> -
> -#ifndef _PARSETHREAD_H
> -#define _PARSETHREAD_H
> -
> -/**
> - * jbNONE means no job available,
> - * jbAVAIL indicates that parseJob_t contains a job
> -*/
> -typedef enum { jbNONE, jbAVAIL } jobStatus;
> -
> -/**
> - * This struct is used for sending a parse job to a worker thread via POSIX MQ
> - */
> -typedef struct {
> -        jobStatus status;                  /**< Info about if job information*/
> -        unsigned int submid;               /**< Work info: Numeric ID of the job being parsed */
> -        char clientid[256];                /**< Work info: Should contain senders hostname */
> -        char filename[4096];               /**< Work info: Full filename of the report to be parsed */
> -} parseJob_t;
> -
> -
> -void *parsethread(void *thrargs);
> -
> -#endif
> diff --git a/server/parser/pgsql.c b/server/parser/pgsql.c
> deleted file mode 100644
> index 5492d02..0000000
> --- a/server/parser/pgsql.c
> +++ /dev/null
> @@ -1,1093 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   pgsql.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 13 17:44:35 2009
> - *
> - * @brief  Database API for the PostgreSQL database.
> - *
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <pthread.h>
> -#include <assert.h>
> -#include <errno.h>
> -
> -#include <libpq-fe.h>
> -
> -#include <libxml/parser.h>
> -#include <libxml/xmlsave.h>
> -#include <libxslt/transform.h>
> -#include <libxslt/xsltutils.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <eurephia_xml.h>
> -#include <eurephia_values.h>
> -#include <configparser.h>
> -#include <xmlparser.h>
> -#include <pgsql.h>
> -#include <log.h>
> -#include <statuses.h>
> -
> -/** forward declaration, to be able to setup dbhelper_func pointers */
> -static char * pgsql_BuildArray(LogContext *log, xmlNode *sql_n);
> -
> -/** Helper functions the xmlparser might beed */
> -static dbhelper_func pgsql_helpers = {
> -        .dbh_FormatArray = &(pgsql_BuildArray)
> -};
> -
> -/**
> - * Connect to a database, based on the given configuration
> - *
> - * @param cfg eurephiaVALUES containing the configuration
> - * @param id  Database connection ID.  Used to identify which thread is doing what with the database
> - * @param log Log context, where all logging will go
> - *
> - * @return Returns a database connection context
> - */
> -dbconn *db_connect(eurephiaVALUES *cfg, unsigned int id, LogContext *log) {
> -	dbconn *ret = NULL;
> -        PGresult *dbr = NULL;
> -
> -	ret = (dbconn *) malloc_nullsafe(log, sizeof(dbconn)+2);
> -	ret->id = id;
> -	ret->log = log;
> -
> -	writelog(log, LOG_DEBUG, "[Connection %i] Connecting to database: server=%s:%s, "
> -		 "database=%s, user=%s", ret->id,
> -		 eGet_value(cfg, "db_server"), eGet_value(cfg, "db_port"),
> -		 eGet_value(cfg, "database"), eGet_value(cfg, "db_username"));
> -	ret->db = PQsetdbLogin(eGet_value(cfg, "db_server"),
> -			   eGet_value(cfg, "db_port"),
> -			   NULL, /* pgopt */
> -			   NULL, /* pgtty */
> -			   eGet_value(cfg, "database"),
> -			   eGet_value(cfg, "db_username"),
> -			   eGet_value(cfg, "db_password"));
> -
> -	if( !ret->db ) {
> -		writelog(log, LOG_EMERG,
> -			 "[Connection %i] Could not connect to the database (unknown reason)", ret->id);
> -		free_nullsafe(ret);
> -		return NULL;
> -	}
> -
> -	if( PQstatus(ret->db) != CONNECTION_OK ) {
> -		writelog(log, LOG_EMERG, "[Connection %i] Failed to connect to the database: %s",
> -			 ret->id, PQerrorMessage(ret->db));
> -		free_nullsafe(ret);
> -		return NULL;
> -	}
> -
> -	// Retrieve the SQL schema version
> -	dbr = PQexec(ret->db,
> -		     "SELECT FLOOR(value::NUMERIC(6,3))*100 " // Convert version string to integer
> -		     "       + to_char(substring(value, position('.' in value)+1)::INTEGER, '00')::INTEGER"
> -		     "  FROM rteval_info WHERE key = 'sql_schema_ver'");
> -	if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) || (PQntuples(dbr) != 1) ) {
> -		// Query failed, assuming SQL schema version 1.00 (100).
> -		// SQL schema versions before 1.1 (101) do not have the rteval_info table, thus
> -		// a failure is not completely unexpected.
> -		ret->sqlschemaver = 100;
> -	} else {
> -		ret->sqlschemaver = atoi_nullsafe(PQgetvalue(dbr, 0, 0));
> -		if( ret->sqlschemaver < 100 ) {
> -			ret->sqlschemaver = 100;  // The minimal version - version 1.00.
> -		}
> -	}
> -	if( dbr ) {
> -		PQclear(dbr);
> -	}
> -	init_xmlparser(&pgsql_helpers);
> -	return ret;
> -}
> -
> -
> -/**
> - * Pings the database connection to check if it is alive
> - *
> - * @param dbc  Database connection to ping
> - *
> - * @return Returns 1 if the connection is alive, otherwise 0
> - */
> -int db_ping(dbconn *dbc) {
> -	PGresult *res = NULL;
> -
> -	// Send ping
> -	res = PQexec(dbc->db, "");
> -	PQclear(res);
> -
> -	// Check status
> -	if( PQstatus(dbc->db) != CONNECTION_OK ) {
> -		PQreset(dbc->db);
> -		if( PQstatus(dbc->db) != CONNECTION_OK ) {
> -			writelog(dbc->log, LOG_EMERG,
> -				 "[Connection %i] Database error - Lost connection: %s",
> -				 dbc->id, PQerrorMessage(dbc->db));
> -			return 0;
> -		} else {
> -			writelog(dbc->log, LOG_CRIT,
> -				 "[Conncetion %i] Database connection restored", dbc->id);
> -		}
> -	}
> -	return 1;
> -}
> -
> -
> -/**
> - * Disconnect from the database
> - *
> - * @param dbc Pointer to the database handle to be disconnected.
> - */
> -void db_disconnect(dbconn *dbc) {
> -	if( dbc && dbc->db ) {
> -		writelog(dbc->log, LOG_DEBUG, "[Connection %i] Disconnecting from database", dbc->id);
> -		PQfinish(dbc->db);
> -		dbc->db = NULL;
> -		dbc->log = NULL;
> -	}
> -	free_nullsafe(dbc);
> -}
> -
> -
> -/**
> - * This function does INSERT SQL queries based on an XML document (sqldata) which contains
> - * all information about table, fields and records to be inserted.  For security and performance,
> - * this function uses prepared SQL statements.
> - *
> - * This function is PostgreSQL specific.
> - *
> - * @param dbc     Database handler to a PostgreSQL
> - * @param sqldoc  sqldata XML document containing the data to be inserted.
> - *
> - * The sqldata XML document must be formated like this:
> - * @code
> - * <sqldata table="{table name}" [key="{field name}">
> - *    <fields>
> - *       <field fid="{integer}">{field name}</field>
> - *       ...
> - *       ...
> - *       <field fid="{integer_n}">{field name 'n'}</field>
> - *    </fields>
> - *    <records>
> - *       <record>
> - *          <value fid="{integer} [type="{data type}"] [hash="{hash type}">{value for field 'fid'</value>
> - *          ...
> - *          ...
> - *          <value fid="{integer_n}">{value for field 'fid_n'</value>
> - *       </record>
> - *       ...
> - *       ...
> - *       ...
> - *    </records>
> - * </sqldata>
> - * @endcode
> - * The 'sqldata' root tag must contain a 'table' attribute.  This must contain the a name of a table
> - * in the database.  If the 'key' attribute is set, the function will return the that field value for
> - * each INSERT query, using INSERT ... RETURNING {field name}.  The sqldata root tag must then have
> - * two children, 'fields' and 'records'.
> - *
> - * The 'fields' tag need to contain 'field' children tags for each field to insert data for.  Each
> - * field in the fields tag must be assigned a unique integer.
> - *
> - * The 'records' tag need to contain 'record' children tags for each record to be inserted.  Each
> - * record tag needs to have 'value' tags for each field which is found in the 'fields' section.
> - *
> - * The 'value' tags must have a 'fid' attribute.  This is the link between the field name in the
> - * 'fields' section and the value to be inserted.
> - *
> - * The 'type' attribute may be used as well, but the only supported data type supported to this
> - * attribute is 'xmlblob'.  In this case, the contents of the 'value' tag must be more XML tags.
> - * These tags will then be serialised to a string which is inserted into the database.
> - *
> - * The 'hash' attribute of the 'value' tag can be set to 'sha1'.  This will make do a SHA1 hash
> - * calculation of the value and this hash value will be used for the insert.
> - *
> - * @return Returns an eurephiaVALUES list containing information about each record which was inserted.
> - *         If the 'key' attribute is not set in the 'sqldata' tag, the OID value of each record will be
> - *         saved.  If the table do not support OIDs, the value will be '0'.  Otherwise the contents of
> - *         the defined field name will be returned.  If one of the INSERT queries fails, it will abort
> - *         further processing and the function will return NULL.
> - */
> -eurephiaVALUES *pgsql_INSERT(dbconn *dbc, xmlDoc *sqldoc) {
> -	xmlNode *root_n = NULL, *fields_n = NULL, *recs_n = NULL, *ptr_n = NULL, *val_n = NULL;
> -	char **field_ar = NULL, *fields = NULL, **value_ar = NULL, *values = NULL, *table = NULL, 
> -		tmp[20], *sql = NULL, *key = NULL, oid[34];
> -
> -	unsigned int fieldcnt = 0, *field_idx, i = 0, schemaver = 0;
> -	PGresult *dbres = NULL;
> -	eurephiaVALUES *res = NULL;
> -
> -	assert( (dbc != NULL) && (sqldoc != NULL) );
> -
> -	root_n = xmlDocGetRootElement(sqldoc);
> -	if( !root_n || (xmlStrcmp(root_n->name, (xmlChar *) "sqldata") != 0) ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Input XML document is not a valid sqldata document", dbc->id);
> -		return NULL;
> -	}
> -
> -	table = xmlGetAttrValue(root_n->properties, "table");
> -	if( !table ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Input XML document is missing table reference", dbc->id);
> -		return NULL;
> -	}
> -
> -	schemaver = sqldataGetRequiredSchemaVer(dbc->log, root_n);
> -	if( schemaver < 100 ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Failed parsing required SQL schema version", dbc->id);
> -		return NULL;
> -	}
> -	if( schemaver > dbc->sqlschemaver ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Cannot process data for the '%s' table.  "
> -			 "The needed SQL schema version is %i, while the database is using version %i",
> -			 dbc->id, table, schemaver, dbc->sqlschemaver);
> -		return NULL;
> -	}
> -
> -	key = xmlGetAttrValue(root_n->properties, "key");
> -
> -	fields_n = xmlFindNode(root_n, "fields");
> -	recs_n = xmlFindNode(root_n, "records");
> -	if( !fields_n || !recs_n ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Input XML document is missing either <fields/> or <records/>",
> -			 dbc->id);
> -		return NULL;
> -	}
> -
> -	// Count number of fields
> -	foreach_xmlnode(fields_n->children, ptr_n) {
> -		if( ptr_n->type == XML_ELEMENT_NODE ) {
> -			fieldcnt++;
> -		}
> -	}
> -
> -	// Generate lists of all fields and a index mapping table
> -	field_idx = calloc(fieldcnt+1, sizeof(unsigned int));
> -	field_ar = calloc(fieldcnt+1, sizeof(char *));
> -	foreach_xmlnode(fields_n->children, ptr_n) {
> -		if( ptr_n->type != XML_ELEMENT_NODE ) {
> -			continue;
> -		}
> -
> -		field_idx[i] = atoi_nullsafe(xmlGetAttrValue(ptr_n->properties, "fid"));
> -		field_ar[i] = xmlExtractContent(ptr_n);
> -		i++;
> -	}
> -
> -	// Generate strings with field names and value place holders
> -	// for a prepared SQL statement
> -	fields = malloc_nullsafe(dbc->log, 3);
> -	values = malloc_nullsafe(dbc->log, 6*(fieldcnt+1));
> -	strcpy(fields, "(");
> -	strcpy(values, "(");
> -	int len = 3;
> -	for( i = 0; i < fieldcnt; i++ ) {
> -		// Prepare VALUES section
> -		snprintf(tmp, 6, "$%i", i+1);
> -		append_str(values, tmp, (6*fieldcnt));
> -
> -		// Prepare fields section
> -		len += strlen_nullsafe(field_ar[i])+2;
> -		fields = realloc(fields, len);
> -		strcat(fields, field_ar[i]);
> -
> -		if( i < (fieldcnt-1) ) {
> -			strcat(fields, ",");
> -			strcat(values, ",");
> -		}
> -	}
> -	strcat(fields, ")");
> -	strcat(values, ")");
> -
> -	// Build up the SQL query
> -	sql = malloc_nullsafe(dbc->log,
> -			      strlen_nullsafe(fields)
> -			      + strlen_nullsafe(values)
> -			      + strlen_nullsafe(table)
> -			      + strlen_nullsafe(key)
> -			      + 34 /* INSERT INTO  VALUES RETURNING*/
> -			      );
> -	sprintf(sql, "INSERT INTO %s %s VALUES %s", table, fields, values);
> -	if( key ) {
> -		strcat(sql, " RETURNING ");
> -		strcat(sql, key);
> -	}
> -
> -	// Create a prepared SQL query
> -#ifdef DEBUG_SQL
> -	writelog(dbc->log, LOG_DEBUG, "[Connection %i] Preparing SQL statement: %s", dbc->id, sql);
> -#endif
> -	dbres = PQprepare(dbc->db, "", sql, fieldcnt, NULL);
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to prepare SQL query: %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		PQclear(dbres);
> -		goto exit;
> -	}
> -	PQclear(dbres);
> -
> -	// Loop through all records and generate SQL statements
> -	res = eCreate_value_space(dbc->log, 1);
> -	memset(&oid, 0, 34);
> -	foreach_xmlnode(recs_n->children, ptr_n) {
> -		if( ptr_n->type != XML_ELEMENT_NODE ) {
> -			continue;
> -		}
> -
> -		// Loop through all value nodes in each record node and get the values for each field
> -		value_ar = calloc(fieldcnt, sizeof(char *));
> -		i = 0;
> -		foreach_xmlnode(ptr_n->children, val_n) {
> -			char *fid_s = NULL;
> -			int fid = -1;
> -
> -			if( i > fieldcnt ) {
> -				break;
> -			}
> -
> -			if( val_n->type != XML_ELEMENT_NODE ) {
> -				continue;
> -			}
> -
> -			fid_s = xmlGetAttrValue(val_n->properties, "fid");
> -			fid = atoi_nullsafe(fid_s);
> -			if( (fid_s == NULL) || (fid < 0) ) {
> -				continue;
> -			}
> -			value_ar[field_idx[i]] = sqldataExtractContent(dbc->log, val_n);
> -			i++;
> -		}
> -
> -		// Insert the record into the database
> -		dbres = PQexecPrepared(dbc->db, "", fieldcnt,
> -				       (const char * const *)value_ar, NULL, NULL, 0);
> -		if( PQresultStatus(dbres) != (key ? PGRES_TUPLES_OK : PGRES_COMMAND_OK) ) {
> -			writelog(dbc->log, LOG_ALERT, "[Connection %i] Failed to do SQL INSERT query: %s",
> -				 dbc->id, PQresultErrorMessage(dbres));
> -			PQclear(dbres);
> -			eFree_values(res);
> -			res = NULL;
> -
> -			// Free up the memory we've used for this record
> -			for( i = 0; i < fieldcnt; i++ ) {
> -				free_nullsafe(value_ar[i]);
> -			}
> -			free_nullsafe(value_ar);
> -			goto exit;
> -		}
> -		if( key ) {
> -			// If the /sqldata/@key attribute was set, fetch the returning ID
> -			eAdd_value(res, key, PQgetvalue(dbres, 0, 0));
> -		} else {
> -			snprintf(oid, 33, "%ld%c", (unsigned long int) PQoidValue(dbres), 0);
> -			eAdd_value(res, "oid", oid);
> -		}
> -		PQclear(dbres);
> -
> -		// Free up the memory we've used for this record
> -		for( i = 0; i < fieldcnt; i++ ) {
> -			free_nullsafe(value_ar[i]);
> -		}
> -		free_nullsafe(value_ar);
> -	}
> -
> - exit:
> -	free_nullsafe(sql);
> -	free_nullsafe(fields);
> -	free_nullsafe(values);
> -	free_nullsafe(field_ar);
> -	free_nullsafe(field_idx);
> -	return res;
> -}
> -
> -/**
> - * @copydoc sqldataValueArray()
> - */
> -static char * pgsql_BuildArray(LogContext *log, xmlNode *sql_n) {
> -	char *ret = NULL, *ptr = NULL;
> -	xmlNode *node = NULL;
> -	size_t retlen = 0;
> -
> -	ret = malloc_nullsafe(log, 2);
> -	if( ret == NULL ) {
> -		writelog(log, LOG_ERR,
> -			 "Failed to allocate memory for a new PostgreSQL array");
> -		return NULL;
> -	}
> -	strncat(ret, "{", 1);
> -
> -	/* Iterate all ./value/value elements and build up a PostgreSQL specific array */
> -	foreach_xmlnode(sql_n->children, node) {
> -		if( (node->type != XML_ELEMENT_NODE)
> -		    || xmlStrcmp(node->name, (xmlChar *) "value") != 0 ) {
> -			// Skip uninteresting nodes
> -			continue;
> -		}
> -		ptr = sqldataValueHash(log, node);
> -		if( ptr ) {
> -			retlen += strlen(ptr) + 4;
> -			ret = realloc(ret, retlen);
> -			if( ret == NULL ) {
> -				writelog(log, LOG_ERR,
> -					 "Failed to allocate memory to expand "
> -					 "array to include '%s'", ptr);
> -				free_nullsafe(ret);
> -				free_nullsafe(ptr);
> -				return NULL;
> -			}
> -			/* Newer PostgreSQL servers expects numbers to be without quotes */
> -			if( isNumber(ptr) == 0 ) {
> -				/* Data is a string */
> -				strncat(ret, "'", 1);
> -				strncat(ret, ptr, strlen(ptr));
> -				strncat(ret, "',", 2);
> -			} else {
> -				/* Data is a number */
> -				strncat(ret, ptr, strlen(ptr));
> -				strncat(ret, ",", 1);
> -			}
> -			free_nullsafe(ptr);
> -		}
> -	}
> -	/* Replace the last comma with a close-array marker */
> -	ret[strlen(ret)-1] = '}';
> -	ret[strlen(ret)] = 0;
> -	return ret;
> -}
> -
> -
> -/**
> - * Start an SQL transaction (SQL BEGIN)
> - *
> - * @param dbc Database handler where to perform the SQL queries
> - *
> - * @return Returns 1 on success, otherwise -1 is returned
> - */
> -int db_begin(dbconn *dbc) {
> -	PGresult *dbres = NULL;
> -
> -	dbres = PQexec(dbc->db, "BEGIN");
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to do prepare a transaction (BEGIN): %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		PQclear(dbres);
> -		return -1;
> -	}
> -	PQclear(dbres);
> -	return 1;
> -}
> -
> -
> -/**
> - * Commits an SQL transaction (SQL COMMIT)
> - *
> - * @param dbc Database handler where to perform the SQL queries
> - *
> - * @return Returns 1 on success, otherwise -1 is returned
> - */
> -int db_commit(dbconn *dbc) {
> -	PGresult *dbres = NULL;
> -
> -	dbres = PQexec(dbc->db, "COMMIT");
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to do commit a database transaction (COMMIT): %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		PQclear(dbres);
> -		return -1;
> -	}
> -	PQclear(dbres);
> -	return 1;
> -}
> -
> -
> -/**
> - * Aborts an SQL transaction (SQL ROLLBACK/ABORT)
> - *
> - * @param dbc Database handler where to perform the SQL queries
> - *
> - * @return Returns 1 on success, otherwise -1 is returned
> - */
> -int db_rollback(dbconn *dbc) {
> -	PGresult *dbres = NULL;
> -
> -	dbres = PQexec(dbc->db, "ROLLBACK");
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_CRIT,
> -			 "[Connection %i] Failed to do abort/rollback a transaction (ROLLBACK): %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		PQclear(dbres);
> -		return -1;
> -	}
> -	PQclear(dbres);
> -	return 1;
> -}
> -
> -
> -/**
> - * This function blocks until a notification is received from the database
> - *
> - * @param dbc        Database connection
> - * @param shutdown   Pointer to the shutdown flag.  Used to avoid reporting false errors.
> - * @param listenfor  Name to be used when calling LISTEN
> - *
> - * @return Returns 1 on successful waiting, otherwise -1
> - */
> -int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor) {
> -	int sock, ret = 0;
> -	PGresult *dbres = NULL;
> -	PGnotify *notify = NULL;
> -	fd_set input_mask;
> -	char *sql = NULL;
> -
> -	sql = malloc_nullsafe(dbc->log, strlen_nullsafe(listenfor) + 12);
> -	assert( sql != NULL );
> -
> -	// Initiate listening
> -	sprintf(sql, "LISTEN %s", listenfor);
> -	dbres = PQexec(dbc->db, sql);
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT, "[Connection %i] SQL %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		free_nullsafe(sql);
> -		PQclear(dbres);
> -		return -1;
> -	}
> -	PQclear(dbres);
> -
> -	// Start listening and waiting
> -	while( ret == 0 ) {
> -		sock = PQsocket(dbc->db);
> -		if (sock < 0) {
> -			// shouldn't happen
> -			ret = -1;
> -			break;
> -		}
> -
> -		// Wait for something to happen on the database socket
> -		FD_ZERO(&input_mask);
> -		FD_SET(sock, &input_mask);
> -		if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) {
> -			// If the shutdown flag is set, select() will fail due to a signal.  Only
> -			// report errors if we're not shutting down, or else exit normally with
> -			// successful waiting.
> -			if( *shutdown == 0 ) {
> -				writelog(dbc->log, LOG_CRIT, "[Connection %i] select() failed: %s",
> -					 dbc->id, strerror(errno));
> -				ret = -1;
> -				goto exit;
> -			} else {
> -				ret = 1;
> -			}
> -			break;
> -		}
> -
> -		// Process the event
> -		PQconsumeInput(dbc->db);
> -
> -		// Check if connection still is valid
> -		if( PQstatus(dbc->db) != CONNECTION_OK ) {
> -			PQreset(dbc->db);
> -			if( PQstatus(dbc->db) != CONNECTION_OK ) {
> -				writelog(dbc->log, LOG_EMERG,
> -					 "[Connection %i] Database connection died: %s",
> -					 dbc->id, PQerrorMessage(dbc->db));
> -				ret = -1;
> -				goto exit;
> -			}
> -			writelog(dbc->log, LOG_CRIT,
> -				 "[Connection %i] Database connection restored", dbc->id);
> -		}
> -
> -		while ((notify = PQnotifies(dbc->db)) != NULL) {
> -			// If a notification was received, inform and exit with success.
> -			writelog(dbc->log, LOG_DEBUG,
> -				 "[Connection %i] Received notfication from pid %d",
> -				 dbc->id, notify->be_pid);
> -			PQfreemem(notify);
> -			ret = 1;
> -			break;
> -		}
> -	}
> -
> -	// Stop listening when we exit
> -	sprintf(sql, "UNLISTEN %s", listenfor);
> -	dbres = PQexec(dbc->db, sql);
> -	if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT, "[Connection %i] SQL %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		free_nullsafe(sql);
> -		ret = -1;
> -	}
> -	free_nullsafe(sql);
> -	PQclear(dbres);
> -
> - exit:
> -	return ret;
> -}
> -
> -
> -/**
> - * Retrive the first available submitted report
> - *
> - * @param dbc   Database connection
> - * @param mtx   pthread_mutex to avoid parallel access to the submission queue table, to avoid
> - *              the same job being retrieved multiple times.
> - *
> - * @return Returns a pointer to a parseJob_t struct, with the parse job info on success, otherwise NULL
> - */
> -parseJob_t *db_get_submissionqueue_job(dbconn *dbc, pthread_mutex_t *mtx) {
> -	parseJob_t *job = NULL;
> -	PGresult *res = NULL;
> -	char sql[4098];
> -
> -	job = (parseJob_t *) malloc_nullsafe(dbc->log, sizeof(parseJob_t));
> -
> -	// Get the first available submission
> -	memset(&sql, 0, 4098);
> -	snprintf(sql, 4096,
> -		 "SELECT submid, filename, clientid"
> -		 "  FROM submissionqueue"
> -		 " WHERE status = %i"
> -		 " ORDER BY submid"
> -		 " LIMIT 1",
> -		 STAT_NEW);
> -
> -	pthread_mutex_lock(mtx);
> -	res = PQexec(dbc->db, sql);
> -	if( PQresultStatus(res) != PGRES_TUPLES_OK ) {
> -		pthread_mutex_unlock(mtx);
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to query submission queue (SELECT): %s",
> -			 dbc->id, PQresultErrorMessage(res));
> -		PQclear(res);
> -		free_nullsafe(job);
> -		return NULL;
> -	}
> -
> -	if( PQntuples(res) == 1 ) {
> -		job->status = jbAVAIL;
> -		job->submid = atoi_nullsafe(PQgetvalue(res, 0, 0));
> -		snprintf(job->filename, 4095, "%.4094s", PQgetvalue(res, 0, 1));
> -		snprintf(job->clientid,  255, "%.254s", PQgetvalue(res, 0, 2));
> -
> -		// Update the submission queue status
> -		if( db_update_submissionqueue(dbc, job->submid, STAT_ASSIGNED) < 1 ) {
> -			pthread_mutex_unlock(mtx);
> -			writelog(dbc->log, LOG_ALERT, "[Connection %i] Failed to update "
> -				 "submission queue statis to STAT_ASSIGNED", dbc->id);
> -			free_nullsafe(job);
> -			return NULL;
> -		}
> -	} else {
> -		job->status = jbNONE;
> -	}
> -	pthread_mutex_unlock(mtx);
> -	PQclear(res);
> -	return job;
> -}
> -
> -
> -/**
> - * Updates the submission queue table with the new status and the appropriate timestamps
> - *
> - * @param dbc     Database handler to the rteval database
> - * @param submid  Submission ID to update
> - * @param status  The new status
> - *
> - * @return Returns 1 on success, 0 on invalid status ID and -1 on database errors.
> - */
> -int db_update_submissionqueue(dbconn *dbc, unsigned int submid, int status) {
> -	PGresult *res = NULL;
> -	char sql[4098];
> -
> -	memset(&sql, 0, 4098);
> -	switch( status ) {
> -	case STAT_ASSIGNED:
> -	case STAT_RTERIDREG:
> -	case STAT_REPMOVE:
> -	case STAT_XMLFAIL:
> -	case STAT_FTOOBIG:
> -		snprintf(sql, 4096,
> -			 "UPDATE submissionqueue SET status = %i"
> -			 " WHERE submid = %i", status, submid);
> -		break;
> -
> -	case STAT_INPROG:
> -		snprintf(sql, 4096,
> -			 "UPDATE submissionqueue SET status = %i, parsestart = NOW()"
> -			 " WHERE submid = %i", status, submid);
> -		break;
> -
> -	case STAT_SUCCESS:
> -	case STAT_UNKNFAIL:
> -	case STAT_SYSREG:
> -	case STAT_GENDB:
> -	case STAT_RTEVRUNS:
> -	case STAT_MEASURE:
> -		snprintf(sql, 4096,
> -			 "UPDATE submissionqueue SET status = %i, parseend = NOW() WHERE submid = %i",
> -			 status, submid);
> -		break;
> -
> -	default:
> -	case STAT_NEW:
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Invalid status (%i) attempted to set on submid %i",
> -			 dbc->id, status, submid);
> -		return 0;
> -	}
> -
> -	res = PQexec(dbc->db, sql);
> -	if( !res ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Unkown error when updating submid %i to status %i",
> -			 dbc->id, submid, status);
> -		return -1;
> -	} else if( PQresultStatus(res) != PGRES_COMMAND_OK ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to UPDATE submissionqueue (submid: %i, status: %i): %s",
> -			 dbc->id, submid, status, PQresultErrorMessage(res));
> -		PQclear(res);
> -		return -1;
> -	}
> -	PQclear(res);
> -	return 1;
> -}
> -
> -
> -/**
> - * Registers information into the 'systems' and 'systems_hostname' tables, based on the
> - * summary/report XML file from rteval.
> - *
> - * @param dbc        Database handler where to perform the SQL queries
> - * @param xslt       A pointer to a parsed 'xmlparser.xsl' XSLT template
> - * @param summaryxml The XML report from rteval
> - *
> - * @return Returns a value > 0 on success, which is a unique reference to the system of the report.
> - *         If the function detects that this system is already registered, the 'syskey' reference will
> - *         be reused.  On errors, -1 will be returned.
> - */
> -int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml) {
> -	PGresult *dbres = NULL;
> -	eurephiaVALUES *dbdata = NULL;
> -	xmlDoc *sysinfo_d = NULL, *hostinfo_d = NULL;
> -	parseParams prms;
> -	char sqlq[4098];
> -	char *sysid = NULL;  // SHA1 value of the system id
> -	char *ipaddr = NULL, *hostname = NULL;
> -	int syskey = -1;
> -
> -	memset(&prms, 0, sizeof(parseParams));
> -	prms.table = "systems";
> -	sysinfo_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms);
> -	if( !sysinfo_d ) {
> -		writelog(dbc->log, LOG_ERR, "[Connection %i] Could not parse the input XML data", dbc->id);
> -		syskey= -1;
> -		goto exit;
> -	}
> -	sysid = sqldataGetValue(dbc->log, sysinfo_d, "sysid", 0);
> -	if( !sysid ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Could not retrieve the sysid field from the input XML", dbc->id);
> -		syskey= -1;
> -		goto exit;
> -	}
> -
> -	memset(&sqlq, 0, 4098);
> -	snprintf(sqlq, 4096, "SELECT syskey FROM systems WHERE sysid = '%.256s'", sysid);
> -	free_nullsafe(sysid);
> -	dbres = PQexec(dbc->db, sqlq);
> -	if( PQresultStatus(dbres) != PGRES_TUPLES_OK ) {
> -		writelog(dbc->log, LOG_ALERT, "[Connection %i] SQL %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -		writelog(dbc->log, LOG_DEBUG, "[Connection %i] Failing SQL query: %s",
> -			 dbc->id, sqlq);
> -		PQclear(dbres);
> -		syskey= -1;
> -		goto exit;
> -	}
> -
> -	if( PQntuples(dbres) == 0 ) {  // No record found, need to register this system
> -		PQclear(dbres);
> -
> -		dbdata = pgsql_INSERT(dbc, sysinfo_d);
> -		if( !dbdata ) {
> -			syskey= -1;
> -			goto exit;
> -		}
> -		if( (eCount(dbdata) != 1) || !dbdata->val ) { // Only one record should be registered
> -			writelog(dbc->log, LOG_ALERT,
> -				 "[Connection %i] Failed to register the system", dbc->id);
> -			eFree_values(dbdata);
> -			syskey= -1;
> -			goto exit;
> -		}
> -		syskey = atoi_nullsafe(dbdata->val);
> -		hostinfo_d = sqldataGetHostInfo(dbc->log, xslt, summaryxml, syskey, &hostname, &ipaddr);
> -		if( !hostinfo_d ) {
> -			syskey = -1;
> -			goto exit;
> -		}
> -		eFree_values(dbdata);
> -
> -		dbdata = pgsql_INSERT(dbc, hostinfo_d);
> -		syskey = (dbdata ? syskey : -1);
> -		eFree_values(dbdata);
> -
> -	} else if( PQntuples(dbres) == 1 ) { // System found - check if the host IP is known or not
> -		syskey = atoi_nullsafe(PQgetvalue(dbres, 0, 0));
> -		hostinfo_d = sqldataGetHostInfo(dbc->log, xslt, summaryxml, syskey, &hostname, &ipaddr);
> -		if( !hostinfo_d ) {
> -			syskey = -1;
> -			goto exit;
> -		}
> -		PQclear(dbres);
> -
> -		// Check if this hostname and IP address is registered
> -		snprintf(sqlq, 4096,
> -			 "SELECT syskey FROM systems_hostname"
> -			 " WHERE hostname='%.256s'",
> -			 hostname);
> -
> -		if( ipaddr ) {
> -			append_str(sqlq, "AND ipaddr='", 4028);
> -			append_str(sqlq, ipaddr, 4092);
> -			append_str(sqlq, "'", 4096);
> -		} else {
> -			append_str(sqlq, "AND ipaddr IS NULL", 4096);
> -		}
> -
> -		dbres = PQexec(dbc->db, sqlq);
> -		if( PQresultStatus(dbres) != PGRES_TUPLES_OK ) {
> -			writelog(dbc->log, LOG_ALERT, "[Connection %i] SQL %s",
> -				 dbc->id, PQresultErrorMessage(dbres));
> -			writelog(dbc->log, LOG_DEBUG, "[Connection %i] Failing SQL query: %s",
> -				 dbc->id, sqlq);
> -			PQclear(dbres);
> -			syskey= -1;
> -			goto exit;
> -		}
> -
> -		if( PQntuples(dbres) == 0 ) { // Not registered, then register it
> -			dbdata = pgsql_INSERT(dbc, hostinfo_d);
> -			syskey = (dbdata ? syskey : -1);
> -			eFree_values(dbdata);
> -		}
> -		PQclear(dbres);
> -	} else {
> -		// Critical -- system IDs should not be registered more than once
> -		writelog(dbc->log, LOG_CRIT, "[Connection %i] Multiple systems registered (%s)",
> -			 dbc->id, sqlq);
> -		syskey= -1;
> -	}
> -
> - exit:
> -	free_nullsafe(hostname);
> -	free_nullsafe(ipaddr);
> -	if( sysinfo_d ) {
> -		xmlFreeDoc(sysinfo_d);
> -	}
> -	if( hostinfo_d ) {
> -		xmlFreeDoc(hostinfo_d);
> -	}
> -	return syskey;
> -}
> -
> -
> -/**
> - * Retrieves the next available rteval run ID (rterid)
> - *
> - * @param dbc  Database handler where to perform the SQL query
> - *
> - * @return Returns a value > 0 on success, containing the assigned rterid value.  Otherwise -1 is returned.
> - */
> -int db_get_new_rterid(dbconn *dbc) {
> -	PGresult *dbres = NULL;
> -	int rterid = 0;
> -
> -	dbres = PQexec(dbc->db, "SELECT nextval('rtevalruns_rterid_seq')");
> -	if( (PQresultStatus(dbres) != PGRES_TUPLES_OK) || (PQntuples(dbres) != 1) ) {
> -		rterid = -1;
> -	} else {
> -		rterid = atoi_nullsafe(PQgetvalue(dbres, 0, 0));
> -	}
> -
> -	if( rterid < 1 ) {
> -		writelog(dbc->log, LOG_CRIT,
> -			 "[Connection %i] Failed to retrieve a new rterid value", dbc->id);
> -	}
> -	if( rterid < 0 ) {
> -		writelog(dbc->log, LOG_ALERT, "[Connection %i] SQL %s",
> -			 dbc->id, PQresultErrorMessage(dbres));
> -	}
> -	PQclear(dbres);
> -	return rterid;
> -}
> -
> -
> -/**
> - * Registers information into the 'rtevalruns' and 'rtevalruns_details' tables
> - *
> - * @param dbc           Database handler where to perform the SQL queries
> - * @param xslt          A pointer to a parsed 'xmlparser.xsl' XSLT template
> - * @param summaryxml    The XML report from rteval
> - * @param submid        Submission ID, referencing the record in the submissionqueue table.
> - * @param syskey        A positive integer containing the return value from db_register_system()
> - * @param rterid        A positive integer containing the return value from db_get_new_rterid()
> - * @param report_fname  A string containing the filename of the report.
> - *
> - * @return Returns 1 on success, otherwise -1 is returned.
> - */
> -int db_register_rtevalrun(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml,
> -			  unsigned int submid, int syskey, int rterid, const char *report_fname)
> -{
> -	int ret = -1;
> -	xmlDoc *rtevalrun_d = NULL, *rtevalrundets_d = NULL;
> -	parseParams prms;
> -	eurephiaVALUES *dbdata = NULL;
> -
> -	// Parse the rtevalruns information
> -	memset(&prms, 0, sizeof(parseParams));
> -	prms.table = "rtevalruns";
> -	prms.syskey = syskey;
> -	prms.rterid = rterid;
> -	prms.submid = submid;
> -	prms.report_filename = report_fname;
> -	rtevalrun_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms);
> -	if( !rtevalrun_d ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Could not parse the input XML data", dbc->id);
> -		ret = -1;
> -		goto exit;
> -	}
> -
> -	// Register the rteval run information
> -	dbdata = pgsql_INSERT(dbc, rtevalrun_d);
> -	if( !dbdata ) {
> -		ret = -1;
> -		goto exit;
> -	}
> -
> -	if( eCount(dbdata) != 1 ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to register the rteval run", dbc->id);
> -		ret = -1;
> -		eFree_values(dbdata);
> -		goto exit;
> -	}
> -	eFree_values(dbdata);
> -
> -	// Parse the rtevalruns_details information
> -	memset(&prms, 0, sizeof(parseParams));
> -	prms.table = "rtevalruns_details";
> -	prms.rterid = rterid;
> -	rtevalrundets_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms);
> -	if( !rtevalrundets_d ) {
> -		writelog(dbc->log, LOG_ERR,
> -			 "[Connection %i] Could not parse the input XML data (rtevalruns_details)",
> -			 dbc->id);
> -		ret = -1;
> -		goto exit;
> -	}
> -
> -	// Register the rteval_details information
> -	dbdata = pgsql_INSERT(dbc, rtevalrundets_d);
> -	if( !dbdata ) {
> -		ret = -1;
> -		goto exit;
> -	}
> -
> -	// Check that only one record was inserted
> -	if( eCount(dbdata) != 1 ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] Failed to register the rteval run details", dbc->id);
> -		ret = -1;
> -	}
> -	eFree_values(dbdata);
> -	ret = 1;
> - exit:
> -	if( rtevalrun_d ) {
> -		xmlFreeDoc(rtevalrun_d);
> -	}
> -	if( rtevalrundets_d ) {
> -		xmlFreeDoc(rtevalrundets_d);
> -	}
> -	return ret;
> -}
> -
> -
> -/**
> - * Registers data returned from measurement results into the database.
> - *
> - * @param dbc        Database handler where to perform the SQL queries
> - * @param xslt       A pointer to a parsed 'xmlparser.xsl' XSLT template
> - * @param summaryxml The XML report from rteval
> - * @param rterid     A positive integer referencing the rteval run ID, returned from db_register_rtevalrun()
> - *
> - * @return Returns 1 on success, otherwise -1
> - */
> -int db_register_measurements(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml, int rterid) {
> -	int result = -1;
> -	xmlDoc *meas_d = NULL;
> -	parseParams prms;
> -	eurephiaVALUES *dbdata = NULL;
> -	int measrecs = 0;
> -        char *tbl = NULL;
> -	int i;
> -
> -	memset(&prms, 0, sizeof(parseParams));
> -	prms.rterid = rterid;
> -
> -	// Loop through all configured measurement tables and process each table
> -        i = 0;
> -        for_array_str(tbl, i, dbc->measurement_tbls) {
> -                writelog(dbc->log, LOG_DEBUG, "Processing measurement table '%s'", tbl);
> -		prms.table = tbl;
> -		meas_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms);
> -		if( meas_d && meas_d->children ) {
> -			// Insert SQL data which was found and generated
> -			dbdata = pgsql_INSERT(dbc, meas_d);
> -			if( !dbdata ) {
> -				result = -1;
> -				xmlFreeDoc(meas_d);
> -				goto exit;
> -			}
> -
> -			if (eCount(dbdata) > 0) {
> -				measrecs++;
> -			}
> -			eFree_values(dbdata);
> -		}
> -		if( meas_d ) {
> -			xmlFreeDoc(meas_d);
> -		}
> -	}
> -
> -	// Report error if not enough cyclictest data is registered.
> -	if( measrecs < 1 ) {
> -		writelog(dbc->log, LOG_ALERT,
> -			 "[Connection %i] No cyclictest raw data or histogram data registered", dbc->id);
> -		result = -1;
> -	} else {
> -		result = 1;
> -	}
> - exit:
> -	return result;
> -}
> diff --git a/server/parser/pgsql.h b/server/parser/pgsql.h
> deleted file mode 100644
> index d8be135..0000000
> --- a/server/parser/pgsql.h
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   pgsql.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 13 17:44:35 2009
> - *
> - * @brief  Database API for the PostgreSQL database.
> - *
> - *
> - */
> -
> -#ifndef _RTEVAL_PGSQL_H
> -#define _RTEVAL_PGSQL_H
> -
> -#include <libpq-fe.h>
> -#include <libxml/parser.h>
> -#include <libxslt/transform.h>
> -
> -#include <log.h>
> -#include <eurephia_values.h>
> -#include <parsethread.h>
> -#include <xmlparser.h>
> -
> -/**
> - *  A unified database abstraction layer, providing log support
> - */
> -typedef struct {
> -	unsigned int id;           /**< Unique connection ID, used for debugging */
> -	LogContext *log;           /**< Initialised log context */
> -	PGconn *db;                /**< Database connection handler */
> -	unsigned int sqlschemaver; /**< SQL schema version, retrieved from rteval_info table */
> -	array_str_t *measurement_tbls; /**< Measurement tables to process */
> -} dbconn;
> -
> -/* Generic database function */
> -dbconn *db_connect(eurephiaVALUES *cfg, unsigned int id, LogContext *log);
> -int db_ping(dbconn *dbc);
> -void db_disconnect(dbconn *dbc);
> -int db_begin(dbconn *dbc);
> -int db_commit(dbconn *dbc);
> -int db_rollback(dbconn *dbc);
> -
> -/* rteval specific database functions */
> -int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor);
> -parseJob_t *db_get_submissionqueue_job(dbconn *dbc, pthread_mutex_t *mtx);
> -int db_update_submissionqueue(dbconn *dbc, unsigned int submid, int status);
> -int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml);
> -int db_get_new_rterid(dbconn *dbc);
> -int db_register_rtevalrun(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml,
> -			  unsigned int submid, int syskey, int rterid, const char *report_fname);
> -int db_register_measurements(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml, int rterid);
> -
> -#endif
> diff --git a/server/parser/rteval-parserd.c b/server/parser/rteval-parserd.c
> deleted file mode 100644
> index 7aba85d..0000000
> --- a/server/parser/rteval-parserd.c
> +++ /dev/null
> @@ -1,533 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   rteval-parserd.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 15 11:59:27 2009
> - *
> - * @brief  Polls the rteval.submissionqueue table for notifications
> - *         from new inserts and sends the file to a processing thread
> - *
> - *
> - *
> - */
> -
> -#include <stdio.h>
> -#include <string.h>
> -#include <unistd.h>
> -#include <signal.h>
> -#include <pthread.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -#include <errno.h>
> -#include <assert.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <eurephia_values.h>
> -#include <configparser.h>
> -#include <pgsql.h>
> -#include <threadinfo.h>
> -#include <parsethread.h>
> -#include <argparser.h>
> -
> -#define DEFAULT_MSG_MAX 5             /**< Default size of the message queue */
> -#define XMLPARSER_XSL "xmlparser.xsl" /**< rteval report parser XSLT, parses XML into database friendly data*/
> -
> -static int shutdown = 0;              /**<  Variable indicating if the program should shutdown */
> -static LogContext *logctx = NULL;     /**<  Initialsed log context, to be used by sigcatch() */
> -
> -
> -/**
> - * Simple signal catcher.  Used for SIGINT and SIGTERM signals, and will set the global shutdown
> - * shutdown flag.  It's expected that all threads behaves properly and exits as soon as their current
> - * work is completed
> - *
> - * @param sig Recieved signal (not used)
> - */
> -void sigcatch(int sig) {
> -	switch( sig ) {
> -	case SIGINT:
> -	case SIGTERM:
> -		if( shutdown == 0 ) {
> -			shutdown = 1;
> -			writelog(logctx, LOG_INFO, "[SIGNAL] Shutting down");
> -		} else {
> -			writelog(logctx, LOG_INFO, "[SIGNAL] Shutdown in progress ... please be patient ...");
> -		}
> -		break;
> -
> -	case SIGUSR1:
> -		writelog(logctx, LOG_EMERG, "[SIGNAL] Shutdown alarm from a worker thread");
> -		shutdown = 1;
> -		break;
> -
> -	default:
> -		break;
> -	}
> -
> -	// re-enable signals, to avoid brute force exits.
> -	// If brute force is needed, SIGKILL is available.
> -	signal(sig, sigcatch);
> -}
> -
> -
> -/**
> - * Opens and reads /proc/sys/fs/mqueue/msg_max, to get the maximum number of allowed messages
> - * on POSIX MQ queues.  rteval-parserd will use as much of this as possible when needed.
> - *
> - * @return Returns the system msg_max value, or DEFAULT_MSG_MAX on failure to read the setting.
> - */
> -unsigned int get_mqueue_msg_max(LogContext *log) {
> -	FILE *fp = NULL;
> -	char buf[130];
> -	unsigned int msg_max = DEFAULT_MSG_MAX;
> -
> -	fp = fopen("/proc/sys/fs/mqueue/msg_max", "r");
> -	if( !fp ) {
> -		writelog(log, LOG_WARNING,
> -			"Could not open /proc/sys/fs/mqueue/msg_max, defaulting to %i",
> -			msg_max);
> -		writelog(log, LOG_INFO, "%s", strerror(errno));
> -		return msg_max;
> -	}
> -
> -	memset(&buf, 0, 130);
> -	if( fread(&buf, 1, 128, fp) < 1 ) {
> -		writelog(log, LOG_WARNING,
> -			"Could not read /proc/sys/fs/mqueue/msg_max, defaulting to %i",
> -			msg_max);
> -		writelog(log, LOG_INFO, "%s", strerror(errno));
> -	} else {
> -		msg_max = atoi_nullsafe(buf);
> -		if( msg_max < 1 ) {
> -			msg_max = DEFAULT_MSG_MAX;
> -			writelog(log, LOG_WARNING,
> -				"Failed to parse /proc/sys/fs/mqueue/msg_max,"
> -				"defaulting to %i", msg_max);
> -		}
> -	}
> -	fclose(fp);
> -	return msg_max;
> -}
> -
> -
> -/**
> - * Main loop, which polls the submissionqueue table and puts jobs found here into a POSIX MQ queue
> - * which the worker threads will pick up.
> - *
> - * @param dbc           Database connection, where to query the submission queue
> - * @param msgq          file descriptor for the message queue
> - * @param activethreads Pointer to an int value containing active worker threads.  Each thread updates
> - *                      this value directly, and this function should only read it.
> - *
> - * @return Returns 0 on successful run, otherwise > 0 on errors.
> - */
> -int process_submission_queue(dbconn *dbc, mqd_t msgq, int *activethreads) {
> -	pthread_mutex_t mtx_submq = PTHREAD_MUTEX_INITIALIZER;
> -	parseJob_t *job = NULL;
> -	int rc = 0, i, actthr_cp = 0;
> -
> -	while( shutdown == 0 ) {
> -		// Check status if the worker threads
> -		// If we don't have any worker threads, shut down immediately
> -		writelog(dbc->log, LOG_DEBUG, "Active worker threads: %i", *activethreads);
> -		if( *activethreads < 1 ) {
> -			writelog(dbc->log, LOG_EMERG,
> -				 "All worker threads ceased to exist.  Shutting down!");
> -			shutdown = 1;
> -			rc = 1;
> -			goto exit;
> -		}
> -
> -		if( db_ping(dbc) != 1 ) {
> -			writelog(dbc->log, LOG_EMERG, "Lost connection to database.  Shutting down!");
> -			shutdown = 1;
> -			rc = 1;
> -			goto exit;
> -		}
> -
> -		// Fetch an available job
> -		job = db_get_submissionqueue_job(dbc, &mtx_submq);
> -		if( !job ) {
> -			writelog(dbc->log, LOG_EMERG,
> -				 "Failed to get submission queue job.  Shutting down!");
> -			shutdown = 1;
> -			rc = 1;
> -			goto exit;
> -		}
> -		if( job->status == jbNONE ) {
> -			free_nullsafe(job);
> -			if( db_wait_notification(dbc, &shutdown, "rteval_submq") < 1 ) {
> -				writelog(dbc->log, LOG_EMERG,
> -					 "Failed to wait for DB notification.  Shutting down!");
> -				shutdown = 1;
> -				rc = 1;
> -				goto exit;
> -			}
> -			continue;
> -		}
> -
> -		// Send the job to the queue
> -		writelog(dbc->log, LOG_DEBUG, "** New job queued: submid %i, %s", job->submid, job->filename);
> -		do {
> -			int res;
> -
> -			errno = 0;
> -			res = mq_send(msgq, (char *) job, sizeof(parseJob_t), 1);
> -			if( (res < 0) && (errno != EAGAIN) ) {
> -				writelog(dbc->log, LOG_EMERG,
> -					 "Could not send parse job to the queue.  "
> -					 "Shutting down!");
> -				shutdown = 1;
> -				rc = 2;
> -				goto exit;
> -			} else if( errno == EAGAIN ) {
> -				writelog(dbc->log, LOG_WARNING,
> -					"Message queue filled up.  "
> -					"Will not add new messages to queue for the next 60 seconds");
> -				sleep(60);
> -			}
> -		} while( (errno == EAGAIN) );
> -		free_nullsafe(job);
> -	}
> -
> - exit:
> -	// Send empty messages to the threads, to make them have a look at the shutdown flag
> -	job = (parseJob_t *) malloc_nullsafe(dbc->log, sizeof(parseJob_t));
> -	errno = 0;
> -	// Need to make a copy, as *activethreads will change when threads completes shutdown
> -	actthr_cp = *activethreads;
> -	for( i = 0; i < actthr_cp; i++ ) {
> -		do {
> -			int res;
> -
> -			writelog(dbc->log, LOG_DEBUG, "%s shutdown message %i of %i",
> -				 (errno == EAGAIN ? "Resending" : "Sending"), i+1, *activethreads);
> -			errno = 0;
> -			res = mq_send(msgq, (char *) job, sizeof(parseJob_t), 1);
> -			if( (res < 0) && (errno != EAGAIN) ) {
> -				writelog(dbc->log, LOG_EMERG,
> -					 "Could not send shutdown notification to the queue.");
> -				free_nullsafe(job);
> -				return rc;
> -			} else if( errno == EAGAIN ) {
> -				writelog(dbc->log, LOG_WARNING,
> -					"Message queue filled up.  "
> -					"Will not add new messages to queue for the next 10 seconds");
> -				sleep(10);
> -			}
> -		} while( (errno == EAGAIN) );
> -	}
> -	free_nullsafe(job);
> -	return rc;
> -}
> -
> -
> -/**
> - * Prepares the program to be daemonised
> - *
> - * @param log   Initialised log context, where log info of the process is reported
> - *
> - * @return Returns 1 on success, otherwise -1
> - */
> -int daemonise(LogContext *log) {
> -	pid_t pid, sid;
> -	int i = 0;
> -
> -	if( (log->logtype == ltCONSOLE) ) {
> -		writelog(log, LOG_EMERG,
> -			 "Cannot daemonise when logging to a console (stdout: or stderr:)");
> -		return -1;
> -	}
> -
> -	pid = fork();
> -	if (pid < 0) {
> -		writelog(log, LOG_EMERG, "Failed to daemonise the process (fork)");
> -		return -1;
> -	} else if (pid > 0) {
> -		writelog(log, LOG_INFO, "Daemon pid: %ld", pid);
> -		exit(EXIT_SUCCESS);
> -	}
> -
> -	umask(0);
> -
> -	sid = setsid();
> -	if (sid < 0) {
> -		writelog(log, LOG_EMERG, "Failed to daemonise the process (setsid)");
> -		return -1;
> -	}
> -
> -	if ((chdir("/")) < 0) {
> -		writelog(log, LOG_EMERG, "Failed to daemonise the process (fork)");
> -		return -1;
> -	}
> -
> -	// Prepare stdin, stdout and stderr for daemon mode
> -	close(2);
> -	close(1);
> -	close(0);
> -	i = open("/dev/null", O_RDWR); /* open stdin */
> -	dup(i); /* stdout */
> -	dup(i); /* stderr */
> -
> -	writelog(log, LOG_INFO, "Daemonised successfully");
> -	return 1;
> -}
> -
> -
> -/**
> - * rtevald_parser main function.
> - *
> - * @param argc
> - * @param argv
> - *
> - * @return Returns the result of the process_submission_queue() function.
> - */
> -int main(int argc, char **argv) {
> -        eurephiaVALUES *config = NULL, *prgargs = NULL;
> -        char xsltfile[2050], *reportdir = NULL;
> -	xsltStylesheet *xslt = NULL;
> -	dbconn *dbc = NULL;
> -        pthread_t **threads = NULL;
> -        pthread_attr_t **thread_attrs = NULL;
> -	pthread_mutex_t mtx_sysreg = PTHREAD_MUTEX_INITIALIZER;
> -	pthread_mutex_t mtx_thrcnt = PTHREAD_MUTEX_INITIALIZER;
> -	threadData_t **thrdata = NULL;
> -	struct mq_attr msgq_attr;
> -	mqd_t msgq = 0;
> -	int i,rc, mq_init = 0, max_threads = 0, started_threads = 0, activethreads = 0;
> -	unsigned int max_report_size = 0;
> -
> -	// Initialise XML and XSLT libraries
> -	xsltInit();
> -	xmlInitParser();
> -
> -	prgargs = parse_arguments(argc, argv);
> -	if( prgargs == NULL ) {
> -		fprintf(stderr, "** ERROR **  Failed to parse program arguments\n");
> -		rc = 2;
> -		goto exit;
> -	}
> -
> -	// Setup a log context
> -	logctx = init_log(eGet_value(prgargs, "log"), eGet_value(prgargs, "loglevel"));
> -	if( !logctx ) {
> -		fprintf(stderr, "** ERROR **  Could not setup a log context\n");
> -		eFree_values(prgargs);
> -		rc = 2;
> -		goto exit;
> -	}
> -
> -	// Fetch configuration
> -        config = read_config(logctx, prgargs, "xmlrpc_parser");
> -	eFree_values(prgargs); // read_config() copies prgargs into config, we don't need prgargs anymore
> -
> -	// Daemonise process if requested
> -	if( atoi_nullsafe(eGet_value(config, "daemon")) == 1 ) {
> -		if( daemonise(logctx) < 1 ) {
> -			rc = 3;
> -			goto exit;
> -		}
> -	}
> -
> -
> -	// Parse XSLT template
> -	snprintf(xsltfile, 512, "%s/%s", eGet_value(config, "xsltpath"), XMLPARSER_XSL);
> -	writelog(logctx, LOG_DEBUG, "Parsing XSLT file: %s", xsltfile);
> -        xslt = xsltParseStylesheetFile((xmlChar *) xsltfile);
> -	if( !xslt ) {
> -		writelog(logctx, LOG_EMERG, "Could not parse XSLT template: %s", xsltfile);
> -		rc = 2;
> -		goto exit;
> -	}
> -
> -	// Open a POSIX MQ
> -	writelog(logctx, LOG_DEBUG, "Preparing POSIX MQ queue: /rteval_parsequeue");
> -	memset(&msgq, 0, sizeof(mqd_t));
> -	msgq_attr.mq_maxmsg = get_mqueue_msg_max(logctx);
> -	msgq_attr.mq_msgsize = sizeof(parseJob_t);
> -	msgq_attr.mq_flags = O_NONBLOCK;
> -	msgq = mq_open("/rteval_parsequeue", O_RDWR | O_CREAT, 0600, &msgq_attr);
> -	if( msgq < 0 ) {
> -		writelog(logctx, LOG_EMERG,
> -			 "Could not open message queue: %s", strerror(errno));
> -		rc = 2;
> -		goto exit;
> -	}
> -	mq_init = 1;
> -
> -	// Get the number of worker threads
> -	max_threads = atoi_nullsafe(eGet_value(config, "threads"));
> -	if( max_threads == 0 ) {
> -		max_threads = 4;
> -	}
> -
> -	// Get a database connection for the main thread
> -        dbc = db_connect(config, max_threads, logctx);
> -        if( !dbc ) {
> -		rc = 4;
> -		goto exit;
> -        }
> -
> -	// Prepare all threads
> -	threads = calloc(max_threads + 1, sizeof(pthread_t *));
> -	thread_attrs = calloc(max_threads + 1, sizeof(pthread_attr_t *));
> -	thrdata = calloc(max_threads + 1, sizeof(threadData_t *));
> -	assert( (threads != NULL) && (thread_attrs != NULL) && (thrdata != NULL) );
> -
> -	reportdir = eGet_value(config, "reportdir");
> -	writelog(logctx, LOG_INFO, "Starting %i worker threads", max_threads);
> -	max_report_size = defaultIntValue(atoi_nullsafe(eGet_value(config, "max_report_size")), 1024*1024);
> -	for( i = 0; i < max_threads; i++ ) {
> -		// Prepare thread specific data
> -		thrdata[i] = malloc_nullsafe(logctx, sizeof(threadData_t));
> -		if( !thrdata[i] ) {
> -			writelog(logctx, LOG_EMERG,
> -				 "Could not allocate memory for thread data");
> -			rc = 2;
> -			goto exit;
> -		}
> -
> -		// Get a database connection for the thread
> -		thrdata[i]->dbc = db_connect(config, i, logctx);
> -		if( !thrdata[i]->dbc ) {
> -			writelog(logctx, LOG_EMERG,
> -				"Could not connect to the database for thread %i", i);
> -			rc = 2;
> -			shutdown = 1;
> -			goto exit;
> -		}
> -
> -		// Parse the measurement_tables config variable, split it up into an array
> -		thrdata[i]->dbc->measurement_tbls = strSplit(eGet_value(config, "measurement_tables"), ", ");
> -		if( !thrdata[i]->dbc->measurement_tbls ) {
> -			writelog(dbc->log, LOG_CRIT, "Failed to parse measurement_tables configuration");
> -			rc = 2;
> -			shutdown = 1;
> -			goto exit;
> -		}
> -
> -		thrdata[i]->shutdown = &shutdown;
> -		thrdata[i]->threadcount = &activethreads;
> -		thrdata[i]->mtx_thrcnt = &mtx_thrcnt;
> -		thrdata[i]->id = i;
> -		thrdata[i]->msgq = msgq;
> -		thrdata[i]->mtx_sysreg = &mtx_sysreg;
> -		thrdata[i]->xslt = xslt;
> -		thrdata[i]->destdir = reportdir;
> -		thrdata[i]->max_report_size = max_report_size;
> -
> -		thread_attrs[i] = malloc_nullsafe(logctx, sizeof(pthread_attr_t));
> -		if( !thread_attrs[i] ) {
> -			writelog(logctx, LOG_EMERG,
> -				"Could not allocate memory for thread attributes");
> -			rc = 2;
> -			goto exit;
> -		}
> -		pthread_attr_init(thread_attrs[i]);
> -		pthread_attr_setdetachstate(thread_attrs[i], PTHREAD_CREATE_JOINABLE);
> -
> -		threads[i] = malloc_nullsafe(logctx, sizeof(pthread_t));
> -		if( !threads[i] ) {
> -			writelog(logctx, LOG_EMERG,
> -				"Could not allocate memory for pthread_t");
> -			rc = 2;
> -			goto exit;
> -		}
> -	}
> -
> -	// Setup signal catching
> -	signal(SIGINT,  sigcatch);
> -	signal(SIGTERM, sigcatch);
> -	signal(SIGHUP,  SIG_IGN);
> -	signal(SIGUSR1, sigcatch);
> -	signal(SIGUSR2, SIG_IGN);
> -
> -	// Start the threads
> -	for( i = 0; i < max_threads; i++ ) {
> -		int thr_rc = pthread_create(threads[i], thread_attrs[i], parsethread, thrdata[i]);
> -		if( thr_rc < 0 ) {
> -			writelog(logctx, LOG_EMERG,
> -				 "** ERROR **  Failed to start thread %i: %s",
> -				 i, strerror(thr_rc));
> -			rc = 3;
> -			goto exit;
> -		}
> -		started_threads++;
> -	}
> -
> -	// Main routine
> -	//
> -	// checks the submission queue and puts unprocessed records on the POSIX MQ
> -	// to be parsed by one of the threads
> -	//
> -	sleep(3); // Allow at least a few parser threads to settle down first before really starting
> -	writelog(logctx, LOG_DEBUG, "Starting submission queue checker");
> -	rc = process_submission_queue(dbc, msgq, &activethreads);
> -	writelog(logctx, LOG_DEBUG, "Submission queue checker shut down");
> -
> - exit:
> -	// Clean up all threads
> -	for( i = 0; i < max_threads; i++ ) {
> -		// Wait for all threads to exit
> -		if( (i < started_threads) && threads && threads[i] ) {
> -			void *thread_rc;
> -			int j_rc;
> -
> -			if( (j_rc = pthread_join(*threads[i], &thread_rc)) != 0 ) {
> -				writelog(logctx, LOG_CRIT,
> -					 "Failed to join thread %i: %s",
> -					 i, strerror(j_rc));
> -			}
> -			pthread_attr_destroy(thread_attrs[i]);
> -		}
> -		if( threads ) {
> -			free_nullsafe(threads[i]);
> -		}
> -		if( thread_attrs ) {
> -			free_nullsafe(thread_attrs[i]);
> -		}
> -
> -		// Disconnect threads database connection
> -		if( thrdata && thrdata[i] ) {
> -			strFree(thrdata[i]->dbc->measurement_tbls);
> -			db_disconnect(thrdata[i]->dbc);
> -			free_nullsafe(thrdata[i]);
> -		}
> -	}
> -	free_nullsafe(thrdata);
> -	free_nullsafe(threads);
> -	free_nullsafe(thread_attrs);
> -
> -	// Close message queue
> -	if( mq_init == 1 ) {
> -		errno = 0;
> -		if( mq_close(msgq) < 0 ) {
> -			writelog(logctx, LOG_CRIT, "Failed to close message queue: %s",
> -				 strerror(errno));
> -		}
> -		errno = 0;
> -		if( mq_unlink("/rteval_parsequeue") < 0 ) {
> -			writelog(logctx, LOG_ALERT, "Failed to remove the message queue: %s",
> -				 strerror(errno));
> -		}
> -	}
> -
> -	// Disconnect from database, main thread connection
> -	db_disconnect(dbc);
> -
> -	// Free up the rest
> -	eFree_values(config);
> -	xsltFreeStylesheet(xslt);
> -	xmlCleanupParser();
> -	xsltCleanupGlobals();
> -
> -	writelog(logctx, LOG_EMERG, "rteval-parserd is stopped");
> -	close_log(logctx);
> -	return rc;
> -}
> -
> diff --git a/server/parser/rteval-parserd.init b/server/parser/rteval-parserd.init
> deleted file mode 100755
> index a7da9db..0000000
> --- a/server/parser/rteval-parserd.init
> +++ /dev/null
> @@ -1,126 +0,0 @@
> -#!/bin/bash
> -#
> -# rteval-parserd  rteval report parser daemon
> -#
> -# Author:      David Sommerseth <davids@xxxxxxxxxx>
> -#
> -# Copyright 2009 Red Hat, Inc. and/or its affiliates.
> -# Released under the GPL
> -#
> -# chkconfig: - 20 80
> -# description: The rteval-parserd waits for rteval summary reports and parses them on arrival
> -# config: /etc/sysconfig/rteval-parserd
> -#
> -### BEGIN INIT INFO
> -# Provides: rteval-parserd
> -# Required-Start: postgresql
> -# Required-Stop: -
> -# Default-Stop: 0 1 6
> -# Short-Description: start and stop rteval-parserd
> -# Description: The rteval-parserd waits for rteval summary reports and parses them on arrival
> -### END INIT INFO
> -
> -. /etc/rc.d/init.d/functions
> -
> -if [ -f /etc/sysconfig/rteval-parserd ]; then
> -    . /etc/sysconfig/rteval-parserd
> -fi
> -
> -prog=rteval-parserd
> -RETVAL=0
> -
> -if [ -z $PIDFILE ]; then
> -    PIDFILE=/var/run/$prog.pid
> -fi
> -
> -start() {
> -    # Check if we have a pid file, if we do check that it is correct
> -    if [ -f $PIDFILE ]; then
> -	filepid=$(cat $PIDFILE)
> -	chkpid=$(pidof $prog)
> -	if [ $? = 0 ]; then
> -	    if [ "$chkpid" != "$filepid" ] ; then
> -		# We have a pid file which is not correct, fix it
> -		echo $chkpid > $PIDFILE
> -		filepid=$chkpid
> -	    fi
> -	    echo "$prog is already started (pid $filepid)"
> -	    return 0
> -	else
> -	    # No process really exists, clean up!
> -	    rm -f $PIDFILE
> -	fi
> -    fi
> -
> -    # Start a new daemon
> -    args="--daemon"
> -    if [ -z "$NUM_THREADS" ]; then
> -	# If NUM_THREADS is not set, use number of cores found.
> -	NUM_THREADS=$(find /sys/devices/system/cpu/cpu? -maxdepth 0 -type d | wc -l)
> -    fi
> -    args="$args --threads $NUM_THREADS"
> -
> -    if [ ! -z "$LOG" ]; then
> -	args="$args --log $LOG"
> -    fi
> -
> -    if [ ! -z "$LOGLEVEL" ]; then
> -	args="$args --log-level $LOGLEVEL"
> -    fi
> -
> -    if [ ! -z "$CONFIGFILE" ]; then
> -	args="$args --config $CONFIGFILE"
> -    fi
> -    echo -n $"Starting $prog ($NUM_THREADS threads): "
> -    $prog $args
> -    pidof $prog > $PIDFILE
> -    RETVAL=$?
> -    [ $RETVAL = 0 ] && success $"$prog startup" || failure $"$prog startup"
> -    [ $RETVAL = 0 ] && touch /var/lock/subsys/$prog
> -    echo
> -    return $RETVAL
> -}
> -
> -stop() {
> -    echo -n $"Stopping $prog: "
> -    if [ ! -f $PIDFILE ]; then
> -	chkpid=$(pidof $prog)
> -	if [ $? = 0 ]; then
> -	    PID=$chkpid
> -	fi
> -    else
> -	PID=$(cat $PIDFILE)
> -    fi
> -    kill -TERM $PID
> -    RETVAL=$?
> -    [ $RETVAL = 0 ] && success $"$prog shutdown" || failure $"$prog (pid $PID) shutdown"
> -    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/$prog $PIDFILE
> -    echo
> -}
> -
> -case "$1" in
> -  start)
> -	start
> -	;;
> -  stop)
> -	stop
> -	;;
> -  status)
> -        status $prog
> -	;;
> -  restart)
> -	stop
> -	start
> -	;;
> -  reload)
> -	stop
> -	start
> -	;;
> -  condrestart)
> -        ;;
> -  *)
> -	echo $"Usage: $prog {start|stop|restart|reload|status|help}"
> -	RETVAL=3
> -esac
> -
> -exit $RETVAL
> diff --git a/server/parser/rteval-parserd.sysconfig b/server/parser/rteval-parserd.sysconfig
> deleted file mode 100644
> index c57f48c..0000000
> --- a/server/parser/rteval-parserd.sysconfig
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -# Configuration parameters for rteval-parserd
> -
> -# *** Number of worker threads
> -# * When this is not set, the default will be one thread per CPU core
> -# NUM_THREADS=2
> -
> -# *** Logging
> -# * Valid values: syslog:[facility] or a file name (full path)
> -# * Valid facility values: daemon, user and local0 to local7
> -# * Default facility will be daemon
> -LOG=syslog:
> -
> -# *** Log level
> -# * Valid values: emerg, alert, crit, error, warn, notice, info, debug
> -LOGLEVEL=notice
> -
> -# *** rteval configuration file
> -# * Default value when not set is /etc/rteval.conf
> -# CONFIGFILE=/etc/rteval.conf
> -
> -# *** PID file
> -# * Full path to where to look for the PID file, defaults to /var/run/rteval-parserd.pid
> -# PIDFILE=/var/run/rteval-parserd.pid
> diff --git a/server/parser/sha1.c b/server/parser/sha1.c
> deleted file mode 100644
> index 3f77aa9..0000000
> --- a/server/parser/sha1.c
> +++ /dev/null
> @@ -1,615 +0,0 @@
> -/*-
> - * Copyright (c) 2001-2003 Allan Saddi <allan@xxxxxxxxx>
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - * 1. Redistributions of source code must retain the above copyright
> - *    notice, this list of conditions and the following disclaimer.
> - * 2. Redistributions in binary form must reproduce the above copyright
> - *    notice, this list of conditions and the following disclaimer in the
> - *    documentation and/or other materials provided with the distribution.
> - *
> - * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
> - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED.  IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
> - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> - * POSSIBILITY OF SUCH DAMAGE.
> - *
> - * $Id: sha1.c 680 2003-07-25 21:57:38Z asaddi $
> - */
> -
> -/*
> - * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
> - *
> - * Define SHA1_TEST to test the implementation using the NIST's
> - * sample messages. The output should be:
> - *
> - *   a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
> - *   84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
> - *   34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f
> - */
> -
> -#include <stdint.h>
> -#include <string.h>
> -
> -#include "sha1.h"
> -
> -#ifndef lint
> -static const char rcsid[] =
> -	"$Id: sha1.c 680 2003-07-25 21:57:38Z asaddi $";
> -#endif /* !lint */
> -
> -#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
> -#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
> -
> -#define F_0_19(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
> -#define F_20_39(x, y, z) ((x) ^ (y) ^ (z))
> -#define F_40_59(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
> -#define F_60_79(x, y, z) ((x) ^ (y) ^ (z))
> -
> -#define DO_ROUND(F, K) { \
> -  temp = ROTL(a, 5) + F(b, c, d) + e + *(W++) + K; \
> -  e = d; \
> -  d = c; \
> -  c = ROTL(b, 30); \
> -  b = a; \
> -  a = temp; \
> -}
> -
> -#define K_0_19 0x5a827999L
> -#define K_20_39 0x6ed9eba1L
> -#define K_40_59 0x8f1bbcdcL
> -#define K_60_79 0xca62c1d6L
> -
> -#ifndef RUNTIME_ENDIAN
> -
> -#ifdef WORDS_BIGENDIAN
> -
> -#define BYTESWAP(x) (x)
> -#define BYTESWAP64(x) (x)
> -
> -#else /* WORDS_BIGENDIAN */
> -
> -#define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
> -		     (ROTL((x), 8) & 0x00ff00ffL))
> -#define BYTESWAP64(x) _byteswap64(x)
> -
> -static inline uint64_t _byteswap64(uint64_t x)
> -{
> -  uint32_t a = x >> 32;
> -  uint32_t b = (uint32_t) x;
> -  return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
> -}
> -
> -#endif /* WORDS_BIGENDIAN */
> -
> -#else /* !RUNTIME_ENDIAN */
> -
> -#define BYTESWAP(x) _byteswap(sc->littleEndian, x)
> -#define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
> -
> -#define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
> -		      (ROTL((x), 8) & 0x00ff00ffL))
> -#define _BYTESWAP64(x) __byteswap64(x)
> -
> -static inline uint64_t __byteswap64(uint64_t x)
> -{
> -  uint32_t a = x >> 32;
> -  uint32_t b = (uint32_t) x;
> -  return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
> -}
> -
> -static inline uint32_t _byteswap(int littleEndian, uint32_t x)
> -{
> -  if (!littleEndian)
> -    return x;
> -  else
> -    return _BYTESWAP(x);
> -}
> -
> -static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
> -{
> -  if (!littleEndian)
> -    return x;
> -  else
> -    return _BYTESWAP64(x);
> -}
> -
> -static inline void setEndian(int *littleEndianp)
> -{
> -  union {
> -    uint32_t w;
> -    uint8_t b[4];
> -  } endian;
> -
> -  endian.w = 1L;
> -  *littleEndianp = endian.b[0] != 0;
> -}
> -
> -#endif /* !RUNTIME_ENDIAN */
> -
> -static const uint8_t padding[64] = {
> -  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> -};
> -
> -void
> -SHA1Init (SHA1Context *sc)
> -{
> -#ifdef RUNTIME_ENDIAN
> -  setEndian (&sc->littleEndian);
> -#endif /* RUNTIME_ENDIAN */
> -
> -  sc->totalLength = 0LL;
> -  sc->hash[0] = 0x67452301L;
> -  sc->hash[1] = 0xefcdab89L;
> -  sc->hash[2] = 0x98badcfeL;
> -  sc->hash[3] = 0x10325476L;
> -  sc->hash[4] = 0xc3d2e1f0L;
> -  sc->bufferLength = 0L;
> -}
> -
> -static void
> -burnStack (int size)
> -{
> -  char buf[128];
> -
> -  memset (buf, 0, sizeof (buf));
> -  size -= sizeof (buf);
> -  if (size > 0)
> -    burnStack (size);
> -}
> -
> -static void
> -SHA1Guts (SHA1Context *sc, const uint32_t *cbuf)
> -{
> -  uint32_t buf[80];
> -  uint32_t *W, *W3, *W8, *W14, *W16;
> -  uint32_t a, b, c, d, e, temp;
> -  int i;
> -
> -  W = buf;
> -
> -  for (i = 15; i >= 0; i--) {
> -    *(W++) = BYTESWAP(*cbuf);
> -    cbuf++;
> -  }
> -
> -  W16 = &buf[0];
> -  W14 = &buf[2];
> -  W8 = &buf[8];
> -  W3 = &buf[13];
> -
> -  for (i = 63; i >= 0; i--) {
> -    *W = *(W3++) ^ *(W8++) ^ *(W14++) ^ *(W16++);
> -    *W = ROTL(*W, 1);
> -    W++;
> -  }
> -
> -  a = sc->hash[0];
> -  b = sc->hash[1];
> -  c = sc->hash[2];
> -  d = sc->hash[3];
> -  e = sc->hash[4];
> -
> -  W = buf;
> -
> -#ifndef SHA1_UNROLL
> -#define SHA1_UNROLL 20
> -#endif /* !SHA1_UNROLL */
> -
> -#if SHA1_UNROLL == 1
> -  for (i = 19; i >= 0; i--)
> -    DO_ROUND(F_0_19, K_0_19);
> -
> -  for (i = 19; i >= 0; i--)
> -    DO_ROUND(F_20_39, K_20_39);
> -
> -  for (i = 19; i >= 0; i--)
> -    DO_ROUND(F_40_59, K_40_59);
> -
> -  for (i = 19; i >= 0; i--)
> -    DO_ROUND(F_60_79, K_60_79);
> -#elif SHA1_UNROLL == 2
> -  for (i = 9; i >= 0; i--) {
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -  }
> -
> -  for (i = 9; i >= 0; i--) {
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -  }
> -
> -  for (i = 9; i >= 0; i--) {
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -  }
> -
> -  for (i = 9; i >= 0; i--) {
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -  }
> -#elif SHA1_UNROLL == 4
> -  for (i = 4; i >= 0; i--) {
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -  }
> -
> -  for (i = 4; i >= 0; i--) {
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -  }
> -
> -  for (i = 4; i >= 0; i--) {
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -  }
> -
> -  for (i = 4; i >= 0; i--) {
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -  }
> -#elif SHA1_UNROLL == 5
> -  for (i = 3; i >= 0; i--) {
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -  }
> -
> -  for (i = 3; i >= 0; i--) {
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -  }
> -
> -  for (i = 3; i >= 0; i--) {
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -  }
> -
> -  for (i = 3; i >= 0; i--) {
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -  }
> -#elif SHA1_UNROLL == 10
> -  for (i = 1; i >= 0; i--) {
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -    DO_ROUND(F_0_19, K_0_19);
> -  }
> -
> -  for (i = 1; i >= 0; i--) {
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -    DO_ROUND(F_20_39, K_20_39);
> -  }
> -
> -  for (i = 1; i >= 0; i--) {
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -    DO_ROUND(F_40_59, K_40_59);
> -  }
> -
> -  for (i = 1; i >= 0; i--) {
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -    DO_ROUND(F_60_79, K_60_79);
> -  }
> -#elif SHA1_UNROLL == 20
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -  DO_ROUND(F_0_19, K_0_19);
> -
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -  DO_ROUND(F_20_39, K_20_39);
> -
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -  DO_ROUND(F_40_59, K_40_59);
> -
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -  DO_ROUND(F_60_79, K_60_79);
> -#else /* SHA1_UNROLL */
> -#error SHA1_UNROLL must be 1, 2, 4, 5, 10 or 20!
> -#endif
> -
> -  sc->hash[0] += a;
> -  sc->hash[1] += b;
> -  sc->hash[2] += c;
> -  sc->hash[3] += d;
> -  sc->hash[4] += e;
> -}
> -
> -void
> -SHA1Update (SHA1Context *sc, const void *vdata, uint32_t len)
> -{
> -  const uint8_t *data = vdata;
> -  uint32_t bufferBytesLeft;
> -  uint32_t bytesToCopy;
> -  int needBurn = 0;
> -
> -#ifdef SHA1_FAST_COPY
> -  if (sc->bufferLength) {
> -    bufferBytesLeft = 64L - sc->bufferLength;
> -
> -    bytesToCopy = bufferBytesLeft;
> -    if (bytesToCopy > len)
> -      bytesToCopy = len;
> -
> -    memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
> -
> -    sc->totalLength += bytesToCopy * 8L;
> -
> -    sc->bufferLength += bytesToCopy;
> -    data += bytesToCopy;
> -    len -= bytesToCopy;
> -
> -    if (sc->bufferLength == 64L) {
> -      SHA1Guts (sc, sc->buffer.words);
> -      needBurn = 1;
> -      sc->bufferLength = 0L;
> -    }
> -  }
> -
> -  while (len > 63) {
> -    sc->totalLength += 512L;
> -
> -    SHA1Guts (sc, data);
> -    needBurn = 1;
> -
> -    data += 64L;
> -    len -= 64L;
> -  }
> -
> -  if (len) {
> -    memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
> -
> -    sc->totalLength += len * 8L;
> -
> -    sc->bufferLength += len;
> -  }
> -#else /* SHA1_FAST_COPY */
> -  while (len) {
> -    bufferBytesLeft = 64L - sc->bufferLength;
> -
> -    bytesToCopy = bufferBytesLeft;
> -    if (bytesToCopy > len)
> -      bytesToCopy = len;
> -
> -    memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
> -
> -    sc->totalLength += bytesToCopy * 8L;
> -
> -    sc->bufferLength += bytesToCopy;
> -    data += bytesToCopy;
> -    len -= bytesToCopy;
> -
> -    if (sc->bufferLength == 64L) {
> -      SHA1Guts (sc, sc->buffer.words);
> -      needBurn = 1;
> -      sc->bufferLength = 0L;
> -    }
> -  }
> -#endif /* SHA1_FAST_COPY */
> -
> -  if (needBurn)
> -    burnStack (sizeof (uint32_t[86]) + sizeof (uint32_t *[5]) + sizeof (int));
> -}
> -
> -void
> -SHA1Final (SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE])
> -{
> -  uint32_t bytesToPad;
> -  uint64_t lengthPad;
> -  int i;
> -
> -  bytesToPad = 120L - sc->bufferLength;
> -  if (bytesToPad > 64L)
> -    bytesToPad -= 64L;
> -
> -  lengthPad = BYTESWAP64(sc->totalLength);
> -
> -  SHA1Update (sc, padding, bytesToPad);
> -  SHA1Update (sc, &lengthPad, 8L);
> -
> -  if (hash) {
> -    for (i = 0; i < SHA1_HASH_WORDS; i++) {
> -#ifdef SHA1_FAST_COPY
> -      *((uint32_t *) hash) = BYTESWAP(sc->hash[i]);
> -#else /* SHA1_FAST_COPY */
> -      hash[0] = (uint8_t) (sc->hash[i] >> 24);
> -      hash[1] = (uint8_t) (sc->hash[i] >> 16);
> -      hash[2] = (uint8_t) (sc->hash[i] >> 8);
> -      hash[3] = (uint8_t) sc->hash[i];
> -#endif /* SHA1_FAST_COPY */
> -      hash += 4;
> -    }
> -  }
> -}
> -
> -#ifdef SHA1_TEST
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -
> -int
> -main (int argc, char *argv[])
> -{
> -  SHA1Context foo;
> -  uint8_t hash[SHA1_HASH_SIZE];
> -  char buf[1000];
> -  int i;
> -
> -  SHA1Init (&foo);
> -  SHA1Update (&foo, "abc", 3);
> -  SHA1Final (&foo, hash);
> -
> -  for (i = 0; i < SHA1_HASH_SIZE;) {
> -    printf ("%02x", hash[i++]);
> -    if (!(i % 4))
> -      printf (" ");
> -  }
> -  printf ("\n");
> -
> -  SHA1Init (&foo);
> -  SHA1Update (&foo,
> -		"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
> -		56);
> -  SHA1Final (&foo, hash);
> -
> -  for (i = 0; i < SHA1_HASH_SIZE;) {
> -    printf ("%02x", hash[i++]);
> -    if (!(i % 4))
> -      printf (" ");
> -  }
> -  printf ("\n");
> -
> -  SHA1Init (&foo);
> -  memset (buf, 'a', sizeof (buf));
> -  for (i = 0; i < 1000; i++)
> -    SHA1Update (&foo, buf, sizeof (buf));
> -  SHA1Final (&foo, hash);
> -
> -  for (i = 0; i < SHA1_HASH_SIZE;) {
> -    printf ("%02x", hash[i++]);
> -    if (!(i % 4))
> -      printf (" ");
> -  }
> -  printf ("\n");
> -
> -  exit (0);
> -}
> -
> -#endif /* SHA1_TEST */
> diff --git a/server/parser/sha1.h b/server/parser/sha1.h
> deleted file mode 100644
> index 9ce5bd6..0000000
> --- a/server/parser/sha1.h
> +++ /dev/null
> @@ -1,66 +0,0 @@
> -/*-
> - * Copyright (c) 2001-2003 Allan Saddi <allan@xxxxxxxxx>
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - * 1. Redistributions of source code must retain the above copyright
> - *    notice, this list of conditions and the following disclaimer.
> - * 2. Redistributions in binary form must reproduce the above copyright
> - *    notice, this list of conditions and the following disclaimer in the
> - *    documentation and/or other materials provided with the distribution.
> - *
> - * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
> - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED.  IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
> - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> - * POSSIBILITY OF SUCH DAMAGE.
> - *
> - * $Id: sha1.h 347 2003-02-23 22:11:49Z asaddi $
> - */
> -
> -#ifndef _SHA1_H
> -#define _SHA1_H
> -
> -#include <stdint.h>
> -
> -#define SHA1_HASH_SIZE 20
> -
> -/* Hash size in 32-bit words */
> -#define SHA1_HASH_WORDS 5
> -
> -struct _SHA1Context {
> -  uint64_t totalLength;
> -  uint32_t hash[SHA1_HASH_WORDS];
> -  uint32_t bufferLength;
> -  union {
> -    uint32_t words[16];
> -    uint8_t bytes[64];
> -  } buffer;
> -#ifdef RUNTIME_ENDIAN
> -  int littleEndian;
> -#endif /* RUNTIME_ENDIAN */
> -};
> -
> -typedef struct _SHA1Context SHA1Context;
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -void SHA1Init (SHA1Context *sc);
> -void SHA1Update (SHA1Context *sc, const void *data, uint32_t len);
> -void SHA1Final (SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE]);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _SHA1_H */
> diff --git a/server/parser/statuses.h b/server/parser/statuses.h
> deleted file mode 100644
> index a1beef6..0000000
> --- a/server/parser/statuses.h
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   statuses.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 21 11:17:24 2009
> - *
> - * @brief  Status values used by rteval-parserd
> - *
> - */
> -
> -#ifndef _RTEVAL_STATUS_H
> -#define _RTEVAL_STATUS_H
> -
> -#define STAT_NEW       0         /**< New, unparsed report in the submission queue */
> -#define STAT_ASSIGNED  1         /**< Submission is assigned to a parser */
> -#define STAT_INPROG    2         /**< Parsing has started */
> -#define STAT_SUCCESS   3         /**< Report parsed successfully */
> -#define STAT_UNKNFAIL  4         /**< Unkown failure */
> -#define STAT_XMLFAIL   5         /**< Failed to parse the report XML file */
> -#define STAT_SYSREG    6         /**< System registration failed */
> -#define STAT_RTERIDREG 7         /**< Failed to get a new rterid value for the rteval run */
> -#define STAT_GENDB     8         /**< General database error */
> -#define STAT_RTEVRUNS  9         /**< Registering rteval run information failed */
> -#define STAT_MEASURE   10        /**< Registering measurement results failed */
> -#define STAT_REPMOVE   11        /**< Failed to move the report file */
> -#define STAT_FTOOBIG   12        /**< Report is too big (see config parameter: max_report_size) */
> -
> -#endif
> diff --git a/server/parser/threadinfo.h b/server/parser/threadinfo.h
> deleted file mode 100644
> index 53c4e7d..0000000
> --- a/server/parser/threadinfo.h
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - */
> -
> -/**
> - * @file   threadinfo.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Thu Oct 15 11:47:51 2009
> - *
> - * @brief  Shared info between the main() and parsethread() functions
> - *
> - */
> -
> -#ifndef _THREADINFO_H
> -#define _THREADINFO_H
> -
> -#include <mqueue.h>
> -#include <libxslt/transform.h>
> -
> -/**
> - *  Thread slot information.  Each thread slot is assigned with one threadData_t element.
> - */
> -typedef struct {
> -        int *shutdown;                /**< If set to 1, the thread should shut down */
> -        int *threadcount;             /**< Number of active worker threads */
> -        pthread_mutex_t *mtx_thrcnt;  /**< Mutex lock for updating active worker threads */
> -        mqd_t msgq;                   /**< POSIX MQ descriptor */
> -        pthread_mutex_t *mtx_sysreg;  /**< Mutex locking, to avoid clashes with registering systems */
> -        unsigned int id;              /**< Numeric ID for this thread */
> -        dbconn *dbc;                  /**< Database connection assigned to this thread */
> -        xsltStylesheet *xslt;         /**< XSLT stylesheet assigned to this thread */
> -        const char *destdir;          /**< Directory where to put the parsed reports */
> -        unsigned int max_report_size; /**< Maximum accepted file size of reports (config: max_report_size) */
> -} threadData_t;
> -
> -#endif
> diff --git a/server/parser/xmlparser.c b/server/parser/xmlparser.c
> deleted file mode 100644
> index 1ea7377..0000000
> --- a/server/parser/xmlparser.c
> +++ /dev/null
> @@ -1,620 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - * David Sommerseth <davids@xxxxxxxxxx>
> - *
> - * Parses summary.xml reports from rteval into a standardised XML format
> - * which is useful when putting data into a database.
> - *
> - */
> -
> -/**
> - * @file   xmlparser.c
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 21 10:58:53 2009
> - *
> - * @brief Parses summary.xml reports from rteval into a standardised XML format
> - *        which is useful when putting data into a database.
> - *
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <assert.h>
> -
> -#include <libxml/tree.h>
> -#include <libxslt/xsltInternals.h>
> -#include <libxslt/transform.h>
> -#include <libxslt/xsltutils.h>
> -#include <libexslt/exslt.h>
> -
> -#include <eurephia_nullsafe.h>
> -#include <eurephia_xml.h>
> -#include <xmlparser.h>
> -#include <sha1.h>
> -#include <log.h>
> -
> -static dbhelper_func const * xmlparser_dbhelpers = NULL;
> -
> -/**
> - * Simple strdup() function which encapsulates the string in single quotes,
> - * which is needed for XSLT parameter values
> - *
> - * @param str The string to be strdup'ed and encapsulated
> - *
> - * @return Returns a pointer to the new buffer.
> - */
> -static char *encapsString(const char *str) {
> -        char *ret = NULL;
> -
> -        if( str == NULL ) {
> -                return NULL;
> -        }
> -
> -        ret = (char *) calloc(1, strlen(str)+4);
> -        assert( ret != NULL );
> -
> -        snprintf(ret, strlen(str)+3, "'%s'", str);
> -        return ret;
> -}
> -
> -
> -/**
> - * Converts an integer to string an encapsulates the value in single quotes,
> - * which is needed for XSLT parameter values.
> - *
> - * @param val Integer value to encapsulate
> - *
> - * @return Returns a pointer to a new buffer with the encapsulated integer value.  This
> - *         buffer must be free'd after usage.
> - */
> -static char *encapsInt(const unsigned int val) {
> -        char *buf = NULL;
> -
> -        buf = (char *) calloc(1, 130);
> -        snprintf(buf, 128, "'%i'", val);
> -        return buf;
> -}
> -
> -
> -/**
> - * Simple function to determine if the given string is a number or not
> - *
> - * @param str Pointer to the tring to be checked
> - *
> - * @returns Returns 0 if not a number and a non-null value if it is a number
> - */
> -int isNumber(const char * str)
> -{
> -    char *ptr = NULL;
> -
> -    if (str == NULL || *str == '\0' || isspace(*str))
> -      return 0;
> -
> -    strtod (str, &ptr);
> -    return *ptr == '\0';
> -}
> -
> -
> -/**
> - * Split a string into an array.
> - * Use strGet() to extract the results and strFree() to free the memory
> - * allocated by strSplit()
> - *
> - * @param str Input string
> - * @param sep Separator list (string)
> - *
> - * @returns Returns a pointer to a array_str_t struct on success, otherwise NULL
> - */
> -array_str_t * strSplit(const char * str, const char * sep)
> -{
> -        array_str_t * ret = calloc(1, sizeof(array_str_t));
> -        char * p = NULL, *cp = strdup(str);
> -
> -        if( !ret || !cp ) {
> -                fprintf(stderr, "Memory allocation error in strSplit()\n");
> -                return NULL;
> -        }
> -
> -        p = strtok(cp, sep);
> -        while( p ) {
> -                ret->data = realloc(ret->data, sizeof(char *) * ++(ret->size));
> -                if( !ret->data ) {
> -                        fprintf(stderr, "Memory allocation error in strSplit() while parsing\n");
> -                        free(ret);
> -                        return NULL;
> -                }
> -                ret->data[ret->size-1] = strdup(p);
> -                p = strtok(NULL, sep);
> -        }
> -        free(cp);
> -        return ret;
> -}
> -
> -/**
> - * Retrieve an array memeber
> - *
> - * @param ar Pointer holding the array_str_t data
> - * @param el Element number to retrive
> - *
> - * @returns Returns a pointer to the array member.  This value must never be freed.
> - * On failure NULL is returned.  Only possible failures are out-of-range or a NULL
> - * array input.
> - */
> -inline char * strGet(array_str_t * ar, unsigned int el)
> -{
> -        return (!ar && (el > ar->size) ? NULL : ar->data[el]);
> -}
> -
> -/**
> - * Retrive number of accessible array members
> - *
> - * @param ar Pointer holding the array_str_t data
> - *
> - * @returns Returns the number of elements in the array_str_t struct.
> - *          If a NULL pointer is given, it will return 0.
> - */
> -inline unsigned int strSize(array_str_t * ar)
> -{
> -        return (!ar ? 0 : ar->size);
> -}
> -
> -/**
> - * Frees up the memory held by an array_str_t struct.
> - *
> - * @params ar Pointer holding the array_str_t data to be freed
> - *
> - */
> -void strFree(array_str_t * ar)
> -{
> -        int i = 0;
> -
> -        if( !ar ) {
> -                return;
> -        }
> -
> -        for( i = 0; i < ar->size; i++ ) {
> -                free(ar->data[i]);
> -                ar->data[i] = NULL;
> -        }
> -        free(ar->data); ar->data = NULL;
> -        free(ar);
> -}
> -
> -/**
> - * Initialise the XML parser, setting some global variables
> - */
> -void init_xmlparser(dbhelper_func const * dbhelpers)
> -{
> -	xmlparser_dbhelpers = dbhelpers;
> -
> -        /* Init libxml2 and load all exslt functions */
> -        xmlInitMemory();
> -        exsltRegisterAll();
> -}
> -
> -
> -/**
> - * Parses any XML input document into a sqldata XML format which can be used by pgsql_INSERT().
> - * The transformation must be defined in the input XSLT template.
> - *
> - * @param log       Log context
> - * @param xslt      XSLT template defining the data transformation
> - * @param indata_d  Input XML data to transform to a sqldata XML document
> - * @param params    Parameters to be sent to the XSLT parser
> - *
> - * @return Returns a well formed sqldata XML document on success, otherwise NULL is returned.
> - */
> -xmlDoc *parseToSQLdata(LogContext *log, xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params) {
> -        xmlDoc *result_d = NULL;
> -        char **xsltparams = NULL;
> -        unsigned int idx = 0, idx_table = 0, idx_submid = 0,
> -		idx_syskey = 0, idx_rterid = 0, idx_repfname = 0;
> -
> -        xsltparams = calloc(10, sizeof(char *));
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return NULL;
> -        }
> -
> -        if( params->table == NULL ) {
> -                writelog(log, LOG_ERR, "Table is not defined");
> -                return NULL;
> -        }
> -
> -        // Prepare XSLT parameters
> -        xsltparams[idx++] = "table\0";
> -        xsltparams[idx] = (char *) encapsString(params->table);
> -        idx_table = idx++;
> -
> -        if( params->submid > 0) {
> -                xsltparams[idx++] = "submid\0";
> -                xsltparams[idx] = (char *) encapsInt(params->submid);
> -                idx_submid = idx++;
> -        }
> -
> -        if( params->syskey > 0) {
> -                xsltparams[idx++] = "syskey\0";
> -                xsltparams[idx] = (char *) encapsInt(params->syskey);
> -                idx_syskey = idx++;
> -        }
> -
> -        if( params->rterid > 0 ) {
> -                xsltparams[idx++] = "rterid";
> -                xsltparams[idx] = (char *) encapsInt(params->rterid);
> -                idx_rterid = idx++;
> -        }
> -
> -        if( params->report_filename ) {
> -                xsltparams[idx++] = "report_filename";
> -                xsltparams[idx] = (char *) encapsString(params->report_filename);
> -                idx_repfname = idx++;
> -        }
> -        xsltparams[idx] = NULL;
> -
> -        // Apply the XSLT template to the input XML data
> -        result_d = xsltApplyStylesheet(xslt, indata_d, (const char **)xsltparams);
> -        if( result_d == NULL ) {
> -                writelog(log, LOG_CRIT, "Failed applying XSLT template to input XML");
> -        }
> -
> -        // Free memory we allocated via encapsString()/encapsInt()
> -        free(xsltparams[idx_table]);
> -        if( params->submid ) {
> -                free(xsltparams[idx_submid]);
> -        }
> -        if( params->syskey ) {
> -                free(xsltparams[idx_syskey]);
> -        }
> -        if( params->rterid ) {
> -                free(xsltparams[idx_rterid]);
> -        }
> -        if( params->report_filename ) {
> -                free(xsltparams[idx_repfname]);
> -        }
> -
> -        free(xsltparams);
> -        return result_d;
> -}
> -
> -
> -/**
> - * Internal xmlparser function.   Extracts the value from a '//sqldata/records/record/value'
> - * node and hashes the value if the 'hash' attribute is set.  Otherwise the value is extracted
> - * from the node directly.  This function is only used by sqldataExtractContent().
> - *
> - * @param sql_n sqldata values node containing the value to extract.
> - *
> - * @return Returns a pointer to a new buffer containing the value on success, otherwise NULL.
> - *         This memory buffer must be free'd after usage.
> - */
> -char * sqldataValueHash(LogContext *log, xmlNode *sql_n) {
> -	const char *hash = NULL, *isnull = NULL;
> -	SHA1Context shactx;
> -	uint8_t shahash[SHA1_HASH_SIZE];
> -	char *ret = NULL, *ptr = NULL;
> -	int i;
> -
> -	if( !(sql_n && (xmlStrcmp(sql_n->name, (xmlChar *) "value") == 0)
> -              && (xmlStrcmp(sql_n->parent->name, (xmlChar *) "record") == 0)
> -              || (xmlStrcmp(sql_n->parent->name, (xmlChar *) "value") == 0)) ) {
> -                return NULL;
> -	}
> -
> -	isnull = xmlGetAttrValue(sql_n->properties, "isnull");
> -	if( isnull && (strcmp(isnull, "1") == 0) ) {
> -		return NULL;
> -	}
> -
> -	hash = xmlGetAttrValue(sql_n->properties, "hash");
> -	if( !hash ) {
> -		// If no hash attribute is found, just use the raw data
> -		ret = strdup_nullsafe(xmlExtractContent(sql_n));
> -	} else if( strcasecmp(hash, "sha1") == 0 ) {
> -		const char *indata = xmlExtractContent(sql_n);
> -		// SHA1 hashing requested
> -		SHA1Init(&shactx);
> -		SHA1Update(&shactx, indata, strlen_nullsafe(indata));
> -		SHA1Final(&shactx, shahash);
> -
> -		// "Convert" to a readable format
> -		ret = malloc_nullsafe(log, (SHA1_HASH_SIZE * 2) + 3);
> -		ptr = ret;
> -		for( i = 0; i < SHA1_HASH_SIZE; i++ ) {
> -			sprintf(ptr, "%02x", shahash[i]);
> -			ptr += 2;
> -		}
> -	} else {
> -		ret = strdup("<Unsupported hashing algorithm>");
> -	}
> -
> -	return ret;
> -}
> -
> -
> -/**
> - * Extract the content of a //sqldata/records/record/value[@type='array']/value node set
> - * and format it in suitable array format for the database backend.
> - *
> - * @param log    Log context
> - * @param sql_n sqldata values node containing the value to extract and format as an array.
> - *
> - * @return Returns a pointer to a new memory buffer containing the value as a string.
> - *         On errors, NULL is returned.  This memory buffer must be free'd after usage.
> - */
> -static char * sqldataValueArray(LogContext *log, xmlNode *sql_n)
> -{
> -	if( xmlparser_dbhelpers == NULL ) {
> -		writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -		return NULL;
> -	}
> -
> -	return xmlparser_dbhelpers->dbh_FormatArray(log, sql_n);
> -}
> -
> -
> -/**
> - * Extract the content of a '//sqldata/records/record/value' node.  It will consider
> - * both the 'hash' and 'type' attributes of the 'value' tag.
> - *
> - * @param log    Log context
> - * @param sql_n  Pointer to a value node of a sqldata XML document.
> - *
> - * @return Returns a pointer to a new memory buffer containing the value as a string.
> - *         On errors, NULL is returned.  This memory buffer must be free'd after usage.
> - */
> -char *sqldataExtractContent(LogContext *log, xmlNode *sql_n) {
> -	const char *valtype = xmlGetAttrValue(sql_n->properties, "type");
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return NULL;
> -        }
> -
> -	if( !sql_n || (xmlStrcmp(sql_n->name, (xmlChar *) "value") != 0)
> -	    || (xmlStrcmp(sql_n->parent->name, (xmlChar *) "record") != 0) ) {
> -		    return NULL;
> -	}
> -
> -	if( valtype && (strcmp(valtype, "xmlblob") == 0) ) {
> -		xmlNode *chld_n = sql_n->children;
> -
> -		// Go to next "real" tag, skipping non-element nodes
> -		while( chld_n && chld_n->type != XML_ELEMENT_NODE ){
> -			chld_n = chld_n->next;
> -		}
> -		return xmlNodeToString(log, chld_n);
> -        } else if( valtype && (strcmp(valtype, "array") == 0) ) {
> -                return sqldataValueArray(log, sql_n);
> -	} else {
> -		return sqldataValueHash(log, sql_n);
> -	}
> -}
> -
> -
> -/**
> - * Return the 'fid' value of a given field in an sqldata XML document.
> - *
> - * @param log    Log context
> - * @param sql_n  Pointer to the root xmlNode element of a sqldata XML document
> - * @param fname  String containing the field name to look up
> - *
> - * @return Returns a value >= 0 on success, containing the 'fid' value of the field.  Otherwise
> - *         a value < 0 is returned.  -1 if the field is not found or -2 if there are some problems
> - *         with the XML document.
> - */
> -int sqldataGetFid(LogContext *log, xmlNode *sql_n, const char *fname) {
> -	xmlNode *f_n = NULL;
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return -2;
> -        }
> -
> -	if( !sql_n || (xmlStrcmp(sql_n->name, (xmlChar *) "sqldata") != 0) ) {
> -		writelog(log, LOG_ERR,
> -			 "sqldataGetFid: Input XML document is not a valid sqldata document");
> -		return -2;
> -	}
> -
> -	f_n = xmlFindNode(sql_n, "fields");
> -	if( !f_n || !f_n->children ) {
> -		writelog(log, LOG_ERR,
> -			 "sqldataGetFid: Input XML document does not contain a fields section");
> -		return -2;
> -	}
> -
> -	foreach_xmlnode(f_n->children, f_n) {
> -		if( (f_n->type != XML_ELEMENT_NODE)
> -		    || xmlStrcmp(f_n->name, (xmlChar *) "field") != 0 ) {
> -			// Skip uninteresting nodes
> -			continue;
> -		}
> -
> -		if( strcmp(xmlExtractContent(f_n), fname) == 0 ) {
> -			char *fid = xmlGetAttrValue(f_n->properties, "fid");
> -			if( !fid ) {
> -				writelog(log, LOG_ERR,
> -					 "sqldataGetFid: Field node is missing 'fid' attribute (field: %s)",
> -					 fname);
> -				return -2;
> -			}
> -			return atoi_nullsafe(fid);
> -		}
> -	}
> -	return -1;
> -}
> -
> -
> -/**
> - * Retrieves the value of a particular field in an sqldata XML document.
> - *
> - * @param log    Log context
> - * @param sqld   pointer to an sqldata XML document.
> - * @param fname  String containing the field name to extract the value of.
> - * @param recid  Integer containing the record ID of the record to extract the value.  This starts
> - *               on 0.
> - *
> - * @return Returns a pointer to a new memory buffer containing the extracted value.  On errors or if
> - *         recid is higher than available records, NULL is returned.
> - */
> -char *sqldataGetValue(LogContext *log, xmlDoc *sqld, const char *fname, int recid ) {
> -	xmlNode *r_n = NULL;
> -	int fid = -3, rc = 0;
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return NULL;
> -        }
> -
> -	if( recid < 0 ) {
> -		writelog(log, LOG_ERR, "sqldataGetValue: Invalid recid");
> -		return NULL;
> -	}
> -
> -	r_n = xmlDocGetRootElement(sqld);
> -	if( !r_n || (xmlStrcmp(r_n->name, (xmlChar *) "sqldata") != 0) ) {
> -		writelog(log, LOG_ERR,
> -			 "sqldataGetValue: Input XML document is not a valid sqldata document");
> -		return NULL;
> -	}
> -
> -	fid = sqldataGetFid(log, r_n, fname);
> -	if( fid < 0 ) {
> -		return NULL;
> -	}
> -
> -	r_n = xmlFindNode(r_n, "records");
> -	if( !r_n || !r_n->children ) {
> -		writelog(log, LOG_ERR,
> -			 "sqldataGetValue: Input XML document does not contain a records section");
> -		return NULL;
> -	}
> -
> -	foreach_xmlnode(r_n->children, r_n) {
> -		if( (r_n->type != XML_ELEMENT_NODE)
> -		    || xmlStrcmp(r_n->name, (xmlChar *) "record") != 0 ) {
> -			// Skip uninteresting nodes
> -			continue;
> -		}
> -		if( rc == recid ) {
> -			xmlNode *v_n = NULL;
> -			// The rigth record is found, find the field we're looking for
> -			foreach_xmlnode(r_n->children, v_n) {
> -				char *fid_s = NULL;
> -				if( (v_n->type != XML_ELEMENT_NODE)
> -				    || (xmlStrcmp(v_n->name, (xmlChar *) "value") != 0) ) {
> -					// Skip uninteresting nodes
> -					continue;
> -				}
> -				fid_s = xmlGetAttrValue(v_n->properties, "fid");
> -				if( fid_s && (fid == atoi_nullsafe(fid_s)) ) {
> -					return sqldataExtractContent(log, v_n);
> -				}
> -			}
> -		}
> -		rc++;
> -	}
> -	return NULL;
> -}
> -
> -
> -/**
> - * Helper function to parse an sqldata XML document for the systems_hostname table.  In addition
> - * it will also return two strings containing hostname and ipaddress of the host.
> - *
> - * @param log        Log context
> - * @param xslt       Pointer to an xmlparser.xml XSLT template
> - * @param summaryxml rteval XML report document
> - * @param syskey     Integer containing the syskey value corresponding to this host
> - * @param hostname   Return pointer for where the hostname will be saved.
> - * @param ipaddr     Return pointer for where the IP address will be saved.
> - *
> - * @return Returns a sqldata XML document on success.  In this case the hostname and ipaddr will point
> - *         at memory buffers containing hostname and ipaddress.  These values must be free'd after usage.
> - *         On errors the function will return NULL and hostname and ipaddr will not have been touched
> - *         at all.
> - */
> -xmlDoc *sqldataGetHostInfo(LogContext *log, xsltStylesheet *xslt, xmlDoc *summaryxml,
> -			   int syskey, char **hostname, char **ipaddr)
> -{
> -	xmlDoc *hostinfo_d = NULL;
> -	parseParams prms;
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return NULL;
> -        }
> -
> -	memset(&prms, 0, sizeof(parseParams));
> -	prms.table = "systems_hostname";
> -	prms.syskey = syskey;
> -
> -	hostinfo_d = parseToSQLdata(log, xslt, summaryxml, &prms);
> -	if( !hostinfo_d ) {
> -		writelog(log, LOG_ERR,
> -			 "sqldatGetHostInfo: Could not parse input XML data");
> -		xmlFreeDoc(hostinfo_d);
> -		goto exit;
> -	}
> -
> -	// Grab hostname from input XML
> -	*hostname = sqldataGetValue(log, hostinfo_d, "hostname", 0);
> -	if( !hostname ) {
> -		writelog(log, LOG_ERR,
> -			"sqldatGetHostInfo: Could not retrieve the hostname field from the input XML");
> -		xmlFreeDoc(hostinfo_d);
> -		goto exit;
> -	}
> -
> -	// Grab ipaddr from input XML
> -	*ipaddr = sqldataGetValue(log, hostinfo_d, "ipaddr", 0);
> -	if( !ipaddr ) {
> -		writelog(log, LOG_ERR,
> -			"sqldatGetHostInfo: Could not retrieve the IP address field from the input XML");
> -		free_nullsafe(hostname);
> -		xmlFreeDoc(hostinfo_d);
> -		goto exit;
> -	}
> - exit:
> -	return hostinfo_d;
> -}
> -
> -int sqldataGetRequiredSchemaVer(LogContext *log, xmlNode *sqldata_root)
> -{
> -	char *schver = NULL, *cp = NULL, *ptr = NULL;
> -	int majv = 0, minv = 0;
> -
> -        if( xmlparser_dbhelpers == NULL ) {
> -                writelog(log, LOG_ERR, "Programming error: xmlparser is not initialised");
> -                return -1;
> -        }
> -
> -	if( !sqldata_root || (xmlStrcmp(sqldata_root->name, (xmlChar *) "sqldata") != 0) ) {
> -		writelog(log, LOG_ERR, "sqldataGetRequiredSchemaVer: Invalid document node");
> -		return -1;
> -	}
> -
> -	schver = xmlGetAttrValue(sqldata_root->properties, "schemaver");
> -	if( schver == NULL ) {
> -		return 100;  // If not defined, presume lowest available version.
> -	}
> -	cp = strdup(schver);
> -	assert( cp != NULL );
> -
> -	if( (ptr = strpbrk(cp, ".")) != NULL ) {
> -		*ptr = 0;
> -		ptr++;
> -		majv = atoi_nullsafe(cp);
> -		minv = atoi_nullsafe(ptr);
> -	} else {
> -		majv = atoi_nullsafe(cp);
> -		minv = 0;
> -	}
> -	free_nullsafe(cp);
> -
> -	return (majv * 100) + minv;
> -}
> diff --git a/server/parser/xmlparser.h b/server/parser/xmlparser.h
> deleted file mode 100644
> index 1aa3977..0000000
> --- a/server/parser/xmlparser.h
> +++ /dev/null
> @@ -1,75 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - * David Sommerseth <davids@xxxxxxxxxx>
> - *
> - *
> - */
> -
> -/**
> - * @file   xmlparser.h
> - * @author David Sommerseth <davids@xxxxxxxxxx>
> - * @date   Wed Oct 7 17:27:39 2009
> - *
> - * @brief Parses summary.xml reports from rteval into a standardised XML format
> - *        which is useful when putting data into a database.
> - *
> - */
> -
> -
> -#ifndef _XMLPARSER_H
> -#define _XMLPARSER_H
> -
> -/**
> - *  Parameters needed by the the xmlparser.xsl XSLT template.
> - */
> -typedef struct {
> -        const char *table;            /**< Which table to parse data for.  Required*/
> -        unsigned int submid;          /**< Submission ID, needed by the 'rtevalruns' table */
> -        unsigned int syskey;          /**< System key (referencing systems.syskey) */
> -        const char *report_filename;  /**< Filename to the saved report (after being parsed) */
> -        unsigned int rterid;          /**< References rtevalruns.rterid */
> -} parseParams;
> -
> -/**
> - * Container for string arrays
> - */
> -typedef struct {
> -        unsigned int size;
> -        char **data;
> -} array_str_t;
> -
> -array_str_t * strSplit(const char * str, const char * sep);
> -inline char * strGet(array_str_t * ar, unsigned int el);
> -inline unsigned int strSize(array_str_t * ar);
> -void strFree(array_str_t * ar);
> -
> -/** Simple for-loop iterator for array_str_t objects
> - *
> - * @param ptr Return pointer (char *) where the element data is returned
> - * @param idx Element index counter, declares where it should start and can be used
> - *            to track the iteration process.  Must be an int variable
> - * @param ar  The array_str_t object to iterate
> - */
> -#define for_array_str(ptr, idx, ar) for( ptr = ar->data[idx]; idx++ < ar->size; \
> -                                         ptr=(idx < ar->size ? ar->data[idx] : NULL) )
> -
> -/**
> - *  Database specific helper functions
> - */
> -typedef struct {
> -        char *(*dbh_FormatArray)(LogContext *log, xmlNode *sql_n); /** Formats data as arrays */
> -} dbhelper_func;
> -
> -void init_xmlparser(dbhelper_func const * dbhelpers);
> -char * sqldataValueHash(LogContext *log, xmlNode *sql_n);
> -xmlDoc *parseToSQLdata(LogContext *log, xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params);
> -char *sqldataExtractContent(LogContext *log, xmlNode *sql_n);
> -int sqldataGetFid(LogContext *log, xmlNode *sqld, const char *fname);
> -char *sqldataGetValue(LogContext *log, xmlDoc *sqld, const char *fname, int recid);
> -xmlDoc *sqldataGetHostInfo(LogContext *log, xsltStylesheet *xslt, xmlDoc *summaryxml,
> -			   int syskey, char **hostname, char **ipaddr);
> -int sqldataGetRequiredSchemaVer(LogContext *log, xmlNode *sqldata_root);
> -
> -#endif
> diff --git a/server/parser/xmlparser.xsl b/server/parser/xmlparser.xsl
> deleted file mode 100644
> index ddef1cc..0000000
> --- a/server/parser/xmlparser.xsl
> +++ /dev/null
> @@ -1,607 +0,0 @@
> -<?xml version="1.0"?>
> -<!-- SPDX-License-Identifier: GPL-2.0-only -->
> -<!--
> -     *
> -     *  GPLv2 - Copyright (C) 2009
> -     *          David Sommerseth <davids@xxxxxxxxxx>
> -     *
> --->
> -
> -<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> -                 xmlns:math="http://exslt.org/math";
> -                 extension-element-prefixes="math">
> -  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
> -
> -  <!-- Used for iterating CPU topology information -->
> -  <xsl:key name="pkgkey" match="cpu" use="@physical_package_id"/>
> -
> -
> -  <!-- Supported tables in reports in rteval v1.37 and older -->
> -  <xsl:template match="/rteval['2.0' > @version]">
> -    <xsl:choose>
> -      <!-- TABLE: systems -->
> -      <xsl:when test="$table = 'systems'">
> -        <xsl:apply-templates select="HardwareInfo" mode="tbl_systems"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: systems_hostname -->
> -      <xsl:when test="$table = 'systems_hostname'">
> -        <xsl:apply-templates select="." mode="tbl_systems_hostname"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: rtevalruns -->
> -      <xsl:when test="$table = 'rtevalruns'">
> -        <xsl:apply-templates select="." mode="tbl_rtevalruns"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: rtevalruns_details -->
> -      <xsl:when test="$table = 'rtevalruns_details'">
> -        <xsl:apply-templates select="." mode="tbl_rtevalruns_details"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_statistics -->
> -      <xsl:when test="$table = 'cyclic_statistics'">
> -        <xsl:apply-templates select="cyclictest" mode="tbl_cyclictest_statistics"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_histogram -->
> -      <xsl:when test="$table = 'cyclic_histogram'">
> -        <xsl:apply-templates select="cyclictest" mode="tbl_cyclictest_histogram"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_rawdata - only used by rteval v1.4 and earlier -->
> -      <xsl:when test="$table = 'cyclic_rawdata'">
> -        <xsl:if test="string(number($rterid)) = 'NaN'">
> -          <xsl:message terminate="yes">
> -            <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -          </xsl:message>
> -        </xsl:if>
> -	<sqldata schemaver="1.0" table="cyclic_rawdata">
> -	  <fields>
> -            <field fid="0">rterid</field>
> -            <field fid="1">cpu_num</field>
> -            <field fid="2">sampleseq</field>
> -            <field fid="3">latency</field>
> -	  </fields>
> -	  <records>
> -            <xsl:for-each select="cyclictest/RawSampleData/Thread/Sample">
> -              <record>
> -		<value fid="0"><xsl:value-of select="$rterid"/></value>
> -		<value fid="1"><xsl:value-of select="../@id"/></value>
> -		<value fid="2"><xsl:value-of select="@seq"/></value>
> -		<value fid="3"><xsl:value-of select="@latency"/></value>
> -              </record>
> -            </xsl:for-each>
> -	  </records>
> -	</sqldata>
> -      </xsl:when>
> -
> -      <!-- Tables only used by rteval v2.0 and newer - just ignore them to avoid parsing warnings -->
> -      <xsl:when test="$table = 'hwlatdetect_summary'">
> -      </xsl:when>
> -      <xsl:when test="$table = 'hwlatdetect_samples'">
> -      </xsl:when>
> -
> -      <xsl:otherwise>
> -        <xsl:message terminate="yes">
> -          <xsl:text>Invalid 'table' parameter value: </xsl:text><xsl:value-of select="$table"/>
> -        </xsl:message>
> -      </xsl:otherwise>
> -    </xsl:choose>
> -  </xsl:template>
> -
> -
> -  <!-- Supported tables in reports from rteval v2.0 and newer -->
> -  <xsl:template match="/rteval[@version >= '2.0']">
> -    <xsl:choose>
> -      <!-- TABLE: systems -->
> -      <xsl:when test="$table = 'systems'">
> -        <xsl:apply-templates select="SystemInfo/DMIinfo/HardwareInfo" mode="tbl_systems"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: systems_hostname -->
> -      <xsl:when test="$table = 'systems_hostname'">
> -        <xsl:apply-templates select="SystemInfo" mode="tbl_systems_hostname"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: rtevalruns -->
> -      <xsl:when test="$table = 'rtevalruns'">
> -        <xsl:apply-templates select="." mode="tbl_rtevalruns"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: rtevalruns_details -->
> -      <xsl:when test="$table = 'rtevalruns_details'">
> -        <xsl:apply-templates select="SystemInfo" mode="tbl_rtevalruns_details"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_statistics -->
> -      <xsl:when test="$table = 'cyclic_statistics'">
> -        <xsl:apply-templates select="Measurements/Profile/cyclictest" mode="tbl_cyclictest_statistics"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_histogram -->
> -      <xsl:when test="$table = 'cyclic_histogram'">
> -        <xsl:apply-templates select="Measurements/Profile/cyclictest" mode="tbl_cyclictest_histogram"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: hwlatdetect_summary -->
> -      <xsl:when test="$table = 'hwlatdetect_summary'">
> -        <xsl:apply-templates select="Measurements/Profile/hwlatdetect" mode="tbl_hwlatdetect_summary"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: hwlatdetect_samples -->
> -      <xsl:when test="$table = 'hwlatdetect_samples'">
> -        <xsl:apply-templates select="Measurements/Profile/hwlatdetect/samples" mode="tbl_hwlatdetect_samples"/>
> -      </xsl:when>
> -
> -      <!-- TABLE: cyclic_rawdata - only used by rteval v1.4 and earlier -->
> -      <xsl:when test="$table = 'cyclic_rawdata'"> <!-- Just ignore this one - avoids parsing warnings -->
> -      </xsl:when>
> -
> -      <xsl:otherwise>
> -        <xsl:message terminate="yes">
> -          <xsl:text>Invalid 'table' parameter value: </xsl:text><xsl:value-of select="$table"/>
> -        </xsl:message>
> -      </xsl:otherwise>
> -    </xsl:choose>
> -  </xsl:template>
> -
> -
> -
> -
> -
> -  <!-- TABLE: systems - all rteval versions -->
> -  <xsl:template match="/rteval['2.0' > @version]/HardwareInfo|/rteval[@version >= '2.0']/SystemInfo/DMIinfo/HardwareInfo" mode="tbl_systems">
> -    <sqldata schemaver="1.0" table="systems" key="syskey">
> -      <fields>
> -        <field fid="0">sysid</field>
> -        <field fid="1">dmidata</field>
> -      </fields>
> -      <records>
> -        <record>
> -          <value fid="0" hash="sha1">
> -            <xsl:value-of select="concat(@SystemUUID,':',@SerialNo)"/>
> -          </value>
> -          <value fid="1" type="xmlblob">
> -            <xsl:copy-of select="."/>
> -          </value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: systems_hostname - rteval v1.37 or older -->
> -  <xsl:template match="/rteval['2.0' > @version]" mode="tbl_systems_hostname">
> -    <xsl:if test="string(number($syskey)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'syskey' parameter value: </xsl:text><xsl:value-of select="syskey"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.0" table="systems_hostname">
> -      <xsl:call-template name="fields_systems_hostname"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$syskey"/></value>
> -          <value fid="1"><xsl:value-of select="uname/node"/></value>
> -          <value fid="2"><xsl:value-of select="network_config/interface/IPv4[@defaultgw=1]/@ipaddr"/></value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <!-- TABLE: systems_hostname - rteval v2.0 or newer -->
> -  <xsl:template match="/rteval[@version >= '2.0']/SystemInfo" mode="tbl_systems_hostname">
> -    <xsl:if test="string(number($syskey)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'syskey' parameter value: </xsl:text><xsl:value-of select="syskey"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.0" table="systems_hostname">
> -      <xsl:call-template name="fields_systems_hostname"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$syskey"/></value>
> -          <value fid="1"><xsl:value-of select="uname/node"/></value>
> -          <value fid="2"><xsl:value-of select="NetworkConfig/interface/IPv4[@defaultgw=1]/@ipaddr"/></value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <xsl:template name="fields_systems_hostname">
> -    <fields>
> -      <field fid="0">syskey</field>
> -      <field fid="1">hostname</field>
> -      <field fid="2">ipaddr</field>
> -    </fields>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: rtevalruns - rteval v1.37 or older -->
> -  <xsl:template match="/rteval['2.0' > @version]" mode="tbl_rtevalruns">
> -    <sqldata schemaver="1.2" table="rtevalruns">
> -      <xsl:call-template name="fields_rtevalruns"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$syskey"/></value>
> -          <value fid="1"><xsl:value-of select="uname/kernel"/></value>
> -          <value fid="2"><xsl:choose>
> -            <xsl:when test="uname/kernel/@is_RT = '1'">true</xsl:when>
> -            <xsl:otherwise>false</xsl:otherwise></xsl:choose>
> -          </value>
> -          <value fid="3"><xsl:value-of select="uname/arch"/></value>
> -          <value fid="4"><xsl:value-of select="concat(run_info/date, ' ', run_info/time)"/></value>
> -          <value fid="5">
> -            <xsl:value-of select="(run_info/@days*86400)+(run_info/@hours*3600)
> -                                  +(run_info/@minutes*60)+(run_info/@seconds)"/>
> -          </value>
> -          <value fid="6"><xsl:value-of select="loads/@load_average"/></value>
> -          <value fid="7"><xsl:value-of select="@version"/></value>
> -          <value fid="8"><xsl:value-of select="$report_filename"/></value>
> -          <value fid="9"><xsl:value-of select="$rterid"/></value>
> -          <value fid="10"><xsl:value-of select="$submid"/></value>
> -          <value fid="11"><xsl:value-of select="uname/baseos"/></value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <!-- TABLE: rtevalruns - rteval v2.0 or newer -->
> -  <xsl:template match="/rteval[@version >= '2.0']" mode="tbl_rtevalruns">
> -    <sqldata schemaver="1.2" table="rtevalruns">
> -      <xsl:call-template name="fields_rtevalruns"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$syskey"/></value>
> -          <value fid="1"><xsl:value-of select="SystemInfo/uname/kernel"/></value>
> -          <value fid="2"><xsl:choose>
> -            <xsl:when test="SystemInfo/uname/kernel/@is_RT = '1'">true</xsl:when>
> -            <xsl:otherwise>false</xsl:otherwise></xsl:choose>
> -          </value>
> -          <value fid="3"><xsl:value-of select="SystemInfo/uname/arch"/></value>
> -          <value fid="4"><xsl:value-of select="concat(run_info/date, ' ', run_info/time)"/></value>
> -          <value fid="5">
> -            <xsl:value-of select="(run_info/@days*86400)+(run_info/@hours*3600)
> -                                  +(run_info/@minutes*60)+(run_info/@seconds)"/>
> -          </value>
> -          <value fid="6"><xsl:value-of select="loads/@load_average"/></value>
> -          <value fid="7"><xsl:value-of select="@version"/></value>
> -          <value fid="8"><xsl:value-of select="$report_filename"/></value>
> -          <value fid="9"><xsl:value-of select="$rterid"/></value>
> -          <value fid="10"><xsl:value-of select="$submid"/></value>
> -          <value fid="11"><xsl:value-of select="SystemInfo/uname/baseos"/></value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <xsl:template name="fields_rtevalruns">
> -    <xsl:if test="string(number($syskey)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'syskey' parameter value: </xsl:text><xsl:value-of select="syskey"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <xsl:if test="string(number($submid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'submid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <xsl:if test="$report_filename = ''">
> -      <xsl:message terminate="yes">
> -        <xsl:text>The parameter 'report_filename' parameter cannot be empty</xsl:text>
> -      </xsl:message>
> -    </xsl:if>
> -      <fields>
> -        <field fid="0">syskey</field>
> -        <field fid="1">kernel_ver</field>
> -        <field fid="2">kernel_rt</field>
> -        <field fid="3">arch</field>
> -        <field fid="4">run_start</field>
> -        <field fid="5">run_duration</field>
> -        <field fid="6">load_avg</field>
> -        <field fid="7">version</field>
> -        <field fid="8">report_filename</field>
> -        <field fid="9">rterid</field>
> -        <field fid="10">submid</field>
> -        <field fid="11">distro</field>
> -      </fields>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: rtevalruns_details - rteval v1.37 or older -->
> -  <xsl:template match="/rteval['2.0' > @version]" mode="tbl_rtevalruns_details">
> -    <sqldata schemaver="1.4" table="rtevalruns_details">
> -      <xsl:call-template name="fields_rtevalruns_details"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$rterid"/></value>
> -          <value fid="1"><xsl:value-of select="hardware/numa_nodes"/></value>
> -          <value fid="2">
> -            <xsl:choose>
> -              <xsl:when test="hardware/cpu_topology">
> -                <xsl:value-of select="hardware/cpu_topology/@num_cpu_cores"/>
> -              </xsl:when>
> -              <xsl:otherwise>
> -                <xsl:value-of select="hardware/cpu_cores"/>
> -              </xsl:otherwise>
> -            </xsl:choose>
> -          </value>
> -          <value fid="3">
> -            <xsl:value-of select="hardware/cpu_topology/@num_cpu_sockets"/>
> -          </value>
> -          <value fid="4" type="xmlblob">
> -            <rteval_details>
> -              <xsl:copy-of select="clocksource|services|kthreads|network_config|loads|cyclictest/command_line"/>
> -              <hardware>
> -                <xsl:copy-of select="hardware/memory_size|hardware/cpu_topology"/>
> -              </hardware>
> -            </rteval_details>
> -          </value>
> -          <value fid="5"><xsl:value-of select="run_info/annotate"/></value>
> -          <value fid="6" type="array">
> -            <xsl:for-each select="hardware/cpu_topology/cpu[generate-id() = generate-id(key('pkgkey', @physical_package_id)[1])]">
> -              <xsl:call-template name="count_core_spread_v1x">
> -                <xsl:with-param name="pkgid" select="@physical_package_id"/>
> -              </xsl:call-template>
> -            </xsl:for-each>
> -          </value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <!-- TABLE: rtevalruns_details - rteval v2.0 or newer -->
> -  <xsl:template match="/rteval[@version >= '2.0']/SystemInfo" mode="tbl_rtevalruns_details">
> -    <sqldata schemaver="1.4" table="rtevalruns_details">
> -      <xsl:call-template name="fields_rtevalruns_details"/>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$rterid"/></value>
> -          <value fid="1"><xsl:value-of select="Memory/numa_nodes"/></value>
> -          <value fid="2">
> -            <xsl:value-of select="CPUtopology/@num_cpu_cores"/>
> -          </value>
> -          <value fid="3">
> -            <xsl:value-of select="CPUtopology/@num_cpu_sockets"/>
> -          </value>
> -          <value fid="4" type="xmlblob">
> -            <rteval_details format="2">
> -              <xsl:copy-of select="Kernel/ClockSource|Services|Kernel/kthreads|NetworkConfig"/>
> -              <xsl:copy-of select="../loads"/>
> -              <Measurement>
> -                <xsl:for-each select="../Measurements/Profile/*">
> -                  <module>
> -                    <xsl:attribute name="name"><xsl:value-of select="name(.)"/></xsl:attribute>
> -                    <xsl:if test="@command_line">
> -                      <command_line><xsl:value-of select="@command_line"/></command_line>
> -                    </xsl:if>
> -                    <xsl:copy-of select="timestamps"/>
> -                  </module>
> -                </xsl:for-each>
> -              </Measurement>
> -              <hardware>
> -                <xsl:copy-of select="Memory|CPUtopology"/>
> -              </hardware>
> -            </rteval_details>
> -          </value>
> -          <value fid="5"><xsl:value-of select="../run_info/annotate"/></value>
> -          <value fid="6" type="array">
> -            <xsl:for-each select="CPUtopology/cpu[generate-id() = generate-id(key('pkgkey', @physical_package_id)[1])]">
> -              <xsl:call-template name="count_core_spread_v2x">
> -                <xsl:with-param name="pkgid" select="@physical_package_id"/>
> -              </xsl:call-template>
> -            </xsl:for-each>
> -          </value>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <xsl:template name="fields_rtevalruns_details">
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <fields>
> -      <field fid="0">rterid</field>
> -      <field fid="1">numa_nodes</field>
> -      <field fid="2">num_cpu_cores</field>
> -      <field fid="3">num_cpu_sockets</field>
> -      <field fid="4">xmldata</field>
> -      <field fid="5">annotation</field>
> -      <field fid="6">cpu_core_spread</field>
> -    </fields>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: cyclic_statistics - rteval - all version -->
> -  <xsl:template match="/rteval['2.0' > @version]/cyclictest|/rteval[@version >= '2.0']/Measurements/Profile/cyclictest"
> -                mode="tbl_cyclictest_statistics">
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.1" table="cyclic_statistics">
> -      <fields>
> -        <field fid="0">rterid</field>
> -        <field fid="1">coreid</field>
> -        <field fid="2">priority</field>
> -        <field fid="3">num_samples</field>
> -        <field fid="4">lat_min</field>
> -        <field fid="5">lat_max</field>
> -        <field fid="6">lat_mean</field>
> -        <field fid="7">mode</field>
> -        <field fid="8">range</field>
> -        <field fid="9">median</field>
> -        <field fid="10">stddev</field>
> -        <field fid="11">mean_abs_dev</field>
> -      </fields>
> -      <records>
> -        <xsl:for-each select="core/statistics[samples > 0]|system/statistics[samples > 0]">
> -          <record>
> -            <value fid="0"><xsl:value-of select="$rterid"/></value>
> -            <value fid="1"><xsl:choose>
> -              <xsl:when test="../@id"><xsl:value-of select="../@id"/></xsl:when>
> -              <xsl:otherwise><xsl:attribute name="isnull">1</xsl:attribute></xsl:otherwise></xsl:choose>
> -            </value>
> -            <value fid="2"><xsl:choose>
> -              <xsl:when test="../@priority"><xsl:value-of select="../@priority"/></xsl:when>
> -              <xsl:otherwise><xsl:attribute name="isnull">1</xsl:attribute></xsl:otherwise></xsl:choose>
> -            </value>
> -            <value fid="3"><xsl:value-of select="samples"/></value>
> -            <value fid="4"><xsl:value-of select="minimum"/></value>
> -            <value fid="5"><xsl:value-of select="maximum"/></value>
> -            <value fid="6"><xsl:value-of select="mean"/></value>
> -            <value fid="7"><xsl:value-of select="mode"/></value>
> -            <value fid="8"><xsl:value-of select="range"/></value>
> -            <value fid="9"><xsl:value-of select="median"/></value>
> -            <value fid="10"><xsl:value-of select="standard_deviation"/></value>
> -            <value fid="11"><xsl:value-of select="mean_absolute_deviation"/></value>
> -          </record>
> -        </xsl:for-each>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: cyclic_histogram - rteval - all version -->
> -  <xsl:template match="/rteval['2.0' > @version]/cyclictest|/rteval[@version >= '2.0']/Measurements/Profile/cyclictest"
> -                mode="tbl_cyclictest_histogram">
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.0" table="cyclic_histogram">
> -      <fields>
> -        <field fid="0">rterid</field>
> -        <field fid="1">core</field>
> -        <field fid="2">index</field>
> -        <field fid="3">value</field>
> -      </fields>
> -      <records>
> -        <!-- Do it in this order, so the overall system results are parsed first -->
> -        <xsl:apply-templates select="./system/histogram/bucket" mode="cyclic_histogram_rec_sql"/>
> -        <xsl:apply-templates select="./core/histogram/bucket" mode="cyclic_histogram_rec_sql"/>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <xsl:template match="/rteval['2.0' > @version]/cyclictest/*/histogram/bucket|/rteval[@version >= '2.0']/Measurements/Profile/cyclictest/*/histogram/bucket"
> -		mode="cyclic_histogram_rec_sql">
> -      <record>
> -	<value fid="0"><xsl:value-of select="$rterid"/></value>
> -	<value fid="1"><xsl:value-of select="../../@id"/></value>
> -	<value fid="2"><xsl:value-of select="@index"/></value>
> -	<value fid="3"><xsl:value-of select="@value"/></value>
> -      </record>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: hwlatdetect_summar - only for rteval 2.0 and newer -->
> -  <xsl:template match="/rteval[@version >= '2.0']/Measurements/Profile/hwlatdetect" mode="tbl_hwlatdetect_summary">
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.5" table="hwlatdetect_summary">
> -      <fields>
> -        <field fid="0">rterid</field>
> -        <field fid="1">duration</field>
> -        <field fid="2">threshold</field>
> -        <field fid="3">timewindow</field>
> -        <field fid="4">width</field>
> -        <field fid="5">samplecount</field>
> -        <field fid="6">hwlat_min</field>
> -        <field fid="7">hwlat_avg</field>
> -        <field fid="8">hwlat_max</field>
> -      </fields>
> -      <records>
> -        <record>
> -          <value fid="0"><xsl:value-of select="$rterid"/></value>
> -          <value fid="1"><xsl:value-of select="RunParams/@duration"/></value>
> -          <value fid="2"><xsl:value-of select="RunParams/@threshold"/></value>
> -          <value fid="3"><xsl:value-of select="RunParams/@window"/></value>
> -          <value fid="4"><xsl:value-of select="RunParams/@width"/></value>
> -          <value fid="5"><xsl:value-of select="samples/@count"/></value>
> -          <xsl:choose>
> -            <xsl:when test="samples/@count > 0">
> -              <value fid="6"><xsl:value-of select="math:min(samples/sample/@duration)"/></value>
> -              <value fid="7"><xsl:value-of select="sum(samples/sample/@duration) div samples/@count"/></value>
> -              <value fid="8"><xsl:value-of select="math:max(samples/sample/@duration)"/></value>
> -            </xsl:when>
> -            <xsl:otherwise>
> -              <value fid="6">0</value>
> -              <value fid="7">0</value>
> -              <value fid="8">0</value>
> -            </xsl:otherwise>
> -          </xsl:choose>
> -        </record>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -
> -
> -  <!-- TABLE: hwlatdetect_samples - only for rteval 2.0 and newer -->
> -  <xsl:template match="/rteval[@version >='2.0']/Measurements/Profile/hwlatdetect/samples" mode="tbl_hwlatdetect_samples">
> -    <xsl:if test="string(number($rterid)) = 'NaN'">
> -      <xsl:message terminate="yes">
> -        <xsl:text>Invalid 'rterid' parameter value: </xsl:text><xsl:value-of select="$rterid"/>
> -      </xsl:message>
> -    </xsl:if>
> -    <sqldata schemaver="1.5" table="hwlatdetect_samples">
> -      <fields>
> -        <field fid="0">rterid</field>
> -        <field fid="1">timestamp</field>
> -        <field fid="2">latency</field>
> -      </fields>
> -      <records>
> -        <xsl:apply-templates select="sample" mode="hwlatdetect_samples"/>
> -      </records>
> -    </sqldata>
> -  </xsl:template>
> -
> -  <xsl:template match="/rteval[@version >='2.0']/Measurements/Profile/hwlatdetect[@format='1.0']/samples/sample" mode="hwlatdetect_samples">
> -    <record>
> -      <value fid="0"><xsl:value-of select="$rterid"/></value>
> -      <value fid="1"><xsl:value-of select="@timestamp"/></value>
> -      <value fid="2"><xsl:value-of select="@duration"/></value>
> -    </record>
> -  </xsl:template>
> -
> -
> -
> -
> -  <!-- Helper "function" for generating a core per physical socket spread overview - for rteval v1.37 or older -->
> -  <xsl:template name="count_core_spread_v1x">
> -    <xsl:param name="pkgid"/>
> -    <value>
> -      <xsl:value-of select="count(/rteval/hardware/cpu_topology/cpu[@physical_package_id = $pkgid])"/>
> -    </value>
> -  </xsl:template>
> -
> -  <!-- Helper "function" for generating a core per physical socket spread overview - for rteval v2.0 or newer -->
> -  <xsl:template name="count_core_spread_v2x">
> -    <xsl:param name="pkgid"/>
> -    <value>
> -      <xsl:value-of select="count(/rteval/SystemInfo/CPUtopology/cpu[@physical_package_id = $pkgid])"/>
> -    </value>
> -  </xsl:template>
> -
> -</xsl:stylesheet>
> diff --git a/server/remove_rtevalrun b/server/remove_rtevalrun
> deleted file mode 100755
> index 8772b33..0000000
> --- a/server/remove_rtevalrun
> +++ /dev/null
> @@ -1,65 +0,0 @@
> -#!/usr/bin/python3 -tt
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   remove_rtevalrun
> -#   A script intended to be run on the database server, which
> -#   removes a given rteval run, based on the 'rterid' value
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import sys
> -import getpass
> -from argparse import ArgumentParser
> -from database import Database
> -
> -def do_delete(dbc, table, rterid):
> -    print "Cleaning up %s ..." % table,
> -    try:
> -        res = dbc.DELETE(table, {"rterid": int(rterid)})
> -        print "%i rows deleted" % res
> -    except Exception, err:
> -        print " ** FAILED **"
> -        print err
> -        dbc.ROLLBACK()
> -        sys.exit(2)
> -
> -
> -if __name__ == '__main__':
> -    parser = ArgumentParser(version="%prog v0.1")
> -
> -    parser.add_argument("-H", "--host", action="store", dest="dbhost", default="localhost",
> -                      help="Database server to connect to (default: %default)",
> -                      metavar="HOST")
> -    parser.add_argument("-p", "--port", action="store", dest="dbport", default="5432",
> -                      help="Database server port to use (default: %default)", metavar="PORT")
> -    parser.add_argument("-U", "--user", action="store", dest="dbuser", default="rtevaladmin",
> -                      help="Database user to connect as (default: %default)", metavar="USERNAME")
> -    parser.add_argument("-d", "--database", action="store", dest="dbname", default="rteval",
> -                      help="Database to use (default: %default)", metavar="DATABASE")
> -    parser.add_argument("-r", "--rterid", action="store", dest="rterid", default=None,
> -                      help="rteval run id to remove from the database", metavar="INTEGER")
> -    opts = parser.parse_args()
> -
> -    if opts.rterid is None:
> -        print "%s:  Missing --rterid value" % sys.argv[0]
> -        sys.exit(1)
> -
> -    dbpwd = getpass.getpass("Database password for '%s': " % opts.dbuser)
> -
> -    try:
> -        dbc = Database(host=opts.dbhost, port=opts.dbport,
> -                       user=opts.dbuser, password=dbpwd, database=opts.dbname)
> -    except Exception, err:
> -        print "Could not connect to the database: %s" % str(err)
> -        sys.exit(2)
> -
> -    # Do the cleanup
> -    do_delete(dbc, "cyclic_rawdata", opts.rterid)
> -    do_delete(dbc, "cyclic_statistics", opts.rterid)
> -    do_delete(dbc, "rtevalruns_details", opts.rterid)
> -    do_delete(dbc, "rtevalruns", opts.rterid)
> -
> -    dbc.COMMIT()
> -else:
> -    raise Exception, "This is a standalone program, not a module to be imported"
> diff --git a/server/rteval-parser.spec b/server/rteval-parser.spec
> deleted file mode 100644
> index 00c75bf..0000000
> --- a/server/rteval-parser.spec
> +++ /dev/null
> @@ -1,133 +0,0 @@
> -Name:		rteval-parser
> -Version:	1.6
> -%define sqlschemaver 1.5
> -Release:	1%{?dist}
> -Summary:	Report parser daemon for  rteval XML-RPC
> -%define pkgname rteval-xmlrpc-%{version}
> -
> -Group:		Applications/System
> -License:	GPLv2
> -URL:		http://git.kernel.org/?p=linux/kernel/git/clrkwllms/rteval.git
> -Source0:	%{pkgname}.tar.gz
> -BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
> -
> -BuildRequires:	postgresql-devel libxml2-devel libxslt-devel
> -Requires:	postgresql httpd mod_wsgi
> -Requires(post): chkconfig
> -Requires(preun): chkconfig
> -Requires(preun): /sbin/service
> -
> -
> -%description
> -The XML parser daemon (rteval-parserd) will parse the received reports
> -and save them in a database for further processing.
> -
> -%package -n rteval-xmlrpc
> -Summary:	XML-RPC server and parser for rteval
> -BuildArch:	noarch
> -
> -
> -%description -n rteval-xmlrpc
> -The XML-RPC server is using Apache and mod_python to receive reports from
> -rteval clients submitting test results via an XML-RPC API.
> -
> -
> -%prep
> -%setup -q -n %{pkgname}
> -
> -
> -%build
> -%configure --with-xmlrpc-webroot=%{_localstatedir}/www/html/rteval --docdir=%{_defaultdocdir}/%{pkgname}
> -make %{?_smp_mflags}
> -
> -
> -%install
> -rm -rf $RPM_BUILD_ROOT
> -make install DESTDIR=$RPM_BUILD_ROOT
> -mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/httpd/conf.d
> -cp apache-rteval.conf $RPM_BUILD_ROOT/%{_sysconfdir}/httpd/conf.d/rteval-xmlrpc.conf
> -
> -# Move the init script and config file from docs, to the proper place on RHEL/Fedora
> -mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/init.d $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig
> -mv $RPM_BUILD_ROOT/%{_defaultdocdir}/%{pkgname}/initscripts/rteval-parserd.init $RPM_BUILD_ROOT/%{_sysconfdir}/init.d/rteval-parserd
> -mv $RPM_BUILD_ROOT/%{_defaultdocdir}/%{pkgname}/initscripts/rteval-parserd.sysconfig $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/rteval-parserd
> -rmdir $RPM_BUILD_ROOT/%{_defaultdocdir}/%{pkgname}/initscripts
> -
> -
> -%post
> -/sbin/chkconfig --add rteval-parserd
> -
> -
> -%preun
> -if [ "$1" = 0 ] ; then
> -   /sbin/service rteval-parserd stop > /dev/null 2>&1
> -   /sbin/chkconfig --del rteval-parserd
> -fi
> -exit 0
> -
> -
> -%clean
> -rm -rf $RPM_BUILD_ROOT
> -
> -
> -%files
> -%defattr(-,root,root,-)
> -%doc COPYING parser/README.parser sql/rteval-%{sqlschemaver}.sql sql/delta-*_*.sql
> -%config(noreplace) %{_sysconfdir}/sysconfig/rteval-parserd
> -%attr(0755,root,root) %{_sysconfdir}/init.d/rteval-parserd
> -%{_bindir}/rteval-parserd
> -%{_datadir}/rteval/xmlparser.xsl
> -
> -
> -%files -n rteval-xmlrpc
> -%defattr(-,root,root,-)
> -%doc COPYING README.xmlrpc
> -%config(noreplace) %{_sysconfdir}/httpd/conf.d/rteval-xmlrpc.conf
> -%{_localstatedir}/www/html/rteval/
> -
> -
> -%changelog
> -* Thu Nov 15 2012 David Sommerseth <davids@xxxxxxxxxx> - 1.6-1
> -- Make rteval-parserd have no hard coded measurement data table restrictions
> -- Added support for hwlatdetect data
> -
> -* Fri Oct  7 2011 David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx> - 1.5-1
> -- Added support for storing data as arrays in PostgreSQL
> -- Updated SQL schema to store CPU topology/core spread as an array in the database
> -
> -* Fri Feb  4 2011 David Sommerseth <dazo@xxxxxxxxxxxxxxxxxxxxx> - 1.4-1
> -- Added support for mod_wsgi
> -- Updated SQL schema, to add rteval annotations to an explicit database column
> -
> -* Fri Apr  9 2010 David Sommerseth <davids@xxxxxxxxxx> - 1.3-1
> -- Updated XML-RPC server, added Hello method
> -
> -* Fri Mar 26 2010 David Sommerseth <davids@xxxxxxxxxx> - 1.2-2
> -- Improved logging
> -
> -* Fri Mar 26 2010 David Sommerseth <davids@xxxxxxxxxx> - 1.2-1
> -- Cleaned up xmlparser.xsl
> -- Honour 'isnull' attributes in SQL XML
> -- Improved IP address handling on system registration when ipaddr == NULL
> -- Fixed wrong GRANT statement in rteval_info table
> -
> -* Mon Mar 22 2010 David Sommerseth <davids@xxxxxxxxxx> - 1.1-2
> -- rteval-xmlrpc.spec renamed to rteval-parser.spec
> -- Split XML-RPC noarch related files and the binary part with rteval-parserd
> -- Reorganised the .spec file - rteval-xmlrpc RPM is now a noarch sub-package
> -- Consider the renamed rteval_parserd -> rteval-parserd
> -- Install /etc/init.d/rteval-parserd and /etc/sysconfig/rteval-parserd
> -
> -* Tue Dec  8 2009 David Sommerseth <davids@xxxxxxxxxx> - 1.1-1
> -- Updated to rteval-xmlrpc v1.1
> -  - Added new database table, rteval_info, containing some information about the
> -    rteval-xmlrpc installation
> -  - Made rteval_parserd aware of which SQL schema version it is working against
> -  - Added 'schemaver' attributes to <sqldata/> tags, defining which SQL schema
> -    version which is needed
> -  - Added mean_absolute_deviation and variance fields from rteval XML reports to
> -    the database
> -
> -* Thu Dec  3 2009 David Sommerseth <davids@xxxxxxxxxx> - 1.0-1
> -- Inital rteval-xmlrpc.spec file
> -
> diff --git a/server/rteval_testserver.py b/server/rteval_testserver.py
> deleted file mode 100644
> index f141b52..0000000
> --- a/server/rteval_testserver.py
> +++ /dev/null
> @@ -1,107 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rteval_testserver.py
> -#   Local XML-RPC test server.  Can be used to verify XML-RPC behavoiur
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import os
> -import sys
> -import signal
> -from xmlrpc.server import SimpleXMLRPCServer
> -from xmlrpc.server import SimpleXMLRPCRequestHandler
> -import argparse
> -
> -import xmlrpc_API1
> -from Logger import Logger
> -
> -# Default values
> -LISTEN="127.0.0.1"
> -PORT=65432
> -
> -# Restrict to a particular path.
> -class RequestHandler(SimpleXMLRPCRequestHandler):
> -    rpc_paths = ('/rteval/API1/',)
> -
> -
> -class RTevald_config(object):
> -    def __init__(self):
> -        self.config = {'datadir': '/tmp/rteval-xmlrpc-testsrv',
> -                       'db_server': 'localhost',
> -                       'db_port': 5432,
> -                       'database': 'dummy',
> -                       'db_username': None,
> -                       'db_password': None}
> -        self.__update_vars()
> -
> -    def __update_vars(self):
> -        for k in list(self.config.keys()):
> -            self.__dict__[k] = self.config[k]
> -
> -
> -class RTevald():
> -    def __init__(self, options, log):
> -        self.options = options
> -        self.log = log
> -        self.server = None
> -        self.config = RTevald_config()
> -
> -    def __prepare_datadir(self):
> -        startdir = os.getcwd()
> -        for dir in self.config.datadir.split("/"):
> -            if dir is '':
> -                continue
> -            if not os.path.exists(dir):
> -                os.mkdir(dir, 0o700)
> -            os.chdir(dir)
> -        if not os.path.exists('queue'):
> -            os.mkdir('queue', 0o700)
> -        os.chdir(startdir)
> -
> -    def StartServer(self):
> -        # Create server
> -        self.server = SimpleXMLRPCServer((self.options.listen, self.options.port),
> -                                         requestHandler=RequestHandler)
> -        self.server.register_introspection_functions()
> -
> -        # setup a class to handle requests
> -        self.server.register_instance(xmlrpc_API1.XMLRPC_API1(self.config, nodbaction=True, debug=True))
> -
> -        # Run the server's main loop
> -        self.log.Log("StartServer", "Listening on %s:%i" % (self.options.listen, self.options.port))
> -        try:
> -            self.__prepare_datadir()
> -            self.server.serve_forever()
> -        except KeyboardInterrupt:
> -            self.log.Log("StartServer", "Server caught SIGINT")
> -            self.server.shutdown()
> -        finally:
> -            self.log.Log("StartServer", "Server stopped")
> -
> -    def StopServer(self):
> -        self.server.shutdown()
> -
> -
> -logger = None
> -rtevalserver = None
> -
> -#
> -#  M A I N   F U N C T I O N
> -#
> -
> -if __name__ == '__main__':
> -    parser = argparse.ArgumentParser(version="%prog v0.1")
> -
> -    parser.add_argument("-L", "--listen", action="store", dest="listen", default=LISTEN,
> -                      help="Which interface to listen to [default: %default]", metavar="IPADDR")
> -    parser.add_argument("-P", "--port", action="store", type="int", dest="port", default=PORT,
> -                      help="Which port to listen to [default: %default]",  metavar="PORT")
> -    parser.add_argument("-l", "--log", action="store", dest="logfile", default=None,
> -                      help="Where to log requests.", metavar="FILE")
> -
> -    options = parser.parse_args()
> -
> -    logger = Logger(options.logfile, "RTeval")
> -    rtevalserver = RTevald(options, logger)
> -    rtevalserver.StartServer()
> diff --git a/server/rteval_xmlrpc.py b/server/rteval_xmlrpc.py
> deleted file mode 100644
> index b63b7d8..0000000
> --- a/server/rteval_xmlrpc.py
> +++ /dev/null
> @@ -1,71 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rteval_xmlrpc.py
> -#   XML-RPC handler for mod_python which will receive requests
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import types
> -from mod_python import apache
> -from xmlrpc.client import dumps, loads, Fault
> -from xmlrpc_API1 import XMLRPC_API1
> -from rteval.rtevalConfig import rtevalConfig
> -
> -
> -def Dispatch(req, method, args):
> -    # Default configuration
> -    defcfg = {'xmlrpc_server': { 'datadir':     '/var/lib/rteval',
> -                                 'db_server':   'localhost',
> -                                 'db_port':     5432,
> -                                 'database':    'rteval',
> -                                 'db_username': 'rtevxmlrpc',
> -                                 'db_password': 'rtevaldb'
> -                                 }
> -              }
> -
> -    # Fetch configuration
> -    cfg = rtevalConfig(defcfg)
> -    cfg.Load(append=True)
> -
> -    # Prepare an object for executing the query
> -    xmlrpc = XMLRPC_API1(config=cfg.GetSection('xmlrpc_server'))
> -
> -    # Exectute it
> -    result = xmlrpc.Dispatch(method, args)
> -
> -    # Send the result
> -    if type(result) == tuple:
> -        req.write(dumps(result, None, methodresponse=1))
> -    else:
> -        req.write(dumps((result,), None, methodresponse=1))
> -
> -
> -def handler(req):
> -    # Only accept POST requests
> -    if req.method != 'POST':
> -        req.content_type = 'text/plain'
> -        req.send_http_header()
> -        req.write("Not valid XML-RPC POST request")
> -        return apache.OK
> -
> -    # Fetch the request
> -    body = req.read()
> -
> -    # Prepare response
> -    req.content_type = "text/xml"
> -    req.send_http_header()
> -
> -    # Process request
> -    try:
> -        args, method = loads(body)
> -    except:
> -        fault = Fault(0x001, "Invalid XML-RPC error")
> -        req.write(dumps(fault, methodresponse=1))
> -        return apache.OK
> -
> -    # Execute it.  The calling function is
> -    # responsive for responding to the request.
> -    Dispatch(req, method, args)
> -
> -    return apache.OK
> diff --git a/server/rteval_xmlrpc.wsgi b/server/rteval_xmlrpc.wsgi
> deleted file mode 100644
> index 1bf6661..0000000
> --- a/server/rteval_xmlrpc.wsgi
> +++ /dev/null
> @@ -1,94 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rteval_xmlrpc.wsgi
> -#   XML-RPC handler for the rteval server, using mod_wsgi
> -#
> -#   Copyright 2011 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -from wsgiref.simple_server import make_server
> -import types
> -from xmlrpclib import dumps, loads, Fault
> -from xmlrpc_API1 import XMLRPC_API1
> -from rteval.rtevalConfig import rtevalConfig
> -
> -def rtevalXMLRPC_Dispatch(method, args):
> -    # Default configuration
> -    defcfg = {'xmlrpc_server': { 'datadir':     './var/lib/rteval',
> -                                 'db_server':   'localhost',
> -                                 'db_port':     5432,
> -                                 'database':    'rteval',
> -                                 'db_username': 'rtevxmlrpc',
> -                                 'db_password': 'rtevaldb'
> -                                 }
> -              }
> -
> -    # Fetch configuration
> -    cfg = rtevalConfig(defcfg)
> -    cfg.Load(append=True)
> -
> -    # Prepare an object for executing the query
> -    xmlrpc = XMLRPC_API1(config=cfg.GetSection('xmlrpc_server'))
> -
> -    # Exectute it
> -    result = xmlrpc.Dispatch(method, args)
> -
> -    # Send the result
> -    if type(result) == types.TupleType:
> -        return dumps(result, None, methodresponse=1)
> -    else:
> -        return dumps((result,), None, methodresponse=1)
> -
> -
> -def rtevalXMLRPC_handler(environ, start_response):
> -
> -   # the environment variable CONTENT_LENGTH may be empty or missing
> -   try:
> -      request_body_size = int(environ.get('CONTENT_LENGTH', 0))
> -   except (ValueError):
> -      request_body_size = 0
> -
> -   # When the method is POST the query string will be sent
> -   # in the HTTP request body which is passed by the WSGI server
> -   # in the file like wsgi.input environment variable.
> -   try:
> -       if (environ['REQUEST_METHOD'] != 'POST') or (request_body_size < 1):
> -           raise Exception('Error in request')
> -
> -       request_body = environ['wsgi.input'].read(request_body_size)
> -       try:
> -           args, method = loads(request_body)
> -       except:
> -           raise Exception('Invalid XML-RPC request')
> -
> -       # Execute the XML-RPC call
> -       status = '200 OK'
> -       cont_type = 'text/xml'
> -       response = [rtevalXMLRPC_Dispatch(method, args)]
> -   except Exception, ex:
> -       status = '500 Internal server error: %s' % str(ex)
> -       cont_type = 'text/plain'
> -       response = [
> -           '500 Internal server error\n',
> -           'ERROR: %s' % str(ex)
> -           ]
> -       import traceback, sys
> -       traceback.print_exc(file=sys.stderr)
> -
> -   response_headers = [('Content-Type', cont_type),
> -                       ('Content-Length', str(len("".join(response))))]
> -   start_response(status, response_headers)
> -   return response
> -
> -
> -if __name__ == '__main__':
> -    #
> -    # Simple stand-alone XML-RPC server, if started manually
> -    # Not suitable for production environments, but for testing
> -    #
> -    httpd = make_server('localhost', 65432, rtevalXMLRPC_handler)
> -    try:
> -        httpd.serve_forever()
> -    except KeyboardInterrupt:
> -        print "\nShutting down"
> -
> diff --git a/server/rtevaldb.py b/server/rtevaldb.py
> deleted file mode 100644
> index b13c85b..0000000
> --- a/server/rtevaldb.py
> +++ /dev/null
> @@ -1,57 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   rtevaldb.py
> -#   Function for registering a rteval summary.xml report into the database
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import os
> -from database import Database
> -
> -def register_submission(config, clientid, filename, debug=False, noaction=False):
> -    "Registers a submission of a rteval report which signalises the rteval_parserd process"
> -
> -    dbc = Database(host=config.db_server, port=config.db_port, database=config.database,
> -                   user=config.db_username, password=config.db_password,
> -                   debug=debug, noaction=noaction)
> -
> -    submvars = {"table": "submissionqueue",
> -                "fields": ["clientid", "filename"],
> -                "records": [[clientid, filename]],
> -                "returning": "submid"
> -                }
> -
> -    res = dbc.INSERT(submvars)
> -    if len(res) != 1:
> -        raise Exception("Could not register the submission")
> -
> -    dbc.COMMIT()
> -    return res[0]
> -
> -def database_status(config, debug=False, noaction=False):
> -    dbc = Database(host=config.db_server, port=config.db_port, database=config.database,
> -                   user=config.db_username, password=config.db_password,
> -                   debug=debug, noaction=noaction)
> -    if not dbc:
> -        return {"status": "No connection to pgsql://%s:%s/%s" % (config.db_server,
> -                                                                 config.db_port,
> -                                                                 config.database)}
> -
> -    res = dbc.SELECT('rtevalruns',
> -                     ["to_char(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS') AS server_time",
> -                      "max(rterid) AS last_rterid",
> -                      "max(submid) AS last_submid"]
> -                     )
> -    if len(res) != 3:
> -        return {"status": "Could not query database pgsql://%s:%s/%s" % (config.db_server,
> -                                                                         config.db_port,
> -                                                                         config.database)}
> -    last_rterid = res['records'][0][1] and res['records'][0][1] or "(None)"
> -    last_submid = res['records'][0][1] and res['records'][0][2] or "(None)"
> -    return {"status": "OK",
> -            "server_time": res['records'][0][0],
> -            "last_rterid": last_rterid,
> -            "last_submid": last_submid
> -            }
> -
> diff --git a/server/sql/delta-1.0_1.1.sql b/server/sql/delta-1.0_1.1.sql
> deleted file mode 100644
> index 9fe230e..0000000
> --- a/server/sql/delta-1.0_1.1.sql
> +++ /dev/null
> @@ -1,15 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- SQL delta update from rteval-1.0.sql to rteval-1.1.sql
> -
> -CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -);
> -GRANT SELECT ON rteval_info TO rtevparser;
> -INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.1');
> -
> -ALTER TABLE cyclic_statistics ADD COLUMN mean_abs_dev REAL;
> -ALTER TABLE cyclic_statistics ADD COLUMN variance REAL;
> -
> diff --git a/server/sql/delta-1.1_1.2.sql b/server/sql/delta-1.1_1.2.sql
> deleted file mode 100644
> index e5d82ab..0000000
> --- a/server/sql/delta-1.1_1.2.sql
> +++ /dev/null
> @@ -1,9 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- SQL delta update from rteval-1.1.sql to rteval-1.2.sql
> -
> -UPDATE rteval_info SET value = '1.2' WHERE key = 'sql_schema_ver';
> -
> -ALTER TABLE rtevalruns ADD COLUMN distro VARCHAR(128);
> -ALTER TABLE rtevalruns_details ADD COLUMN num_cpu_cores INTEGER;
> -ALTER TABLE rtevalruns_details ADD COLUMN num_cpu_sockets INTEGER;
> -ALTER TABLE rtevalruns_details ADD COLUMN numa_nodes INTEGER;
> diff --git a/server/sql/delta-1.2_1.3.sql b/server/sql/delta-1.2_1.3.sql
> deleted file mode 100644
> index 1c10bf2..0000000
> --- a/server/sql/delta-1.2_1.3.sql
> +++ /dev/null
> @@ -1,6 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- SQL delta update from rteval-1.2.sql to rteval-1.3.sql
> -
> -UPDATE rteval_info SET value = '1.3' WHERE key = 'sql_schema_ver';
> -
> -ALTER TABLE rtevalruns_details ADD COLUMN annotation TEXT;
> diff --git a/server/sql/delta-1.3_1.4.sql b/server/sql/delta-1.3_1.4.sql
> deleted file mode 100644
> index e0c0162..0000000
> --- a/server/sql/delta-1.3_1.4.sql
> +++ /dev/null
> @@ -1,6 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- SQL delta update from rteval-1.3.sql to rteval-1.4.sql
> -
> -UPDATE rteval_info SET value = '1.4' WHERE key = 'sql_schema_ver';
> -
> -ALTER TABLE rtevalruns_details ADD COLUMN cpu_core_spread INTEGER[];
> diff --git a/server/sql/delta-1.4_1.5.sql b/server/sql/delta-1.4_1.5.sql
> deleted file mode 100644
> index bd1336e..0000000
> --- a/server/sql/delta-1.4_1.5.sql
> +++ /dev/null
> @@ -1,31 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- SQL delta update from rteval-1.4.sql to rteval-1.5.sql
> -
> -UPDATE rteval_info SET value = '1.5' WHERE key = 'sql_schema_ver';
> -
> --- TABLE: hwlatdetect_summary
> --- Tracks hwlatdetect results for a particular hardware
> ---
> -   CREATE TABLE hwlatdetect_summary (
> -       rterid         INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -       duration       INTEGER NOT NULL,
> -       threshold      INTEGER NOT NULL,
> -       timewindow     INTEGER NOT NULL,
> -       width          INTEGER NOT NULL,
> -       samplecount    INTEGER NOT NULL,
> -       hwlat_min      REAL NOT NULL,
> -       hwlat_avg      REAL NOT NULL,
> -       hwlat_max      REAL NOT NULL
> -   ) WITHOUT OIDS;
> -   GRANT SELECT, INSERT ON hwlatdetect_summary TO rtevparser;
> -
> --- TABLE: hwlatdetect_samples
> --- Contains the hwlatdetect sample records from a particular run
> ---
> -   CREATE TABLE hwlatdetect_samples (
> -       rterid         INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -       timestamp      NUMERIC(20,10) NOT NULL,
> -       latency        REAL NOT NULL
> -   ) WITHOUT OIDS;
> -   GRANT SELECT, INSERT ON hwlatdetect_samples TO rtevparser;
> -
> diff --git a/server/sql/rteval-1.0.sql b/server/sql/rteval-1.0.sql
> deleted file mode 100644
> index 107c90e..0000000
> --- a/server/sql/rteval-1.0.sql
> +++ /dev/null
> @@ -1,189 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr      
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        xmldata       xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different 
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/sql/rteval-1.1.sql b/server/sql/rteval-1.1.sql
> deleted file mode 100644
> index 6ec783f..0000000
> --- a/server/sql/rteval-1.1.sql
> +++ /dev/null
> @@ -1,203 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- TABLE: rteval_info
> --- Contains information the current rteval XML-RPC and parser installation
> ---
> -    CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -    );
> -    GRANT SELECT ON rteval_info TO rtevaldb_parser;
> -    INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.1');
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -    CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        xmldata       xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -	mean_abs_dev  REAL NOT NULL,
> -	variance      REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/sql/rteval-1.2.sql b/server/sql/rteval-1.2.sql
> deleted file mode 100644
> index 4a37eb6..0000000
> --- a/server/sql/rteval-1.2.sql
> +++ /dev/null
> @@ -1,207 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- TABLE: rteval_info
> --- Contains information the current rteval XML-RPC and parser installation
> ---
> -    CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -    );
> -    GRANT SELECT ON rteval_info TO rtevparser;
> -    INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.2');
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -    CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -	distro		VARCHAR(64),
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid          INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        num_cpu_cores   INTEGER,
> -        num_cpu_sockets INTEGER,
> -        numa_nodes      INTEGER,
> -        xmldata         xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -	mean_abs_dev  REAL NOT NULL,
> -	variance      REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/sql/rteval-1.3.sql b/server/sql/rteval-1.3.sql
> deleted file mode 100644
> index ca7837b..0000000
> --- a/server/sql/rteval-1.3.sql
> +++ /dev/null
> @@ -1,208 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- TABLE: rteval_info
> --- Contains information the current rteval XML-RPC and parser installation
> ---
> -    CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -    );
> -    GRANT SELECT ON rteval_info TO rtevparser;
> -    INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.3');
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -    CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -	distro		VARCHAR(64),
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid          INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        annotation      TEXT,
> -        num_cpu_cores   INTEGER,
> -        num_cpu_sockets INTEGER,
> -        numa_nodes      INTEGER,
> -        xmldata         xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -	mean_abs_dev  REAL NOT NULL,
> -	variance      REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/sql/rteval-1.4.sql b/server/sql/rteval-1.4.sql
> deleted file mode 100644
> index 6d3efdd..0000000
> --- a/server/sql/rteval-1.4.sql
> +++ /dev/null
> @@ -1,209 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- TABLE: rteval_info
> --- Contains information the current rteval XML-RPC and parser installation
> ---
> -    CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -    );
> -    GRANT SELECT ON rteval_info TO rtevparser;
> -    INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.4');
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -    CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -	distro		VARCHAR(64),
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid          INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        annotation      TEXT,
> -        num_cpu_cores   INTEGER,
> -        num_cpu_sockets INTEGER,
> -        cpu_core_spread INTEGER[],
> -        numa_nodes      INTEGER,
> -        xmldata         xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -	mean_abs_dev  REAL NOT NULL,
> -	variance      REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/sql/rteval-1.5.sql b/server/sql/rteval-1.5.sql
> deleted file mode 100644
> index 68e0fcc..0000000
> --- a/server/sql/rteval-1.5.sql
> +++ /dev/null
> @@ -1,235 +0,0 @@
> --- SPDX-License-Identifier: GPL-2.0-or-later
> --- Create rteval database users
> ---
> -CREATE USER rtevxmlrpc NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb';
> -CREATE USER rtevparser NOSUPERUSER ENCRYPTED PASSWORD 'rtevaldb_parser';
> -
> --- Create rteval database
> ---
> -CREATE DATABASE rteval ENCODING 'utf-8';
> -
> -\c rteval
> -
> --- TABLE: rteval_info
> --- Contains information the current rteval XML-RPC and parser installation
> ---
> -    CREATE TABLE rteval_info (
> -       key    varchar(32) NOT NULL,
> -       value  TEXT NOT NULL,
> -       rtiid  SERIAL,
> -       PRIMARY KEY(rtiid)
> -    );
> -    GRANT SELECT ON rteval_info TO rtevparser;
> -    INSERT INTO rteval_info (key, value) VALUES ('sql_schema_ver','1.5');
> -
> --- Enable plpgsql.  It is expected that this PL/pgSQL is available.
> -    CREATE LANGUAGE 'plpgsql';
> -
> --- FUNCTION: trgfnc_submqueue_notify
> --- Trigger function which is called on INSERT queries to the submissionqueue table.
> --- It will send a NOTIFY rteval_submq on INSERTs.
> ---
> -    CREATE FUNCTION trgfnc_submqueue_notify() RETURNS TRIGGER
> -    AS $BODY$
> -      DECLARE
> -      BEGIN
> -        NOTIFY rteval_submq;
> -        RETURN NEW;
> -      END
> -    $BODY$ LANGUAGE 'plpgsql';
> -
> -    -- The user(s) which are allowed to do INSERT on the submissionqueue
> -    -- must also be allowed to call this trigger function.
> -    GRANT EXECUTE ON FUNCTION trgfnc_submqueue_notify() TO rtevxmlrpc;
> -
> --- TABLE: submissionqueue
> --- All XML-RPC clients registers their submissions into this table.  Another parser thread
> --- will pickup the records where parsestart IS NULL.
> ---
> -    CREATE TABLE submissionqueue (
> -           clientid   varchar(128) NOT NULL,
> -           filename   VARCHAR(1024) NOT NULL,
> -           status     INTEGER DEFAULT '0',
> -           received   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
> -           parsestart TIMESTAMP WITH TIME ZONE,
> -           parseend   TIMESTAMP WITH TIME ZONE,
> -           submid     SERIAL,
> -           PRIMARY KEY(submid)
> -    ) WITH OIDS;
> -    CREATE INDEX submissionq_status ON submissionqueue(status);
> -
> -    CREATE TRIGGER trg_submissionqueue AFTER INSERT
> -           ON submissionqueue FOR EACH STATEMENT
> -	   EXECUTE PROCEDURE trgfnc_submqueue_notify();
> -
> -    GRANT SELECT, INSERT ON submissionqueue TO rtevxmlrpc;
> -    GRANT USAGE ON submissionqueue_submid_seq TO rtevxmlrpc;
> -    GRANT SELECT, UPDATE ON submissionqueue TO rtevparser;
> -
> --- TABLE: systems
> --- Overview table over all systems which have sent reports
> --- The dmidata column will keep the complete DMIdata available
> --- for further information about the system.
> ---
> -    CREATE TABLE systems (
> -        syskey        SERIAL NOT NULL,
> -        sysid         VARCHAR(64) NOT NULL,
> -        dmidata       xml NOT NULL,
> -        PRIMARY KEY(syskey)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON systems TO rtevparser;
> -    GRANT USAGE ON systems_syskey_seq TO rtevparser;
> -
> --- TABLE: systems_hostname
> --- This table is used to track the hostnames and IP addresses
> --- a registered system have used over time
> ---
> -   CREATE TABLE systems_hostname (
> -        syskey        INTEGER REFERENCES systems(syskey) NOT NULL,
> -        hostname      VARCHAR(256) NOT NULL,
> -        ipaddr        cidr
> -    ) WITH OIDS;
> -    CREATE INDEX systems_hostname_syskey ON systems_hostname(syskey);
> -    CREATE INDEX systems_hostname_hostname ON systems_hostname(hostname);
> -    CREATE INDEX systems_hostname_ipaddr ON systems_hostname(ipaddr);
> -
> -    GRANT SELECT, INSERT ON systems_hostname TO rtevparser;
> -
> -
> --- TABLE: rtevalruns
> --- Overview over all rteval runs, when they were run and how long they ran.
> ---
> -    CREATE TABLE rtevalruns (
> -        rterid          SERIAL NOT NULL, -- RTEval Run Id
> -        submid          INTEGER REFERENCES submissionqueue(submid) NOT NULL,
> -        syskey          INTEGER REFERENCES systems(syskey) NOT NULL,
> -        kernel_ver      VARCHAR(32) NOT NULL,
> -        kernel_rt       BOOLEAN NOT NULL,
> -        arch            VARCHAR(12) NOT NULL,
> -	distro		VARCHAR(64),
> -        run_start       TIMESTAMP WITH TIME ZONE NOT NULL,
> -        run_duration    INTEGER NOT NULL,
> -        load_avg        REAL NOT NULL,
> -        version         VARCHAR(4), -- Version of rteval
> -        report_filename TEXT,
> -        PRIMARY KEY(rterid)
> -    ) WITH OIDS;
> -
> -    GRANT SELECT,INSERT ON rtevalruns TO rtevparser;
> -    GRANT SELECT ON rtevalruns TO rtevxmlrpc;
> -    GRANT USAGE ON rtevalruns_rterid_seq TO rtevparser;
> -
> --- TABLE rtevalruns_details
> --- More specific information on the rteval run.  The data is stored
> --- in XML for flexibility
> ---
> --- Tags being saved here includes: /rteval/clocksource, /rteval/hardware,
> --- /rteval/loads and /rteval/cyclictest/command_line
> ---
> -    CREATE TABLE rtevalruns_details (
> -        rterid          INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        annotation      TEXT,
> -        num_cpu_cores   INTEGER,
> -        num_cpu_sockets INTEGER,
> -        cpu_core_spread INTEGER[],
> -        numa_nodes      INTEGER,
> -        xmldata         xml NOT NULL,
> -        PRIMARY KEY(rterid)
> -    );
> -    GRANT INSERT ON rtevalruns_details TO rtevparser;
> -
> --- TABLE: cyclic_statistics
> --- This table keeps statistics overview over a particular rteval run
> ---
> -    CREATE TABLE cyclic_statistics (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        coreid        INTEGER, -- NULL=system
> -        priority      INTEGER, -- NULL=system
> -        num_samples   BIGINT NOT NULL,
> -        lat_min       REAL NOT NULL,
> -        lat_max       REAL NOT NULL,
> -        lat_mean      REAL NOT NULL,
> -        mode          REAL NOT NULL,
> -        range         REAL NOT NULL,
> -        median        REAL NOT NULL,
> -        stddev        REAL NOT NULL,
> -	mean_abs_dev  REAL NOT NULL,
> -	variance      REAL NOT NULL,
> -        cstid         SERIAL NOT NULL, -- unique record ID
> -        PRIMARY KEY(cstid)
> -    ) WITH OIDS;
> -    CREATE INDEX cyclic_statistics_rterid ON cyclic_statistics(rterid);
> -
> -    GRANT INSERT ON cyclic_statistics TO rtevparser;
> -    GRANT USAGE ON cyclic_statistics_cstid_seq TO rtevparser;
> -
> --- TABLE: cyclic_histogram
> --- This table keeps the raw histogram data for each rteval run being
> --- reported.
> ---
> -    CREATE TABLE cyclic_histogram (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        core          INTEGER, -- NULL=system
> -        index         INTEGER NOT NULL,
> -        value         BIGINT NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_histogram_rterid ON cyclic_histogram(rterid);
> -
> -    GRANT INSERT ON cyclic_histogram TO rtevparser;
> -
> --- TABLE: cyclic_rawdata
> --- This table keeps the raw data for each rteval run being reported.
> --- Due to that it will be an enormous amount of data, we avoid using
> --- OID on this table.
> ---
> -    CREATE TABLE cyclic_rawdata (
> -        rterid        INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -        cpu_num       INTEGER NOT NULL,
> -        sampleseq     INTEGER NOT NULL,
> -        latency       REAL NOT NULL
> -    ) WITHOUT OIDS;
> -    CREATE INDEX cyclic_rawdata_rterid ON cyclic_rawdata(rterid);
> -
> -    GRANT INSERT ON cyclic_rawdata TO rtevparser;
> -
> --- TABLE: hwlatdetect_summary
> --- Tracks hwlatdetect results for a particular hardware
> ---
> -   CREATE TABLE hwlatdetect_summary (
> -       rterid         INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -       duration       INTEGER NOT NULL,
> -       threshold      INTEGER NOT NULL,
> -       timewindow     INTEGER NOT NULL,
> -       width          INTEGER NOT NULL,
> -       samplecount    INTEGER NOT NULL,
> -       hwlat_min      REAL NOT NULL,
> -       hwlat_avg      REAL NOT NULL,
> -       hwlat_max      REAL NOT NULL
> -   ) WITHOUT OIDS;
> -   GRANT SELECT, INSERT ON hwlatdetect_summary TO rtevparser;
> -
> --- TABLE: hwlatdetect_samples
> --- Contains the hwlatdetect sample records from a particular run
> ---
> -   CREATE TABLE hwlatdetect_samples (
> -       rterid         INTEGER REFERENCES rtevalruns(rterid) NOT NULL,
> -       timestamp      NUMERIC(20,10) NOT NULL,
> -       latency        REAL NOT NULL
> -   ) WITHOUT OIDS;
> -   GRANT SELECT, INSERT ON hwlatdetect_samples TO rtevparser;
> -
> --- TABLE: notes
> --- This table is purely to make notes, connected to different
> --- records in the database
> ---
> -    CREATE TABLE notes (
> -        ntid          SERIAL NOT NULL,
> -        reftbl        CHAR NOT NULL,    -- S=systems, R=rtevalruns
> -        refid         INTEGER NOT NULL, -- reference id, to the corresponding table
> -        notes         TEXT NOT NULL,
> -        createdby     VARCHAR(48),
> -        created       TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
> -        PRIMARY KEY(ntid)
> -    ) WITH OIDS;
> -    CREATE INDEX notes_refid ON notes(reftbl,refid);
> diff --git a/server/testclient.py b/server/testclient.py
> deleted file mode 100644
> index dc9745b..0000000
> --- a/server/testclient.py
> +++ /dev/null
> @@ -1,37 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   testclient.py
> -#   XML-RPC test client for testing the supported XML-RPC API 
> -#   in the rteval server.
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import sys
> -import libxml2
> -import io
> -
> -sys.path.append('../rteval')
> -import rtevalclient
> -
> -print("** Creating doc")
> -d = libxml2.newDoc("1.0")
> -n = libxml2.newNode('TestNode1')
> -d.setRootElement(n)
> -n2 = n.newTextChild(None, 'TestNode2','Just a little test')
> -n2.newProp('test','true')
> -
> -for i in range(1,5):
> -    n2 = n.newTextChild(None, 'TestNode3', 'Test line %i' %i)
> -
> -print("** Doc to be sent")
> -d.saveFormatFileEnc('-','UTF-8', 1)
> -
> -
> -print("** Testing API")
> -client = rtevalclient.rtevalclient("http://localhost:65432/rteval/API1/";)
> -
> -print("** 1: Hello(): %s" % str(client.Hello()))
> -status = client.SendReport(d)
> -print("** 2: SendReport(xmlDoc): %s" % str(status))
> -
> diff --git a/server/testclient_sendreportfile b/server/testclient_sendreportfile
> deleted file mode 100755
> index 5d3ed74..0000000
> --- a/server/testclient_sendreportfile
> +++ /dev/null
> @@ -1,36 +0,0 @@
> -#!/usr/bin/python3 -tt
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   testclient_sendfile.py
> -#   XML-RPC test client which just sends an XML file to the given rteval server
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import sys
> -import libxml2
> -from argparse import ArgumentParser
> -
> -sys.path.append('../rteval')
> -import rtevalclient
> -
> -if __name__ == '__main__':
> -    parser = ArgumentParser(version="%prog v0.1")
> -
> -    parser.add_argument("-r", "--report", action="store", dest="report", default="summary.xml",
> -                      help="Which XML report to send to the XML-RPC server  (default: %default)",
> -                      metavar="FILE")
> -    parser.add_argument("-X", "--xmlrpc-submit", dest="xmlrpchost", default="localhost:65432",
> -                      help="Hostname to the XML-RPC server to send the data (default: %default)",
> -                      metavar="HOST[:PORT]")
> -
> -    opts = parser.parse_args()
> -
> -    d = libxml2.parseFile(opts.report)
> -
> -    client = rtevalclient.rtevalclient("http://%s/rteval/API1/"; % opts.xmlrpchost)
> -
> -    status = client.SendReport(d)
> -    print "SendReport(xmlDoc): %s" % status
> -else:
> -    raise Exception, "This is a standalone program, not a module to be imported"
> diff --git a/server/unittest.py b/server/unittest.py
> deleted file mode 100644
> index 73cee9d..0000000
> --- a/server/unittest.py
> +++ /dev/null
> @@ -1,91 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -import sys, threading, time, signal, libxml2
> -import argparse
> -from rteval_testserver import RTevald
> -from Logger import Logger
> -
> -sys.path.insert(0,'..')
> -sys.path.insert(0,'../rteval')
> -sys.path.insert(0,'rteval')
> -import rtevalclient
> -
> -class ServerThread(threading.Thread):
> -    def __init__(self, port):
> -        threading.Thread.__init__(self)
> -        self.port = port
> -        self.log = Logger('unit-test-server.log','rteval-xmlrpc-testsrv')
> -
> -        parser = argparse.ArgumentParser()
> -        parser.add_argument("-L", "--listen", action="store", dest="listen", default="127.0.0.1",
> -                          help="Which interface to listen to [default: %default]", metavar="IPADDR")
> -        parser.add_argument("-P", "--port", action="store", type="int", dest="port", default=self.port,
> -                          help="Which port to listen to [default: %default]",  metavar="PORT")
> -
> -        (options, args) = parser.parse_args()
> -
> -        self.child = RTevald(options, self.log)
> -
> -    def run(self):
> -        self.child.StartServer()
> -
> -    def stop(self):
> -        self.child.StopServer()
> -
> -    def sigcatch(self, signum, frame):
> -        print("Shutting down")
> -        self.stop()
> -
> -
> -class ClientTest(object):
> -    def __init__(self, port):
> -        self.client = rtevalclient.rtevalclient("http://localhost:%s/rteval/API1/"; % port)
> -
> -    def __prepare_data(self):
> -        d = libxml2.newDoc("1.0")
> -        n = libxml2.newNode('TestNode1')
> -        d.setRootElement(n)
> -        n2 = n.newTextChild(None, 'TestNode2','Just a little test')
> -        n2.newProp('test','true')
> -        for i in range(1,5):
> -            n2 = n.newTextChild(None, 'TestNode3', 'Test line %i' %i)
> -        self.testdoc = d
> -
> -    def RunTest(self):
> -        try:
> -            print("** Creating XML test document")
> -            self.__prepare_data()
> -            self.testdoc.saveFormatFileEnc('-','UTF-8', 1)
> -
> -            print("** Client test [1]: Hello(): %s" % str(self.client.Hello()))
> -            status = self.client.SendReport(self.testdoc)
> -            print("** Client test [2]; SendReport(xmlDoc): %s" % str(status))
> -        except Exception as e:
> -            raise Exception("XML-RPC client test failed: %s" % str(e))
> -
> -
> -def unit_test(rootdir):
> -    ret = 1
> -    try:
> -        # Prepare server and client objects
> -        srvthread = ServerThread('65432')
> -        clienttest = ClientTest('65432')
> -        signal.signal(signal.SIGINT, srvthread.sigcatch)
> -
> -        # Start a local XML-RPC test server
> -        srvthread.start()
> -        print("** Waiting 2 seconds for server to settle")
> -        time.sleep(2)
> -
> -        # Start the client test
> -        print("** Starting client tests")
> -        clienttest.RunTest()
> -        ret = 0
> -    except Exception as e:
> -        print("** EXCEPTION: %s" % str(e))
> -    finally:
> -        # Stop the local XML-RPC test server
> -        srvthread.stop()
> -    return ret
> -
> -if __name__ == "__main__":
> -    sys.exit(unit_test('..'))
> diff --git a/server/xmlrpc_API1.py b/server/xmlrpc_API1.py
> deleted file mode 100644
> index e2ad4ec..0000000
> --- a/server/xmlrpc_API1.py
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-or-later
> -#
> -#   xmlrpc_API1.py
> -#   XML-RPC functions supported by the API1 version for the rteval server
> -#
> -#   Copyright 2009 - 2013   David Sommerseth <davids@xxxxxxxxxx>
> -#
> -
> -import os
> -import bz2
> -import base64
> -import libxml2
> -import string
> -import platform
> -import rtevaldb
> -
> -
> -class XMLRPC_API1():
> -    def __init__(self, config=None, debug=False, nodbaction=False):
> -        # Some defaults
> -        self.apiversion = 1
> -        self.fnametrans = string.maketrans("/\\.", "::_") # replace path delimiters in filenames
> -        self.debug = debug
> -        self.nodbaction = nodbaction
> -        self.config = config
> -
> -
> -    def __mkdatadir(self, dirpath):
> -        startdir = os.getcwd()
> -        if dirpath[0] == '/':
> -            os.chdir('/')
> -        for dir in dirpath.split("/"):
> -            if dir is '':
> -                continue
> -            if not os.path.exists(dir):
> -                os.mkdir(dir, 0o700)
> -            os.chdir(dir)
> -        os.chdir(startdir)
> -
> -
> -    def __getfilename(self, dir, fname, ext, comp):
> -        idx = 0
> -        if comp:
> -            filename = "%s/%s/%s%s.bz2" % (self.config.datadir, dir, fname.translate(self.fnametrans), ext)
> -        else:
> -            filename = "%s/%s/%s%s" % (self.config.datadir, dir, fname.translate(self.fnametrans), ext)
> -
> -        while 1:
> -            if not os.path.exists(filename):
> -                return filename
> -            idx += 1
> -            if comp:
> -                filename = "%s/%s/%s-{%i}.bz2" % (self.config.datadir, dir,
> -                                                  fname.translate(self.fnametrans), idx)
> -            else:
> -                filename = "%s/%s/%s-{%i}" % (self.config.datadir, dir,
> -                                              fname.translate(self.fnametrans), idx)
> -
> -
> -    def Dispatch(self, method, params):
> -        # Call the method requested
> -        # FIXME: Improve checking for valid methods
> -        func = getattr(self, method)
> -        return func(*params)
> -
> -
> -    def _dispatch(self, method, params):
> -        "Wrapper method for Dispatch(), used by xmlrpclib in a local test server. Only used for testing."
> -        return self.Dispatch(method, params)
> -
> -
> -    def SendReport(self, clientid, xmlbzb64):
> -        decompr = bz2.BZ2Decompressor()
> -        xmldoc = libxml2.parseDoc(decompr.decompress(base64.b64decode(xmlbzb64)))
> -
> -        # Save a copy of the report on the file system
> -        # Make sure we have a directory to write files into
> -        self.__mkdatadir(os.path.join(self.config.datadir, 'queue'))
> -        fname = self.__getfilename('queue/', ('%s' % clientid), '.xml', False)
> -        xmldoc.saveFormatFileEnc(fname,'UTF-8',1)
> -        if self.debug:
> -            print("Copy of report: %s" % fname)
> -
> -        # Register the submission and put it in a parse queue
> -        rterid = rtevaldb.register_submission(self.config, clientid, fname,
> -                                                        debug=self.debug, noaction=self.nodbaction)
> -        if self.nodbaction:
> -            rterid = 999999999 # Fake ID when no database registration is done
> -
> -        return rterid
> -
> -
> -    def Hello(self, clientid):
> -        return {"greeting": "Hello %s" % clientid,
> -                "server": platform.node(),
> -                "APIversion": self.apiversion}
> -
> -
> -    def DatabaseStatus(self):
> -        return rtevaldb.database_status(self.config)
> diff --git a/unit-tests/unittest.py b/unit-tests/unittest.py
> index a60af16..00811d7 100644
> --- a/unit-tests/unittest.py
> +++ b/unit-tests/unittest.py
> @@ -113,7 +113,6 @@ if __name__ == '__main__':
>              ('rteval/sysinfo','dmi'),
>              ('rteval','rtevalConfig'),
>              ('rteval','xmlout'),
> -            ('server','unittest')
>              ))
>      # Run all tests
>      tests.RunTests()
> -- 

Thank you

Signed-off-by: John Kacur <jkacur@xxxxxxxxxx>





[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux