Commit b8ff945d authored by Stéphane Borel's avatar Stéphane Borel

Support for libdvdread.

Libdvdread files are in extras/libdvdread. They have not been changed from
those of libdvdread 0.9.2. The changes are in the subdirectory videolan.
They basically consist of a new function in the API that does a readv()
instead fo a read().

The library is statically linked with libdvdcss from extras/libdvdcss, and
the whole is statically linked with the plugin dvdread. Dvdread can only be
compiled as a builtin module for the time being, I think (which means I
haven't tried to compile it as a plugin).

Basically, input_dvdread.c is a copy and paste from input_dvd.c with a few
changes to use libdvdread calls. It is still in very alpha stage, but it
should offer the same features as the current DVD input.

It can be called with either the syntax: "dvdread:/dev/dvd"
or "--input dvdread /dev/dvd". The command line switches (-t, -T, -c, -u)
should work too.
parent 81287869
......@@ -23,6 +23,7 @@ PLUGINS_DIR := ac3_adec \
dsp \
dummy \
dvd \
dvdread \
esd \
fb \
ggi \
......@@ -58,6 +59,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
dummy/dummy \
dummy/null \
dvd/dvd \
dvdread/dvdread \
esd/esd \
fb/fb \
ggi/ggi \
......@@ -198,7 +200,7 @@ show:
#
# Cleaning rules
#
clean: libdvdcss-clean plugins-clean vlc-clean
clean: libdvdcss-clean libdvdread-clean plugins-clean vlc-clean
rm -f src/*/*.o extras/*/*.o
rm -f lib/*.so* lib/*.a
rm -f plugins/*.so plugins/*.a
......@@ -207,6 +209,9 @@ clean: libdvdcss-clean plugins-clean vlc-clean
libdvdcss-clean:
-cd extras/libdvdcss && $(MAKE) clean
libdvdread-clean:
-cd extras/libdvdread && $(MAKE) clean
plugins-clean:
for dir in $(PLUGINS_DIR) ; do \
( cd plugins/$${dir} && $(MAKE) clean ) ; done
......@@ -533,3 +538,10 @@ $(BUILTIN_OBJ): FORCE
#
libdvdcss: Makefile.opts
cd extras/libdvdcss && $(MAKE)
#
# libdvdread target
#
libdvdread: Makefile.opts
cd extras/libdvdread && $(MAKE)
......@@ -72,6 +72,8 @@ LIB_BEOS = @LIB_BEOS@
LIB_DARWIN = @LIB_DARWIN@
LIB_DVD = @LIB_DVD@
LIB_DVD_PLUGIN = @LIB_DVD_PLUGIN@
LIB_DVDREAD = @LIB_DVDREAD@
LIB_DVDREAD_PLUGIN = @LIB_DVDREAD_PLUGIN@
LIB_ESD = @LIB_ESD@
LIB_GGI = @LIB_GGI@
LIB_GLIDE = @LIB_GLIDE@
......@@ -95,6 +97,7 @@ LIB_YUV = @LIB_YUV@
#
CFLAGS_ALTIVEC = @CFLAGS_ALTIVEC@
CFLAGS_DVD = @CFLAGS_DVD@
CFLAGS_DVDREAD = @CFLAGS_DVDREAD@
CFLAGS_ARTS = @CFLAGS_ARTS@
CFLAGS_ESD = @CFLAGS_ESD@
CFLAGS_LIBDVDCSS = @CFLAGS_LIBDVDCSS@
......
This diff is collapsed.
......@@ -683,6 +683,25 @@ AC_ARG_WITH(dvdcss,
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldl"
fi ])
dnl
dnl DVDREAD module: check for libdvdread plugin
dnl
AC_ARG_ENABLE(dvdread,
[ --enable-dvdread Enable dvdread support (default enabled)],
[ if test x$enableval = xyes
then
NEED_LIBDVDCSS=1
STATIC_LIBDVDCSS=1
BUILTINS="${BUILTINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} -I../../extras/libdvdread"
LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a"
fi ],
[ NEED_LIBDVDCSS=1
STATIC_LIBDVDCSS=1
BUILTINS="${BUILTINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} -I../../extras/libdvdread"
LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a" ])
dnl
dnl VCD module
dnl
......@@ -1186,6 +1205,8 @@ AC_SUBST(LIB_BEOS)
AC_SUBST(LIB_DARWIN)
AC_SUBST(LIB_DVD)
AC_SUBST(LIB_DVD_PLUGIN)
AC_SUBST(LIB_DVDREAD)
AC_SUBST(LIB_DVDREAD_PLUGIN)
AC_SUBST(LIB_ESD)
AC_SUBST(LIB_GGI)
AC_SUBST(LIB_GLIDE)
......@@ -1207,6 +1228,7 @@ AC_SUBST(LIB_YUV)
AC_SUBST(CFLAGS_VLC)
AC_SUBST(CFLAGS_ALTIVEC)
AC_SUBST(CFLAGS_DVD)
AC_SUBST(CFLAGS_DVDREAD)
AC_SUBST(CFLAGS_LIBDVDCSS)
AC_SUBST(CFLAGS_ARTS)
AC_SUBST(CFLAGS_ESD)
......
###############################################################################
# vlc (VideoLAN Client) dvdread module Makefile
# (c)2001 VideoLAN
###############################################################################
LIBDVDREAD_VERSION := 0.9.2
CFLAGS_LIBDVDREAD := -I. -DHAVE_CONFIG_H
LIB_LIBDVDREAD := -ldl
BASE_A := libdvdread.a
BASE_SO := libdvdread.so
MAJOR_SO := libdvdread.so.$(shell echo $(LIBDVDREAD_VERSION) | cut -f1 -d.)
FULL_SO := libdvdread.so.$(LIBDVDREAD_VERSION)
ifneq (,$(SOFLAGS))
ALL_SOFLAGS := $(SOFLAGS)$(MAJOR_SO)
SOFLAGS :=
endif
#
# Objects
#
OBJ_C = dvdread.o dvd_udf.o nav_print.o nav_read.o ifo_print.o ifo_read.o
PLUGIN_OBJ = $(OBJ_C) $(OBJ_LIBDVDREAD)
BUILTIN_OBJ = $(OBJ_C:%.o=DVDREAD_%.o)
ALL_OBJ = $(PLUGIN_OBJ) $(BUILTIN_OBJ)
include ../../Makefile.modules
$(OBJ_C): %.o: .dep/%.d
$(OBJ_C): %.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_LIBDVDREAD) $(PCFLAGS) -c -o $@ $<
$(BUILTIN_OBJ): DVDREAD_%.o: .dep/%.d
$(BUILTIN_OBJ): DVDREAD_%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_LIBDVDREAD) $(PCFLAGS) -c -o $@ $<
../../lib/$(FULL_SO): $(OBJ_C) $(OBJ_LIBDVDREAD)
$(CC) $(PCFLAGS) $(ALL_SOFLAGS) -o $@ $^ $(PLCFLAGS) $(LIB_LIBDVDREAD)
rm -f ../../lib/$(BASE_SO) && ln -s $(FULL_SO) ../../lib/$(BASE_SO)
rm -f ../../lib/$(MAJOR_SO) && ln -s $(FULL_SO) ../../lib/$(MAJOR_SO)
../../lib/$(BASE_A): libdvdcss $(BUILTIN_OBJ) $(OBJ_LIBDVDREAD)
ar r $@ $(BUILTIN_OBJ)
$(RANLIB) $@
#
# Virtual targets
#
all: ../../lib/$(BASE_A)
libdvdcss:
cd ../../ && $(MAKE) libdvdcss
#install:
# mkdir -p $(DESTDIR)$(includedir)/videolan
# $(INSTALL) -m 644 videolan/dvdcss.h $(DESTDIR)$(includedir)/videolan
# mkdir -p $(DESTDIR)$(libdir)
# -$(INSTALL) -m 644 ../../lib/$(BASE_A) $(DESTDIR)$(libdir)
# -$(INSTALL) -m 644 ../../lib/$(FULL_SO) $(DESTDIR)$(libdir)
# rm -f $(DESTDIR)$(libdir)/$(BASE_SO) && ln -s $(FULL_SO) $(DESTDIR)$(libdir)/$(BASE_SO)
# rm -f $(DESTDIR)$(libdir)/$(MAJOR_SO) && ln -s $(FULL_SO) $(DESTDIR)$(libdir)/$(MAJOR_SO)
#
#uninstall:
# rm -f $(DESTDIR)$(includedir)/videolan/dvdcss.h
# rm -f $(DESTDIR)$(libdir)/$(BASE_A)
# rm -f $(DESTDIR)$(libdir)/$(BASE_SO)
# rm -f $(DESTDIR)$(libdir)/$(MAJOR_SO)
# rm -f $(DESTDIR)$(libdir)/$(FULL_SO)
/**
* Copyright (C) 2000, 2001 Billy Biggs <vektor@dumbterm.net>,
* Hkan Hjort <d95hjort@dtek.chalmers.se>
*
* 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
*/
#ifndef BSWAP_H_INCLUDED
#define BSWAP_H_INCLUDED
#include <config.h>
#if defined(WORDS_BIGENDIAN)
/* All bigendian systems are fine, just ignore the swaps. */
#define B2N_16(x) (void)(x)
#define B2N_32(x) (void)(x)
#define B2N_64(x) (void)(x)
#else
#if defined(__linux__)
#include <byteswap.h>
#define B2N_16(x) x = bswap_16(x)
#define B2N_32(x) x = bswap_32(x)
#define B2N_64(x) x = bswap_64(x)
#elif defined(__NetBSD__)
#include <sys/endian.h>
#define B2N_16(x) BE16TOH(x)
#define B2N_32(x) BE32TOH(x)
#define B2N_64(x) BE64TOH(x)
#elif defined(__OpenBSD__)
#include <sys/endian.h>
#define B2N_16(x) x = swap16(x)
#define B2N_32(x) x = swap32(x)
#define B2N_64(x) x = swap64(x)
/* This is a slow but portable implementation, it has multiple evaluation
* problems so beware.
* FreeBSD and Solaris don't have <byteswap.h> or any other such
* functionality!
*/
#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__)
#define B2N_16(x) \
x = ((((x) & 0xff00) >> 8) | \
(((x) & 0x00ff) << 8))
#define B2N_32(x) \
x = ((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define B2N_64(x) \
x = ((((x) & 0xff00000000000000) >> 56) | \
(((x) & 0x00ff000000000000) >> 40) | \
(((x) & 0x0000ff0000000000) >> 24) | \
(((x) & 0x000000ff00000000) >> 8) | \
(((x) & 0x00000000ff000000) << 8) | \
(((x) & 0x0000000000ff0000) << 24) | \
(((x) & 0x000000000000ff00) << 40) | \
(((x) & 0x00000000000000ff) << 56))
#else
/* If there isn't a header provided with your system with this functionality
* add the relevant || define( ) to the portable implementation above.
*/
#error "You need to add endian swap macros for you're system"
#endif
#endif /* WORDS_BIGENDIAN */
#endif /* BSWAP_H_INCLUDED */
/**
* Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h> /* For the timing of dvdcss_title crack. */
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <dlfcn.h>
#include <dirent.h>
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__)
#define SYS_BSD 1
#endif
#if defined(__sun)
#include <sys/mnttab.h>
#elif defined(SYS_BSD)
#include <fstab.h>
#elif defined(__linux__)
#include <mntent.h>
#endif
#if defined(SYS_BSD)
typedef off_t off64_t;
#define lseek64 lseek
#define stat64 stat
#endif
/* #include "dvdcss.h" */
typedef struct dvdcss_s* dvdcss_handle;
#define DVDCSS_NOFLAGS 0
#define DVDCSS_INIT_QUIET (1 << 0)
#define DVDCSS_INIT_DEBUG (1 << 1)
#define DVDCSS_READ_DECRYPT (1 << 0)
#include "dvd_udf.h"
#include "dvd_reader.h"
/**
* Handle to the loaded dvdcss library.
*/
void *dvdcss_library = 0;
/**
* libdvdcss functions.
*/
static dvdcss_handle (*dvdcss_open) ( char *psz_target,
int i_flags );
static int (*dvdcss_close) ( dvdcss_handle );
static int (*dvdcss_title) ( dvdcss_handle,
int i_block );
static int (*dvdcss_seek) ( dvdcss_handle,
int i_blocks );
static int (*dvdcss_read) ( dvdcss_handle,
void *p_buffer,
int i_blocks,
int i_title );
static char * (*dvdcss_error) ( dvdcss_handle );
struct dvd_reader_s {
/* Basic information. */
int isImageFile;
/* Information required for an image file. */
dvdcss_handle dev;
int init_keys;
int fd;
/* Information required for a directory path drive. */
char *path_root;
};
struct dvd_file_s {
/* Basic information. */
dvd_reader_t *dvd;
/* Information required for an image file. */
uint32_t lb_start;
uint32_t seek_pos;
/* Information required for a directory path drive. */
size_t title_sizes[ 9 ];
int title_fds[ 9 ];
/* Calculated at open-time, size in blocks. */
ssize_t filesize;
};
static void setupCSS( void )
{
if( !dvdcss_library ) {
dvdcss_library = dlopen( "libdvdcss.so.0", RTLD_LAZY );
if( !dvdcss_library ) {
fprintf( stderr, "libdvdread: Can't open libdvdcss: %s.\n",
dlerror() );
} else {
#if defined(__OpenBSD__)
#define U_S "_"
#else
#define U_S
#endif
dvdcss_open = (dvdcss_handle (*)(char*, int))
dlsym( dvdcss_library, U_S "dvdcss_open" );
dvdcss_close = (int (*)(dvdcss_handle))
dlsym( dvdcss_library, U_S "dvdcss_close" );
dvdcss_title = (int (*)(dvdcss_handle, int))
dlsym( dvdcss_library, U_S "dvdcss_title" );
dvdcss_seek = (int (*)(dvdcss_handle, int))
dlsym( dvdcss_library, U_S "dvdcss_seek" );
dvdcss_read = (int (*)(dvdcss_handle, void*, int, int))
dlsym( dvdcss_library, U_S "dvdcss_read" );
dvdcss_error = (char* (*)(dvdcss_handle))
dlsym( dvdcss_library, U_S "dvdcss_error" );
if( dlsym( dvdcss_library, U_S "dvdcss_crack" ) ) {
fprintf( stderr, "libdvdread: Old (pre-0.0.2) version of "
"libdvdcss found.\n"
"libdvdread: You should get the "
"latest version from "
"http://www.videolan.org/\n" );
dlclose( dvdcss_library );
dvdcss_library = 0;
} else if( !dvdcss_open || !dvdcss_close || !dvdcss_seek ||
!dvdcss_title || !dvdcss_read || !dvdcss_error ) {
fprintf( stderr, "libdvdread: Unknown incompatible version "
"of libdvdcss found.\n"
"libdvdread: Try to find a "
"newer version of libdvdread?\n" );
dlclose( dvdcss_library );
dvdcss_library = 0;
}
}
}
if( !dvdcss_library ) {
fprintf( stderr, "libdvdread: Encrypted DVD support unavailable.\n" );
}
}
/* Loop over all titles and call dvdcss_title to crack the keys. */
static int initAllCSSKeys( dvd_reader_t *dvd )
{
if( dvdcss_library ) {
struct timeval all_s, all_e;
struct timeval t_s, t_e;
char filename[ MAX_UDF_FILE_NAME_LEN ];
uint32_t start, len;
int title;
fprintf( stderr, "\n" );
fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" );
fprintf( stderr, "libdvdread: This can take a _long_ time, "
"please be patient\n\n" );
gettimeofday(&all_s, NULL);
for( title = 0; title < 100; title++ ) {
gettimeofday( &t_s, NULL );
if( title == 0 ) {
sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
} else {
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
}
start = UDFFindFile( dvd, filename, &len );
if( start != 0 && len != 0 ) {
/* Perform CSS key cracking for this title. */
fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
filename, start );
if( dvdcss_title( dvd->dev, (int)start ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key!!\n");
}
gettimeofday( &t_e, NULL );
fprintf( stderr, "libdvdread: Elapsed time %ld\n",
(long int) t_e.tv_sec - t_s.tv_sec );
}
if( title == 0 ) continue;
gettimeofday( &t_s, NULL );
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
start = UDFFindFile( dvd, filename, &len );
if( start == 0 || len == 0 ) break;
/* Perform CSS key cracking for this title. */
fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
filename, start );
if( dvdcss_title( dvd->dev, (int)start ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key!!\n");
}
gettimeofday( &t_e, NULL );
fprintf( stderr, "libdvdread: Elapsed time %ld\n",
(long int) t_e.tv_sec - t_s.tv_sec );
}
title--;
fprintf( stderr, "libdvdread: Found %d VTS's\n", title );
gettimeofday(&all_e, NULL);
fprintf( stderr, "libdvdread: Elapsed time %ld\n",
(long int) all_e.tv_sec - all_s.tv_sec );
}
return 0;
}
/**
* Open a DVD image or block device file.
*/
static dvd_reader_t *DVDOpenImageFile( const char *location )
{
dvd_reader_t *dvd;
dvdcss_handle dev = 0;
int fd = -1;
setupCSS();
if( dvdcss_library ) {
dev = dvdcss_open( (char *) location, DVDCSS_INIT_DEBUG );
if( !dev ) {
fprintf( stderr, "libdvdread: Can't open %s for reading.\n",
location );
return 0;
}
} else {
fd = open( location, O_RDONLY );
if( fd < 0 ) {
fprintf( stderr, "libdvdread: Can't open %s for reading.\n",
location );
return 0;
}
}
dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
if( !dvd ) return 0;
dvd->isImageFile = 1;
dvd->dev = dev;
dvd->init_keys = 0;
dvd->fd = fd;
dvd->path_root = 0;
return dvd;
}
static dvd_reader_t *DVDOpenPath( const char *path_root )
{
dvd_reader_t *dvd;
dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
if( !dvd ) return 0;
dvd->isImageFile = 0;
dvd->dev = 0;
dvd->init_keys = 0;
dvd->fd = -1;
dvd->path_root = strdup( path_root );
return dvd;
}
#if defined(__sun)
/* /dev/rdsk/c0t6d0s0 (link to /devices/...)
/vol/dev/rdsk/c0t6d0/??
/vol/rdsk/<name> */
static char *sun_block2char( const char *path )
{
char *new_path;
/* Must contain "/dsk/" */
if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path );
/* Replace "/dsk/" with "/rdsk/" */
new_path = malloc( strlen(path) + 2 );
strcpy( new_path, path );
strcpy( strstr( new_path, "/dsk/" ), "" );
strcat( new_path, "/rdsk/" );
strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) );
return new_path;
}
#endif
#if defined(SYS_BSD)
/* FreeBSD /dev/(r)(a)cd0 (a is for atapi, should work without r)
OpenBSD /dev/rcd0c
NetBSD /dev/rcd0d or /dev/rcd0c (for non x86)
BSD/OS /dev/sr0 (if not mounted) or /dev/rsr0 */
static char *bsd_block2char( const char *path )
{
char *new_path;
/* If it doesn't start with "/dev/" or does start with "/dev/r" exit */
if( !strncmp( path, "/dev/", 5 ) || strncmp( path, "/dev/r", 6 ) )
return (char *) strdup( path );
/* Replace "/dev/" with "/dev/r" */
new_path = malloc( strlen(path) + 2 );
strcpy( new_path, "/dev/r" );
strcat( new_path, path + strlen( "/dev/" ) );
return new_path;
}
#endif
dvd_reader_t *DVDOpen( const char *path )
{
struct stat64 fileinfo;
int ret;
if( !path ) return 0;
ret = stat64( path, &fileinfo );
if( ret < 0 ) {
/* If we can't stat the file, give up */
fprintf( stderr, "libdvdread: Can't stat %s\n", path );
perror("");
return 0;
}
/* First check if this is a block/char device or a file*/
if( S_ISBLK( fileinfo.st_mode ) ||
S_ISCHR( fileinfo.st_mode ) ||
S_ISREG( fileinfo.st_mode ) ) {
/**
* Block devices and regular files are assumed to be DVD-Video images.
*/
#if defined(__sun)
return DVDOpenImageFile( sun_block2char( path ) );
#elif defined(SYS_BSD)
return DVDOpenImageFile( bsd_block2char( path ) );
#else
return DVDOpenImageFile( path );
#endif
} else if( S_ISDIR( fileinfo.st_mode ) ) {
dvd_reader_t *auth_drive = 0;
char *path_copy;
#if defined(SYS_BSD)
struct fstab* fe;
#elif defined(__sun) || defined(__linux__)
FILE *mntfile;
#endif
/* XXX: We should scream real loud here. */
if( !(path_copy = strdup( path ) ) ) return 0;
/* Resolve any symlinks and get the absolut dir name. */
{
char *new_path;
int cdir = open( ".", O_RDONLY );
if( cdir >= 0 ) {
chdir( path_copy );
new_path = getcwd( NULL, PATH_MAX );
fchdir( cdir );
close( cdir );
if( new_path ) {
free( path_copy );
path_copy = new_path;
}
}
}
/**
* If we're being asked to open a directory, check if that directory
* is the mountpoint for a DVD-ROM which we can use instead.
*/
if( strlen( path_copy ) > 1 ) {
if( path[ strlen( path_copy ) - 1 ] == '/' )
path_copy[ strlen( path_copy ) - 1 ] = '\0';
}
if( strlen( path_copy ) > 9 ) {
if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]),
"/video_ts" ) ) {
path_copy[ strlen( path_copy ) - 9 ] = '\0';
}
}
#if defined(SYS_BSD)
if( ( fe = getfsfile( path_copy ) ) ) {
char *dev_name = bsd_block2char( fe->fs_spec );
fprintf( stderr,
"libdvdread: Attempting to use device %s"
" mounted on %s for CSS authentication\n",
dev_name,
fe->fs_file );
auth_drive = DVDOpenImageFile( dev_name );
free( dev_name );
}
#elif defined(__sun)
mntfile = fopen( MNTTAB, "r" );
if( mntfile ) {
struct mnttab mp;
int res;
while( ( res = getmntent( mntfile, &mp ) ) != -1 ) {
if( res == 0 && !strcmp( mp.mnt_mountp, path_copy ) ) {
char *dev_name = sun_block2char( mp.mnt_special );
fprintf( stderr,
"libdvdread: Attempting to use device %s"
" mounted on %s for CSS authentication\n",
dev_name,
mp.mnt_mountp );
auth_drive = DVDOpenImageFile( dev_name );
free( dev_name );
break;
}
}
fclose( mntfile );
}
#elif defined(__linux__)
mntfile = fopen( MOUNTED, "r" );
if( mntfile ) {
struct mntent *me;
while( ( me = getmntent( mntfile ) ) ) {
if( !strcmp( me->mnt_dir, path_copy ) ) {
fprintf( stderr,
"libdvdread: Attempting to use device %s"
" mounted on %s for CSS authentication\n",
me->mnt_fsname,
me->mnt_dir );
auth_drive = DVDOpenImageFile( me->mnt_fsname );
break;
}
}
fclose( mntfile );
}
#endif
if( !auth_drive ) {
fprintf( stderr, "libdvdread: Device inaccessible, "
"CSS authentication not available.\n" );
}
free( path_copy );
/**
* If we've opened a drive, just use that.
*/
if( auth_drive ) return auth_drive;
/**
* Otherwise, we now try to open the directory tree instead.
*/
fprintf( stderr, "libdvdread: Using normal filesyste