diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index fad747b9..ae550b81 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -161,6 +161,7 @@ Stefan Huelswitt <huels@iname.com>
  for fixing handling 'Transfer Mode' on single device systems when recording an
  encrypted channel
  for reporting a problem with timers when channel IDs have a 'source' that is 0
+ for reporting a new/delete malloc/free mismatch in ringbuffer.c
 
 Ulrich R�der <roeder@efr-net.de>
  for pointing out that there are channels that have a symbol rate higher than
diff --git a/HISTORY b/HISTORY
index 90859361..8e770ee7 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1941,3 +1941,9 @@ Video Disk Recorder Revision History
 - Fixed handling user defined CFLAGS in libdtv/libvdr/Makefile (thanks to Clemens
   Kirchgatterer and Robert Schiele).
 - Fixed skipping unavailable channels in the EPG scanner.
+
+2003-02-02: Version 1.1.23
+
+- Fixed a new/delete malloc/free mismatch in ringbuffer.c (thanks to Stefan
+  Huelswitt for reporting this one).
+- Improved CAM handling.
diff --git a/ci.c b/ci.c
index 61bc7482..97de9b01 100644
--- a/ci.c
+++ b/ci.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ci.c 1.2 2003/01/11 11:15:19 kls Exp $
+ * $Id: ci.c 1.3 2003/02/02 15:49:52 kls Exp $
  */
 
 /* XXX TODO
@@ -13,7 +13,6 @@
 - update CA descriptors in case they change
 - dynamically react on CAM insert/remove
 - implement CAM reset (per slot)
-- implement a CA enquiry menu with actual user input
 XXX*/
 
 #include "ci.h"
@@ -45,7 +44,7 @@ static int SysLogLevel = 3;
 static bool DumpTPDUDataTransfer = false;
 static bool DebugProtocol = false;
 
-#define dbgprotocol(a...) if (DebugProtocol) printf(a)
+#define dbgprotocol(a...) if (DebugProtocol) fprintf(stderr, a)
 
 #define OK       0
 #define TIMEOUT -1
@@ -460,19 +459,32 @@ cCiTransportConnection *cCiTransportLayer::NewConnection(void)
   return NULL;
 }
 
-#define CA_RESET_TIMEOUT  2 // seconds
+#define CA_RESET_TIMEOUT  3 // seconds
 
 bool cCiTransportLayer::ResetSlot(int Slot)
 {
+  dbgprotocol("Resetting slot %d...", Slot);
   ca_slot_info_t sinfo;
   sinfo.num = Slot;
-  ioctl(fd, CA_RESET, Slot);
-  time_t t0 = time(NULL);
-  do {
-     ioctl(fd, CA_GET_SLOT_INFO, &sinfo);
-     if ((sinfo.flags & CA_CI_MODULE_READY) != 0)
-        return true;
-     } while (time(NULL) - t0 < CA_RESET_TIMEOUT);
+  if (ioctl(fd, CA_RESET, 1 << Slot) != -1) {
+     time_t t0 = time(NULL);
+     do {
+        if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
+           ioctl(fd, CA_GET_SLOT_INFO, &sinfo);
+           if ((sinfo.flags & CA_CI_MODULE_READY) != 0) {
+              dbgprotocol("ok.\n");
+              return true;
+              }
+           }
+        else {
+           esyslog("ERROR: can't get info on CAM slot %d: %m", Slot);
+           break;
+           }
+        } while (time(NULL) - t0 < CA_RESET_TIMEOUT);
+     }
+  else
+     esyslog("ERROR: can't reset CAM slot %d: %m", Slot);
+  dbgprotocol("failed!\n");
   return false;
 }
 
