Commit Diff


commit - 3078e1bc2a28ec8a601f3880af32291ca7119434
commit + 64f4f8e21263a2ffeede63a19bbb28c897a90f2a
blob - 03f3394a4fa4a1f0d58e5cc0a48bb4152e247c27
blob + 66e45249a521ca684e82a0124682cc90e98213f7
--- fs.c
+++ fs.c
@@ -25,7 +25,6 @@
 
 #include <dirent.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <limits.h>
 #include <libgen.h>
 #include <stdio.h>
@@ -45,17 +44,12 @@
 #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
@@ -74,12 +68,6 @@ char		crashed_file[PATH_MAX];
 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)
 {
@@ -381,264 +369,4 @@ fs_init(void)
 	    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
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -34,8 +34,6 @@ extern char	session_file[PATH_MAX], session_file_tmp[P
 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
@@ -17,7 +17,7 @@
 #ifndef SESSION_H
 #define SESSION_H
 
-#include "telescope.h"
+struct ohash;
 
 struct session_tab {
 	uint32_t	flags;
@@ -69,4 +69,7 @@ void		 autosave_init(void);
 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
@@ -17,6 +17,7 @@
 #include "compat.h"
 
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -393,5 +394,263 @@ autosave_hook(void)
 		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
@@ -1175,7 +1175,7 @@ main(int argc, char * const *argv)
 
 	if (ui_init()) {
 		sandbox_ui_process();
-		fs_load_state(&certs);
+		load_session(&certs);
 		operating = 1;
 		switch_to_tab(current_tab);
 		ui_main_loop();