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

Joey Parrish joey at nicewarrior.org
Mon Aug 2 19:00:20 CEST 2004


Hello,

This patch came from tivo-mplayer (tivo-mplayer.sf.net I think).  I
diff'd their source tarball against the pre-release they made it from,
and I've updated the patch to current CVS without cosmetics.

This patch allows mplayer to stream from your tivo using a tivo:// url.
Your tivo must have an app called vstream installed, which is from
tivo-mplayer.sf.net I think.

Not my code, so I can't promise it's all for the best.  I also can't
explain any of the strange things it does.

Comments?

--Joey

-- 
"I eat donuts for dying children." --Andrew
-------------- next part --------------
diff -Nur main.cvs/Makefile main.dev/Makefile
--- main.cvs/Makefile	Fri Jul  9 12:32:17 2004
+++ main.dev/Makefile	Sun Aug  1 23:27:37 2004
@@ -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
@@ -122,6 +127,9 @@
 
 libfame/libfame.a:
 	$(MAKE) -C libfame
+
+vstream/vstream.a:
+	$(MAKE) -C vstream
 
 libmpdemux/libmpdemux.a:
 	$(MAKE) -C libmpdemux
diff -Nur main.cvs/configure main.dev/configure
--- main.cvs/configure	Sat Jul 31 17:17:23 2004
+++ main.dev/configure	Sun Aug  1 23:36:00 2004
@@ -249,6 +249,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:
@@ -1197,6 +1198,7 @@
 _tremor=no
 _faad_internal=auto
 _faad_external=auto
+_vstream=yes
 _xmms=no
 # dvdnav disabled, it does not work
 #_dvdnav=no
@@ -1379,6 +1381,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	;;
@@ -4511,6 +4515,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"
 
@@ -6114,6 +6125,7 @@
 MPLAYER_NETWORK_LIB = $_ld_live $_ld_network
 DVBIN = $_dvbin
 VIDIX = $_vidix
+VSTREAM = $_vstream
 SHARED_PP = $_shared_pp
 CONFIG_PP = yes
 CONFIG_RISKY = yes
@@ -6562,6 +6574,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.cvs/libmpdemux/cache2.c main.dev/libmpdemux/cache2.c
--- main.cvs/libmpdemux/cache2.c	Mon Jul 26 17:06:30 2004
+++ main.dev/libmpdemux/cache2.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/libmpdemux/demux_ty.c main.dev/libmpdemux/demux_ty.c
--- main.cvs/libmpdemux/demux_ty.c	Mon Jul 19 18:17:37 2004
+++ main.dev/libmpdemux/demux_ty.c	Sun Aug  1 23:36:00 2004
@@ -79,32 +79,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;
 
-   int           tivoType;           // 1 = SA, 2 = DTiVo
+   unsigned char   lastAudio[ MAX_AUDIO_BUFFER ];
+   int             lastAudioEnd;
 
-   float         firstAudioPTS;
-   float         firstVideoPTS;
+   int             tivoType;           // 1 = SA, 2 = DTiVo
+
+   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 +384,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 +397,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 +633,9 @@
    int              esOffset1;
    int              esOffset2;
 
+   unsigned char    lastCC[ 16 ];
+   unsigned char    lastXDS[ 16 ];
+
    TiVoInfo         *tivo = 0;
 
    if ( demux->stream->type == STREAMTYPE_DVD )
