summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'config.c')
-rw-r--r--config.c333
1 files changed, 333 insertions, 0 deletions
diff --git a/config.c b/config.c
new file mode 100644
index 00000000..50315691
--- /dev/null
+++ b/config.c
@@ -0,0 +1,333 @@
+/*
+ * config.c: Configuration file handling
+ *
+ * See the main source file 'osm.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: config.c 1.1 2000/02/19 13:36:48 kls Exp $
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <time.h>
+#include "dvbapi.h"
+#include "interface.h"
+
+// -- cKeys ------------------------------------------------------------------
+
+tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
+ { kUp, "Up", 0 },
+ { kDown, "Down", 0 },
+ { kMenu, "Menu", 0 },
+ { kOk, "Ok", 0 },
+ { kBack, "Back", 0 },
+ { kLeft, "Left", 0 },
+ { kRight, "Right", 0 },
+ { k0, "0", 0 },
+ { k1, "1", 0 },
+ { k2, "2", 0 },
+ { k3, "3", 0 },
+ { k4, "4", 0 },
+ { k5, "5", 0 },
+ { k6, "6", 0 },
+ { k7, "7", 0 },
+ { k8, "8", 0 },
+ { k9, "9", 0 },
+ { kNone, "", 0 },
+ };
+
+cKeys::cKeys(void)
+{
+ fileName = NULL;
+ code = 0;
+ address = 0;
+ keys = keyTable;
+}
+
+void cKeys::Clear(void)
+{
+ for (tKey *k = keys; k->type != kNone; k++)
+ k->code = 0;
+}
+
+bool cKeys::Load(char *FileName)
+{
+ isyslog(LOG_INFO, "loading %s", FileName);
+ bool result = false;
+ if (FileName)
+ fileName = strdup(FileName);
+ if (fileName) {
+ FILE *f = fopen(fileName, "r");
+ if (f) {
+ int line = 0;
+ char buffer[MaxBuffer];
+ result = true;
+ while (fgets(buffer, sizeof(buffer), f) > 0) {
+ line++;
+ char *Name = buffer;
+ char *p = strpbrk(Name, " \t");
+ if (p) {
+ *p = 0; // terminates 'Name'
+ while (*++p && isspace(*p))
+ ;
+ if (*p) {
+ if (strcasecmp(Name, "Code") == 0)
+ code = *p;
+ else if (strcasecmp(Name, "Address") == 0)
+ address = strtol(p, NULL, 16);
+ else {
+ for (tKey *k = keys; k->type != kNone; k++) {
+ if (strcasecmp(Name, k->name) == 0) {
+ k->code = strtol(p, NULL, 16);
+ Name = NULL; // to indicate that we found it
+ break;
+ }
+ }
+ if (Name) {
+ fprintf(stderr, "unknown key in %s, line %d\n", fileName, line);
+ result = false;
+ break;
+ }
+ }
+ }
+ continue;
+ }
+ fprintf(stderr, "error in %s, line %d\n", fileName, line);
+ result = false;
+ break;
+ }
+ fclose(f);
+ }
+ else
+ fprintf(stderr, "can't open '%s'\n", fileName);
+ }
+ else
+ fprintf(stderr, "no key configuration file name supplied!\n");
+ return result;
+}
+
+bool cKeys::Save(void)
+{
+ //TODO make backup copies???
+ bool result = true;
+ FILE *f = fopen(fileName, "w");
+ if (f) {
+ if (fprintf(f, "Code\t%c\nAddress\t%04X\n", code, address) > 0) {
+ for (tKey *k = keys; k->type != kNone; k++) {
+ if (fprintf(f, "%s\t%08X\n", k->name, k->code) <= 0) {
+ result = false;
+ break;
+ }
+ }
+ }
+ else
+ result = false;
+ fclose(f);
+ }
+ else
+ result = false;
+ return result;
+}
+
+eKeys cKeys::Get(unsigned int Code)
+{
+ if (Code != 0) {
+ tKey *k;
+ for (k = keys; k->type != kNone; k++) {
+ if (k->code == Code)
+ break;
+ }
+ return k->type;
+ }
+ return kNone;
+}
+
+void cKeys::Set(eKeys Key, unsigned int Code)
+{
+ for (tKey *k = keys; k->type != kNone; k++) {
+ if (k->type == Key) {
+ k->code = Code;
+ break;
+ }
+ }
+}
+
+// -- cChannel ---------------------------------------------------------------
+
+cChannel::cChannel(void)
+{
+ *name = 0;
+}
+
+bool cChannel::Parse(char *s)
+{
+ char *buffer = NULL;
+ if (7 == sscanf(s, "%a[^:]:%d:%c:%d:%d:%d:%d", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apid)) {
+ strncpy(name, buffer, MaxChannelName - 1);
+ name[strlen(buffer)] = 0;
+ delete buffer;
+ return true;
+ }
+ return false;
+}
+
+bool cChannel::Save(FILE *f)
+{
+ return fprintf(f, "%s:%d:%c:%d:%d:%d:%d\n", name, frequency, polarization, diseqc, srate, vpid, apid) > 0;
+}
+
+bool cChannel::Switch(void)
+{
+ if (!ChannelLocked) {
+ isyslog(LOG_INFO, "switching to channel %d", Index() + 1);
+ CurrentChannel = Index();
+ Interface.DisplayChannel(CurrentChannel + 1, name);
+ for (int i = 3; --i;) {
+ if (DvbSetChannel(frequency, polarization, diseqc, srate, vpid, apid))
+ return true;
+ esyslog(LOG_ERR, "retrying");
+ }
+ }
+ Interface.Info("Channel locked (recording)!");
+ return false;
+}
+
+bool cChannel::SwitchTo(int i)
+{
+ cChannel *channel = Channels.Get(i);
+ return channel && channel->Switch();
+}
+
+// -- cTimer -----------------------------------------------------------------
+
+cTimer::cTimer(void)
+{
+ *file = 0;
+}
+
+int cTimer::TimeToInt(int t)
+{
+ return (t / 100 * 60 + t % 100) * 60;
+}
+
+int cTimer::ParseDay(char *s)
+{
+ char *tail;
+ int d = strtol(s, &tail, 10);
+ if (tail && *tail) {
+ d = 0;
+ if (tail == s) {
+ if (strlen(s) == 7) {
+ for (char *p = s + 6; p >= s; p--) {
+ d <<= 1;
+ d |= (*p != '-');
+ }
+ d |= 0x80000000;
+ }
+ }
+ }
+ else if (d < 1 || d > 31)
+ d = 0;
+ return d;
+}
+
+char *cTimer::PrintDay(int d)
+{
+ static char buffer[8];
+ if ((d & 0x80000000) != 0) {
+ char *b = buffer;
+ char *w = "MTWTFSS";
+ *b = 0;
+ while (*w) {
+ *b++ = (d & 1) ? *w : '-';
+ d >>= 1;
+ w++;
+ }
+ }
+ else
+ sprintf(buffer, "%d", d);
+ return buffer;
+}
+
+bool cTimer::Parse(char *s)
+{
+ char *buffer1 = NULL;
+ char *buffer2 = NULL;
+ if (9 == sscanf(s, "%d:%d:%a[^:]:%d:%d:%c:%d:%d:%as", &active, &channel, &buffer1, &start, &stop, &quality, &priority, &lifetime, &buffer2)) {
+ day = ParseDay(buffer1);
+ strncpy(file, buffer2, MaxFileName - 1);
+ file[strlen(buffer2)] = 0;
+ delete buffer1;
+ delete buffer2;
+ return day != 0;
+ }
+ return false;
+}
+
+bool cTimer::Save(FILE *f)
+{
+ return fprintf(f, "%d:%d:%s:%d:%d:%c:%d:%d:%s\n", active, channel, PrintDay(day), start, stop, quality, priority, lifetime, file) > 0;
+}
+
+bool cTimer::Matches(void)
+{
+ if (active) {
+ time_t t = time(NULL);
+ struct tm *now = localtime(&t);
+ int weekday = now->tm_wday == 0 ? 6 : now->tm_wday - 1; // we start with monday==0!
+ int current = (now->tm_hour * 60 + now->tm_min) * 60 + now->tm_sec;
+ int begin = TimeToInt(start);
+ int end = TimeToInt(stop);
+ bool twoDays = (end < begin);
+
+ bool todayMatches = false, yesterdayMatches = false;
+ if ((day & 0x80000000) != 0) {
+ if ((day & (1 << weekday)) != 0)
+ todayMatches = true;
+ else if (twoDays) {
+ int yesterday = weekday == 0 ? 6 : weekday - 1;
+ if ((day & (1 << yesterday)) != 0)
+ yesterdayMatches = true;
+ }
+ }
+ else if (day == now->tm_mday)
+ todayMatches = true;
+ else if (twoDays) {
+ t -= 86400;
+ now = localtime(&t);
+ if (day == now->tm_mday)
+ yesterdayMatches = true;
+ }
+ return (todayMatches && current >= begin && (current <= end || twoDays))
+ || (twoDays && yesterdayMatches && current <= end);
+ }
+ return false;
+}
+
+cTimer *cTimer::GetMatch(void)
+{
+ cTimer *t = (cTimer *)Timers.First();
+ while (t) {
+ if (t->Matches())
+ return t;
+ t = (cTimer *)t->Next();
+ }
+ return NULL;
+}
+
+// -- cKeys ------------------------------------------------------------------
+
+cKeys Keys;
+
+// -- cChannels --------------------------------------------------------------
+
+int CurrentChannel = 0;
+bool ChannelLocked = false;
+
+cChannels Channels;
+
+// -- cTimers ----------------------------------------------------------------
+
+cTimers Timers;
+