Filesystem hierachy standard patch needs review.

Message ID 4F81C974.6030809@gmx.de
State New
Headers

Commit Message

Udo Richter April 8, 2012, 5:23 p.m. UTC
  Am 08.04.2012 09:48, schrieb Manuel Reimer:
> It is difficult to read your description (and no, I didn't understand
> it). How would you want to document this in a way, someone actually
> understands it?

I guess I have to find a way to be more clear...

Ok, second attempt:
- Makefile does not set CACHEDIR and RESDIR
- Make.config *can* set CACHEDIR and RESDIR, or not.
- If --cachedir or --resdir is set by command line, use them.
- If not, default to CACHEDIR and RESDIR.
- If CACHEDIR or RESDIR is not set (empty string), fall back to whatever
--video and --config is set to.


Patched patch attached. ;)
Needs documentation updated though.


Cheers,

Udo
  

Comments

Christopher Reimer April 8, 2012, 5:57 p.m. UTC | #1
2012/4/8 Udo Richter <udo_richter@gmx.de>

> - If CACHEDIR or RESDIR is not set (empty string), fall back to whatever
> --video and --config is set to.
>

No, CACHEDIR and RESDIR should work in the same behaviour as CONFDIR or
VIDEODIR.

This sounds a bit like you set all your directories by command line. Sorry,
but why don't you just use Make.config like everyone else does.
  
VDRU VDRU April 8, 2012, 7:02 p.m. UTC | #2
On Sun, Apr 8, 2012 at 10:57 AM, Christopher Reimer
<c.reimer1993@googlemail.com> wrote:
>> - If CACHEDIR or RESDIR is not set (empty string), fall back to whatever
>> --video and --config is set to.
>
> No, CACHEDIR and RESDIR should work in the same behaviour as CONFDIR or
> VIDEODIR.
>
> This sounds a bit like you set all your directories by command line. Sorry,
> but why don't you just use Make.config like everyone else does.

I know several people who set their directories on the command line
and ignore maintaining Make.config completely so it's not true
everyone uses Make.config.

Cheers
  
Christopher Reimer April 8, 2012, 9:11 p.m. UTC | #3
2012/4/8 VDR User <user.vdr@gmail.com>

> I know several people who set their directories on the command line
> and ignore maintaining Make.config completely so it's not true
> everyone uses Make.config.
>

OK, that could be possible, although I don't understand why.

Let's wait what Klaus says.
  
VDRU VDRU April 9, 2012, 12:13 a.m. UTC | #4
On Sun, Apr 8, 2012 at 2:11 PM, Christopher Reimer
<c.reimer1993@googlemail.com> wrote:
> 2012/4/8 VDR User <user.vdr@gmail.com>
>>
>> I know several people who set their directories on the command line
>> and ignore maintaining Make.config completely so it's not true
>> everyone uses Make.config.
>
> OK, that could be possible, although I don't understand why.

For me personally, I set these things (and many others) in my
(multi-purpose) tv script so I have most settings in one place. I
prefer consolidating when possible simply because it's easier to
maintain in my opinion. Any time I update VDR for example, I don't
have to worry about modifying or copying an archived Make.config. I
just compile the source, set my /vdr symlink to it and "tv restart".

Cheers
  
Klaus Schmidinger April 9, 2012, 9:54 a.m. UTC | #5
On 08.04.2012 23:11, Christopher Reimer wrote:
> 2012/4/8 VDR User <user.vdr@gmail.com <mailto:user.vdr@gmail.com>>
>
>     I know several people who set their directories on the command line
>     and ignore maintaining Make.config completely so it's not true
>     everyone uses Make.config.
>
>
> OK, that could be possible, although I don't understand why.
>
> Let's wait what Klaus says.

The only condition I want to be met is that when building the original,
unpatched VDR out of the box, without any user defined Make.config etc.,
it needs to behave just like it does now.

However, there is one thing in the current behavior that I would even
consider a bug: if one starts VDR with

   vdr -v /mydir

it uses /mydir as the video directory, but still uses /video for the
configuration files. I believe that as long as there is no explicit
-c option given, the config directory should follow what's given in
the -v option. So I wouldn't mind if this was fixed along with implementing
the FHS stuff ;-) (or in a separate step).

Klaus
  
