--- ./diseqc.c	2009/12/05 15:57:02	2.1
+++ ./diseqc.c	2010/02/06 15:43:31
@@ -16,6 +16,11 @@
 
 cDiseqc::cDiseqc(void)
 {
+  devices = 0;
+  source = 0;
+  slof = 0;
+  polarization = 0;
+  lof = 0;
   commands = NULL;
   parsing = false;
   numCodes = 0;
@@ -30,6 +35,21 @@
 {
   bool result = false;
   char *sourcebuf = NULL;
+  if (*s && s[strlen(s) - 1] == ':') {
+     const char *p = s;
+     while (*p && *p != ':') {
+           char *t = NULL;
+           int d = strtol(p, &t, 10);
+           p = t;
+           if (0 < d && d < 32)
+              devices |= (1 << d - 1);
+           else {
+              esyslog("ERROR: invalid device number %d in '%s'", d, s);
+              return false;
+              }
+           }
+     return true;
+     }
   int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
   if (fields == 4)
      commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string
@@ -126,9 +146,16 @@
 
 cDiseqcs Diseqcs;
 
-cDiseqc *cDiseqcs::Get(int Source, int Frequency, char Polarization)
+cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization)
 {
+  int Devices = 0;
   for (cDiseqc *p = First(); p; p = Next(p)) {
+      if (p->Devices()) {
+         Devices = p->Devices();
+         continue;
+         }
+      if (Devices && !(Devices & (1 << Device - 1)))
+         continue;
       if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization))
         return p;
       }
--- ./diseqc.conf	2006/03/31 14:05:52	2.0
+++ ./diseqc.conf	2010/02/06 15:54:04
@@ -23,6 +23,10 @@
 #
 # The 'command...' part is optional.
 #
+# A line containing space separated integer numbers, terminated with a ':',
+# defines that any following DiSEqC sequences apply only to the given list
+# of device numbers.
+#
 # Examples:
 
 # Full DiSEqC sequence:
--- ./diseqc.h	2002/12/07 13:54:02	2.0
+++ ./diseqc.h	2010/02/06 15:14:42
@@ -26,6 +26,7 @@
     };
   enum { MaxDiseqcCodes = 6 };
 private:
+  int devices;
   int source;
   int slof;
   char polarization;
@@ -48,6 +49,7 @@
       // it. Call Execute() repeatedly (always providing the same CurrentAction pointer)
       // until it returns daNone. After a successful execution of all commands
       // *CurrentAction points to the value 0x00.
+  int Devices(void) const { return devices; }
   int Source(void) const { return source; }
   int Slof(void) const { return slof; }
   char Polarization(void) const { return polarization; }
@@ -58,7 +60,7 @@
 
 class cDiseqcs : public cConfig<cDiseqc> {
 public:
-  cDiseqc *Get(int Source, int Frequency, char Polarization);
+  cDiseqc *Get(int Device, int Source, int Frequency, char Polarization);
   };
 
 extern cDiseqcs Diseqcs;
--- ./dvbdevice.c	2010/02/06 14:38:44	2.26
+++ ./dvbdevice.c	2010/02/06 15:34:14
@@ -30,6 +30,7 @@
 class cDvbTuner : public cThread {
 private:
   enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
+  int device;
   int fd_frontend;
   int adapter, frontend;
   int tuneTimeout;
@@ -46,7 +47,7 @@
   bool SetFrontend(void);
   virtual void Action(void);
 public:
-  cDvbTuner(int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType);
+  cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType);
   virtual ~cDvbTuner();
   const cChannel *GetTransponder(void) const { return &channel; }
   bool IsTunedTo(const cChannel *Channel) const;
@@ -54,8 +55,9 @@
   bool Locked(int TimeoutMs = 0);
   };
 
-cDvbTuner::cDvbTuner(int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType)
+cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType)
 {
+  device = Device;
   fd_frontend = Fd_Frontend;
   adapter = Adapter;
   frontend = Frontend;
@@ -175,7 +177,7 @@
   if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) {
      unsigned int frequency = channel.Frequency();
      if (Setup.DiSEqC) {
-        cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+        cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), channel.Polarization());
         if (diseqc) {
            if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
               cDiseqc::eDiseqcActions da;
@@ -420,7 +422,7 @@
         if (frontendType == SYS_DVBS2)
            numProvidedSystems++;
         isyslog("frontend %d/%d provides %s (\"%s\")", adapter, frontend, DeliverySystems[frontendType], frontendInfo.name);
-        dvbTuner = new cDvbTuner(fd_frontend, adapter, frontend, frontendType);
+        dvbTuner = new cDvbTuner(DeviceNumber(), fd_frontend, adapter, frontend, frontendType);
         }
      }
   else
@@ -612,7 +614,7 @@
      return DeviceHooksProvidesTransponder(Channel); // source is sufficient for non sat
   if (frontendType == SYS_DVBS && Channel->System() == SYS_DVBS2)
      return false; // requires modulation system which frontend doesn't provide
-  if (!Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()))
+  if (!Setup.DiSEqC || Diseqcs.Get(DeviceNumber(), Channel->Source(), Channel->Frequency(), Channel->Polarization()))
      return DeviceHooksProvidesTransponder(Channel);
   return false;
 }
--- ./vdr.5	2010/01/31 12:59:50	2.13
+++ ./vdr.5	2010/02/06 15:52:38
@@ -452,6 +452,15 @@
 There can be any number of actions in a line, including none at all - in which case
 the entry would be used only to set the LOF to use for the given frequency range
 and polarization.
+
+By default it is assumed that every DVB-S device can receive every satellite.
+If this is not the case in a particular setup, lines of the form
+
+\fB1 2 4:\fR
+
+may be inserted in the \fIdiseqc.conf\fR file, defining the devices that are able
+to receive the satellites following thereafter. In this case, only the devices
+1, 2 and 4 would be able to receive any satellites following this line.
 .SS REMOTE CONTROL KEYS
 The file \fIremote.conf\fR contains the key assignments for all remote control
 units. Each line consists of one key assignment in the following format:
