Blame


1 35e1f40a 2021-03-14 op /*
2 0ec5e323 2024-02-03 op * Copyright (c) 2021, 2024 Omar Polo <op@omarpolo.com>
3 35e1f40a 2021-03-14 op *
4 35e1f40a 2021-03-14 op * Permission to use, copy, modify, and distribute this software for any
5 35e1f40a 2021-03-14 op * purpose with or without fee is hereby granted, provided that the above
6 35e1f40a 2021-03-14 op * copyright notice and this permission notice appear in all copies.
7 35e1f40a 2021-03-14 op *
8 35e1f40a 2021-03-14 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 35e1f40a 2021-03-14 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 35e1f40a 2021-03-14 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 35e1f40a 2021-03-14 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 35e1f40a 2021-03-14 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 35e1f40a 2021-03-14 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 35e1f40a 2021-03-14 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 35e1f40a 2021-03-14 op */
16 35e1f40a 2021-03-14 op
17 740f578b 2021-03-15 op /*
18 eb2ed626 2021-10-07 op * Handles config and runtime files
19 740f578b 2021-03-15 op */
20 786e6deb 2021-07-21 op
21 786e6deb 2021-07-21 op #include "compat.h"
22 35e1f40a 2021-03-14 op
23 6cd6a9e1 2021-03-20 op #include <sys/stat.h>
24 65124267 2021-08-13 op #include <sys/types.h>
25 6cd6a9e1 2021-03-20 op
26 65124267 2021-08-13 op #include <dirent.h>
27 35e1f40a 2021-03-14 op #include <errno.h>
28 35e1f40a 2021-03-14 op #include <limits.h>
29 eb2ed626 2021-10-07 op #include <libgen.h>
30 35e1f40a 2021-03-14 op #include <stdio.h>
31 35e1f40a 2021-03-14 op #include <stdlib.h>
32 35e1f40a 2021-03-14 op #include <string.h>
33 35e1f40a 2021-03-14 op #include <unistd.h>
34 4913b479 2021-07-12 op
35 5a824be4 2021-07-13 op #include "pages.h"
36 f63b8f73 2022-04-24 op #include "parser.h"
37 eb9cbcba 2022-01-03 op #include "session.h"
38 9d65b1d9 2022-01-11 op #include "utils.h"
39 35e1f40a 2021-03-14 op
40 f63b8f73 2022-04-24 op #include "fs.h"
41 f63b8f73 2022-04-24 op
42 f63b8f73 2022-04-24 op #ifndef nitems
43 f63b8f73 2022-04-24 op #define nitems(x) (sizeof(x) / sizeof(x[0]))
44 f63b8f73 2022-04-24 op #endif
45 f63b8f73 2022-04-24 op
46 5cbe1763 2021-08-13 op static int select_non_dot(const struct dirent *);
47 5cbe1763 2021-08-13 op static int select_non_dotdot(const struct dirent *);
48 eb2ed626 2021-10-07 op static size_t join_path(char*, const char*, const char*, size_t);
49 eb2ed626 2021-10-07 op static void getenv_default(char*, const char*, const char*, size_t);
50 eb2ed626 2021-10-07 op static void mkdirs(const char*, mode_t);
51 6c8ddace 2022-01-03 op static void init_paths(void);
52 35e1f40a 2021-03-14 op
53 f88fbabc 2021-11-27 op /*
54 f88fbabc 2021-11-27 op * Where to store user data. These are all equal to ~/.telescope if
55 f88fbabc 2021-11-27 op * it exists.
56 f88fbabc 2021-11-27 op */
57 fb3d08c1 2021-10-07 op char config_path_base[PATH_MAX];
58 fb3d08c1 2021-10-07 op char data_path_base[PATH_MAX];
59 fb3d08c1 2021-10-07 op char cache_path_base[PATH_MAX];
60 eb2ed626 2021-10-07 op
61 4cf6ba13 2022-02-11 op char ctlsock_path[PATH_MAX];
62 eb2ed626 2021-10-07 op char config_path[PATH_MAX];
63 fb3d08c1 2021-10-07 op char lockfile_path[PATH_MAX];
64 fb3d08c1 2021-10-07 op char bookmark_file[PATH_MAX];
65 fb3d08c1 2021-10-07 op char known_hosts_file[PATH_MAX], known_hosts_tmp[PATH_MAX];
66 fb3d08c1 2021-10-07 op char crashed_file[PATH_MAX];
67 de6a6a40 2022-04-24 op char session_file[PATH_MAX], session_file_tmp[PATH_MAX];
68 de6a6a40 2022-04-24 op char history_file[PATH_MAX], history_file_tmp[PATH_MAX];
69 f0e62b85 2024-02-15 op char cert_dir[PATH_MAX], cert_dir_tmp[PATH_MAX];
70 d35e18b3 2024-02-04 op char certs_file[PATH_MAX], certs_file_tmp[PATH_MAX];
71 26e95b82 2024-01-16 op
72 26e95b82 2024-01-16 op char cwd[PATH_MAX];
73 740f578b 2021-03-15 op
74 f63b8f73 2022-04-24 op static int
75 f63b8f73 2022-04-24 op select_non_dot(const struct dirent *d)
76 fb4dc49f 2021-08-13 op {
77 f63b8f73 2022-04-24 op return strcmp(d->d_name, ".");
78 f63b8f73 2022-04-24 op }
79 fb4dc49f 2021-08-13 op
80 f63b8f73 2022-04-24 op static int
81 f63b8f73 2022-04-24 op select_non_dotdot(const struct dirent *d)
82 f63b8f73 2022-04-24 op {
83 f63b8f73 2022-04-24 op return strcmp(d->d_name, ".") && strcmp(d->d_name, "..");
84 fb4dc49f 2021-08-13 op }
85 fb4dc49f 2021-08-13 op
86 fb4dc49f 2021-08-13 op static void
87 f63b8f73 2022-04-24 op send_dir(struct tab *tab, const char *path)
88 35e1f40a 2021-03-14 op {
89 f63b8f73 2022-04-24 op struct dirent **names;
90 f63b8f73 2022-04-24 op int (*selector)(const struct dirent *) = select_non_dot;
91 f63b8f73 2022-04-24 op int i, len;
92 35e1f40a 2021-03-14 op
93 f63b8f73 2022-04-24 op #if notyet
94 f63b8f73 2022-04-24 op /*
95 f63b8f73 2022-04-24 op * need something to fake a redirect
96 f63b8f73 2022-04-24 op */
97 35e1f40a 2021-03-14 op
98 f63b8f73 2022-04-24 op if (!has_suffix(path, "/")) {
99 f63b8f73 2022-04-24 op if (asprintf(&s, "%s/", path) == -1)
100 f63b8f73 2022-04-24 op die();
101 f63b8f73 2022-04-24 op send_hdr(peerid, 30, s);
102 f63b8f73 2022-04-24 op free(s);
103 f63b8f73 2022-04-24 op return;
104 56e7efb4 2021-07-21 op }
105 f63b8f73 2022-04-24 op #endif
106 56e7efb4 2021-07-21 op
107 f63b8f73 2022-04-24 op if (!strcmp(path, "/"))
108 f63b8f73 2022-04-24 op selector = select_non_dotdot;
109 f63b8f73 2022-04-24 op
110 f63b8f73 2022-04-24 op if ((len = scandir(path, &names, selector, alphasort)) == -1) {
111 f63b8f73 2022-04-24 op load_page_from_str(tab, "# failure reading the directory\n");
112 a2728733 2021-07-18 op return;
113 35e1f40a 2021-03-14 op }
114 a2728733 2021-07-18 op
115 f63b8f73 2022-04-24 op parser_init(tab, gemtext_initparser);
116 f63b8f73 2022-04-24 op parser_parsef(tab, "# Index of %s\n\n", path);
117 56e7efb4 2021-07-21 op
118 f63b8f73 2022-04-24 op for (i = 0; i < len; ++i) {
119 f63b8f73 2022-04-24 op const char *sufx = "";
120 fb4dc49f 2021-08-13 op
121 f63b8f73 2022-04-24 op if (names[i]->d_type == DT_DIR)
122 f63b8f73 2022-04-24 op sufx = "/";
123 f63b8f73 2022-04-24 op
124 f63b8f73 2022-04-24 op parser_parsef(tab, "=> %s%s\n", names[i]->d_name, sufx);
125 f63b8f73 2022-04-24 op }
126 f63b8f73 2022-04-24 op
127 f63b8f73 2022-04-24 op parser_free(tab);
128 f63b8f73 2022-04-24 op free(names);
129 fb4dc49f 2021-08-13 op }
130 fb4dc49f 2021-08-13 op
131 f63b8f73 2022-04-24 op static int
132 f63b8f73 2022-04-24 op is_dir(FILE *fp)
133 24a68158 2021-08-13 op {
134 f63b8f73 2022-04-24 op struct stat sb;
135 24a68158 2021-08-13 op
136 f63b8f73 2022-04-24 op if (fstat(fileno(fp), &sb) == -1)
137 f63b8f73 2022-04-24 op return 0;
138 24a68158 2021-08-13 op
139 f63b8f73 2022-04-24 op return S_ISDIR(sb.st_mode);
140 24a68158 2021-08-13 op }
141 24a68158 2021-08-13 op
142 f63b8f73 2022-04-24 op static parserinit
143 65124267 2021-08-13 op file_type(const char *path)
144 fb4dc49f 2021-08-13 op {
145 21268f10 2022-04-24 op const struct mapping {
146 fb4dc49f 2021-08-13 op const char *ext;
147 f63b8f73 2022-04-24 op parserinit fn;
148 fb4dc49f 2021-08-13 op } ms[] = {
149 f63b8f73 2022-04-24 op {"diff", textpatch_initparser},
150 f63b8f73 2022-04-24 op {"gemini", gemtext_initparser},
151 f63b8f73 2022-04-24 op {"gmi", gemtext_initparser},
152 f63b8f73 2022-04-24 op {"markdown", textplain_initparser},
153 f63b8f73 2022-04-24 op {"md", textplain_initparser},
154 f63b8f73 2022-04-24 op {"patch", gemtext_initparser},
155 fb4dc49f 2021-08-13 op {NULL, NULL},
156 65124267 2021-08-13 op }, *m;
157 21268f10 2022-04-24 op const char *dot;
158 65124267 2021-08-13 op
159 65124267 2021-08-13 op if ((dot = strrchr(path, '.')) == NULL)
160 f63b8f73 2022-04-24 op return textplain_initparser;
161 65124267 2021-08-13 op
162 65124267 2021-08-13 op dot++;
163 65124267 2021-08-13 op
164 65124267 2021-08-13 op for (m = ms; m->ext != NULL; ++m)
165 65124267 2021-08-13 op if (!strcmp(m->ext, dot))
166 f63b8f73 2022-04-24 op return m->fn;
167 65124267 2021-08-13 op
168 f63b8f73 2022-04-24 op return textplain_initparser;
169 5cbe1763 2021-08-13 op }
170 5cbe1763 2021-08-13 op
171 f63b8f73 2022-04-24 op void
172 f63b8f73 2022-04-24 op fs_load_url(struct tab *tab, const char *url)
173 5cbe1763 2021-08-13 op {
174 f63b8f73 2022-04-24 op const char *bpath = "bookmarks.gmi", *fallback = "# Not found\n";
175 f63b8f73 2022-04-24 op parserinit initfn = gemtext_initparser;
176 f63b8f73 2022-04-24 op char path[PATH_MAX];
177 f63b8f73 2022-04-24 op FILE *fp = NULL;
178 f63b8f73 2022-04-24 op size_t i;
179 f63b8f73 2022-04-24 op char buf[BUFSIZ];
180 f63b8f73 2022-04-24 op struct page {
181 f63b8f73 2022-04-24 op const char *name;
182 f63b8f73 2022-04-24 op const char *path;
183 f63b8f73 2022-04-24 op const uint8_t *data;
184 f63b8f73 2022-04-24 op size_t len;
185 f63b8f73 2022-04-24 op } pages[] = {
186 f63b8f73 2022-04-24 op {"about", NULL, about_about, about_about_len},
187 f63b8f73 2022-04-24 op {"blank", NULL, about_blank, about_blank_len},
188 f63b8f73 2022-04-24 op {"bookmarks", bpath, bookmarks, bookmarks_len},
189 f63b8f73 2022-04-24 op {"crash", NULL, about_crash, about_crash_len},
190 f63b8f73 2022-04-24 op {"help", NULL, about_help, about_help_len},
191 f63b8f73 2022-04-24 op {"license", NULL, about_license, about_license_len},
192 f63b8f73 2022-04-24 op {"new", NULL, about_new, about_new_len},
193 f63b8f73 2022-04-24 op }, *page = NULL;
194 65124267 2021-08-13 op
195 f63b8f73 2022-04-24 op if (!strncmp(url, "about:", 6)) {
196 f63b8f73 2022-04-24 op url += 6;
197 65124267 2021-08-13 op
198 f63b8f73 2022-04-24 op for (i = 0; page == NULL && i < nitems(pages); ++i) {
199 f63b8f73 2022-04-24 op if (!strcmp(url, pages[i].name))
200 f63b8f73 2022-04-24 op page = &pages[i];
201 f63b8f73 2022-04-24 op }
202 5d43215b 2021-08-13 op
203 f63b8f73 2022-04-24 op if (page == NULL)
204 f63b8f73 2022-04-24 op goto done;
205 5cbe1763 2021-08-13 op
206 f63b8f73 2022-04-24 op strlcpy(path, data_path_base, sizeof(path));
207 f63b8f73 2022-04-24 op strlcat(path, "/", sizeof(path));
208 f63b8f73 2022-04-24 op if (page->path != NULL)
209 f63b8f73 2022-04-24 op strlcat(path, page->path, sizeof(path));
210 f63b8f73 2022-04-24 op else {
211 f63b8f73 2022-04-24 op strlcat(path, "page/about_", sizeof(path));
212 f63b8f73 2022-04-24 op strlcat(path, page->name, sizeof(path));
213 f63b8f73 2022-04-24 op strlcat(path, ".gmi", sizeof(path));
214 f63b8f73 2022-04-24 op }
215 65124267 2021-08-13 op
216 f63b8f73 2022-04-24 op fallback = page->data;
217 f63b8f73 2022-04-24 op } else if (!strncmp(url, "file://", 7)) {
218 f63b8f73 2022-04-24 op url += 7;
219 f63b8f73 2022-04-24 op strlcpy(path, url, sizeof(path));
220 f63b8f73 2022-04-24 op initfn = file_type(url);
221 f63b8f73 2022-04-24 op } else
222 f63b8f73 2022-04-24 op goto done;
223 65124267 2021-08-13 op
224 f63b8f73 2022-04-24 op if ((fp = fopen(path, "r")) == NULL)
225 f63b8f73 2022-04-24 op goto done;
226 65124267 2021-08-13 op
227 f63b8f73 2022-04-24 op if (is_dir(fp)) {
228 f63b8f73 2022-04-24 op fclose(fp);
229 f63b8f73 2022-04-24 op send_dir(tab, path);
230 f63b8f73 2022-04-24 op goto done;
231 fb4dc49f 2021-08-13 op }
232 fb4dc49f 2021-08-13 op
233 f63b8f73 2022-04-24 op parser_init(tab, initfn);
234 f63b8f73 2022-04-24 op for (;;) {
235 f63b8f73 2022-04-24 op size_t r;
236 fb4dc49f 2021-08-13 op
237 f63b8f73 2022-04-24 op r = fread(buf, 1, sizeof(buf), fp);
238 f63b8f73 2022-04-24 op if (!parser_parse(tab, buf, r))
239 f63b8f73 2022-04-24 op break;
240 f63b8f73 2022-04-24 op if (r != sizeof(buf))
241 f63b8f73 2022-04-24 op break;
242 fb4dc49f 2021-08-13 op }
243 f63b8f73 2022-04-24 op parser_free(tab);
244 fb4dc49f 2021-08-13 op
245 f63b8f73 2022-04-24 op done:
246 f63b8f73 2022-04-24 op if (fp != NULL)
247 f63b8f73 2022-04-24 op fclose(fp);
248 f63b8f73 2022-04-24 op else
249 f63b8f73 2022-04-24 op load_page_from_str(tab, fallback);
250 740f578b 2021-03-15 op }
251 288fd238 2021-04-25 op
252 eb2ed626 2021-10-07 op static size_t
253 eb2ed626 2021-10-07 op join_path(char *buf, const char *lhs, const char *rhs, size_t buflen)
254 35e1f40a 2021-03-14 op {
255 eb2ed626 2021-10-07 op strlcpy(buf, lhs, buflen);
256 eb2ed626 2021-10-07 op return strlcat(buf, rhs, buflen);
257 eb2ed626 2021-10-07 op }
258 d0fd368a 2021-07-15 op
259 eb2ed626 2021-10-07 op static void
260 eb2ed626 2021-10-07 op getenv_default(char *buf, const char *name, const char *def, size_t buflen)
261 eb2ed626 2021-10-07 op {
262 eb2ed626 2021-10-07 op size_t ret;
263 eb2ed626 2021-10-07 op char *home, *env;
264 740f578b 2021-03-15 op
265 eb2ed626 2021-10-07 op if ((home = getenv("HOME")) == NULL)
266 eb2ed626 2021-10-07 op errx(1, "HOME is not defined");
267 3a227e9a 2021-03-18 op
268 eb2ed626 2021-10-07 op if ((env = getenv(name)) != NULL)
269 eb2ed626 2021-10-07 op ret = strlcpy(buf, env, buflen);
270 eb2ed626 2021-10-07 op else
271 eb2ed626 2021-10-07 op ret = join_path(buf, home, def, buflen);
272 288fd238 2021-04-25 op
273 eb2ed626 2021-10-07 op if (ret >= buflen)
274 eb2ed626 2021-10-07 op errx(1, "buffer too small for %s", name);
275 eb2ed626 2021-10-07 op }
276 c7107cec 2021-04-01 op
277 eb2ed626 2021-10-07 op static void
278 eb2ed626 2021-10-07 op mkdirs(const char *path, mode_t mode)
279 eb2ed626 2021-10-07 op {
280 444dad86 2021-10-07 op char copy[PATH_MAX+1], orig[PATH_MAX+1], *parent;
281 ea080950 2021-07-20 op
282 eb2ed626 2021-10-07 op strlcpy(copy, path, sizeof(copy));
283 444dad86 2021-10-07 op strlcpy(orig, path, sizeof(orig));
284 eb2ed626 2021-10-07 op parent = dirname(copy);
285 eb2ed626 2021-10-07 op if (!strcmp(parent, "/"))
286 eb2ed626 2021-10-07 op return;
287 eb2ed626 2021-10-07 op mkdirs(parent, mode);
288 eb2ed626 2021-10-07 op
289 444dad86 2021-10-07 op if (mkdir(orig, mode) != 0) {
290 eb2ed626 2021-10-07 op if (errno == EEXIST)
291 eb2ed626 2021-10-07 op return;
292 444dad86 2021-10-07 op err(1, "can't mkdir %s", orig);
293 eb2ed626 2021-10-07 op }
294 eb2ed626 2021-10-07 op }
295 eb2ed626 2021-10-07 op
296 eb2ed626 2021-10-07 op static void
297 6c8ddace 2022-01-03 op init_paths(void)
298 eb2ed626 2021-10-07 op {
299 7e60a21a 2022-01-03 op char xdg_config_base[PATH_MAX];
300 7e60a21a 2022-01-03 op char xdg_data_base[PATH_MAX];
301 7e60a21a 2022-01-03 op char xdg_cache_base[PATH_MAX];
302 7e60a21a 2022-01-03 op char old_path[PATH_MAX];
303 7e60a21a 2022-01-03 op char *home;
304 7e60a21a 2022-01-03 op struct stat info;
305 eb2ed626 2021-10-07 op
306 26e95b82 2024-01-16 op if (getcwd(cwd, sizeof(cwd)) == NULL)
307 26e95b82 2024-01-16 op err(1, "getcwd failed");
308 26e95b82 2024-01-16 op
309 eb2ed626 2021-10-07 op /* old path */
310 eb2ed626 2021-10-07 op if ((home = getenv("HOME")) == NULL)
311 eb2ed626 2021-10-07 op errx(1, "HOME is not defined");
312 eb2ed626 2021-10-07 op join_path(old_path, home, "/.telescope", sizeof(old_path));
313 eb2ed626 2021-10-07 op
314 eb2ed626 2021-10-07 op /* if ~/.telescope exists, use that instead of xdg dirs */
315 eb2ed626 2021-10-07 op if (stat(old_path, &info) == 0 && S_ISDIR(info.st_mode)) {
316 eb2ed626 2021-10-07 op join_path(config_path_base, home, "/.telescope",
317 eb2ed626 2021-10-07 op sizeof(config_path_base));
318 eb2ed626 2021-10-07 op join_path(data_path_base, home, "/.telescope",
319 eb2ed626 2021-10-07 op sizeof(data_path_base));
320 eb2ed626 2021-10-07 op join_path(cache_path_base, home, "/.telescope",
321 eb2ed626 2021-10-07 op sizeof(cache_path_base));
322 eb2ed626 2021-10-07 op return;
323 eb2ed626 2021-10-07 op }
324 eb2ed626 2021-10-07 op
325 eb2ed626 2021-10-07 op /* xdg paths */
326 eb2ed626 2021-10-07 op getenv_default(xdg_config_base, "XDG_CONFIG_HOME", "/.config",
327 eb2ed626 2021-10-07 op sizeof(xdg_config_base));
328 eb2ed626 2021-10-07 op getenv_default(xdg_data_base, "XDG_DATA_HOME", "/.local/share",
329 eb2ed626 2021-10-07 op sizeof(xdg_data_base));
330 eb2ed626 2021-10-07 op getenv_default(xdg_cache_base, "XDG_CACHE_HOME", "/.cache",
331 eb2ed626 2021-10-07 op sizeof(xdg_cache_base));
332 eb2ed626 2021-10-07 op
333 eb2ed626 2021-10-07 op join_path(config_path_base, xdg_config_base, "/telescope",
334 eb2ed626 2021-10-07 op sizeof(config_path_base));
335 eb2ed626 2021-10-07 op join_path(data_path_base, xdg_data_base, "/telescope",
336 eb2ed626 2021-10-07 op sizeof(data_path_base));
337 eb2ed626 2021-10-07 op join_path(cache_path_base, xdg_cache_base, "/telescope",
338 eb2ed626 2021-10-07 op sizeof(cache_path_base));
339 eb2ed626 2021-10-07 op
340 eb2ed626 2021-10-07 op mkdirs(xdg_config_base, S_IRWXU);
341 eb2ed626 2021-10-07 op mkdirs(xdg_data_base, S_IRWXU);
342 eb2ed626 2021-10-07 op mkdirs(xdg_cache_base, S_IRWXU);
343 eb2ed626 2021-10-07 op
344 eb2ed626 2021-10-07 op mkdirs(config_path_base, S_IRWXU);
345 eb2ed626 2021-10-07 op mkdirs(data_path_base, S_IRWXU);
346 eb2ed626 2021-10-07 op mkdirs(cache_path_base, S_IRWXU);
347 eb2ed626 2021-10-07 op }
348 eb2ed626 2021-10-07 op
349 eb2ed626 2021-10-07 op int
350 eb2ed626 2021-10-07 op fs_init(void)
351 eb2ed626 2021-10-07 op {
352 6c8ddace 2022-01-03 op init_paths();
353 eb2ed626 2021-10-07 op
354 4cf6ba13 2022-02-11 op join_path(ctlsock_path, cache_path_base, "/ctl",
355 4cf6ba13 2022-02-11 op sizeof(ctlsock_path));
356 eb2ed626 2021-10-07 op join_path(config_path, config_path_base, "/config",
357 eb2ed626 2021-10-07 op sizeof(config_path));
358 eb2ed626 2021-10-07 op join_path(lockfile_path, cache_path_base, "/lock",
359 eb2ed626 2021-10-07 op sizeof(lockfile_path));
360 eb2ed626 2021-10-07 op join_path(bookmark_file, data_path_base, "/bookmarks.gmi",
361 eb2ed626 2021-10-07 op sizeof(bookmark_file));
362 eb2ed626 2021-10-07 op join_path(known_hosts_file, data_path_base, "/known_hosts",
363 eb2ed626 2021-10-07 op sizeof(known_hosts_file));
364 eb2ed626 2021-10-07 op join_path(known_hosts_tmp, cache_path_base,
365 eb2ed626 2021-10-07 op "/known_hosts.tmp.XXXXXXXXXX", sizeof(known_hosts_tmp));
366 eb2ed626 2021-10-07 op join_path(session_file, cache_path_base, "/session",
367 de6a6a40 2022-04-24 op sizeof(session_file));
368 de6a6a40 2022-04-24 op join_path(session_file_tmp, cache_path_base, "/session.XXXXXXXXXX",
369 0ec5e323 2024-02-03 op sizeof(session_file_tmp));
370 9e97090d 2022-02-26 op join_path(history_file, cache_path_base, "/history",
371 de6a6a40 2022-04-24 op sizeof(history_file));
372 de6a6a40 2022-04-24 op join_path(history_file_tmp, cache_path_base, "/history.XXXXXXXXXX",
373 0ec5e323 2024-02-03 op sizeof(history_file_tmp));
374 d35e18b3 2024-02-04 op join_path(cert_dir, data_path_base, "/certs/",
375 d35e18b3 2024-02-04 op sizeof(cert_dir));
376 f0e62b85 2024-02-15 op join_path(cert_dir_tmp, data_path_base, "/certs/id.XXXXXXXXXX",
377 f0e62b85 2024-02-15 op sizeof(cert_dir_tmp));
378 64b6a451 2024-02-05 op join_path(certs_file, config_path_base, "/certs.conf",
379 d35e18b3 2024-02-04 op sizeof(certs_file));
380 609eaf39 2024-02-05 op join_path(certs_file_tmp, config_path_base, "/certs.conf.XXXXXXXXXX",
381 d35e18b3 2024-02-04 op sizeof(certs_file_tmp));
382 eb2ed626 2021-10-07 op join_path(crashed_file, cache_path_base, "/crashed",
383 eb2ed626 2021-10-07 op sizeof(crashed_file));
384 eb2ed626 2021-10-07 op
385 d35e18b3 2024-02-04 op mkdirs(cert_dir, S_IRWXU);
386 d35e18b3 2024-02-04 op
387 108aa312 2024-02-14 op return 0;
388 9e97090d 2022-02-26 op }