From 7450a788baa5d9d7ea16dcf1468adac424dd6305 Mon Sep 17 00:00:00 2001
From: Chris Tallon <chris@vomp.tv>
Date: Wed, 7 Mar 2018 20:15:47 +0000
Subject: [PATCH] Switch to libconfig++

---
 Makefile               |   7 +-
 config.c               | 524 -----------------------------------------
 config.h               |  80 -------
 jsonserver.c           | 101 +++-----
 jsonserver.conf.sample |   9 +-
 5 files changed, 47 insertions(+), 674 deletions(-)
 delete mode 100644 config.c
 delete mode 100644 config.h

diff --git a/Makefile b/Makefile
index f9fa715..46a3cd4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+# Dependencies:
+# libjsoncpp-dev libconfig++-dev
+
 #
 # Makefile for a Video Disk Recorder plugin
 #
@@ -56,7 +59,7 @@ CXXFLAGS += -fpermissive
 
 ### The object files (add further files here):
 
-OBJS = $(PLUGIN).o mongoose.o handler.o log.o config.o
+OBJS = $(PLUGIN).o mongoose.o handler.o log.o
 
 ### The main target:
 
@@ -105,7 +108,7 @@ install-i18n: $(I18Nmsgs)
 ### Targets:
 
 $(SOFILE): $(OBJS)
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -ljsoncpp -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -ljsoncpp -lconfig++ -o $@
 
 install-lib: $(SOFILE)
 	install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
