CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
fi
;;
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} -Llib -ldvdcss"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -L../../lib -ldvdcss"
+ LIB_DVDREAD="${LIB_DVD} -Llib -ldvdread -ldvdcss"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -L../../lib -ldvdcss"
fi
;;
CFLAGS_DVD="${CFLAGS_DVD} -DLIBDVDCSS_VERSION=\"${LIBDVDCSS_VERSION}\""
LIB_DVD="${LIB_DVD} -ldl"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldl"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a -ldl"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldl"
;;
*)
fi
LIB_DVD="${LIB_DVD} -ldvdcss"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldvdcss"
- LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldvdcss"
+ LIB_DVDREAD="${LIB_DVDREAD} -ldvdread -ldvdcss"
+ LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldvdread -ldvdcss"
esac
else
# user didn't decide, we choose to use local libdvdcss and link statically
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
- LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdread.a ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
else
# XXX: no check for libdl is done, don't try this at home !
DUMMY_LIBDVDCSS=1
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
LIB_DVD="${LIB_DVD} -ldl"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldl"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a -ldl"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldl"
fi
fi
enableval="$enable_dvdread"
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"
+ CFLAGS_DVDREAD="${CFLAGS_DVD} ${CFLAGS_DVDREAD} -I../../extras/libdvdread"
fi
fi
if test x$enable_vcd != xno
then
cat > conftest.$ac_ext <<EOF
-#line 6378 "configure"
+#line 6381 "configure"
#include "confdefs.h"
#include <linux/cdrom.h>
EOF
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6452: checking for $ac_hdr" >&5
+echo "configure:6455: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6457 "configure"
+#line 6460 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
done
echo $ac_n "checking for mad_bit_init in -lmad""... $ac_c" 1>&6
-echo "configure:6492: checking for mad_bit_init in -lmad" >&5
+echo "configure:6495: checking for mad_bit_init in -lmad" >&5
ac_lib_var=`echo mad'_'mad_bit_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lmad $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6500 "configure"
+#line 6503 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mad_bit_init()
; return 0; }
EOF
-if { (eval echo configure:6511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
# Extract the first word of "esd-config", so it can be a program name with args.
set dummy esd-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6578: checking for $ac_word" >&5
+echo "configure:6581: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "artsc-config", so it can be a program name with args.
set dummy artsc-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6629: checking for $ac_word" >&5
+echo "configure:6632: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ARTS_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6687: checking for $ac_hdr" >&5
+echo "configure:6690: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6692 "configure"
+#line 6695 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6697: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6700: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6742: checking for $ac_hdr" >&5
+echo "configure:6745: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6747 "configure"
+#line 6750 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6752: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
# Extract the first word of "sdl12-config", so it can be a program name with args.
set dummy sdl12-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6840: checking for $ac_word" >&5
+echo "configure:6843: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL12_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sdl11-config", so it can be a program name with args.
set dummy sdl11-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6880: checking for $ac_word" >&5
+echo "configure:6883: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL11_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sdl-config", so it can be a program name with args.
set dummy sdl-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6921: checking for $ac_word" >&5
+echo "configure:6924: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6967: checking for $ac_hdr" >&5
+echo "configure:6970: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6972 "configure"
+#line 6975 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7047: checking for $ac_hdr" >&5
+echo "configure:7050: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7052 "configure"
+#line 7055 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7060: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
else
echo $ac_n "checking for directX headers in ${withval}""... $ac_c" 1>&6
-echo "configure:7086: checking for directX headers in ${withval}" >&5
+echo "configure:7089: checking for directX headers in ${withval}" >&5
if test -f ${withval}/include/directx.h
then
PLUGINS="${PLUGINS} directx"
# Extract the first word of "gnome-config", so it can be a program name with args.
set dummy gnome-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7183: checking for $ac_word" >&5
+echo "configure:7186: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GNOME_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7228: checking for $ac_hdr" >&5
+echo "configure:7231: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7233 "configure"
+#line 7236 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7241: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
# Extract the first word of "gtk-config", so it can be a program name with args.
set dummy gtk-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7298: checking for $ac_word" >&5
+echo "configure:7301: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7348: checking for $ac_hdr" >&5
+echo "configure:7351: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7353 "configure"
+#line 7356 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7358: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7361: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7415: checking for $ac_hdr" >&5
+echo "configure:7418: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7420 "configure"
+#line 7423 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7478: checking for $ac_hdr" >&5
+echo "configure:7481: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7483 "configure"
+#line 7486 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7488: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7491: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
saved_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -L$x_libraries -lX11 -lXext"
echo $ac_n "checking for XvSetPortAttribute in -lXv_pic""... $ac_c" 1>&6
-echo "configure:7512: checking for XvSetPortAttribute in -lXv_pic" >&5
+echo "configure:7515: checking for XvSetPortAttribute in -lXv_pic" >&5
ac_lib_var=`echo Xv_pic'_'XvSetPortAttribute | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lXv_pic $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7520 "configure"
+#line 7523 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
XvSetPortAttribute()
; return 0; }
EOF
-if { (eval echo configure:7531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
then
ac_safe=`echo "alsa/asoundlib.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for alsa/asoundlib.h""... $ac_c" 1>&6
-echo "configure:7575: checking for alsa/asoundlib.h" >&5
+echo "configure:7578: checking for alsa/asoundlib.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7580 "configure"
+#line 7583 "configure"
#include "confdefs.h"
#include <alsa/asoundlib.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7588: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6
-echo "configure:7602: checking for main in -lasound" >&5
+echo "configure:7605: checking for main in -lasound" >&5
ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lasound $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7610 "configure"
+#line 7613 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:7617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
fi
;;
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} -Llib -ldvdcss"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -L../../lib -ldvdcss"
+ LIB_DVDREAD="${LIB_DVD} -Llib -ldvdread -ldvdcss"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -L../../lib -ldvdcss"
fi
;;
CFLAGS_DVD="${CFLAGS_DVD} -DLIBDVDCSS_VERSION=\"${LIBDVDCSS_VERSION}\""
LIB_DVD="${LIB_DVD} -ldl"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldl"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a -ldl"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldl"
;;
*)
fi
LIB_DVD="${LIB_DVD} -ldvdcss"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldvdcss"
- LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldvdcss"
+ LIB_DVDREAD="${LIB_DVDREAD} -ldvdread -ldvdcss"
+ LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldvdread -ldvdcss"
esac ],
# user didn't decide, we choose to use local libdvdcss and link statically
# if libdvdcss is in the archive, or to use the dummy replacement otherwise.
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
- LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a lib/libdvdcss.a ${LIB_LIBDVDCSS}"
+ LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} ../../lib/libdvdread.a ../../lib/libdvdcss.a ${LIB_LIBDVDCSS}"
else
# XXX: no check for libdl is done, don't try this at home !
DUMMY_LIBDVDCSS=1
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
LIB_DVD="${LIB_DVD} -ldl"
LIB_DVD_PLUGIN="${LIB_DVD_PLUGIN} -ldl"
+ LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a -ldl"
LIB_DVDREAD_PLUGIN="${LIB_DVDREAD_PLUGIN} -ldl"
fi ])
[ --enable-dvdread Enable dvdread support (default disabled)],
[ 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"
+ CFLAGS_DVDREAD="${CFLAGS_DVD} ${CFLAGS_DVDREAD} -I../../extras/libdvdread"
fi ])
dnl
* css.c: Functions for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: css.c,v 1.21 2002/01/21 07:00:21 gbazin Exp $
+ * $Id: css.c,v 1.22 2002/01/23 03:15:31 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
* Håkan Hjort <d95hjort@dtek.chalmers.se>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
+static int CSSAuth ( dvdcss_handle dvdcss );
static int CSSGetASF ( dvdcss_handle dvdcss );
static void CSSCryptKey ( int i_key_type, int i_varient,
u8 const * p_challenge, u8* p_key );
}
/*****************************************************************************
- * CSSAuth : CSS Structure initialisation and DVD authentication.
+ * CSSAuth : DVD CSS authentication.
*****************************************************************************
- * It simulates the mutual authentication between logical unit and host.
- * Since we don't need the disc key to find the title key, we just run the
- * basic unavoidable commands to authenticate device and disc.
+ * It simulates the mutual authentication between logical unit and host,
+ * and stops when a session key (called bus key) has been established.
+ * Always do the full auth sequence. Some drives seem to lie and always
+ * respond with ASF=1. For instance the old DVD roms on Compaq Armada says
+ * that ASF=1 from the start and then later fail with a 'read of scrambled
+ * block without authentication' error.
*****************************************************************************/
-int CSSAuth( dvdcss_handle dvdcss )
+static int CSSAuth( dvdcss_handle dvdcss )
{
- /* structures defined in cdrom.h or dvdio.h */
- unsigned char p_buffer[10];
- char psz_warning[48];
- int i_ret = -1;
- int i;
-
- dvdcss->css.i_agid = 0;
-
- /* Test authentication success */
- switch( CSSGetASF( dvdcss ) )
+ u8 p_buffer[10];
+ u8 p_challenge[2*KEY_SIZE];
+ dvd_key_t p_key1;
+ dvd_key_t p_key2;
+ dvd_key_t p_key_check;
+ u8 i_varient = 0;
+ char psz_warning[48];
+ int i_ret = -1;
+ int i;
+
+ /* So this isn't really necessary except for debuging. */
+ if( CSSGetASF( dvdcss ) < 0 )
{
- case -1:
- return -1;
-
- case 1:
- _dvdcss_debug( dvdcss, "already authenticated" );
- break;
-
- case 0:
- _dvdcss_debug( dvdcss, "need to authenticate" );
- break;
+ _dvdcss_error( dvdcss, "fatal error in CSSAuth" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
+ return -1;
}
- /* Init sequence, request AGID */
- for( i = 1; i < 4 ; ++i )
- {
- snprintf( psz_warning, sizeof(psz_warning), "requesting AGID %d", i );
- _dvdcss_debug( dvdcss, psz_warning );
+ _dvdcss_debug( dvdcss, "requesting AGID" );
+ i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
-
- if( i_ret != -1 )
- {
- /* No error during ioctl: we know the device is authenticated */
- break;
- }
-
- _dvdcss_error( dvdcss, "ioctl_ReportAgid failed, invalidating" );
-
- dvdcss->css.i_agid = 0;
+ /* We might have to reset hung authentication processes in the drive
+ by invalidating the corresponding AGID'. As long as we haven't got
+ an AGID, invalidate one (in sequence) and try again. */
+ for( i = 0; i_ret == -1 && i < 4 ; ++i )
+ {
+ _dvdcss_debug( dvdcss, "ioctl_ReportAgid failed" );
+
+ sprintf( psz_warning, "invalidating AGID %d", i );
+ _dvdcss_debug( dvdcss, psz_warning );
+
+ /* This is really _not good_, should be handled by the OS.
+ Invalidating an AGID could make another process fail some
+ where in it's authentication process. */
+ dvdcss->css.i_agid = i;
ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
+
+ _dvdcss_debug( dvdcss, "requesting AGID" );
+ i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
}
/* Unable to authenticate without AGID */
return -1;
}
+ /* Setup a challenge, any valuse should work */
for( i = 0 ; i < 10; ++i )
{
- dvdcss->css.disc.p_challenge[i] = i;
+ p_challenge[i] = i;
}
/* Get challenge from host */
for( i = 0 ; i < 10 ; ++i )
{
- p_buffer[9-i] = dvdcss->css.disc.p_challenge[i];
+ p_buffer[9-i] = p_challenge[i];
}
/* Send challenge to LU */
if( ioctl_SendChallenge( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
{
_dvdcss_error( dvdcss, "ioctl_SendChallenge failed" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
return -1;
}
if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0)
{
_dvdcss_error( dvdcss, "ioctl_ReportKey1 failed" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
return -1;
}
/* Send key1 to host */
for( i = 0 ; i < KEY_SIZE ; i++ )
{
- dvdcss->css.disc.p_key1[i] = p_buffer[4-i];
+ p_key1[i] = p_buffer[4-i];
}
for( i = 0 ; i < 32 ; ++i )
{
- CSSCryptKey( 0, i, dvdcss->css.disc.p_challenge,
- dvdcss->css.disc.p_key_check );
+ CSSCryptKey( 0, i, p_challenge, p_key_check );
- if( memcmp( dvdcss->css.disc.p_key_check,
- dvdcss->css.disc.p_key1, KEY_SIZE ) == 0 )
+ if( memcmp( p_key_check, p_key1, KEY_SIZE ) == 0 )
{
snprintf( psz_warning, sizeof(psz_warning),
- "drive authentic, using variant %d", i );
+ "drive authentic, using varient %d", i );
_dvdcss_debug( dvdcss, psz_warning );
- dvdcss->css.disc.i_varient = i;
+ i_varient = i;
break;
}
}
if( i == 32 )
{
_dvdcss_error( dvdcss, "drive would not authenticate" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
return -1;
}
/* Get challenge from LU */
- if( ioctl_ReportChallenge( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
+ if( ioctl_ReportChallenge( dvdcss->i_fd,
+ &dvdcss->css.i_agid, p_buffer ) < 0 )
{
_dvdcss_error( dvdcss, "ioctl_ReportKeyChallenge failed" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
return -1;
}
/* Send challenge to host */
for( i = 0 ; i < 10 ; ++i )
{
- dvdcss->css.disc.p_challenge[i] = p_buffer[9-i];
+ p_challenge[i] = p_buffer[9-i];
}
- CSSCryptKey( 1, dvdcss->css.disc.i_varient,
- dvdcss->css.disc.p_challenge,
- dvdcss->css.disc.p_key2 );
+ CSSCryptKey( 1, i_varient, p_challenge, p_key2 );
/* Get key2 from host */
for( i = 0 ; i < KEY_SIZE ; ++i )
{
- p_buffer[4-i] = dvdcss->css.disc.p_key2[i];
+ p_buffer[4-i] = p_key2[i];
}
/* Send key2 to LU */
if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
{
_dvdcss_error( dvdcss, "ioctl_SendKey2 failed" );
+ // ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); ??
return -1;
}
+ /* The drive has accepted us as authentic. */
_dvdcss_debug( dvdcss, "authentication established" );
- memcpy( dvdcss->css.disc.p_challenge,
- dvdcss->css.disc.p_key1, KEY_SIZE );
- memcpy( dvdcss->css.disc.p_challenge+KEY_SIZE,
- dvdcss->css.disc.p_key2, KEY_SIZE );
-
- CSSCryptKey( 2, dvdcss->css.disc.i_varient,
- dvdcss->css.disc.p_challenge,
- dvdcss->css.disc.p_key_check );
-
- _dvdcss_debug( dvdcss, "received session key" );
-
- if( dvdcss->css.i_agid < 0 )
- {
- return -1;
- }
+ memcpy( p_challenge, p_key1, KEY_SIZE );
+ memcpy( p_challenge + KEY_SIZE, p_key2, KEY_SIZE );
- /* Test authentication success */
- switch( CSSGetASF( dvdcss ) )
- {
- case -1:
- return -1;
+ CSSCryptKey( 2, i_varient, p_challenge, dvdcss->css.p_bus_key );
- case 1:
- _dvdcss_debug( dvdcss, "already authenticated" );
- return 0;
+ return 0;
+}
- case 0:
- _dvdcss_debug( dvdcss, "need to get disc key" );
- return 0;
- }
+/*****************************************************************************
+ * CSSPrintKey : debug function that dumps a key value
+ *****************************************************************************/static void CSSPrintKey( dvdcss_handle dvdcss, u8* data )
+{
+ char psz_output[80];
- return -1;
+ sprintf( psz_output, "the key is %02x %02x %02x %02x %02x",
+ data[0], data[1], data[2], data[3], data[4] );
+ _dvdcss_debug( dvdcss, psz_output );
}
/*****************************************************************************
*****************************************************************************/
int CSSGetDiscKey( dvdcss_handle dvdcss )
{
- unsigned char p_buffer[2048 + 4 + 1];
+ unsigned char p_buffer[2048];
#ifdef HAVE_CSSKEYS
dvd_key_t disc_key;
dvd_key_t test_key;
/* Unencrypt disc key using bus key */
for( i = 0 ; i < 2048 ; i++ )
{
- p_buffer[ i ] ^= dvdcss->css.disc.p_key_check[ 4 - (i % KEY_SIZE) ];
+ p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
}
- memcpy( dvdcss->css.disc.p_disc_key, p_buffer, 2048 );
switch( dvdcss->i_method )
{
{
/* Take encrypted disc key and decrypt it */
memcpy( disc_key,
- dvdcss->css.disc.p_disc_key
- + playerkeys[i].i_offset,
+ p_buffer + playerkeys[i].i_offset,
KEY_SIZE );
CSSDecryptKey( disc_key, playerkeys[i].p_key, 0 );
/* Encrypt disc key hash with disc key to
* check we have disc key */
- memcpy( test_key, dvdcss->css.disc.p_disc_key, KEY_SIZE );
+ memcpy( test_key, p_buffer, KEY_SIZE );
CSSDecryptKey( test_key, disc_key, 0);
i++;
( memcmp( test_key, disc_key, KEY_SIZE ) ) );
/* The decrypted disk key will replace the disk key hash */
- memcpy( dvdcss->css.disc.p_disc_key, disc_key, KEY_SIZE );
+ memcpy( dvdcss->css.p_disc_key, disc_key, KEY_SIZE );
break;
#else
dvdcss->i_method = DVDCSS_METHOD_DISC;
/* Crack Disc key to be able to use it */
_dvdcss_debug( dvdcss, "cracking disc key with key hash" );
_dvdcss_debug( dvdcss, "building 64MB table ... this will take some time" );
- CSSDiscCrack( dvdcss, dvdcss->css.disc.p_disc_key );
+ CSSDiscCrack( dvdcss, p_buffer );
+ memcpy( dvdcss->css.p_disc_key, p_buffer, KEY_SIZE );
break;
default:
_dvdcss_debug( dvdcss, "disc key won't be decrypted" );
}
+ CSSPrintKey( dvdcss, dvdcss->css.p_disc_key );
return 0;
}
if( b_stop_scanning )
{
memcpy( dvdcss->css.p_title_key, &p_key, sizeof(dvd_key_t) );
+ CSSPrintKey( dvdcss, dvdcss->css.p_title_key );
_dvdcss_debug( dvdcss, "vts key initialized" );
return 0;
}
if( !b_encrypted )
{
_dvdcss_debug( dvdcss, "file was unscrambled" );
+ dvdcss->b_encrypted = 0;
return 0;
}
*/
_dvdcss_debug( dvdcss, "decrypting title key with disc key" );
-
+
/* We need to authenticate again for every key
* (to get a new session key ?) */
CSSAuth( dvdcss );
/* Unencrypt title key using bus key */
for( i = 0 ; i < KEY_SIZE ; i++ )
{
- p_key[ i ] ^= dvdcss->css.disc.p_key_check[ 4 - (i % KEY_SIZE ) ];
+ p_key[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE ) ];
}
+ /* If p_key is all zero then there realy wasn't any key pressent. */
+ if( !( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] ) )
+ {
+ memset( dvdcss->css.p_title_key, 0, sizeof(dvd_key_t) );
+ CSSPrintKey( dvdcss, dvdcss->css.p_title_key );
+ return 0;
+ }
+
/* Title key decryption needs one inversion 0xff */
- CSSDecryptKey( p_key, dvdcss->css.disc.p_disc_key, 0xff );
+ CSSDecryptKey( p_key, dvdcss->css.p_disc_key, 0xff );
memcpy( dvdcss->css.p_title_key, p_key, KEY_SIZE );
+ CSSPrintKey( dvdcss, dvdcss->css.p_title_key );
}
return 0;
*****************************************************************************/
static int CSSGetASF( dvdcss_handle dvdcss )
{
- int i_agid;
int i_asf = 0;
- for( i_agid = 0 ; i_agid < 4 ; i_agid++ )
+ if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 )
{
- if( ioctl_ReportASF( dvdcss->i_fd, &i_agid, &i_asf ) == 0 )
- {
- if( i_asf )
- {
- _dvdcss_debug( dvdcss, "GetASF authenticated" );
- }
- else
- {
- _dvdcss_debug( dvdcss, "GetASF not authenticated" );
- }
+ /* The ioctl process has failed */
+ _dvdcss_error( dvdcss, "GetASF fatal error" );
+ return -1;
+ }
- return i_asf;
- }
+ if( i_asf )
+ {
+ _dvdcss_debug( dvdcss, "GetASF authenticated (ASF=1)" );
+ }
+ else
+ {
+ _dvdcss_debug( dvdcss, "GetASF not authenticated (ASF=0)" );
}
- /* The ioctl process has failed */
- _dvdcss_error( dvdcss, "GetASF fatal error" );
- return -1;
+ return i_asf;
}
/*****************************************************************************
* css.h: Structures for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: css.h,v 1.7 2002/01/14 22:06:57 stef Exp $
+ * $Id: css.h,v 1.8 2002/01/23 03:15:31 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
typedef u8 dvd_key_t[KEY_SIZE];
-typedef struct disc_s
-{
- u8 p_challenge[2*KEY_SIZE];
- dvd_key_t p_key1;
- dvd_key_t p_key2;
- dvd_key_t p_key_check;
- u8 i_varient;
- u8 p_disc_key[2048];
-} disc_t;
-
typedef struct dvd_title_s
{
int i_startlb;
typedef struct css_s
{
- int i_agid;
- disc_t disc;
- dvd_key_t p_unenc_key; /* title key before decryption */
- dvd_key_t p_title_key; /* title key after decryption */
+ int i_agid; /* Current Authenication Grant ID. */
+ dvd_key_t p_bus_key; /* Current session key. */
+ dvd_key_t p_disc_key; /* This DVD disc's key. */
+ dvd_key_t p_unenc_key; /* Current title key before decryption. */
+ dvd_key_t p_title_key; /* Current title key. */
} css_t;
/*****************************************************************************
struct css_s;
int CSSTest ( dvdcss_handle );
-int CSSAuth ( dvdcss_handle );
int CSSGetDiscKey ( dvdcss_handle );
int CSSGetTitleKey ( dvdcss_handle, int );
int CSSDescrambleSector ( u8 * , u8 * );
* libdvdcss.c: DVD reading library.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: libdvdcss.c,v 1.29 2002/01/21 07:00:21 gbazin Exp $
+ * $Id: libdvdcss.c,v 1.30 2002/01/23 03:15:31 stef Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
dvdcss->i_method = DVDCSS_METHOD_TITLE;
dvdcss->b_ioctls = 0;
dvdcss->b_encrypted = 1;
- memset( &dvdcss->css.disc, 0, sizeof(dvdcss->css.disc) );
}
/* If disc is CSS protected and the ioctls work, authenticate the drive */
memset( dvdcss->css.p_unenc_key, 0, KEY_SIZE );
}
+ memset( dvdcss->css.p_title_key, 0, KEY_SIZE );
#ifndef WIN32
if( psz_raw_device != NULL )
# Objects
#
-OBJ_C = dvdread.o dvd_udf.o nav_print.o nav_read.o ifo_print.o ifo_read.o
+OBJ_C = dvd_setup.o dvd_reader.o dvd_udf.o nav_print.o nav_read.o ifo_print.o ifo_read.o
ALL_OBJ = $(OBJ_C) $(OBJ_LIBDVDREAD)
#
$(OBJ_C): %.o: .dep/%.d
$(OBJ_C): %.o: %.c
- $(CC) $(CFLAGS) $(CFLAGS_LIBDVDREAD) $(PCFLAGS) -c -o $@ $<
+ $(CC) $(CFLAGS) $(CFLAGS_DVDREAD) $(CFLAGS_LIBDVDREAD) $(PCFLAGS) -c -o $@ $<
../../lib/$(FULL_SO): $(OBJ_C) $(OBJ_LIBDVDREAD)
$(CC) $(PCFLAGS) $(ALL_SOFLAGS) -o $@ $^ $(PLCFLAGS) $(LIB_LIBDVDREAD)
#ifndef BSWAP_H_INCLUDED
#define BSWAP_H_INCLUDED
-#include <defs.h>
#include <config.h>
#if defined(WORDS_BIGENDIAN)
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/time.h> /* For the timing of dvdcss_title crack. */
+#include <sys/uio.h> /* readv() */
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.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 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 );
+#include "dvd_setup.h"
struct dvd_reader_s {
/* Basic information. */
int isImageFile;
/* Information required for an image file. */
- dvdcss_handle dev;
- int init_keys;
- int fd;
+ dvd_handle dev;
/* Information required for a directory path drive. */
char *path_root;
uint32_t seek_pos;
/* Information required for a directory path drive. */
+ dvd_handle title_devs[9];
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;
+ dvd_handle dev = 0;
- 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;
- }
+ dev = pf_dvd_open( (char *) location );
+ if( !dev ) {
+ 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;
{
dvd_reader_t *dvd;
+ fprintf(stderr, "libdvdread: opening %s as folder\n", path_root );
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;
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;
+ /* 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*/
+ /* Try to open libdvdcss or fall back to standard functions */
+ DVDSetupRead();
+
+ /* 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 ) ) {
+ S_ISCHR( fileinfo.st_mode ) ||
+ S_ISREG( fileinfo.st_mode ) ) {
- /**
- * Block devices and regular files are assumed to be DVD-Video images.
- */
+ /**
+ * Block devices and regular files are assumed to be DVD-Video images.
+ */
#if defined(__sun)
- return DVDOpenImageFile( sun_block2char( path ) );
+ return DVDOpenImageFile( sun_block2char( path ) );
#elif defined(SYS_BSD)
- return DVDOpenImageFile( bsd_block2char( path ) );
+ return DVDOpenImageFile( bsd_block2char( path ) );
#else
- return DVDOpenImageFile( path );
+ return DVDOpenImageFile( path );
#endif
} else if( S_ISDIR( fileinfo.st_mode ) ) {
- dvd_reader_t *auth_drive = 0;
- char *path_copy;
+ dvd_reader_t *auth_drive = 0;
+ char *path_copy;
#if defined(SYS_BSD)
- struct fstab* fe;
+ struct fstab* fe;
#elif defined(__sun) || defined(__linux__)
- FILE *mntfile;
+ 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';
- }
- }
+ fprintf(stderr, "libdvdread: file is directory\n" );
+ /* 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 );
- }
+ 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 );
- }
+ 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 ) {
while( ( me = getmntent( mntfile ) ) ) {
if( !strcmp( me->mnt_dir, path_copy ) ) {
- fprintf( stderr,
- "libdvdread: Attempting to use device %s"
+ fprintf( stderr,
+ "libdvdread: Attempting to use device %s"
" mounted on %s for CSS authentication\n",
me->mnt_fsname,
- me->mnt_dir );
+ me->mnt_dir );
auth_drive = DVDOpenImageFile( me->mnt_fsname );
break;
}
}
+ fprintf(stderr, "libdvdread: mounted device %p\n", me );
fclose( mntfile );
- }
+ }
#endif
- if( !auth_drive ) {
- fprintf( stderr, "libdvdread: Device inaccessible, "
- "CSS authentication not available.\n" );
- }
+ if( !auth_drive ) {
+ fprintf( stderr, "libdvdread: Device inaccessible, "
+ "CSS authentication not available.\n" );
+ }
- free( path_copy );
+ free( path_copy );
/**
* If we've opened a drive, just use that.
/**
* Otherwise, we now try to open the directory tree instead.
*/
- fprintf( stderr, "libdvdread: Using normal filesystem access.\n" );
+ fprintf( stderr, "libdvdread: Using normal filesystem access.\n" );
return DVDOpenPath( path );
}
void DVDClose( dvd_reader_t *dvd )
{
if( dvd ) {
- if( dvd->dev ) dvdcss_close( dvd->dev );
- if( dvd->fd >= 0 ) close( dvd->fd );
+ if( dvd->dev ) pf_dvd_close( dvd->dev );
if( dvd->path_root ) free( dvd->path_root );
free( dvd );
dvd = 0;
start = UDFFindFile( dvd, filename, &len );
if( !start ) return 0;
+ fprintf( stderr, "libdvdread: opening %s as image\n", filename );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0;
dvd_file->dvd = dvd;
dvd_file->lb_start = start;
dvd_file->seek_pos = 0;
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
+ //memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
return dvd_file;
char full_path[ PATH_MAX + 1 ];
dvd_file_t *dvd_file;
struct stat fileinfo;
- int fd;
+ dvd_handle dev;
/* Get the full path of the file. */
if( !findDVDFile( dvd, filename, full_path ) ) return 0;
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) return 0;
+ fprintf( stderr, "libdvdread: opening %s as file\n", full_path );
+ dev = pf_dvd_open( full_path );
+ if( dev == NULL ) return 0;
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0;
dvd_file->lb_start = 0;
dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
+ memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
dvd_file->filesize = 0;
if( stat( full_path, &fileinfo ) < 0 ) {
return 0;
}
dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
+ dvd_file->title_devs[ 0 ] = dev;
dvd_file->filesize = dvd_file->title_sizes[ 0 ];
return dvd_file;
}
-static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd,
- int title, int menu )
+static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
uint32_t start, len;
dvd_file_t *dvd_file;
+ fprintf( stderr, "libdvdread: opening VOB as image\n" );
if( title == 0 ) {
sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
} else {
dvd_file->lb_start = start;
dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
+ memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
/* Calculate the complete file size for every file in the VOBS */
}
}
- /* Hack to crack all the keys on the first open. */
- if( dvdcss_library ) {
- if( !dvd_file->dvd->init_keys ) {
- initAllCSSKeys( dvd_file->dvd );
- dvd_file->dvd->init_keys = 1;
- }
- }
-
- /* Perform CSS key cracking for this title. */
- if( dvdcss_library ) {
- if( dvdcss_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
+ if( pf_dvd_seek( dvd_file->dvd->dev, (int)start, DVDCSS_SEEK_KEY ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
filename );
- }
}
return dvd_file;
}
-static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
- int title, int menu )
+static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
char full_path[ PATH_MAX + 1 ];
dvd_file_t *dvd_file;
int i;
+ fprintf( stderr, "libdvdread: opening VOB as file\n" );
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
if( !dvd_file ) return 0;
dvd_file->dvd = dvd;
dvd_file->lb_start = 0;
dvd_file->seek_pos = 0;
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
+ memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
dvd_file->filesize = 0;
if( menu ) {
- int fd;
+ dvd_handle dev;
if( title == 0 ) {
sprintf( filename, "VIDEO_TS.VOB" );
return 0;
}
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) {
+ dev = pf_dvd_open( full_path );
+ if( dev == NULL ) {
free( dvd_file );
return 0;
}
return 0;
}
dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
+ dvd_file->title_devs[ 0 ] = dev;
+ pf_dvd_title( dvd_file->title_devs[0], 0 );
dvd_file->filesize = dvd_file->title_sizes[ 0 ];
} else {
}
dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ i ] = open( full_path, O_RDONLY );
+ dvd_file->title_devs[ i ] = pf_dvd_open( full_path );
+ pf_dvd_title( dvd_file->title_devs[i], 0 );
dvd_file->filesize += dvd_file->title_sizes[ i ];
}
if( !(dvd_file->title_sizes[ 0 ]) ) {
}
dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
- dvd_read_domain_t domain )
+ dvd_read_domain_t domain )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
if( dvd_file ) {
if( !dvd_file->dvd->isImageFile ) {
for( i = 0; i < 9; ++i ) {
- if( dvd_file->title_fds[ i ] >= 0 )
- close( dvd_file->title_fds[ i ] );
+ if( dvd_file->title_devs[ i ] ) {
+ pf_dvd_close( dvd_file->title_devs[i] );
+ }
}
}
}
int64_t DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,
- int encrypted )
+ size_t block_count, unsigned char *data,
+ int encrypted )
{
- if( dvdcss_library ) {
- int ret;
-
- if( !device->dev ) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
-
- ret = dvdcss_seek( device->dev, (int) lb_number );
- if( ret != (int) lb_number ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
-
- return (int64_t) ( dvdcss_read( device->dev, (char *) data,
- (int) block_count, encrypted )
- * (uint64_t) DVD_VIDEO_LB_LEN );
- } else {
- off64_t off;
+ int ret;
- if( device->fd < 0) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
+ if( !device->dev ) {
+ fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
+ return 0;
+ }
- off = lseek64( device->fd, lb_number * (int64_t) DVD_VIDEO_LB_LEN,
- SEEK_SET );
- if( off != ( lb_number * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
- return (int64_t) ( read( device->fd, data,
- block_count * DVD_VIDEO_LB_LEN ) );
+ ret = pf_dvd_seek( device->dev, (int) lb_number, DVDCSS_NOFLAGS );
+ if( ret != (int) lb_number ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %u\n",
+ lb_number );
+ return 0;
}
+
+ return (int64_t) ( pf_dvd_read( device->dev, (char *) data,
+ (int) block_count, encrypted )
+ * (uint64_t) DVD_VIDEO_LB_LEN );
}
static int64_t DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, unsigned char *data )
+ size_t block_count, unsigned char *data )
{
return DVDReadLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
block_count, data, DVDCSS_READ_DECRYPT );
}
static int64_t DVDReadBlocksPath( dvd_file_t *dvd_file, size_t offset,
- size_t block_count, unsigned char *data )
+ size_t block_count, unsigned char *data )
{
int i;
ssize_t ret, ret2;
if( offset < dvd_file->title_sizes[ i ] ) {
if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data,
- block_count * DVD_VIDEO_LB_LEN );
+ off = pf_dvd_seek( dvd_file->title_devs[ i ], (int)offset, 0 );
+ if( off != (int)offset ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %d\n",
+ offset );
+ return 0;
+ }
+ ret = pf_dvd_read( dvd_file->title_devs[ i ], data,
+ (int)block_count, DVDCSS_READ_DECRYPT );
break;
} else {
- size_t part1_size
- = ( dvd_file->title_sizes[ i ] - offset ) * DVD_VIDEO_LB_LEN;
- /* FIXME: Really needs to be a while loop.
- (This is only true if you try and read >1GB at a time) */
-
+ size_t part1_size = dvd_file->title_sizes[ i ] - offset;
+ /* FIXME: Really needs to be a while loop.
+ * (This is only true if you try and read >1GB at a time) */
+
/* Read part 1 */
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data, part1_size );
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.
- also error from this read will not show in ret. */
-
+ off = pf_dvd_seek( dvd_file->title_devs[ i ], offset, 0 );
+ if( off != offset ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %d\n",
+ offset );
+ return 0;
+ }
+ ret = pf_dvd_read( dvd_file->title_devs[ i ], data,
+ part1_size, DVDCSS_READ_DECRYPT );
+ if( ret < 0 ) return ret;
+ /* FIXME: This is wrong if i is the last file in the set.
+ * also error from this read will not show in ret. */
+
/* Read part 2 */
- lseek64( dvd_file->title_fds[ i + 1 ], (off64_t)0, SEEK_SET );
- ret2 = read( dvd_file->title_fds[ i + 1 ], data + part1_size,
- block_count * DVD_VIDEO_LB_LEN - part1_size );
+ pf_dvd_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
+ ret2 = pf_dvd_read( dvd_file->title_devs[ i + 1 ], data +
+ ( part1_size * (int64_t)DVD_VIDEO_LB_LEN ),
+ block_count - part1_size,
+ DVDCSS_READ_DECRYPT );
if( ret2 < 0 ) return ret2;
- break;
+ break;
}
} else {
offset -= dvd_file->title_sizes[ i ];
}
}
- return ( (int64_t) ret + (int64_t) ret2 );
+ return ( (int64_t) ret + (int64_t) ret2 ) * DVD_VIDEO_LB_LEN;
}
/* These are broken for some cases reading more than 2Gb at a time. */
ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, unsigned char *data )
+ size_t block_count, unsigned char *data )
{
int64_t ret;
if( dvd_file->dvd->isImageFile ) {
- ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
- block_count, data );
+ ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
+ block_count, data );
} else {
- ret = DVDReadBlocksPath( dvd_file, (size_t) offset,
- block_count, data );
+ ret = DVDReadBlocksPath( dvd_file, (size_t) offset,
+ block_count, data );
}
if( ret <= 0 ) {
return (ssize_t) ret;
}
+
{
ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
if( sret == 0 ) {
- fprintf(stderr, "libdvdread: DVDReadBlocks got %d bytes\n", (int)ret );
+ fprintf(stderr, "libdvdread: DVDReadBlocks got %d bytes\n", (int)ret );
}
return sret;
}
dvd_file->seek_pos = (uint32_t) offset;
return offset;
} else {
- return (int32_t) ( lseek( dvd_file->title_fds[ 0 ],
- (off_t) offset, SEEK_SET ) );
+ return (int32_t) ( lseek( dvd_file->title_devs[0]->i_fd,
+ (off_t)offset, SEEK_SET ) );
}
}
static ssize_t DVDReadBytesUDF( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
+ size_t byte_size )
{
unsigned char *secbuf;
unsigned int numsec, seek_sector, seek_byte;
numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + 1;
secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
if( !secbuf ) {
- fprintf( stderr, "libdvdread: Can't allocate memory "
- "for file read!\n" );
+ fprintf( stderr, "libdvdread: Can't allocate memory "
+ "for file read!\n" );
return 0;
}
}
static ssize_t DVDReadBytesPath( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
+ size_t byte_size )
{
- return read( dvd_file->title_fds[ 0 ], data, byte_size );
+ return read( dvd_file->title_devs[0]->i_fd, data, byte_size );
}
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
return dvd_file->filesize;
}
+int64_t DVDReadVLBUDF( dvd_reader_t *device, uint32_t lb_number,
+ size_t block_count, struct iovec * vector, int encrypted )
+{
+ int ret;
+
+ if( !device->dev ) {
+ fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
+ return 0;
+ }
+
+ ret = pf_dvd_seek( device->dev, (int) lb_number, 0 );
+ if( ret != (int) lb_number ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %u\n",
+ lb_number );
+ return 0;
+ }
+
+ return (int64_t) ( pf_dvd_readv( device->dev, vector,
+ (int)block_count, encrypted )
+ * (uint64_t) DVD_VIDEO_LB_LEN );
+}
+
+static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
+ size_t block_count, struct iovec *vector )
+{
+ return DVDReadVLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
+ block_count, vector, DVDCSS_READ_DECRYPT );
+}
+
+static int64_t DVDReadVBlocksPath( dvd_file_t *dvd_file, size_t offset,
+ size_t block_count, struct iovec *vector )
+{
+ int i;
+ int ret, ret2;
+ int off;
+
+ ret = 0;
+ ret2 = 0;
+ for( i = 0 ; i < 9 ; ++i ) {
+ if( !dvd_file->title_sizes[ i ] ) {
+ return 0;
+ }
+
+ if( offset < dvd_file->title_sizes[ i ] ) {
+ if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
+ off = pf_dvd_seek( dvd_file->title_devs[ i ],
+ (int)offset, 0 );
+ if( off != (int)offset ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %d\n",
+ offset );
+ return 0;
+ }
+ ret = pf_dvd_readv( dvd_file->title_devs[ i ], vector,
+ (int)block_count, DVDCSS_READ_DECRYPT );
+ break;
+ } else {
+ int part1_size = dvd_file->title_sizes[ i ] - offset;
+ /* FIXME: Really needs to be a while loop.
+ * (This is only true if you try and read >1GB at a time) */
+
+ /* Read part 1 */
+ off = pf_dvd_seek( dvd_file->title_devs[ i ], offset, 0 );
+ if( off != offset ) {
+ fprintf( stderr, "libdvdread: Can't seek to block %d\n",
+ offset );
+ return 0;
+ }
+ ret = pf_dvd_readv( dvd_file->title_devs[ i ], vector,
+ part1_size, DVDCSS_READ_DECRYPT );
+
+ if( ret < 0 ) return ret;
+ /* FIXME: This is wrong if i is the last file in the set.
+ * also error from this read will not show in ret. */
+
+ /* Read part 2 */
+ pf_dvd_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
+ ret2 = pf_dvd_readv( dvd_file->title_devs[ i + 1 ],
+ vector + part1_size,
+ (int)(block_count - part1_size),
+ DVDCSS_READ_DECRYPT );
+ if( ret2 < 0 ) return ret2;
+ break;
+ }
+ } else {
+ offset -= dvd_file->title_sizes[ i ];
+ }
+ }
+
+ return ( ret + ret2 ) * (int64_t) DVD_VIDEO_LB_LEN;
+}
+
+
+ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
+ size_t block_count, struct iovec * vector )
+{
+ int64_t ret;
+
+ if( dvd_file->dvd->isImageFile ) {
+ ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset,
+ block_count, vector );
+ } else {
+ ret = DVDReadVBlocksPath( dvd_file, (size_t) offset,
+ block_count, vector );
+ }
+ if( ret <= 0 ) {
+ return (ssize_t) ret;
+ }
+
+ {
+ ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
+ if( sret == 0 )
+ {
+ fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret );
+ }
+ return sret;
+ }
+}
+
ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
size_t block_count, unsigned char *data );
+/**
+ * The same calling a readv-like function to fill a struct iovec.
+ */
+struct iovec;
+ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
+ size_t block_count, struct iovec * vector );
/**
* Seek to the given position in the file. Returns the resulting position in
* bytes from the beginning of the file. The seek position is only used for
--- /dev/null
+/**
+ * dvd_setup.c: setup read functions with either libdvdcss
+ * or minimal DVD access.
+ */
+
+/**
+ * Copyright (C) 2001 VideoLAN
+ * $Id: dvd_setup.c,v 1.1 2002/01/23 03:15:31 stef Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * 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, USA.
+ */
+
+/**
+ * Preamble
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/uio.h> /* struct iovec */
+
+#include "dvd_reader.h"
+#include "dvd_setup.h"
+
+#ifdef GOD_DAMN_DMCA
+/**
+ * dvd_open: initialize library, open a DVD device.
+ */
+static dvd_handle dvd_open ( char *psz_target )
+{
+ dvd_handle dev;
+
+ /* Allocate the library structure */
+ dev = malloc( sizeof( dvd_handle ) );
+ if( dev == NULL )
+ {
+ fprintf( stderr, "libdvdread: Could not allocate memory.\n" );
+ return NULL;
+ }
+
+ /* Open the device */
+ dev->i_fd = open( psz_target, 0 );
+ if( dev->i_fd < 0 )
+ {
+ fprintf( stderr, "libdvdread: Could not open device.\n" );
+ free( dev );
+ return NULL;
+ }
+
+ return dev;
+}
+
+/**
+ * dvd_error: return the last error message
+ */
+static char * dvd_error ( dvd_handle dev )
+{
+ return "unknown error";
+}
+
+/**
+ * dvd_seek: seek into the device.
+ */
+static int dvd_seek ( dvd_handle dev, int i_blocks, int i_flags )
+{
+ off_t i_read;
+
+ i_read = lseek( dev->i_fd,
+ (off_t)i_blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET );
+
+ return i_read / DVD_VIDEO_LB_LEN;
+}
+
+/**
+ * dvd_title: crack the current title key if needed.
+ */
+static int dvd_title ( dvd_handle dev, int i_block )
+{
+ return 0;
+}
+
+/**
+ * dvd_read: read data from the device.
+ */
+static int dvd_read ( dvd_handle dev, void *p_buffer,
+ int i_blocks,
+ int i_flags )
+{
+ int i_bytes;
+
+ i_bytes = read( dev->i_fd, p_buffer,
+ (size_t)i_blocks * DVD_VIDEO_LB_LEN );
+
+ return i_bytes / DVD_VIDEO_LB_LEN;
+}
+
+/**
+ * dvd_readv: read data to an iovec structure.
+ */
+static int dvd_readv ( dvd_handle dev, void *p_iovec,
+ int i_blocks,
+ int i_flags )
+{
+ int i_read;
+
+ i_read = readv( dev->i_fd, (struct iovec*)p_iovec, i_blocks );
+
+ return i_read / DVD_VIDEO_LB_LEN;
+}
+
+/**
+ * dvd_close: close the DVD device and clean up the library.
+ */
+static int dvd_close ( dvd_handle dev )
+{
+ int i_ret;
+
+ i_ret = close( dev->i_fd );
+
+ if( i_ret < 0 )
+ {
+ return i_ret;
+ }
+
+ free( dev );
+
+ return 0;
+}
+
+void DVDSetupRead( void )
+{
+ void * dvdcss_library = NULL;
+
+ if( ( dvdcss_library = dlopen( "libdvdcss.so.1", RTLD_LAZY ) ) )
+ {
+ pf_dvd_open = dlsym( dvdcss_library, "dvdcss_open" );
+ pf_dvd_close = dlsym( dvdcss_library, "dvdcss_close" );
+ pf_dvd_title = dlsym( dvdcss_library, "dvdcss_title" );
+ pf_dvd_seek = dlsym( dvdcss_library, "dvdcss_seek" );
+ pf_dvd_read = dlsym( dvdcss_library, "dvdcss_read" );
+ pf_dvd_readv = dlsym( dvdcss_library, "dvdcss_readv" );
+ pf_dvd_error = dlsym( dvdcss_library, "dvdcss_error" );
+
+ if( pf_dvd_open == NULL || pf_dvd_close == NULL
+ || pf_dvd_title == NULL || pf_dvd_seek == NULL
+ || pf_dvd_read == NULL || pf_dvd_readv == NULL
+ || pf_dvd_error == NULL )
+ {
+ fprintf( stderr, "libdvdread: Missing symbols in libdvdcss.so.1, "
+ "this shouldn't happen !" );
+ dlclose( dvdcss_library );
+ dvdcss_library = NULL;
+ }
+ else
+ {
+ printf( "libdvdread: Using libdvdcss.so.1 for DVD access\n" );
+ }
+ }
+ else
+ {
+ fprintf( stderr, "libdvdread: Can't open libdvdcss.so.1: %s.\n",
+ dlerror() );
+ }
+
+ if( !dvdcss_library )
+ {
+ /* Replacement functions */
+ pf_dvd_open = dvd_open;
+ pf_dvd_close = dvd_close;
+ pf_dvd_title = dvd_title;
+ pf_dvd_seek = dvd_seek;
+ pf_dvd_read = dvd_read;
+ pf_dvd_readv = dvd_readv;
+ pf_dvd_error = dvd_error;
+ }
+}
+#else
+void DVDSetupRead( void )
+{
+ pf_dvd_open = dvdcss_open;
+ pf_dvd_close = dvdcss_close;
+ pf_dvd_title = dvdcss_title;
+ pf_dvd_seek = dvdcss_seek;
+ pf_dvd_read = dvdcss_read;
+ pf_dvd_readv = dvdcss_readv;
+ pf_dvd_error = dvdcss_error;
+}
+#endif
--- /dev/null
+/**
+ * dvd_setup.h: setup functions header.
+ */
+
+/* Copyright (C) 2001 VideoLAN
+ * $Id: dvd_setup.h,v 1.1 2002/01/23 03:15:31 stef Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * 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, USA.
+ */
+
+/**
+ * The libdvdcss structure.
+ */
+struct dvdcss_s
+{
+ /* File descriptor */
+ int i_fd;
+};
+
+#ifdef GOD_DAMN_DMCA
+/**
+ * Defines and flags.
+ */
+# define DVDCSS_NOFLAGS 0
+# define DVDCSS_READ_DECRYPT (1 << 0)
+# define DVDCSS_SEEK_MPEG (1 << 0)
+# define DVDCSS_SEEK_KEY (1 << 1)
+
+#else
+# include <videolan/dvdcss.h>
+#endif
+
+typedef struct dvdcss_s* dvd_handle;
+
+/**
+ * Pointers which will be filled either with dummy functions or
+ * with the dlopen()ed ones.
+ */
+dvd_handle (*pf_dvd_open) ( char * );
+int (*pf_dvd_close) ( dvd_handle );
+int (*pf_dvd_title) ( dvd_handle, int );
+int (*pf_dvd_seek) ( dvd_handle, int, int );
+int (*pf_dvd_read) ( dvd_handle, void *, int, int );
+int (*pf_dvd_readv) ( dvd_handle, void *, int, int );
+char * (*pf_dvd_error) ( dvd_handle );
+
+/**
+ * Setup function accessed by dvd_reader.c
+ */
+void DVDSetupRead( void );
+++ /dev/null
-/*****************************************************************************
- * libdvdcss.h: DVD reading library, exported functions.
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: dvdcss.h,v 1.1 2001/11/25 05:04:38 stef Exp $
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Samuel Hocevar <sam@zoy.org>
- *
- * 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, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * The libdvdcss structure
- *****************************************************************************/
-typedef struct dvdcss_s* dvdcss_handle;
-
-/*****************************************************************************
- * Flags
- *****************************************************************************/
-#define DVDCSS_NOFLAGS 0
-
-#define DVDCSS_INIT_QUIET (1 << 0)
-#define DVDCSS_INIT_DEBUG (1 << 1)
-
-#define DVDCSS_READ_DECRYPT (1 << 0)
-
-#define DVDCSS_BLOCK_SIZE 2048
-
+++ /dev/null
-/*****************************************************************************
- * dvdread.c: replacement for dvd_reader.c that always takes dvdcss functions
- * (hard-linked) and adds a readv call function to tha API.
- *****************************************************************************
- * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
- * $Id: dvdread.c,v 1.3 2002/01/15 05:22:21 stef Exp $
- *
- * Author: Billy Biggs <vektor@dumbterm.net>
- * Stéphane Borel <stef@via.ecp.fr>
- *
- * 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, USA.
- *****************************************************************************/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h> /* readv() */
-#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 "dvd_udf.h"
-#include "dvd_reader.h"
-
-#include "../libdvdcss/videolan/dvdcss.h"
-
-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. */
- dvdcss_handle title_devs[9];
- size_t title_sizes[ 9 ];
- int title_fds[ 9 ];
-
- /* Calculated at open-time, size in blocks. */
- ssize_t filesize;
-};
-
-/**
- * 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;
-
- dev = dvdcss_open( (char *) location );
- if( !dev ) {
- 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;
-
- fprintf(stderr, "libdvdread: opening %s as folder\n", path_root );
- 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 filesystem access.\n" );
- return DVDOpenPath( path );
- }
-
- /* If it's none of the above, screw it. */
- fprintf( stderr, "libdvdread: Could not open %s\n", path );
- return 0;
-}
-
-void DVDClose( dvd_reader_t *dvd )
-{
- if( dvd ) {
- if( dvd->dev ) dvdcss_close( dvd->dev );
- if( dvd->fd >= 0 ) close( dvd->fd );
- if( dvd->path_root ) free( dvd->path_root );
- free( dvd );
- dvd = 0;
- }
-}
-
-/**
- * Open an unencrypted file on a DVD image file.
- */
-static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
-{
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- start = UDFFindFile( dvd, filename, &len );
- if( !start ) return 0;
-
- fprintf( stderr, "libdvdread: opening %s as image\n", filename );
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- return dvd_file;
-}
-
-/**
- * Searches for <file> in directory <path>, ignoring case.
- * Returns 0 and full filename in <filename>.
- * or -1 on file not found.
- * or -2 on path not found.
- */
-static int findDirFile( const char *path, const char *file, char *filename )
-{
- DIR *dir;
- struct dirent *ent;
-
- dir = opendir( path );
- if( !dir ) return -2;
-
- while( ( ent = readdir( dir ) ) != NULL ) {
- if( !strcasecmp( ent->d_name, file ) ) {
- sprintf( filename, "%s%s%s", path,
- ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ),
- ent->d_name );
- return 0;
- }
- }
-
- return -1;
-}
-
-static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename )
-{
- char video_path[ PATH_MAX + 1 ];
- const char *nodirfile;
- int ret;
-
- /* Strip off the directory for our search */
- if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) {
- nodirfile = &(file[ 10 ]);
- } else {
- nodirfile = file;
- }
-
- ret = findDirFile( dvd->path_root, nodirfile, filename );
- if( ret < 0 ) {
- /* Try also with adding the path, just in case. */
- sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- /* Try with the path, but in lower case. */
- sprintf( video_path, "%s/video_ts/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-/**
- * Open an unencrypted file from a DVD directory tree.
- */
-static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
-{
- char full_path[ PATH_MAX + 1 ];
- dvd_file_t *dvd_file;
- struct stat fileinfo;
- int fd;
-
- /* Get the full path of the file. */
- if( !findDVDFile( dvd, filename, full_path ) ) return 0;
-
- fprintf( stderr, "libdvdread: opening %s as file\n", full_path );
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = 0;
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd,
- int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- fprintf( stderr, "libdvdread: opening VOB as image\n" );
- if( title == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
- }
- start = UDFFindFile( dvd, filename, &len );
- if( start == 0 ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- /* Calculate the complete file size for every file in the VOBS */
- if( !menu ) {
- int cur;
-
- for( cur = 2; cur < 10; cur++ ) {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
- if( !UDFFindFile( dvd, filename, &len ) ) break;
- dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
- }
- }
-
- if( dvdcss_seek( dvd_file->dvd->dev, (int)start, DVDCSS_SEEK_KEY ) < 0 ) {
- fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
- filename );
- }
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
- int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- char full_path[ PATH_MAX + 1 ];
- struct stat fileinfo;
- dvd_file_t *dvd_file;
- int i;
-
- fprintf( stderr, "libdvdread: opening VOB as file\n" );
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = 0;
-
- if( menu ) {
- int fd;
-
- if( title == 0 ) {
- sprintf( filename, "VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "VTS_%02i_0.VOB", title );
- }
- if( !findDVDFile( dvd, filename, full_path ) ) {
- free( dvd_file );
- return 0;
- }
-
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) {
- free( dvd_file );
- return 0;
- }
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
- dvd_file->title_devs[ 0 ] = dvdcss_open( full_path );
- dvdcss_title( dvd_file->title_devs[0], 0 );
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- } else {
- for( i = 0; i < 9; ++i ) {
-
- sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
- if( !findDVDFile( dvd, filename, full_path ) ) {
- break;
- }
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- break;
- }
-
- dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ i ] = open( full_path, O_RDONLY );
- dvd_file->title_devs[ i ] = dvdcss_open( full_path );
- dvdcss_title( dvd_file->title_devs[i], 0 );
- dvd_file->filesize += dvd_file->title_sizes[ i ];
- }
- if( !(dvd_file->title_sizes[ 0 ]) ) {
- free( dvd_file );
- return 0;
- }
- }
-
- return dvd_file;
-}
-
-dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
- dvd_read_domain_t domain )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
-
- switch( domain ) {
- case DVD_READ_INFO_FILE:
- if( titlenum == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
- }
- break;
- case DVD_READ_INFO_BACKUP_FILE:
- if( titlenum == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
- }
- break;
- case DVD_READ_MENU_VOBS:
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 1 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 1 );
- }
- break;
- case DVD_READ_TITLE_VOBS:
- if( titlenum == 0 ) return 0;
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 0 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 0 );
- }
- break;
- default:
- fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
- return 0;
- }
-
- if( dvd->isImageFile ) {
- return DVDOpenFileUDF( dvd, filename );
- } else {
- return DVDOpenFilePath( dvd, filename );
- }
-}
-
-void DVDCloseFile( dvd_file_t *dvd_file )
-{
- int i;
-
- if( dvd_file ) {
- if( !dvd_file->dvd->isImageFile ) {
- for( i = 0; i < 9; ++i ) {
- if( dvd_file->title_fds[ i ] >= 0 )
- {
- close( dvd_file->title_fds[ i ] );
- dvdcss_close( dvd_file->title_devs[i] );
- }
- }
- }
-
- free( dvd_file );
- dvd_file = 0;
- }
-}
-
-int64_t DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,
- int encrypted )
-{
- int ret;
-
- if( !device->dev ) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
-
- ret = dvdcss_seek( device->dev, (int) lb_number, DVDCSS_NOFLAGS );
- if( ret != (int) lb_number ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
-
- return (int64_t) ( dvdcss_read( device->dev, (char *) data,
- (int) block_count, encrypted )
- * (uint64_t) DVD_VIDEO_LB_LEN );
-}
-
-static int64_t DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, unsigned char *data )
-{
- return DVDReadLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, data, DVDCSS_READ_DECRYPT );
-}
-
-static int64_t DVDReadBlocksPath( dvd_file_t *dvd_file, size_t offset,
- size_t block_count, unsigned char *data )
-{
- int i;
- ssize_t ret, ret2;
- off64_t off;
-
- ret = 0;
- ret2 = 0;
- for( i = 0; i < 9; ++i ) {
- if( !dvd_file->title_sizes[ i ] ) return 0;
-
- if( offset < dvd_file->title_sizes[ i ] ) {
- if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data,
- block_count * DVD_VIDEO_LB_LEN );
- break;
- } else {
- size_t part1_size
- = ( dvd_file->title_sizes[ i ] - offset ) * DVD_VIDEO_LB_LEN;
- /* FIXME: Really needs to be a while loop.
- (This is only true if you try and read >1GB at a time) */
-
- /* Read part 1 */
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data, part1_size );
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.
- also error from this read will not show in ret. */
-
- /* Read part 2 */
- lseek64( dvd_file->title_fds[ i + 1 ], (off64_t)0, SEEK_SET );
- ret2 = read( dvd_file->title_fds[ i + 1 ], data + part1_size,
- block_count * DVD_VIDEO_LB_LEN - part1_size );
- if( ret2 < 0 ) return ret2;
- break;
- }
- } else {
- offset -= dvd_file->title_sizes[ i ];
- }
- }
-
- return ( (int64_t) ret + (int64_t) ret2 );
-}
-
-/* These are broken for some cases reading more than 2Gb at a time. */
-ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, unsigned char *data )
-{
- int64_t ret;
-
- if( dvd_file->dvd->isImageFile ) {
- ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
- block_count, data );
- } else {
- ret = DVDReadBlocksPath( dvd_file, (size_t) offset,
- block_count, data );
- }
- if( ret <= 0 ) {
- return (ssize_t) ret;
- }
- {
- ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
- if( sret == 0 ) {
- fprintf(stderr, "libdvdread: DVDReadBlocks got %d bytes\n", (int)ret );
- }
- return sret;
- }
-}
-
-int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
-{
- if( dvd_file->dvd->isImageFile ) {
- dvd_file->seek_pos = (uint32_t) offset;
- return offset;
- } else {
- return (int32_t) ( lseek( dvd_file->title_fds[ 0 ],
- (off_t) offset, SEEK_SET ) );
- }
-}
-
-static ssize_t DVDReadBytesUDF( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
-{
- unsigned char *secbuf;
- unsigned int numsec, seek_sector, seek_byte;
- int64_t len;
-
- seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
- seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
-
- numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + 1;
- secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
- if( !secbuf ) {
- fprintf( stderr, "libdvdread: Can't allocate memory "
- "for file read!\n" );
- return 0;
- }
-
- len = DVDReadLBUDF( dvd_file->dvd, dvd_file->lb_start + seek_sector,
- numsec, secbuf, DVDCSS_NOFLAGS );
- if( len != numsec * (int64_t) DVD_VIDEO_LB_LEN ) {
- free( secbuf );
- return 0;
- }
-
- dvd_file->seek_pos += byte_size;
-
- memcpy( data, &(secbuf[ seek_byte ]), byte_size );
- free( secbuf );
-
- return byte_size;
-}
-
-static ssize_t DVDReadBytesPath( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
-{
- return read( dvd_file->title_fds[ 0 ], data, byte_size );
-}
-
-ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
-{
- if( dvd_file->dvd->isImageFile ) {
- return DVDReadBytesUDF( dvd_file, data, byte_size );
- } else {
- return DVDReadBytesPath( dvd_file, data, byte_size );
- }
-}
-
-ssize_t DVDFileSize( dvd_file_t *dvd_file )
-{
- return dvd_file->filesize;
-}
-
-int64_t DVDReadVLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, struct iovec * vector,
- int encrypted )
-{
- int ret;
-
- if( !device->dev ) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
-
- ret = dvdcss_seek( device->dev, (int) lb_number, 0 );
- if( ret != (int) lb_number ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
-
- return (int64_t) ( dvdcss_readv( device->dev, vector,
- (int)block_count, encrypted )
- * (uint64_t) DVD_VIDEO_LB_LEN );
-}
-
-static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, struct iovec *vector )
-{
- return DVDReadVLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, vector, DVDCSS_READ_DECRYPT );
-}
-
-static int64_t DVDReadVBlocksPath( dvd_file_t *dvd_file, size_t offset,
- size_t block_count, struct iovec *vector )
-{
- int i;
- int ret, ret2;
- int off;
-
- ret = 0;
- ret2 = 0;
- for( i = 0 ; i < 9 ; ++i )
- {
- if( !dvd_file->title_sizes[ i ] )
- {
- return 0;
- }
-
- if( offset < dvd_file->title_sizes[ i ] )
- {
- if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] )
- {
- off = dvdcss_seek( dvd_file->title_devs[ i ],
- (int)offset, 0 );
- if( off != (int)offset )
- {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
- (int)block_count, DVDCSS_READ_DECRYPT );
- break;
- }
- else
- {
- int part1_size = dvd_file->title_sizes[ i ] - offset;
- /* FIXME: Really needs to be a while loop.
- (This is only true if you try and read >1GB at a time) */
-
- /* Read part 1 */
- off = dvdcss_seek( dvd_file->title_devs[ i ], offset, 0 );
- if( off != offset )
- {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
- part1_size, DVDCSS_READ_DECRYPT );
-
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.
- also error from this read will not show in ret. */
-
- /* Read part 2 */
- dvdcss_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
- ret2 = dvdcss_readv( dvd_file->title_devs[ i + 1 ],
- vector + part1_size, (int)(block_count - part1_size),
- DVDCSS_READ_DECRYPT );
- if( ret2 < 0 ) return ret2;
- break;
- }
- }
- else
- {
- offset -= dvd_file->title_sizes[ i ];
- }
- }
-
- return ( ret + ret2 ) * (int64_t) DVD_VIDEO_LB_LEN;
-}
-
-
-ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, struct iovec * vector )
-{
- int64_t ret;
-
- if( dvd_file->dvd->isImageFile )
- {
- ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset,
- block_count, vector );
- }
- else
- {
- ret = DVDReadVBlocksPath( dvd_file, (size_t) offset,
- block_count, vector );
- }
- if( ret <= 0 )
- {
- return (ssize_t) ret;
- }
-
- {
- ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
- if( sret == 0 )
- {
- fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret );
- }
- return sret;
- }
-
-}
-
#ifndef IFO_PRINT_H_INCLUDED
#define IFO_PRINT_H_INCLUDED
-//#include <dvdread/ifo_types.h>
-//#include <dvdread/dvd_reader.h>
-#include "ifo_types.h"
-#include "dvd_reader.h"
+#include <dvdread/ifo_types.h>
+#include <dvdread/dvd_reader.h>
#ifdef __cplusplus
extern "C" {
#ifndef IFO_READ_H_INCLUDED
#define IFO_READ_H_INCLUDED
-//#include <dvdread/ifo_types.h>
-//#include <dvdread/dvd_reader.h>
-#include "ifo_types.h"
-#include "dvd_reader.h"
+#include <dvdread/ifo_types.h>
+#include <dvdread/dvd_reader.h>
#ifdef __cplusplus
extern "C" {
#define IFO_TYPES_H_INCLUDED
#include <inttypes.h>
-//#include <dvdread/dvd_reader.h>
-#include "dvd_reader.h"
+#include <dvdread/dvd_reader.h>
#undef ATTRIBUTE_PACKED
#define NAV_PRINT_H_INCLUDED
#include <stdio.h>
-//#include <dvdread/nav_types.h>
-#include "nav_types.h"
+#include <dvdread/nav_types.h>
#ifdef __cplusplus
extern "C" {
#ifndef NAV_READ_H_INCLUDED
#define NAV_READ_H_INCLUDED
-//#include <dvdread/nav_types.h>
-#include "nav_types.h"
+#include <dvdread/nav_types.h>
#ifdef __cplusplus
extern "C" {
#define NAV_TYPES_H_INCLUDED
#include <inttypes.h>
-//#include <dvdread/ifo_types.h> // only dvd_time_t, vm_cmd_t and user_ops_t
-#include "ifo_types.h"
+#include <dvdread/ifo_types.h> // only dvd_time_t, vm_cmd_t and user_ops_t
+
#undef ATTRIBUTE_PACKED
#undef PRAGMA_PACK_BEGIN
+++ /dev/null
-/*****************************************************************************
- * dvdread.c: replacement for dvd_reader.c that always takes dvdcss functions
- * (hard-linked) and adds a readv call function to tha API.
- *****************************************************************************
- * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
- * $Id: dvdread.c,v 1.2 2002/01/15 05:22:21 stef Exp $
- *
- * Author: Billy Biggs <vektor@dumbterm.net>
- * Stéphane Borel <stef@via.ecp.fr>
- *
- * 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, USA.
- *****************************************************************************/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h> /* readv() */
-#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 "dvd_udf.h"
-#include "dvd_reader.h"
-
-#include "../libdvdcss/videolan/dvdcss.h"
-
-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. */
- dvdcss_handle title_devs[9];
- size_t title_sizes[ 9 ];
- int title_fds[ 9 ];
-
- /* Calculated at open-time, size in blocks. */
- ssize_t filesize;
-};
-
-/**
- * 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;
-
- dev = dvdcss_open( (char *) location );
- if( !dev ) {
- 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;
-
- fprintf(stderr, "libdvdread: opening %s as folder\n", path_root );
- 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 filesystem access.\n" );
- return DVDOpenPath( path );
- }
-
- /* If it's none of the above, screw it. */
- fprintf( stderr, "libdvdread: Could not open %s\n", path );
- return 0;
-}
-
-void DVDClose( dvd_reader_t *dvd )
-{
- if( dvd ) {
- if( dvd->dev ) dvdcss_close( dvd->dev );
- if( dvd->fd >= 0 ) close( dvd->fd );
- if( dvd->path_root ) free( dvd->path_root );
- free( dvd );
- dvd = 0;
- }
-}
-
-/**
- * Open an unencrypted file on a DVD image file.
- */
-static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
-{
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- start = UDFFindFile( dvd, filename, &len );
- if( !start ) return 0;
-
- fprintf( stderr, "libdvdread: opening %s as image\n", filename );
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- return dvd_file;
-}
-
-/**
- * Searches for <file> in directory <path>, ignoring case.
- * Returns 0 and full filename in <filename>.
- * or -1 on file not found.
- * or -2 on path not found.
- */
-static int findDirFile( const char *path, const char *file, char *filename )
-{
- DIR *dir;
- struct dirent *ent;
-
- dir = opendir( path );
- if( !dir ) return -2;
-
- while( ( ent = readdir( dir ) ) != NULL ) {
- if( !strcasecmp( ent->d_name, file ) ) {
- sprintf( filename, "%s%s%s", path,
- ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ),
- ent->d_name );
- return 0;
- }
- }
-
- return -1;
-}
-
-static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename )
-{
- char video_path[ PATH_MAX + 1 ];
- const char *nodirfile;
- int ret;
-
- /* Strip off the directory for our search */
- if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) {
- nodirfile = &(file[ 10 ]);
- } else {
- nodirfile = file;
- }
-
- ret = findDirFile( dvd->path_root, nodirfile, filename );
- if( ret < 0 ) {
- /* Try also with adding the path, just in case. */
- sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- /* Try with the path, but in lower case. */
- sprintf( video_path, "%s/video_ts/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-/**
- * Open an unencrypted file from a DVD directory tree.
- */
-static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
-{
- char full_path[ PATH_MAX + 1 ];
- dvd_file_t *dvd_file;
- struct stat fileinfo;
- int fd;
-
- /* Get the full path of the file. */
- if( !findDVDFile( dvd, filename, full_path ) ) return 0;
-
- fprintf( stderr, "libdvdread: opening %s as file\n", full_path );
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = 0;
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd,
- int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- fprintf( stderr, "libdvdread: opening VOB as image\n" );
- if( title == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
- }
- start = UDFFindFile( dvd, filename, &len );
- if( start == 0 ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- /* Calculate the complete file size for every file in the VOBS */
- if( !menu ) {
- int cur;
-
- for( cur = 2; cur < 10; cur++ ) {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
- if( !UDFFindFile( dvd, filename, &len ) ) break;
- dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
- }
- }
-
- if( dvdcss_seek( dvd_file->dvd->dev, (int)start, DVDCSS_SEEK_KEY ) < 0 ) {
- fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
- filename );
- }
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd,
- int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- char full_path[ PATH_MAX + 1 ];
- struct stat fileinfo;
- dvd_file_t *dvd_file;
- int i;
-
- fprintf( stderr, "libdvdread: opening VOB as file\n" );
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, -1, sizeof( dvd_file->title_devs ) );
- memset( dvd_file->title_fds, -1, sizeof( dvd_file->title_fds ) );
- dvd_file->filesize = 0;
-
- if( menu ) {
- int fd;
-
- if( title == 0 ) {
- sprintf( filename, "VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "VTS_%02i_0.VOB", title );
- }
- if( !findDVDFile( dvd, filename, full_path ) ) {
- free( dvd_file );
- return 0;
- }
-
- fd = open( full_path, O_RDONLY );
- if( fd < 0 ) {
- free( dvd_file );
- return 0;
- }
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ 0 ] = fd;
- dvd_file->title_devs[ 0 ] = dvdcss_open( full_path );
- dvdcss_title( dvd_file->title_devs[0], 0 );
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- } else {
- for( i = 0; i < 9; ++i ) {
-
- sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
- if( !findDVDFile( dvd, filename, full_path ) ) {
- break;
- }
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- break;
- }
-
- dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_fds[ i ] = open( full_path, O_RDONLY );
- dvd_file->title_devs[ i ] = dvdcss_open( full_path );
- dvdcss_title( dvd_file->title_devs[i], 0 );
- dvd_file->filesize += dvd_file->title_sizes[ i ];
- }
- if( !(dvd_file->title_sizes[ 0 ]) ) {
- free( dvd_file );
- return 0;
- }
- }
-
- return dvd_file;
-}
-
-dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
- dvd_read_domain_t domain )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
-
- switch( domain ) {
- case DVD_READ_INFO_FILE:
- if( titlenum == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
- }
- break;
- case DVD_READ_INFO_BACKUP_FILE:
- if( titlenum == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
- }
- break;
- case DVD_READ_MENU_VOBS:
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 1 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 1 );
- }
- break;
- case DVD_READ_TITLE_VOBS:
- if( titlenum == 0 ) return 0;
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 0 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 0 );
- }
- break;
- default:
- fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
- return 0;
- }
-
- if( dvd->isImageFile ) {
- return DVDOpenFileUDF( dvd, filename );
- } else {
- return DVDOpenFilePath( dvd, filename );
- }
-}
-
-void DVDCloseFile( dvd_file_t *dvd_file )
-{
- int i;
-
- if( dvd_file ) {
- if( !dvd_file->dvd->isImageFile ) {
- for( i = 0; i < 9; ++i ) {
- if( dvd_file->title_fds[ i ] >= 0 )
- {
- close( dvd_file->title_fds[ i ] );
- dvdcss_close( dvd_file->title_devs[i] );
- }
- }
- }
-
- free( dvd_file );
- dvd_file = 0;
- }
-}
-
-int64_t DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,
- int encrypted )
-{
- int ret;
-
- if( !device->dev ) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
-
- ret = dvdcss_seek( device->dev, (int) lb_number, DVDCSS_NOFLAGS );
- if( ret != (int) lb_number ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
-
- return (int64_t) ( dvdcss_read( device->dev, (char *) data,
- (int) block_count, encrypted )
- * (uint64_t) DVD_VIDEO_LB_LEN );
-}
-
-static int64_t DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, unsigned char *data )
-{
- return DVDReadLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, data, DVDCSS_READ_DECRYPT );
-}
-
-static int64_t DVDReadBlocksPath( dvd_file_t *dvd_file, size_t offset,
- size_t block_count, unsigned char *data )
-{
- int i;
- ssize_t ret, ret2;
- off64_t off;
-
- ret = 0;
- ret2 = 0;
- for( i = 0; i < 9; ++i ) {
- if( !dvd_file->title_sizes[ i ] ) return 0;
-
- if( offset < dvd_file->title_sizes[ i ] ) {
- if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data,
- block_count * DVD_VIDEO_LB_LEN );
- break;
- } else {
- size_t part1_size
- = ( dvd_file->title_sizes[ i ] - offset ) * DVD_VIDEO_LB_LEN;
- /* FIXME: Really needs to be a while loop.
- (This is only true if you try and read >1GB at a time) */
-
- /* Read part 1 */
- off = lseek64( dvd_file->title_fds[ i ],
- offset * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off != ( offset * (int64_t) DVD_VIDEO_LB_LEN ) ) {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = read( dvd_file->title_fds[ i ], data, part1_size );
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.
- also error from this read will not show in ret. */
-
- /* Read part 2 */
- lseek64( dvd_file->title_fds[ i + 1 ], (off64_t)0, SEEK_SET );
- ret2 = read( dvd_file->title_fds[ i + 1 ], data + part1_size,
- block_count * DVD_VIDEO_LB_LEN - part1_size );
- if( ret2 < 0 ) return ret2;
- break;
- }
- } else {
- offset -= dvd_file->title_sizes[ i ];
- }
- }
-
- return ( (int64_t) ret + (int64_t) ret2 );
-}
-
-/* These are broken for some cases reading more than 2Gb at a time. */
-ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, unsigned char *data )
-{
- int64_t ret;
-
- if( dvd_file->dvd->isImageFile ) {
- ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset,
- block_count, data );
- } else {
- ret = DVDReadBlocksPath( dvd_file, (size_t) offset,
- block_count, data );
- }
- if( ret <= 0 ) {
- return (ssize_t) ret;
- }
- {
- ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
- if( sret == 0 ) {
- fprintf(stderr, "libdvdread: DVDReadBlocks got %d bytes\n", (int)ret );
- }
- return sret;
- }
-}
-
-int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
-{
- if( dvd_file->dvd->isImageFile ) {
- dvd_file->seek_pos = (uint32_t) offset;
- return offset;
- } else {
- return (int32_t) ( lseek( dvd_file->title_fds[ 0 ],
- (off_t) offset, SEEK_SET ) );
- }
-}
-
-static ssize_t DVDReadBytesUDF( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
-{
- unsigned char *secbuf;
- unsigned int numsec, seek_sector, seek_byte;
- int64_t len;
-
- seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
- seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
-
- numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + 1;
- secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
- if( !secbuf ) {
- fprintf( stderr, "libdvdread: Can't allocate memory "
- "for file read!\n" );
- return 0;
- }
-
- len = DVDReadLBUDF( dvd_file->dvd, dvd_file->lb_start + seek_sector,
- numsec, secbuf, DVDCSS_NOFLAGS );
- if( len != numsec * (int64_t) DVD_VIDEO_LB_LEN ) {
- free( secbuf );
- return 0;
- }
-
- dvd_file->seek_pos += byte_size;
-
- memcpy( data, &(secbuf[ seek_byte ]), byte_size );
- free( secbuf );
-
- return byte_size;
-}
-
-static ssize_t DVDReadBytesPath( dvd_file_t *dvd_file, void *data,
- size_t byte_size )
-{
- return read( dvd_file->title_fds[ 0 ], data, byte_size );
-}
-
-ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
-{
- if( dvd_file->dvd->isImageFile ) {
- return DVDReadBytesUDF( dvd_file, data, byte_size );
- } else {
- return DVDReadBytesPath( dvd_file, data, byte_size );
- }
-}
-
-ssize_t DVDFileSize( dvd_file_t *dvd_file )
-{
- return dvd_file->filesize;
-}
-
-int64_t DVDReadVLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, struct iovec * vector,
- int encrypted )
-{
- int ret;
-
- if( !device->dev ) {
- fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
-
- ret = dvdcss_seek( device->dev, (int) lb_number, 0 );
- if( ret != (int) lb_number ) {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n",
- lb_number );
- return 0;
- }
-
- return (int64_t) ( dvdcss_readv( device->dev, vector,
- (int)block_count, encrypted )
- * (uint64_t) DVD_VIDEO_LB_LEN );
-}
-
-static int64_t DVDReadVBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, struct iovec *vector )
-{
- return DVDReadVLBUDF( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, vector, DVDCSS_READ_DECRYPT );
-}
-
-static int64_t DVDReadVBlocksPath( dvd_file_t *dvd_file, size_t offset,
- size_t block_count, struct iovec *vector )
-{
- int i;
- int ret, ret2;
- int off;
-
- ret = 0;
- ret2 = 0;
- for( i = 0 ; i < 9 ; ++i )
- {
- if( !dvd_file->title_sizes[ i ] )
- {
- return 0;
- }
-
- if( offset < dvd_file->title_sizes[ i ] )
- {
- if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] )
- {
- off = dvdcss_seek( dvd_file->title_devs[ i ],
- (int)offset, 0 );
- if( off != (int)offset )
- {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
- (int)block_count, DVDCSS_READ_DECRYPT );
- break;
- }
- else
- {
- int part1_size = dvd_file->title_sizes[ i ] - offset;
- /* FIXME: Really needs to be a while loop.
- (This is only true if you try and read >1GB at a time) */
-
- /* Read part 1 */
- off = dvdcss_seek( dvd_file->title_devs[ i ], offset, 0 );
- if( off != offset )
- {
- fprintf( stderr, "libdvdread: Can't seek to block %d\n",
- offset );
- return 0;
- }
- ret = dvdcss_readv( dvd_file->title_devs[ i ], vector,
- part1_size, DVDCSS_READ_DECRYPT );
-
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.
- also error from this read will not show in ret. */
-
- /* Read part 2 */
- dvdcss_seek( dvd_file->title_devs[ i + 1 ], 0, 0 );
- ret2 = dvdcss_readv( dvd_file->title_devs[ i + 1 ],
- vector + part1_size, (int)(block_count - part1_size),
- DVDCSS_READ_DECRYPT );
- if( ret2 < 0 ) return ret2;
- break;
- }
- }
- else
- {
- offset -= dvd_file->title_sizes[ i ];
- }
- }
-
- return ( ret + ret2 ) * (int64_t) DVD_VIDEO_LB_LEN;
-}
-
-
-ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, struct iovec * vector )
-{
- int64_t ret;
-
- if( dvd_file->dvd->isImageFile )
- {
- ret = DVDReadVBlocksUDF( dvd_file, (uint32_t)offset,
- block_count, vector );
- }
- else
- {
- ret = DVDReadVBlocksPath( dvd_file, (size_t) offset,
- block_count, vector );
- }
- if( ret <= 0 )
- {
- return (ssize_t) ret;
- }
-
- {
- ssize_t sret = (ssize_t) (ret / (int64_t)DVD_VIDEO_LB_LEN );
- if( sret == 0 )
- {
- fprintf(stderr, "libdvdread: DVDReadVBlocks got %d bytes\n", (int)ret );
- }
- return sret;
- }
-
-}
-
+++ /dev/null
-/*****************************************************************************
- * dvdread.h: DVD reading library, exported functions.
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: dvdread.h,v 1.1 2001/11/25 05:04:38 stef Exp $
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- *
- * 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, USA.
- *****************************************************************************/
-
-ssize_t DVDReadVBlocks( dvd_file_t *dvd_file, int offset,
- size_t block_count, struct iovec * vector );
-/* include/defs.h.in. Generated automatically from configure.in by autoheader. */
+/* include/defs.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* Define if using alloca.c. */
#undef C_ALLOCA
* dummy_dvdcss.h: Dummy libdvdcss header.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: dummy_dvdcss.h,v 1.6 2002/01/07 02:12:29 sam Exp $
+ * $Id: dummy_dvdcss.h,v 1.7 2002/01/23 03:15:31 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* Pointers which will be filled either with dummy_dvdcss functions or
* with the dlopen()ed ones.
*****************************************************************************/
+#define ____dvdcss_open dvdcss_open
+#define ____dvdcss_close dvdcss_close
+#define ____dvdcss_title dvdcss_title
+#define ____dvdcss_seek dvdcss_seek
+#define ____dvdcss_read dvdcss_read
+#define ____dvdcss_readv dvdcss_readv
+#define ____dvdcss_error dvdcss_error
+
dvdcss_handle (* ____dvdcss_open ) ( char * );
int (* ____dvdcss_close ) ( dvdcss_handle );
int (* ____dvdcss_title ) ( dvdcss_handle, int );
int (* ____dvdcss_readv ) ( dvdcss_handle, void *, int, int );
char * (* ____dvdcss_error ) ( dvdcss_handle );
-#define ____dvdcss_open dvdcss_open
-#define ____dvdcss_close dvdcss_close
-#define ____dvdcss_title dvdcss_title
-#define ____dvdcss_seek dvdcss_seek
-#define ____dvdcss_read dvdcss_read
-#define ____dvdcss_readv dvdcss_readv
-#define ____dvdcss_error dvdcss_error
* dvdread.c : DvdRead input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: dvdread.c,v 1.7 2002/01/08 23:34:06 stef Exp $
+ * $Id: dvdread.c,v 1.8 2002/01/23 03:15:31 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#include <videolan/vlc.h>
-#ifdef GOD_DAMN_DMCA
-# include <dlfcn.h>
-# include "dummy_dvdcss.h"
-#endif
-
/*****************************************************************************
* Capabilities defined in the other files.
*****************************************************************************/
void _M( input_getfunctions )( function_list_t * p_function_list );
-/*****************************************************************************
- * Local prototypes.
- *****************************************************************************/
-#ifdef GOD_DAMN_DMCA
-static void *p_libdvdcss;
-static void ProbeLibDVDCSS ( void );
-static void UnprobeLibDVDCSS( void );
-#endif
-
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_STOP
MODULE_INIT_START
-#ifdef GOD_DAMN_DMCA
- SET_DESCRIPTION( "DVDRead input module, uses libdvdcss if present" )
- ADD_CAPABILITY( INPUT, 70 )
-#else
- SET_DESCRIPTION( "DVDRead input module, linked with libdvdcss" )
+ SET_DESCRIPTION( "DVDRead input module" )
ADD_CAPABILITY( INPUT, 110 )
-#endif
ADD_SHORTCUT( "dvdread" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
_M( input_getfunctions )( &p_module->p_functions->input );
-#ifdef GOD_DAMN_DMCA
- ProbeLibDVDCSS();
-#endif
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
-#ifdef GOD_DAMN_DMCA
- UnprobeLibDVDCSS();
-#endif
MODULE_DEACTIVATE_STOP
-
-
-/* Following functions are local */
-
-#ifdef GOD_DAMN_DMCA
-/*****************************************************************************
- * ProbeLibDVDCSS: look for a libdvdcss object.
- *****************************************************************************
- * This functions looks for libdvdcss, using dlopen(), and fills function
- * pointers with what it finds. On failure, uses the dummy libdvdcss
- * replacement provided by vlc.
- *****************************************************************************/
-static void ProbeLibDVDCSS( void )
-{
- char *pp_filelist[4] = { "libdvdcss.so.0",
- "./libdvdcss.so.0",
- "./lib/libdvdcss.so.0",
- NULL };
- char **pp_file = pp_filelist;
-
- /* Try to open the dynamic object */
- do
- {
- p_libdvdcss = dlopen( *pp_file, RTLD_LAZY );
- if( p_libdvdcss != NULL )
- {
- intf_WarnMsg( 2, "module: builtin module `dvd' found libdvdcss "
- "in `%s'", *pp_file );
- break;
- }
- pp_file++;
-
- } while( *pp_file != NULL );
-
- /* If libdvdcss.so was found, check that it's valid */
- if( p_libdvdcss == NULL )
- {
- intf_ErrMsg( "dvd warning: libdvdcss.so.0 not present" );
- }
- else
- {
- /* Check for libdvdcss 0.0.1 */
- if( dlsym( p_libdvdcss, "dvdcss_crack" ) != NULL )
- {
- intf_ErrMsg( "dvd warning: libdvdcss.so.0 has deprecated symbol "
- "dvdcss_crack(), please upgrade" );
- dlclose( p_libdvdcss );
- p_libdvdcss = NULL;
- }
- else
- {
- dvdcss_open = dlsym( p_libdvdcss, "dvdcss_open" );
- dvdcss_close = dlsym( p_libdvdcss, "dvdcss_close" );
- dvdcss_title = dlsym( p_libdvdcss, "dvdcss_title" );
- dvdcss_seek = dlsym( p_libdvdcss, "dvdcss_seek" );
- dvdcss_read = dlsym( p_libdvdcss, "dvdcss_read" );
- dvdcss_readv = dlsym( p_libdvdcss, "dvdcss_readv" );
- dvdcss_error = dlsym( p_libdvdcss, "dvdcss_error" );
-
- if( dvdcss_open == NULL || dvdcss_close == NULL
- || dvdcss_title == NULL || dvdcss_seek == NULL
- || dvdcss_read == NULL || dvdcss_readv == NULL
- || dvdcss_error == NULL )
- {
- intf_ErrMsg( "dvd warning: missing symbols in libdvdcss.so.0, "
- "please upgrade libdvdcss or vlc" );
- dlclose( p_libdvdcss );
- p_libdvdcss = NULL;
- }
- }
- }
-
- /* If libdvdcss was not found or was not valid, use the dummy
- * replacement functions. */
- if( p_libdvdcss == NULL )
- {
- intf_ErrMsg( "dvd warning: no valid libdvdcss found, "
- "I will only play unencrypted DVDs" );
- intf_ErrMsg( "dvd warning: get libdvdcss at "
- "http://www.videolan.org/libdvdcss/" );
-
- dvdcss_open = dummy_dvdcss_open;
- dvdcss_close = dummy_dvdcss_close;
- dvdcss_title = dummy_dvdcss_title;
- dvdcss_seek = dummy_dvdcss_seek;
- dvdcss_read = dummy_dvdcss_read;
- dvdcss_readv = dummy_dvdcss_readv;
- dvdcss_error = dummy_dvdcss_error;
- }
-}
-
-/*****************************************************************************
- * UnprobeLibDVDCSS: free resources allocated by ProbeLibDVDCSS, if any.
- *****************************************************************************/
-static void UnprobeLibDVDCSS( void )
-{
- if( p_libdvdcss != NULL )
- {
- dlclose( p_libdvdcss );
- p_libdvdcss = NULL;
- }
-}
-#endif
-
* input_dvdread.h: thread structure of the DVD plugin
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dvdread.h,v 1.3 2001/12/29 22:22:01 massiot Exp $
+ * $Id: input_dvdread.h,v 1.4 2002/01/23 03:15:31 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
#include "dvd_udf.h"
#include "nav_read.h"
#include "nav_print.h"
-#include "videolan/dvdread.h"
/* Logical block size for DVD-VIDEO */
#define LB2OFF(x) ((off_t)(x) * (off_t)(DVD_VIDEO_LB_LEN))