💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 611f4885de972286942f892be601e… captured on 2023-12-28 at 15:42:05. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include "strlcpy.h"
8 #include "macro.h"
9 #include "error.h"
10 #include "storage.h"
11 #include "bookmarks.h"
12 #include "parser.h"
13 #include "utf8.h"
14
15 #define FILENAME "bookmarks.txt"
16 struct bookmark *bookmarks = NULL;
17 size_t bookmark_length = 0;
18
19 int bookmark_load() {
20
21 size_t i, j;
22 FILE *f = storage_fopen(FILENAME, "r");
23 int space, eof;
24
25 if (!f) { /* default bookmarks */
26 bookmark_add("gemini://geminispace.info", "Geminispace");
27 bookmark_add("gemini://gmi.rmf-dev.com/repo/Vaati/Vgmi/readme",
28 "Vgmi");
29 bookmark_add("about:about", "Settings");
30 return 0;
31 }
32 eof = 0;
33 while (!eof) {
34 uint32_t ch;
35 void *ptr;
36 struct bookmark bookmark = {0};
37 ch = j = space = 0;
38 for (i = 0; ; i++) {
39 int len;
40 if (utf8_fgetc(f, &ch)) {
41 eof = 1;
42 break;
43 }
44 if (ch == '\n') break;
45 if (space < 2 && WHITESPACE(ch)) {
46 space = 1;
47 continue;
48 }
49 if (space == 1) {
50 space = 2;
51 j = 0;
52 }
53 len = utf8_unicode_length(ch);
54 if (space) {
55 if (len + j > sizeof(bookmark.name)) {
56 bookmark.name[j] = 0;
57 break;
58 }
59 utf8_unicode_to_char(&bookmark.name[j], ch);
60 } else {
61 if (len + j > sizeof(bookmark.url)) {
62 bookmark.url[j] = 0;
63 break;
64 }
65 utf8_unicode_to_char(&bookmark.url[j], ch);
66 }
67 j += len;
68 }
69 if (*bookmark.url) {
70 bookmark_length++;
71 ptr = realloc(bookmarks,
72 sizeof(bookmark) * bookmark_length);
73 if (!ptr) {
74 free(bookmarks);
75 bookmarks = NULL;
76 fclose(f);
77 return ERROR_MEMORY_FAILURE;
78 }
79 bookmarks = ptr;
80 bookmarks[bookmark_length - 1] = bookmark;
81 }
82 if (!eof && ch != '\n') {
83 int ch = 0;
84 while (1) {
85 ch = fgetc(f);
86 if (ch == '\n' || ch == EOF) break;
87 }
88 if (ch == EOF) break;
89 }
90 }
91 fclose(f);
92 return 0;
93 }
94
95 int bookmark_rewrite() {
96
97 size_t i;
98 FILE *f = storage_fopen(FILENAME, "w");
99
100 if (!f) return ERROR_ERRNO;
101 for (i = 0; i < bookmark_length; i++)
102 fprintf(f, "%s %s\n", bookmarks[i].url, bookmarks[i].name);
103 fclose(f);
104
105 return 0;
106 }
107
108 int bookmark_add(const char *url, const char *name) {
109
110 void *ptr = realloc(bookmarks,
111 (bookmark_length + 1) * sizeof(struct bookmark));
112 if (!ptr) return ERROR_MEMORY_FAILURE;
113 bookmarks = ptr;
114 STRLCPY(bookmarks[bookmark_length].url, url);
115 STRLCPY(bookmarks[bookmark_length].name, name);
116 bookmark_length++;
117
118 return 0;
119 }
120
121 int bookmark_remove(size_t id) {
122 size_t i;
123 if (id >= bookmark_length) return -1;
124 bookmark_length--;
125 for (i = id; i < bookmark_length; i++) bookmarks[i] = bookmarks[i + 1];
126 return 0;
127 }
128