Manuel Reimer April 9, 2012, 9:54 a.m. UTC | #6
Udo Richter wrote:

> Ok, second attempt:
> - Makefile does not set CACHEDIR and RESDIR
> - Make.config *can* set CACHEDIR and RESDIR, or not.
> - If --cachedir or --resdir is set by command line, use them.
> - If not, default to CACHEDIR and RESDIR.
> - If CACHEDIR or RESDIR is not set (empty string), fall back to whatever
> --video and --config is set to.
> 
> Patched patch attached. ;)
> Needs documentation updated though.

Do so. I guess it is nearly impossible to document this in a way, a user actually understands.

Yours

Manuel
  
Christopher Reimer April 9, 2012, 10:35 a.m. UTC | #7
2012/4/9 Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
>
> However, there is one thing in the current behavior that I would even
> consider a bug: if one starts VDR with
>
>  vdr -v /mydir
>
> it uses /mydir as the video directory, but still uses /video for the
> configuration files. I believe that as long as there is no explicit
> -c option given, the config directory should follow what's given in
> the -v option. So I wouldn't mind if this was fixed along with implementing
> the FHS stuff ;-) (or in a separate step).
>
>
Ok, maybe Udo can add this to the patch.

Udo, please also mind the additional Makefile change I mentioned before.

I can't find a special place where to add this to the documentation. In
addition I think it's self explanatory
  
Pertti Kosunen April 9, 2012, 11:15 a.m. UTC | #8
On 9.4.2012 12:54, Klaus Schmidinger wrote:
> vdr -v /mydir
>
> it uses /mydir as the video directory, but still uses /video for the
> configuration files. I believe that as long as there is no explicit
> -c option given, the config directory should follow what's given in
> the -v option.

Shouldn't it follow option given at ./configure?
  
Klaus Schmidinger April 9, 2012, 11:19 a.m. UTC | #9
On 09.04.2012 13:15, Pertti Kosunen wrote:
> On 9.4.2012 12:54, Klaus Schmidinger wrote:
>> vdr -v /mydir
>>
>> it uses /mydir as the video directory, but still uses /video for the
>> configuration files. I believe that as long as there is no explicit
>> -c option given, the config directory should follow what's given in
>> the -v option.
>
> Shouldn't it follow option given at ./configure?

What "./configure"???

Klaus
  
Pertti Kosunen April 9, 2012, 11:44 a.m. UTC | #10
On 9.4.2012 14:19, Klaus Schmidinger wrote:
> What "./configure"???

When compiling VDR from source, "./configure ; make ; make install".
  
Klaus Schmidinger April 9, 2012, 11:50 a.m. UTC | #11
On 09.04.2012 13:44, Pertti Kosunen wrote:
> On 9.4.2012 14:19, Klaus Schmidinger wrote:
>> What "./configure"???
>
> When compiling VDR from source, "./configure ; make ; make install".

There is no "./configure" in the VDR source.

Klaus
  
Udo Richter April 9, 2012, 1:18 p.m. UTC | #12
Am 09.04.2012 11:54, schrieb Klaus Schmidinger:
> However, there is one thing in the current behavior that I would even
> consider a bug: if one starts VDR with
> 
>   vdr -v /mydir
> 
> it uses /mydir as the video directory, but still uses /video for the
> configuration files. I believe that as long as there is no explicit
> -c option given, the config directory should follow what's given in
> the -v option.

You're sure about -c following -v? It worked that way until 1.5.8, but
has been dropped in favor of the final changes regarding CONFDIR in
1.5.11. I don't see any reason to change that. Or did you mess up
--config with --cachedir? Happened to me too.


In the latter case:
In my patch, the cacheDirectory follows the VideoDirectory, even if the
latter is set by --video, but only as long as CACHEDIR is un-set. (Same
applies to --config and RESDIR.)

I'm not sure whether this should also be the case if VDR is compiled to
be FHS compliant. In that case users should know about the various
folders, and setting a --video directory should not have precedence over
CACHEDIR=/var/lib/vdr. The only thing I could think of is to check
whether CACHEDIR==VIDEODIR, and only then let cacheDirectory follow
--video, but I would prefer to not use such hacks.
  