diff --git a/config.c b/config.c
deleted file mode 100644
index 3866abc..0000000
--- a/config.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
-    Copyright 2004-2005 Chris Tallon
-    Copyright 2004-2005 University Of Bradford
-
-    This file is part of VOMP.
-
-    VOMP 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.
-
-    VOMP 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 VOMP; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*/
-
-#include "config.h"
-
-Config::Config()
-{
-  initted = 0;
-  lastLineLength = 0;
-  log = Log::getInstance();
-}
-
-int Config::init(char* takeFileName)
-{
-  if (initted) return 1;
-
-  pthread_mutex_init(&fileLock, NULL);
-
-  if (strlen(takeFileName) > (MAX_FILENAME_LENGTH - 1))
-  {
-    log->log("Config", Log::DEBUG, "Config error: Config filename too long");
-    return 0;
-  }
-
-  strcpy(fileName, takeFileName);
-  strcpy(fileNameTemp, takeFileName);
-  strcat(fileNameTemp, ".tmp");
-
-  file = fopen(fileName, "r");
-  if (!file)
-  {
-    file = fopen(fileName, "w");
-    if (!file)
-    {
-      log->log("Config", Log::DEBUG, "Config error: Could not access config file");
-      return 0;
-    }
-  }
-  fclose(file);
-
-  initted = 1;
-  log->log("Config", Log::DEBUG, "Opened config file: %s", fileName);
-
-  return 1;
-}
-
-int Config::status()
-{
-  return initted;
-}
-
-int Config::shutdown()
-{
-  if (!initted) return 1;
-
-  pthread_mutex_lock(&fileLock);
-  initted = 0;
-  pthread_mutex_unlock(&fileLock);
-  pthread_mutex_destroy(&fileLock);
-
-  return 1;
-}
-
-int Config::openFile()
-{
-  if (!initted) return 0;
-  if (pthread_mutex_lock(&fileLock))
-  {
-    log->log("Config", Log::DEBUG, "Config error: Could not get lock");
-    return 0;
-  }
-  if (!initted)
-  {
-    log->log("Config", Log::DEBUG, "Config error: Initted 0 after lock");
-    pthread_mutex_unlock(&fileLock);
-    return 0;
-  }
-
-  file = fopen(fileName, "r");
-  if (!file)
-  {
-    log->log("Config", Log::DEBUG, "Config error: Could not open config file");
-    pthread_mutex_unlock(&fileLock);
-    return 0;
-  }
-  return 1;
-}
-
-void Config::closeFile()
-{
-  if (!initted) return;
-
-  fclose(file);
-  file = NULL;
-  pthread_mutex_unlock(&fileLock);
-}
-
-int Config::readLine()
-{
-  if (!initted || !file) { log->log("Config", Log::DEBUG, "1"); return 0; }
-  if (!fgets(buffer, BUFFER_LENGTH-1, file)) { /*log->log("Config", Log::DEBUG, "2");*/ return 0; }
-  lastLineLength = strlen(buffer);
-//  log->log("Config", Log::DEBUG, "buffer before trim: '%s'", buffer);
-  trim(buffer);
-//  log->log("Config", Log::DEBUG, "buffer after trim: '%s'", buffer);
-  return 1;
-}
-
-// START HERE
-
-FILE* Config::copyToHere(long position)
-{
-  FILE* newFile = fopen(fileNameTemp, "w");
-
-  if (!newFile) return NULL;
-
-  long newPos = 0;
-  rewind(file);
-
-  while (newPos < position)
-  {
-    fgets(buffer, BUFFER_LENGTH-1, file);
-    fputs(buffer, newFile);
-    newPos += strlen(buffer);
-  }
-  return newFile;
-}
-
-int Config::copyRest(FILE* newFile)
-{
-  if (newFile)
-  {
-    while(fgets(buffer, BUFFER_LENGTH-1, file))
-    {
-      fputs(buffer, newFile);
-    }
-
-    fclose(newFile);
-  }
-  fclose(file);
-  file = NULL;
-
-  if (newFile) rename(fileNameTemp, fileName);
-
-  pthread_mutex_unlock(&fileLock);
-  return 1;
-}
-
-int Config::deleteValue(const char* section, char* key)
-{
-  if (!initted) return 0;
-  if (!openFile()) return 0;
-
-  if (!findSection(section))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Section %s not found", section);
-    return 0;
-  }
-  if (!findKey(key))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Key %s not found", key);
-    return 0;
-  }
-
-  FILE* newFile = copyToHere(ftell(file) - lastLineLength);
-  fgets(buffer, BUFFER_LENGTH-1, file);
-
-  return copyRest(newFile);
-}
-
-int Config::setValueLong(const char* section, char* key, long newValue)
-{
-  char longBuffer[50];
-  sprintf(longBuffer, "%li", newValue);
-  return setValueString(section, key, longBuffer);
-}
-
-int Config::setValueLongLong(char* section, char* key, long long newValue)
-{
-  char longBuffer[50];
-  sprintf(longBuffer, "%lli", newValue);
-  return setValueString(section, key, longBuffer);
-}
-
-int Config::setValueDouble(char* section, char* key, double newValue)
-{
-  char doubleBuffer[50];
-  sprintf(doubleBuffer, "%f", newValue);
-  return setValueString(section, key, doubleBuffer);
-}
-
-int Config::setValueString(const char* section, const char* key, const char* newValue)
-{
-  if (!initted) return 0;
-  if (!openFile()) return 0;
-
-  if (findSection(section))
-  {
-    if (findKey(key))
-    {
-      FILE* newFile = copyToHere(ftell(file) - lastLineLength);
-      if (!newFile)
-      {
-        closeFile();
-        log->log("Config", Log::DEBUG, "Config error: Could not write temp config file");
-        return 0;
-      }
-
-      fgets(buffer, BUFFER_LENGTH-1, file);
-      fprintf(newFile, "%s = %s\n", key, newValue);
-      return copyRest(newFile);
-    }
-    else
-    {
-      rewind(file);
-      findSection(section);
-      FILE* newFile = copyToHere(ftell(file));
-      if (!newFile)
-      {
-        closeFile();
-        log->log("Config", Log::DEBUG, "Config error: Could not write temp config file");
-        return 0;
-      }
-
-      fprintf(newFile, "%s = %s\n", key, newValue);
-      return copyRest(newFile);
-    }
-  }
-  else
-  {
-    // section not found
-    fseek(file, 0, SEEK_END);
-    FILE* newFile = copyToHere(ftell(file));
-    if (!newFile)
-    {
-      closeFile();
-      log->log("Config", Log::DEBUG, "Config error: Could not write temp config file");
-      return 0;
-    }
-
-    fprintf(newFile, "[%s]\n%s = %s\n", section, key, newValue);
-    return copyRest(newFile);
-  }
-}
-
-char* Config::getSectionKeyNames(const char* section, int& numberOfReturns, int& allKeysSize)
-{
-  numberOfReturns = 0;
-  allKeysSize = 0;
-  char* allKeys = NULL;
-  int allKeysIndex = 0;
-  int keyLength;
-  char* equalspos;
-
-  if (!initted) return NULL;
-  if (!openFile()) return NULL;
-  if (!findSection(section)) return NULL;
-
-  char foundKey[BUFFER_LENGTH];
-
-  while(readLine())
-  {
-    // Is this line a section header? if so, exit
-    if ((buffer[0] == '[') && (buffer[strlen(buffer)-1] == ']')) break;
-
-    equalspos = strstr(buffer, "=");
-    if (!equalspos) continue;  // if there is no = then it's not a key
-    memcpy(foundKey, buffer, equalspos-buffer);
-    foundKey[equalspos-buffer] = '\0';
-    trim(foundKey);
-    keyLength = strlen(foundKey);
-    allKeysSize += keyLength + 1;
-    allKeys = (char*)realloc(allKeys, allKeysSize);
-    memcpy(&allKeys[allKeysIndex], foundKey, keyLength);
-    allKeysIndex += keyLength;
-    allKeys[allKeysIndex] = '\0';
-    allKeysIndex++;
-    numberOfReturns++;
-  }
-
-  closeFile();
-  return allKeys;
-}
-
-
-// END HERE
-
-int Config::findSection(const char* section)
-{
-  if (!initted || !file) return 0;
-  if (strlen(section) > (BUFFER_LENGTH-2))
-  {
-    log->log("Config", Log::DEBUG, "Config error: Section given exceeds max length");
-    return 0;
-  }
-
-  char toFind[BUFFER_LENGTH];
-  toFind[0] = '[';
-  toFind[1] = '\0';
-  strcat(toFind, section);
-  strcat(toFind, "]");
-
-  while(readLine())
-  {
-//    log->log("Config", Log::DEBUG, "to find '%s' this line '%s'", toFind, buffer);
-    if (!strcmp(toFind, buffer)) return 1;
-  }
-  return 0;
-}
-
-int Config::findKey(const char* key)
-{
-  if (!initted || !file) return 0;
-
-  if (strlen(key) > (BUFFER_LENGTH-1))
-  {
-    log->log("Config", Log::DEBUG, "Config error: Key given exceeds max length");
-    return 0;
-  }
-
-  char prepForTest[BUFFER_LENGTH];
-
-  // do a rough search first, this could match substrings that we don't want
-  while(readLine())
-  {
-    // Is this line a section header? if so, exit
-    if ((buffer[0] == '[') && (buffer[strlen(buffer)-1] == ']')) return 0;
-    if (strstr(buffer, key))
-    {
-      // rough search found match
-      char* equalspos = strstr(buffer, "=");
-      if (!equalspos) continue;
-      memcpy(prepForTest, buffer, equalspos-buffer);
-      prepForTest[equalspos-buffer] = '\0';
-      trim(prepForTest);
-
-      if (!strcmp(key, prepForTest))
-      {
-        // in buffer, set all up to equals to space, then trim!
-        for(char* curPos = buffer; curPos <= equalspos; curPos++)
-        {
-          *curPos = ' ';
-        }
-        trim(buffer);
-        return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-char* Config::getValueString(const char* section, const char* key)
-{
-  if (!initted) return NULL;
-  if (!openFile()) return NULL;
-
-  if (!findSection(section))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Section %s not found", section);
-    return 0;
-  }
-  if (!findKey(key))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Key %s not found", key);
-    return 0;
-  }
-
-  char* returnString = new char[strlen(buffer)+1];
-  strcpy(returnString, buffer);
-
-  closeFile();
-
-  return returnString;
-}
-
-long Config::getValueLong(const char* section, const char* key, int* failure)
-{
-  *failure = 1;
-  if (!initted) return 0;
-  if (!openFile()) return 0;
-
-  if (!findSection(section))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Section %s not found", section);
-    return 0;
-  }
-  if (!findKey(key))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Key %s not found", key);
-    return 0;
-  }
-  *failure = 0;
-
-  char* check;
-  long retVal = strtol(buffer, &check, 10);
-  if ((retVal == 0) && (check == buffer)) *failure = 1;
-  closeFile();
-
-  return retVal;
-}
-
-long long Config::getValueLongLong(char* section, char* key, int* failure)
-{
-  *failure = 1;
-  if (!initted) return 0;
-  if (!openFile()) return 0;
-
-  if (!findSection(section))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Section %s not found", section);
-    return 0;
-  }
-  if (!findKey(key))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Key %s not found", key);
-    return 0;
-  }
-  *failure = 0;
-
-  char* check;
-  long long retVal = strtoll(buffer, &check, 10);
-  if ((retVal == 0) && (check == buffer)) *failure = 1;
-  closeFile();
-
-  return retVal;
-}
-
-double Config::getValueDouble(char* section, char* key, int* failure)
-{
-  *failure = 1;
-  if (!initted) return 0;
-  if (!openFile()) return 0;
-
-  if (!findSection(section))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Section %s not found", section);
-    return 0;
-  }
-  if (!findKey(key))
-  {
-    closeFile();
-    log->log("Config", Log::DEBUG, "Config error: Key %s not found", key);
-    return 0;
-  }
-
-  *failure = 0;
-
-  char* check;
-  double retVal = strtod(buffer, &check);
-  if ((retVal == 0) && (check == buffer)) *failure = 1;
-
-  closeFile();
-
-  return retVal;
-}
-
-
-
-void Config::trim(char* str)
-{
-  int pos, len, start, end;
-
-  // Kill comments
-  len = strlen(str);
-  for(pos = 0; pos < len; pos++)
-  {
-    if ((str[pos] == '#') || (str[pos] == ';'))
-    {
-      // Mod. If #/; is at start of line ok. Else, if it is after a space, ok.
-
-      if ((pos == 0) || (isspace(str[pos - 1])))
-      {
-        str[pos] = '\0';
-        break;
-      }
-
-    }
-  }
-
-  len = strlen(str);
-  end = len;
-  if (!len) return;
-
-  start = 0;
-  while(isspace(str[start])) start++;
-  while(isspace(str[end-1]))
-  {
-    end--;
-    if (end == 0)
-    {
-      str[0] = '\0';
-      return;
-    }
-  }
-  for(pos = start; pos < end; pos++) str[pos - start] = str[pos];
-  str[end - start] = '\0';
-}
diff --git a/config.h b/config.h
deleted file mode 100644
index 2e4a2dd..0000000
--- a/config.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-    Copyright 2004-2005 Chris Tallon
-    Copyright 2004-2005 University Of Bradford
-
-    This file is part of VOMP.
-
-    VOMP 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.
-
-    VOMP 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 VOMP; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*/
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <ctype.h>
-
-#include "log.h"
-
-#define MAX_FILENAME_LENGTH 500
-#define BUFFER_LENGTH 1500
-
-class Config
-{
-  public:
-    Config();
-
-    int init(char* fileName);
-    int shutdown();
-    int status();
-
-    char* getValueString(const char* section, const char* key);
-    long getValueLong(const char* section, const char* key, int* failure);
-    long long getValueLongLong(char* section, char* key, int* failure);
-    double getValueDouble(char* section, char* key, int* failure);
-
-    int setValueString(const char* section, const char* key, const char* newValue);
-    int setValueLong(const char* section, char* key, long newValue);
-    int setValueLongLong(char* section, char* key, long long newValue);
-    int setValueDouble(char* section, char* key, double newValue);
-
-    int deleteValue(const char* section, char* key); // err.. delete "key".
-    char* getSectionKeyNames(const char* section, int& numberOfReturns, int& length);
-
-  private:
-    pthread_mutex_t fileLock;
-    int initted;
-    int lastLineLength;
-    Log* log;
-
-    char fileName[MAX_FILENAME_LENGTH];
-    char fileNameTemp[MAX_FILENAME_LENGTH];
-
-    FILE* file;
-    char buffer[BUFFER_LENGTH];
-
-    int openFile();
-    void closeFile();
-    int readLine();
-    int findSection(const char* section);
-    int findKey(const char* key);
-    void trim(char* sting);
-    FILE* copyToHere(long position);
-    int copyRest(FILE* newFile);
-};
-
-#endif
diff --git a/jsonserver.c b/jsonserver.c
index 8d1cbb8..fa4ea8c 100644
--- a/jsonserver.c
+++ b/jsonserver.c
@@ -8,10 +8,12 @@
 #include <vdr/plugin.h>
 #include <stdio.h>
 
