diff options
Diffstat (limited to 'src/tsnifd.c')
-rw-r--r-- | src/tsnifd.c | 231 |
1 files changed, 230 insertions, 1 deletions
diff --git a/src/tsnifd.c b/src/tsnifd.c index 5864387..14127b4 100644 --- a/src/tsnifd.c +++ b/src/tsnifd.c @@ -1,7 +1,236 @@ #include <stdio.h> +#include <sys/select.h> +#include <unistd.h> +#include <termios.h> +#include <getopt.h> +#include <errno.h> +#include <setjmp.h> +#include <signal.h> -int main(int argc, char **argv) +#include "autoconf.h" +#include "intf.h" +#include "storage.h" +#include "misc.h" + +extern int tsnif_debug; + +static struct tsnif_storage_opts init_storage_opts = { + .flags = TSNIF_STORAGE_OPT_WRITE, + .size_max = 1024*1024, +}; + +static struct tsnif_handle handle; + +struct terminal { + /* interface term */ + struct tsnif_term term; + + /* storage */ + struct tsnif_storage_opts storage_opts; + struct tsnif_storage_handle storage_handle; +}; + +static int foreground = 0; +static int killed = 0; +static char *store_dir = "/var/log/tsnid/"; + +int terminal_add(struct tsnif_term *term) +{ + struct terminal *t; + int err; + + TSNIF_DEBUG("type %d, idx %d\n", term->type, term->idx); + + if (term->type != TSNIF_TYPE_PTY) + return 0; + + t = malloc(sizeof(*t)); + if (!t) + return -ENOMEM; + + memset(t, 0x0, sizeof(*t)); + + err = tsnif_term_add(&handle, &t->term, term->type, term->idx); + if (err) { + free(t); + return err; + } + + return tsnif_attach(&t->term); +} + +int terminal_del(struct tsnif_term *term) +{ + struct terminal *t; + int err; + + TSNIF_DEBUG("type %d, idx %d\n", term->type, term->idx); + + err = tsnif_term_del(&handle, term); + if (err) { + /* TODO do smth smart */ + } + + t = container_of(term, struct terminal, term); + free(t); + + return err; +} + +static int data_cb(struct tsnif_term* term, struct tsnif_data *data) +{ + struct terminal *t; + + t = container_of(term, struct terminal, term); + return 0; +} + +static int err_cb(struct tsnif_term *term, int err) +{ + return err; +} + +static int release_cb(struct tsnif_term *term) +{ + return terminal_del(term); +} + +static int notify_cb(struct tsnif_term *term, int action) +{ + int err = 0; + + switch(action) { + case TSNIF_CMD_TTY_RELEASE: + printf("not watched terminal released - type %d, idx %d\n", + term->type, term->idx); + break; + + case TSNIF_CMD_TTY_CREATE: + case TSNIF_CMD_TTY_LIST: + err = terminal_add(term); + break; + + default: + err = -EINVAL; + } + return err; +} + +struct tsnif_ops ops = { + .cb_data = data_cb, + .cb_err = err_cb, + .cb_release = release_cb, + .cb_notify = notify_cb, +}; + +static void sig_handler(int sig) +{ + printf("killed\n"); + killed = 1; +} + +static void usage() { + printf("tsnifd [-dfvhs]\n"); + _exit(-1); +} + +static int get_args(int argc, char **argv) +{ + while (1) { + int c; + int option_index = 0; + static struct option long_options[] = { + {"version", no_argument, 0, 'v'}, + {"debug", no_argument, 0, 'd'}, + {"foreground", no_argument, 0, 'f'}, + {"store-dir", required_argument, 0, 's'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "t:i:s:vdh", + long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 'v': + printf("tsnif "CONFIG_TSNIF_VER"\n"); + break; + + case 'd': + tsnif_debug = 1; + break; + + case 'f': + foreground = 1; + break; + + case 's': + store_dir = optarg; + break; + + case 'h': + usage(); + break; + + default: + printf("unknown option '%c'", c); + } /* switch(c) */ + } /* while(1) */ + return 0; } + +int main(int argc, char **argv) +{ + int err, ret; + jmp_buf env; + + if (get_args(argc, argv)) + usage(); + + err = tsnif_init(&handle, &ops); + if (err) + return err; + + if ((ret = setjmp(env))) { + + tsnif_close(&handle); + printf("done err = %d\n", err); + return err; + } + + err = tsnif_list(&handle); + if (err) + longjmp(env, 1); + + signal(SIGINT, sig_handler); + + while(!killed) { + fd_set rfds; + struct timeval tv = { 1, 0}; + int ts_fd = tsnif_fd(&handle); + + FD_ZERO(&rfds); + FD_SET(ts_fd, &rfds); + + err = select(ts_fd + 1, &rfds, NULL, NULL, &tv); + if (err == -1) { + perror("select()"); + continue; + } else if (!err) + continue; + + if (FD_ISSET(ts_fd, &rfds)) { + err = tsnif_process(&handle); + if (err) + longjmp(env, 3); + } + } + + longjmp(env, 3); +} |