X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=extras%2Flibdvdcss%2Flibdvdcss.c;h=638fb8c0b4ddc975c9f9c3c5701f7a0dea087d80;hb=922535189ca1d75e8715fc54cea5596eca5e84a1;hp=f698209eab5fc2622055ac2aeded8c764e643d96;hpb=beda27837feb875ff28d2540fb3f189d39f2d050;p=vlc diff --git a/extras/libdvdcss/libdvdcss.c b/extras/libdvdcss/libdvdcss.c index f698209eab..638fb8c0b4 100644 --- a/extras/libdvdcss/libdvdcss.c +++ b/extras/libdvdcss/libdvdcss.c @@ -2,7 +2,7 @@ * 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 * Samuel Hocevar @@ -26,8 +26,6 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include #include #include @@ -35,6 +33,8 @@ #include #include +#include + #ifdef HAVE_UNISTD_H # include #endif @@ -45,9 +45,6 @@ # include /* struct iovec */ #endif -#include "config.h" -#include "common.h" - #if defined( WIN32 ) # include "input_iovec.h" #endif @@ -61,8 +58,6 @@ *****************************************************************************/ 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 ); /***************************************************************************** @@ -75,16 +70,22 @@ static int _win32_dvdcss_aopen ( char c_drive, dvdcss_handle dvdcss ); 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; @@ -92,37 +93,63 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) 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 ) { @@ -157,6 +184,15 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) } } + 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; } @@ -174,11 +210,32 @@ extern char * dvdcss_error ( dvdcss_handle 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 ); @@ -428,7 +485,7 @@ static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target ) 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 ) { @@ -441,6 +498,25 @@ static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target ) 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 ) @@ -464,12 +540,18 @@ static int _dvdcss_close ( dvdcss_handle dvdcss ) #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; @@ -501,11 +583,11 @@ static int _dvdcss_seek ( dvdcss_handle dvdcss, int 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; @@ -513,7 +595,7 @@ static int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks ) } -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 ) @@ -536,7 +618,7 @@ static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks ) #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 @@ -572,7 +654,7 @@ static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec, 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