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 ) strcpy( filename, "VIDEO_TS.VOB" ); else sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); if( !findDVDFile( dvd, filename, full_path ) ) return -1; if( mythfile_stat( full_path, &fileinfo ) < 0 ) { 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( mythfile_stat( full_path, &fileinfo ) < 0 ) { 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 mythfile_stat_fd(int fileID, struct stat *buf) { LOG(VB_FILE, LOG_DEBUG, QString("mythfile_stat_fd(%1, %2)") .arg(fileID).arg((long long)buf)); m_fileWrapperLock.lockForRead(); if (!m_filenames.contains(fileID)) { m_fileWrapperLock.unlock(); return -1; } QString filename = m_filenames[fileID]; m_fileWrapperLock.unlock(); return mythfile_stat(filename.toLocal8Bit().constData(), buf); }
/** * 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; dvd_input_t dev; /* Get the full path of the file. */ if( !findDVDFile( dvd, filename, full_path ) ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:findDVDFile %s failed\n", filename ); return NULL; } dev = dvdinput_open( full_path ); if( !dev ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvdinput_open %s failed\n", full_path ); return NULL; } dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvd_file malloc failed\n" ); dvdinput_close(dev); return NULL; } 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, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; if( mythfile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); free( dvd_file ); dvdinput_close(dev); return NULL; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvd_file->filesize = dvd_file->title_sizes[ 0 ]; return dvd_file; }
int mythfile_open(const char *pathname, int flags) { LOG(VB_FILE, LOG_DEBUG, QString("mythfile_open('%1', %2)") .arg(pathname).arg(flags)); struct stat fileinfo; if (mythfile_stat(pathname, &fileinfo)) return -1; if (S_ISDIR( fileinfo.st_mode )) // libmythdvdnav tries to open() a dir return errno = EISDIR, -1; int fileID = -1; if (strncmp(pathname, "myth://", 7)) { int lfd = open(pathname, flags); if (lfd < 0) return -1; m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); m_localfiles[fileID] = lfd; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } else { RingBuffer *rb = NULL; RemoteFile *rf = NULL; if ((fileinfo.st_size < 512) && (fileinfo.st_mtime < (time(NULL) - 300))) { if (flags & O_WRONLY) rf = new RemoteFile(pathname, true, false); // Writeable else rf = new RemoteFile(pathname, false, true); // Read-Only if (!rf) return -1; } else { if (flags & O_WRONLY) rb = RingBuffer::Create( pathname, true, false, RingBuffer::kDefaultOpenTimeout, true); // Writeable else rb = RingBuffer::Create( pathname, false, true, RingBuffer::kDefaultOpenTimeout, true); // Read-Only if (!rb) return -1; rb->Start(); } m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); if (rf) m_remotefiles[fileID] = rf; else if (rb) m_ringbuffers[fileID] = rb; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } m_callbackLock.lock(); if (!m_fileOpenCallbacks.isEmpty()) { QString path(pathname); QHashIterator<QString,Callback> it(m_fileOpenCallbacks); while (it.hasNext()) { it.next(); if (path.startsWith(it.key())) it.value().m_callback(it.value().m_object); } } m_callbackLock.unlock(); return fileID; }
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; dvd_file = calloc( 1, sizeof( dvd_file_t ) ); if( !dvd_file ) return NULL; dvd_file->dvd = dvd; /*Hack*/ dvd_file->css_title = title << 1 | menu; if( menu ) { dvd_input_t dev; if( title == 0 ) { strcpy( filename, "VIDEO_TS.VOB" ); } else { sprintf( filename, "VTS_%02i_0.VOB", title ); } if( !findDVDFile( dvd, filename, full_path ) ) { free( dvd_file ); return NULL; } dev = dvdinput_open( full_path, NULL, NULL ); if( dev == NULL ) { free( dvd_file ); return NULL; } if( mythfile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); dvdinput_close(dev); free( dvd_file ); return NULL; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvdinput_title( dvd_file->title_devs[0], 0); dvd_file->filesize = dvd_file->title_sizes[ 0 ]; } else { int i; for( i = 0; i < TITLES_MAX; ++i ) { sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 ); if( !findDVDFile( dvd, filename, full_path ) ) { break; } if( mythfile_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_devs[ i ] = dvdinput_open( full_path, NULL, NULL ); dvdinput_title( dvd_file->title_devs[ i ], 0 ); dvd_file->filesize += dvd_file->title_sizes[ i ]; } if( !dvd_file->title_devs[ 0 ] ) { free( dvd_file ); return NULL; } } return dvd_file; }
static dvd_reader_t *DVDOpenCommon( const char *ppath, void *stream, dvd_reader_stream_cb *stream_cb ) { struct stat fileinfo; int ret, have_css, retval, cdir = -1; dvd_reader_t *ret_val = NULL; char *dev_name = NULL; char *path = NULL, *new_path = NULL, *path_copy = NULL; #if defined(_WIN32) || defined(__OS2__) int len; #endif /* Try to open DVD using stream_cb functions */ if( stream != NULL && stream_cb != NULL ) { have_css = dvdinput_setup( "" ); return DVDOpenImageFile( NULL, stream, stream_cb, have_css ); } if( ppath == NULL ) goto DVDOpen_error; path = strdup(ppath); if( path == NULL ) goto DVDOpen_error; /* Try to open libdvdcss or fall back to standard functions */ have_css = dvdinput_setup(path); #if defined(_WIN32) || defined(__OS2__) /* Strip off the trailing \ if it is not a drive */ len = strlen(path); if ((len > 1) && (path[len - 1] == '\\') && (path[len - 2] != ':')) { path[len-1] = '\0'; } #endif ret = mythfile_stat( path, &fileinfo ); if( ret < 0 ) { /* maybe "host:port" url? try opening it with acCeSS library */ if( strchr(path,':') ) { ret_val = DVDOpenImageFile( path, NULL, NULL, have_css ); free(path); return ret_val; } /* If we can't stat the file, give up */ fprintf( stderr, "libdvdread: Can't stat %s\n", path ); perror(""); goto DVDOpen_error; } /* 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. */ dvd_reader_t *dvd = NULL; #if defined(__sun) dev_name = sun_block2char( path ); #elif defined(SYS_BSD) dev_name = bsd_block2char( path ); #else dev_name = strdup( path ); #endif if(!dev_name) goto DVDOpen_error; dvd = DVDOpenImageFile( dev_name, NULL, NULL, have_css ); free( dev_name ); free(path); return dvd; } else if( S_ISDIR( fileinfo.st_mode ) ) { dvd_reader_t *auth_drive = 0; #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 ) ) ) goto DVDOpen_error; #ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */ /* Also WIN32 does not have symlinks, so we don't need this bit of code. */ /* Resolve any symlinks and get the absolute dir name. */ if (!strncmp(path, "myth://", 7)) dev_name = strdup( path ); else { if( ( cdir = open( ".", O_RDONLY ) ) >= 0 ) { if( chdir( path_copy ) == -1 ) { goto DVDOpen_error; } new_path = malloc(PATH_MAX+1); if(!new_path) { goto DVDOpen_error; } if( getcwd( new_path, PATH_MAX ) == NULL ) { goto DVDOpen_error; } retval = fchdir( cdir ); close( cdir ); cdir = -1; if( retval == -1 ) { goto DVDOpen_error; } free(path_copy); path_copy = new_path; new_path = NULL; } } #endif /** * If we're being asked to open a directory, check if that directory * is the mount point for a DVD-ROM which we can use instead. */ if( strlen( path_copy ) > 1 ) { if( path_copy[ strlen( path_copy ) - 1 ] == '/' ) { path_copy[ strlen( path_copy ) - 1 ] = '\0'; } } #if defined(_WIN32) || defined(__OS2__) if( strlen( path_copy ) > 9 ) { if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]), "\\video_ts")) path_copy[ strlen( path_copy ) - (9-1) ] = '\0'; } #endif if( strlen( path_copy ) > 9 ) { if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]), "/video_ts" ) ) { path_copy[ strlen( path_copy ) - 9 ] = '\0'; } } if(path_copy[0] == '\0') { free( path_copy ); if( !(path_copy = strdup( "/" ) ) ) goto DVDOpen_error; } #if defined(__APPLE__) struct statfs s[128]; int r = getfsstat(NULL, 0, MNT_NOWAIT); if (r > 0) { if (r > 128) r = 128; r = getfsstat(s, r * sizeof(s[0]), MNT_NOWAIT); int i; for (i=0; i<r; i++) { if (!strcmp(path_copy, s[i].f_mntonname)) { dev_name = bsd_block2char(s[i].f_mntfromname); fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s for CSS authentication\n", dev_name, s[i].f_mntonname); auth_drive = DVDOpenImageFile( dev_name, NULL, NULL, have_css ); break; } } } #elif defined(SYS_BSD) if( ( fe = getfsfile( path_copy ) ) ) { 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, NULL, NULL, have_css ); } #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 ) ) { 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, NULL, NULL, have_css ); break; } } fclose( mntfile ); } #elif defined(__linux__) mntfile = fopen( _PATH_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, NULL, NULL, have_css ); dev_name = strdup(me->mnt_fsname); break; } } fclose( mntfile ); } #elif defined(_WIN32) || defined(__OS2__) #ifdef __OS2__ /* Use DVDOpenImageFile() only if it is a drive */ if(isalpha(path[0]) && path[1] == ':' && ( !path[2] || ((path[2] == '\\' || path[2] == '/') && !path[3]))) #endif auth_drive = DVDOpenImageFile( path, NULL, NULL, have_css ); #endif #if !defined(_WIN32) && !defined(__OS2__) if( !dev_name ) { fprintf( stderr, "libdvdread: Couldn't find device name.\n" ); } else if( !auth_drive ) { fprintf( stderr, "libdvdread: Device %s inaccessible, " "CSS authentication not available.\n", dev_name ); } #else if( !auth_drive ) { fprintf( stderr, "libdvdread: Device %s inaccessible, " "CSS authentication not available.\n", path ); } #endif free( dev_name ); dev_name = NULL; free( path_copy ); path_copy = NULL; /** * If we've opened a drive, just use that. */ if( auth_drive ) { free(path); return auth_drive; } /** * Otherwise, we now try to open the directory tree instead. */ ret_val = DVDOpenPath( path ); free( path ); return ret_val; } DVDOpen_error: /* If it's none of the above, screw it. */ fprintf( stderr, "libdvdread: Could not open %s\n", path ); free( path ); free( path_copy ); if ( cdir >= 0 ) close( cdir ); free( new_path ); return NULL; }
int DVDFileStat( dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain, dvd_stat_t *statbuf ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; 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 ) strcpy( 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 ) strcpy( 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: 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 { char full_path[ PATH_MAX + 1 ]; if( findDVDFile( dvd, filename, full_path ) ) { if( mythfile_stat( full_path, &fileinfo ) < 0 ) 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; }
int mythfile_open(const char *pathname, int flags) { VERBOSE(VB_FILE+VB_EXTRA, QString("mythfile_open('%1', %2)").arg(pathname).arg(flags)); struct stat fileinfo; if (mythfile_stat(pathname, &fileinfo)) return -1; if (S_ISDIR( fileinfo.st_mode )) // libmythdvdnav tries to open() a dir return -1; int fileID = -1; if (strncmp(pathname, "myth://", 7)) { int lfd = open(pathname, flags); if (lfd < 0) return -1; m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); m_localfiles[fileID] = lfd; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } else { RingBuffer *rb = NULL; RemoteFile *rf = NULL; if ((fileinfo.st_size < 51200) && (fileinfo.st_mtime < (time(NULL) - 300))) { if (flags & O_WRONLY) rf = new RemoteFile(pathname, true, false); // Writeable else rf = new RemoteFile(pathname, false, true); // Read-Only if (!rf) return -1; } else { if (flags & O_WRONLY) rb = RingBuffer::Create( pathname, true, false, RingBuffer::kDefaultOpenTimeout, true); // Writeable else rb = RingBuffer::Create( pathname, false, true, RingBuffer::kDefaultOpenTimeout, true); // Read-Only if (!rb) return -1; rb->Start(); } m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); if (rf) m_remotefiles[fileID] = rf; else if (rb) m_ringbuffers[fileID] = rb; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } return fileID; }