+// Config docs: http://www.hyperrealm.com/libconfig/libconfig_manual.html#The-C_002b_002b-API
+#include <libconfig.h++>
+
 #include "mongoose.h"
 #include "handler.h"
 #include "log.h"
-#include "config.h"
 
 static const char *VERSION        = "0.0.1";
 static const char *DESCRIPTION    = "JSON data server plugin for VDR";
@@ -22,10 +24,7 @@ private:
   // Add any member variables or functions you may need here.
   struct mg_context *mg;
   Log* log;
-  Config* config;
-  char* cfgDocRoot;
-  char* cfgPort;
-  char* cfgSSLFilename;
+  libconfig::Config config;
   bool mgRunning;
 public:
   cPluginJsonserver(void);
@@ -56,11 +55,7 @@ cPluginJsonserver::cPluginJsonserver(void)
   // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
   // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
 
-  config = NULL;
   log = NULL;
-  cfgDocRoot = NULL;
-  cfgPort = NULL;
-  cfgSSLFilename = NULL;
   mgRunning = false;
 }
 
@@ -69,9 +64,6 @@ cPluginJsonserver::~cPluginJsonserver()
   // Clean up after yourself!
   if (log) delete log;
   log = NULL;
-
-  if (config) delete config;
-  config = NULL;
 }
 
 const char *cPluginJsonserver::CommandLineHelp(void)
