* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <vlc/vlc.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <assert.h>
#include <time.h>
+#include <errno.h>
+
+#include <vlc_access.h>
-#include "vlc_access.h"
-#include "vlc_block.h"
-#include "charset.h"
+#include <vlc_charset.h>
#include "vlc_keys.h"
#define DEFAULT_MARGIN 32 // megabytes
MARGIN_LONGTEXT, VLC_FALSE);
vlc_module_end();
-static int Read (access_t *access, uint8_t *buffer, int len);
+static ssize_t Read (access_t *access, uint8_t *buffer, size_t len);
static block_t *Block (access_t *access);
static int Seek (access_t *access, int64_t offset);
static int Control (access_t *access, int cmd, va_list ap);
{
FILE *stream;
int64_t tmp_max;
+ int64_t dumpsize;
};
/**
if ((p_sys->stream = tmpfile ()) == NULL)
{
- msg_Err (access, "cannot create temporary file: %s", strerror (errno));
+ msg_Err (access, "cannot create temporary file: %m");
free (p_sys);
return VLC_EGENERIC;
}
access_sys_t *p_sys = access->p_sys;
FILE *stream = p_sys->stream;
- if ((stream == NULL) || (len == 0))
+ if ((stream == NULL) /* not dumping */
+ || (access->info.i_pos < p_sys->dumpsize) /* already known data */)
return;
+ size_t needed = access->info.i_pos - p_sys->dumpsize;
+ if (len < needed)
+ return; /* gap between data and dump offset (seek too far ahead?) */
+
+ buffer += len - needed;
+ len = needed;
+
+ if (len == 0)
+ return; /* no useful data */
+
if ((p_sys->tmp_max != -1) && (access->info.i_pos > p_sys->tmp_max))
{
msg_Dbg (access, "too much data - dump will not work");
goto error;
}
+ assert (len > 0);
if (fwrite (buffer, len, 1, stream) != 1)
{
- msg_Err (access, "cannot write to file: %s", strerror (errno));
+ msg_Err (access, "cannot write to file: %m");
goto error;
}
+ p_sys->dumpsize += len;
return;
error:
}
-static int Read (access_t *access, uint8_t *buffer, int len)
+static ssize_t Read (access_t *access, uint8_t *buffer, size_t len)
{
access_t *src = access->p_source;
access->info = src->info;
Dump (access, buffer, len);
- //Trigger (access);
return len;
}
}
if (p_sys->stream != NULL)
- {
- msg_Dbg (access, "seeking - dump will not work");
- fclose (p_sys->stream);
- p_sys->stream = NULL;
- }
+ msg_Dbg (access, "seeking - dump might not work");
src->info.i_update = access->info.i_update;
int ret = src->pf_seek (src, offset);
}
+#ifndef HAVE_LOCALTIME_R
+static inline struct tm *localtime_r (const time_t *now, struct tm *res)
+{
+ struct tm *unsafe = localtime (now);
+ /*
+ * This is not thread-safe. Blame your C library.
+ * On Win32 there SHOULD be _localtime_s instead, but of course
+ * Cygwin and Mingw32 don't know about it. You're on your own if you
+ * use this platform.
+ */
+ if (unsafe == NULL)
+ return NULL;
+
+ memcpy (res, unsafe, sizeof (*res));
+ return res;
+}
+#endif
+
+
static void Trigger (access_t *access)
{
access_sys_t *p_sys = access->p_sys;
msg_Info (access, "dumping media to \"%s\"...", filename);
- FILE *newstream = fopen (filename, "wb");
+ FILE *newstream = utf8_fopen (filename, "wb");
if (newstream == NULL)
{
- msg_Err (access, "cannot create dump file \"%s\": %s", filename,
- strerror (errno));
+ msg_Err (access, "cannot create dump file \"%s\": %m", filename);
return;
}
{
if (ferror (oldstream))
{
- msg_Err (access, "cannot read temporary file: %s",
- strerror (errno));
+ msg_Err (access, "cannot read temporary file: %m");
break;
}
if (fwrite (buf, len, 1, newstream) != 1)
{
- msg_Err (access, "cannot write dump file: %s", strerror (errno));
+ msg_Err (access, "cannot write dump file: %m");
break;
}
}