diff options
Diffstat (limited to 'src/tsnif-replay.c')
-rw-r--r-- | src/tsnif-replay.c | 185 |
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); } |