Klaus Schmidinger April 9, 2012, 2:22 p.m. UTC | #13
On 09.04.2012 15:18, Udo Richter wrote:
> Am 09.04.2012 11:54, schrieb Klaus Schmidinger:
>> However, there is one thing in the current behavior that I would even
>> consider a bug: if one starts VDR with
>>
>>    vdr -v /mydir
>>
>> it uses /mydir as the video directory, but still uses /video for the
>> configuration files. I believe that as long as there is no explicit
>> -c option given, the config directory should follow what's given in
>> the -v option.
>
> You're sure about -c following -v? It worked that way until 1.5.8, but
> has been dropped in favor of the final changes regarding CONFDIR in
> 1.5.11. I don't see any reason to change that. Or did you mess up
> --config with --cachedir? Happened to me too.

I surely didn't mean --cachedir because my VDR doesn't have that option (yet) ;-).
A while ago I ran a test and wanted to use a different video directory,
so I started VDR with the -v option. I was surprised to see that it still
loaded the config files from the default /video directory.

> In the latter case:
> In my patch, the cacheDirectory follows the VideoDirectory, even if the
> latter is set by --video, but only as long as CACHEDIR is un-set. (Same
> applies to --config and RESDIR.)
>
> I'm not sure whether this should also be the case if VDR is compiled to
> be FHS compliant. In that case users should know about the various
> folders, and setting a --video directory should not have precedence over
> CACHEDIR=/var/lib/vdr. The only thing I could think of is to check
> whether CACHEDIR==VIDEODIR, and only then let cacheDirectory follow
> --video, but I would prefer to not use such hacks.

Currently VDR has only two directories, 'video' and 'config'.
The idea is that by default the video directory is /video, and
the config directory is the same. If -v is given, this changes the
video directory, and since config follows video (or at least is supposed to),
the config files will be loaded from the new video directory. Only
if there is an explicit -c option shall the config directory be
different from the video directory.

I'd like to see a similar mechanism for the two new directories
'cache' and 'resource'. By default they follow 'config' and can only
be different if the respective options are given.
The default values for 'cache' and 'resource' shall be empty, in which
case they follow 'config'. If VDR is compiled with non-empty values
for 'cache' and/or 'resource', simply let them no longer follow 'config'
(same behavior as if a command line option has been given).

Don't know whether the patch already behaves this way (haven't checked),
but that's the way it should be.

Klaus
  
Manuel Reimer May 9, 2012, 2:36 p.m. UTC | #14
Hello,

what is the current status in this topic? Anyone working on this?

Yours

Manuel

Klaus Schmidinger wrote:
> On 09.04.2012 15:18, Udo Richter wrote:
>> Am 09.04.2012 11:54, schrieb Klaus Schmidinger:
>>> However, there is one thing in the current behavior that I would even
>>> consider a bug: if one starts VDR with
>>>
>>> vdr -v /mydir
>>>
>>> it uses /mydir as the video directory, but still uses /video for the
>>> configuration files. I believe that as long as there is no explicit
>>> -c option given, the config directory should follow what's given in
>>> the -v option.
>>
>> You're sure about -c following -v? It worked that way until 1.5.8, but
>> has been dropped in favor of the final changes regarding CONFDIR in
>> 1.5.11. I don't see any reason to change that. Or did you mess up
>> --config with --cachedir? Happened to me too.
>
> I surely didn't mean --cachedir because my VDR doesn't have that option (yet) ;-).
> A while ago I ran a test and wanted to use a different video directory,
> so I started VDR with the -v option. I was surprised to see that it still
> loaded the config files from the default /video directory.
>
>> In the latter case:
>> In my patch, the cacheDirectory follows the VideoDirectory, even if the
>> latter is set by --video, but only as long as CACHEDIR is un-set. (Same
>> applies to --config and RESDIR.)
>>
>> I'm not sure whether this should also be the case if VDR is compiled to
>> be FHS compliant. In that case users should know about the various
>> folders, and setting a --video directory should not have precedence over
>> CACHEDIR=/var/lib/vdr. The only thing I could think of is to check
>> whether CACHEDIR==VIDEODIR, and only then let cacheDirectory follow
>> --video, but I would prefer to not use such hacks.
>
> Currently VDR has only two directories, 'video' and 'config'.
> The idea is that by default the video directory is /video, and
> the config directory is the same. If -v is given, this changes the
> video directory, and since config follows video (or at least is supposed to),
> the config files will be loaded from the new video directory. Only
> if there is an explicit -c option shall the config directory be
> different from the video directory.
>
> I'd like to see a similar mechanism for the two new directories
> 'cache' and 'resource'. By default they follow 'config' and can only
> be different if the respective options are given.
> The default values for 'cache' and 'resource' shall be empty, in which
> case they follow 'config'. If VDR is compiled with non-empty values
> for 'cache' and/or 'resource', simply let them no longer follow 'config'
> (same behavior as if a command line option has been given).
>
> Don't know whether the patch already behaves this way (haven't checked),
> but that's the way it should be.
>
> Klaus
>
> _______________________________________________
> vdr mailing list
> vdr@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
  

