commit 64f4f8e21263a2ffeede63a19bbb28c897a90f2a from: Omar Polo date: Sun Apr 24 12:14:54 2022 UTC move load session stuff to session.c commit - 3078e1bc2a28ec8a601f3880af32291ca7119434 commit + 64f4f8e21263a2ffeede63a19bbb28c897a90f2a blob - 03f3394a4fa4a1f0d58e5cc0a48bb4152e247c27 blob + 66e45249a521ca684e82a0124682cc90e98213f7 --- fs.c +++ fs.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -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 + * Copyright (c) 2021, 2022 Omar Polo * * 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 +#include #include #include #include @@ -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();