+++ /dev/null
-/*
- 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';
-}
+++ /dev/null
-/*
- 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
#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";
// 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);
// 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;
}
// Clean up after yourself!
if (log) delete log;
log = NULL;
-
- if (config) delete config;
- config = NULL;
}
const char *cPluginJsonserver::CommandLineHelp(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
};
// 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)