diff -ruN vdr-1.3.42/CONTRIBUTORS vdr-1.3.43/CONTRIBUTORS
--- vdr-1.3.42/CONTRIBUTORS	2006-02-05 16:09:51.000000000 +0100
+++ vdr-1.3.43/CONTRIBUTORS	2006-02-19 15:23:17.000000000 +0100
@@ -548,10 +548,12 @@
  for suggesting to increase the default value for 'Min. user inactivity' to 300 minutes
  for suggesting to add cChannel::LinkChannels() and cChannel::RefChannel()
  for suggesting to give a message when an instant recording is started
- fpr suggesting to retry a shutdown after a while
+ for suggesting to retry a shutdown after a while
  for separating the 'install' target into several individual targets
  for reporting a problem with scrolling with Up/Down in case there are non-selectable
  items at the beginning of the menu
+ for a patch that was used to implement stopping scanning the video directory if
+ there are too many levels of symbolic links
 
 Jeremy Hall <jhall@UU.NET>
  for fixing an incomplete initialization of the filter parameters in eit.c
@@ -604,6 +606,8 @@
  for making cEIT::cEIT() drop EPG events that have a zero start time or duration
  for reporting an unnecessary OSD draw operation caused by the audio track description
  display in the ST:TNG skin's channel display
+ for suggesting to make CharArray::DataOwnData::assign() in 'libsi' more robust
+ against invalid data
 
 Reinhard Walter Buchner <rw.buchner@freenet.de>
  for adding some satellites to 'sources.conf'
@@ -953,6 +957,10 @@
  via the numeric keys
  for reporting a problem with expired timers when shutting down via the Power key
  for fixing handling the "Blue" key in the "Schedule" menu for the current channel
+ for making cMenuText use the given font
+ for making the channel number be reset if the number entered through the numeric keys
+ exceeds the maximum channel number
+ for suggesting to also set the language codes when setting the audio track descriptions
 
 Ralf Klueber <ralf.klueber@vodafone.com>
  for reporting a bug in cutting a recording if there is only a single editing mark
@@ -1050,6 +1058,7 @@
  for fixing handling TS packets in cTS2PES
  for adding a mutex to synchronize cDevice::PlayPesPacket() and SetCurrentAudioTrack()
  for a suggestion that lead to implementing cDevice::Transferring()
+ for fixing replaying recordings of radio channels with many audio tracks
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1306,6 +1315,9 @@
  for removing leftover 'needsBufferReserve' variable from cTransfer
  for adding an 'Id' parameter to cDevice::PlayAudio() to allow plugins to easier
  process the audio data
+ for improving OSD area handling in cDvbSpuDecoder
+ for suggesting to log the description (if present) in case a thread is canceled
+ for fixing handling DPID when deciding whether to switch to 'Transfer Mode'
 
 Jürgen Schmitz <j.schmitz@web.de>
  for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -1412,6 +1424,8 @@
  are being edited via the menu
  for suggesting to change the API of the functions cStatus::Recording() and
  cStatus::Replaying(), so that they can provide the full file name of the recording
+ for suggesting that externally provided EPG data (with table ID 0x00) shall get its
+ component descriptors set from the broadcast data
 
 Dino Ravnic <dino.ravnic@fer.hr>
  for fixing some characters in the iso8859-2 font file
@@ -1568,6 +1582,7 @@
  for adding missing storing of the MenuScrollPage parameter
  for reporting a problem with channel switching with the Down (Up) key in case the
  current channel is already the first (last) in the list
+ for fixing some typos in the CONTRIBUTORS file
 
 Bernhard Stegmaier <bernhard.stegmaier@in.tum.de>
  for reporting a problem in cEITScanner::Process() with forced EPG scans if EPG
@@ -1718,12 +1733,14 @@
 
 Markus Hahn <mhahn@reel-multimedia.com>
  for suggesting to only start recordings if there is at least 300MB free disk space
+ for suggesting that the "Back" key should restore the original string when pressed
+ while editing a string item
 
 Jaroslaw Swierczynski <swiergot@gmail.com>
  for updating the Polish OSD texts and the fontosd-iso8859-2.c file
 
 Alexander Hans <cleditor@arcor.de>
- fpr reporting a crash when pressing '0' in the "Schedule" menu on a channel that
+ for reporting a crash when pressing '0' in the "Schedule" menu on a channel that
  doesn't have any EPG data 
 
 Daniel Karsubka <dkar@gmx.de>
diff -ruN vdr-1.3.42/HISTORY vdr-1.3.43/HISTORY
--- vdr-1.3.42/HISTORY	2006-02-05 16:09:21.000000000 +0100
+++ vdr-1.3.43/HISTORY	2006-02-19 15:41:15.000000000 +0100
@@ -4316,3 +4316,46 @@
   beginning or end of the menu (reported by Helmut Auer).
 - Added cSkin::GetTextAreaWidth() and cSkin::GetTextAreaFont(), so that a plugin
   that wants to do special text formatting can do so (thanks to Alexander Rieger).
+
+2006-02-19: Version 1.3.43
+
+- Removed an unnecessary toFile->SetReadAhead() from cutter.c (thanks to Artur
+  Skawina).
+- The "Back" key now restores the original string when pressed while editing a
+  string item (suggested by Markus Hahn).
+- Now stopping scanning the video directory if there are too many levels of
+  symbolic links, which might indicate a recursive link loop (based on a patch
+  from Helmut Auer).
+- Improved OSD area handling in cDvbSpuDecoder (thanks to Marco Schlüßler).
+- Now logging the description (if present) in case a thread is canceled (suggested
+  by Marco Schlüßler).
+- cMenuText now uses the given font (thanks to Rolf Ahrenberg).
+- The ST:TNG skin now uses the fixed font if requested when displaying texts.
+- Fixed some typos in the CONTRIBUTORS file (thanks to Frank Krömmelbein).
+- Changed offset and size handling in 'libsi' from 'unsigned' to 'signed', so that
+  overflows can be better detected (thanks to Marcel Wiesweg).
+- Checking data size in CaDescriptor::Parse() and LinkageDescriptor::Parse() of
+  'libsi' to avoid crashes with invalid data (thanks to Marcel Wiesweg).
+- Made CharArray::DataOwnData::assign() in 'libsi' more robust against invalid
+  data (suggested by Oliver Endriss). Also changed CharArray::DataOwnData::Delete()
+  so that it sets 'size' and 'data' to 0.
+- Now resetting the channel number if the number entered through the numeric keys
+  exceeds the maximum channel number (thanks to Rolf Ahrenberg).
+- The language code in the 'X' component records of EPG data can now consist of
+  two codes, separated by '+'.
+- If a recording starts and there is no EPG data available for the recorded channel,
+  the 'X' audio component records for the 'info.vdr' file are now generated from the
+  channel's PID data.
+- Externally provided EPG data (with table ID 0x00) now gets its component
+  descriptors set from the broadcast data, so that language codes and descriptions
+  are available (suggested by Andreas Brugger).
+- When setting the audio track descriptions, the language codes are now also set
+  in case this is a replay session (based on a patch from Rolf Ahrenberg).
+- If a recording starts and the channel's audio PID data has more language code
+  information than the EPG's component data, the code from the channel is taken.
+- Fixed handling DPID when deciding whether to switch to 'Transfer Mode' (thanks
+  to Marco Schlüßler).
+- Fixed replaying recordings of radio channels with many audio tracks (thanks to
+  Reinhard Nissl).
+- Added a comment to tChannelID::nid, explaining that is is actually the "original"
+  network id.
diff -ruN vdr-1.3.42/channels.conf vdr-1.3.43/channels.conf
--- vdr-1.3.42/channels.conf	2006-02-05 16:12:54.000000000 +0100
+++ vdr-1.3.43/channels.conf	2006-02-19 16:00:54.000000000 +0100
@@ -1,5 +1,3 @@
-: first line
-: second line
 RTL Television,RTL;RTL World:12187:hC34:S19.2E:27500:163:104=deu:105:0:12003:1:1089:0
 SAT.1;ProSiebenSat.1:12480:vC34:S19.2E:27500:1791:1792=deu;1795=deu:34:0:46:133:33:0
 ProSieben;ProSiebenSat.1:12480:vC34:S19.2E:27500:255:256=deu;257=deu:32:0:898:133:33:0
