summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--doc/snac.85
-rw-r--r--httpd.c6
-rw-r--r--mastoapi.c15
-rw-r--r--snac.c3
-rw-r--r--utils.c4
-rw-r--r--xs_encdec.h196
-rw-r--r--xs_time.h13
-rw-r--r--xs_unicode.h46
-rw-r--r--xs_version.h2
10 files changed, 91 insertions, 201 deletions
diff --git a/Makefile b/Makefile
index 7dbd9e7..62beea0 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,7 @@ html.o: html.c xs.h xs_io.h xs_encdec.h xs_json.h xs_regex.h xs_set.h \
37http.o: http.c xs.h xs_io.h xs_encdec.h xs_openssl.h xs_curl.h xs_time.h \ 37http.o: http.c xs.h xs_io.h xs_encdec.h xs_openssl.h xs_curl.h xs_time.h \
38 xs_json.h snac.h 38 xs_json.h snac.h
39httpd.o: httpd.c xs.h xs_io.h xs_encdec.h xs_json.h xs_socket.h \ 39httpd.o: httpd.c xs.h xs_io.h xs_encdec.h xs_json.h xs_socket.h \
40 xs_httpd.h xs_mime.h snac.h 40 xs_httpd.h xs_mime.h xs_time.h snac.h
41main.o: main.c xs.h xs_io.h xs_encdec.h xs_json.h snac.h 41main.o: main.c xs.h xs_io.h xs_encdec.h xs_json.h snac.h
42mastoapi.o: mastoapi.c xs.h xs_encdec.h xs_openssl.h xs_json.h xs_io.h \ 42mastoapi.o: mastoapi.c xs.h xs_encdec.h xs_openssl.h xs_json.h xs_io.h \
43 xs_time.h xs_glob.h snac.h 43 xs_time.h xs_glob.h snac.h
diff --git a/doc/snac.8 b/doc/snac.8
index 2f60c96..38c9a90 100644
--- a/doc/snac.8
+++ b/doc/snac.8
@@ -179,6 +179,11 @@ By setting this to true, no email notification will be sent for any user.
179.It Ic disable_inbox_collection 179.It Ic disable_inbox_collection
180By setting this to true, no inbox collection is done. Inbox collection helps 180By setting this to true, no inbox collection is done. Inbox collection helps
181being discovered from remote instances, but also increases network traffic. 181being discovered from remote instances, but also increases network traffic.
182.It Ic admin_email
183The email address of the instance administrator (optional).
184.It Ic admin_account
185The user name of the instance administrator (optional, used only in the
186Mastodon API).
182.El 187.El
183.Pp 188.Pp
184You must restart the server to make effective these changes. 189You must restart the server to make effective these changes.
diff --git a/httpd.c b/httpd.c
index d946eae..841ad4c 100644
--- a/httpd.c
+++ b/httpd.c
@@ -8,6 +8,7 @@
8#include "xs_socket.h" 8#include "xs_socket.h"
9#include "xs_httpd.h" 9#include "xs_httpd.h"
10#include "xs_mime.h" 10#include "xs_mime.h"
11#include "xs_time.h"
11 12
12#include "snac.h" 13#include "snac.h"
13 14
@@ -480,6 +481,7 @@ void httpd(void)
480 pthread_t threads[MAX_THREADS] = {0}; 481 pthread_t threads[MAX_THREADS] = {0};
481 int n_threads = 0; 482 int n_threads = 0;
482 int n; 483 int n;
484 time_t start_time = time(NULL);
483 char sem_name[24]; 485 char sem_name[24];
484 486
485 address = xs_dict_get(srv_config, "address"); 487 address = xs_dict_get(srv_config, "address");
@@ -569,5 +571,7 @@ void httpd(void)
569 sem_close(job_sem); 571 sem_close(job_sem);
570 sem_unlink(sem_name); 572 sem_unlink(sem_name);
571 573
572 srv_log(xs_fmt("httpd stop %s:%d", address, port)); 574 xs *uptime = xs_str_time_diff(time(NULL) - start_time);
575
576 srv_log(xs_fmt("httpd stop %s:%d (run time: %s)", address, port, uptime));
573} 577}
diff --git a/mastoapi.c b/mastoapi.c
index 1b9ab09..fe46b23 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -1335,6 +1335,21 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1335 1335
1336 ins = xs_dict_append(ins, "configuration", cfg); 1336 ins = xs_dict_append(ins, "configuration", cfg);
1337 1337
1338 const char *admin_account = xs_dict_get(srv_config, "admin_account");
1339
1340 if (!xs_is_null(admin_account) && *admin_account) {
1341 snac admin;
1342
1343 if (user_open(&admin, admin_account)) {
1344 xs *actor = msg_actor(&admin);
1345 xs *acct = mastoapi_account(actor);
1346
1347 ins = xs_dict_append(ins, "contact_account", acct);
1348
1349 user_free(&admin);
1350 }
1351 }
1352
1338 *body = xs_json_dumps_pp(ins, 4); 1353 *body = xs_json_dumps_pp(ins, 4);
1339 *ctype = "application/json"; 1354 *ctype = "application/json";
1340 status = 200; 1355 status = 200;
diff --git a/snac.c b/snac.c
index a5b2080..8005546 100644
--- a/snac.c
+++ b/snac.c
@@ -5,8 +5,9 @@
5 5
6#include "xs.h" 6#include "xs.h"
7#include "xs_io.h" 7#include "xs_io.h"
8#include "xs_encdec.h" 8#include "xs_unicode.h"
9#include "xs_json.h" 9#include "xs_json.h"
10#include "xs_encdec.h"
10#include "xs_curl.h" 11#include "xs_curl.h"
11#include "xs_openssl.h" 12#include "xs_openssl.h"
12#include "xs_socket.h" 13#include "xs_socket.h"
diff --git a/utils.c b/utils.c
index 14e9f5d..189bd18 100644
--- a/utils.c
+++ b/utils.c
@@ -25,7 +25,9 @@ const char *default_srv_config = "{"
25 "\"cssurls\": [\"\"]," 25 "\"cssurls\": [\"\"],"
26 "\"max_timeline_entries\": 128," 26 "\"max_timeline_entries\": 128,"
27 "\"timeline_purge_days\": 120," 27 "\"timeline_purge_days\": 120,"
28 "\"local_purge_days\": 0" 28 "\"local_purge_days\": 0,"
29 "\"admin_email\": \"\","
30 "\"admin_account\": \"\""
29 "}"; 31 "}";
30 32
31const char *default_css = 33const char *default_css =
diff --git a/xs_encdec.h b/xs_encdec.h
index 2502520..f4ffe22 100644
--- a/xs_encdec.h
+++ b/xs_encdec.h
@@ -7,14 +7,9 @@
7 xs_str *xs_hex_enc(const xs_val *data, int size); 7 xs_str *xs_hex_enc(const xs_val *data, int size);
8 xs_val *xs_hex_dec(const xs_str *hex, int *size); 8 xs_val *xs_hex_dec(const xs_str *hex, int *size);
9 int xs_is_hex(const char *str); 9 int xs_is_hex(const char *str);
10 xs_str *xs_base32_enc(const xs_val *data, int sz);
11 xs_str *xs_base32hex_enc(const xs_val *data, int sz);
12 xs_val *xs_base32_dec(const xs_str *data, int *size);
13 xs_val *xs_base32hex_dec(const xs_str *data, int *size);
14 xs_str *xs_base64_enc(const xs_val *data, int sz); 10 xs_str *xs_base64_enc(const xs_val *data, int sz);
15 xs_val *xs_base64_dec(const xs_str *data, int *size); 11 xs_val *xs_base64_dec(const xs_str *data, int *size);
16 int xs_is_base64(const char *str); 12 int xs_is_base64(const char *str);
17 xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint);
18 13
19 14
20#ifdef XS_IMPLEMENTATION 15#ifdef XS_IMPLEMENTATION
@@ -85,165 +80,6 @@ int xs_is_hex(const char *str)
85} 80}
86 81
87 82
88/** base32 */
89
90static char *xs_b32_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
91 "234567=";
92
93static char *xs_b32hex_tbl = "0123456789"
94 "ABCDEFGHIJKLMNOPQRSTUV=";
95
96/*
97 00000|00011|11111|12222|22223|33333|33444|44444
98*/
99
100xs_str *xs_base32_enc_tbl(const xs_val *data, int sz, const char *b32_tbl)
101/* encodes data to base32 using a table */
102{
103 xs_str *s = xs_str_new(NULL);
104 unsigned char *p;
105 int n;
106
107 p = (unsigned char *)data;
108
109 for (n = 0; n < sz; n += 5) {
110 int l = sz - n;
111 char enc[9] = "========";
112
113 enc[0] = b32_tbl[(p[n] >> 3) & 0x1f];
114
115 if (l > 1) {
116 enc[1] = b32_tbl[(p[n] << 2 | p[n + 1] >> 6) & 0x1f];
117 enc[2] = b32_tbl[(p[n + 1] >> 1) & 0x1f];
118
119 if (l > 2) {
120 enc[3] = b32_tbl[(p[n + 1] << 4 | p[n + 2] >> 4) & 0x1f];
121
122 if (l > 3) {
123 enc[4] = b32_tbl[(p[n + 2] << 1 | p[n + 3] >> 7) & 0x1f];
124 enc[5] = b32_tbl[(p[n + 3] >> 2) & 0x1f];
125
126 if (l > 4) {
127 enc[6] = b32_tbl[(p[n + 3] << 3 | p[n + 4] >> 5) & 0x1f];
128 enc[7] = b32_tbl[(p[n + 4]) & 0x1f];
129 }
130 else
131 enc[6] = b32_tbl[(p[n + 3] << 3) & 0x1f];
132 }
133 else
134 enc[4] = b32_tbl[(p[n + 2] << 1) & 0x1f];
135 }
136 else
137 enc[3] = b32_tbl[(p[n + 1] << 4) & 0x1f];
138 }
139 else
140 enc[1] = b32_tbl[(p[n] << 2) & 0x1f];
141
142 s = xs_str_cat(s, enc);
143 }
144
145 return s;
146}
147
148
149xs_str *xs_base32_enc(const xs_val *data, int sz)
150/* encodes data to base32 */
151{
152 return xs_base32_enc_tbl(data, sz, xs_b32_tbl);
153}
154
155
156xs_str *xs_base32hex_enc(const xs_val *data, int sz)
157/* encodes data to base32 with HEX alphabet (RFC4648) */
158{
159 return xs_base32_enc_tbl(data, sz, xs_b32hex_tbl);
160}
161
162
163xs_val *xs_base32_dec_tbl(const xs_str *data, int *size, const char *b32_tbl)
164/* decodes data from base32 using a table */
165{
166 xs_val *s = NULL;
167 int sz = 0;
168 char *p;
169
170 p = (char *)data;
171
172 /* size of data must be a multiple of 8 */
173 if (strlen(p) % 8)
174 return NULL;
175
176 for (p = (char *)data; *p; p += 8) {
177 int cs[8];
178 int n;
179 unsigned char tmp[5];
180
181 for (n = 0; n < 8; n++) {
182 char *ss = strchr(b32_tbl, p[n]);
183
184 if (ss == NULL) {
185 /* not a base32 char */
186 return xs_free(s);
187 }
188
189 cs[n] = ss - b32_tbl;
190 }
191
192 n = 0;
193
194 /* #0 byte */
195 tmp[n++] = cs[0] << 3 | cs[1] >> 2;
196
197 if (cs[2] != 32) {
198 /* #1 byte */
199 tmp[n++] = (cs[1] & 0x3) << 6 | cs[2] << 1 | (cs[3] & 0x10) >> 4;
200
201 if (cs[4] != 32) {
202 /* #2 byte */
203 tmp[n++] = (cs[3] & 0xf) << 4 | cs[4] >> 1;
204
205 if (cs[5] != 32) {
206 /* #3 byte */
207 tmp[n++] = (cs[4] & 0x1) << 7 | cs[5] << 2 | cs[6] >> 3;
208
209 if (cs[7] != 32) {
210 /* #4 byte */
211 tmp[n++] = (cs[6] & 0x7) << 5 | cs[7];
212 }
213 }
214 }
215 }
216
217 /* must be done manually because data can be pure binary */
218 s = xs_realloc(s, _xs_blk_size(sz + n));
219 memcpy(s + sz, tmp, n);
220 sz += n;
221 }
222
223 /* asciiz it to use it as a string */
224 s = xs_realloc(s, _xs_blk_size(sz + 1));
225 s[sz] = '\0';
226
227 *size = sz;
228
229 return s;
230}
231
232
233xs_val *xs_base32_dec(const xs_str *data, int *size)
234/* decodes data from base32 */
235{
236 return xs_base32_dec_tbl(data, size, xs_b32_tbl);
237}
238
239
240xs_val *xs_base32hex_dec(const xs_str *data, int *size)
241/* decodes data from base32 with HEX alphabet (RFC4648) */
242{
243 return xs_base32_dec_tbl(data, size, xs_b32hex_tbl);
244}
245
246
247/** base64 */ 83/** base64 */
248 84
249static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 85static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -383,38 +219,6 @@ int xs_is_base64(const char *str)
383} 219}
384 220
385 221
386/** utf-8 **/
387
388xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint)
389/* encodes an Unicode codepoint to utf8 */
390{
391 unsigned char tmp[4];
392 int n = 0;
393
394 if (cpoint < 0x80)
395 tmp[n++] = cpoint & 0xff;
396 else
397 if (cpoint < 0x800) {
398 tmp[n++] = 0xc0 | (cpoint >> 6);
399 tmp[n++] = 0x80 | (cpoint & 0x3f);
400 }
401 else
402 if (cpoint < 0x10000) {
403 tmp[n++] = 0xe0 | (cpoint >> 12);
404 tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f);
405 tmp[n++] = 0x80 | (cpoint & 0x3f);
406 }
407 else
408 if (cpoint < 0x200000) {
409 tmp[n++] = 0xf0 | (cpoint >> 18);
410 tmp[n++] = 0x80 | ((cpoint >> 12) & 0x3f);
411 tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f);
412 tmp[n++] = 0x80 | (cpoint & 0x3f);
413 }
414
415 return xs_append_m(str, (char *)tmp, n);
416}
417
418#endif /* XS_IMPLEMENTATION */ 222#endif /* XS_IMPLEMENTATION */
419 223
420#endif /* _XS_ENCDEC_H */ 224#endif /* _XS_ENCDEC_H */
diff --git a/xs_time.h b/xs_time.h
index 94e472d..793b243 100644
--- a/xs_time.h
+++ b/xs_time.h
@@ -12,6 +12,7 @@ xs_str *xs_str_time(time_t t, const char *fmt, int local);
12time_t xs_parse_time(const char *str, const char *fmt, int local); 12time_t xs_parse_time(const char *str, const char *fmt, int local);
13#define xs_parse_localtime(str, fmt) xs_parse_time(str, fmt, 1) 13#define xs_parse_localtime(str, fmt) xs_parse_time(str, fmt, 1)
14#define xs_parse_utctime(str, fmt) xs_parse_time(str, fmt, 0) 14#define xs_parse_utctime(str, fmt) xs_parse_time(str, fmt, 0)
15xs_str *xs_str_time_diff(time_t time_diff);
15 16
16#ifdef XS_IMPLEMENTATION 17#ifdef XS_IMPLEMENTATION
17 18
@@ -37,6 +38,18 @@ xs_str *xs_str_time(time_t t, const char *fmt, int local)
37} 38}
38 39
39 40
41xs_str *xs_str_time_diff(time_t time_diff)
42/* returns time_diff in seconds to 'human' units (d:hh:mm:ss) */
43{
44 int secs = time_diff % 60;
45 int mins = (time_diff /= 60) % 60;
46 int hours = (time_diff /= 60) % 24;
47 int days = (time_diff /= 24);
48
49 return xs_fmt("%d:%02d:%02d:%02d", days, hours, mins, secs);
50}
51
52
40char *strptime(const char *s, const char *format, struct tm *tm); 53char *strptime(const char *s, const char *format, struct tm *tm);
41 54
42time_t xs_parse_time(const char *str, const char *fmt, int local) 55time_t xs_parse_time(const char *str, const char *fmt, int local)
diff --git a/xs_unicode.h b/xs_unicode.h
new file mode 100644
index 0000000..6f78d58
--- /dev/null
+++ b/xs_unicode.h
@@ -0,0 +1,46 @@
1/* copyright (c) 2022 - 2023 grunfink / MIT license */
2
3#ifndef _XS_UNICODE_H
4
5#define _XS_UNICODE_H
6
7 xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint);
8
9
10#ifdef XS_IMPLEMENTATION
11
12/** utf-8 **/
13
14xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint)
15/* encodes an Unicode codepoint to utf8 */
16{
17 unsigned char tmp[4];
18 int n = 0;
19
20 if (cpoint < 0x80)
21 tmp[n++] = cpoint & 0xff;
22 else
23 if (cpoint < 0x800) {
24 tmp[n++] = 0xc0 | (cpoint >> 6);
25 tmp[n++] = 0x80 | (cpoint & 0x3f);
26 }
27 else
28 if (cpoint < 0x10000) {
29 tmp[n++] = 0xe0 | (cpoint >> 12);
30 tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f);
31 tmp[n++] = 0x80 | (cpoint & 0x3f);
32 }
33 else
34 if (cpoint < 0x200000) {
35 tmp[n++] = 0xf0 | (cpoint >> 18);
36 tmp[n++] = 0x80 | ((cpoint >> 12) & 0x3f);
37 tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f);
38 tmp[n++] = 0x80 | (cpoint & 0x3f);
39 }
40
41 return xs_append_m(str, (char *)tmp, n);
42}
43
44#endif /* XS_IMPLEMENTATION */
45
46#endif /* _XS_UNICODE_H */
diff --git a/xs_version.h b/xs_version.h
index 6117ce9..d2b2069 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
/* dfdd729248d7169b80cb6a7462fe6c0ba6efeb16 */ /* 01bea7d4a0e631c0406b358dda9cc9409362c003 */