Пример #1
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 )
    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;
}
Пример #2
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);
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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 ];
  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;
}
Пример #8
0
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;
}