Patch

diff -ruN vdr-1.7.27/INSTALL vdr-1.7.27.patched//INSTALL
--- vdr-1.7.27/INSTALL	2012-02-27 12:03:14.000000000 +0100
+++ vdr-1.7.27.patched//INSTALL	2012-04-06 09:43:38.590832504 +0200
@@ -375,6 +375,18 @@ 
 VDR archive into your video directory (or into your config directory,
 respectively, in case you have redirected it with the -c option).
 
+If you prefer to have your system set up according to the FHS
+("File system Hierarchy Standard") and thus have all your files spread
+around the entire file system, you can do this by adding a Make.config
+file with the following settings
+
+CACHEDIR = /var/cache/vdr
+CONFDIR = /var/lib/vdr
+LOCDIR = $(PREFIX)/share/locale
+PLUGINLIBDIR = $(PREFIX)/lib/vdr
+RESDIR = $(PREFIX)/share/vdr
+VIDEODIR = /srv/vdr/video0
+
 Setting up DiSEqC:
 ------------------
 
diff -ruN vdr-1.7.27/Make.config.template vdr-1.7.27.patched//Make.config.template
--- vdr-1.7.27/Make.config.template	2012-03-20 12:20:13.000000000 +0100
+++ vdr-1.7.27.patched//Make.config.template	2012-04-06 09:43:38.591832504 +0200
@@ -33,6 +33,8 @@ 
 PLUGINLIBDIR = $(PLUGINDIR)/lib
 VIDEODIR     = /video
 CONFDIR      = $(VIDEODIR)
+#CACHEDIR     = $(VIDEODIR)
+#RESDIR       = $(CONFDIR)
 
 ### The remote control:
 
diff -ruN vdr-1.7.27/Makefile vdr-1.7.27.patched//Makefile
--- vdr-1.7.27/Makefile	2012-03-11 16:33:57.000000000 +0100
+++ vdr-1.7.27.patched//Makefile	2012-04-06 10:06:28.004832504 +0200
@@ -29,6 +29,8 @@ 
 
 VIDEODIR = /video
 CONFDIR  = $(VIDEODIR)
+#CACHEDIR = $(VIDEODIR)
+#RESDIR   = $(CONFDIR)
 
 DOXYGEN ?= /usr/bin/doxygen
 DOXYFILE = Doxyfile
@@ -71,6 +73,8 @@ 
 DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
 DEFINES += -DCONFDIR=\"$(CONFDIR)\"
 DEFINES += -DPLUGINDIR=\"$(PLUGINLIBDIR)\"
+DEFINES += -DCACHEDIR=\"$(CACHEDIR)\"
+DEFINES += -DRESDIR=\"$(RESDIR)\"
 DEFINES += -DLOCDIR=\"$(LOCDIR)\"
 
 # The version numbers of VDR and the plugin API (taken from VDR's "config.h"):
@@ -112,6 +116,8 @@ 
 	@echo "configdir=$(CONFDIR)" >> $@
 	@echo "videodir=$(VIDEODIR)" >> $@
 	@echo "plugindir=$(PLUGINLIBDIR)" >> $@
+	@echo "cachedir=$(CACHEDIR)" >> $@
+	@echo "resdir=$(RESDIR)" >> $@
 	@echo "localedir=$(LOCDIR)" >> $@
 	@echo "apiversion=$(APIVERSION)" >> $@
 	@echo "cflags=$(CXXFLAGS) $(DEFINES) -I\$${includedir}" >> $@
@@ -183,7 +189,7 @@ 
 
 # Install the files:
 
