[MPlayer-dev-eng] [PATCH] tivo vstream

Joey Parrish joey at nicewarrior.org
Thu Aug 12 02:11:05 CEST 2004


Hello,

This patch is taken from source at tivo-mplayer.sf.net and adds vstream
support.  This allows streaming from a tivo running vstream server by
giving mplayer a tivo:// URL.

I diff'd the tivo-mplayer source and removed cosmetic changes.  I also
added a small compilation fix for cygwin/darwin systems.

I've tested this a lot at home, and would like to see it committed.
Any objections, comments, etc?

--Joey

-- 
"The Hell Law says that Hell is reserved exclusively for them that believe
in it.  Further, the lowest Rung in Hell is reserved for them that believe
in it on the supposition that they'll go there if they don't."
  HBT; The Gospel According to Fred, 3:1
-------------- next part --------------
add tivo vstream capabilities
  see tivo-mplayer.sf.net
  taken from their source tree
    minus cosmetics, plus cygwin/darwin compilation fix

diff -Nur main.sofar/Makefile main.dev/Makefile
--- main.sofar/Makefile	2004-08-10 03:07:20.000000000 +0000
+++ main.dev/Makefile	2004-08-11 03:18:37.405635200 +0000
@@ -72,6 +72,11 @@
 
 COMMON_DEPS = $(W32_DEP) $(DS_DEP) $(MP1E_DEP) $(AV_DEP) libmpdemux/libmpdemux.a libmpcodecs/libmpcodecs.a libao2/libao2.a liba52/liba52.a mp3lib/libMP3.a libmpeg2/libmpeg2.a osdep/libosdep.a postproc/libswscale.a input/libinput.a libvo/libvo.a libaf/libaf.a
 
+ifeq ($(VSTREAM),yes)
+COMMON_LIBS += vstream/vstream.a
+COMMON_DEPS += vstream/vstream.a
+PARTS += vstream
+endif
 ifeq ($(INTERNAL_FAAD),yes)
 COMMON_DEPS += libfaad2/libfaad2.a
 endif
@@ -123,6 +128,9 @@
 libfame/libfame.a:
 	$(MAKE) -C libfame
 
+vstream/vstream.a:
+	$(MAKE) -C vstream
+
 libmpdemux/libmpdemux.a:
 	$(MAKE) -C libmpdemux
 
diff -Nur main.sofar/configure main.dev/configure
--- main.sofar/configure	2004-08-10 03:07:20.000000000 +0000
+++ main.dev/configure	2004-08-11 03:18:37.485750400 +0000
@@ -248,6 +248,7 @@
   --enable-zr            build with ZR360[56]7/ZR36060 support [autodetect]
   --enable-bl		 build with Blinkenlights support [disable]
   --enable-tdfxvid       build with tdfx_vid support [disable]
+  --disable-vstream      build with TiVo vstream [enable]
   --disable-tga          disable targa output support [enable]
   
 Audio output:
@@ -1222,6 +1223,7 @@
 _tremor=no
 _faad_internal=auto
 _faad_external=auto
+_vstream=yes
 _xmms=no
 # dvdnav disabled, it does not work
 #_dvdnav=no
@@ -1402,6 +1404,8 @@
   --disable-internal-faad)	_faad_internal=no	;;
   --enable-external-faad)	_faad_external=yes	_faad_internal=no	;;
   --disable-external-faad)	_faad_external=no	;;
+  --enable-vstream)	_vstream=yes    ;;
+  --disable-vstream)	_vstream=no     ;;
   --enable-xmms)	_xmms=yes	;;
   --disable-xmms)	_xmms=no	;;
   --enable-dvdread)	_dvdread=yes	;;
@@ -4532,6 +4536,13 @@
 fi
 echores "$_cdparanoia"
 
+echocheck "vstream"
+if test "$_vstream" = yes ; then
+    _def_vstream='#define HAVE_VSTREAM 1'
+else
+_def_vstream='#undef HAVE_VSTREAM'
+fi
+echores "$_vstream"
 
 echocheck "freetype >= 2.0.9"
 
@@ -6104,6 +6115,7 @@
 MPLAYER_NETWORK_LIB = $_ld_live $_ld_network
 DVBIN = $_dvbin
 VIDIX = $_vidix
+VSTREAM = $_vstream
 SHARED_PP = $_shared_pp
 CONFIG_PP = yes
 CONFIG_RISKY = yes
@@ -6551,6 +6563,9 @@
 /* LIVE.COM Streaming Media library support */
 $_def_live
 
+/* vstream support */
+$_def_vstream
+
 /* Use 3dnow/mmxext/sse/mmx optimized fast memcpy() [maybe buggy... signal 4]*/
 $_def_fastmemcpy
 
diff -Nur main.sofar/libmpdemux/cache2.c main.dev/libmpdemux/cache2.c
--- main.sofar/libmpdemux/cache2.c	2004-08-02 18:01:54.000000000 +0000
+++ main.dev/libmpdemux/cache2.c	2004-08-11 03:18:37.515793600 +0000
@@ -121,7 +121,10 @@
       // seek...
       mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%X  \n",read);
       // streaming: drop cache contents only if seeking backward or too much fwd:
-      if(s->stream->type!=STREAMTYPE_STREAM ||
+      if(s->stream->type!=STREAMTYPE_STREAM || 
+#ifdef STREAMTYPE_STREAM_TY
+         s->stream->type!=STREAMTYPE_STREAM_TY || 
+#endif
           read<s->min_filepos || read>=s->max_filepos+s->buffer_size)
       {
         s->offset= // FIXME!?
@@ -260,6 +263,16 @@
     return 1;
   }
 
+#ifdef STREAMTYPE_STREAM_TY
+  if ( stream->type == STREAMTYPE_STREAM_TY )
+#else
+  if ( 0 )
+#endif
+  {
+    ss = 128 * 1024;
+    if ( size < 2 * 1024 * 1024 ) size = 2 * 1024 * 1024;
+  }
+  
   s=cache_init(size,ss);
   if(s == NULL) return 0;
   stream->cache_data=s;
diff -Nur main.sofar/libmpdemux/demux_ty.c main.dev/libmpdemux/demux_ty.c
--- main.sofar/libmpdemux/demux_ty.c	2004-07-19 23:17:37.000000000 +0000
+++ main.dev/libmpdemux/demux_ty.c	2004-08-11 03:21:54.909632000 +0000
@@ -50,6 +50,14 @@
 
 //#include "dvdauth.h"
 
+#if defined(__CYGWIN__)
+typedef unsigned long long loff_t;
+#endif
+
+#if defined(SYS_DARWIN)
+typedef unsigned long long loff_t;
+#endif
+
 extern void resync_audio_stream( sh_audio_t *sh_audio );
 extern void skip_audio_frame( sh_audio_t *sh_audio );
 extern int sub_justify;
@@ -79,32 +87,300 @@
 #define PTS_KHZ          ( PTS_MHZ * 1000 )
 
 #define TY_V             ( 1 )
-#define TY_A             ( 1 )
+#define TY_A             ( 2 )
+
+typedef struct stmf_fileParts
+{
+   int     fileNo;
+   loff_t  fileSize;
+   int     chunks;
+   loff_t  startOffset;
+} tmf_fileParts;
+
+#define MAX_TMF_PARTS ( 16 )
 
 typedef struct sTivoInfo
 {
-   unsigned char lastAudio[ MAX_AUDIO_BUFFER ];
-   int           lastAudioEnd;
+   int             whichChunk;
+
+   unsigned char   lastAudio[ MAX_AUDIO_BUFFER ];
+   int             lastAudioEnd;
+
+   int             tivoType;           // 1 = SA, 2 = DTiVo
 
-   int           tivoType;           // 1 = SA, 2 = DTiVo
+   float           firstAudioPTS;
+   float           firstVideoPTS;
 
-   float         firstAudioPTS;
-   float         firstVideoPTS;
+   float           lastAudioPTS;
+   float           lastVideoPTS;
+
+   int             headerOk;
+   unsigned int    pesFileId;          // Should be 0xf5467abd
+   int             streamType;         // Should be 0x02
+   int             chunkSize;          // Should always be 128k
+   off_t           size;
+   int             readHeader;
+   
+   int             tmf;
+   tmf_fileParts   tmfparts[ MAX_TMF_PARTS ];
+   int             tmf_totalparts;
+   off_t           tmf_totalsize;
+   off_t           tmf_totalchunks;
 
-   float         lastAudioPTS;
-   float         lastVideoPTS;
-
-   int           headerOk;
-   unsigned int  pesFileId;          // Should be 0xf5467abd
-   int           streamType;         // Should be 0x02
-   int           chunkSize;          // Should always be 128k
-   off_t         size;
-   int           readHeader;
 } TiVoInfo;
 
 off_t vstream_streamsize( );
 void ty_ClearOSD( int start );
 
+// ===========================================================================
+#define TMF_SIG "showing.xml"
+
+int ty_octaltodecimal( char *num )
+{
+   int i;
+   int result = 0;
+   int len;
+   int mult;
+
+   len = strlen( num );
+   mult = 1;
+
+   for ( i = ( len - 1 ) ; i >= 0 ; i-- )
+   {
+      result += ( ( num[ i ] - '0') * mult );
+      mult *= 8;
+   }
+   return( result );
+}
+
+
+
+// ===========================================================================
+int ty_extensionis( char *name, char *ext )
+{
+   char *ptr;
+
+   if ( strlen( ext ) > strlen( name ) ) return( 0 );
+   ptr = name;
+   ptr += ( strlen( name ) - strlen( ext ) );
+   if ( strcmp( ptr, ext ) == 0 ) return( 1 );
+   return( 0 );
+}
+
+
+// ===========================================================================
+int ty_tmf_filetoparts( demuxer_t *demux, TiVoInfo *tivo )
+{
+   char    header[ 512 ];
+   char    name[ 80 ];
+   char    sizestr[ 80 ];
+   int     size;
+   int     count;
+   int     blocks;
+   int     done;
+   loff_t  offset;
+   loff_t  totalsize;
+   loff_t  skip;
+   int     error = 0;
+   int     parts = 0;
+   int     isty;
+   int     index;
+   int     ok;
+
+   offset = 0;
+   totalsize = demux->stream->end_pos;
+
+   done = 0;
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "Dumping tar contents\n" );
+   while ( done == 0 )
+   {
+      ok = stream_seek( demux->stream, offset );
+      if ( ( offset + 512 ) == totalsize )
+      {
+         done = 1;
+         break;
+      }
+      if ( ok == 0 )
+      { 
+         mp_msg( MSGT_NETWORK, MSGL_DBG3, "Seek bad %d\n", offset );
+         done = 1;
+         error = 1;
+         break;
+      }
+      count = stream_read( demux->stream, header, 512 );
+      if ( count < 512 )
+      { 
+         mp_msg( MSGT_NETWORK, MSGL_DBG3, "Read bad\n" );
+         done = 1;
+         error = 1;
+         break;
+      }
+      strncpy( name, &header[ 0 ], 100 );
+      strncpy( sizestr, &header[ 124 ], 12 );
+      size = ty_octaltodecimal( sizestr );
+
+      blocks = size / 512;
+      if ( ( size % 512 ) > 0 ) blocks++;
+      skip = ( blocks + 1 ) * 512;
+
+      if ( ( offset + skip ) > totalsize )
+      {
+         size = totalsize - offset;
+      }
+
+      isty = ty_extensionis( name, ".ty" );
+
+      mp_msg( MSGT_NETWORK, MSGL_DBG3, "name %-20.20s size %-12.12s %d %d\n", 
+         name, sizestr, size, isty );
+
+      if ( isty )
+      {
+         tivo->tmfparts[ parts ].fileNo = parts;
+			// HACK - Ignore last chunk of a Part File
+			// Why?  I have no idea.
+         tivo->tmfparts[ parts ].fileSize = size - 0x20000;
+         tivo->tmfparts[ parts ].startOffset = offset + 512;
+         tivo->tmfparts[ parts ].chunks = 
+            ( tivo->tmfparts[ parts ].fileSize / CHUNKSIZE );
+         mp_msg
+         ( 
+            MSGT_NETWORK, MSGL_DBG3,
+           "tmf_filetoparts(): index %d, file %d, chunks %d\n",
+            parts,
+            tivo->tmfparts[ parts ].fileNo,
+            tivo->tmfparts[ parts ].chunks
+         );
+         mp_msg
+         ( 
+            MSGT_NETWORK, MSGL_DBG3,
+           "tmf_filetoparts(): size %lld\n",
+           tivo->tmfparts[ parts ].fileSize
+         );
+         mp_msg
+         ( 
+            MSGT_NETWORK, MSGL_DBG3,
+           "tmf_filetoparts(): startOffset %lld\n",
+           tivo->tmfparts[ parts ].startOffset
+         );
+         parts++;
+         if ( parts > MAX_TMF_PARTS )
+         {
+            mp_msg( MSGT_DEMUX, MSGL_ERR, "ty:tmf too big\n" );
+         }
+      }
+
+      if ( ( offset + skip ) > totalsize )
+      {
+         done = 1;
+         error = 1;
+      }
+      else
+      {
+         offset += skip;
+      }
+   }
+   if ( error )
+   {
+      mp_msg( MSGT_NETWORK, MSGL_DBG3, 
+         "WARNING : tmf parse error, not intact\n" );
+   }
+   tivo->tmf_totalparts = parts;
+   mp_msg( MSGT_NETWORK, MSGL_DBG3,
+      "tmf_filetoparts(): No More Part Files %d\n", parts );
+
+   tivo->tmf_totalsize = 0;
+   tivo->tmf_totalchunks = 0;
+   for( index = 0 ; index < tivo->tmf_totalparts ; index++ )
+   {
+      tivo->tmf_totalsize += tivo->tmfparts[ index ].fileSize;
+      tivo->tmf_totalchunks += ( tivo->tmfparts[ index ].fileSize / CHUNKSIZE );
+   }
+   mp_msg( MSGT_NETWORK, MSGL_DBG3,
+      "tmf_filetoparts():total size %lld\n", tivo->tmf_totalsize );
+   mp_msg( MSGT_NETWORK, MSGL_DBG3,
+      "tmf_filetoparts():total chunks %d\n", tivo->tmf_totalchunks );
+
+   return( 1 );
+}
+
+
+// ===========================================================================
+void tmf_filetooffset( TiVoInfo *tivo, int chunk, loff_t *offset )
+{
+   int index;
+
+   *offset = 0;
+
+   for( index = 0 ; index < tivo->tmf_totalparts ; index++ )
+   {
+      if ( chunk >= tivo->tmfparts[ index ].chunks )
+      {
+         chunk -= tivo->tmfparts[ index ].chunks;
+      }
+      else
+      {
+         break;
+      }
+   }
+   if ( chunk < tivo->tmfparts[ index ].chunks )
+   {
+      *offset = tivo->tmfparts[ index ].startOffset +
+         ( chunk * CHUNKSIZE );
+   }
+   mp_msg
+   ( 
+      MSGT_NETWORK, MSGL_DBG3, 
+      "tmf_filetooffset() offset %llx\n", *offset
+   );
+}
+
+
+// ===========================================================================
+int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo, 
+   unsigned char *buff, int size, int readChunk )
+{
+   loff_t fileoffset;
+   int    count;
+
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n", 
+      readChunk );
+
+   if ( tivo->tmf_totalparts <= 0 )
+   {
+      return( 0 );
+   }
+
+   if ( readChunk >= tivo->tmf_totalchunks )
+   {
+      mp_msg( MSGT_NETWORK, MSGL_ERR, "Read past EOF()\n" );
+      return( 0 );
+   }
+
+   tmf_filetooffset( tivo, readChunk, &fileoffset );
+
+   if ( stream_seek( demux->stream, fileoffset ) != 1 )
+   {
+      mp_msg( MSGT_NETWORK, MSGL_ERR, "Read past EOF()\n" );
+      return( 0 );
+   }
+   count = stream_read( demux->stream, buff, size );
+	demux->filepos = stream_tell( demux->stream );
+
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "tmf_load_chunk() count %x\n", 
+		count );
+
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, 
+		"tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n", 
+		buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ],
+		buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] );
+
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "tmf_load_chunk() end\n" );
+    
+   return( count );
+}
+
+// ===========================================================================
+
 // DTiVo MPEG 336, 480, 576, 768
 // SA TiVo 864
 // DTiVo AC-3 1550
@@ -116,10 +392,11 @@
 #define AC3_PTS_LENGTH             ( 16 )
 #define AC3_PTS_OFFSET             ( 9 )
 
-#define NUMBER_DIFFERENT_AUDIO_SIZES ( 6 )
+#define NUMBER_DIFFERENT_AUDIO_SIZES ( 7 )
 static int Series1AudioWithPTS[ NUMBER_DIFFERENT_AUDIO_SIZES ] = 
 { 
    336 + SERIES1_PTS_LENGTH, 
+   384 + SERIES1_PTS_LENGTH, 
    480 + SERIES1_PTS_LENGTH, 
    576 + SERIES1_PTS_LENGTH, 
    768 + SERIES1_PTS_LENGTH, 
@@ -128,6 +405,7 @@
 static int Series2AudioWithPTS[ NUMBER_DIFFERENT_AUDIO_SIZES ] = 
 { 
    336 + SERIES2_PTS_LENGTH, 
+   384 + SERIES2_PTS_LENGTH, 
    480 + SERIES2_PTS_LENGTH, 
    576 + SERIES2_PTS_LENGTH, 
    768 + SERIES2_PTS_LENGTH, 
@@ -363,6 +641,9 @@
    int              esOffset1;
    int              esOffset2;
 
+   unsigned char    lastCC[ 16 ];
+   unsigned char    lastXDS[ 16 ];
+
    TiVoInfo         *tivo = 0;
 
    if ( demux->stream->type == STREAMTYPE_DVD )
@@ -370,7 +651,7 @@
 		return( 0 );
 	}
 
-   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Parsing a chunk\n" );
+   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" );
    if ( ( demux->a_streams[ MAX_A_STREAMS - 1 ] ) == 0 )
    {
       demux->a_streams[ MAX_A_STREAMS - 1 ] = malloc( sizeof( TiVoInfo ) );
@@ -407,31 +688,64 @@
       if ( tivo->readHeader == 0 )
       {
          tivo->readHeader = 1;
+         tivo->size = demux->stream->end_pos;
+
          filePos = demux->filepos;
          stream_seek( demux->stream, 0 );
+
          // mp_msg( MSGT_DEMUX, MSGL_DBG3, 
 			// 	"ty:Reading a chunk %d\n", __LINE__ );
+
          readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+
+         if ( memcmp( chunk, TMF_SIG, sizeof( TMF_SIG ) ) == 0 )
+         {
+            mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Detected a tmf\n" );
+            tivo->tmf = 1;
+            ty_tmf_filetoparts( demux, tivo );
+            readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, 0 );
+         }
+
          if ( readSize == CHUNKSIZE )
          {
             tivo->pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] );
             tivo->streamType = tivobuffer2hostlong( &chunk[ 0x04 ] );
             tivo->chunkSize = tivobuffer2hostlong( &chunk[ 0x08 ] );
-            tivo->size = tivobuffer2hostlong( &chunk[ 0x0c ] );
+
             if ( tivo->pesFileId == TIVO_PES_FILEID )
             {
                off_t numberParts;
-               off_t size;
 
-               if ( demux->stream->end_pos > TIVO_PART_LENGTH )
+               readSize = 0;
+               
+               if ( tivo->tmf != 1 )
                {
+                  off_t size;
+                  off_t offset;
+
                   numberParts = demux->stream->end_pos / TIVO_PART_LENGTH;
-                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Number Parts %d\n",
+                  offset = numberParts * TIVO_PART_LENGTH;
+
+                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty/ty+Number Parts %d\n",
                     numberParts );
-                  stream_seek( demux->stream, numberParts * TIVO_PART_LENGTH );
-                  // mp_msg( MSGT_DEMUX, MSGL_DBG3, 
-				      //    "ty:Reading a chunk %d\n", __LINE__ );
-                  readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+
+                  if ( ( offset + CHUNKSIZE ) < demux->stream->end_pos )
+                  {
+                     stream_seek( demux->stream, offset );
+                     readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+                  }
+               }
+               else
+               {
+                  numberParts = tivo->tmf_totalparts;
+                  offset = numberParts * TIVO_PART_LENGTH;
+                  readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, 
+                     ( numberParts * ( TIVO_PART_LENGTH - 0x20000 ) / 
+                     CHUNKSIZE ) );
+               }
+
+               if ( readSize == CHUNKSIZE )
+               {
                   pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] );
                   if ( pesFileId == TIVO_PES_FILEID )
                   {
@@ -439,26 +753,16 @@
                      size /= 256;
                      size -= 4;
                      size *= CHUNKSIZE;
+
                      tivo->size = numberParts * TIVO_PART_LENGTH;
                      tivo->size += size;
                      mp_msg( MSGT_DEMUX, MSGL_DBG3, 
                         "ty:Header Calc Stream Size %lld\n", tivo->size );
                   }
-                  else
-                  {
-                     tivo->size = demux->stream->end_pos;
-                  }
-               }
-               else
-               {
-                  tivo->size = demux->stream->end_pos;
                }
             }
-            else
-            {
-               tivo->size = demux->stream->end_pos;
-            }
          }
+
          if ( tivo->size > demux->stream->end_pos )
          {
             tivo->size = demux->stream->end_pos;
@@ -468,8 +772,10 @@
 			{
 				filePos = demux->stream->start_pos;
 			}
+
          stream_seek( demux->stream, filePos );
 			demux->filepos = stream_tell( demux->stream );
+         tivo->whichChunk = ( filePos / CHUNKSIZE );
       }
       demux->movi_start = 0;
       demux->movi_end = tivo->size;
@@ -481,10 +787,9 @@
    mp_msg( MSGT_DEMUX, MSGL_DBG3,
       "ty:ty header size %llx\n", tivo->size );
    mp_msg( MSGT_DEMUX, MSGL_DBG3,
+      "ty:ty which Chunk %llx\n", tivo->whichChunk );
+   mp_msg( MSGT_DEMUX, MSGL_DBG3,
       "ty:file end_pos   %llx\n", demux->stream->end_pos );
-//   mp_msg( MSGT_DEMUX, MSGL_DBG3,
-//      "ty:vstream size   %llx\n", vstream_streamsize() );
-
    mp_msg( MSGT_DEMUX, MSGL_DBG3,
       "\nty:wanted current offset %llx\n", stream_tell( demux->stream ) );
 
@@ -497,31 +802,55 @@
       }
    }
 
-   // Make sure we are on a 128k boundary
-   if ( ( demux->filepos % CHUNKSIZE ) != 0 )
+   if ( tivo->tmf != 1 )
    {
-      whichChunk = demux->filepos / CHUNKSIZE;
-      if ( ( demux->filepos % CHUNKSIZE ) > ( CHUNKSIZE / 2 ) )
+      // Make sure we are on a 128k boundary
+      if ( ( demux->filepos % CHUNKSIZE ) != 0 )
       {
-         whichChunk++;
+         whichChunk = demux->filepos / CHUNKSIZE;
+         if ( ( demux->filepos % CHUNKSIZE ) > ( CHUNKSIZE / 2 ) )
+         {
+            whichChunk++;
+         }
+         stream_seek( demux->stream, ( whichChunk * CHUNKSIZE ) );
       }
-      stream_seek( demux->stream, ( whichChunk * CHUNKSIZE ) );
-   }
 
-   demux->filepos = stream_tell( demux->stream );
-   readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
-   if ( readSize != CHUNKSIZE )
+      demux->filepos = stream_tell( demux->stream );
+      tivo->whichChunk = demux->filepos / CHUNKSIZE;
+      readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+      if ( readSize != CHUNKSIZE )
+      {
+         return( 0 );
+      }
+   }
+   else
    {
-      return( 0 );
+      readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, 
+         tivo->whichChunk );
+      if ( readSize != CHUNKSIZE )
+      {
+         return( 0 );
+      }
+      tivo->whichChunk++;
    }
 
    // We found a part header, skip it
    pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] );
    if( pesFileId == TIVO_PES_FILEID )
    {
-      demux->filepos = stream_tell( demux->stream );
       mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" );
-      readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+      if ( tivo->tmf != 1 )
+      {
+         demux->filepos = stream_tell( demux->stream );
+         readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
+      }
+      else
+      {
+         readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, 
+            tivo->whichChunk );
+         tivo->whichChunk++;
+      }
+
       if ( readSize != CHUNKSIZE )
       {
          return( 0 );
@@ -545,6 +874,7 @@
    // ======================================================================
    // Finally, we get to actually parse the chunk
    // ======================================================================
+   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" );
    numberRecs = chunk[ 0 ];
    recPtr = &chunk[ 4 ];
    offset = ( numberRecs * 16 ) + 4;
@@ -815,17 +1145,20 @@
 
 			mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:CC %x %x\n", b1, b2 );
 
-			buffer[ 0x00 ] = 0x00;
-			buffer[ 0x01 ] = 0x00;
-			buffer[ 0x02 ] = 0x01;
-			buffer[ 0x03 ] = 0xb2;
-			buffer[ 0x04 ] = 'T';
-			buffer[ 0x05 ] = 'Y';
-			buffer[ 0x06 ] = 0x01;
-			buffer[ 0x07 ] = b1;
-			buffer[ 0x08 ] = b2;
-			demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, buffer, 0x09,
-				( demux->filepos + offset ), tivo->lastVideoPTS );
+			lastCC[ 0x00 ] = 0x00;
+			lastCC[ 0x01 ] = 0x00;
+			lastCC[ 0x02 ] = 0x01;
+			lastCC[ 0x03 ] = 0xb2;
+			lastCC[ 0x04 ] = 'T';
+			lastCC[ 0x05 ] = 'Y';
+			lastCC[ 0x06 ] = 0x01;
+			lastCC[ 0x07 ] = b1;
+			lastCC[ 0x08 ] = b2;
+         if ( subcc_enabled )
+         {
+			   demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, lastCC, 0x09,
+  				   ( demux->filepos + offset ), tivo->lastVideoPTS );
+         }
 		}
       // ================================================================
       // Extended Data Services
@@ -845,17 +1178,20 @@
 
          mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:XDS %x %x\n", b1, b2 );
 
-			buffer[ 0x00 ] = 0x00;
-			buffer[ 0x01 ] = 0x00;
-			buffer[ 0x02 ] = 0x01;
-			buffer[ 0x03 ] = 0xb2;
-			buffer[ 0x04 ] = 'T';
-			buffer[ 0x05 ] = 'Y';
-			buffer[ 0x06 ] = 0x02;
-			buffer[ 0x07 ] = b1;
-			buffer[ 0x08 ] = b2;
-			demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, buffer, 0x09,
-				( demux->filepos + offset ), tivo->lastVideoPTS );
+			lastXDS[ 0x00 ] = 0x00;
+			lastXDS[ 0x01 ] = 0x00;
+			lastXDS[ 0x02 ] = 0x01;
+			lastXDS[ 0x03 ] = 0xb2;
+			lastXDS[ 0x04 ] = 'T';
+			lastXDS[ 0x05 ] = 'Y';
+			lastXDS[ 0x06 ] = 0x02;
+			lastXDS[ 0x07 ] = b1;
+			lastXDS[ 0x08 ] = b2;
+         if ( subcc_enabled )
+         {
+			   demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, lastXDS, 0x09,
+				   ( demux->filepos + offset ), tivo->lastVideoPTS );
+         }
 		}
       // ================================================================
       // Found a 0x03 on Droid's TiVo, I have no idea what it is
@@ -868,6 +1204,16 @@
 			}
 		}
       // ================================================================
+      // Found a 0x03 on Hermit's TiVo, I have no idea what it is
+      // ================================================================
+		else if ( type == 0x03 )
+		{
+         if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) )
+         {
+            offset += size;
+			}
+		}
+      // ================================================================
       // Unknown
       // ================================================================
 		else if ( type == 0x05 )
@@ -913,6 +1259,8 @@
    return( 1 );
 }
 
+extern off_t seek_to_byte;
+
 void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, int flags )
 {
    demux_stream_t *d_audio = demuxer->audio;
@@ -972,11 +1320,14 @@
       newpos = res * CHUNKSIZE;
    }
 
-   if ( newpos < 0 )
+   if ( newpos < seek_to_byte )
    {
-      newpos = 0;
+      newpos = seek_to_byte;
    }
-   stream_seek( demuxer->stream, newpos  );
+
+   tivo->whichChunk = newpos / CHUNKSIZE;
+
+   stream_seek( demuxer->stream, newpos );
 
    // re-sync video:
    videobuf_code_len = 0; // reset ES stream buffer
diff -Nur main.sofar/libmpdemux/demuxer.c main.dev/libmpdemux/demuxer.c
--- main.sofar/libmpdemux/demuxer.c	2004-07-16 20:31:17.000000000 +0000
+++ main.dev/libmpdemux/demuxer.c	2004-08-11 03:18:37.615937600 +0000
@@ -941,6 +941,18 @@
       demuxer = NULL;
   }
 }
+//=============== Try to open as MPEG-TY file: =================
+if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_TY)
+{
+  demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_TY,audio_id,video_id,dvdsub_id);
+  if(ds_fill_buffer(demuxer->video)){
+      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"TiVo (DeMuxer By WyngNut)");
+      file_format=DEMUXER_TYPE_MPEG_TY;
+  } else {
+      free_demuxer(demuxer);
+      demuxer = NULL;
+  }
+}
 //=============== Try to open as MPEG-PS file: =================
 if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_PS){
  int pes=1;
diff -Nur main.sofar/libmpdemux/network.c main.dev/libmpdemux/network.c
--- main.sofar/libmpdemux/network.c	2004-08-02 18:01:55.000000000 +0000
+++ main.dev/libmpdemux/network.c	2004-08-11 03:18:37.655995200 +0000
@@ -43,6 +43,7 @@
 
 extern int mp_input_check_interrupt(int time);
 
+int ty_streaming_start( stream_t *stream );
 int asf_streaming_start( stream_t *stream, int *demuxer_type );
 int rtsp_streaming_start( stream_t *stream );
 
@@ -717,6 +718,11 @@
 			return 0;
 		}
 
+		if( !strncasecmp(url->protocol, "tivo", 2) ) {
+			*file_format = DEMUXER_TYPE_MPEG_TY;
+			return 0;
+		}
+
 		// HTTP based protocol
 		if( !strcasecmp(url->protocol, "http") || !strcasecmp(url->protocol, "http_proxy") ) {
 			fd = http_send_request( url, 0 );
@@ -1322,6 +1328,17 @@
 				mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
 			}
 			break;
+#ifdef STREAMTYPE_STREAM_TY
+		case DEMUXER_TYPE_MPEG_TY:
+ 		   stream->type = STREAMTYPE_STREAM_TY;
+         ret = ty_streaming_start( stream );
+			if( ret<0 ) {
+				mp_msg(MSGT_NETWORK,MSGL_ERR,"ty_streaming_start failed\n");
+			}
+			if((*demuxer_type) == DEMUXER_TYPE_PLAYLIST)
+			  stream->type = STREAMTYPE_PLAYLIST;
+         break;
+#endif
 		default:
 			mp_msg(MSGT_NETWORK,MSGL_ERR,"Unable to detect the streaming type\n");
 			ret = -1;
@@ -1348,3 +1365,164 @@
 	stream->streaming_ctrl->status = streaming_stopped_e;
 	return 0;
 }
