diff options
Diffstat (limited to 'src/tsnifd-storage.c')
-rw-r--r-- | src/tsnifd-storage.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/tsnifd-storage.c b/src/tsnifd-storage.c new file mode 100644 index 0000000..152221f --- /dev/null +++ b/src/tsnifd-storage.c @@ -0,0 +1,149 @@ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <time.h> + +#include "tsnifd.h" +#include "debug.h" + +static struct tsnif_storage_opts init_storage_opts = { + .flags = TSNIF_STORAGE_OPT_WRITE, + .size_max = 1024*1024, +}; + +char *storage_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(storage_dir)) + return NULL; + + type_str = type_get(type); + if (!type_str) + return NULL; + + len = snprintf(path, MAXPATH, "%s/%s", storage_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; + + p = strrchr(new, '-'); + if (!p) + return -1; + + sprintf(p, "%s", ".tsnif"); + + TSNIF_DEBUG(APP, "putting to %s\n", new); + + err = rename(name, new); + free(new); + return err; +} + +int storage_data(struct terminal *t, 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(&t->storage_handle, &rec); +} + +int storage_init(struct terminal *t) +{ + char *file; + + file = file_get(t->term.type, t->term.idx); + if (!file) + return -1; + + TSNIF_DEBUG(APP, "storing to %s\n", file); + + t->file = strdup(file); + t->storage_opts = init_storage_opts; + + return tsnif_storage_init(&t->storage_handle, + &t->storage_opts, file); +} + +int storage_close(struct terminal *t) +{ + tsnif_storage_close(&t->storage_handle); + file_put(t->file); + free(t->file); + return 0; +} |