@@ -370,7 +643,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 +680,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 +745,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 +764,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 +779,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 +794,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 +866,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 +1137,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 +1170,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 +1196,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 +1251,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 +1312,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.cvs/libmpdemux/demuxer.c main.dev/libmpdemux/demuxer.c
--- main.cvs/libmpdemux/demuxer.c	Fri Jul 16 15:31:17 2004
+++ main.dev/libmpdemux/demuxer.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/libmpdemux/network.c main.dev/libmpdemux/network.c
--- main.cvs/libmpdemux/network.c	Sat Jul 24 19:37:07 2004
+++ main.dev/libmpdemux/network.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/libmpdemux/stream.c main.dev/libmpdemux/stream.c
--- main.cvs/libmpdemux/stream.c	Sat Mar 13 10:10:02 2004
+++ main.dev/libmpdemux/stream.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/libmpdemux/stream.h main.dev/libmpdemux/stream.h
--- main.cvs/libmpdemux/stream.h	Sat Mar 13 10:10:02 2004
+++ main.dev/libmpdemux/stream.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/mencoder.c main.dev/mencoder.c
--- main.cvs/mencoder.c	Fri Jul 16 15:31:16 2004
+++ main.dev/mencoder.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/mplayer.c main.dev/mplayer.c
--- main.cvs/mplayer.c	Sat Jul 24 19:33:32 2004
+++ main.dev/mplayer.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/Makefile main.dev/vstream/Makefile
--- main.cvs/vstream/Makefile	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/Makefile	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/README main.dev/vstream/README
--- main.cvs/vstream/README	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/README	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/bitmap.c main.dev/vstream/bitmap.c
--- main.cvs/vstream/bitmap.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/bitmap.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/crc.c main.dev/vstream/crc.c
--- main.cvs/vstream/crc.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/crc.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/darwin_dlfcn.h main.dev/vstream/darwin_dlfcn.h
--- main.cvs/vstream/darwin_dlfcn.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/darwin_dlfcn.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/darwin_getopt.h main.dev/vstream/darwin_getopt.h
--- main.cvs/vstream/darwin_getopt.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/darwin_getopt.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/darwin_unistd.h main.dev/vstream/darwin_unistd.h
--- main.cvs/vstream/darwin_unistd.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/darwin_unistd.h	Sun Aug  1 23:36:00 2004
@@ -0,0 +1,8 @@
+#ifndef _LIBSA_UNISTD_H_
+#define _LIBSA_UNISTD_H_
+
+
+#define getpagesize()    PAGE_SIZE
+
+
+#endif /* _LIBSA_UNISTD_H_ */
diff -Nur main.cvs/vstream/io.c main.dev/vstream/io.c
--- main.cvs/vstream/io.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/io.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/mfs.c main.dev/vstream/mfs.c
--- main.cvs/vstream/mfs.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/mfs.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/mfs.h main.dev/vstream/mfs.h
--- main.cvs/vstream/mfs.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/mfs.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/mkproto.awk main.dev/vstream/mkproto.awk
--- main.cvs/vstream/mkproto.awk	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/mkproto.awk	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/object.c main.dev/vstream/object.c
--- main.cvs/vstream/object.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/object.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/partition.c main.dev/vstream/partition.c
--- main.cvs/vstream/partition.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/partition.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/preload_schema.h main.dev/vstream/preload_schema.h
--- main.cvs/vstream/preload_schema.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/preload_schema.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/proto.h main.dev/vstream/proto.h
--- main.cvs/vstream/proto.h	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/proto.h	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/query.c main.dev/vstream/query.c
--- main.cvs/vstream/query.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/query.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/schema.c main.dev/vstream/schema.c
--- main.cvs/vstream/schema.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/schema.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/test.c main.dev/vstream/test.c
--- main.cvs/vstream/test.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/test.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/util.c main.dev/vstream/util.c
--- main.cvs/vstream/util.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/util.c	Sun Aug  1 23:36:00 2004
@@ -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.cvs/vstream/vstream.c main.dev/vstream/vstream.c
--- main.cvs/vstream/vstream.c	Wed Dec 31 18:00:00 1969
+++ main.dev/vstream/vstream.c	Sun Aug  1 23:36:00 2004
@@ -0,0 +1,406 @@
+/* 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++ )
+         {
+#if defined(__CYGWIN__)
+            diff = max_32bit - vstream_totalSize;
+            if ( fileParts[ index ].fileSize > diff )
+            {
+               if ( vstream_totalSize != max_32bit )
+               {
+                  vstream_totalSize = max_32bit;
+                  mp_msg( MSGT_NETWORK, MSGL_ERR,
+     "WARNING stream too big for CYGWIN, will play as much as possible!\n" );
+               }
+            }
+            else
+            {
+               vstream_totalSize += fileParts[ index ].fileSize;
+            }
+#else
+            vstream_totalSize += fileParts[ index ].fileSize;
+#endif
+         }
+
+         // 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