summaryrefslogtreecommitdiffstats
path: root/dvdread/dvd_reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvdread/dvd_reader.c')
-rw-r--r--dvdread/dvd_reader.c218
1 files changed, 207 insertions, 11 deletions
diff --git a/dvdread/dvd_reader.c b/dvdread/dvd_reader.c
index 4ba75e9a4e..a96a0903d8 100644
--- a/dvdread/dvd_reader.c
+++ b/dvdread/dvd_reader.c
@@ -413,17 +413,21 @@ static char *sun_block2char( const char *path )
#if defined(SYS_BSD)
/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r
+ update: FreeBSD and DragonFly no longer uses the prefix so don't add it.
+
OpenBSD /dev/rcd0c, it needs to be the raw device
NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others
Darwin /dev/rdisk0, it needs to be the raw device
- BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do) */
+ BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do)
+
+ returns a string allocated with strdup which should be free()'d when
+ no longer used.
+*/
static char *bsd_block2char( const char *path )
-#if defined(__FreeBSD__)
{
- return (char *) strdup( path );
-}
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+ return (char *) strdup( path );
#else
-{
char *new_path;
/* If it doesn't start with "/dev/" or does start with "/dev/r" exit */
@@ -436,8 +440,8 @@ static char *bsd_block2char( const char *path )
strcat( new_path, path + strlen( "/dev/" ) );
return new_path;
+#endif /* __FreeBSD__ || __DragonFly__ */
}
-#endif /* __FreeBSD__ */
#endif
@@ -486,18 +490,21 @@ dvd_reader_t *DVDOpen( const char *path )
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.
*/
+ dvd_reader_t *dvd = NULL;
#if defined(__sun)
- return DVDOpenImageFile( sun_block2char( path ), have_css );
+ dev_name = sun_block2char( path );
#elif defined(SYS_BSD)
- return DVDOpenImageFile( bsd_block2char( path ), have_css );
+ dev_name = bsd_block2char( path );
#else
- return DVDOpenImageFile( path, have_css );
+ dev_name = strdup( path );
#endif
-
+ dvd = DVDOpenImageFile( dev_name, have_css );
+ free( dev_name );
+
+ return dvd;
} else if( S_ISDIR( fileinfo.st_mode ) ) {
dvd_reader_t *auth_drive = 0;
char *path_copy;
@@ -1020,6 +1027,195 @@ void DVDCloseFile( dvd_file_t *dvd_file )
}
}
+static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title,
+ int menu, dvd_stat_t *statbuf)
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ uint32_t size;
+ off_t tot_size;
+ off_t parts_size[9];
+ int nr_parts = 0;
+ int n;
+
+ if( title == 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
+ }
+ if(!UDFFindFile( dvd, filename, &size )) {
+ return -1;
+ }
+ tot_size = size;
+ nr_parts = 1;
+ parts_size[0] = size;
+
+ if( !menu ) {
+ int cur;
+
+ for( cur = 2; cur < 10; cur++ ) {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
+ if( !UDFFindFile( dvd, filename, &size ) ) {
+ break;
+ }
+ parts_size[nr_parts] = size;
+ tot_size += size;
+ nr_parts++;
+ }
+ }
+
+ statbuf->size = tot_size;
+ statbuf->nr_parts = nr_parts;
+ for(n = 0; n < nr_parts; n++) {
+ statbuf->parts_size[n] = parts_size[n];
+ }
+ return 0;
+}
+
+
+static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
+ int menu, dvd_stat_t *statbuf )
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char full_path[ PATH_MAX + 1 ];
+ struct stat fileinfo;
+ off_t tot_size;
+ off_t parts_size[9];
+ int nr_parts = 0;
+ int n;
+
+
+
+ if( title == 0 ) {
+ sprintf( filename, "VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
+ }
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ return -1;
+ }
+
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >= 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ return -1;
+ }
+
+
+ tot_size = fileinfo.st_size;
+ nr_parts = 1;
+ parts_size[0] = fileinfo.st_size;
+
+ if( !menu ) {
+ int cur;
+
+ for( cur = 2; cur < 10; cur++ ) {
+
+ sprintf( filename, "VTS_%02d_%d.VOB", title, cur );
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ break;
+ }
+
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >= 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ break;
+ }
+
+ parts_size[nr_parts] = fileinfo.st_size;
+ tot_size += parts_size[nr_parts];
+ nr_parts++;
+ }
+ }
+
+ statbuf->size = tot_size;
+ statbuf->nr_parts = nr_parts;
+ for(n = 0; n < nr_parts; n++) {
+ statbuf->parts_size[n] = parts_size[n];
+ }
+ return 0;
+}
+
+
+int DVDFileStat(dvd_reader_t *dvd, int titlenum,
+ dvd_read_domain_t domain, dvd_stat_t *statbuf)
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char full_path[ PATH_MAX + 1 ];
+ struct stat fileinfo;
+ uint32_t size;
+
+ /* Check arguments. */
+ if( dvd == NULL || titlenum < 0 ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ 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 DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
+ } else {
+ return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
+ }
+ break;
+ case DVD_READ_TITLE_VOBS:
+ if( titlenum == 0 ) {
+ return -1;
+ }
+ if( dvd->isImageFile ) {
+ return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
+ } else {
+ return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
+ }
+ break;
+ default:
+ if(dvd->verbose >= 1) {
+ fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );
+ }
+ errno = EINVAL;
+ return -1;
+ }
+
+ if( dvd->isImageFile ) {
+ if( UDFFindFile( dvd, filename, &size ) ) {
+ statbuf->size = size;
+ statbuf->nr_parts = 1;
+ statbuf->parts_size[0] = size;
+ return 0;
+ }
+ } else {
+ if( findDVDFile( dvd, filename, full_path ) ) {
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >= 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ } else {
+ statbuf->size = fileinfo.st_size;
+ statbuf->nr_parts = 1;
+ statbuf->parts_size[0] = statbuf->size;
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
/**
* Internal, but used from dvd_udf.c
*