commit - 3078e1bc2a28ec8a601f3880af32291ca7119434
commit + 64f4f8e21263a2ffeede63a19bbb28c897a90f2a
blob - 03f3394a4fa4a1f0d58e5cc0a48bb4152e247c27
blob + 66e45249a521ca684e82a0124682cc90e98213f7
--- fs.c
+++ fs.c
#include <dirent.h>
#include <errno.h>
-#include <fcntl.h>
#include <limits.h>
#include <libgen.h>
#include <stdio.h>
#define nitems(x) (sizeof(x) / sizeof(x[0]))
#endif
-static void die(void) __attribute__((__noreturn__));
static int select_non_dot(const struct dirent *);
static int select_non_dotdot(const struct dirent *);
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);
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(struct ohash *);
/*
* Where to store user data. These are all equal to ~/.telescope if
char session_file[PATH_MAX], session_file_tmp[PATH_MAX];
char history_file[PATH_MAX], history_file_tmp[PATH_MAX];
-static void __attribute__((__noreturn__))
-die(void)
-{
- abort(); /* TODO */
-}
-
static int
select_non_dot(const struct dirent *d)
{
sizeof(crashed_file));
return 1;
-}
-
-/*
- * Parse a line of the session file and restores it. The format is:
- *
- * URL [flags,...] [title]\n
- */
-static inline struct tab *
-parse_session_line(char *line, struct tab **ct)
-{
- struct tab *tab;
- char *s, *t, *ap;
- const char *uri, *title = "";
- int current = 0, killed = 0;
- size_t top_line = 0, current_line = 0;
-
- uri = line;
- if ((s = strchr(line, ' ')) == NULL)
- return NULL;
-
- *s++ = '\0';
-
- if ((t = strchr(s, ' ')) != NULL) {
- *t++ = '\0';
- title = t;
- }
-
- while ((ap = strsep(&s, ",")) != NULL) {
- if (!strcmp(ap, "current"))
- current = 1;
- else if (!strcmp(ap, "killed"))
- killed = 1;
- else if (has_prefix(ap, "top="))
- top_line = strtonum(ap+4, 0, UINT32_MAX, NULL);
- else if (has_prefix(ap, "cur="))
- current_line = strtonum(ap+4, 0, UINT32_MAX, NULL);
- }
-
- if (top_line > current_line) {
- top_line = 0;
- current_line = 0;
- }
-
- 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(struct tab *tab, const char *uri, int future)
-{
- struct hist *h;
-
- if ((h = calloc(1, sizeof(*h))) == NULL)
- die();
- strlcpy(h->h, uri, sizeof(h->h));
-
- 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 future;
- char *nl, *s, *line = NULL;
-
- if ((session = fopen(session_file, "r")) == NULL) {
- new_tab("about:new", NULL, NULL);
- switch_to_tab(new_tab("about:help", NULL, NULL));
- return;
- }
-
- while ((linelen = getline(&line, &linesize, session)) != -1) {
- if ((nl = strchr(line, '\n')) != NULL)
- *nl = '\0';
-
- if (*line == '<' || *line == '>') {
- future = *line == '>';
- s = line+1;
- if (*s != ' ' || tab == NULL)
- continue;
- sendhist(tab, ++s, future);
- } else {
- tab = parse_session_line(line, &ct);
- }
- }
-
- fclose(session);
- free(line);
-
- if (ct != NULL)
- switch_to_tab(ct);
-
- if (last_time_crashed())
- switch_to_tab(new_tab("about:crash", NULL, NULL));
-}
-
-static void
-load_hist(void)
-{
- FILE *hist;
- size_t linesize = 0;
- ssize_t linelen;
- char *nl, *spc, *line = NULL;
- const char *errstr;
- struct histitem hi;
-
- if ((hist = fopen(history_file, "r")) == NULL)
- return;
-
- while ((linelen = getline(&line, &linesize, hist)) != -1) {
- if ((nl = strchr(line, '\n')) != NULL)
- *nl = '\0';
- if ((spc = strchr(line, ' ')) == NULL)
- continue;
- *spc = '\0';
- spc++;
-
- memset(&hi, 0, sizeof(hi));
- hi.ts = strtonum(line, INT64_MIN, INT64_MAX, &errstr);
- if (errstr != NULL)
- continue;
- if (strlcpy(hi.uri, spc, sizeof(hi.uri)) >= sizeof(hi.uri))
- continue;
-
- history_push(&hi);
- }
-
- fclose(hist);
- free(line);
-
- history_sort();
}
-
-int
-fs_load_state(struct ohash *certs)
-{
- load_certs(certs);
- load_hist();
- load_last_session();
- return 0;
-}
-
-/*
- * Check if the last time telescope crashed. The check is done by
- * looking at `crashed_file': if it exists then last time we crashed.
- * Then, while here, touch the file too. During IMSG_QUIT we'll
- * remove it.
- */
-static int
-last_time_crashed(void)
-{
- int fd, crashed = 1;
-
- if (safe_mode)
- return 0;
-
- if (unlink(crashed_file) == -1 && errno == ENOENT)
- crashed = 0;
-
- if ((fd = open(crashed_file, O_CREAT|O_WRONLY, 0600)) == -1)
- return crashed;
- close(fd);
-
- return crashed;
-}
-
-int
-lock_session(void)
-{
- struct flock lock;
- int fd;
-
- if ((fd = open(lockfile_path, O_WRONLY|O_CREAT, 0600)) == -1)
- return -1;
-
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- if (fcntl(fd, F_SETLK, &lock) == -1) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-static inline int
-parse_khost_line(char *line, char *tmp[3])
-{
- char **ap;
-
- for (ap = tmp; ap < &tmp[3] &&
- (*ap = strsep(&line, " \t\n")) != NULL;) {
- if (**ap != '\0')
- ap++;
- }
-
- return ap == &tmp[3] && *line == '\0';
-}
-
-static 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;
-
- 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++;
-
- if (parse_khost_line(line, tmp)) {
- strlcpy(e->domain, tmp[0], sizeof(e->domain));
- strlcpy(e->hash, tmp[1], sizeof(e->hash));
-
- 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]);
-
- tofu_add(certs, e);
- } else {
- warnx("%s:%zu invalid entry",
- known_hosts_file, lineno);
- }
- }
-
- free(line);
- fclose(f);
- return;
-}
blob - db32291cf8dce46d1ef193fb319fc6c7a4cd71e7
blob + a907499540a49280b469c1392c0fd0ff39c063b5
--- include/fs.h
+++ include/fs.h
/*
- * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ * Copyright (c) 2021, 2022 Omar Polo <op@omarpolo.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
extern char history_file[PATH_MAX], history_file_tmp[PATH_MAX];
int fs_init(void);
-int lock_session(void);
void fs_load_url(struct tab *, const char *);
-int fs_load_state(struct ohash *);
#endif
blob - fcb02e901a04e7942b801206c5e170627e7cc97b
blob + d68cbf629a2dbac8c9f42b70d0513c05805e7589
--- include/session.h
+++ include/session.h
#ifndef SESSION_H
#define SESSION_H
-#include "telescope.h"
+struct ohash;
struct session_tab {
uint32_t flags;
void autosave_timer(int, short, void *);
void autosave_hook(void);
+int load_session(struct ohash *);
+int lock_session(void);
+
#endif
blob - 49f267c9fb03d61e18a50c8e530f12bb1893dde6
blob + 29dd22293830349fed6858a83f1c516bd2b6862b
--- session.c
+++ session.c
#include "compat.h"
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
tv.tv_usec = 0;
evtimer_add(&autosaveev, &tv);
+ }
+}
+
+static inline int
+parse_khost_line(char *line, char *tmp[3])
+{
+ char **ap;
+
+ for (ap = tmp; ap < &tmp[3] &&
+ (*ap = strsep(&line, " \t\n")) != NULL;) {
+ if (**ap != '\0')
+ ap++;
+ }
+
+ return ap == &tmp[3] && *line == '\0';
+}
+
+static 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;
+
+ 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++;
+
+ if (parse_khost_line(line, tmp)) {
+ strlcpy(e->domain, tmp[0], sizeof(e->domain));
+ strlcpy(e->hash, tmp[1], sizeof(e->hash));
+
+ 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]);
+
+ tofu_add(certs, e);
+ } else
+ warnx("%s:%zu invalid entry",
+ known_hosts_file, lineno);
+ }
+
+ free(line);
+ fclose(f);
+ return;
}
+
+
+static void
+load_hist(void)
+{
+ FILE *hist;
+ size_t linesize = 0;
+ ssize_t linelen;
+ char *nl, *spc, *line = NULL;
+ const char *errstr;
+ struct histitem hi;
+
+ if ((hist = fopen(history_file, "r")) == NULL)
+ return;
+
+ while ((linelen = getline(&line, &linesize, hist)) != -1) {
+ if ((nl = strchr(line, '\n')) != NULL)
+ *nl = '\0';
+ if ((spc = strchr(line, ' ')) == NULL)
+ continue;
+ *spc = '\0';
+ spc++;
+
+ memset(&hi, 0, sizeof(hi));
+ hi.ts = strtonum(line, INT64_MIN, INT64_MAX, &errstr);
+ if (errstr != NULL)
+ continue;
+ if (strlcpy(hi.uri, spc, sizeof(hi.uri)) >= sizeof(hi.uri))
+ continue;
+
+ history_push(&hi);
+ }
+
+ fclose(hist);
+ free(line);
+
+ history_sort();
+}
+
+/*
+ * Check if the last time telescope crashed. The check is done by
+ * looking at `crashed_file': if it exists then last time we crashed.
+ * Then, while here, touch the file too, it's removed during the
+ * teardown.
+ */
+static int
+last_time_crashed(void)
+{
+ int fd, crashed = 1;
+
+ if (safe_mode)
+ return 0;
+
+ if (unlink(crashed_file) == -1 && errno == ENOENT)
+ crashed = 0;
+
+ if ((fd = open(crashed_file, O_CREAT|O_WRONLY, 0600)) == -1)
+ return crashed;
+ close(fd);
+
+ return crashed;
+}
+
+/*
+ * Parse and restore a tab from the session file. The format is:
+ *
+ * URL [flags,...] [title]\n
+ */
+static inline struct tab *
+parse_tab_line(char *line, struct tab **ct)
+{
+ struct tab *tab;
+ char *s, *t, *ap;
+ const char *uri, *title = "";
+ int current = 0, killed = 0;
+ size_t tline = 0, cline = 0;
+
+ uri = line;
+ if ((s = strchr(line, ' ')) == NULL)
+ return NULL;
+ *s++ = '\0';
+
+ if ((t = strchr(s, ' ')) != NULL) {
+ *t++ = '\0';
+ title = t;
+ }
+
+ while ((ap = strsep(&s, ",")) != NULL) {
+ if (!strcmp(ap, "current"))
+ current = 1;
+ else if (!strcmp(ap, "killed"))
+ killed = 1;
+ else if (!strncmp(ap, "top=", 4))
+ tline = strtonum(ap+4, 0, UINT32_MAX, NULL);
+ else if (!strncmp(ap, "cur=", 4))
+ cline = strtonum(ap + 4, 0, UINT32_MAX, NULL);
+ }
+
+ if (tline > cline) {
+ tline = 0;
+ cline = 0;
+ }
+
+ if ((tab = new_tab(uri, NULL, NULL)) == NULL)
+ err(1, "new_tab");
+ tab->hist_cur->line_off = tline;
+ tab->hist_cur->current_off = cline;
+ 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 void
+load_tabs(void)
+{
+ struct tab *tab = NULL, *ct = NULL;
+ struct hist *h;
+ FILE *session;
+ size_t lineno = 0, linesize = 0;
+ ssize_t linelen;
+ char *uri, *line = NULL;
+
+ if ((session = fopen(session_file, "r")) == NULL) {
+ new_tab("about:new", NULL, NULL);
+ new_tab("about:help", NULL, NULL);
+ return;
+ }
+
+ while ((linelen = getline(&line, &linesize, session)) != -1) {
+ lineno++;
+
+ if (linelen > 0 && line[linelen-1] == '\n')
+ line[linelen-1] = '\0';
+
+ if (*line == '<' || *line == '>') {
+ uri = line + 1;
+ if (*uri != ' ' || tab == NULL) {
+ fprintf(stderr, "%s:%zu invalid line\n",
+ session_file, lineno);
+ continue;
+ }
+ uri++;
+
+ if ((h = calloc(1, sizeof(*h))) == NULL)
+ err(1, "calloc");
+ strlcpy(h->h, uri, sizeof(h->h));
+
+ if (*line == '>') /* future hist */
+ hist_push(&tab->hist, h);
+ else
+ hist_add_before(&tab->hist, tab->hist_cur, h);
+ } else
+ tab = parse_tab_line(line, &ct);
+ }
+
+ fclose(session);
+ free(line);
+
+ if (ct == NULL || TAILQ_EMPTY(&tabshead))
+ ct = new_tab("about:new", NULL, NULL);
+
+ switch_to_tab(ct);
+
+ if (last_time_crashed())
+ new_tab("about:crash", NULL, NULL);
+}
+
+int
+load_session(struct ohash *certs)
+{
+ load_certs(certs);
+ load_hist();
+ load_tabs();
+ return 0;
+}
+
+int
+lock_session(void)
+{
+ struct flock lock;
+ int fd;
+
+ if ((fd = open(lockfile_path, O_WRONLY|O_CREAT, 0600)) == -1)
+ return -1;
+
+ lock.l_start = 0;
+ lock.l_len = 0;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+
+ if (fcntl(fd, F_SETLK, &lock) == -1) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
blob - c9fe8eb60a4e8b9d201366b70e2687b4dde9a626
blob + 9c67fc6711f528acca01bab54217503f90aee94c
--- telescope.c
+++ telescope.c
if (ui_init()) {
sandbox_ui_process();
- fs_load_state(&certs);
+ load_session(&certs);
operating = 1;
switch_to_tab(current_tab);
ui_main_loop();