]> git.sesse.net Git - vlc/blobdiff - modules/access/dvdnav.c
MKV: privatize matroska_segment_c methods
[vlc] / modules / access / dvdnav.c
index e96c301346688c5cb6dfdf728a4de95ba0213a2a..8cceae4b9a180f2e4256129c656fe8aa27e74aaa 100644 (file)
@@ -52,6 +52,7 @@
 #ifdef HAVE_FCNTL_H
 #   include <fcntl.h>
 #endif
+#include <errno.h>
 
 #include <vlc_keys.h>
 #include <vlc_iso_lang.h>
@@ -163,7 +164,7 @@ static void ESSubtitleUpdate( demux_t * );
 static void ButtonUpdate( demux_t *, bool );
 
 static void ESNew( demux_t *, int );
-static int ProbeDVD( demux_t *, char * );
+static int ProbeDVD( const char * );
 
 static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var );
 
@@ -189,11 +190,16 @@ static int Open( vlc_object_t *p_this )
     int         i_angle;
     char        *psz_file;
     char        *psz_code;
+    bool forced = false;
+
+    if( p_demux->psz_access != NULL
+     && !strncmp(p_demux->psz_access, "dvd", 3) )
+        forced = true;
 
     if( !p_demux->psz_file || !*p_demux->psz_file )
     {
         /* Only when selected */
-        if( !p_demux->psz_access || !*p_demux->psz_access )
+        if( !forced )
             return VLC_EGENERIC;
 
         psz_file = var_InheritString( p_this, "dvd" );
@@ -216,7 +222,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
 
     /* Try some simple probing to avoid going through dvdnav_open too often */
-    if( ProbeDVD( p_demux, psz_file ) != VLC_SUCCESS )
+    if( !forced && ProbeDVD( psz_file ) != VLC_SUCCESS )
     {
         free( psz_file );
         return VLC_EGENERIC;
@@ -1446,46 +1452,49 @@ static int EventIntf( vlc_object_t *p_input, char const *psz_var,
 /*****************************************************************************
  * ProbeDVD: very weak probing that avoids going too often into a dvdnav_open()
  *****************************************************************************/
-static int ProbeDVD( demux_t *p_demux, char *psz_name )
+static int ProbeDVD( const char *psz_name )
 {
-    (void)p_demux;
-#ifdef HAVE_SYS_STAT_H
-    struct stat stat_info;
-    uint8_t pi_anchor[2];
-    int i_fd, i_ret;
-
     if( !*psz_name )
-    {
         /* Triggers libdvdcss autodetection */
         return VLC_SUCCESS;
-    }
 
-    if( (i_fd = vlc_open( psz_name, O_RDONLY |O_NONBLOCK )) == -1 )
-    {
-        return VLC_SUCCESS; /* Let dvdnav_open() do the probing */
-    }
+    int fd = vlc_open( psz_name, O_RDONLY | O_NONBLOCK );
+    if( fd == -1 )
+#ifdef HAVE_FDOPENDIR
+        return VLC_EGENERIC;
+#else
+        return (errno == ENOENT) ? VLC_EGENERIC : VLC_SUCCESS;
+#endif
 
-    i_ret = VLC_EGENERIC;
+    int ret = VLC_EGENERIC;
 
-    if( fstat( i_fd, &stat_info ) || !S_ISREG( stat_info.st_mode ) )
+#ifdef HAVE_SYS_STAT_H
+    struct stat stat_info;
+
+    if( fstat( fd, &stat_info ) == -1 )
+         goto bailout;
+
+    if( !S_ISREG( stat_info.st_mode ) )
     {
-        if( !S_ISFIFO( stat_info.st_mode ) )
-            i_ret = VLC_SUCCESS; /* Let dvdnav_open() do the probing */
+        if( S_ISDIR( stat_info.st_mode ) || S_ISBLK( stat_info.st_mode ) )
+            ret = VLC_SUCCESS; /* Let dvdnav_open() do the probing */
         goto bailout;
     }
+#endif
+    /* Match extension as the anchor exhibits too many false positives */
+    const size_t len = strlen( psz_name );
+    if( len < 4 || strcasecmp( psz_name + len - 4, ".iso" ) )
+        goto bailout;
 
     /* Try to find the anchor (2 bytes at LBA 256) */
-    if( lseek( i_fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) != -1
-     && read( i_fd, pi_anchor, 2 ) == 2
-     && GetWLE( pi_anchor ) == 2 )
-        i_ret = VLC_SUCCESS; /* Found a potential anchor */
+    uint16_t anchor;
 
-bailout:
-    close( i_fd );
+    if( lseek( fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) != -1
+     && read( fd, &anchor, 2 ) == 2
+     && GetWLE( &anchor ) == 2 )
+        ret = VLC_SUCCESS; /* Found a potential anchor */
 
-    return i_ret;
-#else
-
-    return VLC_SUCCESS;
-#endif
+bailout:
+    close( fd );
+    return ret;
 }