304
306
#if defined(SYS_BSD)
305
307
/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recommended to _not_ use r
306
update: FreeBSD and DragonFly no longer uses the prefix so don't add it.
307
308
OpenBSD /dev/rcd0c, it needs to be the raw device
308
309
NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others
309
310
Darwin /dev/rdisk0, it needs to be the raw device
310
BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do)
311
returns a string allocated with strdup. It should be freed when no longer
311
BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do) */
313
312
static char *bsd_block2char( const char *path )
315
#if defined(__FreeBSD__) || defined(__DragonFly__)
316
return (char *) strdup( path );
320
316
/* If it doesn't start with "/dev/" or does start with "/dev/r" exit */
413
409
/* XXX: We should scream real loud here. */
414
if( !(path_copy = strdup( path ) ) )
410
if( !(path_copy = strdup( path ) ) ) {
417
415
#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */
418
416
/* Also WIN32 does not have symlinks, so we don't need this bit of code. */
420
418
/* Resolve any symlinks and get the absolute dir name. */
422
if( ( cdir = open( ".", O_RDONLY ) ) >= 0 ) {
423
if( chdir( path_copy ) == -1 ) {
421
int cdir = open( ".", O_RDONLY );
426
425
new_path = malloc(PATH_MAX+1);
430
if( getcwd( new_path, PATH_MAX ) == NULL ) {
433
retval = fchdir( cdir );
430
getcwd(new_path, PATH_MAX );
439
path_copy = new_path;
434
path_copy = new_path;
906
static int DVDFileStatVOBUDF( dvd_reader_t *dvd, int title,
907
int menu, dvd_stat_t *statbuf )
909
char filename[ MAX_UDF_FILE_NAME_LEN ];
912
off_t parts_size[ 9 ];
917
sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
919
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
921
if( !UDFFindFile( dvd, filename, &size ) )
926
parts_size[ 0 ] = size;
931
for( cur = 2; cur < 10; cur++ ) {
932
sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
933
if( !UDFFindFile( dvd, filename, &size ) )
936
parts_size[ nr_parts ] = size;
942
statbuf->size = tot_size;
943
statbuf->nr_parts = nr_parts;
944
for( n = 0; n < nr_parts; n++ )
945
statbuf->parts_size[ n ] = parts_size[ n ];
951
static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
952
int menu, dvd_stat_t *statbuf )
954
char filename[ MAX_UDF_FILE_NAME_LEN ];
955
char full_path[ PATH_MAX + 1 ];
956
struct stat fileinfo;
958
off_t parts_size[ 9 ];
963
sprintf( filename, "VIDEO_TS.VOB" );
965
sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
967
if( !findDVDFile( dvd, filename, full_path ) )
970
if( stat( full_path, &fileinfo ) < 0 ) {
971
fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
975
tot_size = fileinfo.st_size;
977
parts_size[ 0 ] = fileinfo.st_size;
981
for( cur = 2; cur < 10; cur++ ) {
982
sprintf( filename, "VTS_%02d_%d.VOB", title, cur );
983
if( !findDVDFile( dvd, filename, full_path ) )
986
if( stat( full_path, &fileinfo ) < 0 ) {
987
fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
991
parts_size[ nr_parts ] = fileinfo.st_size;
992
tot_size += parts_size[ nr_parts ];
997
statbuf->size = tot_size;
998
statbuf->nr_parts = nr_parts;
999
for( n = 0; n < nr_parts; n++ )
1000
statbuf->parts_size[ n ] = parts_size[ n ];
1006
int DVDFileStat( dvd_reader_t *dvd, int titlenum,
1007
dvd_read_domain_t domain, dvd_stat_t *statbuf )
1009
char filename[ MAX_UDF_FILE_NAME_LEN ];
1010
char full_path[ PATH_MAX + 1 ];
1011
struct stat fileinfo;
1014
/* Check arguments. */
1015
if( dvd == NULL || titlenum < 0 ) {
1021
case DVD_READ_INFO_FILE:
1023
sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
1025
sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
1028
case DVD_READ_INFO_BACKUP_FILE:
1030
sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
1032
sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
1035
case DVD_READ_MENU_VOBS:
1036
if( dvd->isImageFile )
1037
return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
1039
return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
1042
case DVD_READ_TITLE_VOBS:
1046
if( dvd->isImageFile )
1047
return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
1049
return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
1053
fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );
1058
if( dvd->isImageFile ) {
1059
if( UDFFindFile( dvd, filename, &size ) ) {
1060
statbuf->size = size;
1061
statbuf->nr_parts = 1;
1062
statbuf->parts_size[ 0 ] = size;
1066
if( findDVDFile( dvd, filename, full_path ) ) {
1067
if( stat( full_path, &fileinfo ) < 0 )
1068
fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
1070
statbuf->size = fileinfo.st_size;
1071
statbuf->nr_parts = 1;
1072
statbuf->parts_size[ 0 ] = statbuf->size;
1080
892
/* Internal, but used from dvd_udf.c */
1081
893
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
1082
894
size_t block_count, unsigned char *data,