@@ -15,10 +13,10 @@
 Phoenix;ARD:11836:hC34:S19.2E:27500:901:902=deu:904:0:28114:1:1101:0
 ZDF;ZDFvision:11953:hC34:S19.2E:27500:110:120=deu,121=2ch;125=dd:130:0:28006:1:1079:0
 3sat;ZDFvision:11953:hC34:S19.2E:27500:210:220=deu,221=2ch;225=dd:230:0:28007:1:1079:0
-KiKa;ZDFvision:11953:hC34:S19.2E:27500:310:320:0:0:28008:1:1079:0
+KiKa;ZDFvision:11953:hC34:S19.2E:27500:310:320=deu:330:0:28008:1:1079:0
 arte;ARD:11836:hC34:S19.2E:27500:401:402=deu,403=fra:404:0:28109:1:1101:0
-ORF1;ORF:12692:hC56:S19.2E:22000:160:161=deu;163=deu:165:0:13001:1:1117:0
-ORF2;ORF:12692:hC56:S19.2E:22000:500:501=deu,502=deu;503=deu:505:1762,D05,1702,1801:13002:1:1117:0
+ORF1;ORF:12692:hC56:S19.2E:22000:160:161=deu;163=deu:165:1762,D05,1801,1702:13001:1:1117:0
+ORF2;ORF:12692:hC56:S19.2E:22000:500:501=deu;503=deu:505:1762,D05,1801,1702:13002:1:1117:0
 ZDFinfokanal;ZDFvision:11953:hC34:S19.2E:27500:610:620=deu:130:0:28011:1:1079:0
 CNN Int.;CNN:11778:vC34:S19.2E:27500:165:100=eng:47:0:28522:1:1068:0
 Super RTL,S RTL;RTL World:12187:hC34:S19.2E:27500:165:120=deu:65:0:12040:1:1089:0
@@ -30,8 +28,8 @@
 HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0
 Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
 EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
-rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0
-Sky News:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
+rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0
+Sky News;BT:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
 Veronica/JETIX;CANALDIGITAAL:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,100:5020:53:1109:0
 BVN;CANALDIGITAAL:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
 n-tv;RTL World:12187:hC34:S19.2E:27500:169:73=deu:80:0:12090:1:1089:0
@@ -39,7 +37,7 @@
 TW1;ORF:12662:hC56:S19.2E:22000:1010:1011=deu:1013:0:13101:1:1115:0
 Eurosport;SES Astra:12226:hC34:S19.2E:27500:101+8190:103=deu:102:0:31200:1:1091:0
 EinsExtra;ARD:12109:hC34:S19.2E:27500:101:102=deu:0:0:28201:1:1073:0
-EinsFestival;ARD:12109:hC34:S19.2E:27500:201:202=deu:0:0:28202:1:1073:0
+EinsFestival;ARD:12109:hC34:S19.2E:27500:201:202=deu:204:0:28202:1:1073:0
 EinsPlus;ARD:12109:hC34:S19.2E:27500:301:302=deu:0:0:28203:1:1073:0
 ZDFtheaterkanal;ZDFvision:11953:hC34:S19.2E:27500:1110:1120=deu:130:0:28016:1:1079:0
 ZDFdokukanal;ZDFvision:11953:hC34:S19.2E:27500:660:670=deu:130:0:28014:1:1079:0
@@ -51,8 +49,8 @@
 PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1801,1722,1702:11:133:2:0
 PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1702,1801:43:133:2:0
 PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0
-PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1722,1702,1801:29:133:2:0
-PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0
+PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1702,1801:29:133:2:0
+PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1801,1722,1702:41:133:2:0
 PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:20:133:2:0
 DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1801,1722,1702:34:133:17:0
 :Premiere Direkt
@@ -67,7 +65,7 @@
 N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0
 LibertyTV FR;LibertyTV.com:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0
 :-
-münchen.TV/RFO,müTV/RFO;BetaDigital:12148:hC34:S19.2E:27500:495:496=deu:0:0:658:133:7:0
+münchen.TV/RFO,müTV/RFO;BetaDigital:12148:hC34:S19.2E:27500:495:496:0:0:658:133:7:0
 ProSieben Austria;ProSiebenSat.1:12051:vC34:S19.2E:27500:161:84=deu;85=deu:36:0:20002:1:1082:0
 Kabel 1 Schweiz;ProSiebenSat.1:12051:vC34:S19.2E:27500:162:163=deu:165:0:20003:1:1082:0
 Kabel 1 Austria;ProSiebenSat.1:12051:vC34:S19.2E:27500:166:167=deu:169:0:20004:1:1082:0
@@ -99,7 +97,7 @@
 Euro1080 HD-5;Euro1080:10758:vC78:S23.5E:22000:34:160=eng:0:0:1085:9999:3104:0
 Euro1080;EURO1080:12168:vC56:S19.2E:27500:308:256:0:0:21100:1:1088:0
 SMD HD;SES ASTRA:12699:vC56:S19.2E:22000:133+80:234=eng:0:0:29700:0:0:0
-SMD HD:12699:V:S19.2E:22000:133:234=eng:0:0:3231:1:1118:0
+SMD HD:12699:vC56:S19.2E:22000:133:234=eng:0:0:3231:1:1118:0
 Astra HD:12441:vC34:S19.2E:27500:133+80:134=eng:0:0:29700:0:0:0
 TV HD;CSAT:12581:vC56:S19.2E:22000:165:100=fra;101=fra:0:0:9306:1:1110:0
 C M HD;Telenor:11261:hC78:S1.0W:24500:517:660=eng;661=eng:0:B00:3306:70:33:0
@@ -118,9 +116,9 @@
 Sky Movies 1;BSkyB:11836:hC23:S28.2E:27500:518+8190:646=eng,653=NAR;666=eng:582:960,961:4303:2:2007:0
 Sky Movies 2;BSkyB:11836:hC23:S28.2E:27500:519+8190:647=eng,655=NAR;667=eng:583:960,961:4302:2:2007:0
 Sky Movies 3;BSkyB:11836:hC23:S28.2E:27500:520+8190:648=eng,654=NAR;668=eng:584:960,961:4403:2:2007:0
-Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:512+8190:640=eng,660=NAR:576:960,961:4402:2:2011:0
-Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:515+8190:643=eng,663=NAR:579:960,961:4503:2:2011:0
-Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:513+8190:641=eng,661=NAR:577:960,961:4502:2:2011:0
+Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:512+8190:640=eng,655=NAR:576:960,961:4402:2:2011:0
+Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:515+8190:643=eng,656=NAR:579:960,961:4503:2:2011:0
+Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:513+8190:641=eng,657=NAR:577:960,961:4502:2:2011:0
 Sky Movies 7;BSkyB:12285:vC23:S28.2E:27500:515+8190:643=eng,663=NAR:579:960,961:4603:2:2030:0
 Sky Movies 8;BSkyB:11836:hC23:S28.2E:27500:515+8190:643=eng,656=NAR:579:960,961:5502:2:2007:0
 Sky Movies 9;BSkyB:12285:vC23:S28.2E:27500:518+8190:646=eng,666=NAR:582:960,961:4602:2:2030:0