@@ -101,87 +93,73 @@ bool cPluginJsonserver::Start(void)
     dsyslog("jsonserver: Error: Could not get config dir from VDR");
     return false;
   }
-  char* configFile;
-  if (asprintf(&configFile, "%s/jsonserver.conf", configDir) == -1)
+
+  std::string configFile(std::string(configDir) + std::string("/server.conf"));
+  dsyslog("%s", configFile.c_str());
+  try
   {
-    dsyslog("jsonserver: Error: asprintf");
-    return false;
+    config.readFile(configFile.c_str());
   }
-  
-  dsyslog("%s", configFile);
-  
-  log = new Log();
-  
-  config = new Config();
-  if (config->init(configFile))
+  catch (const libconfig::FileIOException &fioex)
   {
-    dsyslog("jsonserver: Config file found");
-    free(configFile);
+    dsyslog("jsonserver: Failed to read config file");
+    return false;
   }
-  else
+  catch(const libconfig::ParseException &pex)
   {
-    dsyslog("jsonserver: Error: Config file not found");
-    free(configFile);
-    delete config;
-    config = NULL;
+    dsyslog("jsonserver: Config parse error at %s: %i - %s", pex.getFile(), pex.getLine(), pex.getError());
     return false;
   }
 
-  char* cfgLogFilename = config->getValueString("General", "Log file");
-  if (cfgLogFilename)
+  std::string cfgLogFilename;
+  if (config.lookupValue("log-file", cfgLogFilename))
   {
-    log->init(Log::DEBUG, cfgLogFilename);
-    delete[] cfgLogFilename;
+    log = new Log();
+    log->init(Log::DEBUG, cfgLogFilename.c_str());
     log->log("Main", Log::INFO, "Logging started");
   }
   else
   {
     dsyslog("jsonserver: Logging disabled");
   }
