commit - 58ba20cd5353626db13092dc3d817c7cb3da925f
commit + 3a227e9a01ae58219cafb85deca09d7efd78597a
blob - 52f9de718c26583b514690d60d90ce3205be586d
blob + 9150b2ae1134e4c1faa1fd8271d3f8432ed4f764
--- fs.c
+++ fs.c
/*
* Handles the data in ~/.telescope
+ *
+ * TODO: add some form of locking on the files
*/
#include "telescope.h"
static void handle_get(struct imsg*, size_t);
static void handle_quit(struct imsg*, size_t);
static void handle_bookmark_page(struct imsg*, size_t);
+static void handle_save_cert(struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
static struct event imsgev;
static struct imsgbuf *ibuf;
static char bookmark_file[PATH_MAX];
+static char known_hosts_file[PATH_MAX];
static imsg_handlerfn *handlers[] = {
[IMSG_GET] = handle_get,
[IMSG_QUIT] = handle_quit,
[IMSG_BOOKMARK_PAGE] = handle_bookmark_page,
+ [IMSG_SAVE_CERT] = handle_save_cert,
};
static void __attribute__((__noreturn__))
}
static void
+handle_save_cert(struct imsg *imsg, size_t datalen)
+{
+ struct tofu_entry e;
+ FILE *f;
+ int res;
+
+ /* TODO: traverse the file to avoid duplications? */
+
+ if (datalen != sizeof(e))
+ die();
+ memcpy(&e, imsg->data, datalen);
+
+ if ((f = fopen(known_hosts_file, "a")) == NULL) {
+ res = errno;
+ goto end;
+ }
+ fprintf(f, "%s %s %d\n", e.domain, e.hash, e.verified);
+ fclose(f);
+
+ res = 0;
+end:
+ imsg_compose(ibuf, IMSG_SAVE_CERT_OK, imsg->hdr.peerid, 0, -1,
+ &res, sizeof(res));
+ imsg_flush(ibuf);
+}
+
+static void
handle_dispatch_imsg(int fd, short ev, void *d)
{
struct imsgbuf *ibuf = d;
}
int
-fs_main(struct imsgbuf *b)
+fs_init(void)
{
- ibuf = b;
+ /* TODO: mkdir(~/.telescope) and touch bookmarks.gmi/known_hosts? */
strlcpy(bookmark_file, getenv("HOME"), sizeof(bookmark_file));
strlcat(bookmark_file, "/.telescope/bookmarks.gmi", sizeof(bookmark_file));
+ strlcpy(known_hosts_file, getenv("HOME"), sizeof(known_hosts_file));
+ strlcat(known_hosts_file, "/.telescope/known_hosts", sizeof(known_hosts_file));
+
+ return 1;
+}
+
+int
+fs_main(struct imsgbuf *b)
+{
+ ibuf = b;
+
event_init();
event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, handle_dispatch_imsg, ibuf);
event_dispatch();
return 0;
}
+
+
+
+int
+load_certs(struct ohash *h)
+{
+ char *p, *last, *errstr, *el, *line = NULL;
+ int i;
+ size_t linesize = 0;
+ ssize_t linelen;
+ FILE *f;
+ struct tofu_entry *e;
+
+ if ((f = fopen(known_hosts_file, "r")) == NULL)
+ return 0;
+
+ while ((linelen = getline(&line, &linesize, f)) != -1) {
+ if ((e = calloc(1, sizeof(*e))) == NULL)
+ abort();
+
+ i = 0;
+ for ((p = strtok_r(line, " ", &last)); p;
+ (p = strtok_r(NULL, " ", &last))) {
+ if (*p == '\n') {
+ free(e);
+ break;
+ }
+
+ switch (i) {
+ case 0:
+ strlcpy(e->domain, p, sizeof(e->domain));
+ break;
+ case 1:
+ strlcpy(e->hash, p, sizeof(e->hash));
+ break;
+ case 2:
+ if ((el = strchr(p, '\n')) == NULL)
+ abort();
+ *el = '\0';
+
+ /* 0 <= verified <= 1 */
+ e->verified = strtonum(p, -1, 2, &errstr);
+ if (errstr != NULL)
+ errx(1, "verification for %s is %s: %s",
+ e->domain, errstr, p);
+ break;
+ default:
+ abort();
+ }
+ i++;
+ }
+
+ if (i != 0 && i != 3)
+ abort();
+
+ if (i != 0)
+ telescope_ohash_insert(h, e);
+ }
+
+ free(line);
+ return ferror(f);
+}
blob - 0f0b79b109c3b7513a761b3e1f2ec9700233e4d3
blob + 7970f07dd792b041a6afdb00a5d4321e813f98f5
--- telescope.c
+++ telescope.c
static void handle_imsg_buf(struct imsg*, size_t);
static void handle_imsg_eof(struct imsg*, size_t);
static void handle_imsg_bookmark_ok(struct imsg*, size_t);
+static void handle_imsg_save_cert_ok(struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
static void load_page_from_str(struct tab*, const char*);
static void do_load_url(struct tab*, const char*);
[IMSG_BUF] = handle_imsg_buf,
[IMSG_EOF] = handle_imsg_eof,
[IMSG_BOOKMARK_OK] = handle_imsg_bookmark_ok,
+ [IMSG_SAVE_CERT_OK] = handle_imsg_save_cert_ok,
};
static struct ohash certs;
strlcpy(e->domain, tab->url.host, sizeof(e->domain));
strlcpy(e->hash, hash, sizeof(e->hash));
telescope_ohash_insert(&certs, e);
+ imsg_compose(fsibuf, IMSG_SAVE_CERT, tab->id, 0, -1,
+ e, sizeof(*e));
+ imsg_flush(fsibuf);
} else
tofu_res = !strcmp(hash, e->hash);
}
static void
+handle_imsg_save_cert_ok(struct imsg *imsg, size_t datalen)
+{
+ int res;
+
+ if (datalen != sizeof(res))
+ die();
+ memcpy(&res, imsg->data, datalen);
+ if (res != 0)
+ ui_notify("Failed to save the cert for: %s",
+ strerror(res));
+}
+
+static void
handle_dispatch_imsg(int fd, short ev, void *d)
{
struct imsgbuf *ibuf = d;
signal(SIGCHLD, SIG_IGN);
+ /* initialize part of the fs layer. Before starting the UI
+ * and dropping the priviledges we need to read some stuff. */
+ fs_init();
+
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fs_fds) == -1)
err(1, "socketpair");
setproctitle("(%d) ui", pid);
telescope_ohash_init(&certs, 5, offsetof(struct tofu_entry, domain));
+ load_certs(&certs);
TAILQ_INIT(&tabshead);
blob - e73ac6d28bd4561c82014846568e4ff45d7efe62
blob + e2832ad89223268a6cf04b4c834b19187fb671e6
--- telescope.h
+++ telescope.h
/* ui <-> fs */
IMSG_BOOKMARK_PAGE,
IMSG_BOOKMARK_OK,
+ IMSG_SAVE_CERT,
+ IMSG_SAVE_CERT_OK,
};
enum line_type {
};
/* fs.c */
+int fs_init(void);
int fs_main(struct imsgbuf*);
+int load_certs(struct ohash*);
/* gemini.c */
int client_main(struct imsgbuf*);
blob - c47a83b8c5a88d648f19103f2f6f69753bff09d4
blob + 88a155f7dac24ee2cba73a819c8ed0e2fd51ae35
--- util.c
+++ util.c
return;
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
i = imsg.hdr.type;
- if (i >= (size / sizeof(imsg_handlerfn*)) || handlers[i] == NULL)
+ if (i > (size / sizeof(imsg_handlerfn*)) || handlers[i] == NULL)
abort();
handlers[i](&imsg, datalen);
imsg_free(&imsg);