diff -ruN vdr-1.3.42/channels.h vdr-1.3.43/channels.h
--- vdr-1.3.42/channels.h	2006-01-14 16:51:26.000000000 +0100
+++ vdr-1.3.43/channels.h	2006-02-19 15:39:43.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.h 1.38 2006/01/14 15:51:26 kls Exp $
+ * $Id: channels.h 1.39 2006/02/19 14:39:43 kls Exp $
  */
 
 #ifndef __CHANNELS_H
@@ -69,7 +69,7 @@
 struct tChannelID {
 private:
   int source;
-  int nid;
+  int nid; ///< actually the "original" network id
   int tid;
   int sid;
   int rid;
diff -ruN vdr-1.3.42/config.h vdr-1.3.43/config.h
--- vdr-1.3.42/config.h	2006-01-29 18:24:53.000000000 +0100
+++ vdr-1.3.43/config.h	2006-02-12 11:07:44.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 1.243 2006/01/29 17:24:53 kls Exp $
+ * $Id: config.h 1.244 2006/02/12 10:07:44 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -19,8 +19,8 @@
 #include "i18n.h"
 #include "tools.h"
 
-#define VDRVERSION  "1.3.42"
-#define VDRVERSNUM   10342  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.3.43"
+#define VDRVERSNUM   10343  // Version * 10000 + Major * 100 + Minor
 
 #define MAXPRIORITY 99
 #define MAXLIFETIME 99
diff -ruN vdr-1.3.42/cutter.c vdr-1.3.43/cutter.c
--- vdr-1.3.42/cutter.c	2006-02-05 12:06:47.000000000 +0100
+++ vdr-1.3.43/cutter.c	2006-02-12 11:07:23.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: cutter.c 1.14 2006/02/05 11:06:47 kls Exp $
+ * $Id: cutter.c 1.15 2006/02/12 10:07:23 kls Exp $
  */
 
 #include "cutter.h"
@@ -67,7 +67,6 @@
      if (!fromFile || !toFile)
         return;
      fromFile->SetReadAhead(MEGABYTE(20));
-     toFile->SetReadAhead(MEGABYTE(20));
      int Index = Mark->position;
      Mark = fromMarks.Next(Mark);
      int FileSize = 0;
diff -ruN vdr-1.3.42/dvbdevice.c vdr-1.3.43/dvbdevice.c
--- vdr-1.3.42/dvbdevice.c	2006-02-04 11:21:51.000000000 +0100
+++ vdr-1.3.43/dvbdevice.c	2006-02-19 14:52:04.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 1.152 2006/02/04 10:21:51 kls Exp $
+ * $Id: dvbdevice.c 1.153 2006/02/19 13:52:04 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -811,7 +811,7 @@
                             );
 
   bool StartTransferMode = IsPrimaryDevice() && !DoTune
-                           && (LiveView && HasPid(Channel->Vpid() ? Channel->Vpid() : Channel->Apid(0)) && (pidHandles[ptVideo].pid != Channel->Vpid() || pidHandles[ptAudio].pid != Channel->Apid(0))// the PID is already set as DMX_PES_OTHER
+                           && (LiveView && HasPid(Channel->Vpid() ? Channel->Vpid() : Channel->Apid(0)) && (pidHandles[ptVideo].pid != Channel->Vpid() || (pidHandles[ptAudio].pid != Channel->Apid(0) && (Channel->Dpid(0) ? pidHandles[ptAudio].pid != Channel->Dpid(0) : true)))// the PID is already set as DMX_PES_OTHER
                               || !LiveView && (pidHandles[ptVideo].pid == Channel->Vpid() || pidHandles[ptAudio].pid == Channel->Apid(0)) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
                               );
 
diff -ruN vdr-1.3.42/dvbplayer.c vdr-1.3.43/dvbplayer.c
--- vdr-1.3.42/dvbplayer.c	2006-01-08 12:39:41.000000000 +0100
+++ vdr-1.3.43/dvbplayer.c	2006-02-19 15:20:15.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.c 1.42 2006/01/08 11:39:41 kls Exp $
+ * $Id: dvbplayer.c 1.43 2006/02/19 14:20:15 kls Exp $
  */
 
 #include "dvbplayer.h"
@@ -80,6 +80,8 @@
   int length;
   bool hasData;
   cCondWait newSet;
+  cCondVar newDataCond;
+  cMutex newDataMutex;
 protected:
   void Action(void);
 public:
@@ -88,6 +90,7 @@
   void Clear(void);
   int Read(cUnbufferedFile *File, uchar *Buffer, int Length);
   bool Reading(void) { return buffer; }
+  bool WaitForDataMs(int msToWait);
   };
 
 cNonBlockingFileReader::cNonBlockingFileReader(void)
@@ -150,8 +153,11 @@
            int r = f->Read(buffer + length, wanted - length);
            if (r >= 0) {
               length += r;
-              if (!r || length == wanted) // r == 0 means EOF
+              if (!r || length == wanted) { // r == 0 means EOF
+                 cMutexLock NewDataLock(&newDataMutex);
                  hasData = true;
+                 newDataCond.Broadcast();
+                 }
               }
            else if (r < 0 && FATALERRNO) {
               LOG_ERROR;
@@ -164,6 +170,14 @@
         }
 }
 
+bool cNonBlockingFileReader::WaitForDataMs(int msToWait)
+{
+  cMutexLock NewDataLock(&newDataMutex);
+  if (hasData)
+     return true;
+  return newDataCond.TimedWait(newDataMutex, msToWait);
+}
+
 // --- cDvbPlayer ------------------------------------------------------------
 
 #define PLAYERBUFSIZE  MEGABYTE(1)
@@ -362,10 +376,14 @@
   nonBlockingFileReader = new cNonBlockingFileReader;
   int Length = 0;
   bool Sleep = false;
+  bool WaitingForData = false;
 
   while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
         if (Sleep) {
-           cCondWait::SleepMs(3); // this keeps the CPU load low
+           if (WaitingForData)
+              nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
+           else
+              cCondWait::SleepMs(3); // this keeps the CPU load low
            Sleep = false;
            }
         cPoller Poller;
@@ -423,11 +441,14 @@
                     }
                  int r = nonBlockingFileReader->Read(replayFile, b, Length);
                  if (r > 0) {
+                    WaitingForData = false;
                     readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
                     b = NULL;
                     }
                  else if (r == 0)
                     eof = true;