@@ -818,7 +830,27 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTrans
 
 bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
 {
-  if (state == 0) {
+  if (Data) {
+     int Tag = GetTag(Length, &Data);
+     switch (Tag) {
+       case AOT_CA_INFO: {
+            dbgprotocol("%d: <== Ca Info", SessionId());
+            int l = 0;
+            const uint8_t *d = GetData(Data, l);
+            while (l > 1) {
+                  dbgprotocol(" %04X", ((unsigned int)(*d) << 8) | *(d + 1));
+                  d += 2;
+                  l -= 2;
+                  }
+            dbgprotocol("\n");
+            }
+            state = 2;
+            break;
+       default: esyslog("ERROR: CI conditional access support: unknown tag %06X", Tag);
+                return false;
+       }
+     }
+  else if (state == 0) {
      dbgprotocol("%d: ==> Ca Info Enq\n", SessionId());
      SendData(AOT_CA_INFO_ENQ);
      state = 1;
@@ -828,7 +860,7 @@ bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
 
 bool cCiConditionalAccessSupport::SendPMT(cCiCaPmt &CaPmt)
 {
-  if (state == 1) {
+  if (state == 2) {
      SendData(AOT_CA_PMT, CaPmt.length, CaPmt.capmt);
      return true;
      }
@@ -1186,27 +1218,27 @@ cCiCaPmt::cCiCaPmt(int ProgramNumber)
   capmt[length++] = (ProgramNumber >> 8) & 0xFF;
   capmt[length++] =  ProgramNumber       & 0xFF;
   capmt[length++] = 0x00; //XXX version_number, current_next_indicator - apparently may be 0x00
-  capmt[length++] = 0x00; //XXX program_info_length H (at program level)
-  capmt[length++] = 0x00; //XXX program_info_length L
-  esInfoLengthPos = 0;
+  esInfoLengthPos = length;
+  capmt[length++] = 0x00; // program_info_length H (at program level)
+  capmt[length++] = 0x00; // program_info_length L
 }
 
 void cCiCaPmt::AddPid(int Pid)
 {
+  //XXX buffer overflow check???
   capmt[length++] = 0x00; //XXX stream_type (apparently doesn't matter)
   capmt[length++] = (Pid >> 8) & 0xFF;
   capmt[length++] =  Pid       & 0xFF;
   esInfoLengthPos = length;
+  capmt[length++] = 0x00; // ES_info_length H (at ES level)
+  capmt[length++] = 0x00; // ES_info_length L
 }
 
 void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
 {
   if (esInfoLengthPos) {
-     if (esInfoLengthPos == length) {
-        length += 2;
-        capmt[length++] = CPCI_OK_DESCRAMBLING;
-        }
      if (length + Length < int(sizeof(capmt))) {
+        capmt[length++] = CPCI_OK_DESCRAMBLING;
         memcpy(capmt + length, Data, Length);
         length += Length;
         int l = length - esInfoLengthPos - 2;
@@ -1215,6 +1247,7 @@ void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
         }
      else
         esyslog("ERROR: buffer overflow in CA descriptor");
+     esInfoLengthPos = 0;
      }
   else
      esyslog("ERROR: adding CA descriptor without Pid!");
diff --git a/config.h b/config.h
index 83045ae3..8bf33f62 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 1.146 2003/01/12 09:44:28 kls Exp $
+ * $Id: config.h 1.147 2003/01/26 19:50:19 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -19,7 +19,7 @@
 #include "device.h"
 #include "tools.h"
 
-#define VDRVERSION "1.1.22"
+#define VDRVERSION "1.1.23"
 
 #define MAXPRIORITY 99
 #define MAXLIFETIME 99
diff --git a/dvbdevice.c b/dvbdevice.c
index 2e12f260..1ffe067a 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 1.41 2003/01/06 14:44:27 kls Exp $
+ * $Id: dvbdevice.c 1.42 2003/02/02 15:31:31 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -263,22 +263,15 @@ void cDvbTuner::Action(void)
            int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), sizeof(buffer), buffer);
            if (length > 0) {
               cCiCaPmt CaPmt(channel.Sid());
-              if (channel.Vpid()) {
+              CaPmt.AddCaDescriptor(length, buffer);
+              if (channel.Vpid())
                  CaPmt.AddPid(channel.Vpid());
-                 CaPmt.AddCaDescriptor(length, buffer);
-                 }
-              if (channel.Apid1()) {
+              if (channel.Apid1())
                  CaPmt.AddPid(channel.Apid1());
-                 CaPmt.AddCaDescriptor(length, buffer);
-                 }
-              if (channel.Apid2()) {
+              if (channel.Apid2())
                  CaPmt.AddPid(channel.Apid2());
-                 CaPmt.AddCaDescriptor(length, buffer);
-                 }
-              if (channel.Dpid1()) {
+              if (channel.Dpid1())
                  CaPmt.AddPid(channel.Dpid1());
-                 CaPmt.AddCaDescriptor(length, buffer);
-                 }
               caSet = ciHandler->SetCaPmt(CaPmt);
               }
            }
diff --git a/eit.c b/eit.c
index 174ad6d4..eebe82c7 100644
--- a/eit.c
+++ b/eit.c
@@ -16,7 +16,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- * $Id: eit.c 1.64 2003/01/26 12:21:15 kls Exp $
+ * $Id: eit.c 1.65 2003/02/02 15:41:03 kls Exp $
  ***************************************************************************/
 
 #include "eit.h"
@@ -1349,7 +1349,7 @@ void cSIProcessor::Action()
 
 /** Add a filter with packet identifier pid and
 table identifer tid */
-bool cSIProcessor::AddFilter(u_char pid, u_char tid)
+bool cSIProcessor::AddFilter(unsigned short pid, u_char tid)
 {
    dmx_sct_filter_params sctFilterParams;
    memset(&sctFilterParams, 0, sizeof(sctFilterParams));
@@ -1390,7 +1390,7 @@ bool cSIProcessor::AddFilter(u_char pid, u_char tid)
    return false;
 }
 
-bool cSIProcessor::DelFilter(u_char pid, u_char tid)
+bool cSIProcessor::DelFilter(unsigned short pid, u_char tid)
 {
    for (int a = 0; a < MAX_FILTERS; a++)
    {
diff --git a/eit.h b/eit.h
index ec203eae..17fa9093 100644
--- a/eit.h
+++ b/eit.h
@@ -16,7 +16,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- * $Id: eit.h 1.23 2003/01/04 10:12:54 kls Exp $
+ * $Id: eit.h 1.24 2003/02/02 14:07:39 kls Exp $
  ***************************************************************************/
 
 #ifndef __EIT_H
@@ -127,7 +127,7 @@ public:
 
 typedef struct sip_filter {
 
-  u_char pid;
+  unsigned short pid;
   u_char tid;
   int handle;
   bool inuse;
@@ -155,8 +155,8 @@ private:
   char *fileName;
   bool active;
   void Action(void);
-  bool AddFilter(u_char pid, u_char tid);
-  bool DelFilter(u_char pid, u_char tid);
+  bool AddFilter(unsigned short pid, u_char tid);
+  bool DelFilter(unsigned short pid, u_char tid);
   bool ShutDownFilters(void);
 public:
   cSIProcessor(const char *FileName);
diff --git a/ringbuffer.c b/ringbuffer.c
index 0734c28d..48622f0c 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -7,7 +7,7 @@
  * Parts of this file were inspired by the 'ringbuffy.c' from the
  * LinuxDVB driver (see linuxtv.org).
  *
- * $Id: ringbuffer.c 1.12 2003/01/26 09:39:24 kls Exp $
+ * $Id: ringbuffer.c 1.13 2003/01/26 19:47:10 kls Exp $
  */
 
 #include "ringbuffer.h"
@@ -188,7 +188,7 @@ cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
   if (Count < 0)
      data = (uchar *)Data;
   else {
-     data = new uchar[count];
+     data = MALLOC(uchar, count);
      if (data)
         memcpy(data, Data, count);
      else
@@ -199,7 +199,7 @@ cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
 
 cFrame::~cFrame()
 {
-  delete data;
+  free(data);
 }
 
 // --- cRingBufferFrame ------------------------------------------------------