💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 1ae26cfbc0efc34ecc52510b2797d… captured on 2024-02-05 at 09:56:11. 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 <string.h>
8 #include "macro.h"
9 #include "strlcpy.h"
10 #include "strnstr.h"
11 #include "error.h"
12 #include "image.h"
13 #include "storage.h"
14 #define CONFIG_INTERNAL
15 #include "config.h"
16
17 #define DEFAULT_SEARCH_URL "gemini://geminispace.info/search?%s"
18 #define CONFIG_FILE "config.conf"
19
20 struct config config = {0};
21
22 void config_default(void) {
23 memset(&config, 0, sizeof(config));
24 config.certificateLifespan = 3600 * 24 * 365 * 2; /* 2 years */
25 config.certificateBits = 2048;
26 config.enableHexViewer = 1;
27 config.enableSandbox = 1;
28 config.enableImage = 1;
29 config.enableHistory = 1;
30 config.enableXdg = 1;
31 config.maximumBodyLength = 8388608;
32 config.maximumDisplayLength = 1048576;
33 config.imageParserScratchPad = 10485760;
34 config.maximumRedirects = 5;
35 config.maximumCachedPages= 15;
36 config.maximumHistorySize = 3000;
37 config.maximumHistoryCache = 200;
38 STRLCPY(config.searchEngineURL, DEFAULT_SEARCH_URL);
39 }
40
41 static int set_field(struct field field, int v, char *str) {
42 unsigned int i = 0;
43 for (i = 0; i < LENGTH(fields); i++) {
44 if (STRCMP(fields[i].name, field.name)) continue;
45 if (fields[i].type != field.type) break;
46 switch (fields[i].type) {
47 case VALUE_INT:
48 {
49 int *integer = fields[i].ptr;
50 *integer = v;
51 }
52 break;
53 case VALUE_STRING:
54 strlcpy(fields[i].ptr, str, CONFIG_STRING_LENGTH);
55 break;
56 }
57 break;
58 }
59 return 0;
60 }
61
62 int config_set_field(int id, const char *value) {
63 if (id < 0 || (unsigned)id > LENGTH(fields))
64 return ERROR_INVALID_ARGUMENT;
65 switch (fields[id].type) {
66 case VALUE_INT:
67 {
68 int ivalue = atoi(value);
69 if (!ivalue && strcmp(value, "0"))
70 return ERROR_INVALID_ARGUMENT;
71 *(int*)fields[id].ptr = ivalue;
72 }
73 break;
74 case VALUE_STRING:
75 strlcpy(fields[id].ptr, value, CONFIG_STRING_LENGTH);
76 break;
77 default:
78 return ERROR_INVALID_ARGUMENT;
79 }
80 config_correction();
81 return 0;
82 }
83
84 int config_load(void) {
85 FILE *f;
86 struct field field;
87 char buf[1024];
88 int i, in_str, in_comment;
89 config_default();
90 if (!(f = storage_fopen(CONFIG_FILE, "r")))
91 return ERROR_STORAGE_ACCESS;
92
93 in_comment = in_str = i = 0;
94 while (1) {
95 int ch = fgetc(f);
96 if (ch == EOF || ch == '\n') {
97 int ivalue;
98 buf[i] = 0;
99 in_comment = in_str = i = 0;
100 ivalue = atoi(buf);
101 if (ivalue || !STRCMP(buf, "0")) {
102 field.type = VALUE_INT;
103 set_field(field, ivalue, NULL);
104 } else {
105 field.type = VALUE_STRING;
106 set_field(field, 0, buf);
107 }
108 field.name[0] = 0;
109 if (ch == EOF) break;
110 continue;
111 }
112 if (in_comment) continue;
113 if (!in_str && ch <= ' ') continue;
114 if (ch == '"') {
115 in_str = !in_str;
116 continue;
117 }
118 if (!in_str && ch == '#') {
119 in_comment = 1;
120 }
121 if (!in_str && ch == '=') {
122 buf[i] = 0;
123 STRLCPY(field.name, buf);
124 i = 0;
125 continue;
126 }
127 if ((unsigned)i >= sizeof(buf)) {
128 i = 0;
129 continue;
130 }
131 buf[i++] = ch;
132 }
133
134 fclose(f);
135 config_correction();
136 return 0;
137 }
138
139 int config_save(void) {
140
141 FILE *f;
142 unsigned int i;
143 if (!(f = storage_fopen(CONFIG_FILE, "w")))
144 return ERROR_STORAGE_ACCESS;
145 for (i = 0; i < LENGTH(fields); i++) {
146 switch (fields[i].type) {
147 case VALUE_INT:
148 fprintf(f, "%s = %d\n", fields[i].name,
149 *(int*)fields[i].ptr);
150 break;
151 case VALUE_STRING:
152 fprintf(f, "%s = \"%s\"\n", fields[i].name,
153 (char*)fields[i].ptr);
154 break;
155 }
156 }
157
158 fclose(f);
159 return 0;
160 }
161
162 int config_correction(void) {
163 size_t i;
164 for (i = 0; i < LENGTH(fields); i++) {
165 if (!STRCMP(fields[i].name, "request.maxdisplay")) {
166 unsigned int *value = fields[i].ptr;
167 if (*value < 4096) *value = 4096;
168 }
169 if (!STRCMP(fields[i].name, "search.url")) {
170 char *value = fields[i].ptr;
171 char *ptr = strnstr(value, "%s", CONFIG_STRING_LENGTH);
172 char *second = NULL;
173 if (ptr) {
174 second = strnstr(ptr + 1, "%s",
175 CONFIG_STRING_LENGTH - (ptr - value));
176 }
177 if (!ptr || second) {
178 strlcpy(fields[i].ptr, DEFAULT_SEARCH_URL,
179 CONFIG_STRING_LENGTH);
180 }
181 }
182 }
183 return 0;
184 }
185