+                 else if (r < 0 && errno == EAGAIN)
+                    WaitingForData = true;
                  else if (r < 0 && FATALERRNO) {
                     LOG_ERROR;
                     break;
diff -ruN vdr-1.3.42/dvbspu.c vdr-1.3.43/dvbspu.c
--- vdr-1.3.42/dvbspu.c	2006-01-08 12:39:46.000000000 +0100
+++ vdr-1.3.43/dvbspu.c	2006-02-12 12:50:20.000000000 +0100
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.c 1.19 2006/01/08 11:39:46 kls Exp $
+ * $Id: dvbspu.c 1.20 2006/02/12 11:50:20 kls Exp $
  */
 
 #include "dvbspu.h"
@@ -368,11 +368,11 @@
     if (bg || fg) {
         if (osd == NULL) {
            osd = cOsdProvider::NewOsd(0, 0);
-           int x2 = areaSize.x2;
-           while ((x2 - areaSize.x1 + 1) & 0x03)
-                 x2++;
-           tArea Area = { areaSize.x1, areaSize.y1, x2, areaSize.y2, (fg && bg) ? 4 : 2 };
-           osd->SetAreas(&Area, 1);
+           if ((areaSize.width() & 3) != 0)
+              areaSize.x2 += 4 - (areaSize.width() & 3);
+           tArea Area = { areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2 };
+           if (osd->SetAreas(&Area, 1) != oeOk)
+              dsyslog("dvbspu: AreaSize (%d, %d) (%d, %d) Bpp %d", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2 );
            }
 
         if (bg)
diff -ruN vdr-1.3.42/eit.c vdr-1.3.43/eit.c
--- vdr-1.3.42/eit.c	2006-01-14 16:41:21.000000000 +0100
+++ vdr-1.3.43/eit.c	2006-02-19 10:51:02.000000000 +0100
@@ -8,7 +8,7 @@
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
  *
- * $Id: eit.c 1.114 2006/01/14 15:41:21 kls Exp $
+ * $Id: eit.c 1.115 2006/02/19 09:51:02 kls Exp $
  */
 
 #include "eit.h"
@@ -39,11 +39,13 @@
 
   bool Empty = true;
   bool Modified = false;
+  bool HasExternalData = false;
   time_t SegmentStart = 0;
   time_t SegmentEnd = 0;
 
   SI::EIT::Event SiEitEvent;
   for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) {
+      bool ExternalData = false;
       // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
       if (SiEitEvent.getStartTime() == 0 || SiEitEvent.getStartTime() > 0 && SiEitEvent.getDuration() == 0)
          continue;
@@ -66,11 +68,14 @@
          pEvent->SetSeen();
          // If the existing event has a zero table ID it was defined externally and shall
          // not be overwritten.
-         if (pEvent->TableID() == 0x00)
-            continue;
+         if (pEvent->TableID() == 0x00) {
+            if (pEvent->Version() == getVersionNumber())
+               continue;
+            HasExternalData = ExternalData = true;
+            }
          // If the new event has a higher table ID, let's skip it.
          // The lower the table ID, the more "current" the information.
-         if (Tid > pEvent->TableID())
+         else if (Tid > pEvent->TableID())
             continue;
          // If the new event comes from the same table and has the same version number
          // as the existing one, let's skip it to avoid unnecessary work.
@@ -78,15 +83,16 @@
          // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
          // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
          // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
-         if (Tid == pEvent->TableID() && pEvent->Version() == getVersionNumber())
+         else if (Tid == pEvent->TableID() && pEvent->Version() == getVersionNumber())
             continue;
          }
-      // XXX TODO log different (non-zero) event IDs for the same event???
-      pEvent->SetEventID(SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
-      pEvent->SetTableID(Tid);
+      if (!ExternalData) {
+         pEvent->SetEventID(SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
+         pEvent->SetTableID(Tid);
+         pEvent->SetStartTime(SiEitEvent.getStartTime());
+         pEvent->SetDuration(SiEitEvent.getDuration());
+         }
       pEvent->SetVersion(getVersionNumber());
-      pEvent->SetStartTime(SiEitEvent.getStartTime());
-      pEvent->SetDuration(SiEitEvent.getDuration());
 
       int LanguagePreferenceShort = -1;
       int LanguagePreferenceExt = -1;
@@ -97,6 +103,8 @@
       cLinkChannels *LinkChannels = NULL;
       cComponents *Components = NULL;
       for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
+          if (ExternalData && d->getDescriptorTag() != SI::ComponentDescriptorTag)
+             continue;
           switch (d->getDescriptorTag()) {
             case SI::ExtendedEventDescriptorTag: {
                  SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d;
@@ -243,7 +251,8 @@
      pSchedule->SetPresentSeen();
   if (Modified) {
      pSchedule->Sort();
-     pSchedule->DropOutdated(SegmentStart, SegmentEnd, Tid, getVersionNumber());
+     if (!HasExternalData)
+        pSchedule->DropOutdated(SegmentStart, SegmentEnd, Tid, getVersionNumber());
      Schedules->SetModified(pSchedule);
      }
 }
diff -ruN vdr-1.3.42/epg.c vdr-1.3.43/epg.c
--- vdr-1.3.42/epg.c	2006-02-03 14:16:54.000000000 +0100
+++ vdr-1.3.43/epg.c	2006-02-19 13:50:26.000000000 +0100
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.c 1.58 2006/02/03 13:16:54 kls Exp $
+ * $Id: epg.c 1.61 2006/02/19 12:50:26 kls Exp $
  */
 
 #include "epg.h"
@@ -23,14 +23,14 @@
 cString tComponent::ToString(void)
 {
   char buffer[256];
-  snprintf(buffer, sizeof(buffer), "%X %02X %-3s %s", stream, type, language, description ? description : "");
+  snprintf(buffer, sizeof(buffer), "%X %02X %s %s", stream, type, language, description ? description : "");
   return buffer;
 }
 
 bool tComponent::FromString(const char *s)
 {
   unsigned int Stream, Type;
-  int n = sscanf(s, "%X %02X %3c %a[^\n]", &Stream, &Type, language, &description);
+  int n = sscanf(s, "%X %02X %7s %a[^\n]", &Stream, &Type, language, &description); // 7 = MAXLANGCODE2 - 1
   if (n != 4 || isempty(description)) {
      free(description);
      description = NULL;
@@ -78,9 +78,23 @@
   p->stream = Stream;
   p->type = Type;
   strn0cpy(p->language, Language, sizeof(p->language));
+  char *q = strchr(p->language, ',');
+  if (q)
+     *q = 0; // strips rest of "normalized" language codes
   p->description = strcpyrealloc(p->description, !isempty(Description) ? Description : NULL);
 }
 
+tComponent *cComponents::GetComponent(int Index, uchar Stream, uchar Type)
+{
+  for (int i = 0; i < numComponents; i++) {
+      if (components[i].stream == Stream && components[i].type == Type) {
+         if (!Index--)
+            return &components[i];
+         }
+      }
+  return NULL;
+}
+
 // --- cEvent ----------------------------------------------------------------
 
 cEvent::cEvent(u_int16_t EventID)
diff -ruN vdr-1.3.42/epg.h vdr-1.3.43/epg.h
--- vdr-1.3.42/epg.h	2006-01-29 15:03:13.000000000 +0100
+++ vdr-1.3.43/epg.h	2006-02-19 13:51:41.000000000 +0100
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.h 1.30 2006/01/29 14:03:13 kls Exp $
+ * $Id: epg.h 1.32 2006/02/19 12:51:41 kls Exp $
  */
 
 #ifndef __EPG_H
@@ -24,7 +24,7 @@
 struct tComponent {
   uchar stream;
   uchar type;
-  char language[4];
+  char language[MAXLANGCODE2];
   char *description;
   cString ToString(void);
   bool FromString(const char *s);
@@ -42,6 +42,7 @@
   void SetComponent(int Index, const char *s);
   void SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description);
   tComponent *Component(int Index) const { return (Index < numComponents) ? &components[Index] : NULL; }
+  tComponent *GetComponent(int Index, uchar Stream, uchar Type); // Gets the Index'th component of Stream and Type, skipping other components
   };
 
 class cSchedule;
diff -ruN vdr-1.3.42/libsi/descriptor.c vdr-1.3.43/libsi/descriptor.c
--- vdr-1.3.42/libsi/descriptor.c	2005-09-03 17:16:49.000000000 +0200
+++ vdr-1.3.43/libsi/descriptor.c	2006-02-18 12:02:25.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.c 1.15 2005/09/03 15:16:49 kls Exp $
+ *   $Id: descriptor.c 1.17 2006/02/18 11:02:25 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -16,7 +16,7 @@
 namespace SI {
 
 void ShortEventDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const descr_short_event *s;
    data.setPointerAndOffset<const descr_short_event>(s, offset);
    languageCode[0]=s->lang_code1;
@@ -38,7 +38,7 @@
 }
 
 void ExtendedEventDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_extended_event>(s, offset);
    languageCode[0]=s->lang_code1;
    languageCode[1]=s->lang_code2;
@@ -51,7 +51,7 @@
 }
 
 void ExtendedEventDescriptor::Item::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const item_extended_event *first;
    data.setPointerAndOffset<const item_extended_event>(first, offset);
    itemDescription.setDataAndOffset(data+offset, first->item_description_length, offset);
@@ -327,9 +327,12 @@
 }
 
 void CaDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_ca>(s, offset);
-   privateData.assign(data.getData(offset), getLength()-offset);
+   if (checkSize(getLength()-offset))
+      privateData.assign(data.getData(offset), getLength()-offset);
+   else
+      privateData.assign(NULL, 0);
 }
 
 int StreamIdentifierDescriptor::getComponentTag() const {
@@ -477,7 +480,7 @@
 }
 
 void ServiceDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_service>(s, offset);
    providerName.setDataAndOffset(data+offset, s->provider_name_length, offset);
    const descr_service_mid *mid;
@@ -526,7 +529,7 @@
 }
 
 void ComponentDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_component>(s, offset);
    languageCode[0]=s->lang_code1;
    languageCode[1]=s->lang_code2;