-install: install-bin install-conf install-doc install-plugins install-i18n install-includes install-pc
+install: install-bin install-dirs install-conf install-doc install-plugins install-i18n install-includes install-pc
 
 # VDR binary:
 
@@ -193,12 +199,15 @@ 
 
 # Configuration files:
 
-install-conf:
+install-dirs:
 	@mkdir -p $(DESTDIR)$(VIDEODIR)
-	@if [ ! -d $(DESTDIR)$(CONFDIR) ]; then\
-	    mkdir -p $(DESTDIR)$(CONFDIR);\
-	    cp *.conf $(DESTDIR)$(CONFDIR);\
-	    fi
+	@mkdir -p $(DESTDIR)$(CONFDIR)
+	@mkdir -p $(DESTDIR)$(RESDIR)
+	@mkdir -p $(DESTDIR)$(CACHEDIR)
+
+install-conf:
+	@cp *.conf $(DESTDIR)$(CONFDIR)
+
 
 # Documentation:
 
diff -ruN vdr-1.7.27/PLUGINS.html vdr-1.7.27.patched//PLUGINS.html
--- vdr-1.7.27/PLUGINS.html	2012-03-09 10:49:29.000000000 +0100
+++ vdr-1.7.27.patched//PLUGINS.html	2012-04-06 09:43:38.594832504 +0200
@@ -82,7 +82,7 @@ 
 <li><a href="#Wakeup">Wakeup</a>
 <li><a href="#Setup parameters">Setup parameters</a>
 <li><a href="#The Setup menu">The Setup menu</a>
-<li><a href="#Configuration files">Configuration files</a>
+<li><a href="#Additional files">Additional files</a>
 <li><a href="#Internationalization">Internationalization</a>
 <li><a href="#Custom services">Custom services</a>
 <li><a href="#SVDRP commands">SVDRP commands</a>
@@ -885,39 +885,55 @@ 
 your setup parameters and use that one to copy all parameters with one single statement
 (like VDR does with its cSetup class).
 
-<hr><h2><a name="Configuration files">Configuration files</a></h2>
+<hr><h2><a name="Additional files">Additional files</a></h2>
 
 <div class="blurb">I want my own stuff!</div><p>
 
-There may be situations where a plugin requires configuration files of its own, maybe
-for data that can't be stored in the simple <a href="#Setup parameters">setup parameters</a>
-of VDR, or maybe because it needs to launch other programs that simply need a separate
-configuration file. While the plugin is free to store such files anywhere it
-sees fit, it might be a good idea to put them in a common place, preferably
-where other configuration data already exists. VDR provides the function
+There may be situations where a plugin requires own files. While the plugin is
+free to store such files anywhere it sees fit, it might be a good idea to put them in a common
+place, preferably where such data already exists.
+<p>
+<i>configuration files</i>, maybe for data that can't be stored in the simple
+<a href="#Setup parameters">setup parameters</a> of VDR, or maybe because it needs to
+launch other programs that simply need a separate configuration file.
+<p>
+<i>cache files</i>, to store data so that future requests for that data can be served faster. The data
+that is stored within a cache might be values that have been computed earlier or duplicates of
+original values that are stored elsewhere.
+<p>
+<i>resource files</i>, for providing additional files, like pictures, movie clips or channel logos.
+<p>
+Threfore VDR provides three functions
 
 <p><table><tr><td class="code"><pre>
 const char *ConfigDirectory(const char *PluginName = NULL);
 </pre></td></tr></table><p>
+<p><table><tr><td class="code"><pre>
+const char *CacheDirectory(const char *PluginName = NULL);
+</pre></td></tr></table><p>
+<p><table><tr><td class="code"><pre>
+const char *ResourceDirectory(const char *PluginName = NULL);
+</pre></td></tr></table><p>
 
-which returns a string containing the directory that VDR uses for its own configuration
-files (defined through the <tt><b>-c</b></tt> option in the call to VDR), extended by
+each of these return a string containing the directory that VDR uses for its own
+files (defined through the options in the call to VDR), extended by
 <tt>"/plugins"</tt>. So assuming the VDR configuration directory is <tt>/video</tt>
 (the default if no <tt><b>-c</b></tt> or <tt><b>-v</b></tt> option is given),
 a call to <tt>ConfigDirectory()</tt> will return <tt>/video/plugins</tt>. The first
 call to <tt>ConfigDirectory()</tt> will automatically make sure that the <tt>plugins</tt>
 subdirectory will exist. If, for some reason, this cannot be achieved, <tt>NULL</tt>
