Пример #1
0
dvd_reader_t *DVDOpen( const char *path )
{
  struct stat fileinfo;
  int ret, have_css;
  char *dev_name = NULL;
  int internal_errno = 0;
  int verbose;

  if( path == NULL ) {
    errno = EINVAL;
    return NULL;
  }
  
  verbose = get_verbose();

#ifdef WIN32
  /* Stat doesn't work on devices under mingwin/cygwin. */
  if( path[0] && path[1] == ':' && path[2] == '\0' )
    {
      /* Don't try to stat the file */
      fileinfo.st_mode = S_IFBLK;
    }
  else
#endif
    {
      ret = stat( path, &fileinfo );
      if( ret < 0 ) {
        int tmp_errno = errno;
        /* If we can't stat the file, give up */
        if(verbose >= 1) {
          fprintf( stderr, "libdvdread: Can't stat '%s': %s\n",
                   path, strerror(errno));
        }
        errno = tmp_errno;
        return NULL;
      }
    }

  /* Try to open libdvdcss or fall back to standard functions */
  have_css = dvdinput_setup();

  /* 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
    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;
#if defined(SYS_BSD)
    struct fstab* fe;
#elif defined(__sun) || defined(__linux__) || defined(__CYGWIN__)
    FILE *mntfile;
#endif

    /* XXX: We should scream real loud here. */
    if( !(path_copy = strdup( path ) ) ) return 0;

#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */
    /* Resolve any symlinks and get the absolut dir name. */
    {
      char *new_path;
      char *current_path;

      current_path = malloc(PATH_MAX);
      if(current_path) {
        if(!getcwd(current_path, PATH_MAX)) {
          free(current_path);
          current_path = NULL;
        }
      }
      if(current_path) {
        chdir( path_copy );
        new_path = malloc(PATH_MAX);
        if(new_path) {
          if(!getcwd(new_path, PATH_MAX )) {
            free(new_path);
            new_path = NULL;
          }
        }

        chdir(current_path);
        free(current_path);
        if( new_path ) {
          free( path_copy );
          path_copy = new_path;
        }
      }
    }
#endif
        
    /**
     * 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_copy[ 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(path_copy[0] == '\0') {
          path_copy[0] = '/';
          path_copy[1] = '\0';
        }
      }
    }

#if defined(SYS_BSD)
    if( ( fe = getfsfile( path_copy ) ) ) {
      dev_name = bsd_block2char( fe->fs_spec );
      if(verbose >= 1) {
        fprintf( stderr,
                 "libdvdread: Attempting to use device %s"
                 " mounted on %s%s\n",
                 dev_name,
                 fe->fs_file,
                 have_css ? " for CSS authentication" : "");
      }
      auth_drive = DVDOpenImageFile( dev_name, have_css );
      if(!auth_drive) {
        internal_errno = errno;
      }
    }
#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 );
          if(verbose >= 1) {
            fprintf( stderr, 
                     "libdvdread: Attempting to use device %s"
                     " mounted on %s%s\n",
                     dev_name,
                     mp.mnt_mountp,
                     have_css ? " for CSS authentication" : "");
          }
          auth_drive = DVDOpenImageFile( dev_name, have_css );
          if(!auth_drive) {
            internal_errno = errno;
          }
          break;
        }
      }
      fclose( mntfile );
    }
#elif defined(__linux__) || defined(__CYGWIN__)
    mntfile = fopen( MOUNTED, "r" );
    if( mntfile ) {
      struct mntent *me;
 
      while( ( me = getmntent( mntfile ) ) ) {
        if( !strcmp( me->mnt_dir, path_copy ) ) {
          if(verbose >= 1) {
            fprintf( stderr, 
                     "libdvdread: Attempting to use device %s"
                     " mounted on %s%s\n",
                     me->mnt_fsname,
                     me->mnt_dir,
                     have_css ? " for CSS authentication" : "");
          }
          auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css );
          if(!auth_drive) {
            internal_errno = errno;
          }
          dev_name = strdup(me->mnt_fsname);
          break;
        }
      }
      fclose( mntfile );
    }
#elif defined(__MINGW32__)
    dev_name = strdup(path);
    auth_drive = DVDOpenImageFile( path, have_css );
#endif
    if( !dev_name ) {
      if(verbose >= 1) {
        fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
      }
    } else if( !auth_drive ) {
      if(verbose >= 1) {
        fprintf( stderr, "libdvdread: Device %s inaccessible%s: %s\n",
                 dev_name,
                 have_css ? ", CSS authentication not available" : "",
                 strerror(internal_errno));
      }
    }

    free( dev_name );
    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.
     */
    return DVDOpenPath( path );
  }

  /* If it's none of the above, screw it. */
  if(verbose >= 1) {
    fprintf( stderr, "libdvdread: Could not open %s\n", path );
  }
  return 0;
}
Пример #2
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;
}
Пример #3
0
dvd_reader_t *DVDOpen( const char *ppath )
{
    struct stat fileinfo;
    int ret;
    int have_css;
	dvd_reader_t *ret_val = NULL;
    char *dev_name = 0;
	char *path;

#ifdef _MSC_VER
	int len;
#endif

    if( ppath == NULL )
      return 0;

	path = strdup(ppath);
	
    /* Try to open libdvdcss or fall back to standard functions */
    have_css = dvdinput_setup();

#ifdef _MSC_VER
	/* 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 = stat( path, &fileinfo );

    if( ret < 0 ) {

        /* maybe "host:port" url? try opening it with acCeSS library */
        if( strchr(path,':') ) {
			ret_val = DVDOpenImageFile( path, 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("");
	free(path);
	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)
	ret_val = DVDOpenImageFile( sun_block2char( path ), have_css );
#elif defined(SYS_BSD)
	ret_val = DVDOpenImageFile( bsd_block2char( path ), have_css );
#else
	ret_val = DVDOpenImageFile( path, have_css );
#endif

	free(path);
	return ret_val;

    } 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 ) ) ) {
		free(path);	
		return 0;
	}

#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 absolut dir name. */
	{
	    char *new_path;
	    int cdir = open( ".", O_RDONLY );
	    
	    if( cdir >= 0 ) {
		chdir( path_copy );
		new_path = getcwd( NULL, XINE_PATH_MAX );
		fchdir( cdir );
		close( cdir );
		if( new_path ) {
		    free( path_copy );
		    path_copy = new_path;
		}
	    }
	}
#endif	
	/**
	 * 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_copy[ 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 ) ) ) {
	    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, 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, have_css );
		    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, have_css );
		    /* If the device is not encrypted, don't access the device
		     * directly as it would fail for non-UDF DVDs */
		    if ( auth_drive && dvdinput_is_encrypted( auth_drive->dev ) == 0) {
		      DVDClose( auth_drive );
		      auth_drive = NULL;
		      break;
		    }
		    dev_name = strdup(me->mnt_fsname);
                    break;
                }
            }
            fclose( mntfile );
	}
#elif defined(_MSC_VER)
    auth_drive = DVDOpenImageFile( path, have_css );
#endif

#ifndef _MSC_VER
	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", dev_name );
	}
#endif

	free( dev_name );
	free( path_copy );

        /**
         * 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;
    }

    /* If it's none of the above, screw it. */
    fprintf( stderr, "libdvdread: Could not open %s\n", path );
	free( path );
    return 0;
}