@@ -580,7 +583,7 @@
 }
 
 void FrequencyListDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_frequency_list>(s, offset);
    frequencies.setData(data+offset, getLength()-offset);
 }
@@ -594,7 +597,7 @@
 }
 
 void MultilingualNameDescriptor::Name::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const entry_multilingual_name *s;
    data.setPointerAndOffset<const entry_multilingual_name>(s, offset);
    languageCode[0]=s->lang_code1;
@@ -609,7 +612,7 @@
 }
 
 void MultilingualComponentDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_multilingual_component>(s, offset);
    nameLoop.setData(data+sizeof(descr_multilingual_component), getLength()-sizeof(descr_multilingual_component));
 }
@@ -619,7 +622,7 @@
 }
 
 void MultilingualServiceNameDescriptor::Name::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const entry_multilingual_name *s;
    data.setPointerAndOffset<const entry_multilingual_name>(s, offset);
    languageCode[0]=s->lang_code1;
@@ -633,9 +636,12 @@
 }
 
 void LinkageDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_linkage>(s, offset);
-   privateData.assign(data.getData(offset), getLength()-offset);
+   if (checkSize(getLength()-offset))
+      privateData.assign(data.getData(offset), getLength()-offset);
+   else
+      privateData.assign(NULL, 0);
 }
 
 int LinkageDescriptor::getTransportStreamId() const {
@@ -682,7 +688,7 @@
 }
 
 void PDCDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_pdc>(s, offset);
 }
 
@@ -731,7 +737,7 @@
 }
 
 void MHP_ApplicationDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const descr_application *dapp;
    data.setPointerAndOffset<const descr_application>(dapp, offset);
    profileLoop.setDataAndOffset(data+offset, dapp->application_profiles_length, offset);
@@ -790,7 +796,7 @@
 }
 
 void MHP_TransportProtocolDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const descr_transport_protocol>(s, offset);
    if (getProtocolId() == ObjectCarousel) {
       const transport_via_oc *oc;
@@ -821,7 +827,7 @@
 }
 
 void MHP_DVBJApplicationLocationDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const descr_dvbj_application_location *first;
    data.setPointerAndOffset<const descr_dvbj_application_location>(first, offset);
    baseDirectory.setDataAndOffset(data+offset, first->base_directory_length, offset);
@@ -836,7 +842,7 @@
 }
 
 void MHP_ApplicationIconsDescriptor::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const descr_application_icons_descriptor *first;
    data.setPointerAndOffset<const descr_application_icons_descriptor>(first, offset);
    iconLocator.setDataAndOffset(data+offset, first->icon_locator_length, offset);
diff -ruN vdr-1.3.42/libsi/section.c vdr-1.3.43/libsi/section.c
--- vdr-1.3.42/libsi/section.c	2004-02-20 14:44:59.000000000 +0100
+++ vdr-1.3.43/libsi/section.c	2006-02-18 11:38:20.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: section.c 1.3 2004/02/20 13:44:59 kls Exp $
+ *   $Id: section.c 1.4 2006/02/18 10:38:20 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -18,7 +18,7 @@
 /*********************** PAT ***********************/
 
 void PAT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const pat>(s, offset);
    associationLoop.setData(data+offset, getLength()-offset-4);
 }
@@ -48,7 +48,7 @@
 /*********************** PMT ***********************/
 
 void PMT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const pmt>(s, offset);
    commonDescriptors.setDataAndOffset(data+offset, HILO(s->program_info_length), offset);
    streamLoop.setData(data+offset, getLength()-offset-4);
@@ -71,7 +71,7 @@
 }
 
 void PMT::Stream::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const pmt_info>(s, offset);
    streamDescriptors.setData(data+offset, HILO(s->ES_info_length));
 }
@@ -79,7 +79,7 @@
 /*********************** TSDT ***********************/
 
 void TSDT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const tsdt>(s, offset);
    transportStreamDescriptors.setDataAndOffset(data+offset, getLength()-offset-4, offset);
 }
@@ -91,7 +91,7 @@
 }
 
 void NIT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const nit>(s, offset);
    commonDescriptors.setDataAndOffset(data+offset, HILO(s->network_descriptor_length), offset);
    const nit_mid *mid;
@@ -108,7 +108,7 @@
 }
 
 void NIT::TransportStream::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const ni_ts>(s, offset);
    transportStreamDescriptors.setData(data+offset, HILO(s->transport_descriptors_length));
 }
@@ -116,7 +116,7 @@
 /*********************** SDT ***********************/
 
 void SDT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const sdt>(s, offset);
    serviceLoop.setData(data+offset, getLength()-offset-4); //4 is for CRC
 }
@@ -150,7 +150,7 @@
 }
 
 void SDT::Service::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const sdt_descr>(s, offset);
    serviceDescriptors.setData(data+offset, HILO(s->descriptors_loop_length));
 }
@@ -188,7 +188,7 @@
 }
 
 void EIT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const eit>(s, offset);
    //printf("%d %d %d %d %d\n", getServiceId(), getTransportStreamId(), getOriginalNetworkId(), isPresentFollowing(), isActualTS());
    eventLoop.setData(data+offset, getLength()-offset-4); //4 is for CRC
@@ -243,7 +243,7 @@
 }
 
 void EIT::Event::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const eit_event>(s, offset);
    //printf("%d %d %d\n", getStartTime(), getDuration(), getRunningStatus());
    eventDescriptors.setData(data+offset, HILO(s->descriptors_loop_length));
@@ -266,7 +266,7 @@
 }
 
 void TOT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const tot>(s, offset);
    descriptorLoop.setData(data+offset, getLength()-offset-4);
 }
@@ -274,7 +274,7 @@
 /*********************** RST ***********************/
 
 void RST::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    const rst *s;
    data.setPointerAndOffset<const rst>(s, offset);
    infoLoop.setData(data+offset, getLength()-offset);
@@ -315,7 +315,7 @@
 }
 
 void AIT::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const ait>(first, offset);
    commonDescriptors.setDataAndOffset(data+offset, HILO(first->common_descriptors_length), offset);
    const ait_mid *mid;
@@ -336,7 +336,7 @@
 }
 
 void AIT::Application::Parse() {
-   unsigned int offset=0;
+   int offset=0;
    data.setPointerAndOffset<const ait_app>(s, offset);
    applicationDescriptors.setData(data+offset, HILO(s->application_descriptors_length));
 }
