* libdvdcss.c: DVD reading library.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: libdvdcss.c,v 1.17 2001/10/14 03:26:20 stef Exp $
+ * $Id: libdvdcss.c,v 1.27 2002/01/14 22:06:57 stef Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include "defs.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <videolan/vlc.h>
+
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
# include <sys/uio.h> /* struct iovec */
#endif
-#include "config.h"
-#include "common.h"
-
#if defined( WIN32 )
# include "input_iovec.h"
#endif
*****************************************************************************/
static int _dvdcss_open ( dvdcss_handle, char *psz_target );
static int _dvdcss_close ( dvdcss_handle );
-static int _dvdcss_seek ( dvdcss_handle, int i_blocks );
-static int _dvdcss_read ( dvdcss_handle, void *p_buffer, int i_blocks );
static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks );
/*****************************************************************************
static int _win32_dvdcss_aclose ( int i_fd );
static int _win32_dvdcss_aseek ( int i_fd, int i_blocks, int i_method );
static int _win32_dvdcss_aread ( int i_fd, void *p_data, int i_blocks );
+#else
+static int _dvdcss_raw_open ( dvdcss_handle, char *psz_target );
#endif
/*****************************************************************************
* dvdcss_open: initialize library, open a DVD device, crack CSS key
*****************************************************************************/
-extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags )
+extern dvdcss_handle dvdcss_open ( char *psz_target )
{
int i_ret;
- char psz_method[16] = "dvdcss_method";
+ char *psz_method = getenv( "DVDCSS_METHOD" );
+ char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
+#ifndef WIN32
+ char *psz_raw_device = getenv( "DVDCSS_RAW_DEVICE" );
+#endif
dvdcss_handle dvdcss;
dvdcss = malloc( sizeof( struct dvdcss_s ) );
if( dvdcss == NULL )
{
- if( ! (i_flags & DVDCSS_INIT_QUIET) )
- {
- DVDCSS_ERROR( "could not initialize library" );
- }
-
return NULL;
}
- /* Initialize structure */
+ /* Initialize structure with default values */
dvdcss->p_titles = NULL;
- dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG;
- dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET);
dvdcss->psz_error = "no error";
+ dvdcss->i_method = DVDCSS_METHOD_TITLE;
+ dvdcss->b_debug = 0;
+ dvdcss->b_errors = 1;
-
-
- /* find method from DVDCSS_METHOD environment variable */
- dvdcss->i_method = DVDCSS_TITLE;
-
- if( getenv( psz_method ) )
+ /* Find method from DVDCSS_METHOD environment variable */
+ if( psz_method != NULL )
{
- if( !strncmp( getenv( psz_method ), "key", 3 ) )
+ if( !strncmp( psz_method, "key", 4 ) )
{
- dvdcss->i_method = DVDCSS_KEY;
+ dvdcss->i_method = DVDCSS_METHOD_KEY;
}
- else if( !strncmp( getenv( psz_method ), "disc", 4 ) )
+ else if( !strncmp( psz_method, "disc", 5 ) )
{
- dvdcss->i_method = DVDCSS_DISC;
+ dvdcss->i_method = DVDCSS_METHOD_DISC;
+ }
+ else if( !strncmp( psz_method, "title", 5 ) )
+ {
+ dvdcss->i_method = DVDCSS_METHOD_TITLE;
+ }
+ else
+ {
+ _dvdcss_error( dvdcss, "unknown decrypt method, please choose "
+ "from 'title', 'key' or 'disc'" );
+ free( dvdcss );
+ return NULL;
+ }
+ }
+
+ /* Find verbosity from DVDCSS_VERBOSE environment variable */
+ if( psz_verbose != NULL )
+ {
+ switch( atoi( psz_verbose ) )
+ {
+ case 0:
+ dvdcss->b_errors = 0;
+ break;
+ case 1:
+ break;
+ case 2:
+ dvdcss->b_debug = 1;
+ break;
+ default:
+ _dvdcss_error( dvdcss, "unknown verbose level, please choose "
+ "from '0', '1' or '2'" );
+ free( dvdcss );
+ return NULL;
+ break;
}
}
+ /* Open device */
i_ret = _dvdcss_open( dvdcss, psz_target );
if( i_ret < 0 )
{
}
}
+ memset( dvdcss->css.p_unenc_key, 0, KEY_SIZE );
+
+#ifndef WIN32
+ if( psz_raw_device != NULL )
+ {
+ _dvdcss_raw_open( dvdcss, psz_raw_device );
+ }
+#endif
+
return dvdcss;
}
extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks, int i_flags )
{
/* title cracking method is too slow to be used at each seek */
- if( ( ( i_flags & DVDCSS_SEEK_MPEG ) && ( dvdcss->i_method != DVDCSS_TITLE ) )
- || ( i_flags & DVDCSS_SEEK_INI ) )
+ if( ( ( i_flags & DVDCSS_SEEK_MPEG )
+ && ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) ) )
+ {
+ int i_ret;
+
+ /* Crack or decrypt CSS title key for current VTS */
+ i_ret = CSSGetTitleKey( dvdcss, i_blocks );
+
+ if( i_ret < 0 )
+ {
+ _dvdcss_error( dvdcss, "fatal error in vts css key" );
+ return i_ret;
+ }
+ else if( i_ret > 0 )
+ {
+ _dvdcss_error( dvdcss, "decryption unavailable" );
+ return -1;
+ }
+ }
+ else if( i_flags & DVDCSS_SEEK_KEY )
{
/* check the title key */
- dvdcss_title( dvdcss, i_blocks );
+ if( dvdcss_title( dvdcss, i_blocks ) )
+ {
+ return -1;
+ }
}
return _dvdcss_seek( dvdcss, i_blocks );
dvdcss->i_readv_buf_size = 0;
#else
- dvdcss->i_fd = open( psz_target, 0 );
+ dvdcss->i_fd = dvdcss->i_read_fd = open( psz_target, 0 );
if( dvdcss->i_fd == -1 )
{
return 0;
}
+#ifndef WIN32
+static int _dvdcss_raw_open ( dvdcss_handle dvdcss, char *psz_target )
+{
+ dvdcss->i_raw_fd = open( psz_target, 0 );
+
+ if( dvdcss->i_raw_fd == -1 )
+ {
+ _dvdcss_error( dvdcss, "failed opening raw device, continuing" );
+ return -1;
+ }
+ else
+ {
+ dvdcss->i_read_fd = dvdcss->i_raw_fd;
+ }
+
+ return 0;
+}
+#endif
+
static int _dvdcss_close ( dvdcss_handle dvdcss )
{
#if defined( WIN32 )
#else
close( dvdcss->i_fd );
+ if( dvdcss->i_raw_fd >= 0 )
+ {
+ close( dvdcss->i_raw_fd );
+ dvdcss->i_raw_fd = -1;
+ }
+
#endif
return 0;
}
-static int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
+int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
{
#if defined( WIN32 )
dvdcss->i_seekpos = i_blocks;
return ( _win32_dvdcss_aseek( dvdcss->i_fd, i_blocks, SEEK_SET ) );
}
#else
- off_t i_read;
+ off_t i_read;
dvdcss->i_seekpos = i_blocks;
- i_read = lseek( dvdcss->i_fd,
+ i_read = lseek( dvdcss->i_read_fd,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
return i_read / DVDCSS_BLOCK_SIZE;
}
-static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
+int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
{
#if defined( WIN32 )
if( WIN2K )
#else
int i_bytes;
- i_bytes = read( dvdcss->i_fd, p_buffer,
+ i_bytes = read( dvdcss->i_read_fd, p_buffer,
(size_t)i_blocks * DVDCSS_BLOCK_SIZE );
return i_bytes / DVDCSS_BLOCK_SIZE;
#endif
return i_read;
#else
- i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );
+ i_read = readv( dvdcss->i_read_fd, p_iovec, i_blocks );
return i_read / DVDCSS_BLOCK_SIZE;
#endif