diff options
author | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-14 11:59:58 +0200 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-14 11:59:58 +0200 |
commit | 1935c50b0f3af15aed865009c728e5eec06c12ac (patch) | |
tree | ef916f58887688da51de95165dbab6032237b40c | |
parent | f6c0943a2b6e8e0a9fc0939dbe5628ecca8d78e4 (diff) | |
download | tsnif-1935c50b0f3af15aed865009c728e5eec06c12ac.tar.gz tsnif-1935c50b0f3af15aed865009c728e5eec06c12ac.tar.xz tsnif-1935c50b0f3af15aed865009c728e5eec06c12ac.zip |
store support for tsnifd
-rw-r--r-- | src/fsm.c | 7 | ||||
-rw-r--r-- | src/intf.c | 14 | ||||
-rw-r--r-- | src/intf.h | 5 | ||||
-rw-r--r-- | src/tsnifd.c | 184 |
4 files changed, 191 insertions, 19 deletions
@@ -104,10 +104,9 @@ static int detach(struct tsnif_handle *h, switch(msg->cmd) { case TSNIF_CMD_DETACH: - if (msg->ack) { - term->state = TSNIF_INTF_STATE_DONE; - break; - } + if (msg->ack) + return process_release(h, term); + err = -EINVAL; if (!msg->err) break; @@ -205,3 +205,17 @@ int tsnif_list(struct tsnif_handle *h) return trans_send(&h->trans, &msg); } + +int tsnif_enum(struct tsnif_handle *h, cb_tsnif_enum_t cb) +{ + struct tsnif_term *term, *t; + int err = 0; + + list_for_each_entry_safe(term, t, &h->terms, list) { + err = cb(term); + if (err) + break; + } + + return err;; +} @@ -59,6 +59,8 @@ struct tsnif_handle { struct trans_handle trans; }; +typedef int(*cb_tsnif_enum_t)(struct tsnif_term *term); + /* handle functions */ int tsnif_init(struct tsnif_handle *h, struct tsnif_ops *ops); int tsnif_close(struct tsnif_handle *h); @@ -73,6 +75,9 @@ int tsnif_term_del(struct tsnif_handle *h, struct tsnif_term *term); int tsnif_attach(struct tsnif_term *term); int tsnif_detach(struct tsnif_term *term); +#define tsnif_for_each(term, t, handle) \ + list_for_each_entry_safe(term, t, (&handle->terms), list) + extern int tsnif_debug; #define TSNIF_DEBUG(fmt, args...) \ diff --git a/src/tsnifd.c b/src/tsnifd.c index 14127b4..22b6da5 100644 --- a/src/tsnifd.c +++ b/src/tsnifd.c @@ -7,12 +7,17 @@ #include <errno.h> #include <setjmp.h> #include <signal.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> #include "autoconf.h" #include "intf.h" #include "storage.h" #include "misc.h" + extern int tsnif_debug; static struct tsnif_storage_opts init_storage_opts = { @@ -27,23 +32,124 @@ struct terminal { struct tsnif_term term; /* storage */ + char *file; 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/"; +static char *store_dir = "/var/log/tsnid"; + +static char *types[TSNIF_TYPE_MAX] = { + "tty", "ttys", "pty" +}; + +static char *type_get(int type) +{ + if ((type >= TSNIF_TYPE_MAX) || + (type < 0)) + return NULL; + + return types[type]; +} + +static int dir_get(char *path) +{ + struct stat st; + int err; + + if (!stat(path, &st)) + return 0; + + err = mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR); + if (err) { + perror("mkdir failed"); + return err; + } + + return 0; + +} + +static char *file_get(int type, int idx) +{ + struct timeval tv; + struct tm *tm; +#define MAXPATH 1024 + static char path[MAXPATH]; + char *type_str; + int len; + + if (dir_get(store_dir)) + return NULL; + + type_str = type_get(type); + if (!type_str) + return NULL; + + len = snprintf(path, MAXPATH, "%s/%s", store_dir, type_str); + + if (dir_get(path)) + return NULL; + + if (-1 == gettimeofday(&tv, NULL)) { + perror("gettimeofday failed"); + return NULL; + } + + tm = localtime(&tv.tv_sec); + if (!tm) { + perror("localtime failed"); + return NULL; + } + + snprintf(path + len, MAXPATH - len, + "/%d-%02d.%02d.%02d_%02d:%02d:%02d.%03lu-alive", + idx, + tm->tm_mday, + tm->tm_mon + 1, + (tm->tm_year + 1900) % 100, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + tv.tv_usec / 1000); + + return path; +} + +static int file_put(char *name) +{ + char *new = strdup(name); + char *p; + int err; -int terminal_add(struct tsnif_term *term) + p = strrchr(new, '-'); + if (!p) + return -1; + + sprintf(p, "%s", ".tsnif"); + + TSNIF_DEBUG("putting to %s\n", new); + + err = rename(name, new); + free(new); + return err; +} + +static int terminal_add(struct tsnif_term *term) { struct terminal *t; int err; + char *file; TSNIF_DEBUG("type %d, idx %d\n", term->type, term->idx); - if (term->type != TSNIF_TYPE_PTY) - return 0; + /* XXX debug gets only PTY XXX */ + if (tsnif_debug) { + if (term->type != TSNIF_TYPE_PTY) + return 0; + } t = malloc(sizeof(*t)); if (!t) @@ -57,25 +163,54 @@ int terminal_add(struct tsnif_term *term) return err; } + file = file_get(term->type, term->idx); + if (!file) { + tsnif_term_del(&handle, &t->term); + free(t); + return -1; + } + + TSNIF_DEBUG("storing to %s\n", file); + + t->file = strdup(file); + t->storage_opts = init_storage_opts; + + err = tsnif_storage_init(&t->storage_handle, + &t->storage_opts, file); + return tsnif_attach(&t->term); } -int terminal_del(struct tsnif_term *term) +static 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 */ - } + tsnif_term_del(&handle, term); t = container_of(term, struct terminal, term); + + tsnif_storage_close(&t->storage_handle); + file_put(t->file); + free(t->file); + free(t); - return err; + return 0; +} + +static int store_data(struct tsnif_storage_handle *h, struct tsnif_data *data) +{ + struct tsnif_storage_rec rec = { + .ptr = data->ptr, + .len = data->len, + .flags = data->flags, + .time = data->time, + .ws = data->ws, + }; + + return tsnif_storage_write(h, &rec); } static int data_cb(struct tsnif_term* term, struct tsnif_data *data) @@ -83,12 +218,13 @@ static int data_cb(struct tsnif_term* term, struct tsnif_data *data) struct terminal *t; t = container_of(term, struct terminal, term); - return 0; + + return store_data(&t->storage_handle, data); } static int err_cb(struct tsnif_term *term, int err) { - return err; + return terminal_del(term); } static int release_cb(struct tsnif_term *term) @@ -117,6 +253,21 @@ static int notify_cb(struct tsnif_term *term, int action) return err; } +static int release_terms(void) +{ + struct tsnif_term *term, *t; + + tsnif_for_each(term, t, (&handle)) { + /* The ACK action (release cb) is never going + * to happen, since we are going down, * so we + * need to run terminal_del manually */ + tsnif_detach(term); + terminal_del(term); + } + + return 0; +} + struct tsnif_ops ops = { .cb_data = data_cb, .cb_err = err_cb, @@ -199,6 +350,9 @@ int main(int argc, char **argv) if ((ret = setjmp(env))) { + if (ret > 1) + release_terms(); + tsnif_close(&handle); printf("done err = %d\n", err); return err; @@ -228,9 +382,9 @@ int main(int argc, char **argv) if (FD_ISSET(ts_fd, &rfds)) { err = tsnif_process(&handle); if (err) - longjmp(env, 3); + longjmp(env, 2); } } - longjmp(env, 3); + longjmp(env, 2); } |