diff -ruN vdr-1.3.42/libsi/si.c vdr-1.3.43/libsi/si.c
--- vdr-1.3.42/libsi/si.c	2005-05-28 16:11:16.000000000 +0200
+++ vdr-1.3.43/libsi/si.c	2006-02-18 11:38:20.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.c 1.14 2005/05/28 14:11:16 kls Exp $
+ *   $Id: si.c 1.15 2006/02/18 10:38:20 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -22,7 +22,7 @@
 Object::Object(CharArray &d) : data(d) {
 }
 
-void Object::setData(const unsigned char*d, unsigned int size, bool doCopy) {
+void Object::setData(const unsigned char*d, int size, bool doCopy) {
    data.assign(d, size, doCopy);
 }
 
@@ -30,7 +30,7 @@
    data=d;
 }
 
-bool Object::checkSize(unsigned int offset) {
+bool Object::checkSize(int offset) {
    return data.checkSize(offset);
 }
 
diff -ruN vdr-1.3.42/libsi/si.h vdr-1.3.43/libsi/si.h
--- vdr-1.3.42/libsi/si.h	2005-09-03 17:19:00.000000000 +0200
+++ vdr-1.3.43/libsi/si.h	2006-02-18 11:38:20.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.h 1.12 2005/09/03 15:19:00 kls Exp $
+ *   $Id: si.h 1.13 2006/02/18 10:38:20 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -184,7 +184,7 @@
    Object();
    Object(CharArray &d);
    //can only be called once since data is immutable
-   void setData(const unsigned char*data, unsigned int size, bool doCopy=true);
+   void setData(const unsigned char*data, int size, bool doCopy=true);
    CharArray getData() { return data; }
    //returns the valid flag which indicates if data is all right or errors have been encountered
    bool isValid() { return data.isValid(); }
@@ -196,7 +196,7 @@
    void setData(CharArray &d);
    //returns whether the given offset fits within the limits of the actual data
    //The valid flag will be set accordingly
-   bool checkSize(unsigned int offset);
+   bool checkSize(int offset);
 };
 
 class Section : public Object {
@@ -242,7 +242,7 @@
    //never forget to call this
    void setData(CharArray d, int l) { Object::setData(d); checkSize(l); length=l; }
    //convenience method
-   void setDataAndOffset(CharArray d, int l, unsigned int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; }
+   void setDataAndOffset(CharArray d, int l, int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; }
    virtual int getLength() { return length; }
 private:
    int length;
@@ -384,7 +384,7 @@
 template <typename T> class TypeLoop : public Loop {
 public:
    int getCount() { return getLength()/sizeof(T); }
-   T operator[](const unsigned int index) const
+   T operator[](const int index) const
       {
          switch (sizeof(T)) {
          case 1:
diff -ruN vdr-1.3.42/libsi/util.c vdr-1.3.43/libsi/util.c
--- vdr-1.3.42/libsi/util.c	2005-05-28 16:15:29.000000000 +0200
+++ vdr-1.3.43/libsi/util.c	2006-02-18 12:17:50.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: util.c 1.5 2005/05/28 14:15:29 kls Exp $
+ *   $Id: util.c 1.7 2006/02/18 11:17:50 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -47,7 +47,7 @@
     return *this;
 }
 
-void CharArray::assign(const unsigned char*data, unsigned int size, bool doCopy) {
+void CharArray::assign(const unsigned char*data, int size, bool doCopy) {
     //immutable
     if (!data_)
       data_= doCopy ? (Data*)new DataOwnData() : (Data*)new DataForeignData();
@@ -76,13 +76,13 @@
       return false;
 
    //do _not_ use strcmp! Data is not necessarily null-terminated.
-   for (unsigned int i=0;i<data_->size;i++)
+   for (int i=0;i<data_->size;i++)
       if (data_->data[i] != other.data_->data[i])
          return false;
    return true;
 }
 
-CharArray CharArray::operator+(const unsigned int offset) const {
+CharArray CharArray::operator+(const int offset) const {
    CharArray f(*this);
    f.off+=offset;
    return f;
@@ -117,8 +117,10 @@
    Delete();
 }
 
-void CharArray::DataOwnData::assign(const unsigned char*d, unsigned int s) {
+void CharArray::DataOwnData::assign(const unsigned char*d, int s) {
    Delete();
+   if (!d || s > 100000 || s <= 0) // ultimate plausibility check
+      return;
    size=s;
    unsigned char *newdata=new unsigned char[size];
    memcpy(newdata, d, size);
@@ -127,13 +129,15 @@
 
 void CharArray::DataOwnData::Delete() {
    delete[] data;
+   size=0;
+   data=0;
 }
 
 CharArray::DataForeignData::~DataForeignData() {
    Delete();
 }
 
-void CharArray::DataForeignData::assign(const unsigned char*d, unsigned int s) {
+void CharArray::DataForeignData::assign(const unsigned char*d, int s) {
    size=s;
    data=d;
 }
@@ -143,7 +147,7 @@
 }
 
 /*
-void CharArray::Data::assign(unsigned int s) {
+void CharArray::Data::assign(int s) {
    if (data)
       delete[] data;
    size=s;
diff -ruN vdr-1.3.42/libsi/util.h vdr-1.3.43/libsi/util.h
--- vdr-1.3.42/libsi/util.h	2004-10-23 16:22:40.000000000 +0200
+++ vdr-1.3.43/libsi/util.h	2006-02-18 11:38:20.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: util.h 1.5 2004/10/23 14:22:40 kls Exp $
+ *   $Id: util.h 1.6 2006/02/18 10:38:20 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -37,14 +37,14 @@
    ~CharArray();
 
    //can be called exactly once
-   void assign(const unsigned char*data, unsigned int size, bool doCopy=true);
+   void assign(const unsigned char*data, int size, bool doCopy=true);
    //compares to a null-terminated string
    bool operator==(const char *string) const;
    //compares to another CharArray (data not necessarily null-terminated)
    bool operator==(const CharArray &other) const;
 
    //returns another CharArray with its offset incremented by offset
-   CharArray operator+(const unsigned int offset) const;
+   CharArray operator+(const int offset) const;
 
    //access and convenience methods
    const unsigned char* getData() const { return data_->data+off; }
@@ -52,28 +52,28 @@
    template <typename T> const T* getData() const { return (T*)(data_->data+off); }
    template <typename T> const T* getData(int offset) const { return (T*)(data_->data+offset+off); }
       //sets p to point to data+offset, increments offset
-   template <typename T> void setPointerAndOffset(const T* &p, unsigned int &offset) const { p=(T*)getData(offset); offset+=sizeof(T); }
-   unsigned char operator[](const unsigned int index) const { return data_->data ? data_->data[off+index] : 0; }
+   template <typename T> void setPointerAndOffset(const T* &p, int &offset) const { p=(T*)getData(offset); offset+=sizeof(T); }
+   unsigned char operator[](const int index) const { return data_->data ? data_->data[off+index] : 0; }
    int getLength() const { return data_->size; }
-   u_int16_t TwoBytes(const unsigned int index) const { return data_->data ? data_->TwoBytes(off+index) : 0; }
-   u_int32_t FourBytes(const unsigned int index) const { return data_->data ? data_->FourBytes(off+index) : 0; }
+   u_int16_t TwoBytes(const int index) const { return data_->data ? data_->TwoBytes(off+index) : 0; }
+   u_int32_t FourBytes(const int index) const { return data_->data ? data_->FourBytes(off+index) : 0; }
 
    bool isValid() const { return data_->valid; }
-   bool checkSize(unsigned int offset) { return (data_->valid && (data_->valid=(off+offset < data_->size))); }
+   bool checkSize(int offset) { return (data_->valid && offset>=0 && (data_->valid=(off+offset < data_->size))); }
 
-   void addOffset(unsigned int offset) { off+=offset; }
+   void addOffset(int offset) { off+=offset; }
 private:
    class Data {
    public:
       Data();
       virtual ~Data();
 
-      virtual void assign(const unsigned char*data, unsigned int size) = 0;
+      virtual void assign(const unsigned char*data, int size) = 0;
       virtual void Delete() = 0;
 
-      u_int16_t TwoBytes(const unsigned int index) const
+      u_int16_t TwoBytes(const int index) const
          { return (data[index] << 8) | data[index+1]; }
-      u_int32_t FourBytes(const unsigned int index) const
+      u_int32_t FourBytes(const int index) const
          { return (data[index] << 24) | (data[index+1] << 16) | (data[index+2] << 8) | data[index+3]; }
       /*#ifdef CHARARRAY_THREADSAFE
       void Lock();
@@ -83,11 +83,11 @@
       void Unlock() {}
       #endif
       Data(const Data& d);
-      void assign(unsigned int size);
+      void assign(int size);
       */
 
       const unsigned char*data;
-      unsigned int size;
+      int size;
 
       // count_ is the number of CharArray objects that point at this
       // count_ must be initialized to 1 by all constructors
@@ -106,18 +106,18 @@
    public:
       DataOwnData() {}
       virtual ~DataOwnData();
-      virtual void assign(const unsigned char*data, unsigned int size);
+      virtual void assign(const unsigned char*data, int size);
       virtual void Delete();
    };
    class DataForeignData : public Data {
    public:
       DataForeignData() {}
       virtual ~DataForeignData();
-      virtual void assign(const unsigned char*data, unsigned int size);
+      virtual void assign(const unsigned char*data, int size);
       virtual void Delete();
    };
    Data* data_;
-   unsigned int off;
+   int off;
 };
 
 
diff -ruN vdr-1.3.42/menu.c vdr-1.3.43/menu.c
--- vdr-1.3.42/menu.c	2006-02-05 14:31:08.000000000 +0100
+++ vdr-1.3.43/menu.c	2006-02-19 11:18:28.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 1.410 2006/02/05 13:31:08 kls Exp $
+ * $Id: menu.c 1.413 2006/02/19 10:18:28 kls Exp $
  */
 
 #include "menu.h"
@@ -572,6 +572,7 @@
 :cOsdMenu(Title)
 {
   text = NULL;
+  font = Font;
   SetText(Text);
 }
 
@@ -589,7 +590,7 @@
 void cMenuText::Display(void)
 {
   cOsdMenu::Display();
-  DisplayMenu()->SetText(text, true);//XXX define control character in text to choose the font???
+  DisplayMenu()->SetText(text, font == fontFix); //XXX define control character in text to choose the font???
   cStatus::MsgOsdTextItem(text);
 }
 
@@ -2988,9 +2989,9 @@
          const tComponent *p = Components->Component(i);
          if (p->stream == 2) {
             if (p->type == 0x05)
-               cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, NULL, p->description);
+               cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, LiveChannel ? NULL : p->language, p->description);
             else
-               cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, NULL, p->description);
+               cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, LiveChannel ? NULL : p->language, p->description);
             }
          }
      }
