summaryrefslogtreecommitdiffstats
path: root/src/tsnifd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tsnifd.c')
-rw-r--r--src/tsnifd.c231
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);
+}