-  
-  cfgDocRoot = config->getValueString("General", "JS App Dir");
-  if (!cfgDocRoot)
+
+  std::string cfgDocRoot;
+  if (!config.lookupValue("doc-root", cfgDocRoot))
   {
-    log->log("Main", Log::CRIT, "Config General/JS App Dir not found");
-    dsyslog("jsonserver: Error: Could not load JS App Dir from plugin config file");
+    log->log("Main", Log::CRIT, "Failed to load doc-root from config");
+    dsyslog("jsonserver: Could not load JS App Dir from plugin config file");
     delete log;
-    delete config;
     log = NULL;
-    config = NULL;
     return false;
   }
 
-  cfgPort = config->getValueString("General", "Port number");
-  if (!cfgPort)
+  std::string cfgPort;
+  if (!config.lookupValue("http-port", cfgPort))
   {
-    cfgPort = new char[5];
-    strcpy(cfgPort, "8005");
+    log->log("Main", Log::CRIT, "Failed to load http-port from config");
+    dsyslog("jsonserver: Could not load http-port from plugin config file");
+    delete log;
+    log = NULL;
+    return false;
   }
 
-  char* cfgSSLFilename = config->getValueString("General", "SSL PEM File");
-  if (!cfgSSLFilename)
+  std::string cfgSSLFilename;
+  if (!config.lookupValue("ssl-pem-file", cfgSSLFilename))
   {
-    log->log("Main", Log::ALERT, "Config General / SSL PEM File not found - can't run!");
-    dsyslog("jsonserver: ERROR: Config: SSL PEM not found");
+    log->log("Main", Log::CRIT, "Failed to load ssl-pem-file from config");
+    dsyslog("jsonserver: Could not load ssl-pem-file from plugin config file");
     delete log;
-    delete config;
     log = NULL;
-    config = NULL;
     return false;
   }
