commit f63b8f7342aefba6b3dac50d6790981987c8faa8 from: Omar Polo date: Sun Apr 24 10:15:32 2022 UTC merge the fs into the ui process The previous separation between the fs and ui process wasn't that good. The idea was to have a `ui' process tightly sandboxed, but it was a lie actually. `ui' was one imsg away from making internet connections and accessing data on the disk, so it wasn't really limited in (almost) any way. Furthermore, having to serialize data to/from the fs proc started to become not really maneagable. As a first step to fix this situation, join the fs and ui process. commit - 55aa433f8f1327733b5f8695d0f211c8c3ab8077 commit + f63b8f7342aefba6b3dac50d6790981987c8faa8 blob - a8bb49116b2901be99e92fbcce1554a3d848d710 blob + 688094dbafe4a14e728cc4f0f42953cc5c52aacb --- downloads.c +++ downloads.c @@ -79,7 +79,7 @@ end: wrap_page(&downloadwin, download_cols); } -void +struct download * enqueue_download(uint32_t id, const char *path, int buffer) { struct download *d; @@ -93,6 +93,8 @@ enqueue_download(uint32_t id, const char *path, int bu d->buffer = buffer; STAILQ_INSERT_HEAD(&downloads, d, entries); + + return d; } void blob - 3d7a767702543a6d9cd2ab23a78ee3b5f600f7a1 blob + 2309904c0b78c1bf3d1042531cd40b17c2442cbd --- fs.c +++ fs.c @@ -33,30 +33,21 @@ #include #include -#include "fs.h" #include "pages.h" -#include "telescope.h" +#include "parser.h" #include "session.h" +#include "telescope.h" #include "utils.h" +#include "fs.h" + +#ifndef nitems +#define nitems(x) (sizeof(x) / sizeof(x[0])) +#endif + static void die(void) __attribute__((__noreturn__)); -static void send_file(uint32_t, FILE *); -static void handle_get(struct imsg*, size_t); static int select_non_dot(const struct dirent *); static int select_non_dotdot(const struct dirent *); -static void handle_get_file(struct imsg*, size_t); -static void handle_misc(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_update_cert(struct imsg*, size_t); -static void handle_file_open(struct imsg*, size_t); -static void handle_session_start(struct imsg*, size_t); -static void handle_session_tab(struct imsg*, size_t); -static void handle_session_tab_hist(struct imsg*, size_t); -static void handle_session_end(struct imsg*, size_t); -static void handle_hist(struct imsg *, size_t); -static void handle_dispatch_imsg(int, short, void*); -static int fs_send_ui(int, uint32_t, int, const void *, uint16_t); static size_t join_path(char*, const char*, const char*, size_t); static void getenv_default(char*, const char*, const char*, size_t); static void mkdirs(const char*, mode_t); @@ -64,11 +55,8 @@ static void init_paths(void); static void load_last_session(void); static void load_hist(void); static int last_time_crashed(void); -static void load_certs(void); +static void load_certs(struct ohash *); -static struct imsgev *iev_ui; -static FILE *session; - /* * Where to store user data. These are all equal to ~/.telescope if * it exists. @@ -84,342 +72,225 @@ char bookmark_file[PATH_MAX]; char known_hosts_file[PATH_MAX], known_hosts_tmp[PATH_MAX]; char crashed_file[PATH_MAX]; char session_file[PATH_MAX]; -static char history_file[PATH_MAX]; +char history_file[PATH_MAX]; -static imsg_handlerfn *handlers[] = { - [IMSG_GET] = handle_get, - [IMSG_GET_FILE] = handle_get_file, - [IMSG_QUIT] = handle_misc, - [IMSG_INIT] = handle_misc, - [IMSG_BOOKMARK_PAGE] = handle_bookmark_page, - [IMSG_SAVE_CERT] = handle_save_cert, - [IMSG_UPDATE_CERT] = handle_update_cert, - [IMSG_FILE_OPEN] = handle_file_open, - [IMSG_SESSION_START] = handle_session_start, - [IMSG_SESSION_TAB] = handle_session_tab, - [IMSG_SESSION_TAB_HIST] = handle_session_tab_hist, - [IMSG_SESSION_END] = handle_session_end, - [IMSG_HIST_ITEM] = handle_hist, - [IMSG_HIST_END] = handle_hist, -}; - static void __attribute__((__noreturn__)) die(void) { abort(); /* TODO */ } -static void -send_file(uint32_t peerid, FILE *f) +static int +select_non_dot(const struct dirent *d) { - ssize_t r; - char buf[BUFSIZ]; + return strcmp(d->d_name, "."); +} - for (;;) { - r = fread(buf, 1, sizeof(buf), f); - if (r != 0) - fs_send_ui(IMSG_BUF, peerid, -1, buf, r); - if (r != sizeof(buf)) - break; - } - fs_send_ui(IMSG_EOF, peerid, -1, NULL, 0); - fclose(f); +static int +select_non_dotdot(const struct dirent *d) +{ + return strcmp(d->d_name, ".") && strcmp(d->d_name, ".."); } static void -handle_get(struct imsg *imsg, size_t datalen) +send_dir(struct tab *tab, const char *path) { - const char *bpath = "bookmarks.gmi"; - char path[PATH_MAX]; - FILE *f; - const char *data, *p; - size_t i; - struct page { - const char *name; - const char *path; - const uint8_t *data; - size_t len; - } pages[] = { - {"about", NULL, about_about, about_about_len}, - {"blank", NULL, about_blank, about_blank_len}, - {"bookmarks", bpath, bookmarks, bookmarks_len}, - {"crash", NULL, about_crash, about_crash_len}, - {"help", NULL, about_help, about_help_len}, - {"license", NULL, about_license, about_license_len}, - {"new", NULL, about_new, about_new_len}, - }, *page = NULL; + struct dirent **names; + int (*selector)(const struct dirent *) = select_non_dot; + int i, len; - data = imsg->data; - if (data[datalen-1] != '\0') /* make sure it's NUL-terminated */ - die(); - if ((data = strchr(data, ':')) == NULL) - goto notfound; - data++; +#if notyet + /* + * need something to fake a redirect + */ - for (i = 0; i < sizeof(pages)/sizeof(pages[0]); ++i) - if (!strcmp(data, pages[i].name)) { - page = &pages[i]; - break; - } - - if (page == NULL) - goto notfound; - - strlcpy(path, data_path_base, sizeof(path)); - strlcat(path, "/", sizeof(path)); - if (page->path != NULL) - strlcat(path, page->path, sizeof(path)); - else { - strlcat(path, "pages/about_", sizeof(path)); - strlcat(path, page->name, sizeof(path)); - strlcat(path, ".gmi", sizeof(path)); + if (!has_suffix(path, "/")) { + if (asprintf(&s, "%s/", path) == -1) + die(); + send_hdr(peerid, 30, s); + free(s); + return; } +#endif - if ((f = fopen(path, "r")) == NULL) { - fs_send_ui(IMSG_BUF, imsg->hdr.peerid, -1, - page->data, page->len); - fs_send_ui(IMSG_EOF, imsg->hdr.peerid, -1, - NULL, 0); + if (!strcmp(path, "/")) + selector = select_non_dotdot; + + if ((len = scandir(path, &names, selector, alphasort)) == -1) { + load_page_from_str(tab, "# failure reading the directory\n"); return; } - send_file(imsg->hdr.peerid, f); - return; + parser_init(tab, gemtext_initparser); + parser_parsef(tab, "# Index of %s\n\n", path); -notfound: - p = "# not found!\n"; - fs_send_ui(IMSG_BUF, imsg->hdr.peerid, -1, p, strlen(p)); - fs_send_ui(IMSG_EOF, imsg->hdr.peerid, -1, NULL, 0); -} + for (i = 0; i < len; ++i) { + const char *sufx = ""; -static inline void -send_hdr(uint32_t peerid, int code, const char *meta) -{ - fs_send_ui(IMSG_GOT_CODE, peerid, -1, &code, sizeof(code)); - fs_send_ui(IMSG_GOT_META, peerid, -1, meta, strlen(meta)+1); + if (names[i]->d_type == DT_DIR) + sufx = "/"; + + parser_parsef(tab, "=> %s%s\n", names[i]->d_name, sufx); + } + + parser_free(tab); + free(names); } -static inline void -send_errno(uint32_t peerid, int code, const char *str, int no) +static int +is_dir(FILE *fp) { - char *s; + struct stat sb; - if (asprintf(&s, "%s: %s", str, strerror(no)) == -1) - s = NULL; + if (fstat(fileno(fp), &sb) == -1) + return 0; - send_hdr(peerid, code, s == NULL ? str : s); - free(s); + return S_ISDIR(sb.st_mode); } -static inline const char * +static parserinit file_type(const char *path) { struct mapping { const char *ext; - const char *mime; + parserinit fn; } ms[] = { - {"diff", "text/x-patch"}, - {"gemini", "text/gemini"}, - {"gmi", "text/gemini"}, - {"markdown", "text/plain"}, - {"md", "text/plain"}, - {"patch", "text/x-patch"}, - {"txt", "text/plain"}, + {"diff", textpatch_initparser}, + {"gemini", gemtext_initparser}, + {"gmi", gemtext_initparser}, + {"markdown", textplain_initparser}, + {"md", textplain_initparser}, + {"patch", gemtext_initparser}, {NULL, NULL}, }, *m; char *dot; if ((dot = strrchr(path, '.')) == NULL) - return NULL; + return textplain_initparser; dot++; for (m = ms; m->ext != NULL; ++m) if (!strcmp(m->ext, dot)) - return m->mime; + return m->fn; - return NULL; + return textplain_initparser; } -static int -select_non_dot(const struct dirent *d) +void +fs_load_url(struct tab *tab, const char *url) { - return strcmp(d->d_name, "."); -} - -static int -select_non_dotdot(const struct dirent *d) -{ - return strcmp(d->d_name, ".") && strcmp(d->d_name, ".."); -} + const char *bpath = "bookmarks.gmi", *fallback = "# Not found\n"; + parserinit initfn = gemtext_initparser; + char path[PATH_MAX]; + FILE *fp = NULL; + size_t i; + char buf[BUFSIZ]; + struct page { + const char *name; + const char *path; + const uint8_t *data; + size_t len; + } pages[] = { + {"about", NULL, about_about, about_about_len}, + {"blank", NULL, about_blank, about_blank_len}, + {"bookmarks", bpath, bookmarks, bookmarks_len}, + {"crash", NULL, about_crash, about_crash_len}, + {"help", NULL, about_help, about_help_len}, + {"license", NULL, about_license, about_license_len}, + {"new", NULL, about_new, about_new_len}, + }, *page = NULL; -static inline void -send_dir(uint32_t peerid, const char *path) -{ - struct dirent **names; - struct evbuffer *ev; - char *s; - int (*selector)(const struct dirent *) = select_non_dot; - int i, len, no; + if (!strncmp(url, "about:", 6)) { + url += 6; - if (!has_suffix(path, "/")) { - if (asprintf(&s, "%s/", path) == -1) - die(); - send_hdr(peerid, 30, s); - free(s); - return; - } + for (i = 0; page == NULL && i < nitems(pages); ++i) { + if (!strcmp(url, pages[i].name)) + page = &pages[i]; + } - if (!strcmp(path, "/")) - selector = select_non_dotdot; + if (page == NULL) + goto done; - if ((ev = evbuffer_new()) == NULL || - (len = scandir(path, &names, selector, alphasort)) == -1) { - no = errno; - evbuffer_free(ev); - send_errno(peerid, 40, "failure reading the directory", no); - return; - } + strlcpy(path, data_path_base, sizeof(path)); + strlcat(path, "/", sizeof(path)); + if (page->path != NULL) + strlcat(path, page->path, sizeof(path)); + else { + strlcat(path, "page/about_", sizeof(path)); + strlcat(path, page->name, sizeof(path)); + strlcat(path, ".gmi", sizeof(path)); + } - evbuffer_add_printf(ev, "# Index of %s\n\n", path); - for (i = 0; i < len; ++i) { - evbuffer_add_printf(ev, "=> %s", names[i]->d_name); - if (names[i]->d_type == DT_DIR) - evbuffer_add(ev, "/", 1); - evbuffer_add(ev, "\n", 1); - } + fallback = page->data; + } else if (!strncmp(url, "file://", 7)) { + url += 7; + strlcpy(path, url, sizeof(path)); + initfn = file_type(url); + } else + goto done; - send_hdr(peerid, 20, "text/gemini"); - fs_send_ui(IMSG_BUF, peerid, -1, - EVBUFFER_DATA(ev), EVBUFFER_LENGTH(ev)); - fs_send_ui(IMSG_EOF, peerid, -1, NULL, 0); + if ((fp = fopen(path, "r")) == NULL) + goto done; - evbuffer_free(ev); - free(names); -} - -static void -handle_get_file(struct imsg *imsg, size_t datalen) -{ - struct stat sb; - FILE *f; - char *data; - const char *meta = NULL; - - data = imsg->data; - data[datalen-1] = '\0'; - - if ((f = fopen(data, "r")) == NULL) { - send_errno(imsg->hdr.peerid, 51, "can't open", errno); - return; + if (is_dir(fp)) { + fclose(fp); + send_dir(tab, path); + goto done; } - if (fstat(fileno(f), &sb) == -1) { - send_errno(imsg->hdr.peerid, 40, "fstat", errno); - return; - } + parser_init(tab, initfn); + for (;;) { + size_t r; - if (S_ISDIR(sb.st_mode)) { - fclose(f); - send_dir(imsg->hdr.peerid, data); - return; + r = fread(buf, 1, sizeof(buf), fp); + if (!parser_parse(tab, buf, r)) + break; + if (r != sizeof(buf)) + break; } + parser_free(tab); - if ((meta = file_type(data)) == NULL) { - fclose(f); - send_hdr(imsg->hdr.peerid, 51, - "don't know how to visualize this file"); - return; - } - - send_hdr(imsg->hdr.peerid, 20, meta); - send_file(imsg->hdr.peerid, f); +done: + if (fp != NULL) + fclose(fp); + else + load_page_from_str(tab, fallback); } -static void -handle_misc(struct imsg *imsg, size_t datalen) +int +bookmark_page(const char *url) { - switch (imsg->hdr.type) { - case IMSG_INIT: - load_certs(); - load_hist(); - load_last_session(); - break; + FILE *f; - case IMSG_QUIT: - if (!safe_mode) - unlink(crashed_file); - event_loopbreak(); - break; - - default: - die(); - } + if ((f = fopen(bookmark_file, "a")) == NULL) + return -1; + fprintf(f, "=> %s\n", url); + fclose(f); + return 0; } -static void -handle_bookmark_page(struct imsg *imsg, size_t datalen) +int +save_cert(const struct tofu_entry *e) { - char *data; - int res; - FILE *f; + FILE *f; - data = imsg->data; - if (data[datalen-1] != '\0') - die(); - - if ((f = fopen(bookmark_file, "a")) == NULL) { - res = errno; - goto end; - } - fprintf(f, "=> %s\n", data); + if ((f = fopen(known_hosts_file, "a")) == NULL) + return -1; + fprintf(f, "%s %s %d\n", e->domain, e->hash, e->verified); fclose(f); - - res = 0; -end: - fs_send_ui(IMSG_BOOKMARK_OK, 0, -1, &res, sizeof(res)); + return 0; } -static void -handle_save_cert(struct imsg *imsg, size_t datalen) +int +update_cert(const struct tofu_entry *e) { - 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: - fs_send_ui(IMSG_SAVE_CERT_OK, imsg->hdr.peerid, -1, - &res, sizeof(res)); -} - -static void -handle_update_cert(struct imsg *imsg, size_t datalen) -{ FILE *tmp, *f; - struct tofu_entry entry; char sfn[PATH_MAX], *line = NULL, *t; size_t l, linesize = 0; ssize_t linelen; - int fd, e, res = 0; + int fd, err; - if (datalen != sizeof(entry)) - die(); - memcpy(&entry, imsg->data, datalen); - strlcpy(sfn, known_hosts_tmp, sizeof(sfn)); if ((fd = mkstemp(sfn)) == -1 || (tmp = fdopen(fd, "w")) == NULL) { @@ -427,190 +298,41 @@ handle_update_cert(struct imsg *imsg, size_t datalen) unlink(sfn); close(fd); } - res = 0; - goto end; + return -1; } if ((f = fopen(known_hosts_file, "r")) == NULL) { unlink(sfn); fclose(tmp); - res = 0; - goto end; + return -1; } - l = strlen(entry.domain); + l = strlen(e->domain); while ((linelen = getline(&line, &linesize, f)) != -1) { - if ((t = strstr(line, entry.domain)) != NULL && + if ((t = strstr(line, e->domain)) != NULL && (line[l] == ' ' || line[l] == '\t')) continue; /* line has a trailing \n */ fprintf(tmp, "%s", line); } - fprintf(tmp, "%s %s %d\n", entry.domain, entry.hash, entry.verified); + fprintf(tmp, "%s %s %d\n", e->domain, e->hash, e->verified); free(line); - e = ferror(tmp); + err = ferror(tmp); fclose(tmp); fclose(f); - if (e) { + if (err) { unlink(sfn); - res = 0; - goto end; + return -1; } - res = rename(sfn, known_hosts_file) != -1; - -end: - fs_send_ui(IMSG_UPDATE_CERT_OK, imsg->hdr.peerid, -1, - &res, sizeof(res)); -} - -static void -handle_file_open(struct imsg *imsg, size_t datalen) -{ - char *path, *e; - int fd; - - path = imsg->data; - if (path[datalen-1] != '\0') - die(); - - if ((fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644)) == -1) { - e = strerror(errno); - fs_send_ui(IMSG_FILE_OPENED, imsg->hdr.peerid, -1, - e, strlen(e)+1); - } else - fs_send_ui(IMSG_FILE_OPENED, imsg->hdr.peerid, fd, - NULL, 0); -} - -static void -handle_session_start(struct imsg *imsg, size_t datalen) -{ - if (datalen != 0) - die(); - - if ((session = fopen(session_file, "w")) == NULL) - die(); -} - -static void -handle_session_tab(struct imsg *imsg, size_t datalen) -{ - struct session_tab tab; - - if (session == NULL) - die(); - - if (datalen != sizeof(tab)) - die(); - - memcpy(&tab, imsg->data, sizeof(tab)); - if (tab.uri[sizeof(tab.uri)-1] != '\0' || - tab.title[sizeof(tab.title)-1] != '\0') - die(); - - fprintf(session, "%s ", tab.uri); - - if (tab.flags & TAB_CURRENT) - fprintf(session, "current,"); - if (tab.flags & TAB_KILLED) - fprintf(session, "killed,"); - - fprintf(session, "top=%zu,cur=%zu %s\n", tab.top_line, - tab.current_line, tab.title); -} - -static void -handle_session_tab_hist(struct imsg *imsg, size_t datalen) -{ - struct session_tab_hist th; - - if (session == NULL) - die(); - - if (datalen != sizeof(th)) - die(); - - memcpy(&th, imsg->data, sizeof(th)); - if (th.uri[sizeof(th.uri)-1] != '\0') - die(); - - fprintf(session, "%s %s\n", th.future ? ">" : "<", th.uri); -} - -static void -handle_session_end(struct imsg *imsg, size_t datalen) -{ - if (session == NULL) - die(); - fclose(session); - session = NULL; -} - -static void -handle_hist(struct imsg *imsg, size_t datalen) -{ - static FILE *hist; - struct histitem hi; - - switch (imsg->hdr.type) { - case IMSG_HIST_ITEM: - if (hist == NULL) { - if ((hist = fopen(history_file, "a")) == NULL) - return; - } - if (datalen != sizeof(hi)) - abort(); - memcpy(&hi, imsg->data, sizeof(hi)); - fprintf(hist, "%lld %s\n", (long long)hi.ts, hi.uri); - break; - - case IMSG_HIST_END: - if (hist == NULL) - return; - fclose(hist); - hist = NULL; - break; - - default: - abort(); - } -} - -static void -handle_dispatch_imsg(int fd, short ev, void *d) -{ - struct imsgev *iev = d; - int e; - - if (dispatch_imsg(iev, ev, handlers, sizeof(handlers)) == -1) { - /* - * This should leave a ~/.cache/telescope/crashed file to - * trigger about:crash on next run. Unfortunately, if - * the main process dies the fs sticks around and - * doesn't notice that the fd was closed. Why EV_READ - * is not triggered when a fd is closed on the other end? - */ - e = errno; - if ((fd = open(crashed_file, O_CREAT|O_TRUNC|O_WRONLY, 0600)) - == -1) - err(1, "open"); - close(fd); - errx(1, "connection closed: %s", strerror(e)); - } + if (rename(sfn, known_hosts_file)) + return -1; + return 0; } -static int -fs_send_ui(int type, uint32_t peerid, int fd, const void *data, - uint16_t datalen) -{ - return imsg_compose_event(iev_ui, type, peerid, 0, fd, - data, datalen); -} - static size_t join_path(char *buf, const char *lhs, const char *rhs, size_t buflen) { @@ -733,80 +455,89 @@ fs_init(void) } /* - * Parse a line of the session file. The format is: + * Parse a line of the session file and restores it. The format is: * * URL [flags,...] [title]\n */ -static void -parse_session_line(char *line) +static inline struct tab * +parse_session_line(char *line, struct tab **ct) { - struct session_tab tab; + struct tab *tab; char *s, *t, *ap; + const char *uri, *title = ""; + int current = 0, killed = 0; + size_t top_line = 0, current_line = 0; - memset(&tab, 0, sizeof(tab)); - + uri = line; if ((s = strchr(line, ' ')) == NULL) - return; + return NULL; *s++ = '\0'; - if (strlcpy(tab.uri, line, sizeof(tab.uri)) >= sizeof(tab.uri)) - return; - if ((t = strchr(s, ' ')) != NULL) { *t++ = '\0'; - - /* don't worry about cached title truncation */ - strlcpy(tab.title, t, sizeof(tab.title)); + title = t; } while ((ap = strsep(&s, ",")) != NULL) { if (!strcmp(ap, "current")) - tab.flags |= TAB_CURRENT; + current = 1; else if (!strcmp(ap, "killed")) - tab.flags |= TAB_KILLED; + killed = 1; else if (has_prefix(ap, "top=")) - tab.top_line = strtonum(ap+4, 0, UINT32_MAX, NULL); + top_line = strtonum(ap+4, 0, UINT32_MAX, NULL); else if (has_prefix(ap, "cur=")) - tab.current_line = strtonum(ap+4, 0, UINT32_MAX, NULL); + current_line = strtonum(ap+4, 0, UINT32_MAX, NULL); } - if (tab.top_line > tab.current_line) { - tab.top_line = 0; - tab.current_line = 0; + if (top_line > current_line) { + top_line = 0; + current_line = 0; } - fs_send_ui(IMSG_SESSION_TAB, 0, -1, &tab, sizeof(tab)); + if ((tab = new_tab(uri, NULL, NULL)) == NULL) + die(); + tab->hist_cur->line_off = top_line; + tab->hist_cur->current_off = current_line; + strlcpy(tab->buffer.page.title, title, sizeof(tab->buffer.page.title)); + + if (current) + *ct = tab; + else if (killed) + kill_tab(tab, 1); + + return tab; } static inline void -sendhist(const char *uri, int future) +sendhist(struct tab *tab, const char *uri, int future) { - struct session_tab_hist sth; + struct hist *h; - memset(&sth, 0, sizeof(sth)); - sth.future = future; + if ((h = calloc(1, sizeof(*h))) == NULL) + die(); + strlcpy(h->h, uri, sizeof(h->h)); - if (strlcpy(sth.uri, uri, sizeof(sth.uri)) >= sizeof(sth.uri)) - return; - - fs_send_ui(IMSG_SESSION_TAB_HIST, 0, -1, &sth, sizeof(sth)); + if (future) + hist_push(&tab->hist, h); + else + hist_add_before(&tab->hist, tab->hist_cur, h); } static void load_last_session(void) { + struct tab *tab = NULL, *ct = NULL; FILE *session; size_t linesize = 0; ssize_t linelen; - int first_time = 0; int future; char *nl, *s, *line = NULL; if ((session = fopen(session_file, "r")) == NULL) { - /* first time? */ - first_time = 1; - goto end; + new_tab("about:new", NULL, NULL); + switch_to_tab(new_tab("about:help", NULL, NULL)); + return; } while ((linelen = getline(&line, &linesize, session)) != -1) { @@ -816,27 +547,22 @@ load_last_session(void) if (*line == '<' || *line == '>') { future = *line == '>'; s = line+1; - if (*s != ' ') + if (*s != ' ' || tab == NULL) continue; - sendhist(++s, future); + sendhist(tab, ++s, future); } else { - parse_session_line(line); + tab = parse_session_line(line, &ct); } } fclose(session); free(line); - if (last_time_crashed()) { - struct session_tab tab; - memset(&tab, 0, sizeof(tab)); - tab.flags = TAB_CURRENT; - strlcpy(tab.uri, "about:crash", sizeof(tab.uri)); - fs_send_ui(IMSG_SESSION_TAB, 0, -1, &tab, sizeof(tab)); - } + if (ct != NULL) + switch_to_tab(ct); -end: - fs_send_ui(IMSG_SESSION_END, 0, -1, &first_time, sizeof(first_time)); + if (last_time_crashed()) + switch_to_tab(new_tab("about:crash", NULL, NULL)); } static void @@ -850,7 +576,7 @@ load_hist(void) struct histitem hi; if ((hist = fopen(history_file, "r")) == NULL) - goto end; + return; while ((linelen = getline(&line, &linesize, hist)) != -1) { if ((nl = strchr(line, '\n')) != NULL) @@ -867,37 +593,21 @@ load_hist(void) if (strlcpy(hi.uri, spc, sizeof(hi.uri)) >= sizeof(hi.uri)) continue; - fs_send_ui(IMSG_HIST_ITEM, 0, -1, &hi, sizeof(hi)); + history_push(&hi); } fclose(hist); free(line); -end: - fs_send_ui(IMSG_HIST_END, 0, -1, NULL, 0); + + history_sort(); } int -fs_main(void) +fs_load_state(struct ohash *certs) { - setproctitle("fs"); - - fs_init(); - - event_init(); - - /* Setup pipe and event handler to the main process */ - if ((iev_ui = malloc(sizeof(*iev_ui))) == NULL) - die(); - imsg_init(&iev_ui->ibuf, 3); - iev_ui->handler = handle_dispatch_imsg; - iev_ui->events = EV_READ; - event_set(&iev_ui->ev, iev_ui->ibuf.fd, iev_ui->events, - iev_ui->handler, iev_ui); - event_add(&iev_ui->ev, NULL); - - sandbox_fs_process(); - - event_dispatch(); + load_certs(certs); + load_hist(); + load_last_session(); return 0; } @@ -962,33 +672,37 @@ parse_khost_line(char *line, char *tmp[3]) } static void -load_certs(void) +load_certs(struct ohash *certs) { char *tmp[3], *line = NULL; const char *errstr; size_t lineno = 0, linesize = 0; ssize_t linelen; FILE *f; - struct tofu_entry e; + struct tofu_entry *e; if ((f = fopen(known_hosts_file, "r")) == NULL) return; + if ((e = calloc(1, sizeof(*e))) == NULL) { + fclose(f); + return; + } + while ((linelen = getline(&line, &linesize, f)) != -1) { lineno++; - memset(&e, 0, sizeof(e)); if (parse_khost_line(line, tmp)) { - strlcpy(e.domain, tmp[0], sizeof(e.domain)); - strlcpy(e.hash, tmp[1], sizeof(e.hash)); + strlcpy(e->domain, tmp[0], sizeof(e->domain)); + strlcpy(e->hash, tmp[1], sizeof(e->hash)); - e.verified = strtonum(tmp[2], 0, 1, &errstr); + e->verified = strtonum(tmp[2], 0, 1, &errstr); if (errstr != NULL) errx(1, "%s:%zu verification for %s is %s: %s", known_hosts_file, lineno, - e.domain, errstr, tmp[2]); + e->domain, errstr, tmp[2]); - fs_send_ui(IMSG_TOFU, 0, -1, &e, sizeof(e)); + tofu_add(certs, e); } else { warnx("%s:%zu invalid entry", known_hosts_file, lineno); @@ -999,4 +713,3 @@ load_certs(void) fclose(f); return; } - blob - 6337fed6e6cfa36597a25e71245cf9b17eec0d16 blob + da0257e65eb443f4bdfca3f75baa41cce5e60076 --- include/fs.h +++ include/fs.h @@ -17,10 +17,9 @@ #ifndef FS_H #define FS_H -#include "compat.h" +struct tab; +struct tofu_entry; -#include - extern char config_path_base[PATH_MAX]; extern char data_path_base[PATH_MAX]; extern char cache_path_base[PATH_MAX]; @@ -32,9 +31,14 @@ extern char bookmark_file[PATH_MAX]; extern char known_hosts_file[PATH_MAX], known_hosts_tmp[PATH_MAX]; extern char crashed_file[PATH_MAX]; extern char session_file[PATH_MAX]; +extern char history_file[PATH_MAX]; int fs_init(void); -int fs_main(void); int lock_session(void); +void fs_load_url(struct tab *, const char *); +int bookmark_page(const char *); +int save_cert(const struct tofu_entry *e); +int update_cert(const struct tofu_entry *e); +int fs_load_state(struct ohash *); #endif blob - 6a667eb7b16f9dad1e16d5bf2c992fa983d7a215 blob + e84ebaa3ff51abebb6b2a55dbf935db3ccc15b46 --- include/telescope.h +++ include/telescope.h @@ -144,6 +144,8 @@ struct vline { struct parser; typedef int (*printfn)(void *, const char *, ...); + +typedef void (*parserinit)(struct parser *); typedef int (*parsechunkfn)(struct parser *, const char *, size_t); typedef int (*parserfreefn)(struct parser *); @@ -162,7 +164,7 @@ struct parser { #define PARSER_IN_PRE 2 #define PARSER_IN_PATCH_HDR 4 int flags; - void (*init)(struct parser *); + parserinit init; parsechunkfn parse; parserfreefn free; parserserial serialize; @@ -308,7 +310,7 @@ struct download { }; void recompute_downloads(void); -void enqueue_download(uint32_t, const char *, int); +struct download *enqueue_download(uint32_t, const char *, int); void dequeue_first_download(void); struct download *download_by_id(uint32_t); @@ -334,7 +336,6 @@ void parseconfig(const char *, int); /* sandbox.c */ void sandbox_net_process(void); void sandbox_ui_process(void); -void sandbox_fs_process(void); /* telescope.c */ extern int operating; @@ -350,11 +351,9 @@ void load_url(struct tab *, const char *, const char void load_url_in_tab(struct tab *, const char *, const char *, int); int load_previous_page(struct tab*); int load_next_page(struct tab*); -void add_to_bookmarks(const char*); void write_buffer(const char *, struct tab *); void humanify_url(const char *, char *, size_t); int ui_send_net(int, uint32_t, const void *, uint16_t); -int ui_send_fs(int, uint32_t, const void *, uint16_t); /* tofu.c */ void tofu_init(struct ohash*, unsigned int, ptrdiff_t); blob - 555f1d665c6d73a02a51cb9379bf25597b553d06 blob + f12756a98c82f0afcdb1f648e668b0c48b3355bd --- minibuffer.c +++ minibuffer.c @@ -16,10 +16,13 @@ #include "compat.h" +#include +#include #include #include #include +#include "fs.h" #include "minibuffer.h" #include "session.h" #include "ui.h" @@ -331,9 +334,11 @@ void bp_select(void) { exit_minibuffer(); - if (*ministate.buf != '\0') - add_to_bookmarks(ministate.buf); - else + if (*ministate.buf != '\0') { + if (!bookmark_page(ministate.buf)) + message("failed to bookmark page: %s", + strerror(errno)); + } else message("Abort."); } blob - 0f2c57ee4215b0e220bf6d9e0f1a1f0ae42ae4c6 blob + 87cfa487e43b3a8c143408f5da36fcf7a17f766b --- sandbox.c +++ sandbox.c @@ -16,13 +16,14 @@ #include "compat.h" +#include + #include "fs.h" #include "telescope.h" #ifdef __OpenBSD__ # include -# include # include # include # include @@ -37,13 +38,6 @@ sandbox_net_process(void) void sandbox_ui_process(void) { - if (pledge("stdio tty unix recvfd", NULL) == -1) - err(1, "pledge"); -} - -void -sandbox_fs_process(void) -{ char path[PATH_MAX]; if (unveil("/tmp", "rwc") == -1) @@ -63,7 +57,7 @@ sandbox_fs_process(void) if (unveil(cache_path_base, "rwc") == -1) err(1, "unveil(%s)", cache_path_base); - if (pledge("stdio rpath wpath cpath sendfd", NULL) == -1) + if (pledge("stdio rpath wpath cpath unix tty", NULL) == -1) err(1, "pledge"); } @@ -212,45 +206,11 @@ sandbox_net_process(void) void sandbox_ui_process(void) { - if (landlock_no_fs() == -1) - err(1, "landlock"); -} - -void -sandbox_fs_process(void) -{ - int fd, rwc; - char path[PATH_MAX]; - /* - * XXX: at build-time we found landlock.h but we've just - * realized it's not available on this kernel, so do nothing. + * Needs to be able to read files *and* execute programs, + * can't be sandboxed. */ - if ((fd = open_landlock()) == -1) - return; - - rwc = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_READ_DIR | - LANDLOCK_ACCESS_FS_WRITE_FILE | - LANDLOCK_ACCESS_FS_MAKE_DIR | - LANDLOCK_ACCESS_FS_MAKE_REG; - - if (landlock_unveil(fd, "/tmp", rwc) == -1) - err(1, "landlock_unveil(/tmp)"); - - strlcpy(path, getenv("HOME"), sizeof(path)); - strlcat(path, "/Downloads", sizeof(path)); - if (landlock_unveil(fd, path, rwc) == -1 && errno != ENOENT) - err(1, "landlock_unveil(%s)", path); - - if (landlock_unveil(fd, config_path_base, rwc) == -1) - err(1, "landlock_unveil(%s)", config_path_base); - - if (landlock_unveil(fd, data_path_base, rwc) == -1) - err(1, "landlock_unveil(%s)", data_path_base); - - if (landlock_unveil(fd, cache_path_base, rwc) == -1) - err(1, "landlock_unveil(%s)", cache_path_base); + return; } #else @@ -269,10 +229,4 @@ sandbox_ui_process(void) return; } -void -sandbox_fs_process(void) -{ - return; -} - #endif blob - d5cdb78eff0b21b41f3eaaab0448c30f63689e41 blob + b5bd2aaf1318f0aded094a8b90bd8a7519ff04d4 --- session.c +++ session.c @@ -17,6 +17,7 @@ #include "compat.h" #include +#include #include #include #include @@ -161,26 +162,23 @@ stop_tab(struct tab *tab) } static inline void -sendtab(struct tab *tab, int killed) +savetab(FILE *fp, struct tab *tab, int killed) { - struct session_tab st; - struct session_tab_hist sth; - struct hist *h; - int future; + struct hist *h; + size_t top_line, current_line; + int future; - memset(&st, 0, sizeof(st)); + get_scroll_position(tab, &top_line, ¤t_line); + fprintf(fp, "%s ", tab->hist_cur->h); if (tab == current_tab) - st.flags |= TAB_CURRENT; + fprintf(fp, "current,"); if (killed) - st.flags |= TAB_KILLED; + fprintf(fp, "killed,"); - get_scroll_position(tab, &st.top_line, &st.current_line); + fprintf(fp, "top=%zu,cur=%zu %s\n", top_line, current_line, + tab->buffer.page.title); - strlcpy(st.uri, tab->hist_cur->h, sizeof(st.uri)); - strlcpy(st.title, tab->buffer.page.title, sizeof(st.title)); - ui_send_fs(IMSG_SESSION_TAB, 0, &st, sizeof(st)); - future = 0; TAILQ_FOREACH(h, &tab->hist.head, entries) { if (h == tab->hist_cur) { @@ -188,33 +186,33 @@ sendtab(struct tab *tab, int killed) continue; } - memset(&sth, 0, sizeof(sth)); - strlcpy(sth.uri, h->h, sizeof(sth.uri)); - sth.future = future; - ui_send_fs(IMSG_SESSION_TAB_HIST, 0, &sth, sizeof(sth)); + fprintf(fp, "%s %s\n", future ? ">" : "<", h->h); } - } void save_session(void) { + FILE *session, *hist; struct tab *tab; - struct histitem hi; size_t i; if (safe_mode) return; - ui_send_fs(IMSG_SESSION_START, 0, NULL, 0); + if ((session = fopen(session_file, "w")) == NULL) + return; TAILQ_FOREACH(tab, &tabshead, tabs) - sendtab(tab, 0); + savetab(session, tab, 0); TAILQ_FOREACH(tab, &ktabshead, tabs) - sendtab(tab, 1); + savetab(session, tab, 1); - ui_send_fs(IMSG_SESSION_END, 0, NULL, 0); + fclose(session); + if ((hist = fopen(history_file, "a")) == NULL) + return; + if (history.dirty) { for (i = 0; i < history.len && history.dirty > 0; ++i) { if (!history.items[i].dirty) @@ -222,14 +220,14 @@ save_session(void) history.dirty--; history.items[i].dirty = 0; - memset(&hi, 0, sizeof(hi)); - hi.ts = history.items[i].ts; - strlcpy(hi.uri, history.items[i].uri, sizeof(hi.uri)); - ui_send_fs(IMSG_HIST_ITEM, 0, &hi, sizeof(hi)); + fprintf(hist, "%lld %s\n", + (long long)history.items[i].ts, + history.items[i].uri); } - ui_send_fs(IMSG_HIST_END, 0, NULL, 0); history.dirty = 0; } + + fclose(hist); } void blob - 9061f38f9535cc4211f5549e5de4c14c681030d1 blob + be43e355c74f7332ed707c95332953fb45ee1e2d --- telescope.c +++ telescope.c @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include #include #include @@ -64,7 +66,7 @@ int operating; */ int safe_mode; -static struct imsgev *iev_fs, *iev_net; +static struct imsgev *iev_net; struct tabshead tabshead = TAILQ_HEAD_INITIALIZER(tabshead); struct tabshead ktabshead = TAILQ_HEAD_INITIALIZER(ktabshead); @@ -72,7 +74,6 @@ struct proxylist proxies = TAILQ_HEAD_INITIALIZER(pro enum telescope_process { PROC_UI, - PROC_FS, PROC_NET, }; @@ -117,15 +118,8 @@ static void handle_imsg_got_code(struct imsg *, size static void handle_imsg_got_meta(struct imsg *, size_t); static void handle_maybe_save_page(int, struct tab *); static void handle_save_page_path(const char *, struct tab *); -static void handle_imsg_file_opened(struct imsg *, size_t); static void handle_imsg_buf(struct imsg *, size_t); static void handle_imsg_eof(struct imsg *, size_t); -static void handle_imsg_tofu(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_imsg_update_cert_ok(struct imsg *, size_t); -static void handle_imsg_session(struct imsg *, size_t); -static void handle_imsg_history(struct imsg *, size_t); static void handle_dispatch_imsg(int, short, void *); static int load_about_url(struct tab *, const char *); static int load_file_url(struct tab *, const char *); @@ -136,7 +130,6 @@ static int load_via_proxy(struct tab *, const char * struct proxy *); static int make_request(struct tab *, struct get_req *, int, const char *); -static int make_fs_request(struct tab *, int, const char *); static int do_load_url(struct tab *, const char *, const char *, int); static pid_t start_child(enum telescope_process, const char *, int); static void send_url(const char *); @@ -161,16 +154,6 @@ static imsg_handlerfn *handlers[] = { [IMSG_GOT_META] = handle_imsg_got_meta, [IMSG_BUF] = handle_imsg_buf, [IMSG_EOF] = handle_imsg_eof, - [IMSG_TOFU] = handle_imsg_tofu, - [IMSG_BOOKMARK_OK] = handle_imsg_bookmark_ok, - [IMSG_SAVE_CERT_OK] = handle_imsg_save_cert_ok, - [IMSG_UPDATE_CERT_OK] = handle_imsg_update_cert_ok, - [IMSG_FILE_OPENED] = handle_imsg_file_opened, - [IMSG_SESSION_TAB] = handle_imsg_session, - [IMSG_SESSION_TAB_HIST] = handle_imsg_session, - [IMSG_SESSION_END] = handle_imsg_session, - [IMSG_HIST_ITEM] = handle_imsg_history, - [IMSG_HIST_END] = handle_imsg_history, }; static struct ohash certs; @@ -253,7 +236,7 @@ handle_imsg_check_cert(struct imsg *imsg, size_t datal } strlcpy(e->hash, hash, sizeof(e->hash)); tofu_add(&certs, e); - ui_send_fs(IMSG_SAVE_CERT, tab->id, e, sizeof(*e)); + save_cert(e); } else tofu_res = !strcmp(hash, e->hash); @@ -332,8 +315,8 @@ handle_maybe_save_new_cert(int accept, struct tab *tab strlcat(e->domain, port, sizeof(e->domain)); } strlcpy(e->hash, tab->cert, sizeof(e->hash)); - ui_send_fs(IMSG_UPDATE_CERT, 0, e, sizeof(*e)); + update_cert(e); tofu_update(&certs, e); tab->trust = TS_TRUSTED; @@ -471,6 +454,9 @@ handle_maybe_save_page(int dosave, struct tab *tab) static void handle_save_page_path(const char *path, struct tab *tab) { + struct download *d; + int fd; + if (path == NULL) { stop_tab(tab); return; @@ -478,39 +464,21 @@ handle_save_page_path(const char *path, struct tab *ta ui_show_downloads_pane(); - enqueue_download(tab->id, path, 0); - ui_send_fs(IMSG_FILE_OPEN, tab->id, path, strlen(path)+1); + d = enqueue_download(tab->id, path, 0); /* * Change this tab id, the old one is associated with the * download now. */ tab->id = tab_new_id(); -} - -static void -handle_imsg_file_opened(struct imsg *imsg, size_t datalen) -{ - struct download *d; - const char *e; - /* - * There are no reason we shouldn't be able to find the - * required download. - */ - if ((d = download_by_id(imsg->hdr.peerid)) == NULL) - die(); - - if (imsg->fd == -1) { - e = imsg->data; - if (e[datalen-1] != '\0') - die(); - message("Can't open file %s: %s", d->path, e); - } else if (d->buffer) { + if ((fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0644)) == -1) + message("Can't open file %s: %s", d->path, strerror(errno)); + else if (d->buffer) { FILE *fp; int r; - if ((fp = fdopen(imsg->fd, "w")) != NULL) { + if ((fp = fdopen(fd, "w")) != NULL) { r = parser_serialize(current_tab, fp); if (!r) message("Failed to save the page."); @@ -519,118 +487,12 @@ handle_imsg_file_opened(struct imsg *imsg, size_t data dequeue_first_download(); } else { - d->fd = imsg->fd; + d->fd = fd; ui_send_net(IMSG_PROCEED, d->id, NULL, 0); - } -} - -static void -handle_imsg_session(struct imsg *imsg, size_t datalen) -{ - static struct tab *curr; - static struct tab *tab; - struct session_tab st; - struct session_tab_hist sth; - struct hist *h; - int first_time; - - /* - * The fs process tried to send tabs after it has announced - * that he's done. Something fishy is going on, better die. - */ - if (operating) - die(); - - switch (imsg->hdr.type) { - case IMSG_SESSION_TAB: - if (datalen != sizeof(st)) - die(); - - memcpy(&st, imsg->data, sizeof(st)); - if ((tab = new_tab(st.uri, NULL, NULL)) == NULL) - die(); - tab->hist_cur->line_off = st.top_line; - tab->hist_cur->current_off = st.current_line; - strlcpy(tab->buffer.page.title, st.title, - sizeof(tab->buffer.page.title)); - if (st.flags & TAB_CURRENT) - curr = tab; - if (st.flags & TAB_KILLED) - kill_tab(tab, 1); - break; - - case IMSG_SESSION_TAB_HIST: - if (tab == NULL || datalen != sizeof(sth)) - die(); - - memcpy(&sth, imsg->data, sizeof(sth)); - if (sth.uri[sizeof(sth.uri)-1] != '\0') - die(); - - if ((h = calloc(1, sizeof(*h))) == NULL) - die(); - strlcpy(h->h, sth.uri, sizeof(h->h)); - - if (sth.future) - hist_push(&tab->hist, h); - else - hist_add_before(&tab->hist, tab->hist_cur, h); - break; - - case IMSG_SESSION_END: - if (datalen != sizeof(first_time)) - die(); - memcpy(&first_time, imsg->data, sizeof(first_time)); - if (first_time) { - new_tab("about:new", NULL, NULL); - curr = new_tab("about:help", NULL, NULL); - } - - operating = 1; - if (curr != NULL) - switch_to_tab(curr); - if (has_url || TAILQ_EMPTY(&tabshead)) - new_tab(url, NULL, NULL); - ui_main_loop(); - break; - - default: - die(); } } static void -handle_imsg_history(struct imsg *imsg, size_t datalen) -{ - struct histitem hi; - - /* - * The fs process tried to send history item after it - * has announced that it's done. Something fishy is - * going on, better die - */ - if (operating) - die(); - - switch (imsg->hdr.type) { - case IMSG_HIST_ITEM: - if (datalen != sizeof(hi)) - die(); - - memcpy(&hi, imsg->data, sizeof(hi)); - history_push(&hi); - break; - - case IMSG_HIST_END: - history_sort(); - break; - - default: - die(); - } -} - -static void handle_imsg_buf(struct imsg *imsg, size_t datalen) { struct tab *tab = NULL; @@ -677,67 +539,6 @@ handle_imsg_eof(struct imsg *imsg, size_t datalen) } static void -handle_imsg_tofu(struct imsg *imsg, size_t datalen) -{ - struct tofu_entry *e; - - if (operating) - die(); - - if ((e = calloc(1, sizeof(*e))) == NULL) - die(); - - if (datalen != sizeof(*e)) - die(); - memcpy(e, imsg->data, sizeof(*e)); - if (e->domain[sizeof(e->domain)-1] != '\0' || - e->hash[sizeof(e->hash)-1] != '\0') - die(); - tofu_add(&certs, e); -} - -static void -handle_imsg_bookmark_ok(struct imsg *imsg, size_t datalen) -{ - int res; - - if (datalen != sizeof(res)) - die(); - - memcpy(&res, imsg->data, sizeof(res)); - if (res == 0) - message("Added to bookmarks!"); - else - message("Failed to add to bookmarks: %s", - strerror(res)); -} - -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) - message("Failed to save the cert for: %s", - strerror(res)); -} - -static void -handle_imsg_update_cert_ok(struct imsg *imsg, size_t datalen) -{ - int res; - - if (datalen != sizeof(res)) - die(); - memcpy(&res, imsg->data, datalen); - if (!res) - message("Failed to update the certificate"); -} - -static void handle_dispatch_imsg(int fd, short ev, void *d) { struct imsgev *iev = d; @@ -749,16 +550,21 @@ handle_dispatch_imsg(int fd, short ev, void *d) static int load_about_url(struct tab *tab, const char *url) { - tab->trust = TS_UNKNOWN; - parser_init(tab, gemtext_initparser); - return make_fs_request(tab, IMSG_GET, url); + tab->trust = TS_TRUSTED; + fs_load_url(tab, url); + ui_on_tab_refresh(tab); + ui_on_tab_loaded(tab); + return 0; } static int load_file_url(struct tab *tab, const char *url) { - tab->trust = TS_UNKNOWN; - return make_fs_request(tab, IMSG_GET_FILE, tab->uri.path); + tab->trust = TS_TRUSTED; + fs_load_url(tab, url); + ui_on_tab_refresh(tab); + ui_on_tab_loaded(tab); + return 0; } static int @@ -914,21 +720,6 @@ make_request(struct tab *tab, struct get_req *req, int return 1; } -static int -make_fs_request(struct tab *tab, int type, const char *r) -{ - stop_tab(tab); - tab->id = tab_new_id(); - - ui_send_fs(type, tab->id, r, strlen(r)+1); - - /* - * So load_{about,file}_url can `return make_fs_request` and - * do_load_url is happy. - */ - return 1; -} - void gopher_send_search_req(struct tab *tab, const char *text) { @@ -1106,20 +897,18 @@ load_next_page(struct tab *tab) } void -add_to_bookmarks(const char *str) -{ - ui_send_fs(IMSG_BOOKMARK_PAGE, 0, - str, strlen(str)+1); -} - -void write_buffer(const char *path, struct tab *tab) { + FILE *fp; + if (path == NULL) return; - enqueue_download(tab->id, path, 1); - ui_send_fs(IMSG_FILE_OPEN, tab->id, path, strlen(path)+1); + if ((fp = fopen(path, "w")) == NULL) + return; + if (!parser_serialize(tab, fp)) + message("Failed to save the page."); + fclose(fp); } /* @@ -1186,9 +975,6 @@ start_child(enum telescope_process p, const char *argv switch (p) { case PROC_UI: errx(1, "Can't start ui process"); - case PROC_FS: - argv[argc++] = "-Tf"; - break; case PROC_NET: argv[argc++] = "-Tn"; break; @@ -1234,13 +1020,6 @@ ui_send_net(int type, uint32_t peerid, const void *dat datalen); } -int -ui_send_fs(int type, uint32_t peerid, const void *data, uint16_t datalen) -{ - return imsg_compose_event(iev_fs, type, peerid, 0, -1, data, - datalen); -} - static void __attribute__((noreturn)) usage(int r) { @@ -1253,10 +1032,10 @@ usage(int r) int main(int argc, char * const *argv) { - struct imsgev net_ibuf, fs_ibuf; + struct imsgev net_ibuf; pid_t pid; int control_fd; - int pipe2net[2], pipe2fs[2]; + int pipe2net[2]; int ch, configtest = 0, fail = 0; int proc = -1; int sessionfd = -1; @@ -1271,8 +1050,6 @@ main(int argc, char * const *argv) if (getenv("NO_COLOR") != NULL) enable_colors = 0; - fs_init(); - while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) { switch (ch) { case 'C': @@ -1291,9 +1068,6 @@ main(int argc, char * const *argv) break; case 'T': switch (*optarg) { - case 'f': - proc = PROC_FS; - break; case 'n': proc = PROC_NET; break; @@ -1317,8 +1091,6 @@ main(int argc, char * const *argv) if (proc != -1) { if (argc > 0) usage(1); - else if (proc == PROC_FS) - return fs_main(); else if (proc == PROC_NET) return net_main(); else @@ -1330,6 +1102,8 @@ main(int argc, char * const *argv) humanify_url(argv[0], url, sizeof(url)); } + fs_init(); + /* setup keys before reading the config */ TAILQ_INIT(&global_map.m); global_map.unhandled_input = global_key_unbound; @@ -1357,13 +1131,6 @@ main(int argc, char * const *argv) } /* Start children. */ - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe2fs) == -1) - err(1, "socketpair"); - start_child(PROC_FS, argv0, pipe2fs[1]); - imsg_init(&fs_ibuf.ibuf, pipe2fs[0]); - iev_fs = &fs_ibuf; - iev_fs->handler = handle_dispatch_imsg; - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe2net) == -1) err(1, "socketpair"); start_child(PROC_NET, argv0, pipe2net[1]); @@ -1390,12 +1157,7 @@ main(int argc, char * const *argv) /* Setup event handler for the autosave */ autosave_init(); - /* Setup event handlers for pipes to fs/net */ - iev_fs->events = EV_READ; - event_set(&iev_fs->ev, iev_fs->ibuf.fd, iev_fs->events, - iev_fs->handler, iev_fs); - event_add(&iev_fs->ev, NULL); - + /* Setup event handlers for pipes to net */ iev_net->events = EV_READ; event_set(&iev_net->ev, iev_net->ibuf.fd, iev_net->events, iev_net->handler, iev_net); @@ -1403,14 +1165,14 @@ main(int argc, char * const *argv) if (ui_init()) { sandbox_ui_process(); - ui_send_fs(IMSG_INIT, 0, NULL, 0); - event_dispatch(); + fs_load_state(&certs); + operating = 1; + switch_to_tab(current_tab); + ui_main_loop(); ui_end(); } - ui_send_fs(IMSG_QUIT, 0, NULL, 0); ui_send_net(IMSG_QUIT, 0, NULL, 0); - imsg_flush(&iev_fs->ibuf); imsg_flush(&iev_net->ibuf); /* wait for children to terminate */ @@ -1423,6 +1185,9 @@ main(int argc, char * const *argv) warnx("child terminated; signal %d", WTERMSIG(status)); } while (pid != -1 || (pid == -1 && errno == EINTR)); + if (!safe_mode) + unlink(crashed_file); + if (!safe_mode && close(sessionfd) == -1) err(1, "close(sessionfd = %d)", sessionfd); blob - fe12f904031d9c35398cc59c25425e3f231b0d08 blob + 605da51f8dec8e5d9ea30481d277de1ba61cce50 --- ui.c +++ ui.c @@ -1200,6 +1200,8 @@ ui_main_loop(void) switch_to_tab(current_tab); rearrange_windows(); + + event_dispatch(); } void