summaryrefslogtreecommitdiffstats
path: root/src/tsnif-replay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tsnif-replay.c')
-rw-r--r--src/tsnif-replay.c185
1 files changed, 170 insertions, 15 deletions
diff --git a/src/tsnif-replay.c b/src/tsnif-replay.c
index 0f1455f..a0ec61e 100644
--- a/src/tsnif-replay.c
+++ b/src/tsnif-replay.c
@@ -1,13 +1,20 @@
#include <stdio.h>
+#include <stdio_ext.h>
#include <unistd.h>
#include <getopt.h>
+#include <sys/select.h>
+#include <setjmp.h>
+#include <string.h>
+#include <signal.h>
#include "storage.h"
+#include "misc.h"
+#include "intf.h"
-
+static int killed;
static char *filename;
-struct tsnif_storage_handle storage_handle;
+static struct tsnif_storage_handle storage_handle;
static struct tsnif_storage_opts storage_opts = {
.flags = TSNIF_STORAGE_OPT_READ,
};
@@ -20,6 +27,12 @@ static void usage()
_exit(-1);
}
+static void sig_handler(int sig)
+{
+ printf("killed\n");
+ killed = 1;
+}
+
static int get_args(int argc, char **argv)
{
while (1) {
@@ -59,9 +72,153 @@ static int get_args(int argc, char **argv)
return 0;
}
+static struct timeval get_timeout(struct timespec *ts_new,
+ struct timespec *ts_old)
+{
+ static struct timeval tv;
+
+ tv.tv_sec = ts_new->tv_sec - ts_old->tv_sec;
+
+ TSNIF_DEBUG("time new %ld:%ld\n", ts_new->tv_sec, ts_new->tv_nsec);
+ TSNIF_DEBUG("time old %ld:%ld\n", ts_old->tv_sec, ts_old->tv_nsec);
+
+ if (ts_new->tv_nsec >= ts_old->tv_nsec)
+ tv.tv_usec = (ts_new->tv_nsec - ts_old->tv_nsec) / 1000;
+ else {
+ tv.tv_usec = (ts_new->tv_nsec + (1000000000 - ts_old->tv_nsec)) / 1000;
+ if (tv.tv_sec)
+ tv.tv_sec--;
+ }
+
+ TSNIF_DEBUG("time fin %ld %ld\n", tv.tv_sec, tv.tv_usec);
+ return tv;
+}
+
+enum {
+ ACTION_NEXT,
+ ACTION_PREV,
+ ACTION_FIRST,
+ ACTION_TIMEOUT,
+ ACTION_STOP,
+ ACTION_RUN,
+ ACTION_QUIT,
+ ACTION_SLAVE,
+ ACTION_MASTER,
+};
+
+static int display_slave = 1;
+static int display_master= 0;
+
+static int output(struct tsnif_storage_rec *rec)
+{
+ fwrite(rec->ptr, rec->len, 1, stdout);
+ fflush(NULL);
+ return 0;
+}
+
+static int get_action(struct timeval *tv)
+{
+ int c, ret;
+ jmp_buf env;
+ fd_set rfds;
+
+ setjmp(env);
+
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+
+ ret = select(1, &rfds, NULL, NULL, tv);
+
+ /* select failed - finish replay */
+ if (-1 == ret)
+ return ACTION_QUIT;
+
+ /* timeout - continue with next record */
+ if (!ret)
+ return ACTION_NEXT;
+
+ /* WTF??? */
+ if (!FD_ISSET(0, &rfds))
+ return ACTION_QUIT;
+
+ /* we got user input */
+ c = getchar();
+
+ if (c == '\033') {
+ __fpurge(stdin);
+ longjmp(env, 1);
+ }
+
+ switch(c) {
+ case 'p' : return ACTION_PREV;
+ case 'n' : return ACTION_NEXT;
+ case 'f' : return ACTION_FIRST;
+ case 'q' : return ACTION_QUIT;
+ case 't' : return ACTION_TIMEOUT;
+ case 's' : return ACTION_SLAVE;
+ case 'm' : return ACTION_MASTER;
+ }
+
+ longjmp(env, 1);
+ return -1;
+}
+
+static int process(void)
+{
+ struct tsnif_storage_rec rec;
+ int err, action;
+
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_NEXT, &rec);
+ if (err < 0)
+ return err;
+
+ do {
+ struct timespec ts_prev;
+ struct timeval tv;
+
+ memset(&tv, 0x0, sizeof(tv));
+
+ if (err != TSNIF_STORAGE_READ_EOF) {
+ output(&rec);
+
+ ts_prev = rec.time;
+
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_NEXT, &rec);
+ if (err < 0)
+ break;
+
+ tv = get_timeout(&rec.time, &ts_prev);
+ }
+
+ action = get_action(&tv);
+ switch(action) {
+ case ACTION_PREV:
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_PREV, &rec);
+ if (err < 0)
+ return err;
+ break;
+
+ case ACTION_SLAVE:
+ display_slave = !display_slave;
+ break;
+
+ case ACTION_MASTER:
+ display_master = !display_master;
+ break;
+ }
+
+ } while(action != ACTION_QUIT);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
- int err;
+ int err, ret;
+ jmp_buf env;
if (get_args(argc, argv))
usage();
@@ -70,20 +227,18 @@ int main(int argc, char **argv)
if (err)
return -1;
- do {
- struct tsnif_storage_rec rec;
-
- err = tsnif_storage_read(&storage_handle,
- TSNIF_STORAGE_READ_NEXT, &rec);
+ if ((ret = setjmp(env))) {
+ set_term(1);
+ tsnif_storage_close(&storage_handle);
- if (err)
- break;
+ printf("done err = %d\n", err);
+ return err;
+ }
- fwrite(rec.ptr, rec.len, 1, stdout);
- fflush(NULL);
+ set_term(0);
+ signal(SIGINT, sig_handler);
- } while(1);
+ err = process();
- tsnif_storage_close(&storage_handle);
- return 0;
+ longjmp(env, 1);
}