* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
-#include <vlc/input.h>
-#include <vlc_interaction.h>
+#include <vlc_input.h>
+#include <vlc_access.h>
+#include <vlc_interface.h>
-#include <stdlib.h>
-#include <string.h>
#include <errno.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if defined( WIN32 ) && !defined( UNDER_CE )
-/* fstat() support for large files on win32 */
-# define fstat(a,b) _fstati64(a,b)
# ifdef lseek
# undef lseek
# endif
# define lseek fseek
#endif
-#include "charset.h"
+#include <vlc_charset.h>
/*****************************************************************************
* Module descriptor
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ACCESS );
add_integer( "file-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
- add_string( "file-cat", NULL, NULL, CAT_TEXT, CAT_LONGTEXT, VLC_TRUE );
+ add_obsolete_string( "file-cat" );
set_capability( "access2", 50 );
add_shortcut( "file" );
add_shortcut( "stream" );
static int Read( access_t *, uint8_t *, int );
static int Control( access_t *, int, va_list );
-static int OpenFile( access_t *, const char * );
+static int open_file( access_t *, const char * );
struct access_sys_t
{
unsigned int i_nb_reads;
vlc_bool_t b_kfir;
- /* Files list */
- unsigned filec;
- int *filev;
- int64_t *sizev;
-
- /* Current file */
- unsigned filep;
+ int fd;
/* */
vlc_bool_t b_seekable;
{
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys;
- char *catlist;
vlc_bool_t b_stdin = !strcmp (p_access->psz_path, "-");
STANDARD_READ_ACCESS_INIT;
p_sys->i_nb_reads = 0;
p_sys->b_kfir = VLC_FALSE;
- p_sys->filec = 1;
- p_sys->filep = 0;
+ int fd = p_sys->fd = -1;
if (!strcasecmp (p_access->psz_access, "stream"))
{
p_sys->b_pace_control = VLC_TRUE;
}
- /* Count number of files */
- catlist = var_CreateGetString (p_access, "file-cat");
- if (catlist == NULL)
- {
- free (p_sys);
- return VLC_ENOMEM;
- }
-
- if (*catlist)
- {
- for (const char *ptr = catlist; ptr != NULL; p_sys->filec++)
- {
- ptr = strchr (ptr, ',');
- if (ptr != NULL)
- ptr++;
- }
- }
+ /* Open file */
+ msg_Dbg (p_access, "opening file `%s'", p_access->psz_path);
- p_sys->filev = calloc (p_sys->filec, sizeof (p_sys->filev[0]));
- if (p_sys->filev == NULL)
- {
- free (catlist);
- free (p_sys);
- return VLC_ENOMEM;
- }
+ if (b_stdin)
+ fd = dup (0);
+ else
+ fd = open_file (p_access, p_access->psz_path);
- p_sys->sizev = calloc (p_sys->filec, sizeof (p_sys->sizev[0]));
- if (p_sys->sizev == NULL)
- {
- free (catlist);
- free (p_sys->filev);
- free (p_sys);
- return VLC_ENOMEM;
- }
+#ifdef HAVE_SYS_STAT_H
+ struct stat st;
- /* Open files */
- char *filename = catlist;
- for (unsigned i = 0; i < p_sys->filec; i++)
+ while (fd != -1)
{
- int fd = -1;
-
- if (i == 0)
- {
- msg_Dbg (p_access, "opening file `%s'", p_access->psz_path);
-
- if (b_stdin)
- fd = dup (0);
- else
- fd = OpenFile (p_access, p_access->psz_path);
- }
+ if (fstat (fd, &st))
+ msg_Err (p_access, "fstat(%d): %m", fd);
else
- {
- assert (filename != NULL);
-
- char *ptr = strchr (filename, ',');
- if (ptr != NULL)
- *ptr = 0;
-
- msg_Dbg (p_access, "opening additionnal file `%s'", filename);
- fd = OpenFile (p_access, filename);
- filename = ptr + 1;
- }
-
-#ifdef HAVE_SYS_STAT_H
- struct stat st;
+ if (S_ISDIR (st.st_mode))
+ /* The directory plugin takes care of that */
+ msg_Dbg (p_access, "file is a directory, aborting");
+ else
+ break; // success
- if ((fd != -1) && fstat (fd, &st))
- {
- msg_Err (p_access, "fstat(%d): %s", fd, strerror (errno));
- close (fd);
- fd = -1;
- }
+ close (fd);
+ fd = -1;
+ }
#endif
- if (fd == -1)
- {
- free (catlist);
- p_sys->filec = i;
- Close (p_this);
- return VLC_EGENERIC;
- }
- p_sys->filev[i] = fd;
+ if (fd == -1)
+ {
+ free (p_sys);
+ return VLC_EGENERIC;
+ }
+ p_sys->fd = fd;
#ifdef HAVE_SYS_STAT_H
- p_sys->sizev[i] = st.st_size;
- p_access->info.i_size += st.st_size;
-
- if (!S_ISREG (st.st_mode) && !S_ISBLK (st.st_mode)
- && (!S_ISCHR (st.st_mode) || (st.st_size == 0)))
- // If one file is not seekable, the concatenation is not either
- p_sys->b_seekable = VLC_FALSE;
+ p_access->info.i_size = st.st_size;
+ if (!S_ISREG (st.st_mode) && !S_ISBLK (st.st_mode)
+ && (!S_ISCHR (st.st_mode) || (st.st_size == 0)))
+ p_sys->b_seekable = VLC_FALSE;
#else
- p_sys->b_seekable = !b_stdin;
+ p_sys->b_seekable = !b_stdin;
+# warning File size not known!
#endif
- }
-
- free (catlist);
-
- if (p_sys->b_seekable && !p_access->info.i_size)
+ if (p_sys->b_seekable && (p_access->info.i_size == 0))
{
/* FIXME that's bad because all others access will be probed */
- msg_Err (p_access, "file %s is empty, aborting", p_access->psz_path);
+ msg_Err (p_access, "file is empty, aborting");
Close (p_this);
return VLC_EGENERIC;
}
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys = p_access->p_sys;
- for (unsigned i = 0; i < p_sys->filec; i++)
- close (p_sys->filev[i]);
-
- free (p_sys->filev);
- free (p_sys->sizev);
+ close (p_sys->fd);
free (p_sys);
}
{
access_sys_t *p_sys = p_access->p_sys;
int i_ret;
- int fd = p_sys->filev[p_sys->filep];
+ int fd = p_sys->fd;
#if !defined(WIN32) && !defined(UNDER_CE)
if( !p_sys->b_pace_control )
break;
default:
- msg_Err (p_access, "read failed (%s)", strerror (errno));
+ msg_Err (p_access, "read failed (%m)");
+ /* FIXME: DO NOT USE strerror!!!! */
intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"),
_("VLC could not read file \"%s\"."),
strerror (errno));
(p_sys->i_nb_reads % INPUT_FSTAT_NB_READS) == 0 )
{
struct stat st;
- int i = p_sys->filep;
if ((fstat (fd, &st) == 0)
- && (p_sys->sizev[i] != st.st_size))
+ && (p_access->info.i_size != st.st_size))
{
- p_access->info.i_size += st.st_size - p_sys->sizev[i];
- p_sys->sizev[i] = st.st_size;
+ p_access->info.i_size = st.st_size;
p_access->info.i_update |= INPUT_UPDATE_SIZE;
}
}
#endif
- /* If we reached an EOF then switch to the next file in the list */
- if (i_ret == 0)
- {
- if (++p_sys->filep < p_sys->filec)
- /* We have to read some data */
- return Read (p_access, p_buffer, i_len);
- else
- p_sys->filep--;
- }
-
if( i_ret > 0 )
p_access->info.i_pos += i_ret;
else if( i_ret == 0 )
*****************************************************************************/
static int Seek (access_t *p_access, int64_t i_pos)
{
- access_sys_t *p_sys = p_access->p_sys;
-
- if (p_access->info.i_size < p_access->info.i_pos)
+ if (i_pos > p_access->info.i_size)
{
msg_Err (p_access, "seeking too far");
- i_pos = p_access->info.i_pos = p_access->info.i_size;
+ i_pos = p_access->info.i_size;
}
- else if (p_access->info.i_pos < 0)
+ else if (i_pos < 0)
{
msg_Err (p_access, "seeking too early");
- i_pos = p_access->info.i_pos = 0;
+ i_pos = 0;
}
p_access->info.i_pos = i_pos;
p_access->info.b_eof = VLC_FALSE;
/* Determine which file we need to access */
- unsigned i = 0;
- assert (p_sys->filec > 0);
-
- while (i_pos > p_sys->sizev[i])
- {
- i_pos -= p_sys->sizev[i++];
- assert (i < p_sys->filec);
- }
- p_sys->filep = i;
-
- lseek (p_sys->filev[i], i_pos, SEEK_SET);
+ lseek (p_access->p_sys->fd, i_pos, SEEK_SET);
return VLC_SUCCESS;
}
/*****************************************************************************
- * OpenFile: Opens a specific file
+ * open_file: Opens a specific file
*****************************************************************************/
-static int OpenFile (access_t *p_access, const char *psz_name)
+static int open_file (access_t *p_access, const char *psz_name)
{
char *path = expand_path (p_access, psz_name);
if ( !p_sys->fd )
{
msg_Err( p_access, "cannot open file %s", psz_name );
- intf_UserFatal( p_access, VLC_FALSE, _("File reading failed"),
+ intf_UserFatal( p_access, VLC_FALSE, _("File reading failed"),
_("VLC could not open file \"%s\"."), psz_name );
free (path);
return VLC_EGENERIC;
p_access->info.i_update |= INPUT_UPDATE_SIZE;
fseek( p_sys->fd, 0, SEEK_SET );
#else
- const char *psz_localname = ToLocale (path);
- if (psz_localname == NULL)
- {
- msg_Err (p_access, "incorrect file name %s", psz_name);
- free (path);
- return -1;
- }
-
- // FIXME: support non-ANSI filenames on Win32
- int fd = open (path, O_NONBLOCK /*| O_LARGEFILE*/);
- LocaleFree (psz_localname);
+ int fd = utf8_open (path, O_RDONLY | O_NONBLOCK /* O_LARGEFILE*/, 0666);
free (path);
-
if (fd == -1)
{
- msg_Err (p_access, "cannot open file %s (%s)", psz_name,
- strerror (errno));
- intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"),
+ msg_Err (p_access, "cannot open file %s (%m)", psz_name);
+ intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"),
_("VLC could not open file \"%s\" (%s)."),
psz_name, strerror (errno));
return -1;