+
+#ifdef STREAMTYPE_STREAM_TY
+/*
+ * tivo at wingert.org, February 2003
+ *
+ * Copyright (C) 2003 Christopher R. Wingert
+ *
+ * The license covers the portions of this file regarding TiVo additions.
+ *
+ * Olaf Beck and Tridge (indirectly) were essential at providing 
+ * information regarding the format of the TiVo streams.  
+ *
+ * However, no code in the following subsection is directly copied from 
+ * either author.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+int vstream_start( char *ipaddress );
+int vstream_startstream( char *fsid );
+off_t vstream_streamsize( );
+int vstream_list_streams( int longList );
+int vstream_load_chunk( char *fsid, unsigned char *buff, int size, off_t offset );
+#define CHUNKSIZE    ( 128 * 1024 )
+
+int ty_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) 
+{
+   char   *ptr;
+	int    len = 0;
+   off_t  pos;
+
+   ptr = stream_ctrl->url->file;
+   if ( *ptr == '/' )
+   {
+      *ptr++;
+   }
+
+   pos = *( (off_t *)stream_ctrl->data );
+
+   if ( ( pos + size ) > vstream_streamsize() )
+   {
+      size = vstream_streamsize() - pos;
+   }
+
+   if ( size > 0 )
+   {
+
+      if( stream_ctrl->buffer_size != 0 ) 
+      {
+         int buffer_len = stream_ctrl->buffer_size-stream_ctrl->buffer_pos;
+         len = ( size < buffer_len ) ? size : buffer_len;
+         memcpy( buffer, ( stream_ctrl->buffer + stream_ctrl->buffer_pos ), 
+            len );
+         stream_ctrl->buffer_pos += len;
+         if( stream_ctrl->buffer_pos >= stream_ctrl->buffer_size ) 
+         {
+            free( stream_ctrl->buffer );
+            stream_ctrl->buffer = NULL;
+            stream_ctrl->buffer_size = 0;
+            stream_ctrl->buffer_pos = 0;
+         }
+      }
+
+      if( len < size ) 
+      {
+         int ret;
+         stream_ctrl->buffer = malloc( CHUNKSIZE + 1 );
+         stream_ctrl->buffer_size = CHUNKSIZE;
+         stream_ctrl->buffer_pos = 0;
+         ret = vstream_load_chunk( ptr, stream_ctrl->buffer, CHUNKSIZE, 
+            *( (off_t *)stream_ctrl->data ) );
+         *( (off_t *)stream_ctrl->data ) += CHUNKSIZE;
+         if ( ret < 0 ) 
+         {
+            mp_msg( MSGT_NETWORK,MSGL_ERR, "ty_streaming_read error\n" );
+         }
+         else
+         {
+            memcpy( &buffer[ len ], stream_ctrl->buffer, ( size - len ) );
+            stream_ctrl->buffer_pos += ( size - len );
+            len = size;
+         }
+      }
+   }
+   
+	return len;
+}
+
+int ty_streaming_seek( int fd, off_t pos, streaming_ctrl_t *stream_ctrl ) 
+{
+   *( (off_t *)stream_ctrl->data ) = pos;
+	return 0;
+	// To shut up gcc warning
+	fd++;
+	// pos++;
+	// stream_ctrl=NULL;
+}
+
+int ty_streaming_start( stream_t *stream ) 
+{
+   char *ptr;
+
+   vstream_start( stream->streaming_ctrl->url->hostname );
+
+   ptr = stream->streaming_ctrl->url->file;
+   if ( *ptr == '/' )
+   {
+      *ptr++;
+   }
+
+   if ( strcmp( ptr, "list" ) == 0 )
+   {
+      vstream_list_streams( 0 );
+      return( -1 );
+   }
+
+   if ( strcmp( ptr, "llist" ) == 0 )
+   {
+      vstream_list_streams( 1 );
+      return( -1 );
+   }
+
+   printf( "Starting to stream from a TiVo %s file %s\n", 
+      stream->streaming_ctrl->url->hostname, ptr );
+
+	stream->streaming_ctrl->streaming_read = ty_streaming_read;
+	stream->streaming_ctrl->streaming_seek = ty_streaming_seek;
+	stream->streaming_ctrl->prebuffer_size = CHUNKSIZE;
+	stream->streaming_ctrl->buffering = 1;
+	stream->streaming_ctrl->status = streaming_playing_e;
+   stream->fd = 255;
+	stream->streaming_ctrl->data = malloc( sizeof( off_t ) );
+   *( (off_t *)stream->streaming_ctrl->data ) = 0;
+
+   if ( vstream_startstream( ptr ) == 0 )
+   {
+      return( -1 );
+   }
+
+   stream->start_pos = 0;
+   stream->end_pos = vstream_streamsize();
+
+	return ( 0 );
+}
+#endif
+
+
diff -Nur main.sofar/libmpdemux/stream.c main.dev/libmpdemux/stream.c
--- main.sofar/libmpdemux/stream.c	2004-03-13 16:10:02.000000000 +0000
+++ main.dev/libmpdemux/stream.c	2004-08-11 03:18:37.686038400 +0000
@@ -188,6 +188,9 @@
     break;
 #endif    
   case STREAMTYPE_STREAM:
+#ifdef STREAMTYPE_STREAM_TY
+  case STREAMTYPE_STREAM_TY:
+#endif
 #ifdef MPLAYER_NETWORK
     if( s->streaming_ctrl!=NULL ) {
 	    len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl);break;
@@ -242,6 +245,9 @@
   switch(s->type){
   case STREAMTYPE_SMB:
   case STREAMTYPE_STREAM:
+#ifdef STREAMTYPE_STREAM_TY
+  case STREAMTYPE_STREAM_TY:
+#endif
 #ifdef _LARGEFILE_SOURCE
     newpos=pos&(~((long long)STREAM_BUFFER_SIZE-1));break;
 #else
@@ -338,6 +344,30 @@
     }
 #endif
     break;
+#ifdef STREAMTYPE_STREAM_TY
+  case STREAMTYPE_STREAM_TY:
+    //s->pos=newpos; // real seek
+    // Some streaming protocol allow to seek backward and forward
+    // A function call that return -1 can tell that the protocol
+    // doesn't support seeking.
+#ifdef STREAMING
+    if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_seek ) {
+      if( s->streaming_ctrl->streaming_seek( s->fd, newpos, s->streaming_ctrl )<0 ) {
+        mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n");
+        return 1;
+      }
+    } 
+#else
+    if(newpos<s->pos){
+      mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n");
+      return 1;
+    }
+    while(s->pos<newpos){
+      if(stream_fill_buffer(s)<=0) break; // EOF
+    }
+#endif
+    break;
+#endif
   default:
     // This should at the beginning as soon as all streams are converted
     if(!s->seek)
diff -Nur main.sofar/libmpdemux/stream.h main.dev/libmpdemux/stream.h
--- main.sofar/libmpdemux/stream.h	2004-03-13 16:10:02.000000000 +0000
+++ main.dev/libmpdemux/stream.h	2004-08-11 03:18:37.706067200 +0000
@@ -19,9 +19,24 @@
 #define STREAMTYPE_SMB 11      // smb:// url, using libsmbclient (samba)
 #define STREAMTYPE_VCDBINCUE 12      // vcd directly from bin/cue files
 #define STREAMTYPE_DVB 13
+#ifdef HAVE_VSTREAM
+#define STREAMTYPE_STREAM_TY 14
+#endif
+
+#define TY_STREAM_BUFFER_SIZE ( 128 * 1024 )
 
 #define STREAM_BUFFER_SIZE 2048
 
+#ifdef HAVE_VSTREAM
+// SET STREAM_MAX_BUFFER to the largest of
+// STREAM_BUFFER_SIZE, VCD_SECTOR_SIZE, TY_STREAM_BUFFER_SIZE
+// or whatever type of stream you add
+#define STREAM_MAX_BUFFER ( TY_STREAM_BUFFER_SIZE )
+#else
+#define STREAM_MAX_BUFFER ( STREAM_BUFFER_SIZE )
+#endif
+
+
 #define VCD_SECTOR_SIZE 2352
 #define VCD_SECTOR_OFFS 24
 #define VCD_SECTOR_DATA 2324
@@ -96,7 +111,7 @@
 #ifdef MPLAYER_NETWORK
   streaming_ctrl_t *streaming_ctrl;
 #endif
-  unsigned char buffer[STREAM_BUFFER_SIZE>VCD_SECTOR_SIZE?STREAM_BUFFER_SIZE:VCD_SECTOR_SIZE];
+  unsigned char buffer[ STREAM_MAX_BUFFER ];
 } stream_t;
 
 #ifdef USE_STREAM_CACHE
diff -Nur main.sofar/mencoder.c main.dev/mencoder.c
--- main.sofar/mencoder.c	2004-07-16 20:31:16.000000000 +0000
+++ main.dev/mencoder.c	2004-08-11 03:18:37.736110400 +0000
@@ -254,7 +254,7 @@
 }
 
 static char *seek_to_sec=NULL;
-static off_t seek_to_byte=0;
+off_t seek_to_byte=0;
 
 static int parse_end_at(m_option_t *conf, const char* param);
 //static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
diff -Nur main.sofar/mplayer.c main.dev/mplayer.c
--- main.sofar/mplayer.c	2004-08-11 03:18:28.182372800 +0000
+++ main.dev/mplayer.c	2004-08-11 03:18:37.776168000 +0000
@@ -222,7 +222,7 @@
 
 // seek:
 static char *seek_to_sec=NULL;
-static off_t seek_to_byte=0;
+off_t seek_to_byte=0;
 static off_t step_sec=0;
 static int loop_times=-1;
 static int loop_seek=0;
diff -Nur main.sofar/vstream/Makefile main.dev/vstream/Makefile
--- main.sofar/vstream/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/Makefile	2004-08-11 03:18:37.796196800 +0000
@@ -0,0 +1,48 @@
+
+LIBNAME = vstream.a
+
+include ../config.mak
+
+SRCS = mfs.c object.c schema.c query.c util.c bitmap.c io.c partition.c crc.c  vstream.c
+
+OBJS	= $(SRCS:.c=.o)
+OBJS   += $(CPLUSPLUSSRCS:.cpp=.o)
+INCLUDE = -I..
+CFLAGS  = $(OPTFLAGS) $(INCLUDE) $(XMMS_CFLAGS) $(CDPARANOIA_INC) $(EXTRA_INC)
+CPLUSPLUSFLAGS  = $(CFLAGS) $(CPLUSPLUSINCLUDE)
+CPLUSPLUS = $(CC)
+
+.SUFFIXES: .c .cpp .o
+
+# .PHONY: all clean
+
+all:	$(LIBNAME)
+
+.c.o:
+	$(CC) -c $(CFLAGS) -o $@ $<
+.cpp.o:
+	$(CPLUSPLUS) -c $(CPLUSPLUSFLAGS) -o $@ $<
+
+$(LIBNAME):	$(OBJS)
+	$(AR) r $(LIBNAME) $(OBJS)
+
+test: $(LIBNAME) test.c
+	$(CC) $(CFLAGS) test.c $(LIBNAME) -o test
+
+clean:
+	rm -f *.o *.a *~
+
+distclean:
+	rm -f test Makefile.bak *.o *.a *~ .depend
+
+dep:    depend
+
+depend:
+	$(CC) -MM $(CFLAGS) test.c $(SRCS) 1>.depend
+
+#
+# include dependency files if they exist
+#
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff -Nur main.sofar/vstream/README main.dev/vstream/README
--- main.sofar/vstream/README	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/README	2004-08-11 03:18:37.866297600 +0000
@@ -0,0 +1,80 @@
+use mfs_streams to find what video stream files are on your tivo
+
+use vplay to "play" with that fsid to a file or device
+
+use vplayer to play files remotely
+
+mfs_ls lists directories. Use -R for recursive listing. Use -l to 
+include sizes.
+
+mfs_dumpobj dumps a TiVo object
+
+mfs_export exports files (of any type) from the mfs to a unix file
+
+mfs_info dumps some basic info on your fs and a fsid
+
+mfs_dump dumps some sectors (useful for debugging)
+
+The Makefile builds both i386 and tivo binaries. To build just the
+i386 binaries run "make host". Similarly for "make tivo". A simple
+"make" will build everything.
+
+Running the tivo binaries is easy, just copy them to your tivo and
+make sure MFS_DEVICE is set correctly before starting them. You should
+find that MFS_DEVICE is set by the tivo startup scripts, usually to
+/dev/hda10. 
+
+Running the binaries on a Linux PC is a bit different. The main thing
+you need to get right is the MFS_DEVLIST environment variable. Setting
+that allows you to run mfs commands against either a locally
+accesssible TiVo drive or a remote TiVo accessed across a TCP link. 
+
+To run on a local drive (or files containing images of a drive) you
+set MFS_DEVLIST to a space separated list of files/devices containing
+the MFS filesystem. For example:
+   export MFS_DEVLIST="/backup/hda10 /backup/hda11_aa /backup/hda11_ab"
+(Don't forget the export!) Then run the mfs_* commands as usual.
+
+To run on a remote TiVo you need to start a tivo vserver binary on the
+TiVo. Then on your Linux PC set MFS_DEVLIST to :hostname where
+hostname is the IP or hostname of your TiVo. Then run the mfs commands
+as usual.
+
+You can also point MFS_DEVLIST at a raw TiVo disk, and the mfs code
+will look in the TiVo partition table to find the MFS partitions. 
+
+
+###############################################################################
+ppchacker, 1/18/2001.  Made the following changes:
+
+    open MFS_DEV read-only (makes me feel safer)
+
+	[this change not committed to the CVS tree]
+
+    new API mfs_read_chunk(): fast read of video stream
+
+    new API io_get_need_bswap() so mfs_read_chunk() and outside users can
+    find out if byte-swapping is going on
+
+    new API mfs_get_attribute(); differs from current query routines in that it
+    returns an entire array of values, not just the first element in the array.
+
+    mfs.c / load_super reads a sector into a variable which is less then
+    a sector in size.  Change the link-order and you see random behavior.
+    I'm not entirely happy with the current patch, but it works.
+
+    preload the schema built-in to the program; avoids having to have
+    schema.txt around.	Note that in v2.5 it is NOT possible to dynamically
+    load the schema from /ObjectType -- they removed this feature.  Probably so
+    we won't see the "CommercialSkipOffset" aka "ScrambleKey" attribute on the
+    RecordingPart (-: You can reenable the old behavior with -DLOAD_FROM_FILE.
+    Thanks to mbm for supplying schema.tcl, which was run on the tivo to
+    create schema.tcl.out, then processed with make-preoload-schema.pl and
+    manually inserted into preload_schema.h.
+
+    first attempt at creating a real "package" with internal and external
+    header files to integrate into my environment better.  Change was to
+    move some symbols / includes into mfs_int.h and remove them from mfs.h
+
+	[this change not committed to the CVS tree]
+
diff -Nur main.sofar/vstream/bitmap.c main.dev/vstream/bitmap.c
--- main.sofar/vstream/bitmap.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/bitmap.c	2004-08-11 03:18:37.886326400 +0000
@@ -0,0 +1,52 @@
+#include "mfs.h"
+
+/****************************************************************************
+allocate a bitmap of the specified size
+****************************************************************************/
+struct bitmap *vstream_bitmap_allocate(int n)
+{
+	struct bitmap *bm;
+
+	bm = (struct bitmap *)malloc(sizeof(*bm));
+
+	if (!bm) return NULL;
+	
+	bm->n = n;
+	bm->b = (u32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
+	if (!bm->b) {
+		free(bm);
+		return NULL;
+	}
+
+	memset(bm->b, 0, sizeof(bm->b[0])*(n+31)/32);
+
+	return bm;
+}
+
+/****************************************************************************
+set a bit in a bitmap
+****************************************************************************/
+void vstream_bitmap_set(struct bitmap *bm, unsigned i, unsigned n)
+{
+	if (i+n > bm->n) {
+		printf("Invalid bitmap set bits=%d i=%d n=%d\n",
+		       bm->n, i, n);
+		exit(1);
+	}
+	while (n--) {
+		bm->b[i/32] |= (1<<((31-i)%32));
+		i++;
+	}
+}
+
+
+/****************************************************************************
+query a bit in a bitmap
+****************************************************************************/
+int vstream_bitmap_query(struct bitmap *bm, unsigned i)
+{
+	if (bm->b[i/32] & (1<<((31-i)%32))) {
+		return 1;
+	}
+	return 0;
+}
diff -Nur main.sofar/vstream/crc.c main.dev/vstream/crc.c
--- main.sofar/vstream/crc.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/crc.c	2004-08-11 03:18:37.926384000 +0000
@@ -0,0 +1,149 @@
+#include "mfs.h"
+
+/*
+ *  Crc - 32 BIT ANSI X3.66 CRC checksum files
+ */
+
+/*
+ * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms.  The  */
+/* polynomial is                                                       */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in  */
+/* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
+/* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
+/* the MSB being 1.                                                    */
+
+/* Note that the usual hardware shift register implementation, which   */
+/* is what we're using (we're merely optimizing it by doing eight-bit  */
+/* chunks at a time) shifts bits into the lowest-order term.  In our   */
+/* implementation, that means shifting towards the right.  Why do we   */
+/* do it this way?  Because the calculated CRC must be transmitted in  */
+/* order from highest-order term to lowest-order term.  UARTs transmit */
+/* characters in order from LSB to MSB.  By storing the CRC this way,  */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part.  Reception works similarly.                  */
+
+/* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
+/*                                                                     */
+/*  1. The table can be generated at runtime if desired; code to do so */
+/*     is shown later.  It might not be obvious, but the feedback      */
+/*     terms simply represent the results of eight shift/xor opera-    */
+/*     tions for all combinations of data and CRC register values.     */
+/*                                                                     */
+/*  2. The CRC accumulation logic is the same for all CRC polynomials, */
+/*     be they sixteen or thirty-two bits wide.  You simply choose the */
+/*     appropriate table.  Alternatively, because the table can be     */
+/*     generated at runtime, you can start by generating the table for */
+/*     the polynomial in question and use exactly the same "updcrc",   */
+/*     if your application needn't simultaneously handle two CRC       */
+/*     polynomials.  (Note, however, that XMODEM is strange.)          */
+/*                                                                     */
+/*  3. For 16-bit CRCs, the table entries need be only 16 bits wide;   */
+/*     of course, 32-bit entries work OK if the high 16 bits are zero. */
+/*                                                                     */
+/*  4. The values must be right-shifted by eight bits by the "updcrc"  */
+/*     logic; the shift must be unsigned (bring in zeroes).  On some   */
+/*     hardware you could probably optimize the shift in assembler by  */
+/*     using byte-swap instructions.                                   */
+
+static long crc32tab[] = { /* CRC polynomial 0xedb88320 */
+
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
+ *  NOTE: First argument must be in range 0 to 255.
+ *        Second argument is referenced twice.
+ * 
+ * Programmers may incorporate any or all code into their programs, 
+ * giving proper credit within the source. Publication of the 
+ * source routines is permitted so long as proper credit is given 
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
+ * Omen Technology.
+ */
+
+/* #define UPDC32(octet, crc) (crc32tab[((int)(crc) ^ octet) & 0xff] ^ (((crc) >> 8) & 0x00FFFFFF)) */
+#define UPDC32(octet, crc) (crc32tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
+
+static u32 crc32(const unsigned char *bytes,int length)
+{
+	int i;
+	unsigned ret;
+
+	for (ret=0,i=0;i<length;i++) {
+		ret=UPDC32(bytes[i], ret);
+	}
+	
+	return(ret);
+}
+
+int vstream_check_crc(void *buf, int length, u32 *crc)
+{
+	u32 crc_saved = ntohl(*crc);
+	u32 new;
+
+	*crc = htonl(MFS_CRC_BASE);
+	new = crc32(buf, length);
+	if (new != crc_saved) {
+		printf("crc mismatch len=%d 0x%08x 0x%08x\n", length, crc_saved, new);
+	}
+	*crc = htonl(crc_saved);
+	return new == crc_saved ? 1 : 0;
+}
+
+void vstream_auto_crc(void *buf, int max_length, u32 *crc)
+{
+	u32 crc_saved = ntohl(*crc);
+	u32 new;
+	int length;
+
+	*crc = htonl(MFS_CRC_BASE);
+	for (length=4; length <= max_length; length += 1) {
+		new = crc32(buf, length);
+		if (new == crc_saved) {
+			printf("XXXXX auto crc match len=%d 0x%08x\n", 
+			       length, new);
+			break;
+		}
+	}
+	*crc = htonl(crc_saved);
+}
diff -Nur main.sofar/vstream/darwin_dlfcn.h main.dev/vstream/darwin_dlfcn.h
--- main.sofar/vstream/darwin_dlfcn.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/darwin_dlfcn.h	2004-08-11 03:18:37.956427200 +0000
@@ -0,0 +1,58 @@
+/* $Revision: 1.1 $ */
+/*
+ * This file was modified by Christoph Pfisterer <cp at chrisp.de>
+ * on Sat, May 5 2001. See the file "ChangeLog" for details of what
+ * was changed.
+ *
+ *
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void * dlopen(
+    const char *path,
+    int mode);
+extern void * dlsym(
+    void * handle,
+    const char *symbol);
+extern const char * dlerror(
+    void);
+extern int dlclose(
+    void * handle);
+
+#define RTLD_LAZY	0x1
+#define RTLD_NOW	0x2
+#define RTLD_LOCAL	0x4
+#define RTLD_GLOBAL	0x8
+#define RTLD_NOLOAD	0x10
+#define RTLD_SHARED	0x20	/* not used, the default */
+#define RTLD_UNSHARED	0x40
+#define RTLD_NODELETE	0x80
+#define RTLD_LAZY_UNDEF	0x100
+
+#ifdef __cplusplus
+}
+#endif
diff -Nur main.sofar/vstream/darwin_getopt.h main.dev/vstream/darwin_getopt.h
--- main.sofar/vstream/darwin_getopt.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/darwin_getopt.h	2004-08-11 03:18:38.016513600 +0000
@@ -0,0 +1,147 @@
+/* Declarations for getopt.
+   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#if defined(WIN32)
+#ifdef _DLL
+#ifdef MAKE_KPSE_DLL
+#define KPSEDLL __declspec( dllexport)
+#else
+#define KPSEDLL __declspec( dllimport)
+#endif
+#else
+#define KPSEDLL
+#endif
+#else /* ! WIN32 */
+#define KPSEDLL
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern KPSEDLL char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern KPSEDLL int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern KPSEDLL int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern KPSEDLL int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern KPSEDLL int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern KPSEDLL int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern KPSEDLL int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern KPSEDLL int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern KPSEDLL int getopt ();
+extern KPSEDLL int getopt_long ();
+extern KPSEDLL int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff -Nur main.sofar/vstream/darwin_unistd.h main.dev/vstream/darwin_unistd.h
--- main.sofar/vstream/darwin_unistd.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/darwin_unistd.h	2004-08-11 03:18:38.046556800 +0000
@@ -0,0 +1,8 @@
+#ifndef _LIBSA_UNISTD_H_
+#define _LIBSA_UNISTD_H_
+
+
+#define getpagesize()    PAGE_SIZE
+
+
+#endif /* _LIBSA_UNISTD_H_ */
diff -Nur main.sofar/vstream/io.c main.dev/vstream/io.c
--- main.sofar/vstream/io.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/io.c	2004-08-11 03:18:38.076600000 +0000
@@ -0,0 +1,344 @@
+/*
+  media-filesystem library, io routines
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+
+static int readahead_enabled;
+static int vserver = -1;
+static int need_bswap;
+static int verbose;
+static u32 total_size;
+static char *dev_list;
+extern char *mfs_dev;
+
+void vstream_mfs_readahead(int set)
+{
+	readahead_enabled = set;
+}
+
+static void vserver_read_req(u32 sec, u32 count)
+{
+	struct vserver_cmd cmd;
+
+	cmd.command = htonl(MFS_CMD_READ);
+	cmd.param1 = htonl(sec);
+	cmd.param2 = htonl(count);
+	vstream_write_all(vserver, &cmd, sizeof(cmd));
+}
+
+static void vserver_receive(void *buf, u32 count)
+{
+	count <<= SECTOR_SHIFT;
+	vstream_read_all(vserver, buf, count);
+}
+
+#define RA_BLOCKS	256
+#define RA_MIN		256
+
+static void vserver_vstream_read_sectors(void *buf, u32 sec, u32 count)
+{
+	static struct mfs_run readahead;
+	u32 discard, coming;
+
+	if (count == 0)
+		return;
+
+	discard = coming = 0;
+	if (sec >= readahead.start && sec < readahead.start + readahead.len) {
+		discard = sec - readahead.start;
+		coming = readahead.len - discard;
+		if (coming <= count) {
+			readahead.len = 0;
+		} else {
+			readahead.start = sec + count;
+			readahead.len -= discard + count;
+		}
+	} else {
+		discard = readahead.len;
+		coming = 0;
+		readahead.len = 0;
+	}
+
+	if (coming < count) {
+		u32 nreq = count - coming;
+		if (readahead_enabled && nreq < RA_BLOCKS) {
+			readahead.start = sec + count;
+			readahead.len = RA_BLOCKS - nreq;
+			nreq = RA_BLOCKS;
+		}
+		vserver_read_req(sec + coming, nreq);
+	}
+
+	if (readahead.len <= RA_MIN && readahead_enabled) {
+		if (readahead.len == 0)
+			readahead.start = sec + count;
+		vserver_read_req(readahead.start + readahead.len, RA_BLOCKS);
+		readahead.len += RA_BLOCKS;
+	}
+
+	if (discard) {
+		void *buf2 = malloc(discard << SECTOR_SHIFT);
+		vserver_receive(buf2, discard);
+		free(buf2);
+	}
+
+	vserver_receive(buf, count);
+
+	if (need_bswap) {
+		u16 *v = (u16 *)buf;
+		int i;
+		for (i=0;i<count<<(SECTOR_SHIFT-1);i++)
+			v[i] = ntohs(v[i]);
+	}
+}
+
+static void vserver_vstream_write_sectors(void *buf, u32 sec, u32 count)
+{
+	struct vserver_cmd cmd;
+
+	if (readahead_enabled) {
+		printf("vserver write not supported with readahead\n");
+		exit(1);
+	}
+
+	cmd.command = htonl(MFS_CMD_WRITE);
+	cmd.param1 = htonl(sec);
+	cmd.param2 = htonl(count);
+	vstream_write_all(vserver, &cmd, sizeof(cmd));
+	vstream_write_all(vserver, buf, count*SECTOR_SIZE);
+}
+
+static void vserver_zero_sectors(u32 sec, u32 count)
+{
+	struct vserver_cmd cmd;
+
+	if (readahead_enabled) {
+		printf("vserver write not supported with readahead\n");
+		exit(1);
+	}
+
+	cmd.command = htonl(MFS_CMD_ZERO);
+	cmd.param1 = htonl(sec);
+	cmd.param2 = htonl(count);
+	vstream_write_all(vserver, &cmd, sizeof(cmd));
+}
+
+/* this holds the list of block devices in the tivo */
+static struct {
+	char *dev;
+	unsigned long sectors;
+	int fd;
+} devs[MAX_DEVS];
+
+/* read from the virtual tivo disk (ie. all partitions 
+   concatenated) */
+void mfs_vstream_read_sectors(void *buf, u32 sec, u32 count)
+{
+	int i;
+	loff_t start=0;
+	
+	if (vserver != -1) {
+		vserver_vstream_read_sectors(buf, sec, count);
+		return;
+	}
+
+	sec = vstream_partition_remap(sec);
+
+	for (i=0; devs[i].dev; i++) {
+		if (sec < start + devs[i].sectors) break;
+		start += devs[i].sectors;
+	}
+	if (!devs[i].dev) {
+		fprintf(stderr,"Failed to map sector %d\n", sec);
+		exit(1);
+	}
+
+	if (verbose) {
+		printf("mapped %d to %s/%d\n", sec, devs[i].dev, (int)(sec-start));
+	}
+
+	vstream_read_sectors(devs[i].fd, buf, sec-start, count);
+
+	if (need_bswap) {
+		u16 *v = (u16 *)buf;
+		for (i=0;i<count<<(SECTOR_SHIFT-1);i++) v[i] = ntohs(v[i]);
+	}
+}
+
+
+/* write to the virtual tivo disk (ie. all partitions 
+   concatenated) */
+void mfs_vstream_write_sectors(void *buf, u32 sec, u32 count)
+{
+	int i;
+	loff_t start=0;
+	
+	if (vserver != -1) {
+		vserver_vstream_write_sectors(buf, sec, count);
+		return;
+	}
+
+	sec = vstream_partition_remap(sec);
+
+	for (i=0; devs[i].dev; i++) {
+		if (sec < start + devs[i].sectors) break;
+		start += devs[i].sectors;
+	}
+	if (!devs[i].dev) {
+		fprintf(stderr,"Failed to map sector %d\n", sec);
+		exit(1);
+	}
+
+	if (verbose) {
+		printf("mapped %d to %s/%d\n", sec, devs[i].dev, (int)(sec-start));
+	}
+
+	vstream_write_sectors(devs[i].fd, buf, sec-start, count);
+}
+
+
+void vstream_mfs_zero_sectors(int sector, int count)
+{
+	int chunk_size=512;
+	char buf[chunk_size*512];
+	char buf1[chunk_size*512];
+	int total=0;
+
+	if (vserver != -1) {
+		vserver_zero_sectors(sector, count);
+		return;
+	}
+
+	bzero(buf, chunk_size*512);
+
+	printf("wiping %d sectors at %d\n", count, sector);
+
+	while (total<count) {
+		int n = MIN(chunk_size, count);
+		mfs_vstream_read_sectors(buf1, sector, n);
+		if (memcmp(buf, buf1, n*SECTOR_SIZE)) {
+			mfs_vstream_write_sectors(buf, sector, n);
+		}
+		sector += n;
+		total += n;
+		printf("%3.1f%%\r", 100.0*total/count);
+		fflush(stdout);
+	}
+	printf("%3.1f%%\n", 100.0*total/count);
+}
+
+
+/* initialise the devices list from the superblock devlist */
+void vstream_load_devs(char *devlist)
+{
+	char *p;
+	int i=0, len;
+
+	if (dev_list) devlist = dev_list;
+
+	if (vserver != -1) return;
+
+	total_size = 0;
+
+	while (1) {
+		p = strchr(devlist, ' ');
+		if (!p) {
+			len = strlen(devlist);
+		} else {
+			len = (int)(p-devlist);
+		}
+		devs[i].dev = (char *)malloc(len+1);
+		strncpy(devs[i].dev, devlist, len);
+		devs[i].dev[len] = 0;
+		devs[i].fd = open(devs[i].dev, O_RDWR|O_LARGEFILE);
+		if (devs[i].fd == -1) {
+			printf("failed to open [%s]\n", devs[i].dev);
+			break;
+		}
+		devs[i].sectors = vstream_llseek(devs[i].fd, 0, SEEK_END) >> SECTOR_SHIFT;
+		if (devs[i].sectors == 0) {
+			ioctl(devs[i].fd, BLKGETSIZE, &devs[i].sectors);
+		}
+		devs[i].sectors &= ~(MFS_BLOCK_ROUND-1);
+		total_size += devs[i].sectors;
+		i++;
+		devlist += len+1;
+		if (!p) break;
+	}	
+}
+
+void vstream_add_dev_map(char *mapping)
+{
+	char *p;
+
+	if (mapping[0] == ':') {
+		vserver = vstream_vstream_open_socket_out(mapping+1, VSERVER_PORT);
+		if (vserver == -1) {
+			fprintf(stderr,"Failed to connect to %s\n", mapping+1);
+			exit(1);
+		}
+		return;
+	}
+
+	dev_list = strdup(mapping);
+	mfs_dev = strdup(dev_list);
+	if ((p = strchr(mfs_dev, ' '))) *p = 0;
+}
+
+void vstream_io_dev_info(void)
+{
+	int i;
+
+	for (i=0; devs[i].dev; i++) {
+		printf("%s has %ld sectors\n", 
+		       devs[i].dev,
+		       devs[i].sectors);
+	}
+}
+
+int vstream_io_vserver(void)
+{
+	return vserver;
+}
+
+void vstream_io_need_bswap(int set)
+{
+	need_bswap = set;
+}
+
+u32 vstream_io_total_size(void)
+{
+	if (vstream_partition_total_size()) {
+		total_size = vstream_partition_total_size();
+	}	
+	return total_size;
+}
+
+
+/* read bytes from a sector, handling partial sectors */
+void vstream_mfs_read_partial(void *buf, u32 sec, u32 size)
+{
+	char tmp[SECTOR_SIZE];
+	if (size >= SECTOR_SIZE) {
+		u32 n = size / SECTOR_SIZE;
+		mfs_vstream_read_sectors(buf, sec, n);
+		buf += n*SECTOR_SIZE;
+		size -= n*SECTOR_SIZE;
+		sec += n;
+	}
+	if (size == 0) return;
+	mfs_vstream_read_sectors(tmp, sec, 1);
+	memcpy(buf, tmp, size);
+}
+
+
+/*******************************************************************************
+    ppchacker 01/18/2002.  Let users know whether byte-swapping is being done.
+*******************************************************************************/
+int vstream_io_get_need_bswap(void)
+{
+	return need_bswap;
+}
diff -Nur main.sofar/vstream/mfs.c main.dev/vstream/mfs.c
--- main.sofar/vstream/mfs.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/mfs.c	2004-08-11 03:18:38.136686400 +0000
@@ -0,0 +1,798 @@
+/*
+  media-filesystem library
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+#include <assert.h>
+
+static struct mfs_super super;
+static struct mfs_zone_map *zones[MAX_ZONES];
+static int num_zones;
+
+static int little_endian;
+static int total_inodes;
+
+char *mfs_dev;
+
+unsigned vstream_fsid_hash(unsigned fsid, unsigned size)
+{
+	return fsid*67289 % size;
+}
+
+/* useful debug routine */
+void vstream_dump_sectors(void *d, int n)
+{
+	u16 *v = d;
+	int i, j;
+	char *p;
+	n = SECTOR_SIZE*n/2;
+	for (i=0;i<n;i+=8) {
+		int i0 = i;
+		while (i>8 && i < (n-8) && memcmp(&v[i-8], &v[i], 16) == 0) {
+			if (i == i0) printf("*\n");
+			i += 8;
+		}
+		printf("%07x: %04x %04x %04x %04x %04x %04x %04x %04x   ", 
+		       i*2, 
+		       ntohs(v[i]), ntohs(v[i+1]), ntohs(v[i+2]), ntohs(v[i+3]),
+		       ntohs(v[i+4]), ntohs(v[i+5]), ntohs(v[i+6]), ntohs(v[i+7]));
+		p = (char *)&v[i];
+		for (j=0;j<16;j++) {
+			printf("%c", isprint(p[j])?p[j]:'.');
+		}
+		printf("\n");
+	}
+}
+
+
+
+/* load the mfs super block - assumes MFS_DEVICE is set */
+static void load_super(void)
+{
+	char buffer[100*SECTOR_SIZE];
+	int fd;
+
+	if (vstream_io_vserver() != -1) {
+		vstream_mfs_read_partial(&super, 0, sizeof(super));
+	} else {
+		if (!mfs_dev) mfs_dev = getenv("MFS_DEVICE");
+		if (!mfs_dev) {
+			mfs_dev = "/dev/hda10";
+			printf("Assuming MFS_DEVICE=%s\n", mfs_dev);
+		}
+
+		fd = open(mfs_dev, O_RDONLY|O_LARGEFILE);
+
+		/* -- this is buggy! overwrites random data RLR 12/31/2001
+		vstream_read_sectors(fd, &super, 0, 1); -- buggy
+		*/
+		vstream_read_sectors(fd, buffer, 0, 1);
+		memcpy(&super, buffer, sizeof(super));
+
+		close(fd);
+	}
+
+	vstream_load_devs(super.devlist);
+
+	if (*(u16 *)&super == 0x1492 || *(u16 *)&super == 0x9214) {
+		if (*(u16 *)&super == 0x1492) vstream_io_need_bswap(1);
+		vstream_partition_parse();
+		vstream_mfs_read_partial(&super, 0, sizeof(super));
+	}
+
+	switch (super.magic) {
+	case 0xabbafeed: /* normal tivo access */
+		break;
+	case 0xbaabedfe:
+		vstream_io_need_bswap(1);
+		break;
+	case 0xedfebaab:
+		little_endian = 1;
+		break;
+	case 0xfeedabba:
+		little_endian = 1;
+		vstream_io_need_bswap(1);
+		break;
+	default:
+		fprintf(stderr,"Not a TiVo super block! (magic=0x%08x)\n", 
+			super.magic);
+		exit(1);
+	}
+
+	/*
+	vstream_mfs_read_partial(&super, 0, sizeof(super));
+	*/
+	vstream_mfs_read_partial(buffer, 0, sizeof(super));
+	memcpy(&super, buffer, sizeof(super));
+
+	vstream_check_crc((void *)&super, sizeof(super) - 512, &super.crc);
+	
+	vstream_byte_swap(&super, "i9 b128 i87");
+
+	if (super.magic != 0xabbafeed) {
+		fprintf(stderr,"Failed to byte swap correctly\n");
+		exit(1);
+	}
+
+	if (vstream_io_total_size() && 
+      vstream_io_total_size() != super.total_sectors) {
+		printf("WARNING: total sectors doesn't match (total=%d sb=%d)\n",
+		       vstream_io_total_size(), super.total_sectors);
+	}
+}
+
+/* load the mfs zones - currently we only use the inode
+   zone but might as well load the lot */
+static void load_zones(void)
+{
+	u32 next = super.zonemap_ptr;
+	u32 map_size = super.zonemap_size;
+	total_inodes = 0;
+
+	while (next) {
+		zones[num_zones] = (struct mfs_zone_map *)malloc(SECTOR_SIZE*map_size);
+		mfs_vstream_read_sectors(zones[num_zones], next, map_size);
+		vstream_check_crc(zones[num_zones], map_size*SECTOR_SIZE, &zones[num_zones]->crc);
+		vstream_byte_swap(zones[num_zones], "i18");
+		if (next != zones[num_zones]->sector) {
+			fprintf(stderr,"sector wrong in zone (%d %d)\n",
+				next, zones[num_zones]->sector);
+			exit(1);
+		}
+		if (zones[num_zones]->type == ZONE_INODE) {
+			total_inodes += zones[num_zones]->zone_size/2;
+		}
+		next = zones[num_zones]->next_zonemap_ptr;
+		map_size = zones[num_zones]->next_zonemap_size;
+		num_zones++;
+		if (num_zones == MAX_ZONES) {
+			fprintf(stderr,"Too many zones\n");
+			exit(1);
+		}
+	}
+}
+
+/* turn a hash into a zone sector */
+static u32 zone_sector(u32 hash)
+{
+	int i;
+	u32 start = 0;
+	for (i=0;i<num_zones;i++) {
+		u32 len;
+		if (zones[i]->type != ZONE_INODE) continue;
+		len = zones[i]->zone_size/2;
+		if (hash < start + len) {
+			return zones[i]->zone_start + (hash-start)*2;
+		}
+		start += len;
+	}
+	fprintf(stderr, "Didn't find hash %x in zones!\n", hash);
+	exit(1);
+}
+
+/* load one inode by fsid - optimised to avoid repeats */
+void vstream_mfs_load_inode(int fsid, struct mfs_inode *inode)
+{
+	static struct mfs_inode in;
+	static u32 last_fsid;
+	unsigned hash, hash1;
+
+	if (fsid && fsid == last_fsid) {
+		*inode = in;
+		return;
+	}
+
+	hash1 = hash = vstream_fsid_hash(fsid, total_inodes);
+	do {
+		vstream_mfs_read_partial(&in, zone_sector(hash), sizeof(in));
+		vstream_byte_swap(&in, "i10 b2 s1 i4");
+		if (in.num_runs) {
+			// cwingert There is more than 24 runs, so just use the
+		   // maximum space available
+			// vstream_byte_swap(&in.u.runs[0], "i48");
+			vstream_byte_swap(&in.u.runs[0], "i112");
+		}
+		hash = (hash+1) % total_inodes;
+	} while ((in.flags & MFS_FLAGS_CHAIN) && in.id != fsid && hash != hash1);
+
+	if (in.id != fsid) {
+		fprintf(stderr, "ERROR: Didn't find fsid=%d!\n", fsid);
+		exit(1);
+	}
+
+	*inode = in;
+	last_fsid = fsid;
+}
+
+/* must call this before anything else */
+void vstream_mfs_init(void)
+{
+	char *p = getenv("MFS_DEVLIST");
+	if (p) vstream_add_dev_map(p);
+	load_super();
+	load_zones();
+}
+
+/* dump some global info on the mfs */
+void vstream_mfs_info(void)
+{
+	int i;
+	u32 total_size = vstream_io_total_size();
+	printf("Super:\n\tstate=%x magic=%x\n\tdevlist=%s\n\tzonemap_ptr=%d total_secs=%d next_fsid=%d\n",
+	       super.state, super.magic, super.devlist, super.zonemap_ptr,
+	       super.total_sectors, super.next_fsid);
+	printf("\tbackup_zonemap_ptr=%x zonemap_size=%d\n",
+	       super.backup_zonemap_ptr, super.zonemap_size);
+
+	vstream_io_dev_info();
+
+	for (i=0; i<num_zones; i++) {
+		printf("zone(%d):\n\tsector=%d type=%d start=%d next_zonemap=%d\n\tsize=%d per_chunk=%d limit=%d zone_size=%d\n",
+		       i,
+		       zones[i]->sector, 
+		       zones[i]->type, 
+		       zones[i]->zone_start, 
+		       zones[i]->next_zonemap_ptr, 
+		       zones[i]->zone_size,
+		       zones[i]->per_chunk,
+		       zones[i]->zone_start+zones[i]->zone_size,
+		       zones[i]->zone_size);
+		printf("\tbackup_sector=%x zonemap_size=%d\n\tbackup_next_zonemap=%x next_zonemap_size=%d\n\tbuddy_size=%d\n",
+		       zones[i]->backup_sector, zones[i]->zonemap_size, 
+		       zones[i]->backup_next_zonemap_ptr, 
+		       zones[i]->next_zonemap_size,
+		       zones[i]->buddy_size);
+		if (total_size &&
+		    zones[i]->zone_start+zones[i]->zone_size > total_size) {
+			printf("Warning: zone is out of range\n");
+		}
+	}
+	
+}
+
+/* dome some details about a fsid */
+/* TODO: RLR need to cleanup mfs to use an error-callback function */
+void vstream_mfs_fsid_info(int fsid)
+{
+	struct mfs_inode inode;
+	int i;
+	u32 hash = vstream_fsid_hash(fsid, zones[0]->zone_size/2);
+
+	vstream_mfs_load_inode(fsid, &inode);
+	printf("id=%d type=%d/%s hash=%x sec=%d typexx=%d units=%d size=%d runs=%d\n", 
+	       inode.id, inode.type, 
+	       vstream_mfs_type_string(inode.type),
+	       hash, zones[0]->zone_start+hash*2,
+	       inode.typexx,
+	       inode.units, inode.size, inode.num_runs);
+	for (i=0; i<inode.num_runs; i++) {
+		printf("run 0x%08x:0x%x\n", 
+		       inode.u.runs[i].start,
+		       inode.u.runs[i].len);
+	}
+	printf("fsid %d is a total of %lld bytes\n", 
+	       fsid, vstream_mfs_fsid_size(fsid));
+}
+
+
+/* read count bytes from a mfs file at offset ofs,
+   returning the number of bytes read 
+   ofs must be on a sector boundary
+*/
+u32 vstream_mfs_fsid_pread(int fsid, void *buf, u64 ofs, u32 count)
+{
+	struct mfs_inode inode;
+	int i, n;
+	u32 start;
+	u32 ret=0;
+	u32 sec = ofs >> SECTOR_SHIFT;
+	u64 size;
+
+	vstream_mfs_load_inode(fsid, &inode);
+
+	if (inode.num_runs == 0) {
+		if (ofs >= inode.size) return 0;
+		ret = count;
+		if (ret > inode.size-ofs) {
+			ret = inode.size-ofs;
+		}
+		memcpy(buf, inode.u.data, ret);
+		return ret;
+	}
+
+	size = inode.size;
+	if (inode.units == 0x20000) {
+		size <<= 17;
+	}
+
+	if (ofs > size) return 0;
+	if (ofs + count > size) {
+		count = size-ofs;
+	}
+
+	// vstream_mfs_fsid_info(fsid);
+
+	while (count > 0) {
+		void *buf2;
+		u32 n2;
+		start = 0;
+		for (i=0; i<inode.num_runs; i++) {
+			if (sec < start + inode.u.runs[i].len) break;
+			start += inode.u.runs[i].len;
+		}
+		if (i == inode.num_runs) return ret;
+		n = (count+(SECTOR_SIZE-1))>>SECTOR_SHIFT;
+		if (n > inode.u.runs[i].len-(sec-start)) {
+			n = inode.u.runs[i].len-(sec-start);
+		}
+		buf2 = malloc(n<<SECTOR_SHIFT);
+		mfs_vstream_read_sectors(buf2, inode.u.runs[i].start+(sec-start), n);
+		n2 = n<<SECTOR_SHIFT;
+		if (n2 > count) n2 = count;
+		memcpy(buf, buf2, n2);
+		free(buf2);
+		buf += n2;
+		sec += n;
+		count -= n2;
+		ret += n2;
+	}
+	return ret;
+}
+
+/* return the type of a fsid */
+int vstream_mfs_fsid_type(int fsid)
+{
+	struct mfs_inode inode;
+	if (fsid == 0) return 0;
+	memset(&inode, 0, sizeof(inode));
+	vstream_mfs_load_inode(fsid, &inode);
+	return inode.type;
+}
+
+/* return the number of bytes used by a fsid */
+u64 vstream_mfs_fsid_size(int fsid)
+{
+	struct mfs_inode inode;
+
+	if (fsid == 0) return 0;
+	vstream_mfs_load_inode(fsid, &inode);
+
+	// vstream_mfs_fsid_info(fsid);
+	switch (inode.units) {
+	case 0: return inode.size;
+	case 0x20000: return ((u64)inode.size) << 17;
+	}
+	fprintf(stderr, "ERROR: fsid=%d Unknown units %d\n", 
+		fsid, inode.units);
+	exit(1);
+	return inode.size;
+}
+
+/* list a mfs directory - make sure you free with vstream_mfs_dir_free() */
+struct mfs_dirent *mfs_dir(int fsid, u32 *count)
+{
+	u32 *buf, *p;
+	int n=0, i;
+	int size = vstream_mfs_fsid_size(fsid);
+	int dsize, dflags;
+	struct mfs_dirent *ret;
+
+	*count = 0;
+
+	if (size < 4) return NULL;
+
+	if (vstream_mfs_fsid_type(fsid) != MFS_TYPE_DIR) {
+		fprintf(stderr,"fsid %d is not a directory\n", fsid);
+		// vstream_mfs_fsid_info(fsid);
+		return NULL;
+	}
+
+	buf = (u32 *)malloc(size);
+	vstream_mfs_fsid_pread(fsid, buf, 0, size);
+	dsize = ntohl(buf[0]) >> 16;
+	dflags = ntohl(buf[0]) & 0xFFFF;
+	p = buf + 1;
+	while ((int)(p-buf) < dsize/4) {
+		u8 *s = ((char *)p)+4;
+		p += s[0]/4;
+		n++;
+	}
+	ret = malloc((n+1)*sizeof(*ret));
+	p = buf + 1;
+	for (i=0;i<n;i++) {
+		u8 *s = ((char *)p)+4;
+		ret[i].name = strdup(s+2);
+		ret[i].type = s[1];
+		ret[i].fsid = ntohl(p[0]);
+		p += s[0]/4;
+	}	
+	ret[n].name = NULL;
+	free(buf);
+	*count = n;
+
+	/* handle meta-directories. These are just directories which are
+	   lists of other directories. All we need to do is recursively read
+	   the other directories and piece together the top level directory */
+	if (dflags == 0x200) {
+		struct mfs_dirent *meta_dir = NULL;
+		int meta_size=0;
+
+		*count = 0;
+
+		for (i=0;i<n;i++) {
+			struct mfs_dirent *d2;
+			int n2;
+			if (ret[i].type != MFS_TYPE_DIR) {
+				printf("ERROR: non dir %d/%s in meta-dir %d!\n", 
+				       ret[i].type, ret[i].name, fsid);
+				continue;
+			}
+			d2 = mfs_dir(ret[i].fsid, &n2);
+			if (!d2 || n2 == 0) continue;
+			meta_dir = realloc(meta_dir, sizeof(ret[0])*(meta_size + n2 + 1));
+			memcpy(meta_dir+meta_size, d2, n2*sizeof(ret[0]));
+			meta_size += n2;
+			free(d2);
+		}
+		vstream_mfs_dir_free(ret);
+		if (meta_dir) meta_dir[meta_size].name = NULL;
+		*count = meta_size;
+		return meta_dir;
+	}
+
+
+	return ret;
+}
+
+/* free a dir from mfs_dir */
+void vstream_mfs_dir_free(struct mfs_dirent *dir)
+{
+	int i;
+	for (i=0; dir[i].name; i++) {
+		free(dir[i].name);
+		dir[i].name = NULL;
+	}
+	free(dir);
+}
+
+/* return a string identifier for a tivo file type */
+char *vstream_mfs_type_string(int type)
+{
+	
+	switch (type) {
+	case 0: return "NULL";
+	case MFS_TYPE_DIR: return "tyDir";
+	case MFS_TYPE_OBJ: return "tyDb";
+	case MFS_TYPE_STREAM: return "tyStream";
+	case MFS_TYPE_FILE: return "tyFile";
+	default: 
+		fprintf(stderr,"ERROR: Unknown file type %d!\n", type);
+		exit(1);
+		break;
+	}
+}
+
+/* resolve a path to a fsid */
+u32 vstream_mfs_resolve(char *path)
+{
+	char *p0, *tok, *r;
+	u32 fsid;
+	struct mfs_dirent *dir = NULL;
+
+	if (path[0] != '/') {
+		return atoi(path);
+	}
+
+	fsid = MFS_ROOT_FSID;
+	p0 = strdup(path);
+	path = p0;
+	for (tok=strtok_r(path,"/", &r); tok; tok=strtok_r(NULL,"/", &r)) {
+		u32 count;
+		int i;
+		dir = mfs_dir(fsid, &count);
+		if (!dir) {
+			fprintf(stderr,"resolve failed for fsid=%d\n",
+				fsid);
+			return 0;
+		}
+		for (i=0;i<count;i++) {
+			if (strcmp(tok, dir[i].name) == 0) break;
+		}
+		if (i == count) {
+			fsid = 0;
+			goto done;
+		}
+		fsid = dir[i].fsid;
+		if (dir[i].type != MFS_TYPE_DIR) {
+			if (strtok_r(NULL, "/", &r)) {
+				fprintf(stderr,"not a directory %s\n",tok);
+				fsid = 0;
+				goto done;
+			}
+			goto done;
+		}
+		vstream_mfs_dir_free(dir);
+		dir = NULL;
+	}
+
+ done:
+	if (dir) vstream_mfs_dir_free(dir);
+	if (p0) free(p0);
+	return fsid;
+}
+
+
+/* loop over all inodes calling fn on each one */
+void vstream_mfs_all_inodes(void (*fn)(struct mfs_inode *))
+{
+	int i, z;
+	u32 start_hash=0;
+	struct mfs_inode inode;
+
+	for (z=0; z<num_zones;z++) {
+		if (zones[z]->type != ZONE_INODE) continue;
+		for (i=0; i<zones[z]->zone_size; i+= 2) {
+			u32 hash = start_hash + i/2;
+			vstream_mfs_read_partial(&inode, zone_sector(hash), 
+					 sizeof(inode));
+			vstream_byte_swap(&inode, "i10 b2 s1 i4");
+			if (inode.num_runs) {
+				vstream_byte_swap(&inode.u.runs[0], "i48");
+			}
+			if (inode.id != 0) {
+				if (inode.id > super.next_fsid) {
+					printf("invalid fsid %d (next=%d)\n",
+					       inode.id, super.next_fsid);
+					exit(1);
+				}
+				fn(&inode);
+			}
+		}
+		start_hash += zones[z]->zone_size/2;
+	}
+}
+
+
+struct bitmap *vstream_mfs_zone_bitmap(int zone, u64 limit)
+{
+	struct bitmap *bm;
+	int num_blocks;
+
+	void bitmap_fn(struct mfs_inode *inode) {
+		int i;
+		//printf("inode %d runs=%d\n", inode->id, inode->num_runs);
+		if (limit && vstream_mfs_fsid_size(inode->id) > limit) {
+			printf("skipping inode %d of size=%lld\n", 
+			       inode->id, vstream_mfs_fsid_size(inode->id));
+			return;
+		}
+		// if (bitmap_excluded(inode->id)) return;
+		for (i=0;i<inode->num_runs;i++) {
+			u32 start, len;
+			start = inode->u.runs[i].start;
+			len = inode->u.runs[i].len;
+			if (start < zones[zone]->zone_start ||
+			    start >= zones[zone]->zone_start+
+			    zones[zone]->zone_size) {
+				continue;
+			}
+			if (len % zones[zone]->per_chunk) {
+				printf("Not a multiple of per-chunk? fsid=%d\n", inode->id);
+				exit(1);
+			}
+			vstream_bitmap_set(bm, 
+				   (start-zones[zone]->zone_start)/
+				   zones[zone]->per_chunk,
+				   len/zones[zone]->per_chunk);
+		}
+	}
+
+	num_blocks = zones[zone]->zone_size / zones[zone]->per_chunk;
+	bm = vstream_bitmap_allocate(num_blocks);
+	
+	vstream_mfs_all_inodes(bitmap_fn);
+
+	return bm;
+}
+
+
+void vstream_mfs_purge_zone(int zone, u32 limit)
+{
+	struct bitmap *bm;
+	int i, n;
+	int units = zones[zone]->per_chunk;
+
+	bm = vstream_mfs_zone_bitmap(zone, limit);
+	
+	for (i=0;i<bm->n;) {
+		if (vstream_bitmap_query(bm, i)) {
+			i++; continue;
+		}
+		n = 1;
+		while (vstream_bitmap_query(bm, i+n) == 0 && 
+		       i+n < bm->n) n++;
+		vstream_mfs_zero_sectors(zones[zone]->zone_start+i*units,
+				 n*units);
+		i += n;
+	}
+}
+
+void vstream_mfs_purge_all(u64 limit)
+{
+	int z;
+
+	for (z=0; z<num_zones;z++) {
+		if (zones[z]->type != ZONE_STREAM &&
+		    zones[z]->type != ZONE_FILE) continue;
+		printf("Purging zone %d with size limit %lld\n", z, limit);
+		vstream_mfs_purge_zone(z, limit);
+	}
+}
+
+/* zone size in sectors */
+u32 vstream_mfs_zone_size(int zone)
+{
+	return zones[zone]->zone_size;
+}
+
+/*******************************************************************************
+    ppchacker 01/18/2002.  Specialized version of vstream_mfs_fsid_pread for speed.
+    Reads a full chunk without an extra copy.  Disables byteswapping while
+    reading the chunk data.  "size" can be 4096 to read just the table of
+    contents, or 256*512 to read the entire chunk.
+
+    We fix a serious bug in the original MFS code.  inode.fill2[1] is not
+    just filler.  It is the true tyStream length in chunks.  This differs from
+    "inode.size" because TiVo allocates file segments in 1 MB sizes, which
+    is 8 chunks.  Not all 8 chunks in the last segment are used.  Hence,
+    we indicate end of file when "chunk_index" >= inode.fill2[1].
+*******************************************************************************/
+#define SECTORS_PER_CHUNK	256
+
+int
+mfs_read_chunk(int fsid, void *buf, int chunk_index, int size)
+{
+    struct mfs_inode inode;
+    int i, save_need_bswap;
+    u32 offset, count;
+
+    /* load the i-node before disabling swapping (-: */
+    vstream_mfs_load_inode(fsid, &inode);
+
+    /* disable swapping */
+    save_need_bswap = vstream_io_get_need_bswap();
+    vstream_io_need_bswap(0);
+
+    assert(inode.num_runs != 0 && inode.units == 0x20000);
+    assert(size == 4096 || size == SECTORS_PER_CHUNK * 512);
+
+    /* map the chunk-index into an offset from one of the inode runs */
+    offset = chunk_index * SECTORS_PER_CHUNK;
+    for(i = 0; i < inode.num_runs && offset >= inode.u.runs[i].len; i++) {
+	offset -= inode.u.runs[i].len;
+    }
+
+    if (i == inode.num_runs || chunk_index >= inode.fill2[1]) {
+	count = 0;
+    } else {
+	count = size;
+	size >>= SECTOR_SHIFT;
+	assert(offset + size <= inode.u.runs[i].len);
+	mfs_vstream_read_sectors(buf, inode.u.runs[i].start + offset, size);
+    }
+
+    /* reenable swapping */
+    vstream_io_need_bswap(save_need_bswap);
+
+    return count;
+}
+
+/*******************************************************************************
+    ppchacker 01/18/2002
+    The MFS interface for querying attributes returns only single value.
+    This API returns the entire array of values.  If the value is TYPE_STRING,
+    copies of the strings are made; they should be freed.
+*******************************************************************************/
+int
+mfs_get_attribute(int fsid, 
+    char *target_subobj_name, unsigned target_subobj_id, char *target_attr_name,
+    mfs_attribute_t *attribute)
+{
+    struct mfs_obj_header *obj;
+    struct mfs_subobj_header *subobj;
+    struct mfs_attr_header *attr;
+    struct mfs_obj_attr *objattr;
+    unsigned char *p, *q, *pend, *qend, *r, *rend;
+    char *subobj_name, *attr_name;
+    unsigned size, *pint;
+    void *buf;
+    int found;
+
+    if (vstream_mfs_fsid_type(fsid) != MFS_TYPE_OBJ) {
+	fprintf(stderr, "%d is not an object\n", fsid);
+	exit(1);
+    }
+    size = vstream_mfs_fsid_size(fsid);
+    buf = malloc(size);
+    vstream_mfs_fsid_pread(fsid, buf, 0, size);
+
+    found = 0;
+
+    obj = (struct mfs_obj_header *) buf;
+    vstream_byte_swap(obj, "i2");
+
+    pend = (char *) buf + obj->size;
+    for(p = (char *) buf + sizeof(struct mfs_obj_header); p < pend && ! found; p += subobj->len) {
+	subobj = (struct mfs_subobj_header *) p;
+	vstream_byte_swap(subobj, "s6 i1");
+
+	subobj_name = vstream_schema_type(subobj->obj_type);
+	if (strcmp(subobj_name, target_subobj_name) != 0) {
+	    continue;
+	}
+	if (target_subobj_id != 0xffffffff && subobj->id != target_subobj_id) {
+	    continue;
+	}
+
+	qend = p + subobj->len;
+	for(q = p + sizeof(struct mfs_subobj_header); q < qend && ! found; q += attr->len) {
+	    attr = (struct mfs_attr_header *) q;
+	    vstream_byte_swap(&attr->len, "s1");
+	    attr->len = (attr->len + 3) & ~3;
+	    attr_name = vstream_schema_attrib(subobj->obj_type, attr->attr);
+
+	    if (strcmp(attr_name, target_attr_name) != 0) {
+	        continue;
+	    }
+
+	    /* this is the one! */
+	    found = 1;
+	    rend = q + attr->len;
+	    r = q + sizeof(struct mfs_attr_header);
+
+	    attribute->type = attr->eltype >> 6;
+	    attribute->n = 0;
+
+	    switch (attribute->type) {
+	    case TYPE_STRING:
+		while (r < rend) {
+		    assert(attribute->n < MFS_MAX_ARRAY_LEN);
+		    attribute->u.string[attribute->n++] = 
+			strcpy(malloc(strlen(r) + 1), r);
+		    r += strlen(r) + 1;
+		}
+
+		break;
+
+	    case TYPE_INT:
+	    case TYPE_FILE:
+		while (r < rend) {
+		    assert(attribute->n < MFS_MAX_ARRAY_LEN);
+		    pint = (int *) r;
+		    vstream_byte_swap(pint, "i1");
+		    attribute->u.integer[attribute->n++] = *pint;
+		    r += sizeof(unsigned);
+		}
+		break;
+
+	    case TYPE_OBJECT:
+		while (r < rend) {
+		    assert(attribute->n < MFS_MAX_ARRAY_LEN);
+		    objattr = (struct mfs_obj_attr *) r;
+		    vstream_byte_swap(objattr, "i2");
+		    attribute->u.object[attribute->n].fsid = objattr->fsid;
+		    attribute->u.object[attribute->n].subobj = objattr->subobj;
+		    attribute->n++;
+		    r += sizeof(struct mfs_obj_attr);
+		}
+		break;
+	    }
+
+	}
+    }
+
+    free(buf);
+    return found;
+}
diff -Nur main.sofar/vstream/mfs.h main.dev/vstream/mfs.h
--- main.sofar/vstream/mfs.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/mfs.h	2004-08-11 03:18:38.166729600 +0000
@@ -0,0 +1,261 @@
+/*
+  media-filesystem library
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#if defined(SYS_DARWIN)
+#include "darwin_unistd.h"
+#include "darwin_getopt.h"
+#include "darwin_dlfcn.h"
+#else
+#include <unistd.h>
+#ifdef __FreeBSD__
+#define loff_t off_t
+#else
+#include <getopt.h>
+#endif /* __FreeBSD__ */
+#include <dlfcn.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/time.h>
+
+#ifdef TIVO
+#include <linux/ide-tivo.h>
+#include <asm/unistd.h>
+#endif
+
+#define MAX_ZONES 32
+#define MAX_DEVS 64
+#define SECTOR_SIZE 512
+#define SECTOR_SHIFT 9
+
+#define ZONE_INODE 0
+#define ZONE_FILE 1
+#define ZONE_STREAM 2
+
+#define MFS_TYPE_DIR 4
+#define MFS_TYPE_OBJ 8
+#define MFS_TYPE_STREAM 2
+#define MFS_TYPE_FILE 1
+
+#define TYPE_INT 0
+#define TYPE_STRING 1
+#define TYPE_OBJECT 2
+#define TYPE_FILE 3
+
+#define MFS_FLAGS_CHAIN 0x80000000
+
+#define MFS_FLAGS_PRIMARY 0x2000
+
+#ifndef BLKGETSIZE
+#ifdef __i386__
+#define BLKGETSIZE 0x1260
+#else
+#define BLKGETSIZE 0x20001260
+#endif
+#endif
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0x8000
+#endif
+
+/* this sets what rounding of the number of blocks in a partition is
+   done. I'm not totally sure, this is right - it oculd be 1024 */
+#define MFS_BLOCK_ROUND 1024
+
+#define VSERVER_PORT 8074
+
+#if defined(__CYGWIN__)
+typedef unsigned long long loff_t;
+#endif
+
+#if defined(SYS_DARWIN)
+typedef unsigned long long loff_t;
+#endif
+
+typedef unsigned long long u64;
+typedef unsigned u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+#define MFS_CRC_BASE 0xdeadf00d
+#define MFS_ROOT_FSID 1
+
+/* length = 232 */
+struct mfs_super {
+	u32 state;
+	u32 magic; /* 0xabbafeed */
+	u32 crc;
+	u32 fill1;
+	u32 geom1; /* 16 */
+	u32 geom2; /* 1 */
+	u32 geom3; /* 64 */
+	u32 fill2[2]; /* unknown */
+	/* 0x24 */
+	char devlist[128];
+	/* 0xa4 */
+	u32 total_sectors;
+	u32 fill3[7];
+	/* 0xc4 */
+	u32 zonemap_ptr; /* pointer to first zone map */
+	u32 backup_zonemap_ptr; /* backup pointer to first zone map */
+	u32 zonemap_size; /* size of first zone map (sectors) */
+	u32 fill4[3];
+	/* 0xd8 */
+	u32 next_fsid; /* the next available fsid to be allocated */
+	u32 fill5[2];
+	char junk[512];		/* ppchacker: hack, pad to avoid over-read */
+};
+
+struct mfs_zone_map {
+	u32 sector; /* this sector */
+	u32 backup_sector; /* where our backup is */
+	u32 zonemap_size; /* how many sectors in this zone map */
+	u32 next_zonemap_ptr;
+	u32 backup_next_zonemap_ptr;
+	u32 next_zonemap_size;
+	u32 fill2[2];
+	u32 type; 
+	u32 fill3;
+	u32 crc;
+	u32 zone_start;
+	u32 next_zone_ptr1;
+	u32 zone_size;
+	u32 per_chunk;
+	u32 fill4[2];
+	u32 buddy_size; /* how many orders in buddy maps */
+	u32 mapdata[0]; /* variable size */
+};
+
+struct mfs_run {
+	u32 start;
+	u32 len;
+};
+
+struct mfs_inode {
+	u32 id;
+	u32 typexx;
+	u32 fill1[3];
+	u32 units;
+	u32 size;
+	u32 fill2[3];
+	u8  type;
+	u8  fill3;
+	u16 fill4;
+	u32 fill5[2];
+	u32 flags;
+	u32 num_runs;
+	union {
+      // cwingert - There are possible more than 24 runs, just fill up
+		// the data space
+		// struct mfs_run runs[24];
+		struct mfs_run runs[56];
+		char data[452];
+	} u;
+};
+
+struct mfs_dirent {
+	u32 fsid;
+	u8 type;
+	char *name;
+};
+
+
+struct mfs_obj_header {
+	u32 fill1;
+	u32 size;
+};
+
+struct mfs_subobj_header {
+	u16 len;
+	u16 len1; /* hmmm, why the dup length? perhaps for padding? */
+	u16 obj_type;
+	u16 flags;
+	u16 fill[2];
+	u32 id;
+};
+
+struct mfs_attr_header {
+	u8 eltype;
+	u8 attr;
+	u16 len;
+};
+
+struct mfs_obj_attr {
+	u32 fsid;
+	int subobj;
+};
+
+struct vserver_cmd {
+	u32	command;
+	u32	param1;
+	u32	param2;
+};
+
+struct bitmap {
+	u32 *b;
+	int n;
+};
+
+#define MFS_CMD_QUIT 0
+#define MFS_CMD_READ 1
+#define MFS_CMD_WRITE 2
+#define MFS_CMD_ZERO 3
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+typedef void (*object_fn)(int fsid, struct mfs_subobj_header *obj, 
+                          struct mfs_attr_header *attr, void *data);
+
+#ifndef CPLUSPLUS
+#include "proto.h"
+#endif
+
+#ifdef TIVO
+char *strtok_r(char *s, const char *delim, char **ptrptr);
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a)>(b)?(a):(b))
+#endif
+
+
+/*******************************************************************************
+    ppchacker: 01/18/2002
+*******************************************************************************/
+#define MFS_MAX_ARRAY_LEN	128
+
+typedef struct attribute_struct {
+    int type;
+    int n;
+    union {
+        char *string[MFS_MAX_ARRAY_LEN];
+        int integer[MFS_MAX_ARRAY_LEN];
+        struct mfs_obj_attr object[MFS_MAX_ARRAY_LEN];
+    } u;
+} mfs_attribute_t;
+
+int mfs_get_attribute(int fsid, char *target_subobj_name, unsigned target_subobj_id, char *target_attr_name, mfs_attribute_t *attribute);
+int mfs_read_chunk(int fsid, void *buf, int chunk_index, int size);
+int vstream_io_get_need_bswap(void);
diff -Nur main.sofar/vstream/mkproto.awk main.dev/vstream/mkproto.awk
--- main.sofar/vstream/mkproto.awk	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/mkproto.awk	2004-08-11 03:18:38.186758400 +0000
@@ -0,0 +1,76 @@
+# generate prototypes for Samba C code
+# tridge, June 1996
+
+BEGIN {
+  inheader=0;
+  print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
+  print ""
+}
+
+{
+  if (inheader) {
+    if (match($0,"[)][ \t]*$")) {
+      inheader = 0;
+      printf "%s;\n",$0;
+    } else {
+      printf "%s\n",$0;
+    }
+    next;
+  }
+}
+
+/^FN_LOCAL_BOOL/ {
+  split($0,a,"[,()]")
+  printf "BOOL %s(int );\n", a[2]
+}
+
+/^FN_LOCAL_STRING/ {
+  split($0,a,"[,()]")
+  printf "char *%s(int );\n", a[2]
+}
+
+/^FN_LOCAL_INT/ {
+  split($0,a,"[,()]")
+  printf "int %s(int );\n", a[2]
+}
+
+/^FN_LOCAL_CHAR/ {
+  split($0,a,"[,()]")
+  printf "char %s(int );\n", a[2]
+}
+
+/^FN_GLOBAL_BOOL/ {
+  split($0,a,"[,()]")
+  printf "BOOL %s(void);\n", a[2]
+}
+
+/^FN_GLOBAL_STRING/ {
+  split($0,a,"[,()]")
+  printf "char *%s(void);\n", a[2]
+}
+
+/^FN_GLOBAL_INT/ {
+  split($0,a,"[,()]")
+  printf "int %s(void);\n", a[2]
+}
+
+/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
+  next;
+}
+
+!/^u32|^u64|^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
+  next;
+}
+
+
+/[(].*[)][ \t]*$/ {
+    printf "%s;\n",$0;
+    next;
+}
+
+/[(]/ {
+  inheader=1;
+  printf "%s\n",$0;
+  next;
+}
+
diff -Nur main.sofar/vstream/object.c main.dev/vstream/object.c
--- main.sofar/vstream/object.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/object.c	2004-08-11 03:18:38.206787200 +0000
@@ -0,0 +1,76 @@
+/*
+  media-filesystem object parse code
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+
+static int parse_attr(char *p, int obj_type, int fsid, 
+		      struct mfs_subobj_header *obj, object_fn fn)
+{
+	struct mfs_attr_header *attr;
+	int ret;
+
+	attr = (struct mfs_attr_header *)p;
+	attr->len = ntohs(attr->len);
+
+	p += sizeof(*attr);
+
+	fn(fsid, obj, attr, p);
+
+	ret = (attr->len+3)&~3;
+	attr->len = htons(attr->len);
+	return ret;
+}
+
+static void parse_subobj(void *p, u16 type, int len, int fsid,
+			 struct mfs_subobj_header *obj, object_fn fn)
+{
+	int ofs=0;
+	while (ofs < len) {
+		ofs += parse_attr(p+ofs, type, fsid, obj, fn);
+	}
+}
+
+/* this is the low-level interface to parsing an object. It will call fn() on
+   all elements in all subobjects */
+void vstream_parse_object(int fsid, void *buf, object_fn fn)
+{
+	char *p;
+	u32 ofs;
+	struct mfs_obj_header *obj = buf;
+	int i=0;
+
+	vstream_byte_swap(obj, "i2");
+
+	p = buf;
+	ofs = sizeof(*obj);
+
+	/* now the subobjects */
+	while (ofs < obj->size) {
+		struct mfs_subobj_header *subobj = buf+ofs;
+		vstream_byte_swap(subobj, "s6 i1");
+		fn(fsid, subobj, NULL, NULL);
+		parse_subobj(buf+ofs+sizeof(*subobj), 
+			     subobj->obj_type,
+			     subobj->len-sizeof(*subobj), fsid, subobj, fn);
+		ofs += subobj->len;
+		i++;
+		vstream_byte_swap(subobj, "s6 i1");
+	}
+
+	vstream_byte_swap(obj, "i2");
+}
+
+/* give a string for a obj type */
+char *vstream_object_typestr(int objtype)
+{
+	switch (objtype) {
+	case TYPE_INT: return "int";
+	case TYPE_STRING: return "string";
+	case TYPE_OBJECT: return "object";
+	case TYPE_FILE: return "file";
+	}
+	return "UNKNOWN";
+}
diff -Nur main.sofar/vstream/partition.c main.dev/vstream/partition.c
--- main.sofar/vstream/partition.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/partition.c	2004-08-11 03:18:38.236830400 +0000
@@ -0,0 +1,109 @@
+/*
+  media-filesystem library, partition routines
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+
+#define MAX_PARTITIONS 20
+#define PARTITION_MAGIC	0x504d
+
+struct tivo_partition {
+	u16	signature;	/* expected to be PARTITION_MAGIC */
+	u16	res1;
+	u32	map_count;	/* # blocks in partition map */
+	u32	start_block;	/* absolute starting block # of partition */
+	u32	block_count;	/* number of blocks in partition */
+	char	name[32];	/* partition name */
+	char	type[32];	/* string type description */
+	u32	data_start;	/* rel block # of first data block */
+	u32	data_count;	/* number of data blocks */
+	u32	status;		/* partition status bits */
+	u32	boot_start;
+	u32	boot_size;
+	u32	boot_load;
+	u32	boot_load2;
+	u32	boot_entry;
+	u32	boot_entry2;
+	u32	boot_cksum;
+	char	processor[16];	/* identifies ISA of boot */
+	/* there is more stuff after this that we don't need */
+};
+
+struct pmap {
+	u32 start;
+	u32 length;
+} pmaps[MAX_PARTITIONS];
+
+static int num_partitions;
+static int use_ptable;
+
+/* parse the tivo partition table */
+void vstream_partition_parse(void)
+{
+	char buf[SECTOR_SIZE];
+	struct tivo_partition *tp;
+	int i, count;
+
+	tp = (struct tivo_partition *)buf;
+
+	mfs_vstream_read_sectors(tp, 1, 1);
+
+	count = ntohl(tp->map_count);
+
+	for (i=0;i<count;i++) {
+		mfs_vstream_read_sectors(tp, i+1, 1);
+		if (ntohs(tp->signature) != PARTITION_MAGIC) {
+			printf("wrong magic %x in partition %d\n",
+			       ntohs(tp->signature), i);
+			exit(1);
+		}
+		if (strcmp(tp->type, "MFS") == 0) {
+			pmaps[num_partitions].start = ntohl(tp->start_block);
+			pmaps[num_partitions].length = ntohl(tp->block_count);
+			num_partitions++;
+		}
+		// printf("%d %4x [%s] [%s]\n", 
+		//       count, tp->signature, tp->name, tp->type);
+	}
+	printf("Found %d MFS partitions\n", num_partitions);
+	use_ptable = 1;
+}
+
+/* map a mfs sector number to a absolute sector number */
+u32 vstream_partition_remap(u32 sec)
+{
+	int i;
+	u32 start=0;
+
+	if (!use_ptable) return sec;
+
+	for (i=0; i<num_partitions; i++) {
+		if (sec < start + pmaps[i].length) {
+			// printf("remapped %d to %d\n",
+			//       sec, pmaps[i].start + (sec - start));
+			return pmaps[i].start + (sec - start);
+		}
+		start += (pmaps[i].length & ~(MFS_BLOCK_ROUND-1));
+	}
+	if (i == num_partitions) {
+		fprintf(stderr,"Failed to partition map sector %d\n", sec);
+		exit(1);
+	}
+	return sec;
+}
+
+u32 vstream_partition_total_size(void)
+{
+	u32 total=0;
+	int i;
+
+	if (!use_ptable) return 0;
+
+	for (i=0; i<num_partitions; i++) {
+		total += (pmaps[i].length & ~(MFS_BLOCK_ROUND-1));
+	}
+
+	return total;
+}
diff -Nur main.sofar/vstream/preload_schema.h main.dev/vstream/preload_schema.h
--- main.sofar/vstream/preload_schema.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/preload_schema.h	2004-08-11 03:18:38.437118400 +0000
@@ -0,0 +1,2294 @@
+typedef struct preload_schema_struct {
+   int itype; 
+   char *type;
+   int iattr;
+   char *attr;
+   char *attr_type;
+} preload_schema_t;
+
+static preload_schema_t preload_schema_table[] = {
+    {1, "Test1", 1, "Version", "int"},
+    {1, "Test1", 2, "Expiration", "int"},
+    {1, "Test1", 3, "Path", "string"},
+    {1, "Test1", 4, "IndexPath", "string"},
+    {1, "Test1", 5, "IndexUsed", "object"},
+    {1, "Test1", 6, "IndexUsedBy", "object"},
+    {1, "Test1", 7, "IndexAttr", "object"},
+    {1, "Test1", 8, "ServerId", "string"},
+    {1, "Test1", 9, "ServerVersion", "int"},
+    {1, "Test1", 10, "Uuid", "string"},
+    {1, "Test1", 11, "Unsatisfied", "string"},
+    {1, "Test1", 12, "Bits", "int"},
+    {1, "Test1", 16, "IS", "int"},
+    {1, "Test1", 17, "IO", "int"},
+    {1, "Test1", 18, "IM", "int"},
+    {1, "Test1", 19, "SS", "string"},
+    {1, "Test1", 20, "SO", "string"},
+    {1, "Test1", 21, "SM", "string"},
+    {1, "Test1", 22, "FS", "file"},
+    {1, "Test1", 23, "FO", "file"},
+    {1, "Test1", 24, "FM", "file"},
+    {1, "Test1", 25, "OSD", "object"},
+    {1, "Test1", 26, "OSS", "object"},
+    {1, "Test1", 27, "OON", "object"},
+    {1, "Test1", 28, "OOD", "object"},
+    {1, "Test1", 29, "OOS", "object"},
+    {1, "Test1", 30, "OMN", "object"},
+    {1, "Test1", 31, "OMD", "object"},
+    {1, "Test1", 32, "OMS", "object"},
+    {2, "Test2", 1, "Version", "int"},
+    {2, "Test2", 2, "Expiration", "int"},
+    {2, "Test2", 3, "Path", "string"},
+    {2, "Test2", 4, "IndexPath", "string"},
+    {2, "Test2", 5, "IndexUsed", "object"},
+    {2, "Test2", 6, "IndexUsedBy", "object"},
+    {2, "Test2", 7, "IndexAttr", "object"},
+    {2, "Test2", 8, "ServerId", "string"},
+    {2, "Test2", 9, "ServerVersion", "int"},
+    {2, "Test2", 10, "Uuid", "string"},
+    {2, "Test2", 11, "Unsatisfied", "string"},
+    {2, "Test2", 12, "Bits", "int"},
+    {2, "Test2", 16, "I", "int"},
+    {2, "Test2", 17, "S", "string"},
+    {2, "Test2", 18, "IndexObject", "object"},
+    {2, "Test2", 19, "IndexInt", "int"},
+    {2, "Test2", 20, "IndexString", "string"},
+    {2, "Test2", 21, "IndexFile", "file"},
+    {3, "Program", 1, "Version", "int"},
+    {3, "Program", 2, "Expiration", "int"},
+    {3, "Program", 3, "Path", "string"},
+    {3, "Program", 4, "IndexPath", "string"},
+    {3, "Program", 5, "IndexUsed", "object"},
+    {3, "Program", 6, "IndexUsedBy", "object"},
+    {3, "Program", 7, "IndexAttr", "object"},
+    {3, "Program", 8, "ServerId", "string"},
+    {3, "Program", 9, "ServerVersion", "int"},
+    {3, "Program", 10, "Uuid", "string"},
+    {3, "Program", 11, "Unsatisfied", "string"},
+    {3, "Program", 12, "Bits", "int"},
+    {3, "Program", 16, "TmsId", "string"},
+    {3, "Program", 17, "Title", "string"},
+    {3, "Program", 18, "Series", "object"},
+    {3, "Program", 19, "Description", "string"},
+    {3, "Program", 20, "DescLanguage", "string"},
+    {3, "Program", 21, "ShowType", "int"},
+    {3, "Program", 22, "MovieYear", "int"},
+    {3, "Program", 23, "MpaaRating", "int"},
+    {3, "Program", 24, "StarRating", "int"},
+    {3, "Program", 25, "MovieRunTime", "int"},
+    {3, "Program", 26, "Country", "string"},
+    {3, "Program", 27, "NetworkSource", "string"},
+    {3, "Program", 28, "SourceType", "int"},
+    {3, "Program", 29, "EpisodeTitle", "string"},
+    {3, "Program", 30, "Advisory", "int"},
+    {3, "Program", 31, "Actor", "string"},
+    {3, "Program", 32, "GuestStar", "string"},
+    {3, "Program", 33, "Director", "string"},
+    {3, "Program", 34, "ExecProducer", "string"},
+    {3, "Program", 35, "Producer", "string"},
+    {3, "Program", 36, "Writer", "string"},
+    {3, "Program", 37, "Host", "string"},
+    {3, "Program", 38, "Choreographer", "string"},
+    {3, "Program", 39, "Genre", "int"},
+    {3, "Program", 40, "ColorCode", "int"},
+    {3, "Program", 41, "EpisodeNum", "int"},
+    {3, "Program", 42, "AltEpisodeNum", "int"},
+    {3, "Program", 43, "ShowingOBSOLETE", "object"},
+    {3, "Program", 44, "Recording", "object"},
+    {3, "Program", 45, "IsEpisode", "int"},
+    {3, "Program", 46, "ApgProgram", "object"},
+    {3, "Program", 47, "Bits", "int"},
+    {3, "Program", 48, "TvRating", "int"},
+    {3, "Program", 49, "OriginalAirDate", "int"},
+    {3, "Program", 50, "RootServerId", "string"},
+    {3, "Program", 51, "Url", "object"},
+    {3, "Program", 52, "AolRating", "string"},
+    {4, "Series", 1, "Version", "int"},
+    {4, "Series", 2, "Expiration", "int"},
+    {4, "Series", 3, "Path", "string"},
+    {4, "Series", 4, "IndexPath", "string"},
+    {4, "Series", 5, "IndexUsed", "object"},
+    {4, "Series", 6, "IndexUsedBy", "object"},
+    {4, "Series", 7, "IndexAttr", "object"},
+    {4, "Series", 8, "ServerId", "string"},
+    {4, "Series", 9, "ServerVersion", "int"},
+    {4, "Series", 10, "Uuid", "string"},
+    {4, "Series", 11, "Unsatisfied", "string"},
+    {4, "Series", 12, "Bits", "int"},
+    {4, "Series", 16, "TmsId", "string"},
+    {4, "Series", 17, "Title", "string"},
+    {4, "Series", 18, "ShowingOBSOLETE", "object"},
+    {4, "Series", 19, "ShowingDerivedOBSOLETE", "object"},
+    {4, "Series", 20, "Genre", "int"},
+    {4, "Series", 21, "SeriesStationOBSOLETE", "object"},
+    {4, "Series", 22, "Episodic", "int"},
+    {4, "Series", 23, "ThumbData", "int"},
+    {5, "Station", 1, "Version", "int"},
+    {5, "Station", 2, "Expiration", "int"},
+    {5, "Station", 3, "Path", "string"},
+    {5, "Station", 4, "IndexPath", "string"},
+    {5, "Station", 5, "IndexUsed", "object"},
+    {5, "Station", 6, "IndexUsedBy", "object"},
+    {5, "Station", 7, "IndexAttr", "object"},
+    {5, "Station", 8, "ServerId", "string"},
+    {5, "Station", 9, "ServerVersion", "int"},
+    {5, "Station", 10, "Uuid", "string"},
+    {5, "Station", 11, "Unsatisfied", "string"},
+    {5, "Station", 12, "Bits", "int"},
+    {5, "Station", 16, "TmsId", "string"},
+    {5, "Station", 17, "Name", "string"},
+    {5, "Station", 18, "CallSign", "string"},
+    {5, "Station", 19, "City", "string"},
+    {5, "Station", 20, "State", "string"},
+    {5, "Station", 21, "ZipCode", "string"},
+    {5, "Station", 22, "Country", "string"},
+    {5, "Station", 23, "Affiliation", "string"},
+    {5, "Station", 24, "DmaName", "string"},
+    {5, "Station", 25, "DmaNum", "int"},
+    {5, "Station", 26, "FccChannelNum", "int"},
+    {5, "Station", 27, "LogoIndex", "int"},
+    {5, "Station", 28, "AffiliationIndex", "int"},
+    {5, "Station", 29, "PayPerView", "int"},
+    {5, "Station", 30, "AolChannel", "int"},
+    {5, "Station", 31, "AolMiniGuide", "int"},
+    {5, "Station", 32, "AolUrl", "object"},
+    {5, "Station", 33, "AolDescription", "string"},
+    {5, "Station", 34, "AolStationType", "string"},
+    {6, "StationDay", 1, "Version", "int"},
+    {6, "StationDay", 2, "Expiration", "int"},
+    {6, "StationDay", 3, "Path", "string"},
+    {6, "StationDay", 4, "IndexPath", "string"},
+    {6, "StationDay", 5, "IndexUsed", "object"},
+    {6, "StationDay", 6, "IndexUsedBy", "object"},
+    {6, "StationDay", 7, "IndexAttr", "object"},
+    {6, "StationDay", 8, "ServerId", "string"},
+    {6, "StationDay", 9, "ServerVersion", "int"},
+    {6, "StationDay", 10, "Uuid", "string"},
+    {6, "StationDay", 11, "Unsatisfied", "string"},
+    {6, "StationDay", 12, "Bits", "int"},
+    {6, "StationDay", 16, "Station", "object"},
+    {6, "StationDay", 17, "Day", "int"},
+    {6, "StationDay", 18, "Showing", "object"},
+    {6, "StationDay", 19, "ApgSchedule", "object"},
+    {6, "StationDay", 20, "StartTime", "int"},
+    {6, "StationDay", 21, "Duration", "int"},
+    {7, "Showing", 1, "Version", "int"},
+    {7, "Showing", 2, "Expiration", "int"},
+    {7, "Showing", 3, "Path", "string"},
+    {7, "Showing", 4, "IndexPath", "string"},
+    {7, "Showing", 5, "IndexUsed", "object"},
+    {7, "Showing", 6, "IndexUsedBy", "object"},
+    {7, "Showing", 7, "IndexAttr", "object"},
+    {7, "Showing", 8, "ServerId", "string"},
+    {7, "Showing", 9, "ServerVersion", "int"},
+    {7, "Showing", 10, "Uuid", "string"},
+    {7, "Showing", 11, "Unsatisfied", "string"},
+    {7, "Showing", 12, "Bits", "int"},
+    {7, "Showing", 16, "Program", "object"},
+    {7, "Showing", 17, "Station", "object"},
+    {7, "Showing", 18, "Date", "int"},
+    {7, "Showing", 19, "Time", "int"},
+    {7, "Showing", 20, "Duration", "int"},
+    {7, "Showing", 21, "PartIndex", "int"},
+    {7, "Showing", 22, "PartCount", "int"},
+    {7, "Showing", 23, "Premiere", "int"},
+    {7, "Showing", 24, "Live", "int"},
+    {7, "Showing", 25, "Bits", "int"},
+    {7, "Showing", 26, "Reason", "int"},
+    {7, "Showing", 27, "DontIndex", "int"},
+    {7, "Showing", 28, "TvRating", "int"},
+    {7, "Showing", 29, "SeriesId", "int"},
+    {7, "Showing", 30, "Genre", "int"},
+    {7, "Showing", 31, "Dolby", "int"},
+    {7, "Showing", 32, "ApgScheduleEvent", "object"},
+    {8, "PlaceHolder", 1, "Version", "int"},
+    {8, "PlaceHolder", 2, "Expiration", "int"},
+    {8, "PlaceHolder", 3, "Path", "string"},
+    {8, "PlaceHolder", 4, "IndexPath", "string"},
+    {8, "PlaceHolder", 5, "IndexUsed", "object"},
+    {8, "PlaceHolder", 6, "IndexUsedBy", "object"},
+    {8, "PlaceHolder", 7, "IndexAttr", "object"},
+    {8, "PlaceHolder", 8, "ServerId", "string"},
+    {8, "PlaceHolder", 9, "ServerVersion", "int"},
+    {8, "PlaceHolder", 10, "Uuid", "string"},
+    {8, "PlaceHolder", 11, "Unsatisfied", "string"},
+    {8, "PlaceHolder", 12, "Bits", "int"},
+    {9, "DlWaitingOBSOLETE", 1, "Version", "int"},
+    {9, "DlWaitingOBSOLETE", 2, "Expiration", "int"},
+    {9, "DlWaitingOBSOLETE", 3, "Path", "string"},
+    {9, "DlWaitingOBSOLETE", 4, "IndexPath", "string"},
+    {9, "DlWaitingOBSOLETE", 5, "IndexUsed", "object"},
+    {9, "DlWaitingOBSOLETE", 6, "IndexUsedBy", "object"},
+    {9, "DlWaitingOBSOLETE", 7, "IndexAttr", "object"},
+    {9, "DlWaitingOBSOLETE", 8, "ServerId", "string"},
+    {9, "DlWaitingOBSOLETE", 9, "ServerVersion", "int"},
+    {9, "DlWaitingOBSOLETE", 10, "Uuid", "string"},
+    {9, "DlWaitingOBSOLETE", 11, "Unsatisfied", "string"},
+    {9, "DlWaitingOBSOLETE", 12, "Bits", "int"},
+    {9, "DlWaitingOBSOLETE", 16, "GenericFile", "file"},
+    {10, "LoopSet", 1, "Version", "int"},
+    {10, "LoopSet", 2, "Expiration", "int"},
+    {10, "LoopSet", 3, "Path", "string"},
+    {10, "LoopSet", 4, "IndexPath", "string"},
+    {10, "LoopSet", 5, "IndexUsed", "object"},
+    {10, "LoopSet", 6, "IndexUsedBy", "object"},
+    {10, "LoopSet", 7, "IndexAttr", "object"},
+    {10, "LoopSet", 8, "ServerId", "string"},
+    {10, "LoopSet", 9, "ServerVersion", "int"},
+    {10, "LoopSet", 10, "Uuid", "string"},
+    {10, "LoopSet", 11, "Unsatisfied", "string"},
+    {10, "LoopSet", 12, "Bits", "int"},
+    {10, "LoopSet", 16, "Name", "string"},
+    {10, "LoopSet", 17, "Port", "int"},
+    {10, "LoopSet", 18, "State", "object"},
+    {10, "LoopSet", 19, "Trans", "object"},
+    {11, "LoopSetClip", 1, "Version", "int"},
+    {11, "LoopSetClip", 2, "Expiration", "int"},
+    {11, "LoopSetClip", 3, "Path", "string"},
+    {11, "LoopSetClip", 4, "IndexPath", "string"},
+    {11, "LoopSetClip", 5, "IndexUsed", "object"},
+    {11, "LoopSetClip", 6, "IndexUsedBy", "object"},
+    {11, "LoopSetClip", 7, "IndexAttr", "object"},
+    {11, "LoopSetClip", 8, "ServerId", "string"},
+    {11, "LoopSetClip", 9, "ServerVersion", "int"},
+    {11, "LoopSetClip", 10, "Uuid", "string"},
+    {11, "LoopSetClip", 11, "Unsatisfied", "string"},
+    {11, "LoopSetClip", 12, "Bits", "int"},
+    {11, "LoopSetClip", 16, "Entrance", "int"},
+    {11, "LoopSetClip", 17, "Exit", "int"},
+    {11, "LoopSetClip", 18, "Video", "file"},
+    {11, "LoopSetClip", 19, "VideoClip", "object"},
+    {11, "LoopSetClip", 20, "SubRecording", "object"},
+    {12, "SwSystem", 1, "Version", "int"},
+    {12, "SwSystem", 2, "Expiration", "int"},
+    {12, "SwSystem", 3, "Path", "string"},
+    {12, "SwSystem", 4, "IndexPath", "string"},
+    {12, "SwSystem", 5, "IndexUsed", "object"},
+    {12, "SwSystem", 6, "IndexUsedBy", "object"},
+    {12, "SwSystem", 7, "IndexAttr", "object"},
+    {12, "SwSystem", 8, "ServerId", "string"},
+    {12, "SwSystem", 9, "ServerVersion", "int"},
+    {12, "SwSystem", 10, "Uuid", "string"},
+    {12, "SwSystem", 11, "Unsatisfied", "string"},
+    {12, "SwSystem", 12, "Bits", "int"},
+    {12, "SwSystem", 16, "Name", "string"},
+    {12, "SwSystem", 17, "Active", "int"},
+    {12, "SwSystem", 18, "Module", "object"},
+    {12, "SwSystem", 19, "ResourceGroup", "object"},
+    {12, "SwSystem", 20, "ObjectType", "object"},
+    {12, "SwSystem", 21, "ResourceChecksum", "string"},
+    {12, "SwSystem", 22, "InstalledOBSOLETE", "int"},
+    {12, "SwSystem", 23, "UserInterfaceOBSOLETE", "object"},
+    {13, "SwModule", 1, "Version", "int"},
+    {13, "SwModule", 2, "Expiration", "int"},
+    {13, "SwModule", 3, "Path", "string"},
+    {13, "SwModule", 4, "IndexPath", "string"},
+    {13, "SwModule", 5, "IndexUsed", "object"},
+    {13, "SwModule", 6, "IndexUsedBy", "object"},
+    {13, "SwModule", 7, "IndexAttr", "object"},
+    {13, "SwModule", 8, "ServerId", "string"},
+    {13, "SwModule", 9, "ServerVersion", "int"},
+    {13, "SwModule", 10, "Uuid", "string"},
+    {13, "SwModule", 11, "Unsatisfied", "string"},
+    {13, "SwModule", 12, "Bits", "int"},
+    {13, "SwModule", 16, "Name", "string"},
+    {13, "SwModule", 17, "ModuleVersion", "string"},
+    {13, "SwModule", 18, "ModuleRelease", "string"},
+    {13, "SwModule", 19, "ModuleFile", "file"},
+    {13, "SwModule", 20, "Dependency", "object"},
+    {14, "Recording", 1, "Version", "int"},
+    {14, "Recording", 2, "Expiration", "int"},
+    {14, "Recording", 3, "Path", "string"},
+    {14, "Recording", 4, "IndexPath", "string"},
+    {14, "Recording", 5, "IndexUsed", "object"},
+    {14, "Recording", 6, "IndexUsedBy", "object"},
+    {14, "Recording", 7, "IndexAttr", "object"},
+    {14, "Recording", 8, "ServerId", "string"},
+    {14, "Recording", 9, "ServerVersion", "int"},
+    {14, "Recording", 10, "Uuid", "string"},
+    {14, "Recording", 11, "Unsatisfied", "string"},
+    {14, "Recording", 12, "Bits", "int"},
+    {14, "Recording", 16, "State", "int"},
+    {14, "Recording", 17, "Showing", "object"},
+    {14, "Recording", 18, "SelectionType", "int"},
+    {14, "Recording", 19, "ExpirationDate", "int"},
+    {14, "Recording", 20, "ExpirationTime", "int"},
+    {14, "Recording", 21, "BitRate", "int"},
+    {14, "Recording", 22, "Score", "int"},
+    {14, "Recording", 23, "UnusedAOBSOLETE", "file"},
+    {14, "Recording", 24, "StartDate", "int"},
+    {14, "Recording", 25, "StartTime", "int"},
+    {14, "Recording", 26, "StopDate", "int"},
+    {14, "Recording", 27, "StopTime", "int"},
+    {14, "Recording", 28, "Bookmark", "object"},
+    {14, "Recording", 29, "CancelReason", "int"},
+    {14, "Recording", 30, "CancelDate", "int"},
+    {14, "Recording", 31, "CancelTime", "int"},
+    {14, "Recording", 32, "ExplicitlyDeletedOBSOLETE", "int"},
+    {14, "Recording", 33, "Outage", "object"},
+    {14, "Recording", 34, "Part", "object"},
+    {14, "Recording", 35, "AudioModeOBSOLETE", "int"},
+    {14, "Recording", 36, "ErrorString", "string"},
+    {14, "Recording", 37, "RelatedPrefs", "object"},
+    {14, "Recording", 38, "DeletionDate", "int"},
+    {14, "Recording", 39, "DeletionTime", "int"},
+    {14, "Recording", 40, "RecordQuality", "int"},
+    {14, "Recording", 41, "ContentType", "int"},
+    {14, "Recording", 42, "ProgramSource", "object"},
+    {14, "Recording", 43, "ActualShowing", "object"},
+    {14, "Recording", 44, "StartPadding", "int"},
+    {14, "Recording", 45, "EndPadding", "int"},
+    {14, "Recording", 46, "ConflictsWithRecording", "object"},
+    {14, "Recording", 47, "NSecondsWatched", "int"},
+    {14, "Recording", 48, "NVisit", "int"},
+    {14, "Recording", 49, "SaveToTapeStatus", "int"},
+    {14, "Recording", 50, "CreatedBy", "int"},
+    {14, "Recording", 51, "ServiceRecordingPriority", "int"},
+    {14, "Recording", 52, "Clips", "object"},
+    {14, "Recording", 53, "Anchors", "object"},
+    {14, "Recording", 54, "StreamFileSize", "int"},
+    {14, "Recording", 55, "ExpirationExtended", "int"},
+    {15, "Bookmark", 1, "Version", "int"},
+    {15, "Bookmark", 2, "Expiration", "int"},
+    {15, "Bookmark", 3, "Path", "string"},
+    {15, "Bookmark", 4, "IndexPath", "string"},
+    {15, "Bookmark", 5, "IndexUsed", "object"},
+    {15, "Bookmark", 6, "IndexUsedBy", "object"},
+    {15, "Bookmark", 7, "IndexAttr", "object"},
+    {15, "Bookmark", 8, "ServerId", "string"},
+    {15, "Bookmark", 9, "ServerVersion", "int"},
+    {15, "Bookmark", 10, "Uuid", "string"},
+    {15, "Bookmark", 11, "Unsatisfied", "string"},
+    {15, "Bookmark", 12, "Bits", "int"},
+    {15, "Bookmark", 16, "TimeMs", "int"},
+    {16, "Enum", 1, "Version", "int"},
+    {16, "Enum", 2, "Expiration", "int"},
+    {16, "Enum", 3, "Path", "string"},
+    {16, "Enum", 4, "IndexPath", "string"},
+    {16, "Enum", 5, "IndexUsed", "object"},
+    {16, "Enum", 6, "IndexUsedBy", "object"},
+    {16, "Enum", 7, "IndexAttr", "object"},
+    {16, "Enum", 8, "ServerId", "string"},
+    {16, "Enum", 9, "ServerVersion", "int"},
+    {16, "Enum", 10, "Uuid", "string"},
+    {16, "Enum", 11, "Unsatisfied", "string"},
+    {16, "Enum", 12, "Bits", "int"},
+    {16, "Enum", 16, "Name", "string"},
+    {16, "Enum", 17, "Item", "object"},
+    {17, "EnumItem", 1, "Version", "int"},
+    {17, "EnumItem", 2, "Expiration", "int"},
+    {17, "EnumItem", 3, "Path", "string"},
+    {17, "EnumItem", 4, "IndexPath", "string"},
+    {17, "EnumItem", 5, "IndexUsed", "object"},
+    {17, "EnumItem", 6, "IndexUsedBy", "object"},
+    {17, "EnumItem", 7, "IndexAttr", "object"},
+    {17, "EnumItem", 8, "ServerId", "string"},
+    {17, "EnumItem", 9, "ServerVersion", "int"},
+    {17, "EnumItem", 10, "Uuid", "string"},
+    {17, "EnumItem", 11, "Unsatisfied", "string"},
+    {17, "EnumItem", 12, "Bits", "int"},
+    {17, "EnumItem", 16, "Name", "string"},
+    {17, "EnumItem", 17, "Value", "int"},
+    {17, "EnumItem", 18, "PrintName", "string"},
+    {17, "EnumItem", 19, "AltName", "string"},
+    {18, "Showcase", 1, "Version", "int"},
+    {18, "Showcase", 2, "Expiration", "int"},
+    {18, "Showcase", 3, "Path", "string"},
+    {18, "Showcase", 4, "IndexPath", "string"},
+    {18, "Showcase", 5, "IndexUsed", "object"},
+    {18, "Showcase", 6, "IndexUsedBy", "object"},
+    {18, "Showcase", 7, "IndexAttr", "object"},
+    {18, "Showcase", 8, "ServerId", "string"},
+    {18, "Showcase", 9, "ServerVersion", "int"},
+    {18, "Showcase", 10, "Uuid", "string"},
+    {18, "Showcase", 11, "Unsatisfied", "string"},
+    {18, "Showcase", 12, "Bits", "int"},
+    {18, "Showcase", 16, "Name", "string"},
+    {18, "Showcase", 17, "Icon", "object"},
+    {18, "Showcase", 18, "Banner", "object"},
+    {18, "Showcase", 19, "Item", "object"},
+    {18, "Showcase", 20, "InterstitialType", "int"},
+    {18, "Showcase", 21, "InterstitialId", "int"},
+    {18, "Showcase", 22, "ExpirationDate", "int"},
+    {18, "Showcase", 23, "ExpirationTime", "int"},
+    {18, "Showcase", 24, "TiVolution", "int"},
+    {18, "Showcase", 25, "SequenceNumber", "int"},
+    {18, "Showcase", 26, "InfoBalloon", "int"},
+    {18, "Showcase", 27, "LoopSet", "object"},
+    {18, "Showcase", 28, "AudioBackground", "object"},
+    {18, "Showcase", 29, "AudioBackgroundPriority", "int"},
+    {18, "Showcase", 30, "Mugshot", "object"},
+    {18, "Showcase", 31, "Title", "string"},
+    {18, "Showcase", 32, "Description", "string"},
+    {18, "Showcase", 33, "BigBanner", "object"},
+    {18, "Showcase", 34, "ClipPlayList", "object"},
+    {18, "Showcase", 35, "ClipAvailableIcon", "object"},
+    {18, "Showcase", 36, "LoopSetName", "string"},
+    {18, "Showcase", 37, "AudioBackgroundName", "string"},
+    {18, "Showcase", 38, "NoBanner", "int"},
+    {18, "Showcase", 39, "NoDescriptionBox", "int"},
+    {18, "Showcase", 40, "WienerDisplay", "int"},
+    {19, "ShowcaseItem", 1, "Version", "int"},
+    {19, "ShowcaseItem", 2, "Expiration", "int"},
+    {19, "ShowcaseItem", 3, "Path", "string"},
+    {19, "ShowcaseItem", 4, "IndexPath", "string"},
+    {19, "ShowcaseItem", 5, "IndexUsed", "object"},
+    {19, "ShowcaseItem", 6, "IndexUsedBy", "object"},
+    {19, "ShowcaseItem", 7, "IndexAttr", "object"},
+    {19, "ShowcaseItem", 8, "ServerId", "string"},
+    {19, "ShowcaseItem", 9, "ServerVersion", "int"},
+    {19, "ShowcaseItem", 10, "Uuid", "string"},
+    {19, "ShowcaseItem", 11, "Unsatisfied", "string"},
+    {19, "ShowcaseItem", 12, "Bits", "int"},
+    {19, "ShowcaseItem", 16, "Name", "string"},
+    {19, "ShowcaseItem", 17, "Icon", "object"},
+    {19, "ShowcaseItem", 18, "Package", "object"},
+    {19, "ShowcaseItem", 19, "Program", "object"},
+    {19, "ShowcaseItem", 20, "ExpirationDate", "int"},
+    {19, "ShowcaseItem", 21, "ExpirationTime", "int"},
+    {19, "ShowcaseItem", 22, "Affiliation", "string"},
+    {19, "ShowcaseItem", 23, "Mugshot", "object"},
+    {19, "ShowcaseItem", 24, "Description", "string"},
+    {19, "ShowcaseItem", 25, "SubItemExpirationDate", "int"},
+    {19, "ShowcaseItem", 26, "ClipPlayList", "object"},
+    {20, "Package", 1, "Version", "int"},
+    {20, "Package", 2, "Expiration", "int"},
+    {20, "Package", 3, "Path", "string"},
+    {20, "Package", 4, "IndexPath", "string"},
+    {20, "Package", 5, "IndexUsed", "object"},
+    {20, "Package", 6, "IndexUsedBy", "object"},
+    {20, "Package", 7, "IndexAttr", "object"},
+    {20, "Package", 8, "ServerId", "string"},
+    {20, "Package", 9, "ServerVersion", "int"},
+    {20, "Package", 10, "Uuid", "string"},
+    {20, "Package", 11, "Unsatisfied", "string"},
+    {20, "Package", 12, "Bits", "int"},
+    {20, "Package", 16, "Name", "string"},
+    {20, "Package", 17, "Icon", "object"},
+    {20, "Package", 18, "PreviewOBSOLETE", "object"},
+    {20, "Package", 19, "Item", "object"},
+    {20, "Package", 20, "Banner", "object"},
+    {20, "Package", 21, "InfoBalloon", "int"},
+    {20, "Package", 22, "LoopSet", "object"},
+    {20, "Package", 23, "AudioBackground", "object"},
+    {20, "Package", 24, "AudioBackgroundPriority", "int"},
+    {20, "Package", 25, "ClipPlayList", "object"},
+    {20, "Package", 26, "LoopSetName", "string"},
+    {20, "Package", 27, "AudioBackgroundName", "string"},
+    {20, "Package", 28, "NoBanner", "int"},
+    {20, "Package", 29, "NoDescriptionBox", "int"},
+    {20, "Package", 30, "WienerDisplay", "int"},
+    {21, "PackageItem", 1, "Version", "int"},
+    {21, "PackageItem", 2, "Expiration", "int"},
+    {21, "PackageItem", 3, "Path", "string"},
+    {21, "PackageItem", 4, "IndexPath", "string"},
+    {21, "PackageItem", 5, "IndexUsed", "object"},
+    {21, "PackageItem", 6, "IndexUsedBy", "object"},
+    {21, "PackageItem", 7, "IndexAttr", "object"},
+    {21, "PackageItem", 8, "ServerId", "string"},
+    {21, "PackageItem", 9, "ServerVersion", "int"},
+    {21, "PackageItem", 10, "Uuid", "string"},
+    {21, "PackageItem", 11, "Unsatisfied", "string"},
+    {21, "PackageItem", 12, "Bits", "int"},
+    {21, "PackageItem", 16, "Name", "string"},
+    {21, "PackageItem", 17, "Icon", "object"},
+    {21, "PackageItem", 18, "Program", "object"},
+    {21, "PackageItem", 19, "ExpirationDate", "int"},
+    {21, "PackageItem", 20, "ExpirationTime", "int"},
+    {21, "PackageItem", 21, "Affiliation", "string"},
+    {21, "PackageItem", 22, "Mugshot", "object"},
+    {21, "PackageItem", 23, "Description", "string"},
+    {21, "PackageItem", 24, "Package", "object"},
+    {21, "PackageItem", 25, "SubItemExpirationDate", "int"},
+    {21, "PackageItem", 26, "ClipPlayList", "object"},
+    {22, "Image", 1, "Version", "int"},
+    {22, "Image", 2, "Expiration", "int"},
+    {22, "Image", 3, "Path", "string"},
+    {22, "Image", 4, "IndexPath", "string"},
+    {22, "Image", 5, "IndexUsed", "object"},
+    {22, "Image", 6, "IndexUsedBy", "object"},
+    {22, "Image", 7, "IndexAttr", "object"},
+    {22, "Image", 8, "ServerId", "string"},
+    {22, "Image", 9, "ServerVersion", "int"},
+    {22, "Image", 10, "Uuid", "string"},
+    {22, "Image", 11, "Unsatisfied", "string"},
+    {22, "Image", 12, "Bits", "int"},
+    {22, "Image", 16, "Name", "string"},
+    {22, "Image", 17, "Format", "int"},
+    {22, "Image", 18, "File", "file"},
+    {23, "Headend", 1, "Version", "int"},
+    {23, "Headend", 2, "Expiration", "int"},
+    {23, "Headend", 3, "Path", "string"},
+    {23, "Headend", 4, "IndexPath", "string"},
+    {23, "Headend", 5, "IndexUsed", "object"},
+    {23, "Headend", 6, "IndexUsedBy", "object"},
+    {23, "Headend", 7, "IndexAttr", "object"},
+    {23, "Headend", 8, "ServerId", "string"},
+    {23, "Headend", 9, "ServerVersion", "int"},
+    {23, "Headend", 10, "Uuid", "string"},
+    {23, "Headend", 11, "Unsatisfied", "string"},
+    {23, "Headend", 12, "Bits", "int"},
+    {23, "Headend", 16, "TmsHeadendId", "string"},
+    {23, "Headend", 17, "CommunityName", "string"},
+    {23, "Headend", 18, "CountyName", "string"},
+    {23, "Headend", 19, "State", "string"},
+    {23, "Headend", 20, "PostalCode", "string"},
+    {23, "Headend", 21, "Name", "string"},
+    {23, "Headend", 22, "TimeZone", "int"},
+    {23, "Headend", 23, "Lineup", "object"},
+    {23, "Headend", 24, "EncryptionKeys", "string"},
+    {23, "Headend", 25, "Location", "string"},
+    {23, "Headend", 26, "CityPostalCode", "object"},
+    {24, "Channel", 1, "Version", "int"},
+    {24, "Channel", 2, "Expiration", "int"},
+    {24, "Channel", 3, "Path", "string"},
+    {24, "Channel", 4, "IndexPath", "string"},
+    {24, "Channel", 5, "IndexUsed", "object"},
+    {24, "Channel", 6, "IndexUsedBy", "object"},
+    {24, "Channel", 7, "IndexAttr", "object"},
+    {24, "Channel", 8, "ServerId", "string"},
+    {24, "Channel", 9, "ServerVersion", "int"},
+    {24, "Channel", 10, "Uuid", "string"},
+    {24, "Channel", 11, "Unsatisfied", "string"},
+    {24, "Channel", 12, "Bits", "int"},
+    {24, "Channel", 16, "TmsHeadendId", "string"},
+    {24, "Channel", 17, "Station", "object"},
+    {24, "Channel", 18, "Number", "int"},
+    {24, "Channel", 19, "ServiceTier", "int"},
+    {24, "Channel", 20, "ABChannelOBSOLETE", "int"},
+    {24, "Channel", 21, "SignalOBSOLETE", "int"},
+    {24, "Channel", 22, "Surf", "int"},
+    {24, "Channel", 23, "Record", "int"},
+    {24, "Channel", 24, "Favorite", "int"},
+    {24, "Channel", 25, "SourceIndex", "int"},
+    {24, "Channel", 26, "ApgChannel", "object"},
+    {25, "ResourceGroup", 1, "Version", "int"},
+    {25, "ResourceGroup", 2, "Expiration", "int"},
+    {25, "ResourceGroup", 3, "Path", "string"},
+    {25, "ResourceGroup", 4, "IndexPath", "string"},
+    {25, "ResourceGroup", 5, "IndexUsed", "object"},
+    {25, "ResourceGroup", 6, "IndexUsedBy", "object"},
+    {25, "ResourceGroup", 7, "IndexAttr", "object"},
+    {25, "ResourceGroup", 8, "ServerId", "string"},
+    {25, "ResourceGroup", 9, "ServerVersion", "int"},
+    {25, "ResourceGroup", 10, "Uuid", "string"},
+    {25, "ResourceGroup", 11, "Unsatisfied", "string"},
+    {25, "ResourceGroup", 12, "Bits", "int"},
+    {25, "ResourceGroup", 16, "Id", "int"},
+    {25, "ResourceGroup", 17, "Item", "object"},
+    {25, "ResourceGroup", 18, "CompressedFile", "file"},
+    {26, "ResourceItem", 1, "Version", "int"},
+    {26, "ResourceItem", 2, "Expiration", "int"},
+    {26, "ResourceItem", 3, "Path", "string"},
+    {26, "ResourceItem", 4, "IndexPath", "string"},
+    {26, "ResourceItem", 5, "IndexUsed", "object"},
+    {26, "ResourceItem", 6, "IndexUsedBy", "object"},
+    {26, "ResourceItem", 7, "IndexAttr", "object"},
+    {26, "ResourceItem", 8, "ServerId", "string"},
+    {26, "ResourceItem", 9, "ServerVersion", "int"},
+    {26, "ResourceItem", 10, "Uuid", "string"},
+    {26, "ResourceItem", 11, "Unsatisfied", "string"},
+    {26, "ResourceItem", 12, "Bits", "int"},
+    {26, "ResourceItem", 16, "Id", "int"},
+    {26, "ResourceItem", 17, "String", "string"},
+    {26, "ResourceItem", 18, "Object", "object"},
+    {26, "ResourceItem", 19, "File", "file"},
+    {26, "ResourceItem", 20, "PreLoad", "int"},
+    {27, "IndexAttr", 1, "Version", "int"},
+    {27, "IndexAttr", 2, "Expiration", "int"},
+    {27, "IndexAttr", 3, "Path", "string"},
+    {27, "IndexAttr", 4, "IndexPath", "string"},
+    {27, "IndexAttr", 5, "IndexUsed", "object"},
+    {27, "IndexAttr", 6, "IndexUsedBy", "object"},
+    {27, "IndexAttr", 7, "IndexAttr", "object"},
+    {27, "IndexAttr", 8, "ServerId", "string"},
+    {27, "IndexAttr", 9, "ServerVersion", "int"},
+    {27, "IndexAttr", 10, "Uuid", "string"},
+    {27, "IndexAttr", 11, "Unsatisfied", "string"},
+    {27, "IndexAttr", 12, "Bits", "int"},
+    {27, "IndexAttr", 16, "Target", "object"},
+    {27, "IndexAttr", 17, "Attribute", "int"},
+    {27, "IndexAttr", 18, "Int", "int"},
+    {27, "IndexAttr", 19, "String", "string"},
+    {27, "IndexAttr", 20, "File", "file"},
+    {27, "IndexAttr", 21, "Object", "object"},
+    {28, "PreferencesOBSOLETE", 1, "Version", "int"},
+    {28, "PreferencesOBSOLETE", 2, "Expiration", "int"},
+    {28, "PreferencesOBSOLETE", 3, "Path", "string"},
+    {28, "PreferencesOBSOLETE", 4, "IndexPath", "string"},
+    {28, "PreferencesOBSOLETE", 5, "IndexUsed", "object"},
+    {28, "PreferencesOBSOLETE", 6, "IndexUsedBy", "object"},
+    {28, "PreferencesOBSOLETE", 7, "IndexAttr", "object"},
+    {28, "PreferencesOBSOLETE", 8, "ServerId", "string"},
+    {28, "PreferencesOBSOLETE", 9, "ServerVersion", "int"},
+    {28, "PreferencesOBSOLETE", 10, "Uuid", "string"},
+    {28, "PreferencesOBSOLETE", 11, "Unsatisfied", "string"},
+    {28, "PreferencesOBSOLETE", 12, "Bits", "int"},
+    {28, "PreferencesOBSOLETE", 16, "Progprefs", "object"},
+    {29, "ProgprefsOBSOLETE", 1, "Version", "int"},
+    {29, "ProgprefsOBSOLETE", 2, "Expiration", "int"},
+    {29, "ProgprefsOBSOLETE", 3, "Path", "string"},
+    {29, "ProgprefsOBSOLETE", 4, "IndexPath", "string"},
+    {29, "ProgprefsOBSOLETE", 5, "IndexUsed", "object"},
+    {29, "ProgprefsOBSOLETE", 6, "IndexUsedBy", "object"},
+    {29, "ProgprefsOBSOLETE", 7, "IndexAttr", "object"},
+    {29, "ProgprefsOBSOLETE", 8, "ServerId", "string"},
+    {29, "ProgprefsOBSOLETE", 9, "ServerVersion", "int"},
+    {29, "ProgprefsOBSOLETE", 10, "Uuid", "string"},
+    {29, "ProgprefsOBSOLETE", 11, "Unsatisfied", "string"},
+    {29, "ProgprefsOBSOLETE", 12, "Bits", "int"},
+    {29, "ProgprefsOBSOLETE", 16, "ShowType", "object"},
+    {29, "ProgprefsOBSOLETE", 17, "MpaaRating", "object"},
+    {29, "ProgprefsOBSOLETE", 18, "Country", "object"},
+    {29, "ProgprefsOBSOLETE", 19, "NetworkSource", "object"},
+    {29, "ProgprefsOBSOLETE", 20, "SourceType", "object"},
+    {29, "ProgprefsOBSOLETE", 21, "Advisory", "object"},
+    {29, "ProgprefsOBSOLETE", 22, "Actor", "object"},
+    {29, "ProgprefsOBSOLETE", 23, "GuestStar", "object"},
+    {29, "ProgprefsOBSOLETE", 24, "Director", "object"},
+    {29, "ProgprefsOBSOLETE", 25, "ExecProducer", "object"},
+    {29, "ProgprefsOBSOLETE", 26, "Producer", "object"},
+    {29, "ProgprefsOBSOLETE", 27, "Writer", "object"},
+    {29, "ProgprefsOBSOLETE", 28, "Host", "object"},
+    {29, "ProgprefsOBSOLETE", 29, "Genre", "object"},
+    {30, "IntMatchPrefOBSOLETE", 1, "Version", "int"},
+    {30, "IntMatchPrefOBSOLETE", 2, "Expiration", "int"},
+    {30, "IntMatchPrefOBSOLETE", 3, "Path", "string"},
+    {30, "IntMatchPrefOBSOLETE", 4, "IndexPath", "string"},
+    {30, "IntMatchPrefOBSOLETE", 5, "IndexUsed", "object"},
+    {30, "IntMatchPrefOBSOLETE", 6, "IndexUsedBy", "object"},
+    {30, "IntMatchPrefOBSOLETE", 7, "IndexAttr", "object"},
+    {30, "IntMatchPrefOBSOLETE", 8, "ServerId", "string"},
+    {30, "IntMatchPrefOBSOLETE", 9, "ServerVersion", "int"},
+    {30, "IntMatchPrefOBSOLETE", 10, "Uuid", "string"},
+    {30, "IntMatchPrefOBSOLETE", 11, "Unsatisfied", "string"},
+    {30, "IntMatchPrefOBSOLETE", 12, "Bits", "int"},
+    {30, "IntMatchPrefOBSOLETE", 16, "Value", "int"},
+    {30, "IntMatchPrefOBSOLETE", 17, "Points", "int"},
+    {31, "StringMatchPrefOBSOLETE", 1, "Version", "int"},
+    {31, "StringMatchPrefOBSOLETE", 2, "Expiration", "int"},
+    {31, "StringMatchPrefOBSOLETE", 3, "Path", "string"},
+    {31, "StringMatchPrefOBSOLETE", 4, "IndexPath", "string"},
+    {31, "StringMatchPrefOBSOLETE", 5, "IndexUsed", "object"},
+    {31, "StringMatchPrefOBSOLETE", 6, "IndexUsedBy", "object"},
+    {31, "StringMatchPrefOBSOLETE", 7, "IndexAttr", "object"},
+    {31, "StringMatchPrefOBSOLETE", 8, "ServerId", "string"},
+    {31, "StringMatchPrefOBSOLETE", 9, "ServerVersion", "int"},
+    {31, "StringMatchPrefOBSOLETE", 10, "Uuid", "string"},
+    {31, "StringMatchPrefOBSOLETE", 11, "Unsatisfied", "string"},
+    {31, "StringMatchPrefOBSOLETE", 12, "Bits", "int"},
+    {31, "StringMatchPrefOBSOLETE", 16, "Value", "string"},
+    {31, "StringMatchPrefOBSOLETE", 17, "Points", "int"},
+    {32, "Font", 1, "Version", "int"},
+    {32, "Font", 2, "Expiration", "int"},
+    {32, "Font", 3, "Path", "string"},
+    {32, "Font", 4, "IndexPath", "string"},
+    {32, "Font", 5, "IndexUsed", "object"},
+    {32, "Font", 6, "IndexUsedBy", "object"},
+    {32, "Font", 7, "IndexAttr", "object"},
+    {32, "Font", 8, "ServerId", "string"},
+    {32, "Font", 9, "ServerVersion", "int"},
+    {32, "Font", 10, "Uuid", "string"},
+    {32, "Font", 11, "Unsatisfied", "string"},
+    {32, "Font", 12, "Bits", "int"},
+    {32, "Font", 16, "Name", "string"},
+    {32, "Font", 17, "Format", "int"},
+    {32, "Font", 18, "Font", "file"},
+    {33, "ActorOBSOLETE", 1, "Version", "int"},
+    {33, "ActorOBSOLETE", 2, "Expiration", "int"},
+    {33, "ActorOBSOLETE", 3, "Path", "string"},
+    {33, "ActorOBSOLETE", 4, "IndexPath", "string"},
+    {33, "ActorOBSOLETE", 5, "IndexUsed", "object"},
+    {33, "ActorOBSOLETE", 6, "IndexUsedBy", "object"},
+    {33, "ActorOBSOLETE", 7, "IndexAttr", "object"},
+    {33, "ActorOBSOLETE", 8, "ServerId", "string"},
+    {33, "ActorOBSOLETE", 9, "ServerVersion", "int"},
+    {33, "ActorOBSOLETE", 10, "Uuid", "string"},
+    {33, "ActorOBSOLETE", 11, "Unsatisfied", "string"},
+    {33, "ActorOBSOLETE", 12, "Bits", "int"},
+    {33, "ActorOBSOLETE", 16, "Name", "string"},
+    {34, "Outage", 1, "Version", "int"},
+    {34, "Outage", 2, "Expiration", "int"},
+    {34, "Outage", 3, "Path", "string"},
+    {34, "Outage", 4, "IndexPath", "string"},
+    {34, "Outage", 5, "IndexUsed", "object"},
+    {34, "Outage", 6, "IndexUsedBy", "object"},
+    {34, "Outage", 7, "IndexAttr", "object"},
+    {34, "Outage", 8, "ServerId", "string"},
+    {34, "Outage", 9, "ServerVersion", "int"},
+    {34, "Outage", 10, "Uuid", "string"},
+    {34, "Outage", 11, "Unsatisfied", "string"},
+    {34, "Outage", 12, "Bits", "int"},
+    {34, "Outage", 16, "Reason", "int"},
+    {34, "Outage", 17, "StartTimeMs", "int"},
+    {34, "Outage", 18, "DurationMs", "int"},
+    {35, "ScheduledActionOBSOLETE", 1, "Version", "int"},
+    {35, "ScheduledActionOBSOLETE", 2, "Expiration", "int"},
+    {35, "ScheduledActionOBSOLETE", 3, "Path", "string"},
+    {35, "ScheduledActionOBSOLETE", 4, "IndexPath", "string"},
+    {35, "ScheduledActionOBSOLETE", 5, "IndexUsed", "object"},
+    {35, "ScheduledActionOBSOLETE", 6, "IndexUsedBy", "object"},
+    {35, "ScheduledActionOBSOLETE", 7, "IndexAttr", "object"},
+    {35, "ScheduledActionOBSOLETE", 8, "ServerId", "string"},
+    {35, "ScheduledActionOBSOLETE", 9, "ServerVersion", "int"},
+    {35, "ScheduledActionOBSOLETE", 10, "Uuid", "string"},
+    {35, "ScheduledActionOBSOLETE", 11, "Unsatisfied", "string"},
+    {35, "ScheduledActionOBSOLETE", 12, "Bits", "int"},
+    {35, "ScheduledActionOBSOLETE", 16, "Date", "int"},
+    {35, "ScheduledActionOBSOLETE", 17, "Time", "int"},
+    {35, "ScheduledActionOBSOLETE", 18, "Action", "int"},
+    {35, "ScheduledActionOBSOLETE", 19, "Recording", "object"},
+    {35, "ScheduledActionOBSOLETE", 20, "ToDelete", "object"},
+    {36, "ViewerEventGroupOBSOLETE", 1, "Version", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 2, "Expiration", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 3, "Path", "string"},
+    {36, "ViewerEventGroupOBSOLETE", 4, "IndexPath", "string"},
+    {36, "ViewerEventGroupOBSOLETE", 5, "IndexUsed", "object"},
+    {36, "ViewerEventGroupOBSOLETE", 6, "IndexUsedBy", "object"},
+    {36, "ViewerEventGroupOBSOLETE", 7, "IndexAttr", "object"},
+    {36, "ViewerEventGroupOBSOLETE", 8, "ServerId", "string"},
+    {36, "ViewerEventGroupOBSOLETE", 9, "ServerVersion", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 10, "Uuid", "string"},
+    {36, "ViewerEventGroupOBSOLETE", 11, "Unsatisfied", "string"},
+    {36, "ViewerEventGroupOBSOLETE", 12, "Bits", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 16, "Date", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 17, "Time", "int"},
+    {36, "ViewerEventGroupOBSOLETE", 18, "Event", "object"},
+    {36, "ViewerEventGroupOBSOLETE", 19, "ViewerId", "int"},
+    {37, "ViewerEventOBSOLETE", 1, "Version", "int"},
+    {37, "ViewerEventOBSOLETE", 2, "Expiration", "int"},
+    {37, "ViewerEventOBSOLETE", 3, "Path", "string"},
+    {37, "ViewerEventOBSOLETE", 4, "IndexPath", "string"},
+    {37, "ViewerEventOBSOLETE", 5, "IndexUsed", "object"},
+    {37, "ViewerEventOBSOLETE", 6, "IndexUsedBy", "object"},
+    {37, "ViewerEventOBSOLETE", 7, "IndexAttr", "object"},
+    {37, "ViewerEventOBSOLETE", 8, "ServerId", "string"},
+    {37, "ViewerEventOBSOLETE", 9, "ServerVersion", "int"},
+    {37, "ViewerEventOBSOLETE", 10, "Uuid", "string"},
+    {37, "ViewerEventOBSOLETE", 11, "Unsatisfied", "string"},
+    {37, "ViewerEventOBSOLETE", 12, "Bits", "int"},
+    {37, "ViewerEventOBSOLETE", 16, "DateOfEvent", "int"},
+    {37, "ViewerEventOBSOLETE", 17, "TimeOfEvent", "int"},
+    {37, "ViewerEventOBSOLETE", 18, "DateOfContent", "int"},
+    {37, "ViewerEventOBSOLETE", 19, "TimeOfContent", "int"},
+    {37, "ViewerEventOBSOLETE", 20, "Action", "int"},
+    {37, "ViewerEventOBSOLETE", 21, "StationTmsId", "string"},
+    {38, "UnusedOBSOLETE", 1, "Version", "int"},
+    {38, "UnusedOBSOLETE", 2, "Expiration", "int"},
+    {38, "UnusedOBSOLETE", 3, "Path", "string"},
+    {38, "UnusedOBSOLETE", 4, "IndexPath", "string"},
+    {38, "UnusedOBSOLETE", 5, "IndexUsed", "object"},
+    {38, "UnusedOBSOLETE", 6, "IndexUsedBy", "object"},
+    {38, "UnusedOBSOLETE", 7, "IndexAttr", "object"},
+    {38, "UnusedOBSOLETE", 8, "ServerId", "string"},
+    {38, "UnusedOBSOLETE", 9, "ServerVersion", "int"},
+    {38, "UnusedOBSOLETE", 10, "Uuid", "string"},
+    {38, "UnusedOBSOLETE", 11, "Unsatisfied", "string"},
+    {38, "UnusedOBSOLETE", 12, "Bits", "int"},
+    {39, "RecordingPart", 1, "Version", "int"},
+    {39, "RecordingPart", 2, "Expiration", "int"},
+    {39, "RecordingPart", 3, "Path", "string"},
+    {39, "RecordingPart", 4, "IndexPath", "string"},
+    {39, "RecordingPart", 5, "IndexUsed", "object"},
+    {39, "RecordingPart", 6, "IndexUsedBy", "object"},
+    {39, "RecordingPart", 7, "IndexAttr", "object"},
+    {39, "RecordingPart", 8, "ServerId", "string"},
+    {39, "RecordingPart", 9, "ServerVersion", "int"},
+    {39, "RecordingPart", 10, "Uuid", "string"},
+    {39, "RecordingPart", 11, "Unsatisfied", "string"},
+    {39, "RecordingPart", 12, "Bits", "int"},
+    {39, "RecordingPart", 16, "Begin", "int"},
+    {39, "RecordingPart", 17, "End", "int"},
+    {39, "RecordingPart", 18, "File", "file"},
+    {39, "RecordingPart", 19, "Checksum", "string"},
+    {39, "RecordingPart", 20, "ScrambleKey", "int"},
+    {40, "ObjectType", 1, "Version", "int"},
+    {40, "ObjectType", 2, "Expiration", "int"},
+    {40, "ObjectType", 3, "Path", "string"},
+    {40, "ObjectType", 4, "IndexPath", "string"},
+    {40, "ObjectType", 5, "IndexUsed", "object"},
+    {40, "ObjectType", 6, "IndexUsedBy", "object"},
+    {40, "ObjectType", 7, "IndexAttr", "object"},
+    {40, "ObjectType", 8, "ServerId", "string"},
+    {40, "ObjectType", 9, "ServerVersion", "int"},
+    {40, "ObjectType", 10, "Uuid", "string"},
+    {40, "ObjectType", 11, "Unsatisfied", "string"},
+    {40, "ObjectType", 12, "Bits", "int"},
+    {40, "ObjectType", 16, "Name", "string"},
+    {40, "ObjectType", 17, "Index", "int"},
+    {40, "ObjectType", 18, "Attribute", "object"},
+    {40, "ObjectType", 19, "Subobject", "int"},
+    {40, "ObjectType", 20, "Derived", "int"},
+    {40, "ObjectType", 21, "Obsolete", "int"},
+    {41, "ObjectAttribute", 1, "Version", "int"},
+    {41, "ObjectAttribute", 2, "Expiration", "int"},
+    {41, "ObjectAttribute", 3, "Path", "string"},
+    {41, "ObjectAttribute", 4, "IndexPath", "string"},
+    {41, "ObjectAttribute", 5, "IndexUsed", "object"},
+    {41, "ObjectAttribute", 6, "IndexUsedBy", "object"},
+    {41, "ObjectAttribute", 7, "IndexAttr", "object"},
+    {41, "ObjectAttribute", 8, "ServerId", "string"},
+    {41, "ObjectAttribute", 9, "ServerVersion", "int"},
+    {41, "ObjectAttribute", 10, "Uuid", "string"},
+    {41, "ObjectAttribute", 11, "Unsatisfied", "string"},
+    {41, "ObjectAttribute", 12, "Bits", "int"},
+    {41, "ObjectAttribute", 16, "Name", "string"},
+    {41, "ObjectAttribute", 17, "Index", "int"},
+    {41, "ObjectAttribute", 18, "Type", "int"},
+    {41, "ObjectAttribute", 19, "Subtype", "string"},
+    {41, "ObjectAttribute", 20, "Arity", "int"},
+    {41, "ObjectAttribute", 21, "Dependency", "int"},
+    {41, "ObjectAttribute", 22, "Level", "int"},
+    {41, "ObjectAttribute", 23, "Subobject", "int"},
+    {41, "ObjectAttribute", 24, "Deprecated", "int"},
+    {41, "ObjectAttribute", 25, "DefaultInt", "int"},
+    {41, "ObjectAttribute", 26, "DefaultString", "string"},
+    {42, "SignalSource", 1, "Version", "int"},
+    {42, "SignalSource", 2, "Expiration", "int"},
+    {42, "SignalSource", 3, "Path", "string"},
+    {42, "SignalSource", 4, "IndexPath", "string"},
+    {42, "SignalSource", 5, "IndexUsed", "object"},
+    {42, "SignalSource", 6, "IndexUsedBy", "object"},
+    {42, "SignalSource", 7, "IndexAttr", "object"},
+    {42, "SignalSource", 8, "ServerId", "string"},
+    {42, "SignalSource", 9, "ServerVersion", "int"},
+    {42, "SignalSource", 10, "Uuid", "string"},
+    {42, "SignalSource", 11, "Unsatisfied", "string"},
+    {42, "SignalSource", 12, "Bits", "int"},
+    {42, "SignalSource", 16, "SignalType", "int"},
+    {42, "SignalSource", 17, "ProviderName", "string"},
+    {42, "SignalSource", 18, "Connector", "int"},
+    {42, "SignalSource", 19, "Channel", "object"},
+    {42, "SignalSource", 20, "Headend", "object"},
+    {42, "SignalSource", 21, "Component", "object"},
+    {42, "SignalSource", 22, "ComponentCode", "object"},
+    {42, "SignalSource", 23, "Lineup", "object"},
+    {42, "SignalSource", 24, "LineupSubId", "int"},
+    {42, "SignalSource", 25, "RFChannel", "int"},
+    {42, "SignalSource", 26, "DBSRemoteMethod", "int"},
+    {42, "SignalSource", 27, "EnterKeyRequired", "int"},
+    {42, "SignalSource", 28, "RecieverNumDigits", "int"},
+    {42, "SignalSource", 29, "CableBoxCodeNum", "int"},
+    {42, "SignalSource", 30, "Inventory", "string"},
+    {42, "SignalSource", 31, "TunerDigitDelay", "int"},
+    {42, "SignalSource", 32, "UnattendedTunerDigitDelay", "int"},
+    {42, "SignalSource", 33, "LineupType", "int"},
+    {42, "SignalSource", 34, "ChannelCloset", "object"},
+    {42, "SignalSource", 35, "CableBoxBrand", "string"},
+    {42, "SignalSource", 36, "VariableBitrate", "int"},
+    {43, "Setup", 1, "Version", "int"},
+    {43, "Setup", 2, "Expiration", "int"},
+    {43, "Setup", 3, "Path", "string"},
+    {43, "Setup", 4, "IndexPath", "string"},
+    {43, "Setup", 5, "IndexUsed", "object"},
+    {43, "Setup", 6, "IndexUsedBy", "object"},
+    {43, "Setup", 7, "IndexAttr", "object"},
+    {43, "Setup", 8, "ServerId", "string"},
+    {43, "Setup", 9, "ServerVersion", "int"},
+    {43, "Setup", 10, "Uuid", "string"},
+    {43, "Setup", 11, "Unsatisfied", "string"},
+    {43, "Setup", 12, "Bits", "int"},
+    {43, "Setup", 16, "PostalCode", "string"},
+    {43, "Setup", 17, "Source", "object"},
+    {43, "Setup", 18, "TimeZone", "int"},
+    {43, "Setup", 19, "DaylightSavingsPolicy", "int"},
+    {43, "Setup", 20, "SoundVolume", "int"},
+    {43, "Setup", 21, "PhoneNumber", "string"},
+    {43, "Setup", 22, "NetConnection", "int"},
+    {43, "Setup", 23, "CableType", "int"},
+    {43, "Setup", 24, "EncryptionKeys", "string"},
+    {43, "Setup", 25, "LastChannelNum", "int"},
+    {43, "Setup", 26, "AudioSource", "int"},
+    {43, "Setup", 27, "MusicVolume", "int"},
+    {43, "Setup", 28, "LastCallAttempt", "int"},
+    {43, "Setup", 29, "LastSuccessCall", "int"},
+    {43, "Setup", 30, "DebugMode", "int"},
+    {43, "Setup", 31, "DemoMode", "int"},
+    {43, "Setup", 32, "LastCallStatus", "string"},
+    {43, "Setup", 33, "RecordQuality", "int"},
+    {43, "Setup", 34, "Complete", "int"},
+    {43, "Setup", 35, "NextCallAttempt", "int"},
+    {43, "Setup", 36, "LocalAccessDigit", "int"},
+    {43, "Setup", 37, "LongDistAccessDigit", "int"},
+    {43, "Setup", 38, "DisableCallWaiting", "int"},
+    {43, "Setup", 39, "DisableCallWaitingCode", "int"},
+    {43, "Setup", 40, "HasPulseDialing", "int"},
+    {43, "Setup", 41, "AreaCodeOBSOLETE", "int"},
+    {43, "Setup", 42, "CountryCode", "int"},
+    {43, "Setup", 43, "InventoryFile", "string"},
+    {43, "Setup", 44, "NoPrivateBackhaul", "int"},
+    {43, "Setup", 45, "ServiceState", "int"},
+    {43, "Setup", 46, "ServiceStateExpiration", "int"},
+    {43, "Setup", 47, "BackgroundHour", "int"},
+    {43, "Setup", 48, "SerialNumber", "string"},
+    {43, "Setup", 49, "DisableAutoRec", "int"},
+    {43, "Setup", 50, "ServiceInfo", "object"},
+    {43, "Setup", 51, "DialPrefix", "string"},
+    {43, "Setup", 52, "DialMethod", "int"},
+    {43, "Setup", 53, "DialHookCheck", "int"},
+    {43, "Setup", 54, "DialToneCheck", "int"},
+    {43, "Setup", 55, "CallWaitingPrefix", "string"},
+    {43, "Setup", 56, "LastChannel", "object"},
+    {43, "Setup", 57, "DemoModeKeyOBSOLETE", "int"},
+    {43, "Setup", 58, "BannerTimeout", "int"},
+    {43, "Setup", 59, "LoopingDemoModeOBSOLETE", "int"},
+    {43, "Setup", 60, "ThumbsLogMagicNumber", "int"},
+    {43, "Setup", 61, "AdvancedTheme", "int"},
+    {43, "Setup", 62, "RemoteAddress", "int"},
+    {43, "Setup", 63, "VCRIrCodeNum", "int"},
+    {43, "Setup", 64, "SetupDate", "int"},
+    {43, "Setup", 65, "DolbyDigital", "int"},
+    {43, "Setup", 66, "AudioLanguage", "int"},
+    {43, "Setup", 67, "AspectRatio", "int"},
+    {43, "Setup", 68, "RFOutputChannel", "int"},
+    {43, "Setup", 69, "ScartSettings", "object"},
+    {43, "Setup", 70, "FrontIRBlaster", "int"},
+    {43, "Setup", 71, "AlternateBitrates", "int"},
+    {43, "Setup", 72, "TunerCount", "int"},
+    {44, "HeadendDayOBSOLETE", 1, "Version", "int"},
+    {44, "HeadendDayOBSOLETE", 2, "Expiration", "int"},
+    {44, "HeadendDayOBSOLETE", 3, "Path", "string"},
+    {44, "HeadendDayOBSOLETE", 4, "IndexPath", "string"},
+    {44, "HeadendDayOBSOLETE", 5, "IndexUsed", "object"},
+    {44, "HeadendDayOBSOLETE", 6, "IndexUsedBy", "object"},
+    {44, "HeadendDayOBSOLETE", 7, "IndexAttr", "object"},
+    {44, "HeadendDayOBSOLETE", 8, "ServerId", "string"},
+    {44, "HeadendDayOBSOLETE", 9, "ServerVersion", "int"},
+    {44, "HeadendDayOBSOLETE", 10, "Uuid", "string"},
+    {44, "HeadendDayOBSOLETE", 11, "Unsatisfied", "string"},
+    {44, "HeadendDayOBSOLETE", 12, "Bits", "int"},
+    {44, "HeadendDayOBSOLETE", 16, "Headend", "object"},
+    {44, "HeadendDayOBSOLETE", 17, "StationDay", "object"},
+    {45, "Lineup", 1, "Version", "int"},
+    {45, "Lineup", 2, "Expiration", "int"},
+    {45, "Lineup", 3, "Path", "string"},
+    {45, "Lineup", 4, "IndexPath", "string"},
+    {45, "Lineup", 5, "IndexUsed", "object"},
+    {45, "Lineup", 6, "IndexUsedBy", "object"},
+    {45, "Lineup", 7, "IndexAttr", "object"},
+    {45, "Lineup", 8, "ServerId", "string"},
+    {45, "Lineup", 9, "ServerVersion", "int"},
+    {45, "Lineup", 10, "Uuid", "string"},
+    {45, "Lineup", 11, "Unsatisfied", "string"},
+    {45, "Lineup", 12, "Bits", "int"},
+    {45, "Lineup", 16, "Name", "string"},
+    {45, "Lineup", 17, "Type", "int"},
+    {45, "Lineup", 18, "Channel", "object"},
+    {46, "ComponentCode", 1, "Version", "int"},
+    {46, "ComponentCode", 2, "Expiration", "int"},
+    {46, "ComponentCode", 3, "Path", "string"},
+    {46, "ComponentCode", 4, "IndexPath", "string"},
+    {46, "ComponentCode", 5, "IndexUsed", "object"},
+    {46, "ComponentCode", 6, "IndexUsedBy", "object"},
+    {46, "ComponentCode", 7, "IndexAttr", "object"},
+    {46, "ComponentCode", 8, "ServerId", "string"},
+    {46, "ComponentCode", 9, "ServerVersion", "int"},
+    {46, "ComponentCode", 10, "Uuid", "string"},
+    {46, "ComponentCode", 11, "Unsatisfied", "string"},
+    {46, "ComponentCode", 12, "Bits", "int"},
+    {46, "ComponentCode", 16, "Name", "string"},
+    {46, "ComponentCode", 17, "Code", "string"},
+    {47, "Component", 1, "Version", "int"},
+    {47, "Component", 2, "Expiration", "int"},
+    {47, "Component", 3, "Path", "string"},
+    {47, "Component", 4, "IndexPath", "string"},
+    {47, "Component", 5, "IndexUsed", "object"},
+    {47, "Component", 6, "IndexUsedBy", "object"},
+    {47, "Component", 7, "IndexAttr", "object"},
+    {47, "Component", 8, "ServerId", "string"},
+    {47, "Component", 9, "ServerVersion", "int"},
+    {47, "Component", 10, "Uuid", "string"},
+    {47, "Component", 11, "Unsatisfied", "string"},
+    {47, "Component", 12, "Bits", "int"},
+    {47, "Component", 16, "Name", "string"},
+    {47, "Component", 17, "Type", "int"},
+    {47, "Component", 18, "Code", "object"},
+    {48, "SeasonPass", 1, "Version", "int"},
+    {48, "SeasonPass", 2, "Expiration", "int"},
+    {48, "SeasonPass", 3, "Path", "string"},
+    {48, "SeasonPass", 4, "IndexPath", "string"},
+    {48, "SeasonPass", 5, "IndexUsed", "object"},
+    {48, "SeasonPass", 6, "IndexUsedBy", "object"},
+    {48, "SeasonPass", 7, "IndexAttr", "object"},
+    {48, "SeasonPass", 8, "ServerId", "string"},
+    {48, "SeasonPass", 9, "ServerVersion", "int"},
+    {48, "SeasonPass", 10, "Uuid", "string"},
+    {48, "SeasonPass", 11, "Unsatisfied", "string"},
+    {48, "SeasonPass", 12, "Bits", "int"},
+    {48, "SeasonPass", 16, "Series", "object"},
+    {48, "SeasonPass", 17, "Program", "object"},
+    {48, "SeasonPass", 18, "Station", "object"},
+    {48, "SeasonPass", 19, "ProcessedOBSOLETE", "object"},
+    {48, "SeasonPass", 20, "ProcessedDate", "int"},
+    {48, "SeasonPass", 21, "ProcessedTime", "int"},
+    {48, "SeasonPass", 22, "RecordQuality", "int"},
+    {48, "SeasonPass", 23, "Type", "int"},
+    {48, "SeasonPass", 24, "DayOfWeekOBSOLETE", "int"},
+    {48, "SeasonPass", 25, "Duration", "int"},
+    {48, "SeasonPass", 26, "StartTimeOBSOLETE", "int"},
+    {48, "SeasonPass", 27, "DayOfWeekLocal", "int"},
+    {48, "SeasonPass", 28, "StartTimeLocal", "int"},
+    {48, "SeasonPass", 29, "MaxRecordings", "int"},
+    {48, "SeasonPass", 30, "KeepTime", "int"},
+    {48, "SeasonPass", 31, "Priority", "int"},
+    {48, "SeasonPass", 32, "ProcessedStation", "object"},
+    {48, "SeasonPass", 33, "StartTimePadding", "int"},
+    {48, "SeasonPass", 34, "EndTimePadding", "int"},
+    {48, "SeasonPass", 35, "Theme", "object"},
+    {48, "SeasonPass", 36, "FirstRun", "int"},
+    {48, "SeasonPass", 37, "CaptureRequest", "object"},
+    {49, "SoundFile", 1, "Version", "int"},
+    {49, "SoundFile", 2, "Expiration", "int"},
+    {49, "SoundFile", 3, "Path", "string"},
+    {49, "SoundFile", 4, "IndexPath", "string"},
+    {49, "SoundFile", 5, "IndexUsed", "object"},
+    {49, "SoundFile", 6, "IndexUsedBy", "object"},
+    {49, "SoundFile", 7, "IndexAttr", "object"},
+    {49, "SoundFile", 8, "ServerId", "string"},
+    {49, "SoundFile", 9, "ServerVersion", "int"},
+    {49, "SoundFile", 10, "Uuid", "string"},
+    {49, "SoundFile", 11, "Unsatisfied", "string"},
+    {49, "SoundFile", 12, "Bits", "int"},
+    {49, "SoundFile", 16, "Name", "string"},
+    {49, "SoundFile", 17, "Format", "int"},
+    {49, "SoundFile", 18, "Sound", "file"},
+    {50, "PostalCode", 1, "Version", "int"},
+    {50, "PostalCode", 2, "Expiration", "int"},
+    {50, "PostalCode", 3, "Path", "string"},
+    {50, "PostalCode", 4, "IndexPath", "string"},
+    {50, "PostalCode", 5, "IndexUsed", "object"},
+    {50, "PostalCode", 6, "IndexUsedBy", "object"},
+    {50, "PostalCode", 7, "IndexAttr", "object"},
+    {50, "PostalCode", 8, "ServerId", "string"},
+    {50, "PostalCode", 9, "ServerVersion", "int"},
+    {50, "PostalCode", 10, "Uuid", "string"},
+    {50, "PostalCode", 11, "Unsatisfied", "string"},
+    {50, "PostalCode", 12, "Bits", "int"},
+    {50, "PostalCode", 16, "PostalCode", "string"},
+    {50, "PostalCode", 17, "Headend", "object"},
+    {50, "PostalCode", 18, "Location", "string"},
+    {51, "PrefsElement", 1, "Version", "int"},
+    {51, "PrefsElement", 2, "Expiration", "int"},
+    {51, "PrefsElement", 3, "Path", "string"},
+    {51, "PrefsElement", 4, "IndexPath", "string"},
+    {51, "PrefsElement", 5, "IndexUsed", "object"},
+    {51, "PrefsElement", 6, "IndexUsedBy", "object"},
+    {51, "PrefsElement", 7, "IndexAttr", "object"},
+    {51, "PrefsElement", 8, "ServerId", "string"},
+    {51, "PrefsElement", 9, "ServerVersion", "int"},
+    {51, "PrefsElement", 10, "Uuid", "string"},
+    {51, "PrefsElement", 11, "Unsatisfied", "string"},
+    {51, "PrefsElement", 12, "Bits", "int"},
+    {51, "PrefsElement", 16, "Viewer", "string"},
+    {51, "PrefsElement", 17, "Type", "int"},
+    {51, "PrefsElement", 18, "Thumbsness", "int"},
+    {51, "PrefsElement", 19, "IntKeyValue", "int"},
+    {51, "PrefsElement", 20, "StringKeyValue", "string"},
+    {51, "PrefsElement", 21, "Points", "int"},
+    {51, "PrefsElement", 22, "Item", "object"},
+    {51, "PrefsElement", 23, "Vector", "int"},
+    {52, "Person", 1, "Version", "int"},
+    {52, "Person", 2, "Expiration", "int"},
+    {52, "Person", 3, "Path", "string"},
+    {52, "Person", 4, "IndexPath", "string"},
+    {52, "Person", 5, "IndexUsed", "object"},
+    {52, "Person", 6, "IndexUsedBy", "object"},
+    {52, "Person", 7, "IndexAttr", "object"},
+    {52, "Person", 8, "ServerId", "string"},
+    {52, "Person", 9, "ServerVersion", "int"},
+    {52, "Person", 10, "Uuid", "string"},
+    {52, "Person", 11, "Unsatisfied", "string"},
+    {52, "Person", 12, "Bits", "int"},
+    {52, "Person", 16, "Name", "string"},
+    {52, "Person", 17, "Role", "int"},
+    {52, "Person", 18, "Star", "int"},
+    {53, "Genre", 1, "Version", "int"},
+    {53, "Genre", 2, "Expiration", "int"},
+    {53, "Genre", 3, "Path", "string"},
+    {53, "Genre", 4, "IndexPath", "string"},
+    {53, "Genre", 5, "IndexUsed", "object"},
+    {53, "Genre", 6, "IndexUsedBy", "object"},
+    {53, "Genre", 7, "IndexAttr", "object"},
+    {53, "Genre", 8, "ServerId", "string"},
+    {53, "Genre", 9, "ServerVersion", "int"},
+    {53, "Genre", 10, "Uuid", "string"},
+    {53, "Genre", 11, "Unsatisfied", "string"},
+    {53, "Genre", 12, "Bits", "int"},
+    {53, "Genre", 16, "Value", "int"},
+    {53, "Genre", 17, "Child", "object"},
+    {53, "Genre", 18, "Name", "string"},
+    {54, "ShowingDerivedOBSOLETE", 1, "Version", "int"},
+    {54, "ShowingDerivedOBSOLETE", 2, "Expiration", "int"},
+    {54, "ShowingDerivedOBSOLETE", 3, "Path", "string"},
+    {54, "ShowingDerivedOBSOLETE", 4, "IndexPath", "string"},
+    {54, "ShowingDerivedOBSOLETE", 5, "IndexUsed", "object"},
+    {54, "ShowingDerivedOBSOLETE", 6, "IndexUsedBy", "object"},
+    {54, "ShowingDerivedOBSOLETE", 7, "IndexAttr", "object"},
+    {54, "ShowingDerivedOBSOLETE", 8, "ServerId", "string"},
+    {54, "ShowingDerivedOBSOLETE", 9, "ServerVersion", "int"},
+    {54, "ShowingDerivedOBSOLETE", 10, "Uuid", "string"},
+    {54, "ShowingDerivedOBSOLETE", 11, "Unsatisfied", "string"},
+    {54, "ShowingDerivedOBSOLETE", 12, "Bits", "int"},
+    {54, "ShowingDerivedOBSOLETE", 16, "Station", "object"},
+    {54, "ShowingDerivedOBSOLETE", 17, "Program", "object"},
+    {54, "ShowingDerivedOBSOLETE", 18, "Date", "int"},
+    {54, "ShowingDerivedOBSOLETE", 19, "Time", "int"},
+    {54, "ShowingDerivedOBSOLETE", 20, "Showing", "object"},
+    {54, "ShowingDerivedOBSOLETE", 21, "Duration", "int"},
+    {54, "ShowingDerivedOBSOLETE", 22, "TvRating", "int"},
+    {55, "SeriesStationOBSOLETE", 1, "Version", "int"},
+    {55, "SeriesStationOBSOLETE", 2, "Expiration", "int"},
+    {55, "SeriesStationOBSOLETE", 3, "Path", "string"},
+    {55, "SeriesStationOBSOLETE", 4, "IndexPath", "string"},
+    {55, "SeriesStationOBSOLETE", 5, "IndexUsed", "object"},
+    {55, "SeriesStationOBSOLETE", 6, "IndexUsedBy", "object"},
+    {55, "SeriesStationOBSOLETE", 7, "IndexAttr", "object"},
+    {55, "SeriesStationOBSOLETE", 8, "ServerId", "string"},
+    {55, "SeriesStationOBSOLETE", 9, "ServerVersion", "int"},
+    {55, "SeriesStationOBSOLETE", 10, "Uuid", "string"},
+    {55, "SeriesStationOBSOLETE", 11, "Unsatisfied", "string"},
+    {55, "SeriesStationOBSOLETE", 12, "Bits", "int"},
+    {55, "SeriesStationOBSOLETE", 16, "StationId", "int"},
+    {55, "SeriesStationOBSOLETE", 17, "Day", "int"},
+    {56, "CityPostalCode", 1, "Version", "int"},
+    {56, "CityPostalCode", 2, "Expiration", "int"},
+    {56, "CityPostalCode", 3, "Path", "string"},
+    {56, "CityPostalCode", 4, "IndexPath", "string"},
+    {56, "CityPostalCode", 5, "IndexUsed", "object"},
+    {56, "CityPostalCode", 6, "IndexUsedBy", "object"},
+    {56, "CityPostalCode", 7, "IndexAttr", "object"},
+    {56, "CityPostalCode", 8, "ServerId", "string"},
+    {56, "CityPostalCode", 9, "ServerVersion", "int"},
+    {56, "CityPostalCode", 10, "Uuid", "string"},
+    {56, "CityPostalCode", 11, "Unsatisfied", "string"},
+    {56, "CityPostalCode", 12, "Bits", "int"},
+    {56, "CityPostalCode", 16, "CommunityName", "string"},
+    {56, "CityPostalCode", 17, "PostalCode", "string"},
+    {57, "IrFormat", 1, "Version", "int"},
+    {57, "IrFormat", 2, "Expiration", "int"},
+    {57, "IrFormat", 3, "Path", "string"},
+    {57, "IrFormat", 4, "IndexPath", "string"},
+    {57, "IrFormat", 5, "IndexUsed", "object"},
+    {57, "IrFormat", 6, "IndexUsedBy", "object"},
+    {57, "IrFormat", 7, "IndexAttr", "object"},
+    {57, "IrFormat", 8, "ServerId", "string"},
+    {57, "IrFormat", 9, "ServerVersion", "int"},
+    {57, "IrFormat", 10, "Uuid", "string"},
+    {57, "IrFormat", 11, "Unsatisfied", "string"},
+    {57, "IrFormat", 12, "Bits", "int"},
+    {57, "IrFormat", 16, "Id", "int"},
+    {57, "IrFormat", 17, "Option", "int"},
+    {57, "IrFormat", 18, "Outcode", "int"},
+    {57, "IrFormat", 19, "Logic1", "int"},
+    {57, "IrFormat", 20, "Logic0", "int"},
+    {57, "IrFormat", 21, "Lead", "int"},
+    {57, "IrFormat", 22, "Repeat", "int"},
+    {57, "IrFormat", 23, "End", "int"},
+    {57, "IrFormat", 24, "Timedb1", "int"},
+    {57, "IrFormat", 25, "Timedb2", "int"},
+    {57, "IrFormat", 26, "Timedb3", "int"},
+    {57, "IrFormat", 27, "Timedw1", "int"},
+    {57, "IrFormat", 28, "Timedw2", "int"},
+    {57, "IrFormat", 29, "Word1", "int"},
+    {57, "IrFormat", 30, "Word2", "int"},
+    {57, "IrFormat", 31, "SubroutineOBSOLETE", "string"},
+    {58, "IrBlastData", 1, "Version", "int"},
+    {58, "IrBlastData", 2, "Expiration", "int"},
+    {58, "IrBlastData", 3, "Path", "string"},
+    {58, "IrBlastData", 4, "IndexPath", "string"},
+    {58, "IrBlastData", 5, "IndexUsed", "object"},
+    {58, "IrBlastData", 6, "IndexUsedBy", "object"},
+    {58, "IrBlastData", 7, "IndexAttr", "object"},
+    {58, "IrBlastData", 8, "ServerId", "string"},
+    {58, "IrBlastData", 9, "ServerVersion", "int"},
+    {58, "IrBlastData", 10, "Uuid", "string"},
+    {58, "IrBlastData", 11, "Unsatisfied", "string"},
+    {58, "IrBlastData", 12, "Bits", "int"},
+    {58, "IrBlastData", 16, "Code", "int"},
+    {58, "IrBlastData", 17, "DevType", "string"},
+    {58, "IrBlastData", 18, "Format", "int"},
+    {58, "IrBlastData", 19, "Carrier", "int"},
+    {58, "IrBlastData", 20, "Syscode", "int"},
+    {58, "IrBlastData", 21, "SubroutineOBSOLETE", "string"},
+    {58, "IrBlastData", 22, "KeyCodes", "int"},
+    {58, "IrBlastData", 23, "NumRepeats", "int"},
+    {58, "IrBlastData", 24, "DigitDelay", "int"},
+    {59, "MessageOBSOLETE", 1, "Version", "int"},
+    {59, "MessageOBSOLETE", 2, "Expiration", "int"},
+    {59, "MessageOBSOLETE", 3, "Path", "string"},
+    {59, "MessageOBSOLETE", 4, "IndexPath", "string"},
+    {59, "MessageOBSOLETE", 5, "IndexUsed", "object"},
+    {59, "MessageOBSOLETE", 6, "IndexUsedBy", "object"},
+    {59, "MessageOBSOLETE", 7, "IndexAttr", "object"},
+    {59, "MessageOBSOLETE", 8, "ServerId", "string"},
+    {59, "MessageOBSOLETE", 9, "ServerVersion", "int"},
+    {59, "MessageOBSOLETE", 10, "Uuid", "string"},
+    {59, "MessageOBSOLETE", 11, "Unsatisfied", "string"},
+    {59, "MessageOBSOLETE", 12, "Bits", "int"},
+    {59, "MessageOBSOLETE", 16, "Title", "string"},
+    {59, "MessageOBSOLETE", 17, "Body", "string"},
+    {59, "MessageOBSOLETE", 18, "MessageId", "string"},
+    {59, "MessageOBSOLETE", 19, "Priority", "int"},
+    {59, "MessageOBSOLETE", 20, "SaveResponse", "int"},
+    {59, "MessageOBSOLETE", 21, "Response", "int"},
+    {59, "MessageOBSOLETE", 22, "Choice", "string"},
+    {59, "MessageOBSOLETE", 23, "RepeatCounter", "int"},
+    {59, "MessageOBSOLETE", 24, "ExpirationDate", "int"},
+    {60, "VideoClip", 1, "Version", "int"},
+    {60, "VideoClip", 2, "Expiration", "int"},
+    {60, "VideoClip", 3, "Path", "string"},
+    {60, "VideoClip", 4, "IndexPath", "string"},
+    {60, "VideoClip", 5, "IndexUsed", "object"},
+    {60, "VideoClip", 6, "IndexUsedBy", "object"},
+    {60, "VideoClip", 7, "IndexAttr", "object"},
+    {60, "VideoClip", 8, "ServerId", "string"},
+    {60, "VideoClip", 9, "ServerVersion", "int"},
+    {60, "VideoClip", 10, "Uuid", "string"},
+    {60, "VideoClip", 11, "Unsatisfied", "string"},
+    {60, "VideoClip", 12, "Bits", "int"},
+    {60, "VideoClip", 16, "Name", "string"},
+    {60, "VideoClip", 17, "File", "file"},
+    {61, "ServiceInfo", 1, "Version", "int"},
+    {61, "ServiceInfo", 2, "Expiration", "int"},
+    {61, "ServiceInfo", 3, "Path", "string"},
+    {61, "ServiceInfo", 4, "IndexPath", "string"},
+    {61, "ServiceInfo", 5, "IndexUsed", "object"},
+    {61, "ServiceInfo", 6, "IndexUsedBy", "object"},
+    {61, "ServiceInfo", 7, "IndexAttr", "object"},
+    {61, "ServiceInfo", 8, "ServerId", "string"},
+    {61, "ServiceInfo", 9, "ServerVersion", "int"},
+    {61, "ServiceInfo", 10, "Uuid", "string"},
+    {61, "ServiceInfo", 11, "Unsatisfied", "string"},
+    {61, "ServiceInfo", 12, "Bits", "int"},
+    {61, "ServiceInfo", 16, "SwSystemName", "string"},
+    {61, "ServiceInfo", 17, "LastCleanupDate", "int"},
+    {61, "ServiceInfo", 18, "LastCleanupTime", "int"},
+    {61, "ServiceInfo", 19, "CallInProgress", "int"},
+    {61, "ServiceInfo", 20, "DialConfig", "string"},
+    {61, "ServiceInfo", 21, "DialInNum", "string"},
+    {61, "ServiceInfo", 22, "DialInAreaCode", "string"},
+    {61, "ServiceInfo", 23, "DialInPrefix", "string"},
+    {61, "ServiceInfo", 24, "LocalAreaCode", "string"},
+    {61, "ServiceInfo", 25, "LastDialInUpdateTime", "int"},
+    {61, "ServiceInfo", 26, "AuthTollFree", "int"},
+    {61, "ServiceInfo", 27, "TollFreeNum", "string"},
+    {61, "ServiceInfo", 28, "CallStatusInfo", "string"},
+    {61, "ServiceInfo", 29, "ForceBackhaul", "int"},
+    {61, "ServiceInfo", 30, "PublicLogFilter", "string"},
+    {61, "ServiceInfo", 31, "LastSuccessPGDCall", "int"},
+    {61, "ServiceInfo", 32, "BackhaulDataOn", "int"},
+    {61, "ServiceInfo", 33, "PersonalDataOn", "int"},
+    {61, "ServiceInfo", 34, "ClientToken", "string"},
+    {61, "ServiceInfo", 35, "LastPrivBackhaul", "int"},
+    {61, "ServiceInfo", 36, "AltPlanYStationID", "string"},
+    {61, "ServiceInfo", 37, "DataGroupList", "string"},
+    {61, "ServiceInfo", 38, "SequenceCookie", "string"},
+    {62, "IrTivoFormat", 1, "Version", "int"},
+    {62, "IrTivoFormat", 2, "Expiration", "int"},
+    {62, "IrTivoFormat", 3, "Path", "string"},
+    {62, "IrTivoFormat", 4, "IndexPath", "string"},
+    {62, "IrTivoFormat", 5, "IndexUsed", "object"},
+    {62, "IrTivoFormat", 6, "IndexUsedBy", "object"},
+    {62, "IrTivoFormat", 7, "IndexAttr", "object"},
+    {62, "IrTivoFormat", 8, "ServerId", "string"},
+    {62, "IrTivoFormat", 9, "ServerVersion", "int"},
+    {62, "IrTivoFormat", 10, "Uuid", "string"},
+    {62, "IrTivoFormat", 11, "Unsatisfied", "string"},
+    {62, "IrTivoFormat", 12, "Bits", "int"},
+    {62, "IrTivoFormat", 16, "DeviceName", "string"},
+    {62, "IrTivoFormat", 17, "TimeSpacer", "int"},
+    {62, "IrTivoFormat", 18, "Dig0", "int"},
+    {62, "IrTivoFormat", 19, "Dig1", "int"},
+    {62, "IrTivoFormat", 20, "Dig2", "int"},
+    {62, "IrTivoFormat", 21, "Dig3", "int"},
+    {62, "IrTivoFormat", 22, "Dig4", "int"},
+    {62, "IrTivoFormat", 23, "Dig5", "int"},
+    {62, "IrTivoFormat", 24, "Dig6", "int"},
+    {62, "IrTivoFormat", 25, "Dig7", "int"},
+    {62, "IrTivoFormat", 26, "Dig8", "int"},
+    {62, "IrTivoFormat", 27, "Dig9", "int"},
+    {62, "IrTivoFormat", 28, "Enter", "int"},
+    {62, "IrTivoFormat", 29, "PowerToggle", "int"},
+    {62, "IrTivoFormat", 30, "PowerOn", "int"},
+    {62, "IrTivoFormat", 31, "PowerOff", "int"},
+    {62, "IrTivoFormat", 32, "ChanUp", "int"},
+    {62, "IrTivoFormat", 33, "ChanDown", "int"},
+    {62, "IrTivoFormat", 34, "SurfingDelay", "int"},
+    {62, "IrTivoFormat", 35, "RecordingDelay", "int"},
+    {62, "IrTivoFormat", 36, "Play", "int"},
+    {62, "IrTivoFormat", 37, "Pause", "int"},
+    {62, "IrTivoFormat", 38, "Stop", "int"},
+    {62, "IrTivoFormat", 39, "Record", "int"},
+    {63, "MessageBoardOBSOLETE", 1, "Version", "int"},
+    {63, "MessageBoardOBSOLETE", 2, "Expiration", "int"},
+    {63, "MessageBoardOBSOLETE", 3, "Path", "string"},
+    {63, "MessageBoardOBSOLETE", 4, "IndexPath", "string"},
+    {63, "MessageBoardOBSOLETE", 5, "IndexUsed", "object"},
+    {63, "MessageBoardOBSOLETE", 6, "IndexUsedBy", "object"},
+    {63, "MessageBoardOBSOLETE", 7, "IndexAttr", "object"},
+    {63, "MessageBoardOBSOLETE", 8, "ServerId", "string"},
+    {63, "MessageBoardOBSOLETE", 9, "ServerVersion", "int"},
+    {63, "MessageBoardOBSOLETE", 10, "Uuid", "string"},
+    {63, "MessageBoardOBSOLETE", 11, "Unsatisfied", "string"},
+    {63, "MessageBoardOBSOLETE", 12, "Bits", "int"},
+    {63, "MessageBoardOBSOLETE", 16, "NewMessageCount", "int"},
+    {63, "MessageBoardOBSOLETE", 17, "NextPtcmDisplayDate", "int"},
+    {63, "MessageBoardOBSOLETE", 18, "NextPtcmDisplayTime", "int"},
+    {64, "MessageItem", 1, "Version", "int"},
+    {64, "MessageItem", 2, "Expiration", "int"},
+    {64, "MessageItem", 3, "Path", "string"},
+    {64, "MessageItem", 4, "IndexPath", "string"},
+    {64, "MessageItem", 5, "IndexUsed", "object"},
+    {64, "MessageItem", 6, "IndexUsedBy", "object"},
+    {64, "MessageItem", 7, "IndexAttr", "object"},
+    {64, "MessageItem", 8, "ServerId", "string"},
+    {64, "MessageItem", 9, "ServerVersion", "int"},
+    {64, "MessageItem", 10, "Uuid", "string"},
+    {64, "MessageItem", 11, "Unsatisfied", "string"},
+    {64, "MessageItem", 12, "Bits", "int"},
+    {64, "MessageItem", 16, "Subject", "string"},
+    {64, "MessageItem", 17, "From", "string"},
+    {64, "MessageItem", 18, "FromId", "int"},
+    {64, "MessageItem", 19, "Body", "string"},
+    {64, "MessageItem", 20, "MessageId", "string"},
+    {64, "MessageItem", 21, "Priority", "int"},
+    {64, "MessageItem", 22, "ExpirationDate", "int"},
+    {64, "MessageItem", 23, "DateGenerated", "int"},
+    {64, "MessageItem", 24, "TimeGenerated", "int"},
+    {64, "MessageItem", 25, "DateRead", "int"},
+    {64, "MessageItem", 26, "TimeRead", "int"},
+    {64, "MessageItem", 27, "MessageFlags", "int"},
+    {64, "MessageItem", 28, "Deleted", "int"},
+    {64, "MessageItem", 29, "Destination", "int"},
+    {64, "MessageItem", 30, "DisplayFrequency", "int"},
+    {64, "MessageItem", 31, "PtcmCountRemaining", "int"},
+    {64, "MessageItem", 32, "LocalMessageType", "int"},
+    {65, "DataSet", 1, "Version", "int"},
+    {65, "DataSet", 2, "Expiration", "int"},
+    {65, "DataSet", 3, "Path", "string"},
+    {65, "DataSet", 4, "IndexPath", "string"},
+    {65, "DataSet", 5, "IndexUsed", "object"},
+    {65, "DataSet", 6, "IndexUsedBy", "object"},
+    {65, "DataSet", 7, "IndexAttr", "object"},
+    {65, "DataSet", 8, "ServerId", "string"},
+    {65, "DataSet", 9, "ServerVersion", "int"},
+    {65, "DataSet", 10, "Uuid", "string"},
+    {65, "DataSet", 11, "Unsatisfied", "string"},
+    {65, "DataSet", 12, "Bits", "int"},
+    {65, "DataSet", 16, "Name", "string"},
+    {65, "DataSet", 17, "Date", "int"},
+    {65, "DataSet", 18, "Data", "object"},
+    {66, "AreaCode", 1, "Version", "int"},
+    {66, "AreaCode", 2, "Expiration", "int"},
+    {66, "AreaCode", 3, "Path", "string"},
+    {66, "AreaCode", 4, "IndexPath", "string"},
+    {66, "AreaCode", 5, "IndexUsed", "object"},
+    {66, "AreaCode", 6, "IndexUsedBy", "object"},
+    {66, "AreaCode", 7, "IndexAttr", "object"},
+    {66, "AreaCode", 8, "ServerId", "string"},
+    {66, "AreaCode", 9, "ServerVersion", "int"},
+    {66, "AreaCode", 10, "Uuid", "string"},
+    {66, "AreaCode", 11, "Unsatisfied", "string"},
+    {66, "AreaCode", 12, "Bits", "int"},
+    {66, "AreaCode", 16, "DBAreaCode", "string"},
+    {66, "AreaCode", 17, "CityPhoneNum", "object"},
+    {67, "CityPhoneNum", 1, "Version", "int"},
+    {67, "CityPhoneNum", 2, "Expiration", "int"},
+    {67, "CityPhoneNum", 3, "Path", "string"},
+    {67, "CityPhoneNum", 4, "IndexPath", "string"},
+    {67, "CityPhoneNum", 5, "IndexUsed", "object"},
+    {67, "CityPhoneNum", 6, "IndexUsedBy", "object"},
+    {67, "CityPhoneNum", 7, "IndexAttr", "object"},
+    {67, "CityPhoneNum", 8, "ServerId", "string"},
+    {67, "CityPhoneNum", 9, "ServerVersion", "int"},
+    {67, "CityPhoneNum", 10, "Uuid", "string"},
+    {67, "CityPhoneNum", 11, "Unsatisfied", "string"},
+    {67, "CityPhoneNum", 12, "Bits", "int"},
+    {67, "CityPhoneNum", 16, "City", "string"},
+    {67, "CityPhoneNum", 17, "PhoneNum", "string"},
+    {68, "User", 1, "Version", "int"},
+    {68, "User", 2, "Expiration", "int"},
+    {68, "User", 3, "Path", "string"},
+    {68, "User", 4, "IndexPath", "string"},
+    {68, "User", 5, "IndexUsed", "object"},
+    {68, "User", 6, "IndexUsedBy", "object"},
+    {68, "User", 7, "IndexAttr", "object"},
+    {68, "User", 8, "ServerId", "string"},
+    {68, "User", 9, "ServerVersion", "int"},
+    {68, "User", 10, "Uuid", "string"},
+    {68, "User", 11, "Unsatisfied", "string"},
+    {68, "User", 12, "Bits", "int"},
+    {68, "User", 16, "Login", "string"},
+    {68, "User", 17, "Password", "string"},
+    {68, "User", 18, "TVRating", "int"},
+    {68, "User", 19, "MPAARating", "int"},
+    {68, "User", 20, "TVAdvisorys", "int"},
+    {68, "User", 21, "BlockedStation", "object"},
+    {68, "User", 22, "SpendingLimit", "int"},
+    {68, "User", 23, "BlockSwitch", "int"},
+    {68, "User", 24, "ApgUser", "object"},
+    {68, "User", 25, "PasswordDelay", "int"},
+    {68, "User", 26, "AutoLockOBSOLETE", "int"},
+    {68, "User", 27, "TvAdvisory", "object"},
+    {68, "User", 28, "AutoRelock", "int"},
+    {69, "SeriesCorrelation", 1, "Version", "int"},
+    {69, "SeriesCorrelation", 2, "Expiration", "int"},
+    {69, "SeriesCorrelation", 3, "Path", "string"},
+    {69, "SeriesCorrelation", 4, "IndexPath", "string"},
+    {69, "SeriesCorrelation", 5, "IndexUsed", "object"},
+    {69, "SeriesCorrelation", 6, "IndexUsedBy", "object"},
+    {69, "SeriesCorrelation", 7, "IndexAttr", "object"},
+    {69, "SeriesCorrelation", 8, "ServerId", "string"},
+    {69, "SeriesCorrelation", 9, "ServerVersion", "int"},
+    {69, "SeriesCorrelation", 10, "Uuid", "string"},
+    {69, "SeriesCorrelation", 11, "Unsatisfied", "string"},
+    {69, "SeriesCorrelation", 12, "Bits", "int"},
+    {69, "SeriesCorrelation", 16, "SeriesId", "string"},
+    {69, "SeriesCorrelation", 17, "Contributor", "object"},
+    {69, "SeriesCorrelation", 18, "Package", "int"},
+    {70, "CorrelationContributor", 1, "Version", "int"},
+    {70, "CorrelationContributor", 2, "Expiration", "int"},
+    {70, "CorrelationContributor", 3, "Path", "string"},
+    {70, "CorrelationContributor", 4, "IndexPath", "string"},
+    {70, "CorrelationContributor", 5, "IndexUsed", "object"},
+    {70, "CorrelationContributor", 6, "IndexUsedBy", "object"},
+    {70, "CorrelationContributor", 7, "IndexAttr", "object"},
+    {70, "CorrelationContributor", 8, "ServerId", "string"},
+    {70, "CorrelationContributor", 9, "ServerVersion", "int"},
+    {70, "CorrelationContributor", 10, "Uuid", "string"},
+    {70, "CorrelationContributor", 11, "Unsatisfied", "string"},
+    {70, "CorrelationContributor", 12, "Bits", "int"},
+    {70, "CorrelationContributor", 16, "SeriesId", "string"},
+    {70, "CorrelationContributor", 17, "Correlation", "int"},
+    {71, "UserInterfaceOBSOLETE", 1, "Version", "int"},
+    {71, "UserInterfaceOBSOLETE", 2, "Expiration", "int"},
+    {71, "UserInterfaceOBSOLETE", 3, "Path", "string"},
+    {71, "UserInterfaceOBSOLETE", 4, "IndexPath", "string"},
+    {71, "UserInterfaceOBSOLETE", 5, "IndexUsed", "object"},
+    {71, "UserInterfaceOBSOLETE", 6, "IndexUsedBy", "object"},
+    {71, "UserInterfaceOBSOLETE", 7, "IndexAttr", "object"},
+    {71, "UserInterfaceOBSOLETE", 8, "ServerId", "string"},
+    {71, "UserInterfaceOBSOLETE", 9, "ServerVersion", "int"},
+    {71, "UserInterfaceOBSOLETE", 10, "Uuid", "string"},
+    {71, "UserInterfaceOBSOLETE", 11, "Unsatisfied", "string"},
+    {71, "UserInterfaceOBSOLETE", 12, "Bits", "int"},
+    {71, "UserInterfaceOBSOLETE", 16, "Name", "string"},
+    {71, "UserInterfaceOBSOLETE", 17, "Global", "object"},
+    {71, "UserInterfaceOBSOLETE", 18, "Context", "object"},
+    {71, "UserInterfaceOBSOLETE", 19, "DefaultContext", "object"},
+    {72, "TuikGlobalOBSOLETE", 1, "Version", "int"},
+    {72, "TuikGlobalOBSOLETE", 2, "Expiration", "int"},
+    {72, "TuikGlobalOBSOLETE", 3, "Path", "string"},
+    {72, "TuikGlobalOBSOLETE", 4, "IndexPath", "string"},
+    {72, "TuikGlobalOBSOLETE", 5, "IndexUsed", "object"},
+    {72, "TuikGlobalOBSOLETE", 6, "IndexUsedBy", "object"},
+    {72, "TuikGlobalOBSOLETE", 7, "IndexAttr", "object"},
+    {72, "TuikGlobalOBSOLETE", 8, "ServerId", "string"},
+    {72, "TuikGlobalOBSOLETE", 9, "ServerVersion", "int"},
+    {72, "TuikGlobalOBSOLETE", 10, "Uuid", "string"},
+    {72, "TuikGlobalOBSOLETE", 11, "Unsatisfied", "string"},
+    {72, "TuikGlobalOBSOLETE", 12, "Bits", "int"},
+    {72, "TuikGlobalOBSOLETE", 16, "Name", "string"},
+    {72, "TuikGlobalOBSOLETE", 17, "File", "file"},
+    {72, "TuikGlobalOBSOLETE", 18, "Resource", "object"},
+    {73, "TuikContextOBSOLETE", 1, "Version", "int"},
+    {73, "TuikContextOBSOLETE", 2, "Expiration", "int"},
+    {73, "TuikContextOBSOLETE", 3, "Path", "string"},
+    {73, "TuikContextOBSOLETE", 4, "IndexPath", "string"},
+    {73, "TuikContextOBSOLETE", 5, "IndexUsed", "object"},
+    {73, "TuikContextOBSOLETE", 6, "IndexUsedBy", "object"},
+    {73, "TuikContextOBSOLETE", 7, "IndexAttr", "object"},
+    {73, "TuikContextOBSOLETE", 8, "ServerId", "string"},
+    {73, "TuikContextOBSOLETE", 9, "ServerVersion", "int"},
+    {73, "TuikContextOBSOLETE", 10, "Uuid", "string"},
+    {73, "TuikContextOBSOLETE", 11, "Unsatisfied", "string"},
+    {73, "TuikContextOBSOLETE", 12, "Bits", "int"},
+    {73, "TuikContextOBSOLETE", 16, "Name", "string"},
+    {73, "TuikContextOBSOLETE", 17, "Id", "string"},
+    {73, "TuikContextOBSOLETE", 18, "File", "file"},
+    {73, "TuikContextOBSOLETE", 19, "Resource", "object"},
+    {74, "DatabaseState", 1, "Version", "int"},
+    {74, "DatabaseState", 2, "Expiration", "int"},
+    {74, "DatabaseState", 3, "Path", "string"},
+    {74, "DatabaseState", 4, "IndexPath", "string"},
+    {74, "DatabaseState", 5, "IndexUsed", "object"},
+    {74, "DatabaseState", 6, "IndexUsedBy", "object"},
+    {74, "DatabaseState", 7, "IndexAttr", "object"},
+    {74, "DatabaseState", 8, "ServerId", "string"},
+    {74, "DatabaseState", 9, "ServerVersion", "int"},
+    {74, "DatabaseState", 10, "Uuid", "string"},
+    {74, "DatabaseState", 11, "Unsatisfied", "string"},
+    {74, "DatabaseState", 12, "Bits", "int"},
+    {74, "DatabaseState", 16, "VersionMajor", "int"},
+    {74, "DatabaseState", 17, "VersionMinor", "int"},
+    {74, "DatabaseState", 18, "GcCompletionDate", "int"},
+    {74, "DatabaseState", 19, "GcCompletionTime", "int"},
+    {74, "DatabaseState", 20, "GcIndexCompletionDate", "int"},
+    {74, "DatabaseState", 21, "GcIndexCompletionTime", "int"},
+    {74, "DatabaseState", 22, "ZapRequest", "int"},
+    {75, "Theme", 1, "Version", "int"},
+    {75, "Theme", 2, "Expiration", "int"},
+    {75, "Theme", 3, "Path", "string"},
+    {75, "Theme", 4, "IndexPath", "string"},
+    {75, "Theme", 5, "IndexUsed", "object"},
+    {75, "Theme", 6, "IndexUsedBy", "object"},
+    {75, "Theme", 7, "IndexAttr", "object"},
+    {75, "Theme", 8, "ServerId", "string"},
+    {75, "Theme", 9, "ServerVersion", "int"},
+    {75, "Theme", 10, "Uuid", "string"},
+    {75, "Theme", 11, "Unsatisfied", "string"},
+    {75, "Theme", 12, "Bits", "int"},
+    {75, "Theme", 16, "Name", "string"},
+    {75, "Theme", 17, "Director", "string"},
+    {75, "Theme", 18, "Actor", "string"},
+    {75, "Theme", 19, "KeywordPhrase", "string"},
+    {75, "Theme", 20, "GenreFilterPath", "int"},
+    {75, "Theme", 21, "ThemeType", "int"},
+    {75, "Theme", 22, "DirectorOp", "int"},
+    {75, "Theme", 23, "ActorOp", "int"},
+    {75, "Theme", 24, "KeywordPhraseOp", "int"},
+    {75, "Theme", 25, "SeasonPass", "object"},
+    {76, "ApgBoot", 1, "Version", "int"},
+    {76, "ApgBoot", 2, "Expiration", "int"},
+    {76, "ApgBoot", 3, "Path", "string"},
+    {76, "ApgBoot", 4, "IndexPath", "string"},
+    {76, "ApgBoot", 5, "IndexUsed", "object"},
+    {76, "ApgBoot", 6, "IndexUsedBy", "object"},
+    {76, "ApgBoot", 7, "IndexAttr", "object"},
+    {76, "ApgBoot", 8, "ServerId", "string"},
+    {76, "ApgBoot", 9, "ServerVersion", "int"},
+    {76, "ApgBoot", 10, "Uuid", "string"},
+    {76, "ApgBoot", 11, "Unsatisfied", "string"},
+    {76, "ApgBoot", 12, "Bits", "int"},
+    {76, "ApgBoot", 16, "RootCategorySystem", "object"},
+    {76, "ApgBoot", 17, "CaScid", "int"},
+    {76, "ApgBoot", 18, "PipScid", "int"},
+    {76, "ApgBoot", 19, "Networks", "object"},
+    {77, "ApgCategorySystem", 1, "Version", "int"},
+    {77, "ApgCategorySystem", 2, "Expiration", "int"},
+    {77, "ApgCategorySystem", 3, "Path", "string"},
+    {77, "ApgCategorySystem", 4, "IndexPath", "string"},
+    {77, "ApgCategorySystem", 5, "IndexUsed", "object"},
+    {77, "ApgCategorySystem", 6, "IndexUsedBy", "object"},
+    {77, "ApgCategorySystem", 7, "IndexAttr", "object"},
+    {77, "ApgCategorySystem", 8, "ServerId", "string"},
+    {77, "ApgCategorySystem", 9, "ServerVersion", "int"},
+    {77, "ApgCategorySystem", 10, "Uuid", "string"},
+    {77, "ApgCategorySystem", 11, "Unsatisfied", "string"},
+    {77, "ApgCategorySystem", 12, "Bits", "int"},
+    {77, "ApgCategorySystem", 16, "Title", "string"},
+    {77, "ApgCategorySystem", 17, "Labels", "object"},
+    {78, "ApgFrequency", 1, "Version", "int"},
+    {78, "ApgFrequency", 2, "Expiration", "int"},
+    {78, "ApgFrequency", 3, "Path", "string"},
+    {78, "ApgFrequency", 4, "IndexPath", "string"},
+    {78, "ApgFrequency", 5, "IndexUsed", "object"},
+    {78, "ApgFrequency", 6, "IndexUsedBy", "object"},
+    {78, "ApgFrequency", 7, "IndexAttr", "object"},
+    {78, "ApgFrequency", 8, "ServerId", "string"},
+    {78, "ApgFrequency", 9, "ServerVersion", "int"},
+    {78, "ApgFrequency", 10, "Uuid", "string"},
+    {78, "ApgFrequency", 11, "Unsatisfied", "string"},
+    {78, "ApgFrequency", 12, "Bits", "int"},
+    {78, "ApgFrequency", 16, "Parameters", "int"},
+    {78, "ApgFrequency", 17, "Lnb", "int"},
+    {79, "ApgNetwork", 1, "Version", "int"},
+    {79, "ApgNetwork", 2, "Expiration", "int"},
+    {79, "ApgNetwork", 3, "Path", "string"},
+    {79, "ApgNetwork", 4, "IndexPath", "string"},
+    {79, "ApgNetwork", 5, "IndexUsed", "object"},
+    {79, "ApgNetwork", 6, "IndexUsedBy", "object"},
+    {79, "ApgNetwork", 7, "IndexAttr", "object"},
+    {79, "ApgNetwork", 8, "ServerId", "string"},
+    {79, "ApgNetwork", 9, "ServerVersion", "int"},
+    {79, "ApgNetwork", 10, "Uuid", "string"},
+    {79, "ApgNetwork", 11, "Unsatisfied", "string"},
+    {79, "ApgNetwork", 12, "Bits", "int"},
+    {79, "ApgNetwork", 16, "NetworkId", "int"},
+    {79, "ApgNetwork", 17, "Satellite", "object"},
+    {80, "ApgSatellite", 1, "Version", "int"},
+    {80, "ApgSatellite", 2, "Expiration", "int"},
+    {80, "ApgSatellite", 3, "Path", "string"},
+    {80, "ApgSatellite", 4, "IndexPath", "string"},
+    {80, "ApgSatellite", 5, "IndexUsed", "object"},
+    {80, "ApgSatellite", 6, "IndexUsedBy", "object"},
+    {80, "ApgSatellite", 7, "IndexAttr", "object"},
+    {80, "ApgSatellite", 8, "ServerId", "string"},
+    {80, "ApgSatellite", 9, "ServerVersion", "int"},
+    {80, "ApgSatellite", 10, "Uuid", "string"},
+    {80, "ApgSatellite", 11, "Unsatisfied", "string"},
+    {80, "ApgSatellite", 12, "Bits", "int"},
+    {80, "ApgSatellite", 16, "OrbitalPosition", "int"},
+    {80, "ApgSatellite", 17, "Direction", "int"},
+    {80, "ApgSatellite", 18, "Frequency", "object"},
+    {81, "ApgCategoryLabel", 1, "Version", "int"},
+    {81, "ApgCategoryLabel", 2, "Expiration", "int"},
+    {81, "ApgCategoryLabel", 3, "Path", "string"},
+    {81, "ApgCategoryLabel", 4, "IndexPath", "string"},
+    {81, "ApgCategoryLabel", 5, "IndexUsed", "object"},
+    {81, "ApgCategoryLabel", 6, "IndexUsedBy", "object"},
+    {81, "ApgCategoryLabel", 7, "IndexAttr", "object"},
+    {81, "ApgCategoryLabel", 8, "ServerId", "string"},
+    {81, "ApgCategoryLabel", 9, "ServerVersion", "int"},
+    {81, "ApgCategoryLabel", 10, "Uuid", "string"},
+    {81, "ApgCategoryLabel", 11, "Unsatisfied", "string"},
+    {81, "ApgCategoryLabel", 12, "Bits", "int"},
+    {81, "ApgCategoryLabel", 16, "Index", "int"},
+    {81, "ApgCategoryLabel", 17, "Subcategory", "object"},
+    {81, "ApgCategoryLabel", 18, "FCoreSet", "int"},
+    {81, "ApgCategoryLabel", 19, "Label", "string"},
+    {81, "ApgCategoryLabel", 20, "AboutText", "string"},
+    {82, "ApgProgram", 1, "Version", "int"},
+    {82, "ApgProgram", 2, "Expiration", "int"},
+    {82, "ApgProgram", 3, "Path", "string"},
+    {82, "ApgProgram", 4, "IndexPath", "string"},
+    {82, "ApgProgram", 5, "IndexUsed", "object"},
+    {82, "ApgProgram", 6, "IndexUsedBy", "object"},
+    {82, "ApgProgram", 7, "IndexAttr", "object"},
+    {82, "ApgProgram", 8, "ServerId", "string"},
+    {82, "ApgProgram", 9, "ServerVersion", "int"},
+    {82, "ApgProgram", 10, "Uuid", "string"},
+    {82, "ApgProgram", 11, "Unsatisfied", "string"},
+    {82, "ApgProgram", 12, "Bits", "int"},
+    {82, "ApgProgram", 16, "Category", "int"},
+    {82, "ApgProgram", 17, "CwpDescription", "string"},
+    {83, "BitrateEstimate", 1, "Version", "int"},
+    {83, "BitrateEstimate", 2, "Expiration", "int"},
+    {83, "BitrateEstimate", 3, "Path", "string"},
+    {83, "BitrateEstimate", 4, "IndexPath", "string"},
+    {83, "BitrateEstimate", 5, "IndexUsed", "object"},
+    {83, "BitrateEstimate", 6, "IndexUsedBy", "object"},
+    {83, "BitrateEstimate", 7, "IndexAttr", "object"},
+    {83, "BitrateEstimate", 8, "ServerId", "string"},
+    {83, "BitrateEstimate", 9, "ServerVersion", "int"},
+    {83, "BitrateEstimate", 10, "Uuid", "string"},
+    {83, "BitrateEstimate", 11, "Unsatisfied", "string"},
+    {83, "BitrateEstimate", 12, "Bits", "int"},
+    {83, "BitrateEstimate", 16, "ProgramGuideSource", "int"},
+    {83, "BitrateEstimate", 17, "Genre", "int"},
+    {83, "BitrateEstimate", 18, "Bitrate", "int"},
+    {84, "MyWorldState", 1, "Version", "int"},
+    {84, "MyWorldState", 2, "Expiration", "int"},
+    {84, "MyWorldState", 3, "Path", "string"},
+    {84, "MyWorldState", 4, "IndexPath", "string"},
+    {84, "MyWorldState", 5, "IndexUsed", "object"},
+    {84, "MyWorldState", 6, "IndexUsedBy", "object"},
+    {84, "MyWorldState", 7, "IndexAttr", "object"},
+    {84, "MyWorldState", 8, "ServerId", "string"},
+    {84, "MyWorldState", 9, "ServerVersion", "int"},
+    {84, "MyWorldState", 10, "Uuid", "string"},
+    {84, "MyWorldState", 11, "Unsatisfied", "string"},
+    {84, "MyWorldState", 12, "Bits", "int"},
+    {84, "MyWorldState", 16, "LockState", "int"},
+    {84, "MyWorldState", 17, "LastChannel", "object"},
+    {84, "MyWorldState", 18, "AutoDetect", "int"},
+    {84, "MyWorldState", 19, "GuideStyle", "int"},
+    {84, "MyWorldState", 20, "GuideChannelList", "int"},
+    {84, "MyWorldState", 21, "StandbyModeActive", "int"},
+    {85, "Test3", 1, "Version", "int"},
+    {85, "Test3", 2, "Expiration", "int"},
+    {85, "Test3", 3, "Path", "string"},
+    {85, "Test3", 4, "IndexPath", "string"},
+    {85, "Test3", 5, "IndexUsed", "object"},
+    {85, "Test3", 6, "IndexUsedBy", "object"},
+    {85, "Test3", 7, "IndexAttr", "object"},
+    {85, "Test3", 8, "ServerId", "string"},
+    {85, "Test3", 9, "ServerVersion", "int"},
+    {85, "Test3", 10, "Uuid", "string"},
+    {85, "Test3", 11, "Unsatisfied", "string"},
+    {85, "Test3", 12, "Bits", "int"},
+    {85, "Test3", 16, "Test3Object", "object"},
+    {85, "Test3", 17, "OptionalFile", "file"},
+    {86, "ApgPip", 1, "Version", "int"},
+    {86, "ApgPip", 2, "Expiration", "int"},
+    {86, "ApgPip", 3, "Path", "string"},
+    {86, "ApgPip", 4, "IndexPath", "string"},
+    {86, "ApgPip", 5, "IndexUsed", "object"},
+    {86, "ApgPip", 6, "IndexUsedBy", "object"},
+    {86, "ApgPip", 7, "IndexAttr", "object"},
+    {86, "ApgPip", 8, "ServerId", "string"},
+    {86, "ApgPip", 9, "ServerVersion", "int"},
+    {86, "ApgPip", 10, "Uuid", "string"},
+    {86, "ApgPip", 11, "Unsatisfied", "string"},
+    {86, "ApgPip", 12, "Bits", "int"},
+    {86, "ApgPip", 16, "Pip", "int"},
+    {87, "ApgChannel", 1, "Version", "int"},
+    {87, "ApgChannel", 2, "Expiration", "int"},
+    {87, "ApgChannel", 3, "Path", "string"},
+    {87, "ApgChannel", 4, "IndexPath", "string"},
+    {87, "ApgChannel", 5, "IndexUsed", "object"},
+    {87, "ApgChannel", 6, "IndexUsedBy", "object"},
+    {87, "ApgChannel", 7, "IndexAttr", "object"},
+    {87, "ApgChannel", 8, "ServerId", "string"},
+    {87, "ApgChannel", 9, "ServerVersion", "int"},
+    {87, "ApgChannel", 10, "Uuid", "string"},
+    {87, "ApgChannel", 11, "Unsatisfied", "string"},
+    {87, "ApgChannel", 12, "Bits", "int"},
+    {87, "ApgChannel", 16, "GuideInclusionExpr", "int"},
+    {87, "ApgChannel", 17, "PipApgObjectId", "int"},
+    {87, "ApgChannel", 18, "PipMessageTag", "int"},
+    {87, "ApgChannel", 19, "CanBeViewed", "int"},
+    {87, "ApgChannel", 20, "SourceId", "int"},
+    {87, "ApgChannel", 21, "ShortName", "string"},
+    {87, "ApgChannel", 22, "ChannelDefinition", "object"},
+    {87, "ApgChannel", 23, "CgmsHda", "int"},
+    {87, "ApgChannel", 24, "CgmsA", "int"},
+    {87, "ApgChannel", 25, "Aps", "int"},
+    {87, "ApgChannel", 26, "CgmsD", "int"},
+    {87, "ApgChannel", 27, "NetworkIdOBSOLETE", "int"},
+    {87, "ApgChannel", 28, "AboutText", "string"},
+    {87, "ApgChannel", 29, "CwpDescription", "string"},
+    {87, "ApgChannel", 30, "DefaultProgram", "object"},
+    {87, "ApgChannel", 31, "AdditionalNetworkId", "int"},
+    {87, "ApgChannel", 32, "PipFrequencyIndex", "int"},
+    {87, "ApgChannel", 33, "PipChannelNumber", "int"},
+    {87, "ApgChannel", 34, "PipMessageNumber", "int"},
+    {87, "ApgChannel", 35, "ApgObjectId", "int"},
+    {87, "ApgChannel", 36, "ChannelPipIndicator", "int"},
+    {87, "ApgChannel", 37, "LogoIndex", "int"},
+    {87, "ApgChannel", 38, "BackupLogoIndex", "int"},
+    {87, "ApgChannel", 39, "ConditionalDescriptorExpr", "int"},
+    {87, "ApgChannel", 40, "LongName", "string"},
+    {87, "ApgChannel", 41, "Category", "int"},
+    {87, "ApgChannel", 42, "FrameHeaderNetworkId", "int"},
+    {88, "ApgChannelDefinition", 1, "Version", "int"},
+    {88, "ApgChannelDefinition", 2, "Expiration", "int"},
+    {88, "ApgChannelDefinition", 3, "Path", "string"},
+    {88, "ApgChannelDefinition", 4, "IndexPath", "string"},
+    {88, "ApgChannelDefinition", 5, "IndexUsed", "object"},
+    {88, "ApgChannelDefinition", 6, "IndexUsedBy", "object"},
+    {88, "ApgChannelDefinition", 7, "IndexAttr", "object"},
+    {88, "ApgChannelDefinition", 8, "ServerId", "string"},
+    {88, "ApgChannelDefinition", 9, "ServerVersion", "int"},
+    {88, "ApgChannelDefinition", 10, "Uuid", "string"},
+    {88, "ApgChannelDefinition", 11, "Unsatisfied", "string"},
+    {88, "ApgChannelDefinition", 12, "Bits", "int"},
+    {88, "ApgChannelDefinition", 16, "ChannelExpression", "int"},
+    {88, "ApgChannelDefinition", 17, "ServiceType", "int"},
+    {88, "ApgChannelDefinition", 18, "Spi", "int"},
+    {88, "ApgChannelDefinition", 19, "NumberOfStreams", "int"},
+    {88, "ApgChannelDefinition", 20, "FrequencyIndex", "int"},
+    {88, "ApgChannelDefinition", 21, "StreamType", "int"},
+    {88, "ApgChannelDefinition", 22, "Scid", "int"},
+    {88, "ApgChannelDefinition", 23, "LanguageCode", "int"},
+    {88, "ApgChannelDefinition", 24, "AboutText", "string"},
+    {88, "ApgChannelDefinition", 25, "ServiceLabel", "string"},
+    {89, "AudioBackground", 1, "Version", "int"},
+    {89, "AudioBackground", 2, "Expiration", "int"},
+    {89, "AudioBackground", 3, "Path", "string"},
+    {89, "AudioBackground", 4, "IndexPath", "string"},
+    {89, "AudioBackground", 5, "IndexUsed", "object"},
+    {89, "AudioBackground", 6, "IndexUsedBy", "object"},
+    {89, "AudioBackground", 7, "IndexAttr", "object"},
+    {89, "AudioBackground", 8, "ServerId", "string"},
+    {89, "AudioBackground", 9, "ServerVersion", "int"},
+    {89, "AudioBackground", 10, "Uuid", "string"},
+    {89, "AudioBackground", 11, "Unsatisfied", "string"},
+    {89, "AudioBackground", 12, "Bits", "int"},
+    {89, "AudioBackground", 16, "Enter", "object"},
+    {89, "AudioBackground", 17, "Loop", "object"},
+    {89, "AudioBackground", 18, "Name", "string"},
+    {90, "AudioBackgroundItem", 1, "Version", "int"},
+    {90, "AudioBackgroundItem", 2, "Expiration", "int"},
+    {90, "AudioBackgroundItem", 3, "Path", "string"},
+    {90, "AudioBackgroundItem", 4, "IndexPath", "string"},
+    {90, "AudioBackgroundItem", 5, "IndexUsed", "object"},
+    {90, "AudioBackgroundItem", 6, "IndexUsedBy", "object"},
+    {90, "AudioBackgroundItem", 7, "IndexAttr", "object"},
+    {90, "AudioBackgroundItem", 8, "ServerId", "string"},
+    {90, "AudioBackgroundItem", 9, "ServerVersion", "int"},
+    {90, "AudioBackgroundItem", 10, "Uuid", "string"},
+    {90, "AudioBackgroundItem", 11, "Unsatisfied", "string"},
+    {90, "AudioBackgroundItem", 12, "Bits", "int"},
+    {90, "AudioBackgroundItem", 16, "AudioClip", "object"},
+    {90, "AudioBackgroundItem", 17, "PlaybackFrequency", "int"},
+    {90, "AudioBackgroundItem", 18, "LastPlaybackTime", "int"},
+    {91, "SubRecording", 1, "Version", "int"},
+    {91, "SubRecording", 2, "Expiration", "int"},
+    {91, "SubRecording", 3, "Path", "string"},
+    {91, "SubRecording", 4, "IndexPath", "string"},
+    {91, "SubRecording", 5, "IndexUsed", "object"},
+    {91, "SubRecording", 6, "IndexUsedBy", "object"},
+    {91, "SubRecording", 7, "IndexAttr", "object"},
+    {91, "SubRecording", 8, "ServerId", "string"},
+    {91, "SubRecording", 9, "ServerVersion", "int"},
+    {91, "SubRecording", 10, "Uuid", "string"},
+    {91, "SubRecording", 11, "Unsatisfied", "string"},
+    {91, "SubRecording", 12, "Bits", "int"},
+    {91, "SubRecording", 16, "Recording", "object"},
+    {91, "SubRecording", 17, "OffsetSeconds", "int"},
+    {91, "SubRecording", 18, "OffsetNanos", "int"},
+    {91, "SubRecording", 19, "DurationSeconds", "int"},
+    {91, "SubRecording", 20, "DurationNanos", "int"},
+    {92, "ApgSchedule", 1, "Version", "int"},
+    {92, "ApgSchedule", 2, "Expiration", "int"},
+    {92, "ApgSchedule", 3, "Path", "string"},
+    {92, "ApgSchedule", 4, "IndexPath", "string"},
+    {92, "ApgSchedule", 5, "IndexUsed", "object"},
+    {92, "ApgSchedule", 6, "IndexUsedBy", "object"},
+    {92, "ApgSchedule", 7, "IndexAttr", "object"},
+    {92, "ApgSchedule", 8, "ServerId", "string"},
+    {92, "ApgSchedule", 9, "ServerVersion", "int"},
+    {92, "ApgSchedule", 10, "Uuid", "string"},
+    {92, "ApgSchedule", 11, "Unsatisfied", "string"},
+    {92, "ApgSchedule", 12, "Bits", "int"},
+    {92, "ApgSchedule", 16, "ApgObjectId", "int"},
+    {92, "ApgSchedule", 17, "StartTime", "int"},
+    {92, "ApgSchedule", 18, "Duration", "int"},
+    {92, "ApgSchedule", 19, "Showing", "object"},
+    {93, "ApgScheduleEvent", 1, "Version", "int"},
+    {93, "ApgScheduleEvent", 2, "Expiration", "int"},
+    {93, "ApgScheduleEvent", 3, "Path", "string"},
+    {93, "ApgScheduleEvent", 4, "IndexPath", "string"},
+    {93, "ApgScheduleEvent", 5, "IndexUsed", "object"},
+    {93, "ApgScheduleEvent", 6, "IndexUsedBy", "object"},
+    {93, "ApgScheduleEvent", 7, "IndexAttr", "object"},
+    {93, "ApgScheduleEvent", 8, "ServerId", "string"},
+    {93, "ApgScheduleEvent", 9, "ServerVersion", "int"},
+    {93, "ApgScheduleEvent", 10, "Uuid", "string"},
+    {93, "ApgScheduleEvent", 11, "Unsatisfied", "string"},
+    {93, "ApgScheduleEvent", 12, "Bits", "int"},
+    {93, "ApgScheduleEvent", 16, "PipMessageNumber", "int"},
+    {93, "ApgScheduleEvent", 17, "CgmsHda", "int"},
+    {93, "ApgScheduleEvent", 18, "CgmsA", "int"},
+    {93, "ApgScheduleEvent", 19, "Aps", "int"},
+    {93, "ApgScheduleEvent", 20, "CgmsD", "int"},
+    {93, "ApgScheduleEvent", 21, "EventPipIndicator", "int"},
+    {94, "SatConfig", 1, "Version", "int"},
+    {94, "SatConfig", 2, "Expiration", "int"},
+    {94, "SatConfig", 3, "Path", "string"},
+    {94, "SatConfig", 4, "IndexPath", "string"},
+    {94, "SatConfig", 5, "IndexUsed", "object"},
+    {94, "SatConfig", 6, "IndexUsedBy", "object"},
+    {94, "SatConfig", 7, "IndexAttr", "object"},
+    {94, "SatConfig", 8, "ServerId", "string"},
+    {94, "SatConfig", 9, "ServerVersion", "int"},
+    {94, "SatConfig", 10, "Uuid", "string"},
+    {94, "SatConfig", 11, "Unsatisfied", "string"},
+    {94, "SatConfig", 12, "Bits", "int"},
+    {94, "SatConfig", 16, "ConnectionType", "int"},
+    {94, "SatConfig", 17, "NetworkPortInfo", "object"},
+    {94, "SatConfig", 18, "DishType", "int"},
+    {94, "SatConfig", 19, "MarketId", "int"},
+    {94, "SatConfig", 20, "Css", "int"},
+    {94, "SatConfig", 21, "CwStat", "int"},
+    {95, "SatNetworkPortInfo", 1, "Version", "int"},
+    {95, "SatNetworkPortInfo", 2, "Expiration", "int"},
+    {95, "SatNetworkPortInfo", 3, "Path", "string"},
+    {95, "SatNetworkPortInfo", 4, "IndexPath", "string"},
+    {95, "SatNetworkPortInfo", 5, "IndexUsed", "object"},
+    {95, "SatNetworkPortInfo", 6, "IndexUsedBy", "object"},
+    {95, "SatNetworkPortInfo", 7, "IndexAttr", "object"},
+    {95, "SatNetworkPortInfo", 8, "ServerId", "string"},
+    {95, "SatNetworkPortInfo", 9, "ServerVersion", "int"},
+    {95, "SatNetworkPortInfo", 10, "Uuid", "string"},
+    {95, "SatNetworkPortInfo", 11, "Unsatisfied", "string"},
+    {95, "SatNetworkPortInfo", 12, "Bits", "int"},
+    {95, "SatNetworkPortInfo", 16, "NetworkId", "int"},
+    {95, "SatNetworkPortInfo", 17, "PolarizationA", "int"},
+    {95, "SatNetworkPortInfo", 18, "PolarizationB", "int"},
+    {95, "SatNetworkPortInfo", 19, "IsStacked", "int"},
+    {95, "SatNetworkPortInfo", 20, "PortNumberA", "int"},
+    {95, "SatNetworkPortInfo", 21, "PortNumberB", "int"},
+    {96, "ApgUpdateList", 1, "Version", "int"},
+    {96, "ApgUpdateList", 2, "Expiration", "int"},
+    {96, "ApgUpdateList", 3, "Path", "string"},
+    {96, "ApgUpdateList", 4, "IndexPath", "string"},
+    {96, "ApgUpdateList", 5, "IndexUsed", "object"},
+    {96, "ApgUpdateList", 6, "IndexUsedBy", "object"},
+    {96, "ApgUpdateList", 7, "IndexAttr", "object"},
+    {96, "ApgUpdateList", 8, "ServerId", "string"},
+    {96, "ApgUpdateList", 9, "ServerVersion", "int"},
+    {96, "ApgUpdateList", 10, "Uuid", "string"},
+    {96, "ApgUpdateList", 11, "Unsatisfied", "string"},
+    {96, "ApgUpdateList", 12, "Bits", "int"},
+    {96, "ApgUpdateList", 16, "NetworkId", "int"},
+    {96, "ApgUpdateList", 17, "ApgChannelObjectId", "int"},
+    {96, "ApgUpdateList", 18, "ApgChannelVersion", "int"},
+    {97, "LogoGroup", 1, "Version", "int"},
+    {97, "LogoGroup", 2, "Expiration", "int"},
+    {97, "LogoGroup", 3, "Path", "string"},
+    {97, "LogoGroup", 4, "IndexPath", "string"},
+    {97, "LogoGroup", 5, "IndexUsed", "object"},
+    {97, "LogoGroup", 6, "IndexUsedBy", "object"},
+    {97, "LogoGroup", 7, "IndexAttr", "object"},
+    {97, "LogoGroup", 8, "ServerId", "string"},
+    {97, "LogoGroup", 9, "ServerVersion", "int"},
+    {97, "LogoGroup", 10, "Uuid", "string"},
+    {97, "LogoGroup", 11, "Unsatisfied", "string"},
+    {97, "LogoGroup", 12, "Bits", "int"},
+    {97, "LogoGroup", 16, "LogoSpace", "int"},
+    {97, "LogoGroup", 17, "Index", "int"},
+    {97, "LogoGroup", 18, "Image", "object"},
+    {97, "LogoGroup", 19, "Size", "int"},
+    {97, "LogoGroup", 20, "Palette", "int"},
+    {98, "NvRam", 1, "Version", "int"},
+    {98, "NvRam", 2, "Expiration", "int"},
+    {98, "NvRam", 3, "Path", "string"},
+    {98, "NvRam", 4, "IndexPath", "string"},
+    {98, "NvRam", 5, "IndexUsed", "object"},
+    {98, "NvRam", 6, "IndexUsedBy", "object"},
+    {98, "NvRam", 7, "IndexAttr", "object"},
+    {98, "NvRam", 8, "ServerId", "string"},
+    {98, "NvRam", 9, "ServerVersion", "int"},
+    {98, "NvRam", 10, "Uuid", "string"},
+    {98, "NvRam", 11, "Unsatisfied", "string"},
+    {98, "NvRam", 12, "Bits", "int"},
+    {98, "NvRam", 16, "Index", "int"},
+    {98, "NvRam", 17, "PackedData", "int"},
+    {99, "Table", 1, "Version", "int"},
+    {99, "Table", 2, "Expiration", "int"},
+    {99, "Table", 3, "Path", "string"},
+    {99, "Table", 4, "IndexPath", "string"},
+    {99, "Table", 5, "IndexUsed", "object"},
+    {99, "Table", 6, "IndexUsedBy", "object"},
+    {99, "Table", 7, "IndexAttr", "object"},
+    {99, "Table", 8, "ServerId", "string"},
+    {99, "Table", 9, "ServerVersion", "int"},
+    {99, "Table", 10, "Uuid", "string"},
+    {99, "Table", 11, "Unsatisfied", "string"},
+    {99, "Table", 12, "Bits", "int"},
+    {99, "Table", 16, "Name", "string"},
+    {99, "Table", 17, "Index", "int"},
+    {99, "Table", 18, "StringData", "string"},
+    {100, "ApgDealerPip", 1, "Version", "int"},
+    {100, "ApgDealerPip", 2, "Expiration", "int"},
+    {100, "ApgDealerPip", 3, "Path", "string"},
+    {100, "ApgDealerPip", 4, "IndexPath", "string"},
+    {100, "ApgDealerPip", 5, "IndexUsed", "object"},
+    {100, "ApgDealerPip", 6, "IndexUsedBy", "object"},
+    {100, "ApgDealerPip", 7, "IndexAttr", "object"},
+    {100, "ApgDealerPip", 8, "ServerId", "string"},
+    {100, "ApgDealerPip", 9, "ServerVersion", "int"},
+    {100, "ApgDealerPip", 10, "Uuid", "string"},
+    {100, "ApgDealerPip", 11, "Unsatisfied", "string"},
+    {100, "ApgDealerPip", 12, "Bits", "int"},
+    {100, "ApgDealerPip", 16, "MessageTag", "int"},
+    {100, "ApgDealerPip", 17, "Pip", "int"},
+    {101, "ApgUser", 1, "Version", "int"},
+    {101, "ApgUser", 2, "Expiration", "int"},
+    {101, "ApgUser", 3, "Path", "string"},
+    {101, "ApgUser", 4, "IndexPath", "string"},
+    {101, "ApgUser", 5, "IndexUsed", "object"},
+    {101, "ApgUser", 6, "IndexUsedBy", "object"},
+    {101, "ApgUser", 7, "IndexAttr", "object"},
+    {101, "ApgUser", 8, "ServerId", "string"},
+    {101, "ApgUser", 9, "ServerVersion", "int"},
+    {101, "ApgUser", 10, "Uuid", "string"},
+    {101, "ApgUser", 11, "Unsatisfied", "string"},
+    {101, "ApgUser", 12, "Bits", "int"},
+    {101, "ApgUser", 16, "BlockedChannel", "object"},
+    {102, "ScartSettings", 1, "Version", "int"},
+    {102, "ScartSettings", 2, "Expiration", "int"},
+    {102, "ScartSettings", 3, "Path", "string"},
+    {102, "ScartSettings", 4, "IndexPath", "string"},
+    {102, "ScartSettings", 5, "IndexUsed", "object"},
+    {102, "ScartSettings", 6, "IndexUsedBy", "object"},
+    {102, "ScartSettings", 7, "IndexAttr", "object"},
+    {102, "ScartSettings", 8, "ServerId", "string"},
+    {102, "ScartSettings", 9, "ServerVersion", "int"},
+    {102, "ScartSettings", 10, "Uuid", "string"},
+    {102, "ScartSettings", 11, "Unsatisfied", "string"},
+    {102, "ScartSettings", 12, "Bits", "int"},
+    {102, "ScartSettings", 16, "AuxInput", "int"},
+    {102, "ScartSettings", 17, "AutoVcrBypass", "int"},
+    {102, "ScartSettings", 18, "TvOutput", "int"},
+    {102, "ScartSettings", 19, "TvScartCtrlActive", "int"},
+    {102, "ScartSettings", 20, "TvAudioLevel", "int"},
+    {103, "UpdateHistory", 1, "Version", "int"},
+    {103, "UpdateHistory", 2, "Expiration", "int"},
+    {103, "UpdateHistory", 3, "Path", "string"},
+    {103, "UpdateHistory", 4, "IndexPath", "string"},
+    {103, "UpdateHistory", 5, "IndexUsed", "object"},
+    {103, "UpdateHistory", 6, "IndexUsedBy", "object"},
+    {103, "UpdateHistory", 7, "IndexAttr", "object"},
+    {103, "UpdateHistory", 8, "ServerId", "string"},
+    {103, "UpdateHistory", 9, "ServerVersion", "int"},
+    {103, "UpdateHistory", 10, "Uuid", "string"},
+    {103, "UpdateHistory", 11, "Unsatisfied", "string"},
+    {103, "UpdateHistory", 12, "Bits", "int"},
+    {103, "UpdateHistory", 16, "WasUpgradedFrom1_3", "int"},
+    {104, "AolMiniGuide", 1, "Version", "int"},
+    {104, "AolMiniGuide", 2, "Expiration", "int"},
+    {104, "AolMiniGuide", 3, "Path", "string"},
+    {104, "AolMiniGuide", 4, "IndexPath", "string"},
+    {104, "AolMiniGuide", 5, "IndexUsed", "object"},
+    {104, "AolMiniGuide", 6, "IndexUsedBy", "object"},
+    {104, "AolMiniGuide", 7, "IndexAttr", "object"},
+    {104, "AolMiniGuide", 8, "ServerId", "string"},
+    {104, "AolMiniGuide", 9, "ServerVersion", "int"},
+    {104, "AolMiniGuide", 10, "Uuid", "string"},
+    {104, "AolMiniGuide", 11, "Unsatisfied", "string"},
+    {104, "AolMiniGuide", 12, "Bits", "int"},
+    {104, "AolMiniGuide", 16, "Name", "string"},
+    {104, "AolMiniGuide", 17, "ChannelId", "string"},
+    {104, "AolMiniGuide", 18, "Url", "object"},
+    {104, "AolMiniGuide", 19, "Description", "string"},
+    {105, "Url", 1, "Version", "int"},
+    {105, "Url", 2, "Expiration", "int"},
+    {105, "Url", 3, "Path", "string"},
+    {105, "Url", 4, "IndexPath", "string"},
+    {105, "Url", 5, "IndexUsed", "object"},
+    {105, "Url", 6, "IndexUsedBy", "object"},
+    {105, "Url", 7, "IndexAttr", "object"},
+    {105, "Url", 8, "ServerId", "string"},
+    {105, "Url", 9, "ServerVersion", "int"},
+    {105, "Url", 10, "Uuid", "string"},
+    {105, "Url", 11, "Unsatisfied", "string"},
+    {105, "Url", 12, "Bits", "int"},
+    {105, "Url", 16, "Url", "string"},
+    {105, "Url", 17, "AolType", "string"},
+    {105, "Url", 18, "Description", "string"},
+    {106, "Asset", 1, "Version", "int"},
+    {106, "Asset", 2, "Expiration", "int"},
+    {106, "Asset", 3, "Path", "string"},
+    {106, "Asset", 4, "IndexPath", "string"},
+    {106, "Asset", 5, "IndexUsed", "object"},
+    {106, "Asset", 6, "IndexUsedBy", "object"},
+    {106, "Asset", 7, "IndexAttr", "object"},
+    {106, "Asset", 8, "ServerId", "string"},
+    {106, "Asset", 9, "ServerVersion", "int"},
+    {106, "Asset", 10, "Uuid", "string"},
+    {106, "Asset", 11, "Unsatisfied", "string"},
+    {106, "Asset", 12, "Bits", "int"},
+    {106, "Asset", 16, "MimeType", "string"},
+    {106, "Asset", 17, "File", "file"},
+    {107, "AssetHolder", 1, "Version", "int"},
+    {107, "AssetHolder", 2, "Expiration", "int"},
+    {107, "AssetHolder", 3, "Path", "string"},
+    {107, "AssetHolder", 4, "IndexPath", "string"},
+    {107, "AssetHolder", 5, "IndexUsed", "object"},
+    {107, "AssetHolder", 6, "IndexUsedBy", "object"},
+    {107, "AssetHolder", 7, "IndexAttr", "object"},
+    {107, "AssetHolder", 8, "ServerId", "string"},
+    {107, "AssetHolder", 9, "ServerVersion", "int"},
+    {107, "AssetHolder", 10, "Uuid", "string"},
+    {107, "AssetHolder", 11, "Unsatisfied", "string"},
+    {107, "AssetHolder", 12, "Bits", "int"},
+    {107, "AssetHolder", 16, "PathBase", "string"},
+    {107, "AssetHolder", 17, "Asset", "object"},
+    {107, "AssetHolder", 18, "MimeType", "string"},
+    {107, "AssetHolder", 19, "File", "file"},
+    {107, "AssetHolder", 20, "AxisSpecification", "object"},
+    {108, "AxisSpecification", 1, "Version", "int"},
+    {108, "AxisSpecification", 2, "Expiration", "int"},
+    {108, "AxisSpecification", 3, "Path", "string"},
+    {108, "AxisSpecification", 4, "IndexPath", "string"},
+    {108, "AxisSpecification", 5, "IndexUsed", "object"},
+    {108, "AxisSpecification", 6, "IndexUsedBy", "object"},
+    {108, "AxisSpecification", 7, "IndexAttr", "object"},
+    {108, "AxisSpecification", 8, "ServerId", "string"},
+    {108, "AxisSpecification", 9, "ServerVersion", "int"},
+    {108, "AxisSpecification", 10, "Uuid", "string"},
+    {108, "AxisSpecification", 11, "Unsatisfied", "string"},
+    {108, "AxisSpecification", 12, "Bits", "int"},
+    {108, "AxisSpecification", 16, "ClientVariant", "int"},
+    {108, "AxisSpecification", 17, "ClientInvariant", "int"},
+    {109, "CaptureRequest", 1, "Version", "int"},
+    {109, "CaptureRequest", 2, "Expiration", "int"},
+    {109, "CaptureRequest", 3, "Path", "string"},
+    {109, "CaptureRequest", 4, "IndexPath", "string"},
+    {109, "CaptureRequest", 5, "IndexUsed", "object"},
+    {109, "CaptureRequest", 6, "IndexUsedBy", "object"},
+    {109, "CaptureRequest", 7, "IndexAttr", "object"},
+    {109, "CaptureRequest", 8, "ServerId", "string"},
+    {109, "CaptureRequest", 9, "ServerVersion", "int"},
+    {109, "CaptureRequest", 10, "Uuid", "string"},
+    {109, "CaptureRequest", 11, "Unsatisfied", "string"},
+    {109, "CaptureRequest", 12, "Bits", "int"},
+    {109, "CaptureRequest", 16, "ContentType", "int"},
+    {109, "CaptureRequest", 17, "SelectionType", "int"},
+    {109, "CaptureRequest", 18, "ServiceRecordingPriority", "int"},
+    {109, "CaptureRequest", 19, "TmsId", "string"},
+    {109, "CaptureRequest", 20, "Affiliation", "string"},
+    {109, "CaptureRequest", 21, "RecordingPriority", "int"},
+    {109, "CaptureRequest", 22, "RecordQuality", "int"},
+    {109, "CaptureRequest", 23, "BillingId", "int"},
+    {109, "CaptureRequest", 24, "SeasonPass", "object"},
+    {109, "CaptureRequest", 25, "KeepTime", "int"},
+    {109, "CaptureRequest", 26, "Processed", "int"},
+    {109, "CaptureRequest", 27, "Name", "string"},
+    {109, "CaptureRequest", 28, "CapturePrePadSeconds", "int"},
+    {109, "CaptureRequest", 29, "CapturePostPadSeconds", "int"},
+    {110, "ApgState", 1, "Version", "int"},
+    {110, "ApgState", 2, "Expiration", "int"},
+    {110, "ApgState", 3, "Path", "string"},
+    {110, "ApgState", 4, "IndexPath", "string"},
+    {110, "ApgState", 5, "IndexUsed", "object"},
+    {110, "ApgState", 6, "IndexUsedBy", "object"},
+    {110, "ApgState", 7, "IndexAttr", "object"},
+    {110, "ApgState", 8, "ServerId", "string"},
+    {110, "ApgState", 9, "ServerVersion", "int"},
+    {110, "ApgState", 10, "Uuid", "string"},
+    {110, "ApgState", 11, "Unsatisfied", "string"},
+    {110, "ApgState", 12, "Bits", "int"},
+    {110, "ApgState", 16, "MarkerTransponder", "int"},
+    {110, "ApgState", 17, "ForcedPgdChangeEnable", "int"},
+    {110, "ApgState", 18, "ForcedPgdChangeTimeGMT", "int"},
+    {110, "ApgState", 19, "ForcedPgdChangeRecheckSeconds", "int"},
+    {111, "DiskPartition", 1, "Version", "int"},
+    {111, "DiskPartition", 2, "Expiration", "int"},
+    {111, "DiskPartition", 3, "Path", "string"},
+    {111, "DiskPartition", 4, "IndexPath", "string"},
+    {111, "DiskPartition", 5, "IndexUsed", "object"},
+    {111, "DiskPartition", 6, "IndexUsedBy", "object"},
+    {111, "DiskPartition", 7, "IndexAttr", "object"},
+    {111, "DiskPartition", 8, "ServerId", "string"},
+    {111, "DiskPartition", 9, "ServerVersion", "int"},
+    {111, "DiskPartition", 10, "Uuid", "string"},
+    {111, "DiskPartition", 11, "Unsatisfied", "string"},
+    {111, "DiskPartition", 12, "Bits", "int"},
+    {111, "DiskPartition", 16, "Id", "int"},
+    {111, "DiskPartition", 17, "SizeInKb", "int"},
+    {112, "DiskConfiguration", 1, "Version", "int"},
+    {112, "DiskConfiguration", 2, "Expiration", "int"},
+    {112, "DiskConfiguration", 3, "Path", "string"},
+    {112, "DiskConfiguration", 4, "IndexPath", "string"},
+    {112, "DiskConfiguration", 5, "IndexUsed", "object"},
+    {112, "DiskConfiguration", 6, "IndexUsedBy", "object"},
+    {112, "DiskConfiguration", 7, "IndexAttr", "object"},
+    {112, "DiskConfiguration", 8, "ServerId", "string"},
+    {112, "DiskConfiguration", 9, "ServerVersion", "int"},
+    {112, "DiskConfiguration", 10, "Uuid", "string"},
+    {112, "DiskConfiguration", 11, "Unsatisfied", "string"},
+    {112, "DiskConfiguration", 12, "Bits", "int"},
+    {112, "DiskConfiguration", 16, "Id", "string"},
+    {112, "DiskConfiguration", 17, "Active", "int"},
+    {112, "DiskConfiguration", 18, "DiskPartitions", "object"},
+    {112, "DiskConfiguration", 19, "MinDiskSize", "int"},
+    {112, "DiskConfiguration", 20, "MaxDiskSize", "int"},
+    {113, "Clip", 1, "Version", "int"},
+    {113, "Clip", 2, "Expiration", "int"},
+    {113, "Clip", 3, "Path", "string"},
+    {113, "Clip", 4, "IndexPath", "string"},
+    {113, "Clip", 5, "IndexUsed", "object"},
+    {113, "Clip", 6, "IndexUsedBy", "object"},
+    {113, "Clip", 7, "IndexAttr", "object"},
+    {113, "Clip", 8, "ServerId", "string"},
+    {113, "Clip", 9, "ServerVersion", "int"},
+    {113, "Clip", 10, "Uuid", "string"},
+    {113, "Clip", 11, "Unsatisfied", "string"},
+    {113, "Clip", 12, "Bits", "int"},
+    {113, "Clip", 16, "Recording", "object"},
+    {113, "Clip", 17, "Number", "int"},
+    {113, "Clip", 18, "NameOBSOLETE", "string"},
+    {113, "Clip", 19, "Authorized", "int"},
+    {113, "Clip", 20, "AuxInfo", "object"},
+    {113, "Clip", 21, "OffsetSeconds", "int"},
+    {113, "Clip", 22, "OffsetNanos", "int"},
+    {113, "Clip", 23, "DurationSeconds", "int"},
+    {113, "Clip", 24, "DurationNanos", "int"},
+    {113, "Clip", 25, "ClipName", "string"},
+    {113, "Clip", 26, "StartAnchorNumber", "int"},
+    {113, "Clip", 27, "EndAnchorNumber", "int"},
+    {114, "AuxInfo", 1, "Version", "int"},
+    {114, "AuxInfo", 2, "Expiration", "int"},
+    {114, "AuxInfo", 3, "Path", "string"},
+    {114, "AuxInfo", 4, "IndexPath", "string"},
+    {114, "AuxInfo", 5, "IndexUsed", "object"},
+    {114, "AuxInfo", 6, "IndexUsedBy", "object"},
+    {114, "AuxInfo", 7, "IndexAttr", "object"},
+    {114, "AuxInfo", 8, "ServerId", "string"},
+    {114, "AuxInfo", 9, "ServerVersion", "int"},
+    {114, "AuxInfo", 10, "Uuid", "string"},
+    {114, "AuxInfo", 11, "Unsatisfied", "string"},
+    {114, "AuxInfo", 12, "Bits", "int"},
+    {114, "AuxInfo", 16, "Name", "string"},
+    {114, "AuxInfo", 17, "Data", "object"},
+    {115, "Anchor", 1, "Version", "int"},
+    {115, "Anchor", 2, "Expiration", "int"},
+    {115, "Anchor", 3, "Path", "string"},
+    {115, "Anchor", 4, "IndexPath", "string"},
+    {115, "Anchor", 5, "IndexUsed", "object"},
+    {115, "Anchor", 6, "IndexUsedBy", "object"},
+    {115, "Anchor", 7, "IndexAttr", "object"},
+    {115, "Anchor", 8, "ServerId", "string"},
+    {115, "Anchor", 9, "ServerVersion", "int"},
+    {115, "Anchor", 10, "Uuid", "string"},
+    {115, "Anchor", 11, "Unsatisfied", "string"},
+    {115, "Anchor", 12, "Bits", "int"},
+    {115, "Anchor", 16, "Recording", "object"},
+    {115, "Anchor", 17, "Number", "int"},
+    {115, "Anchor", 18, "OffsetSeconds", "int"},
+    {115, "Anchor", 19, "OffsetNanos", "int"},
+    {115, "Anchor", 20, "Flags", "int"},
+    {116, "ClipPlayList", 1, "Version", "int"},
+    {116, "ClipPlayList", 2, "Expiration", "int"},
+    {116, "ClipPlayList", 3, "Path", "string"},
+    {116, "ClipPlayList", 4, "IndexPath", "string"},
+    {116, "ClipPlayList", 5, "IndexUsed", "object"},
+    {116, "ClipPlayList", 6, "IndexUsedBy", "object"},
+    {116, "ClipPlayList", 7, "IndexAttr", "object"},
+    {116, "ClipPlayList", 8, "ServerId", "string"},
+    {116, "ClipPlayList", 9, "ServerVersion", "int"},
+    {116, "ClipPlayList", 10, "Uuid", "string"},
+    {116, "ClipPlayList", 11, "Unsatisfied", "string"},
+    {116, "ClipPlayList", 12, "Bits", "int"},
+    {116, "ClipPlayList", 16, "Name", "string"},
+    {116, "ClipPlayList", 17, "Description", "string"},
+    {116, "ClipPlayList", 18, "ClipToPlay", "string"},
+    {117, "MediaState", 1, "Version", "int"},
+    {117, "MediaState", 2, "Expiration", "int"},
+    {117, "MediaState", 3, "Path", "string"},
+    {117, "MediaState", 4, "IndexPath", "string"},
+    {117, "MediaState", 5, "IndexUsed", "object"},
+    {117, "MediaState", 6, "IndexUsedBy", "object"},
+    {117, "MediaState", 7, "IndexAttr", "object"},
+    {117, "MediaState", 8, "ServerId", "string"},
+    {117, "MediaState", 9, "ServerVersion", "int"},
+    {117, "MediaState", 10, "Uuid", "string"},
+    {117, "MediaState", 11, "Unsatisfied", "string"},
+    {117, "MediaState", 12, "Bits", "int"},
+    {117, "MediaState", 16, "DiskConfiguration", "int"},
+    {117, "MediaState", 17, "ControlByte", "int"},
+    {118, "UserAdvisoryRating", 1, "Version", "int"},
+    {118, "UserAdvisoryRating", 2, "Expiration", "int"},
+    {118, "UserAdvisoryRating", 3, "Path", "string"},
+    {118, "UserAdvisoryRating", 4, "IndexPath", "string"},
+    {118, "UserAdvisoryRating", 5, "IndexUsed", "object"},
+    {118, "UserAdvisoryRating", 6, "IndexUsedBy", "object"},
+    {118, "UserAdvisoryRating", 7, "IndexAttr", "object"},
+    {118, "UserAdvisoryRating", 8, "ServerId", "string"},
+    {118, "UserAdvisoryRating", 9, "ServerVersion", "int"},
+    {118, "UserAdvisoryRating", 10, "Uuid", "string"},
+    {118, "UserAdvisoryRating", 11, "Unsatisfied", "string"},
+    {118, "UserAdvisoryRating", 12, "Bits", "int"},
+    {118, "UserAdvisoryRating", 16, "TVRating", "int"},
+    {118, "UserAdvisoryRating", 17, "TVAdvisory", "int"},
+    {119, "AvalancheState", 1, "Version", "int"},
+    {119, "AvalancheState", 2, "Expiration", "int"},
+    {119, "AvalancheState", 3, "Path", "string"},
+    {119, "AvalancheState", 4, "IndexPath", "string"},
+    {119, "AvalancheState", 5, "IndexUsed", "object"},
+    {119, "AvalancheState", 6, "IndexUsedBy", "object"},
+    {119, "AvalancheState", 7, "IndexAttr", "object"},
+    {119, "AvalancheState", 8, "ServerId", "string"},
+    {119, "AvalancheState", 9, "ServerVersion", "int"},
+    {119, "AvalancheState", 10, "Uuid", "string"},
+    {119, "AvalancheState", 11, "Unsatisfied", "string"},
+    {119, "AvalancheState", 12, "Bits", "int"},
+    {119, "AvalancheState", 16, "LastSuccessDownloadDate", "int"},
+    {119, "AvalancheState", 17, "LastSuccessDownloadTime", "int"},
+    {119, "AvalancheState", 18, "LastAttemptedDownloadDate", "int"},
+    {119, "AvalancheState", 19, "LastAttemptedDownloadTime", "int"},
+    {119, "AvalancheState", 20, "LastStatus", "int"},
+    {119, "AvalancheState", 21, "LastSuccessDirectoryDate", "int"},
+    {119, "AvalancheState", 22, "LastSuccessDirectoryTime", "int"},
+    {119, "AvalancheState", 23, "LastAttemptedDirectoryDate", "int"},
+    {119, "AvalancheState", 24, "LastAttemptedDirectoryTime", "int"},
+    {120, "ModemState", 1, "Version", "int"},
+    {120, "ModemState", 2, "Expiration", "int"},
+    {120, "ModemState", 3, "Path", "string"},
+    {120, "ModemState", 4, "IndexPath", "string"},
+    {120, "ModemState", 5, "IndexUsed", "object"},
+    {120, "ModemState", 6, "IndexUsedBy", "object"},
+    {120, "ModemState", 7, "IndexAttr", "object"},
+    {120, "ModemState", 8, "ServerId", "string"},
+    {120, "ModemState", 9, "ServerVersion", "int"},
+    {120, "ModemState", 10, "Uuid", "string"},
+    {120, "ModemState", 11, "Unsatisfied", "string"},
+    {120, "ModemState", 12, "Bits", "int"},
+    {120, "ModemState", 16, "CurrentMode", "int"},
+    {120, "ModemState", 17, "ExpirationDay", "int"},
+    {120, "ModemState", 18, "SuccessiveFailures", "int"},
+};
diff -Nur main.sofar/vstream/proto.h main.dev/vstream/proto.h
--- main.sofar/vstream/proto.h	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/proto.h	2004-08-11 03:18:38.467161600 +0000
@@ -0,0 +1,61 @@
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+unsigned vstream_fsid_hash(unsigned fsid, unsigned size);
+void vstream_dump_sectors(void *d, int n);
+void vstream_mfs_load_inode(int fsid, struct mfs_inode *inode);
+void vstream_mfs_init(void);
+void vstream_mfs_info(void);
+void vstream_mfs_fsid_info(int fsid);
+u32 vstream_mfs_fsid_pread(int fsid, void *buf, u64 ofs, u32 count);
+int vstream_mfs_fsid_type(int fsid);
+u64 vstream_mfs_fsid_size(int fsid);
+struct mfs_dirent *mfs_dir(int fsid, u32 *count);
+void vstream_mfs_dir_free(struct mfs_dirent *dir);
+char *vstream_mfs_type_string(int type);
+u32 vstream_mfs_resolve(char *path);
+void vstream_mfs_all_inodes(void (*fn)(struct mfs_inode *));
+struct bitmap *vstream_mfs_zone_bitmap(int zone, u64 limit);
+void vstream_mfs_purge_zone(int zone, u32 limit);
+void vstream_mfs_purge_all(u64 limit);
+u32 vstream_mfs_zone_size(int zone);
+void vstream_parse_object(int fsid, void *buf, object_fn fn);
+char *vstream_object_typestr(int objtype);
+char *vstream_schema_type(int type);
+char *vstream_schema_attrib(int type, int attr);
+void vstream_dump_schema(FILE *f);
+void *vstream_query_part(int fsid, int subobj, char *name, int *len);
+int vstream_myisdigit( char p );
+void *vstream_query_path(int fsid, char *path, int *len);
+char *vstream_query_string(int fsid, char *path);
+int vstream_query_int(int fsid, char *path);
+struct mfs_obj_attr *query_object(int fsid, char *path, int *count);
+void vstream_query_streams(char *path);
+void vstream_read_all(int fd, void *buf, int size);
+void vstream_write_all(int fd, void *buf, int size);
+int vstream_vstream_open_socket_out(char *host, int port);
+void vstream_byte_swap(void *p, char *desc);
+u64 vstream_llseek(int fd, u64 offset, int whence);
+u32 vstream_read_sectors(int fd, void *buf, u32 sector, u32 count);
+u32 vstream_write_sectors(int fd, void *buf, u32 sector, u32 count);
+void vstream_set_nonblocking(int fd);
+int vstream_bitcount32(u32 x);
+struct bitmap *vstream_bitmap_allocate(int n);
+void vstream_bitmap_set(struct bitmap *bm, unsigned i, unsigned n);
+int vstream_bitmap_query(struct bitmap *bm, unsigned i);
+void vstream_mfs_readahead(int set);
+void mfs_vstream_read_sectors(void *buf, u32 sec, u32 count);
+void mfs_vstream_write_sectors(void *buf, u32 sec, u32 count);
+void vstream_mfs_zero_sectors(int sector, int count);
+void vstream_load_devs(char *devlist);
+void vstream_add_dev_map(char *mapping);
+void vstream_io_dev_info(void);
+int vstream_io_vserver(void);
+void vstream_io_need_bswap(int set);
+u32 vstream_io_total_size(void);
+void vstream_mfs_read_partial(void *buf, u32 sec, u32 size);
+int vstream_io_get_need_bswap(void);
+void vstream_partition_parse(void);
+u32 vstream_partition_remap(u32 sec);
+u32 vstream_partition_total_size(void);
+int vstream_check_crc(void *buf, int length, u32 *crc);
+void vstream_auto_crc(void *buf, int max_length, u32 *crc);
diff -Nur main.sofar/vstream/query.c main.dev/vstream/query.c
--- main.sofar/vstream/query.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/query.c	2004-08-11 03:18:38.507219200 +0000
@@ -0,0 +1,178 @@
+/*
+  media-filesystem object query code
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+
+static struct {
+	int fsid;
+	void *buf;
+	int size;
+} loaded;
+
+static void load_object(int fsid)
+{
+	if (fsid == loaded.fsid) return;
+
+	if (loaded.buf) free(loaded.buf);
+
+	loaded.size = vstream_mfs_fsid_size(fsid);
+	loaded.buf = malloc(loaded.size);
+	loaded.fsid = fsid;
+	vstream_mfs_fsid_pread(fsid, loaded.buf, 0, loaded.size);
+}
+
+static void *memdup(void *p, int size)
+{
+	void *ret = malloc(size);
+	memcpy(ret, p, size);
+	return ret;
+}
+
+#if defined(SYS_DARWIN)
+
+/* Patch submitted by DealDatabase's GardenHose */
+/* this mess is due to mac os x's gcc not having working trampoline support */
+/* I imagine it could be done nicer but this works-- just setting up global 
+   versions of the call stack and assigning them before each call. */
+
+int subobj_g=0;
+char *name_g=NULL;
+int *len_g;
+void *ret_g=NULL;
+
+void callback(int fsid, struct mfs_subobj_header *obj,
+      struct mfs_attr_header *attr, void *data)
+{
+	if (!attr) return;
+	if (!(obj->flags && subobj_g == -1) && !(obj->id == subobj_g)) return;
+	if (strcmp(vstream_schema_attrib(obj->obj_type, attr->attr), name_g)) return;
+	*len_g = attr->len;
+	ret_g = data;
+	// printf("len=%d ret=%*.*s\n", *len, *len, *len, ret);
+}
+
+#endif
+
+
+/* return the data portion of a part of an object */
+void *vstream_query_part(int fsid, int subobj, char *name, int *len)
+{
+	void *ret = NULL;
+
+#if !defined(SYS_DARWIN)
+   void callback(int fsid, struct mfs_subobj_header *obj,
+            struct mfs_attr_header *attr, void *data)
+   {
+      if (!attr) return;
+      if (!(obj->flags && subobj == -1) && !(obj->id == subobj)) return;
+      if (strcmp(vstream_schema_attrib(obj->obj_type, attr->attr), name)) return;
+      *len = attr->len;
+      ret = data;
+      // printf("len=%d ret=%*.*s\n", *len, *len, *len, ret);
+   }
+#endif
+
+	if (vstream_mfs_fsid_type(fsid) != MFS_TYPE_OBJ) {
+		fprintf(stderr,"%d is not an object\n", fsid);
+		exit(1);
+	}
+
+	load_object(fsid);
+#if defined(SYS_DARWIN)
+   subobj_g = subobj;
+   name_g = name;
+   len_g = len;
+#endif
+	vstream_parse_object(fsid, loaded.buf, callback);
+   
+#if defined(SYS_DARWIN)
+   return ret_g;
+#else
+	return ret;
+#endif
+}
+
+/* query a subobject path starting at fsid returning the data in the
+   tail of the path */
+int vstream_myisdigit( char p )
+{
+   if ( ( p >= '0' ) && ( p <= '9' ) )
+      return( 1 );
+   return( 0 );
+}
+
+void *vstream_query_path(int fsid, char *path, int *len)
+{
+	char *tok, *p;
+	void *ret=NULL;
+	int subobj = -1;
+	
+	path = strdup(path);
+	tok = strtok_r(path,"/", &p);
+
+	while (tok) {
+		// printf("%d/%d %s\n", fsid, subobj, tok);
+		ret = vstream_query_part(fsid, subobj, tok, len);
+		if (!ret) return NULL;
+		tok = strtok_r(NULL,"/", &p);
+		if (tok && vstream_myisdigit(tok[0])) {
+			subobj = atoi(tok);
+			tok = strtok_r(NULL,"/", &p);
+		} else if (tok) {
+			struct mfs_obj_attr *objattr = ret;
+			fsid = ntohl(objattr->fsid);
+			subobj = ntohl(objattr->subobj);
+		}
+	}
+	free(path);
+	return ret;
+}
+
+char *vstream_query_string(int fsid, char *path)
+{
+	int len;
+	char *p = vstream_query_path(fsid, path, &len);
+	// printf("str=[%s] %d\n", p, len);
+	return p;
+}
+
+int vstream_query_int(int fsid, char *path)
+{
+	int len;
+	int *p = vstream_query_path(fsid, path, &len);
+	if (!p) return -1;
+	return ntohl(*p);
+}
+
+struct mfs_obj_attr *query_object(int fsid, char *path, int *count)
+{
+	int len, i;
+	struct mfs_obj_attr *ret = NULL;
+	struct mfs_obj_attr *p = vstream_query_path(fsid, path, &len);
+	if (!p) return ret;
+	*count = (len-4)/8;
+	ret = calloc(*count, sizeof(*ret));
+	for (i=0;i<*count;i++) {
+		ret[i] = p[i];
+		ret[i].fsid = ntohl(ret[i].fsid);
+		ret[i].subobj = ntohl(ret[i].subobj);
+	}
+	return ret;
+}
+
+void vstream_query_streams(char *path)
+{
+	struct mfs_dirent *dir;
+	u32 count, i;
+	dir = mfs_dir(vstream_mfs_resolve(path), &count);
+	for (i=0;i<count;i++) {
+		printf("%d: ",
+		       vstream_query_int(dir[i].fsid, "Part/File"));
+		printf("%s\n", 
+		       vstream_query_string(dir[i].fsid, "Showing/Program/Title"));
+	}
+	if (dir) vstream_mfs_dir_free(dir);
+}
diff -Nur main.sofar/vstream/schema.c main.dev/vstream/schema.c
--- main.sofar/vstream/schema.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/schema.c	2004-08-11 03:18:38.537262400 +0000
@@ -0,0 +1,264 @@
+/*
+  media-filesystem object schema code
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+#include "preload_schema.h"
+#include <assert.h>
+
+#define MAX_TYPES 200
+#define MAX_ATTRS 100
+
+static int current_type;
+static char *types[MAX_TYPES];
+
+static struct {
+	char *name;
+	int objtype;
+} attrs[MAX_TYPES][MAX_ATTRS];
+
+static void schema_add(int type, int attr, char *name, int objtype)
+{
+	int i;
+
+	assert(type < MAX_TYPES);
+	assert(attr < MAX_ATTRS);
+
+	name = strdup(name);
+	if (type != -1) {
+		attrs[type][attr].name = name;
+		attrs[type][attr].objtype = objtype;
+		return;
+	}
+	for (i=0;i<MAX_TYPES;i++) {
+		attrs[i][attr].name = name;
+		attrs[i][attr].objtype = objtype;
+	}
+	// printf("added %d/%s\n", type, name);
+}
+
+/* used to load a local schema.txt to make things faster */
+static int preload_schema(char *fname)
+{
+#ifdef LOAD_FROM_FILE
+	FILE *f = fopen(fname, "r");
+	int itype, iattr, atype=0;
+	char *type, *attr, *flag;
+
+	char line[200];
+
+	if (!f) return 0;
+
+	while (fgets(line, sizeof(line), f)) {
+		if (!isdigit(line[0])) continue;
+		if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0;
+		itype = atoi(strtok(line,"\t "));
+		type = strtok(NULL,"\t ");
+		iattr = atoi(strtok(NULL,"\t "));
+		attr = strtok(NULL,"\t ");
+		flag = strtok(NULL,"\t ");
+
+		if (!types[itype]) types[itype] = strdup(type);
+		attrs[itype][iattr].name = strdup(attr);
+		if (strcmp(flag,"string")==0) {
+			atype = TYPE_STRING;
+		} else if (strcmp(flag,"int")==0) {
+			atype = TYPE_INT;
+		} else if (strcmp(flag,"object")==0) {
+			atype = TYPE_OBJECT;
+		} else if (strcmp(flag,"file")==0) {
+			atype = TYPE_FILE;
+		}
+		if (!types[itype]) types[itype] = strdup(type);
+		schema_add(itype, iattr, attr, atype);
+		// printf("preloaded %d/%d/%s/%d\n",itype, iattr, attr, atype);
+	}
+
+	fclose(f);
+	return 1;
+#else
+	int i, itype, iattr, atype=0;
+	char *type, *attr, *flag;
+
+	for(i = 0; i < sizeof(preload_schema_table) / sizeof(preload_schema_t); i++) {
+		itype = preload_schema_table[i].itype;
+		type = preload_schema_table[i].type;
+		iattr = preload_schema_table[i].iattr;
+		attr = preload_schema_table[i].attr;
+		flag = preload_schema_table[i].attr_type;
+
+		if (!types[itype]) types[itype] = strdup(type);
+		attrs[itype][iattr].name = strdup(attr);
+		if (strcmp(flag,"string")==0) {
+			atype = TYPE_STRING;
+		} else if (strcmp(flag,"int")==0) {
+			atype = TYPE_INT;
+		} else if (strcmp(flag,"object")==0) {
+			atype = TYPE_OBJECT;
+		} else if (strcmp(flag,"file")==0) {
+			atype = TYPE_FILE;
+		} else {
+		    printf("error parsing preloaded schema table\n");
+		    exit(1);
+		}
+		if (! types[itype]) {
+		    types[itype] = strdup(type);
+		}
+		schema_add(itype, iattr, attr, atype);
+		// printf("preloaded %d/%d/%s/%d\n",itype, iattr, attr, atype);
+	}
+
+	return 1;
+#endif
+}
+
+static void load_types(void)
+{
+	struct mfs_dirent *dir;
+	u32 count, i;
+	static int loaded;
+	
+	if (loaded) return;
+
+	loaded = 1;
+
+	if (preload_schema("schema.txt")) return;
+
+	types[40] = "ObjectType";
+	
+	dir = mfs_dir(vstream_mfs_resolve("/ObjectType"), &count);
+
+	for (i=0;i<count;i++) {
+		int index = vstream_query_int(dir[i].fsid, "Index");
+		if (!types[index]) {
+			// printf("adding type %d %s\n", index, dir[i].name);
+			types[index] = strdup(dir[i].name);
+		}
+	}
+
+	if (dir) vstream_mfs_dir_free(dir);
+}
+
+
+void load_callback2(int fsid, struct mfs_subobj_header *obj,
+		    struct mfs_attr_header *attr, void *data)
+	{
+		static char *name;
+		static u32 iattr;
+		if (obj->flags || !attr) return;
+		if (attr->attr == 16) {
+			name = (char *)data;
+		} else if (attr->attr == 17) {
+			iattr = ntohl(*(u32 *)data);
+		} else if (attr->attr == 18) {
+			u32 objtype = ntohl(*(u32 *)data);
+			schema_add(current_type, iattr, name, objtype);
+		}
+	}
+
+void load_callback1(int fsid, struct mfs_subobj_header *obj,
+		    struct mfs_attr_header *attr, void *data)
+	{
+		static char *name;
+		if (!obj->flags || !attr) return;
+		if (attr->attr == 16) {
+			name = strdup((char *)data);
+		} else if (attr->attr == 17) {
+			current_type = ntohl(*(u32 *)data);
+			types[current_type] = name;
+		}
+	}
+
+
+static void load_schema(int type)
+{
+	u32 size, fsid;
+	char path[100];
+	void *buf;
+
+	if (!attrs[0][1].name) {
+		schema_add(-1, 1, "Version", TYPE_INT);
+		schema_add(-1, 2, "Expiration", TYPE_INT);
+		schema_add(-1, 3, "Path", TYPE_STRING);
+		schema_add(-1, 4, "IndexPath", TYPE_STRING);
+		schema_add(-1, 5, "IndexUsed", TYPE_OBJECT);
+		schema_add(-1, 6, "IndexUsedBy", TYPE_OBJECT);
+		schema_add(-1, 7, "IndexAttr", TYPE_OBJECT);
+		schema_add(-1, 8, "ServerId", TYPE_STRING);
+		schema_add(-1, 9, "ServerVersion", TYPE_INT);
+		schema_add(-1, 10, "Uuid", TYPE_STRING);
+		schema_add(-1, 11, "Unsatisfied", TYPE_STRING);
+		schema_add(-1, 12, "Bits", TYPE_INT);
+		schema_add(-1, 13, "Unused1", TYPE_INT);
+		schema_add(-1, 14, "Unused2", TYPE_INT);
+		schema_add(-1, 15, "Unused3", TYPE_INT);
+	}
+
+	sprintf(path, "/ObjectType/%s", vstream_schema_type(type));
+
+	fsid = vstream_mfs_resolve(path);
+	if (fsid != 0) {
+	    size = vstream_mfs_fsid_size(fsid);
+	    if (size > 0) {
+		    buf = malloc(size);
+		    vstream_mfs_fsid_pread(fsid, buf, 0, size);
+		    vstream_parse_object(fsid, buf, load_callback1);
+		    vstream_parse_object(fsid, buf, load_callback2);
+		    free(buf);
+	    }
+	}
+}
+
+/* lookup a string for a schema type */
+char *vstream_schema_type(int type)
+{
+	if (!types[type]) load_types();
+
+	return types[type];
+}
+
+/* lookup an attribute for a given type and attr value,
+   auto-loading the schema if necessary */
+char *vstream_schema_attrib(int type, int attr)
+{
+	(void) vstream_schema_type(type);
+	if (type >= MAX_TYPES) {
+		fprintf(stderr,"Invalid type %d in vstream_schema_attrib\n", type);
+		return "UNKNOWN";
+	}
+	if (attr >= MAX_ATTRS) {
+		fprintf(stderr,"Invalid attr %d in vstream_schema_attrib\n", attr);
+		return "UNKNOWN";
+	}
+	if (!attrs[type][attr].name) {
+		load_schema(type);
+	}
+	if (!attrs[type][attr].name) {
+		asprintf(&attrs[type][attr].name, "UNKNOWN(%d,%d)", type, attr);
+	}
+	//	printf("vstream_schema_attrib(%d, %d) -> %s\n", type, attr, attrs[type][attr]);
+	return attrs[type][attr].name;
+}
+
+/* dump the complete schema */
+void vstream_dump_schema(FILE *f)
+{
+	int i, j;
+
+	load_types();
+
+	for (i=1; i<MAX_TYPES; i++) {
+		if (!types[i]) continue;
+		load_schema(i);
+		for (j=1; j<MAX_ATTRS; j++) {
+			if (attrs[i][j].name) {
+				printf("%d %s %d %s %s\n",
+				       i, types[i], j, attrs[i][j].name,
+				       vstream_object_typestr(attrs[i][j].objtype));
+			}
+		}
+	}
+}
+
diff -Nur main.sofar/vstream/test.c main.dev/vstream/test.c
--- main.sofar/vstream/test.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/test.c	2004-08-11 03:18:38.557291200 +0000
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "mfs.h"
+
+int vstream_start( char *ipaddress );
+int vstream_startstream( char *fsid );
+off_t vstream_streamsize( );
+int vstream_list_streams( int longList );
+int vstream_load_chunk( char *fsid, unsigned char *buff, int size, off_t offset );
+
+void mp_msg_c( int x, const char *format, ... )
+{
+	va_list va;
+	va_start( va, format );
+	vprintf( format, va );
+	va_end( va );
+}
+
+#define CHUNK ( 128 * 1024 )
+
+int main( int argc, char *argv[] )
+{
+	off_t         offset;
+	unsigned char buffer[ CHUNK ];
+	int           count;
+	int           index;
+
+   vstream_start( "tivo" );
+
+	if ( argc == 1 )
+	{
+      vstream_list_streams( 0 );
+	}
+	else
+	{
+	   vstream_startstream( argv[ 1 ] );
+		sscanf( argv[ 2 ], "0x%lx", &offset );
+		printf( "Reading from Chunk 0x%lx\n", offset );
+		count = vstream_load_chunk( argv[ 1 ], buffer, CHUNK, offset );
+		for ( index = 0 ; index < 16 ; index++ )
+		{
+			printf( "%2.2x ", buffer[ index ] );
+		}
+		printf( "\n" );
+	}
+}
+
diff -Nur main.sofar/vstream/util.c main.dev/vstream/util.c
--- main.sofar/vstream/util.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/util.c	2004-08-11 03:18:38.587334400 +0000
@@ -0,0 +1,183 @@
+/*
+  media-filesystem library
+  tridge at samba.org, January 2001
+  released under the Gnu GPL v2
+*/
+
+#include "mfs.h"
+#ifndef TIVO			/* ppchacker, remove compiler warning */
+#include <netinet/tcp.h>
+#endif
+
+void vstream_read_all(int fd, void *buf, int size)
+{
+	while (size) {
+		int n = read(fd, buf, size);
+		if (n <= 0) {
+			// fprintf(stderr,"ERROR: eof in vstream_read_all\n");
+			exit(1);
+		}
+		buf += n;
+		size -= n;
+	}
+}
+
+void vstream_write_all(int fd, void *buf, int size)
+{
+	while (size) {
+		int n = write(fd, buf, size);
+		if (n <= 0) {
+			// fprintf(stderr,"ERROR: eof in vstream_write_all\n");
+			exit(1);
+		}
+		buf += n;
+		size -= n;
+	}
+}
+
+/* open a socket to a tcp remote host with the specified port 
+   based on code from Warren */
+int vstream_vstream_open_socket_out(char *host, int port)
+{
+	int type = SOCK_STREAM;
+	struct sockaddr_in sock_out;
+	int res;
+	struct hostent *hp;  
+	int nodelay = 1;
+	int window = 65535;
+
+	res = socket(PF_INET, type, 0);
+	if (res == -1) {
+		return -1;
+	}
+
+	hp = gethostbyname(host);
+	if (!hp) {
+		fprintf(stderr,"unknown host: %s\n", host);
+		return -1;
+	}
+
+	memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
+	sock_out.sin_port = htons(port);
+	sock_out.sin_family = PF_INET;
+
+	if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
+		close(res);
+		fprintf(stderr,"failed to connect to %s - %s\n", 
+			host, strerror(errno));
+		return -1;
+	}
+
+	setsockopt(res, SOL_SOCKET, SO_RCVBUF, &window, sizeof(int));
+	setsockopt(res, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(int));
+
+	return res;
+}
+
+void vstream_byte_swap(void *p, char *desc)
+{
+	int n, i;
+	while (*desc) {
+		switch (*desc) {
+		case 'i': {
+			u32 *v;
+			n = strtol(desc+1, &desc, 10);
+			v = p;
+			for (i=0;i<n;i++) v[i] = ntohl(v[i]);
+			p = (void *)(v+n);
+			break;
+		}
+
+		case 's': {
+			u16 *v;
+			n = strtol(desc+1, &desc, 10);
+			v = p;
+			for (i=0;i<n;i++) v[i] = ntohs(v[i]);
+			p = (void *)(v+n);
+			break;
+		}
+
+		case 'b': {
+			n = strtol(desc+1, &desc, 10);
+			p += n;
+			break;
+		}
+		}
+		while (*desc == ' ') desc++;
+	}
+}
+
+
+u64 vstream_llseek(int fd, u64 offset, int whence)
+{
+	u64 result = 0;
+#ifdef TIVO
+	if (syscall(__NR__vstream_llseek, fd, (u32)(offset>>32), (u32)(offset&0xffffffff), &result, whence) != 0) {
+		fprintf(stderr,"vstream_llseek failed\n");
+		exit(1);
+	}
+#endif
+	return result;
+}
+
+u32 vstream_read_sectors(int fd, void *buf, u32 sector, u32 count)
+{
+#ifdef TIVO
+	struct FsIovec vec;
+	struct FsIoRequest req;
+
+	vec.pb = buf;
+	vec.cb = count*SECTOR_SIZE;
+	req.sector = sector;
+	req.num_sectors = count;
+	req.deadline = 0;
+	
+	return syscall(__NR_readsectors, fd, &vec, 1, &req);
+#else
+	vstream_llseek(fd, ((u64)sector)<<SECTOR_SHIFT, SEEK_SET);
+	return read(fd, buf, count * SECTOR_SIZE)>>SECTOR_SHIFT;
+#endif
+}
+
+u32 vstream_write_sectors(int fd, void *buf, u32 sector, u32 count)
+{
+#ifdef TIVO
+	struct FsIovec vec;
+	struct FsIoRequest req;
+
+	vec.pb = buf;
+	vec.cb = count*SECTOR_SIZE;
+	req.sector = sector;
+	req.num_sectors = count;
+	req.deadline = 0;
+	
+	return syscall(__NR_writesectors, fd, &vec, 1, &req);
+#else
+	vstream_llseek(fd, ((u64)sector)<<SECTOR_SHIFT, SEEK_SET);
+	return write(fd, buf, count * SECTOR_SIZE)>>SECTOR_SHIFT;
+#endif
+}
+
+
+/****************************************************************************
+Set a fd into nonblocking mode
+****************************************************************************/
+void vstream_set_nonblocking(int fd)
+{
+	int val;
+
+	if((val = fcntl(fd, F_GETFL, 0)) == -1)
+		return;
+	if (!(val & O_NONBLOCK)) {
+		val |= O_NONBLOCK;
+		fcntl(fd, F_SETFL, val);
+	}
+}
+
+int vstream_bitcount32(u32 x)
+{
+	int count;
+	for (count=0; x; count++)
+		x &= (x-1);
+	return count;
+}
diff -Nur main.sofar/vstream/vstream.c main.dev/vstream/vstream.c
--- main.sofar/vstream/vstream.c	1970-01-01 00:00:00.000000000 +0000
+++ main.dev/vstream/vstream.c	2004-08-11 03:23:51.627464000 +0000
@@ -0,0 +1,389 @@
+/* Glue to play a stream from a remote TiVo
+ *
+ * tivo at wingert.org, February 2003
+ *
+ * Copyright (C) 2003 Christopher R. Wingert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "mfs.h"
+#include "mp_msg.h"
+
+#define ENV_VAR                  "MFS_DEVLIST"
+#define CHUNKSIZE                ( 128 * 1024 )
+
+struct sNowShowing 
+{
+   char dirName[ 80 ];
+   char blankTitle[ 80 ];
+};
+
+struct sNowShowing dirList[] =
+{
+   { "/Recording/LiveCache", "Live TV Buffer" },
+   { "/Recording/NowShowingByTitle", "Now Showing Title" },
+   { "/Recording/NowShowing", "Now Showing Title" },
+   { "/Recording/Complete", "Now Showing Title" },
+   { "/Recording/NowShowingByBucketTitle", "Now Showing Title" },
+   { "", "" }
+};
+
+int vstream_start( char *ipaddress );
+int vstream_startstream( char *fsid );
+off_t vstream_streamsize( );
+int vstream_list_streams( int longList );
+int vstream_load_chunk( char *fsid, unsigned char *buff, int size, off_t offset );
+
+struct sfileParts
+{
+   int    fileNo;
+   off_t  fileSize;
+   int    chunks;
+};
+
+char tivoIP[ 80 ] = "";
+char lastFsid[ 80 ] = "";
+int filePart = -1;
+struct sfileParts fileParts[ 255 ];
+int filePartsTotal = 0;
+off_t vstream_totalSize = 0;
+off_t max_32bit = 0x7fffffff;
+
+int vstream_fsidtoparts( char *fsid )
+{
+   struct mfs_obj_attr *obj;
+   int                 pcount;
+   int                 index;
+   int                 ifsid;
+   char                calcFsid[ 80 ];
+   unsigned char       *buffer;
+   int                 pesFileId;
+   int                 size;
+   int                 count;
+   char                myfsid[ 80 ];
+   char                *mypart;
+   off_t               diff;
+   
+
+   if ( strcmp( fsid, lastFsid ) != 0 )
+   {
+      strcpy( myfsid, fsid );
+      mypart = strchr( myfsid, '/' );
+      if ( mypart != 0 )
+      {
+         *mypart = 0;
+         mypart++;
+         filePart = atoi( mypart );
+      }
+
+      ifsid = vstream_mfs_resolve( myfsid );
+      if ( ifsid > 0 )
+      {
+         vstream_totalSize = 0;
+         obj = query_object( ifsid, "Part", &pcount );
+         for( index = 0 ; index < pcount ; index ++ )
+         {
+            sprintf( calcFsid, "Part/%d/File", obj[ index ].subobj );
+            fileParts[ index ].fileNo = vstream_query_int( ifsid, calcFsid );
+				// HACK - Ignore last chunk of a Part File
+				// Why?  I have no idea.
+            fileParts[ index ].fileSize = 
+               vstream_mfs_fsid_size( fileParts[ index ].fileNo ) - 0x20000;
+            fileParts[ index ].chunks = 
+               ( fileParts[ index ].fileSize / CHUNKSIZE );
+
+            mp_msg
+            ( 
+               MSGT_NETWORK, MSGL_DBG3,
+              "vstream_fsidtoparts(): index %d, file %d, chunks %d, size %ld\n",
+               index,
+               fileParts[ index ].fileNo,
+               fileParts[ index ].fileSize,
+               fileParts[ index ].chunks
+            );
+
+         }
+         free( obj );
+         filePartsTotal = pcount;
+         mp_msg( MSGT_NETWORK, MSGL_DBG3,
+            "vstream_fsidtoparts(): No More Part Files\n" );
+
+         if ( filePart != -1 )
+         {
+            if ( filePart > filePartsTotal )
+            {
+               mp_msg( MSGT_NETWORK, MSGL_ERR,
+                  "vstream_fsidtoparts(): Invalid Part File %d\n", filePart );
+               return( 0 );
+            }
+            else
+            {
+               fileParts[ 0 ].fileNo = fileParts[ filePart ].fileNo;
+               fileParts[ 0 ].fileSize = fileParts[ filePart ].fileSize;
+               fileParts[ 0 ].chunks = fileParts[ filePart ].chunks;
+               filePartsTotal = 1;
+            }
+         }
+
+         for( index = 0 ; index < filePartsTotal ; index++ )
+         {
+            vstream_totalSize += fileParts[ index ].fileSize;
+         }
+
+         // We have to go into the last chunk to figure its exact size
+         buffer = malloc( CHUNKSIZE );
+         count = vstream_mfs_fsid_pread( fileParts[ filePartsTotal - 1 ].fileNo, 
+            buffer, 0, CHUNKSIZE );
+         if ( count == CHUNKSIZE )
+         {
+            pesFileId = buffer[ 0x00 ] << 24 | buffer[ 0x01 ] << 16 | 
+               buffer[ 0x02 ] << 8 | buffer[ 0x03 ];
+            if ( pesFileId == 0xf5467abd )
+            {
+               vstream_totalSize -= fileParts[ filePartsTotal - 1 ].fileSize;
+               size = buffer[ 0x0c ] << 24 | buffer[ 0x0d ] << 16 | 
+                  buffer[ 0x0e ] << 8 | buffer[ 0x03 ];
+               size /= 256;
+               size -= 4;
+               size *= CHUNKSIZE;
+               fileParts[ filePartsTotal - 1 ].fileSize = size;
+               fileParts[ filePartsTotal - 1 ].chunks = ( size / CHUNKSIZE );
+               vstream_totalSize += size;
+            }
+         }
+         free( buffer );
+
+         mp_msg( MSGT_NETWORK, MSGL_DBG3,
+            "vstream_fsidtoparts(): totalsize %lld\n", vstream_totalSize );
+
+         strcpy( lastFsid, fsid );
+      }
+      else
+      {
+         filePartsTotal = 0;
+      }
+   }
+   return( 1 );
+}
+
+off_t vstream_streamsize( )
+{
+   return( vstream_totalSize );
+}
+
+
+void vstream_fsidtooffset( int chunk, int *fileNo, off_t *fileChunk )
+{
+   int index;
+
+   *fileNo = 0;
+   *fileChunk = 0;
+
+   for( index = 0 ; index < filePartsTotal ; index++ )
+   {
+      if ( chunk >= fileParts[ index ].chunks )
+      {
+         chunk -= fileParts[ index ].chunks;
+      }
+      else
+      {
+         break;
+      }
+   }
+   if ( chunk < fileParts[ index ].chunks )
+   {
+      *fileNo = fileParts[ index ].fileNo;
+      *fileChunk = chunk;
+   }
+   mp_msg
+   ( 
+      MSGT_NETWORK, MSGL_DBG3, 
+      "vstream_fsidtooffset() file %d, chunk %d\n",
+      *fileNo, *fileChunk 
+   );
+}
+
+int vstream_startstream( char *fsid )
+{
+   return( vstream_fsidtoparts( fsid ) );
+}
+
+
+int vstream_load_chunk( char *fsid, unsigned char *buff, int size, off_t foffset )
+{
+   int    count;
+   off_t  chunk;
+   off_t  fileoffset;
+   int    fileNo;
+   off_t  fileNoChunkOffset;
+   off_t  offset;
+
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, 
+      "vstream_load_chunk() begin %llx\n", foffset );
+
+   vstream_mfs_readahead( 1 );
+   if ( vstream_fsidtoparts( fsid ) == 0 )
+   {
+      return( 0 );
+   }
+   if ( filePartsTotal <= 0 )
+   {
+      return( 0 );
+   }
+   if ( foffset >= vstream_streamsize() )
+   {
+      return( 0 );
+   }
+
+   chunk = foffset / CHUNKSIZE;
+   offset = foffset - ( chunk * CHUNKSIZE );
+   vstream_fsidtooffset( chunk, &fileNo, &fileNoChunkOffset );
+   fileoffset = ( fileNoChunkOffset * CHUNKSIZE ) + offset;
+   // mp_msg( MSGT_NETWORK, MSGL_DBG3, "vstream_load_chunk() fN %d\n", 
+	// 	fileNo );
+   // mp_msg( MSGT_NETWORK, MSGL_DBG3, "vstream_load_chunk() fO %llx\n", 
+	// 	fileoffset );
+   count = vstream_mfs_fsid_pread( fileNo, buff, fileoffset, size );
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "vstream_load_chunk() count %x\n", 
+		count );
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, 
+		"vstream_load_chunk() bytes %x %x %x %x %x %x %x %x\n", 
+		buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ],
+		buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] );
+   mp_msg( MSGT_NETWORK, MSGL_DBG3, "vstream_load_chunk() end %llx\n", 
+		foffset );
+    
+   return( count );
+}
+
+void vstream_vstream_query_streams( )
+{
+   struct mfs_dirent   *dir;
+   struct mfs_obj_attr *obj;
+   u32                 count;
+   u32                 h;
+   u32                 i;
+   int                 pcount;
+   char                *ptr;
+
+   h = 0;
+   while( strlen( dirList[ h ].dirName ) > 0 )
+   {
+      dir = mfs_dir( vstream_mfs_resolve( dirList[ h ].dirName ), &count );
+      for ( i = 0 ; i < count ; i++ ) 
+      {
+         obj = query_object( dir[ i ].fsid, "Part", &pcount );
+         free( obj );
+         printf( "[%10d]", vstream_query_int( dir[ i ].fsid, "Part" ) );
+         printf( "[%2d]", pcount );
+         ptr = vstream_query_string( dir[ i ].fsid, "Showing/Program/Title" );
+         if ( ptr == 0 )
+         {
+            ptr = dirList[ h ].blankTitle;
+         }
+         printf( "[%-20.20s]", ptr );
+         printf( "[%-40.40s]\n",
+                vstream_query_string( dir[ i ].fsid, "Showing/Program/EpisodeTitle" ) );
+      }
+      if ( dir ) vstream_mfs_dir_free( dir );
+      h++;
+   }
+}
+
+void vstream_vstream_query_streams_long( )
+{
+   struct mfs_dirent   *dir;
+   struct mfs_obj_attr *obj;
+   u32                 count;
+   u32                 h;
+   u32                 i;
+   int                 pcount;
+	int                 dt;
+	int                 tm;
+   time_t              recTime;
+   struct tm           *recTimetm;
+   char                *ptr;
+
+   h = 0;
+   while( strlen( dirList[ h ].dirName ) > 0 )
+   {
+      dir = mfs_dir( vstream_mfs_resolve( dirList[ h ].dirName ), &count );
+      for ( i = 0 ; i < count ; i++ ) 
+      {
+         obj = query_object( dir[ i ].fsid, "Part", &pcount );
+         free( obj );
+
+         recTime = ( vstream_query_int( dir[ i ].fsid, "StartDate" ) * 86400 );
+         recTime += vstream_query_int( dir[ i ].fsid, "StartTime" ) + 60;
+         recTimetm = localtime( &recTime );
+         recTimetm->tm_year %= 100;
+
+         printf( "|" );
+         printf( "%2.2d/%2.2d/%2.2d", recTimetm->tm_mon + 1, recTimetm->tm_mday,
+            recTimetm->tm_year );
+         printf( "|" );
+         printf( "%2.2d:%2.2d", recTimetm->tm_hour, recTimetm->tm_min );
+         printf( "|" );
+         ptr = vstream_query_string( dir[ i ].fsid, "Showing/Program/Title" );
+         if ( ptr == 0 )
+         {
+            ptr = dirList[ h ].blankTitle;
+         }
+         printf( "%s", ptr );
+         printf( "|" );
+         printf( "%s", vstream_query_string( dir[ i ].fsid, 
+               "Showing/Program/EpisodeTitle" ) );
+         printf( "|" );
+         printf( "%d", vstream_query_int( dir[ i ].fsid, "Part" ) );
+         printf( "|" );
+         printf( "%d", pcount );
+         printf( "|" );
+         printf( "\n" );
+      }
+      if ( dir ) vstream_mfs_dir_free( dir );
+      h++;
+   }
+}
+
+int vstream_list_streams( int longList )
+{
+   vstream_mfs_init();
+
+	if ( longList == 0 )
+	{
+      vstream_vstream_query_streams( );
+	}
+	else
+	{
+      vstream_vstream_query_streams_long( );
+	}
+
+   return( 0 );
+}
+
+int vstream_start( char *ipaddress )
+{
+   sprintf( tivoIP, ":%s", ipaddress );
+   setenv( ENV_VAR, tivoIP, 0 );
+   vstream_mfs_init();
+}
+
+
+


More information about the MPlayer-dev-eng mailing list