-  
+
   // Make Mongoose options
   const char *options[] =
   {
-    "document_root", cfgDocRoot,
-//    "listening_ports", cfgPort,
+    "document_root", cfgDocRoot.c_str(),
+    "listening_ports", cfgPort.c_str(),
     "num_threads", "5",
-
-    "listening_ports", "8005s",
-    "ssl_certificate", cfgSSLFilename,
-
-//    "auth_domain", "VDRWeb",
-
+    "ssl_certificate", cfgSSLFilename.c_str(),
     NULL
   };
 
@@ -201,9 +179,6 @@ void cPluginJsonserver::Stop(void)
   // Stop any background activities the plugin is performing.
   if (mgRunning) mg_stop(mg);
   mgRunning = false;
-  if (cfgDocRoot) { delete[] cfgDocRoot; cfgDocRoot = NULL; }
-  if (cfgPort) { delete[] cfgPort; cfgPort = NULL; }
-  if (cfgSSLFilename) { delete[] cfgSSLFilename; cfgSSLFilename = NULL; }
 }
 
 void cPluginJsonserver::Housekeeping(void)
diff --git a/jsonserver.conf.sample b/jsonserver.conf.sample
index 4fdc122..fa95733 100644
--- a/jsonserver.conf.sample
+++ b/jsonserver.conf.sample
@@ -1,5 +1,4 @@
-[General]
-Log file = /var/log/jsonserver.log
-JS App Dir = /srv/vdrweb
-Port number = 8005
-
+log-file = "/home/chris/dvb/vdrweb/jsonserver.log";
+doc-root = "/home/chris/dvb/vdrweb/html";
+ssl-pem-file = "/home/chris/dvb/vdrweb/sslcert.pem";
+http-port = "8005";
-- 
2.39.5