Home

Dokumentation

Impressum

Dokumentation VDR
 

Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

config.c

Go to the documentation of this file.
00001 /*
00002  * config.c: Configuration file handling
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * $Id: config.c 1.112 2002/11/02 13:13:49 kls Exp $
00008  */
00009 
00010 #include "config.h"
00011 #include <ctype.h>
00012 #include <stdlib.h>
00013 #include "i18n.h"
00014 #include "interface.h"
00015 #include "plugin.h"
00016 #include "recording.h"
00017 
00018 // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
00019 // format characters in order to allow any number of blanks after a numeric
00020 // value!
00021 
00022 // --- cCommand -------------------------------------------------------------
00023 
00024 char *cCommand::result = NULL;
00025 
00026 cCommand::cCommand(void)
00027 {
00028   title = command = NULL;
00029   confirm = false;
00030 }
00031 
00032 cCommand::~cCommand()
00033 {
00034   free(title);
00035   free(command);
00036 }
00037 
00038 bool cCommand::Parse(const char *s)
00039 {
00040   const char *p = strchr(s, ':');
00041   if (p) {
00042      int l = p - s;
00043      if (l > 0) {
00044         title = MALLOC(char, l + 1);
00045         stripspace(strn0cpy(title, s, l + 1));
00046         if (!isempty(title)) {
00047            int l = strlen(title);
00048            if (l > 1 && title[l - 1] == '?') {
00049               confirm = true;
00050               title[l - 1] = 0;
00051               }
00052            command = stripspace(strdup(skipspace(p + 1)));
00053            return !isempty(command);
00054            }
00055         }
00056      }
00057   return false;
00058 }
00059 
00060 const char *cCommand::Execute(const char *Parameters)
00061 {
00062   free(result);
00063   result = NULL;
00064   char *cmdbuf = NULL;
00065   if (Parameters)
00066      asprintf(&cmdbuf, "%s %s", command, Parameters);
00067   const char *cmd = cmdbuf ? cmdbuf : command;
00068   dsyslog("executing command '%s'", cmd);
00069   FILE *p = popen(cmd, "r");
00070   if (p) {
00071      int l = 0;
00072      int c;
00073      while ((c = fgetc(p)) != EOF) {
00074            if (l % 20 == 0)
00075               result = (char *)realloc(result, l + 21);
00076            result[l++] = c;
00077            }
00078      if (result)
00079         result[l] = 0;
00080      pclose(p);
00081      }
00082   else
00083      esyslog("ERROR: can't open pipe for command '%s'", cmd);
00084   free(cmdbuf);
00085   return result;
00086 }
00087 
00088 // -- cSVDRPhost -------------------------------------------------------------
00089 
00090 cSVDRPhost::cSVDRPhost(void)
00091 {
00092   addr.s_addr = 0;
00093   mask = 0;
00094 }
00095 
00096 bool cSVDRPhost::Parse(const char *s)
00097 {
00098   mask = 0xFFFFFFFF;
00099   const char *p = strchr(s, '/');
00100   if (p) {
00101      char *error = NULL;
00102      int m = strtoul(p + 1, &error, 10);
00103      if (error && *error && !isspace(*error) || m > 32)
00104         return false;
00105      *(char *)p = 0; // yes, we know it's 'const' - will be restored!
00106      if (m == 0)
00107         mask = 0;
00108      else
00109         mask >>= (32 - m);
00110      }
00111   int result = inet_aton(s, &addr);
00112   if (p)
00113      *(char *)p = '/'; // there it is again
00114   return result != 0 && (mask != 0 || addr.s_addr == 0);
00115 }
00116 
00117 bool cSVDRPhost::Accepts(in_addr_t Address)
00118 {
00119   return (Address & mask) == addr.s_addr;
00120 }
00121 
00122 // -- cCaDefinition ----------------------------------------------------------
00123 
00124 cCaDefinition::cCaDefinition(void)
00125 {
00126   number = 0;
00127   description = NULL;
00128 }
00129 
00130 cCaDefinition::~cCaDefinition()
00131 {
00132   free(description);
00133 }
00134 
00135 bool cCaDefinition::Parse(const char *s)
00136 {
00137   return 2 == sscanf(s, "%d %a[^\n]", &number, &description) && description && *description;
00138 }
00139 
00140 // -- cCommands --------------------------------------------------------------
00141 
00142 cCommands Commands;
00143 cCommands RecordingCommands;
00144 
00145 // -- cSVDRPhosts ------------------------------------------------------------
00146 
00147 cSVDRPhosts SVDRPhosts;
00148 
00149 bool cSVDRPhosts::Acceptable(in_addr_t Address)
00150 {
00151   cSVDRPhost *h = First();
00152   while (h) {
00153         if (h->Accepts(Address))
00154            return true;
00155         h = (cSVDRPhost *)h->Next();
00156         }
00157   return false;
00158 }
00159 
00160 // -- cCaDefinitions ---------------------------------------------------------
00161 
00162 cCaDefinitions CaDefinitions;
00163 
00164 const cCaDefinition *cCaDefinitions::Get(int Number)
00165 {
00166   cCaDefinition *p = First();
00167   while (p) {
00168         if (p->Number() == Number)
00169            return p;
00170         p = (cCaDefinition *)p->Next();
00171         }
00172   return NULL;
00173 }
00174 
00175 // -- cSetupLine -------------------------------------------------------------
00176 
00177 cSetupLine::cSetupLine(void)
00178 {
00179   plugin = name = value = NULL;
00180 }
00181 
00182 cSetupLine::cSetupLine(const char *Name, const char *Value, const char *Plugin)
00183 {
00184   name = strdup(Name);
00185   value = strdup(Value);
00186   plugin = Plugin ? strdup(Plugin) : NULL;
00187 }
00188 
00189 cSetupLine::~cSetupLine()
00190 {
00191   free(plugin);
00192   free(name);
00193   free(value);
00194 }
00195 
00196 bool cSetupLine::operator< (const cListObject &ListObject)
00197 {
00198   const cSetupLine *sl = (cSetupLine *)&ListObject;
00199   if (!plugin && !sl->plugin)
00200      return strcasecmp(name, sl->name) < 0;
00201   if (!plugin)
00202      return true;
00203   if (!sl->plugin)
00204      return false;
00205   int result = strcasecmp(plugin, sl->plugin);
00206   if (result == 0)
00207      result = strcasecmp(name, sl->name);
00208   return result < 0;
00209 }
00210 
00211 bool cSetupLine::Parse(char *s)
00212 {
00213   char *p = strchr(s, '=');
00214   if (p) {
00215      *p = 0;
00216      char *Name  = compactspace(s);
00217      char *Value = compactspace(p + 1);
00218      if (*Name && *Value) {
00219         p = strchr(Name, '.');
00220         if (p) {
00221            *p = 0;
00222            char *Plugin = compactspace(Name);
00223            Name = compactspace(p + 1);
00224            if (!(*Plugin && *Name))
00225               return false;
00226            plugin = strdup(Plugin);
00227            }
00228         name = strdup(Name);
00229         value = strdup(Value);
00230         return true;
00231         }
00232      }
00233   return false;
00234 }
00235 
00236 bool cSetupLine::Save(FILE *f)
00237 {
00238   return fprintf(f, "%s%s%s = %s\n", plugin ? plugin : "", plugin ? "." : "", name, value) > 0;
00239 }
00240 
00241 // -- cSetup -----------------------------------------------------------------
00242 
00243 cSetup Setup;
00244 
00245 cSetup::cSetup(void)
00246 {
00247   OSDLanguage = 0;
00248   PrimaryDVB = 1;
00249   ShowInfoOnChSwitch = 1;
00250   MenuScrollPage = 1;
00251   MarkInstantRecord = 1;
00252   strcpy(NameInstantRecord, "TITLE EPISODE");
00253   InstantRecordTime = 180;
00254   LnbSLOF    = 11700;
00255   LnbFrequLo =  9750;
00256   LnbFrequHi = 10600;
00257   DiSEqC = 0;
00258   SetSystemTime = 0;
00259   TimeTransponder = 0;
00260   MarginStart = 2;
00261   MarginStop = 10;
00262   EPGScanTimeout = 5;
00263   EPGBugfixLevel = 2;
00264   SVDRPTimeout = 300;
00265   SortTimers = 1;
00266   PrimaryLimit = 0;
00267   DefaultPriority = 50;
00268   DefaultLifetime = 50;
00269   UseSubtitle = 1;
00270   RecordingDirs = 1;
00271   VideoFormat = 0;
00272   RecordDolbyDigital = 1;
00273   ChannelInfoPos = 0;
00274   OSDwidth = 52;
00275   OSDheight = 18;
00276   OSDMessageTime = 1;
00277   MaxVideoFileSize = MAXVIDEOFILESIZE;
00278   SplitEditedFiles = 0;
00279   MinEventTimeout = 30;
00280   MinUserInactivity = 120;
00281   MultiSpeedMode = 0;
00282   ShowReplayMode = 0;
00283   memset(CaCaps, sizeof(CaCaps), 0);
00284   CurrentChannel = -1;
00285   CurrentVolume = MAXVOLUME;
00286 }
00287 
00288 cSetup& cSetup::operator= (const cSetup &s)
00289 {
00290   memcpy(&__BeginData__, &s.__BeginData__, (char *)&s.__EndData__ - (char *)&s.__BeginData__);
00291   return *this;
00292 }
00293 
00294 cSetupLine *cSetup::Get(const char *Name, const char *Plugin)
00295 {
00296   for (cSetupLine *l = First(); l; l = Next(l)) {
00297       if ((l->Plugin() == NULL) == (Plugin == NULL)) {
00298          if ((!Plugin || strcasecmp(l->Plugin(), Plugin) == 0) && strcasecmp(l->Name(), Name) == 0)
00299             return l;
00300          }
00301       }
00302   return NULL;
00303 }
00304 
00305 void cSetup::Store(const char *Name, const char *Value, const char *Plugin, bool AllowMultiple)
00306 {
00307   if (Name && *Name) {
00308      cSetupLine *l = Get(Name, Plugin);
00309      if (l && !AllowMultiple)
00310         Del(l);
00311      if (Value)
00312         Add(new cSetupLine(Name, Value, Plugin));
00313      }
00314 }
00315 
00316 void cSetup::Store(const char *Name, int Value, const char *Plugin)
00317 {
00318   char *buffer = NULL;
00319   asprintf(&buffer, "%d", Value);
00320   Store(Name, buffer, Plugin);
00321   free(buffer);
00322 }
00323 
00324 bool cSetup::Load(const char *FileName)
00325 {
00326   if (cConfig<cSetupLine>::Load(FileName, true)) {
00327      bool result = true;
00328      for (cSetupLine *l = First(); l; l = Next(l)) {
00329          bool error = false;
00330          if (l->Plugin()) {
00331             cPlugin *p = cPluginManager::GetPlugin(l->Plugin());
00332             if (p && !p->SetupParse(l->Name(), l->Value()))
00333                error = true;
00334             }
00335          else {
00336             if (!Parse(l->Name(), l->Value()))
00337                error = true;
00338             }
00339          if (error) {
00340             esyslog("ERROR: unknown config parameter: %s%s%s = %s", l->Plugin() ? l->Plugin() : "", l->Plugin() ? "." : "", l->Name(), l->Value());
00341             result = false;
00342             }
00343          }
00344      return result;
00345      }
00346   return false;
00347 }
00348 
00349 void cSetup::StoreCaCaps(const char *Name)
00350 {
00351   cSetupLine *l;
00352   while ((l = Get(Name)) != NULL)
00353         Del(l);
00354   for (int d = 0; d < MAXDEVICES; d++) {
00355       char buffer[MAXPARSEBUFFER];
00356       char *q = buffer;
00357       *buffer = 0;
00358       for (int i = 0; i < MAXCACAPS; i++) {
00359           if (CaCaps[d][i]) {
00360              if (!*buffer)
00361                 q += snprintf(buffer, sizeof(buffer), "%d", d + 1);
00362              q += snprintf(q, sizeof(buffer) - (q - buffer), " %d", CaCaps[d][i]);
00363              }
00364           }
00365       if (*buffer)
00366          Store(Name, buffer, NULL, true);
00367       }
00368 }
00369 
00370 bool cSetup::ParseCaCaps(const char *Value)
00371 {
00372   char *p;
00373   int d = strtol(Value, &p, 10);
00374   if (d > 0 && d <= MAXDEVICES) {
00375      d--;
00376      int i = 0;
00377      while (p != Value && p && *p) {
00378            if (i < MAXCACAPS) {
00379               int c = strtol(p, &p, 10);
00380               if (c > 0)
00381                  CaCaps[d][i++] = c;
00382               else
00383                  return false;
00384               }
00385            else
00386               return false;
00387            }
00388      return true;
00389      }
00390   return false;
00391 }
00392 
00393 bool cSetup::Parse(const char *Name, const char *Value)
00394 {
00395   if      (!strcasecmp(Name, "OSDLanguage"))         OSDLanguage        = atoi(Value);
00396   else if (!strcasecmp(Name, "PrimaryDVB"))          PrimaryDVB         = atoi(Value);
00397   else if (!strcasecmp(Name, "ShowInfoOnChSwitch"))  ShowInfoOnChSwitch = atoi(Value);
00398   else if (!strcasecmp(Name, "MenuScrollPage"))      MenuScrollPage     = atoi(Value);
00399   else if (!strcasecmp(Name, "MarkInstantRecord"))   MarkInstantRecord  = atoi(Value);
00400   else if (!strcasecmp(Name, "NameInstantRecord"))   strn0cpy(NameInstantRecord, Value, MaxFileName);
00401   else if (!strcasecmp(Name, "InstantRecordTime"))   InstantRecordTime  = atoi(Value);
00402   else if (!strcasecmp(Name, "LnbSLOF"))             LnbSLOF            = atoi(Value);
00403   else if (!strcasecmp(Name, "LnbFrequLo"))          LnbFrequLo         = atoi(Value);
00404   else if (!strcasecmp(Name, "LnbFrequHi"))          LnbFrequHi         = atoi(Value);
00405   else if (!strcasecmp(Name, "DiSEqC"))              DiSEqC             = atoi(Value);
00406   else if (!strcasecmp(Name, "SetSystemTime"))       SetSystemTime      = atoi(Value);
00407   else if (!strcasecmp(Name, "TimeTransponder"))     TimeTransponder    = atoi(Value);
00408   else if (!strcasecmp(Name, "MarginStart"))         MarginStart        = atoi(Value);
00409   else if (!strcasecmp(Name, "MarginStop"))          MarginStop         = atoi(Value);
00410   else if (!strcasecmp(Name, "EPGScanTimeout"))      EPGScanTimeout     = atoi(Value);
00411   else if (!strcasecmp(Name, "EPGBugfixLevel"))      EPGBugfixLevel     = atoi(Value);
00412   else if (!strcasecmp(Name, "SVDRPTimeout"))        SVDRPTimeout       = atoi(Value);
00413   else if (!strcasecmp(Name, "SortTimers"))          SortTimers         = atoi(Value);
00414   else if (!strcasecmp(Name, "PrimaryLimit"))        PrimaryLimit       = atoi(Value);
00415   else if (!strcasecmp(Name, "DefaultPriority"))     DefaultPriority    = atoi(Value);
00416   else if (!strcasecmp(Name, "DefaultLifetime"))     DefaultLifetime    = atoi(Value);
00417   else if (!strcasecmp(Name, "UseSubtitle"))         UseSubtitle        = atoi(Value);
00418   else if (!strcasecmp(Name, "RecordingDirs"))       RecordingDirs      = atoi(Value);
00419   else if (!strcasecmp(Name, "VideoFormat"))         VideoFormat        = atoi(Value);
00420   else if (!strcasecmp(Name, "RecordDolbyDigital"))  RecordDolbyDigital = atoi(Value);
00421   else if (!strcasecmp(Name, "ChannelInfoPos"))      ChannelInfoPos     = atoi(Value);
00422   else if (!strcasecmp(Name, "OSDwidth"))            OSDwidth           = atoi(Value);
00423   else if (!strcasecmp(Name, "OSDheight"))           OSDheight          = atoi(Value);
00424   else if (!strcasecmp(Name, "OSDMessageTime"))      OSDMessageTime     = atoi(Value);
00425   else if (!strcasecmp(Name, "MaxVideoFileSize"))    MaxVideoFileSize   = atoi(Value);
00426   else if (!strcasecmp(Name, "SplitEditedFiles"))    SplitEditedFiles   = atoi(Value);
00427   else if (!strcasecmp(Name, "MinEventTimeout"))     MinEventTimeout    = atoi(Value);
00428   else if (!strcasecmp(Name, "MinUserInactivity"))   MinUserInactivity  = atoi(Value);
00429   else if (!strcasecmp(Name, "MultiSpeedMode"))      MultiSpeedMode     = atoi(Value);
00430   else if (!strcasecmp(Name, "ShowReplayMode"))      ShowReplayMode     = atoi(Value);
00431   else if (!strcasecmp(Name, "CaCaps"))              return ParseCaCaps(Value);
00432   else if (!strcasecmp(Name, "CurrentChannel"))      CurrentChannel     = atoi(Value);
00433   else if (!strcasecmp(Name, "CurrentVolume"))       CurrentVolume      = atoi(Value);
00434   else
00435      return false;
00436   return true;
00437 }
00438 
00439 bool cSetup::Save(void)
00440 {
00441   Store("OSDLanguage",        OSDLanguage);
00442   Store("PrimaryDVB",         PrimaryDVB);
00443   Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch);
00444   Store("MenuScrollPage",     MenuScrollPage);
00445   Store("MarkInstantRecord",  MarkInstantRecord);
00446   Store("NameInstantRecord",  NameInstantRecord);
00447   Store("InstantRecordTime",  InstantRecordTime);
00448   Store("LnbSLOF",            LnbSLOF);
00449   Store("LnbFrequLo",         LnbFrequLo);
00450   Store("LnbFrequHi",         LnbFrequHi);
00451   Store("DiSEqC",             DiSEqC);
00452   Store("SetSystemTime",      SetSystemTime);
00453   Store("TimeTransponder",    TimeTransponder);
00454   Store("MarginStart",        MarginStart);
00455   Store("MarginStop",         MarginStop);
00456   Store("EPGScanTimeout",     EPGScanTimeout);
00457   Store("EPGBugfixLevel",     EPGBugfixLevel);
00458   Store("SVDRPTimeout",       SVDRPTimeout);
00459   Store("SortTimers",         SortTimers);
00460   Store("PrimaryLimit",       PrimaryLimit);
00461   Store("DefaultPriority",    DefaultPriority);
00462   Store("DefaultLifetime",    DefaultLifetime);
00463   Store("UseSubtitle",        UseSubtitle);
00464   Store("RecordingDirs",      RecordingDirs);
00465   Store("VideoFormat",        VideoFormat);
00466   Store("RecordDolbyDigital", RecordDolbyDigital);
00467   Store("ChannelInfoPos",     ChannelInfoPos);
00468   Store("OSDwidth",           OSDwidth);
00469   Store("OSDheight",          OSDheight);
00470   Store("OSDMessageTime",     OSDMessageTime);
00471   Store("MaxVideoFileSize",   MaxVideoFileSize);
00472   Store("SplitEditedFiles",   SplitEditedFiles);
00473   Store("MinEventTimeout",    MinEventTimeout);
00474   Store("MinUserInactivity",  MinUserInactivity);
00475   Store("MultiSpeedMode",     MultiSpeedMode);
00476   Store("ShowReplayMode",     ShowReplayMode);
00477   StoreCaCaps("CaCaps");
00478   Store("CurrentChannel",     CurrentChannel);
00479   Store("CurrentVolume",      CurrentVolume);
00480 
00481   Sort();
00482 
00483   if (cConfig<cSetupLine>::Save()) {
00484      isyslog("saved setup to %s", FileName());
00485      return true;
00486      }
00487   return false;
00488 }

Generated on Wed Feb 5 23:30:07 2003 for VDR by doxygen1.3-rc2