-will be returned.
+will be returned. The behavoir of <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt>
+is similar
 <p>
 The additional <tt>plugins</tt> directory is used to keep files from plugins apart
 from those of VDR itself, making sure there will be no name clashes. If a plugin
-needs only one extra configuration file, it is suggested that this file be named
-<tt>name.conf</tt>, where <i>name</i> shall be the name of the plugin.
+needs only one extra file, it is suggested that this file be named <tt>name.*</tt>,
+where <i>name</i> shall be the name of the plugin.
 <p>
 If a plugin needs more than one such file, it is suggested that the plugin stores
 these in a subdirectory of its own, named after the plugin. To easily get such a name
-the <tt>ConfigDirectory()</tt> function can be given an additional string that will
-be appended to the returned directory name, as in
+the functions can be given an additional string that will be appended to the returned
+directory name, as in
 
 <p><table><tr><td class="code"><pre>
 const char *MyConfigDir = ConfigDirectory(Name());
@@ -928,13 +944,13 @@ 
 (or return <tt>NULL</tt> in case of an error).
 <p>
 <b>
-The returned string is statically allocated and will be overwritten by subsequent
-calls to ConfigDirectory()!
+The returned strings are statically allocated and will be overwritten by subsequent
+calls!
 </b>
 <p>
-The <tt>ConfigDirectory()</tt> function is a static member function of the <tt>cPlugin</tt>
-class. This allows it to be called even from outside any member function of the derived
-plugin class, by writing
+The <tt>ConfigDirectory()</tt>, <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt>
+functions are static member functions of the <tt>cPlugin</tt> class. This allows them to be
+called even from outside any member function of the derived plugin class, by writing
 
 <p><table><tr><td class="code"><pre>
 const char *MyConfigDir = cPlugin::ConfigDirectory();
diff -ruN vdr-1.7.27/plugin.c vdr-1.7.27.patched//plugin.c
--- vdr-1.7.27/plugin.c	2012-03-11 14:56:02.000000000 +0100
+++ vdr-1.7.27.patched//plugin.c	2012-04-06 09:43:38.595832504 +0200
@@ -26,6 +26,8 @@ 
 // --- cPlugin ---------------------------------------------------------------
 
 char *cPlugin::configDirectory = NULL;
+char *cPlugin::cacheDirectory = NULL;
+char *cPlugin::resourceDirectory = NULL;
 
 cPlugin::cPlugin(void)
 {
@@ -145,6 +147,36 @@ 
   return MakeDirs(buffer, true) ? *buffer : NULL;
 }
 
+void cPlugin::SetCacheDirectory(const char *Dir)
+{
+  free(cacheDirectory);
+  cacheDirectory = strdup(Dir);
+}
+
+const char *cPlugin::CacheDirectory(const char *PluginName)
+{
+  static cString buffer;
+  if (!cThread::IsMainThread())
+     esyslog("ERROR: plugin '%s' called cPlugin::CacheDirectory(), which is not thread safe!", PluginName ? PluginName : "<no name given>");
+  buffer = cString::sprintf("%s/plugins%s%s", cacheDirectory, PluginName ? "/" : "", PluginName ? PluginName : "");
+  return MakeDirs(buffer, true) ? *buffer : NULL;
+}
+
+void cPlugin::SetResourceDirectory(const char *Dir)
+{
+  free(resourceDirectory);
+  resourceDirectory = strdup(Dir);
+}
+
+const char *cPlugin::ResourceDirectory(const char *PluginName)
+{
+  static cString buffer;
+  if (!cThread::IsMainThread())
+     esyslog("ERROR: plugin '%s' called cPlugin::ResourceDirectory(), which is not thread safe!", PluginName ? PluginName : "<no name given>");
+  buffer = cString::sprintf("%s/plugins%s%s", resourceDirectory, PluginName ? "/" : "", PluginName ? PluginName : "");
+  return MakeDirs(buffer, true) ? *buffer : NULL;
+}
+
 // --- cDll ------------------------------------------------------------------
 
 cDll::cDll(const char *FileName, const char *Args)