@@ -3104,7 +3105,10 @@
             }
     case k1 ... k9:
          if (number >= 0) {
-            number = number * 10 + Key - k0;
+            if (number > Channels.MaxNumber())
+               number = Key - k0;
+            else
+               number = number * 10 + Key - k0;
             channel = Channels.GetByNumber(number);
             displayChannel->SetEvents(NULL, NULL);
             withInfo = false;
diff -ruN vdr-1.3.42/menu.h vdr-1.3.43/menu.h
--- vdr-1.3.42/menu.h	2006-01-22 15:24:31.000000000 +0100
+++ vdr-1.3.43/menu.h	2006-02-17 16:38:40.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.h 1.82 2006/01/22 14:24:31 kls Exp $
+ * $Id: menu.h 1.83 2006/02/17 15:38:40 kls Exp $
  */
 
 #ifndef __MENU_H
@@ -22,6 +22,7 @@
 class cMenuText : public cOsdMenu {
 private:
   char *text;
+  eDvbFont font;
 public:
   cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
   virtual ~cMenuText();
diff -ruN vdr-1.3.42/menuitems.c vdr-1.3.43/menuitems.c
--- vdr-1.3.42/menuitems.c	2006-02-04 13:47:08.000000000 +0100
+++ vdr-1.3.43/menuitems.c	2006-02-12 11:31:08.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.c 1.31 2006/02/04 12:47:08 kls Exp $
+ * $Id: menuitems.c 1.32 2006/02/12 10:31:08 kls Exp $
  */
 
 #include "menuitems.h"
@@ -239,6 +239,7 @@
 cMenuEditStrItem::cMenuEditStrItem(const char *Name, char *Value, int Length, const char *Allowed)
 :cMenuEditItem(Name)
 {
+  orgValue = NULL;
   value = Value;
   length = Length;
   allowed = strdup(Allowed);
@@ -253,6 +254,7 @@
 
 cMenuEditStrItem::~cMenuEditStrItem()
 {
+  free(orgValue);
   free(allowed);
 }
 
@@ -409,8 +411,10 @@
                  break;
     case kRight|k_Repeat:
     case kRight: AdvancePos();
-                 if (pos == 0)
+                 if (pos == 0) {
+                    orgValue = strdup(value);
                     SetHelpKeys();
+                    }
                  break;
     case kUp|k_Repeat:
     case kUp:
@@ -469,7 +473,13 @@
                     return cMenuEditItem::ProcessKey(Key);
                  }
                  break;
+    case kBack:
     case kOk:    if (InEditMode()) {
+                    if (Key == kBack && orgValue) {
+                       strcpy(value, orgValue);
+                       free(orgValue);
+                       orgValue = NULL;
+                       }
                     pos = -1;
                     newchar = true;
                     stripspace(value);
diff -ruN vdr-1.3.42/menuitems.h vdr-1.3.43/menuitems.h
--- vdr-1.3.42/menuitems.h	2006-01-21 11:45:55.000000000 +0100
+++ vdr-1.3.43/menuitems.h	2006-02-12 11:22:03.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.h 1.16 2006/01/21 10:45:55 kls Exp $
+ * $Id: menuitems.h 1.17 2006/02/12 10:22:03 kls Exp $
  */
 
 #ifndef __MENUITEMS_H
@@ -77,6 +77,7 @@
 
 class cMenuEditStrItem : public cMenuEditItem {
 private:
+  char *orgValue;
   char *value;
   int length;
   char *allowed;
diff -ruN vdr-1.3.42/recording.c vdr-1.3.43/recording.c
--- vdr-1.3.42/recording.c	2006-02-05 13:34:08.000000000 +0100
+++ vdr-1.3.43/recording.c	2006-02-19 14:09:29.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 1.134 2006/02/05 12:34:08 kls Exp $
+ * $Id: recording.c 1.137 2006/02/19 13:09:29 kls Exp $
  */
 
 #include "recording.h"
@@ -58,6 +58,8 @@
 
 #define MAX_SUBTITLE_LENGTH  40
 
+#define MAX_LINK_LEVEL  6
+
 bool VfatFileSystem = false;
 
 cRecordings DeletedRecordings(true);
@@ -254,15 +256,44 @@
 
 // --- cRecordingInfo --------------------------------------------------------
 
-cRecordingInfo::cRecordingInfo(tChannelID ChannelID, const cEvent *Event)
+cRecordingInfo::cRecordingInfo(const cChannel *Channel, const cEvent *Event)
 {
-  channelID = ChannelID;
-  if (Event) {
-     event = Event;
-     ownEvent = NULL;
+  channelID = Channel ? Channel->GetChannelID() : tChannelID::InvalidID;
+  ownEvent = Event ? NULL : new cEvent(0);
+  event = ownEvent ? ownEvent : Event;
+  if (Channel) {
+     // Since the EPG data's component records can carry only a single
+     // language code, let's see whether the channel's PID data has
+     // more information:
+     cComponents *Components = (cComponents *)event->Components();
+     if (!Components)
+        Components = new cComponents;
+     for (int i = 0; i < MAXAPIDS; i++) {
+         const char *s = Channel->Alang(i);
+         if (*s) {
+            tComponent *Component = Components->GetComponent(i, 2, 3);
+            if (!Component)
+               Components->SetComponent(Components->NumComponents(), 2, 3, s, NULL);
+            else if (strlen(s) > strlen(Component->language))
+               strn0cpy(Component->language, s, sizeof(Component->language));
+            }
+         }
+     // There's no "multiple languages" for Dolby Digital tracks, but
+     // we do the same procedure here, too, in case there is no component
+     // information at all:
+     for (int i = 0; i < MAXDPIDS; i++) {
+         const char *s = Channel->Dlang(i);
+         if (*s) {
+            tComponent *Component = Components->GetComponent(i, 2, 5);
+            if (!Component)
+               Components->SetComponent(Components->NumComponents(), 2, 5, s, NULL);
+            else if (strlen(s) > strlen(Component->language))
+               strn0cpy(Component->language, s, sizeof(Component->language));
+            }
+         }
+     if (Components != event->Components())
+        ((cEvent *)event)->SetComponents(Components);
      }
-  else
-     event = ownEvent = new cEvent(0);
 }
 
 cRecordingInfo::~cRecordingInfo()
@@ -465,7 +496,7 @@
   priority = Timer->Priority();
   lifetime = Timer->Lifetime();
   // handle info:
-  info = new cRecordingInfo(Timer->Channel()->GetChannelID(), Event);
+  info = new cRecordingInfo(Timer->Channel(), Event);
   // this is a somewhat ugly hack to get the 'summary' information from the
   // timer into the recording info, but it saves us from having to actually
   // copy the entire event data:
@@ -811,7 +842,7 @@
   ScanVideoDir(VideoDirectory, Foreground);
 }
 
-void cRecordings::ScanVideoDir(const char *DirName, bool Foreground)
+void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel)
 {
   cReadDir d(DirName);
   struct dirent *e;
@@ -821,7 +852,13 @@
            asprintf(&buffer, "%s/%s", DirName, e->d_name);
            struct stat st;
            if (stat(buffer, &st) == 0) {
+              int Link = 0;
               if (S_ISLNK(st.st_mode)) {
+                 if (LinkLevel > MAX_LINK_LEVEL) {
+                    isyslog("max link level exceeded - not scanning %s", buffer);
+                    continue;
+                    }
+                 Link = 1;
                  char *old = buffer;
                  buffer = ReadLink(old);
                  free(old);
@@ -849,7 +886,7 @@
                        delete r;
                     }
                  else
-                    ScanVideoDir(buffer, Foreground);
+                    ScanVideoDir(buffer, Foreground, LinkLevel + Link);
                  }
               }
            free(buffer);
diff -ruN vdr-1.3.42/recording.h vdr-1.3.43/recording.h
--- vdr-1.3.42/recording.h	2006-01-20 18:18:28.000000000 +0100
+++ vdr-1.3.43/recording.h	2006-02-18 15:08:09.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.h 1.49 2006/01/20 17:18:28 kls Exp $
+ * $Id: recording.h 1.51 2006/02/18 14:08:09 kls Exp $
  */
 
 #ifndef __RECORDING_H
@@ -44,7 +44,7 @@
   tChannelID channelID;
   const cEvent *event;
   cEvent *ownEvent;
-  cRecordingInfo(tChannelID ChannelID = tChannelID::InvalidID, const cEvent *Event = NULL);
+  cRecordingInfo(const cChannel *Channel = NULL, const cEvent *Event = NULL);
   void SetData(const char *Title, const char *ShortText, const char *Description);
 public:
   ~cRecordingInfo();
@@ -104,7 +104,7 @@
   int state;
   const char *UpdateFileName(void);
   void Refresh(bool Foreground = false);
-  void ScanVideoDir(const char *DirName, bool Foreground = false);
+  void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0);
 protected:
   void Action(void);
 public:
diff -ruN vdr-1.3.42/skinsttng.c vdr-1.3.43/skinsttng.c
--- vdr-1.3.42/skinsttng.c	2006-02-05 15:51:39.000000000 +0100
+++ vdr-1.3.43/skinsttng.c	2006-02-17 16:57:37.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinsttng.c 1.18 2006/02/05 14:51:39 kls Exp $
+ * $Id: skinsttng.c 1.19 2006/02/17 15:57:37 kls Exp $
  */
 
 // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@@ -632,7 +632,7 @@
 const cFont *cSkinSTTNGDisplayMenu::GetTextAreaFont(bool FixedFont) const
 {
   const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
-  font = cFont::GetFont(fontSml);//XXX -> make a way to let the text define which font to use
+  //XXX -> make a way to let the text define which font to use
   return font;
 }
 
diff -ruN vdr-1.3.42/thread.c vdr-1.3.43/thread.c
--- vdr-1.3.42/thread.c	2006-01-28 12:34:35.000000000 +0100
+++ vdr-1.3.43/thread.c	2006-02-12 13:24:39.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.c 1.52 2006/01/28 11:34:35 kls Exp $
+ * $Id: thread.c 1.53 2006/02/12 12:24:39 kls Exp $
  */
 
 #include "thread.h"
@@ -300,7 +300,7 @@
                return;
             cCondWait::SleepMs(10);
             }
-        esyslog("ERROR: thread %d won't end (waited %d seconds) - canceling it...", childThreadId, WaitSeconds);
+        esyslog("ERROR: %s thread %d won't end (waited %d seconds) - canceling it...", description ? description : "", childThreadId, WaitSeconds);
         }
      pthread_cancel(childTid);
      childTid = 0;
diff -ruN vdr-1.3.42/vdr.5 vdr-1.3.43/vdr.5
--- vdr-1.3.42/vdr.5	2006-01-29 12:31:58.000000000 +0100
+++ vdr-1.3.43/vdr.5	2006-02-19 16:04:21.000000000 +0100
@@ -8,9 +8,9 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.5 1.48 2006/01/29 11:31:58 kls Exp $
+.\" $Id: vdr.5 1.49 2006/02/19 15:04:21 kls Exp $
 .\"
-.TH vdr 5 "08 Jan 2006" "1.3.38" "Video Disk Recorder Files"
+.TH vdr 5 "19 Feb 2006" "1.3.43" "Video Disk Recorder Files"
 .SH NAME
 vdr file formats - the Video Disk Recorder Files
 .SH DESCRIPTION
@@ -641,7 +641,7 @@
 <description>  @is the description of the event (any '|' characters will be interpreted as newlines)
 <stream>       @is the stream content (1 = video, 2 = audio)
 <type>         @is the stream type according to ETSI EN 300 468
-<language>     @is the three letter language code
+<language>     @is the three letter language code (optionally two codes, separated by '+')
 <descr>        @is the description of this stream component
 <vps time>     @is the Video Programming Service time of this event
 .TE
