1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00
vdr/config.c

540 lines
16 KiB
C
Raw Normal View History

2000-02-19 13:36:48 +01:00
/*
* config.c: Configuration file handling
*
2000-04-24 09:46:05 +02:00
* See the main source file 'vdr.c' for copyright information and
2000-02-19 13:36:48 +01:00
* how to reach the author.
*
* $Id: config.c 1.121 2004/01/25 14:41:10 kls Exp $
2000-02-19 13:36:48 +01:00
*/
#include "config.h"
#include <ctype.h>
#include <stdlib.h>
2000-11-11 10:39:27 +01:00
#include "i18n.h"
2000-02-19 13:36:48 +01:00
#include "interface.h"
2002-05-09 16:26:56 +02:00
#include "plugin.h"
#include "recording.h"
2000-02-19 13:36:48 +01:00
// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
// format characters in order to allow any number of blanks after a numeric
// value!
2000-11-11 16:38:41 +01:00
// --- cCommand -------------------------------------------------------------
char *cCommand::result = NULL;
cCommand::cCommand(void)
{
title = command = NULL;
confirm = false;
2000-11-11 16:38:41 +01:00
}
cCommand::~cCommand()
{
free(title);
free(command);
2000-11-11 16:38:41 +01:00
}
bool cCommand::Parse(const char *s)
{
const char *p = strchr(s, ':');
if (p) {
int l = p - s;
if (l > 0) {
title = MALLOC(char, l + 1);
stripspace(strn0cpy(title, s, l + 1));
2000-11-11 16:38:41 +01:00
if (!isempty(title)) {
int l = strlen(title);
if (l > 1 && title[l - 1] == '?') {
confirm = true;
title[l - 1] = 0;
}
2000-11-11 16:38:41 +01:00
command = stripspace(strdup(skipspace(p + 1)));
return !isempty(command);
}
}
}
return false;
}
2002-10-13 12:14:49 +02:00
const char *cCommand::Execute(const char *Parameters)
2000-11-11 16:38:41 +01:00
{
free(result);
2000-11-11 16:38:41 +01:00
result = NULL;
2002-10-13 12:14:49 +02:00
char *cmdbuf = NULL;
if (Parameters)
asprintf(&cmdbuf, "%s %s", command, Parameters);
const char *cmd = cmdbuf ? cmdbuf : command;
dsyslog("executing command '%s'", cmd);
FILE *p = popen(cmd, "r");
2000-11-11 16:38:41 +01:00
if (p) {
int l = 0;
int c;
while ((c = fgetc(p)) != EOF) {
if (l % 20 == 0)
result = (char *)realloc(result, l + 21);
result[l++] = c;
}
if (result)
result[l] = 0;
pclose(p);
}
else
2002-10-13 12:14:49 +02:00
esyslog("ERROR: can't open pipe for command '%s'", cmd);
free(cmdbuf);
2000-11-11 16:38:41 +01:00
return result;
}
2002-02-02 17:20:54 +01:00
// -- cSVDRPhost -------------------------------------------------------------
cSVDRPhost::cSVDRPhost(void)
{
addr.s_addr = 0;
mask = 0;
}
bool cSVDRPhost::Parse(const char *s)
{
mask = 0xFFFFFFFF;
const char *p = strchr(s, '/');
if (p) {
char *error = NULL;
int m = strtoul(p + 1, &error, 10);
2002-09-29 13:40:45 +02:00
if (error && *error && !isspace(*error) || m > 32)
2002-02-02 17:20:54 +01:00
return false;
*(char *)p = 0; // yes, we know it's 'const' - will be restored!
if (m == 0)
mask = 0;
else
mask >>= (32 - m);
}
int result = inet_aton(s, &addr);
if (p)
*(char *)p = '/'; // there it is again
return result != 0 && (mask != 0 || addr.s_addr == 0);
}
bool cSVDRPhost::Accepts(in_addr_t Address)
{
return (Address & mask) == addr.s_addr;
}
// -- cCaDefinition ----------------------------------------------------------
cCaDefinition::cCaDefinition(void)
{
number = 0;
description = NULL;
}
cCaDefinition::~cCaDefinition()
{
free(description);
}
bool cCaDefinition::Parse(const char *s)
{
return 2 == sscanf(s, "%d %a[^\n]", &number, &description) && description && *description;
}
2000-11-11 16:38:41 +01:00
// -- cCommands --------------------------------------------------------------
cCommands Commands;
2002-10-13 12:14:49 +02:00
cCommands RecordingCommands;
2000-11-11 16:38:41 +01:00
2002-02-02 17:20:54 +01:00
// -- cSVDRPhosts ------------------------------------------------------------
cSVDRPhosts SVDRPhosts;
bool cSVDRPhosts::Acceptable(in_addr_t Address)
{
cSVDRPhost *h = First();
while (h) {
if (h->Accepts(Address))
return true;
h = (cSVDRPhost *)h->Next();
}
return false;
}
// -- cCaDefinitions ---------------------------------------------------------
cCaDefinitions CaDefinitions;
const cCaDefinition *cCaDefinitions::Get(int Number)
{
cCaDefinition *p = First();
while (p) {
if (p->Number() == Number)
return p;
p = (cCaDefinition *)p->Next();
}
return NULL;
}
2002-05-09 16:26:56 +02:00
// -- cSetupLine -------------------------------------------------------------
cSetupLine::cSetupLine(void)
{
plugin = name = value = NULL;
}
cSetupLine::cSetupLine(const char *Name, const char *Value, const char *Plugin)
{
name = strdup(Name);
value = strdup(Value);
plugin = Plugin ? strdup(Plugin) : NULL;
}
cSetupLine::~cSetupLine()
{
free(plugin);
free(name);
free(value);
2002-05-09 16:26:56 +02:00
}
bool cSetupLine::operator< (const cListObject &ListObject)
{
const cSetupLine *sl = (cSetupLine *)&ListObject;
if (!plugin && !sl->plugin)
return strcasecmp(name, sl->name) < 0;
2002-05-09 16:26:56 +02:00
if (!plugin)
return true;
if (!sl->plugin)
return false;
int result = strcasecmp(plugin, sl->plugin);
if (result == 0)
result = strcasecmp(name, sl->name);
return result < 0;
}
bool cSetupLine::Parse(char *s)
{
char *p = strchr(s, '=');
if (p) {
*p = 0;
char *Name = compactspace(s);
char *Value = compactspace(p + 1);
if (*Name) { // value may be an empty string
2002-05-09 16:26:56 +02:00
p = strchr(Name, '.');
if (p) {
*p = 0;
char *Plugin = compactspace(Name);
Name = compactspace(p + 1);
if (!(*Plugin && *Name))
return false;
plugin = strdup(Plugin);
}
name = strdup(Name);
value = strdup(Value);
return true;
}
}
return false;
}
bool cSetupLine::Save(FILE *f)
{
return fprintf(f, "%s%s%s = %s\n", plugin ? plugin : "", plugin ? "." : "", name, value) > 0;
}
2000-09-10 10:51:58 +02:00
// -- cSetup -----------------------------------------------------------------
cSetup Setup;
cSetup::cSetup(void)
{
2000-11-11 10:39:27 +01:00
OSDLanguage = 0;
2000-09-10 10:51:58 +02:00
PrimaryDVB = 1;
ShowInfoOnChSwitch = 1;
MenuScrollPage = 1;
MarkInstantRecord = 1;
strcpy(NameInstantRecord, "TITLE EPISODE");
InstantRecordTime = 180;
LnbSLOF = 11700;
2000-10-08 16:18:23 +02:00
LnbFrequLo = 9750;
LnbFrequHi = 10600;
DiSEqC = 0;
2000-10-29 13:17:22 +01:00
SetSystemTime = 0;
TimeTransponder = 0;
2000-10-29 13:17:22 +01:00
MarginStart = 2;
MarginStop = 10;
EPGLanguages[0] = -1;
EPGScanTimeout = 5;
2001-08-17 13:19:10 +02:00
EPGBugfixLevel = 2;
SVDRPTimeout = 300;
ZapTimeout = 3;
2001-08-26 14:17:20 +02:00
SortTimers = 1;
PrimaryLimit = 0;
DefaultPriority = 50;
2003-10-17 14:14:46 +02:00
DefaultLifetime = 99;
PausePriority = 10;
PauseLifetime = 1;
UseSubtitle = 1;
RecordingDirs = 1;
VideoFormat = 0;
UpdateChannels = 4;
2002-02-24 11:55:24 +01:00
RecordDolbyDigital = 1;
ChannelInfoPos = 0;
OSDwidth = 52;
OSDheight = 18;
2001-09-01 15:23:27 +02:00
OSDMessageTime = 1;
2001-08-25 13:52:38 +02:00
MaxVideoFileSize = MAXVIDEOFILESIZE;
2001-09-30 11:31:43 +02:00
SplitEditedFiles = 0;
2001-09-07 15:37:26 +02:00
MinEventTimeout = 30;
2001-09-01 09:04:37 +02:00
MinUserInactivity = 120;
2001-09-09 12:52:41 +02:00
MultiSpeedMode = 0;
2001-09-14 14:06:43 +02:00
ShowReplayMode = 0;
ResumeID = 0;
memset(CaCaps, sizeof(CaCaps), 0);
CurrentChannel = -1;
2001-09-22 13:41:49 +02:00
CurrentVolume = MAXVOLUME;
2000-09-10 10:51:58 +02:00
}
2002-05-09 16:26:56 +02:00
cSetup& cSetup::operator= (const cSetup &s)
{
memcpy(&__BeginData__, &s.__BeginData__, (char *)&s.__EndData__ - (char *)&s.__BeginData__);
return *this;
}
cSetupLine *cSetup::Get(const char *Name, const char *Plugin)
{
for (cSetupLine *l = First(); l; l = Next(l)) {
if ((l->Plugin() == NULL) == (Plugin == NULL)) {
if ((!Plugin || strcasecmp(l->Plugin(), Plugin) == 0) && strcasecmp(l->Name(), Name) == 0)
return l;
}
}
return NULL;
}
void cSetup::Store(const char *Name, const char *Value, const char *Plugin, bool AllowMultiple)
2002-05-09 16:26:56 +02:00
{
if (Name && *Name) {
cSetupLine *l = Get(Name, Plugin);
if (l && !AllowMultiple)
2002-05-09 16:26:56 +02:00
Del(l);
if (Value)
Add(new cSetupLine(Name, Value, Plugin));
}
}
void cSetup::Store(const char *Name, int Value, const char *Plugin)
{
char *buffer = NULL;
asprintf(&buffer, "%d", Value);
Store(Name, buffer, Plugin);
free(buffer);
2002-05-09 16:26:56 +02:00
}
bool cSetup::Load(const char *FileName)
{
if (cConfig<cSetupLine>::Load(FileName, true)) {
bool result = true;
for (cSetupLine *l = First(); l; l = Next(l)) {
bool error = false;
2002-05-09 16:26:56 +02:00
if (l->Plugin()) {
cPlugin *p = cPluginManager::GetPlugin(l->Plugin());
if (p && !p->SetupParse(l->Name(), l->Value()))
error = true;
2002-05-09 16:26:56 +02:00
}
else {
if (!Parse(l->Name(), l->Value()))
error = true;
}
if (error) {
2002-05-13 16:35:49 +02:00
esyslog("ERROR: unknown config parameter: %s%s%s = %s", l->Plugin() ? l->Plugin() : "", l->Plugin() ? "." : "", l->Name(), l->Value());
result = false;
2002-05-09 16:26:56 +02:00
}
}
return result;
}
return false;
}
void cSetup::StoreCaCaps(const char *Name)
{
cSetupLine *l;
while ((l = Get(Name)) != NULL)
Del(l);
for (int d = 0; d < MAXDEVICES; d++) {
2002-05-09 16:26:56 +02:00
char buffer[MAXPARSEBUFFER];
char *q = buffer;
*buffer = 0;
for (int i = 0; i < MAXCACAPS; i++) {
if (CaCaps[d][i]) {
2002-05-09 16:26:56 +02:00
if (!*buffer)
q += snprintf(buffer, sizeof(buffer), "%d", d + 1);
q += snprintf(q, sizeof(buffer) - (q - buffer), " %d", CaCaps[d][i]);
}
}
2002-05-09 16:26:56 +02:00
if (*buffer)
Store(Name, buffer, NULL, true);
}
}
bool cSetup::ParseCaCaps(const char *Value)
{
char *p;
int d = strtol(Value, &p, 10);
if (d > 0 && d <= MAXDEVICES) {
d--;
int i = 0;
while (p != Value && p && *p) {
if (i < MAXCACAPS) {
int c = strtol(p, &p, 10);
if (c > 0)
CaCaps[d][i++] = c;
else
return false;
}
else
return false;
}
return true;
}
return false;
}
void cSetup::StoreLanguages(const char *Name, int *Values)
{
char buffer[I18nNumLanguages * 4];
char *q = buffer;
for (int i = 0; i < I18nNumLanguages; i++) {
if (Values[i] < 0)
break;
const char *s = I18nLanguageCode(Values[i]);
if (s) {
if (q > buffer)
*q++ = ' ';
strncpy(q, s, 3);
q += 3;
}
}
*q = 0;
Store(Name, buffer);
}
bool cSetup::ParseLanguages(const char *Value, int *Values)
{
int n = 0;
while (Value && *Value && n < I18nNumLanguages) {
int i = I18nLanguageIndex(Value);
if (i >= 0)
Values[n++] = i;
if ((Value = strchr(Value, ' ')) != NULL)
Value++;
}
Values[n] = -1;
return true;
}
2002-05-09 16:26:56 +02:00
bool cSetup::Parse(const char *Name, const char *Value)
{
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value);
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
else if (!strcasecmp(Name, "NameInstantRecord")) strn0cpy(NameInstantRecord, Value, MaxFileName);
else if (!strcasecmp(Name, "InstantRecordTime")) InstantRecordTime = atoi(Value);
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value);
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
2002-05-09 16:26:56 +02:00
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value);
2002-05-09 16:26:56 +02:00
else if (!strcasecmp(Name, "SortTimers")) SortTimers = atoi(Value);
else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value);
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value);
else if (!strcasecmp(Name, "PausePriority")) PausePriority = atoi(Value);
else if (!strcasecmp(Name, "PauseLifetime")) PauseLifetime = atoi(Value);
2002-05-09 16:26:56 +02:00
else if (!strcasecmp(Name, "UseSubtitle")) UseSubtitle = atoi(Value);
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value);
else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value);
2002-05-09 16:26:56 +02:00
else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value);
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
else if (!strcasecmp(Name, "OSDwidth")) OSDwidth = atoi(Value);
else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value);
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value);
else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value);
else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value);
else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value);
2002-05-09 16:26:56 +02:00
else if (!strcasecmp(Name, "CaCaps")) return ParseCaCaps(Value);
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
2000-09-10 10:51:58 +02:00
else
2002-05-09 16:26:56 +02:00
return false;
return true;
2000-09-10 10:51:58 +02:00
}
2002-05-09 16:26:56 +02:00
bool cSetup::Save(void)
{
Store("OSDLanguage", OSDLanguage);
Store("PrimaryDVB", PrimaryDVB);
Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch);
Store("MenuScrollPage", MenuScrollPage);
Store("MarkInstantRecord", MarkInstantRecord);
Store("NameInstantRecord", NameInstantRecord);
Store("InstantRecordTime", InstantRecordTime);
Store("LnbSLOF", LnbSLOF);
Store("LnbFrequLo", LnbFrequLo);
Store("LnbFrequHi", LnbFrequHi);
Store("DiSEqC", DiSEqC);
Store("SetSystemTime", SetSystemTime);
Store("TimeTransponder", TimeTransponder);
Store("MarginStart", MarginStart);
Store("MarginStop", MarginStop);
StoreLanguages("EPGLanguages", EPGLanguages);
2002-05-09 16:26:56 +02:00
Store("EPGScanTimeout", EPGScanTimeout);
Store("EPGBugfixLevel", EPGBugfixLevel);
Store("SVDRPTimeout", SVDRPTimeout);
Store("ZapTimeout", ZapTimeout);
2002-05-09 16:26:56 +02:00
Store("SortTimers", SortTimers);
Store("PrimaryLimit", PrimaryLimit);
Store("DefaultPriority", DefaultPriority);
Store("DefaultLifetime", DefaultLifetime);
Store("PausePriority", PausePriority);
Store("PauseLifetime", PauseLifetime);
2002-05-09 16:26:56 +02:00
Store("UseSubtitle", UseSubtitle);
Store("RecordingDirs", RecordingDirs);
Store("VideoFormat", VideoFormat);
Store("UpdateChannels", UpdateChannels);
2002-05-09 16:26:56 +02:00
Store("RecordDolbyDigital", RecordDolbyDigital);
Store("ChannelInfoPos", ChannelInfoPos);
Store("OSDwidth", OSDwidth);
Store("OSDheight", OSDheight);
Store("OSDMessageTime", OSDMessageTime);
Store("MaxVideoFileSize", MaxVideoFileSize);
Store("SplitEditedFiles", SplitEditedFiles);
Store("MinEventTimeout", MinEventTimeout);
Store("MinUserInactivity", MinUserInactivity);
Store("MultiSpeedMode", MultiSpeedMode);
Store("ShowReplayMode", ShowReplayMode);
Store("ResumeID", ResumeID);
2002-05-09 16:26:56 +02:00
StoreCaCaps("CaCaps");
Store("CurrentChannel", CurrentChannel);
Store("CurrentVolume", CurrentVolume);
Sort();
if (cConfig<cSetupLine>::Save()) {
2002-05-13 16:35:49 +02:00
isyslog("saved setup to %s", FileName());
2002-05-09 16:26:56 +02:00
return true;
2000-09-10 10:51:58 +02:00
}
return false;
}