diff -ruN vdr-1.7.27/plugin.h vdr-1.7.27.patched//plugin.h
--- vdr-1.7.27/plugin.h	2012-03-11 14:55:56.000000000 +0100
+++ vdr-1.7.27.patched//plugin.h	2012-04-06 09:43:38.596832504 +0200
@@ -22,6 +22,8 @@ 
   friend class cPluginManager;
 private:
   static char *configDirectory;
+  static char *cacheDirectory;
+  static char *resourceDirectory;
   const char *name;
   bool started;
   void SetName(const char *s);
@@ -57,6 +59,12 @@ 
 
   static void SetConfigDirectory(const char *Dir);
   static const char *ConfigDirectory(const char *PluginName = NULL);
+
+  static void SetCacheDirectory(const char *Dir);
+  static const char *CacheDirectory(const char *PluginName = NULL);
+
+  static void SetResourceDirectory(const char *Dir);
+  static const char *ResourceDirectory(const char *PluginName = NULL);
   };
 
 class cDll : public cListObject {
diff -ruN vdr-1.7.27/vdr.1 vdr-1.7.27.patched//vdr.1
--- vdr-1.7.27/vdr.1	2012-02-27 12:01:17.000000000 +0100
+++ vdr-1.7.27.patched//vdr.1	2012-04-06 09:43:38.596832504 +0200
@@ -42,6 +42,9 @@ 
 .BI \-a\  cmd ,\ \-\-audio= cmd
 Send Dolby Digital audio to stdin of command \fIcmd\fR.
 .TP
+.BI \-\-cachedir= dir
+save cache files in \fIdir\fR.
+.TP
 .BI \-c\  dir ,\ \-\-config= dir
 Read config files from directory \fIdir\fR
 (default is to read them from the video directory).
@@ -157,6 +160,9 @@ 
 Call \fIcmd\fR before and after a recording. See the file \fIINSTALL\fR for
 more information.
 .TP
+.BI \-\-resdir= dir
+read resource files from \fIdir\fR.
+.TP
 .BI \-s\  cmd ,\ \-\-shutdown= cmd
 Call \fIcmd\fR to shutdown the computer. See the file \fIINSTALL\fR for more
 information.
diff -ruN vdr-1.7.27/vdr.c vdr-1.7.27.patched//vdr.c
--- vdr-1.7.27/vdr.c	2012-03-14 10:09:19.000000000 +0100
+++ vdr-1.7.27.patched//vdr.c	2012-04-06 09:45:15.546832504 +0200
@@ -181,15 +181,19 @@ 
 #define DEFAULTWATCHDOG     0 // seconds
 #define DEFAULTCONFDIR CONFDIR
 #define DEFAULTPLUGINDIR PLUGINDIR
+#define DEFAULTCACHEDIR CACHEDIR
 #define DEFAULTEPGDATAFILENAME "epg.data"
+#define DEFAULTRESDIR RESDIR
 
   bool StartedAsRoot = false;
   const char *VdrUser = NULL;
   bool UserDump = false;
   int SVDRPport = DEFAULTSVDRPPORT;
   const char *AudioCommand = NULL;
+  const char *CacheDirectory = NULL;
   const char *ConfigDirectory = NULL;
   const char *EpgDataFileName = DEFAULTEPGDATAFILENAME;
+  const char *ResourceDirectory = NULL;
   bool DisplayHelp = false;
   bool DisplayVersion = false;
   bool DaemonMode = false;
@@ -215,6 +219,7 @@ 
 
   static struct option long_options[] = {
       { "audio",    required_argument, NULL, 'a' },
+      { "cachedir", required_argument, NULL, 'c' | 0x100 },
       { "config",   required_argument, NULL, 'c' },
       { "daemon",   no_argument,       NULL, 'd' },
       { "device",   required_argument, NULL, 'D' },
@@ -234,6 +239,7 @@ 
       { "plugin",   required_argument, NULL, 'P' },
       { "port",     required_argument, NULL, 'p' },
       { "record",   required_argument, NULL, 'r' },
+      { "resdir",   required_argument, NULL, 'r' | 0x200 },
       { "shutdown", required_argument, NULL, 's' },
       { "split",    no_argument,       NULL, 's' | 0x100 },
       { "terminal", required_argument, NULL, 't' },
@@ -251,6 +257,9 @@ 
         switch (c) {
           case 'a': AudioCommand = optarg;
                     break;
+          case 'c' | 0x100:
+                    CacheDirectory = optarg;
+                    break;
           case 'c': ConfigDirectory = optarg;
                     break;
           case 'd': DaemonMode = true; break;
@@ -348,6 +357,9 @@ 
                     break;
           case 'r': cRecordingUserCommand::SetCommand(optarg);
                     break;
+          case 'r' | 0x200:
+                    ResourceDirectory = optarg;
+                    break;
           case 's': ShutdownHandler.SetShutdownCommand(optarg);
                     break;
           case 's' | 0x100:
@@ -413,6 +425,7 @@ 
      if (DisplayHelp) {
         printf("Usage: vdr [OPTIONS]\n\n"          // for easier orientation, this is column 80|
                "  -a CMD,   --audio=CMD    send Dolby Digital audio to stdin of command CMD\n"
+               "            --cachedir=DIR save cache files in DIR (default: %s)\n"
                "  -c DIR,   --config=DIR   read config files from DIR (default: %s)\n"
                "  -d,       --daemon       run in daemon mode\n"
                "  -D NUM,   --device=NUM   use only the given DVB device (NUM = 0, 1, 2...)\n"
@@ -449,6 +462,7 @@ 
                "                           0 turns off SVDRP\n"
                "  -P OPT,   --plugin=OPT   load a plugin defined by the given options\n"
                "  -r CMD,   --record=CMD   call CMD before and after a recording\n"
+               "            --resdir=DIR   read resource files from DIR (default: %s)\n"
                "  -s CMD,   --shutdown=CMD call CMD to shutdown the computer\n"
                "            --split        split edited files at the editing marks (only\n"
                "                           useful in conjunction with --edit)\n"
@@ -463,6 +477,7 @@ 
                "  -w SEC,   --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
                "                           seconds (default: %d); '0' disables the watchdog\n"
                "\n",
+               strcmp(DEFAULTCACHEDIR, "") ? DEFAULTCACHEDIR : VideoDirectory,
                DEFAULTCONFDIR,
                DEFAULTEPGDATAFILENAME,
                MAXVIDEOFILESIZEDEFAULT,
@@ -470,6 +485,7 @@ 
                LIRC_DEVICE,
                LOCDIR,
                DEFAULTSVDRPPORT,
+               strcmp(DEFAULTRESDIR, "") ? DEFAULTRESDIR : DEFAULTCONFDIR,
                VideoDirectory,
                DEFAULTWATCHDOG
                );
@@ -577,14 +593,39 @@ 
   if (!PluginManager.LoadPlugins(true))
      EXIT(2);
 
-  // Configuration data:
+  // Configuration directory:
 
   if (!ConfigDirectory)
      ConfigDirectory = DEFAULTCONFDIR;
 
   cPlugin::SetConfigDirectory(ConfigDirectory);
+
+  // Cache directory:
+
+  if (!CacheDirectory) {
+     CacheDirectory = DEFAULTCACHEDIR;
+     if (!CacheDirectory[0])
+        CacheDirectory = VideoDirectory;
+     }
+
+  cPlugin::SetCacheDirectory(CacheDirectory);
+
+  // Resource directory:
+
+  if (!ResourceDirectory) {
+     ResourceDirectory = DEFAULTRESDIR;
+     if (!ResourceDirectory[0])
+        ResourceDirectory = ConfigDirectory;
+     }
+
+  cPlugin::SetResourceDirectory(ResourceDirectory);
+
+  // Themes directory:
+
   cThemes::SetThemesDirectory(AddDirectory(ConfigDirectory, "themes"));
 
+  // Configuration data:
+
   Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
   Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true);
   Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC);
@@ -618,7 +653,7 @@ 
         EpgDataFileName = DEFAULTEPGDATAFILENAME;
         }
      else if (*EpgDataFileName != '/' && *EpgDataFileName != '.')
-        EpgDirectory = VideoDirectory;
+        EpgDirectory = CacheDirectory;
      if (EpgDirectory)
         cSchedules::SetEpgDataFileName(AddDirectory(EpgDirectory, EpgDataFileName));
      else