diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | doc/snac.8 | 5 | ||||
-rw-r--r-- | httpd.c | 6 | ||||
-rw-r--r-- | mastoapi.c | 15 | ||||
-rw-r--r-- | snac.c | 3 | ||||
-rw-r--r-- | utils.c | 4 | ||||
-rw-r--r-- | xs_encdec.h | 196 | ||||
-rw-r--r-- | xs_time.h | 13 | ||||
-rw-r--r-- | xs_unicode.h | 46 | ||||
-rw-r--r-- | xs_version.h | 2 |
10 files changed, 91 insertions, 201 deletions
@@ -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 \ http.o: http.c xs.h xs_io.h xs_encdec.h xs_openssl.h xs_curl.h xs_time.h \ xs_json.h snac.h httpd.o: httpd.c xs.h xs_io.h xs_encdec.h xs_json.h xs_socket.h \ - xs_httpd.h xs_mime.h snac.h + xs_httpd.h xs_mime.h xs_time.h snac.h main.o: main.c xs.h xs_io.h xs_encdec.h xs_json.h snac.h mastoapi.o: mastoapi.c xs.h xs_encdec.h xs_openssl.h xs_json.h xs_io.h \ xs_time.h xs_glob.h snac.h @@ -179,6 +179,11 @@ By setting this to true, no email notification will be sent for any user. .It Ic disable_inbox_collection By setting this to true, no inbox collection is done. Inbox collection helps being discovered from remote instances, but also increases network traffic. +.It Ic admin_email +The email address of the instance administrator (optional). +.It Ic admin_account +The user name of the instance administrator (optional, used only in the +Mastodon API). .El .Pp You must restart the server to make effective these changes. @@ -8,6 +8,7 @@ #include "xs_socket.h" #include "xs_httpd.h" #include "xs_mime.h" +#include "xs_time.h" #include "snac.h" @@ -480,6 +481,7 @@ void httpd(void) pthread_t threads[MAX_THREADS] = {0}; int n_threads = 0; int n; + time_t start_time = time(NULL); char sem_name[24]; address = xs_dict_get(srv_config, "address"); @@ -569,5 +571,7 @@ void httpd(void) sem_close(job_sem); sem_unlink(sem_name); - srv_log(xs_fmt("httpd stop %s:%d", address, port)); + xs *uptime = xs_str_time_diff(time(NULL) - start_time); + + srv_log(xs_fmt("httpd stop %s:%d (run time: %s)", address, port, uptime)); } @@ -1335,6 +1335,21 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, ins = xs_dict_append(ins, "configuration", cfg); + const char *admin_account = xs_dict_get(srv_config, "admin_account"); + + if (!xs_is_null(admin_account) && *admin_account) { + snac admin; + + if (user_open(&admin, admin_account)) { + xs *actor = msg_actor(&admin); + xs *acct = mastoapi_account(actor); + + ins = xs_dict_append(ins, "contact_account", acct); + + user_free(&admin); + } + } + *body = xs_json_dumps_pp(ins, 4); *ctype = "application/json"; status = 200; @@ -5,8 +5,9 @@ #include "xs.h" #include "xs_io.h" -#include "xs_encdec.h" +#include "xs_unicode.h" #include "xs_json.h" +#include "xs_encdec.h" #include "xs_curl.h" #include "xs_openssl.h" #include "xs_socket.h" @@ -25,7 +25,9 @@ const char *default_srv_config = "{" "\"cssurls\": [\"\"]," "\"max_timeline_entries\": 128," "\"timeline_purge_days\": 120," - "\"local_purge_days\": 0" + "\"local_purge_days\": 0," + "\"admin_email\": \"\"," + "\"admin_account\": \"\"" "}"; const 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 @@ xs_str *xs_hex_enc(const xs_val *data, int size); xs_val *xs_hex_dec(const xs_str *hex, int *size); int xs_is_hex(const char *str); - xs_str *xs_base32_enc(const xs_val *data, int sz); - xs_str *xs_base32hex_enc(const xs_val *data, int sz); - xs_val *xs_base32_dec(const xs_str *data, int *size); - xs_val *xs_base32hex_dec(const xs_str *data, int *size); xs_str *xs_base64_enc(const xs_val *data, int sz); xs_val *xs_base64_dec(const xs_str *data, int *size); int xs_is_base64(const char *str); - xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint); #ifdef XS_IMPLEMENTATION @@ -85,165 +80,6 @@ int xs_is_hex(const char *str) } -/** base32 */ - -static char *xs_b32_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "234567="; - -static char *xs_b32hex_tbl = "0123456789" - "ABCDEFGHIJKLMNOPQRSTUV="; - -/* - 00000|00011|11111|12222|22223|33333|33444|44444 -*/ - -xs_str *xs_base32_enc_tbl(const xs_val *data, int sz, const char *b32_tbl) -/* encodes data to base32 using a table */ -{ - xs_str *s = xs_str_new(NULL); - unsigned char *p; - int n; - - p = (unsigned char *)data; - - for (n = 0; n < sz; n += 5) { - int l = sz - n; - char enc[9] = "========"; - - enc[0] = b32_tbl[(p[n] >> 3) & 0x1f]; - - if (l > 1) { - enc[1] = b32_tbl[(p[n] << 2 | p[n + 1] >> 6) & 0x1f]; - enc[2] = b32_tbl[(p[n + 1] >> 1) & 0x1f]; - - if (l > 2) { - enc[3] = b32_tbl[(p[n + 1] << 4 | p[n + 2] >> 4) & 0x1f]; - - if (l > 3) { - enc[4] = b32_tbl[(p[n + 2] << 1 | p[n + 3] >> 7) & 0x1f]; - enc[5] = b32_tbl[(p[n + 3] >> 2) & 0x1f]; - - if (l > 4) { - enc[6] = b32_tbl[(p[n + 3] << 3 | p[n + 4] >> 5) & 0x1f]; - enc[7] = b32_tbl[(p[n + 4]) & 0x1f]; - } - else - enc[6] = b32_tbl[(p[n + 3] << 3) & 0x1f]; - } - else - enc[4] = b32_tbl[(p[n + 2] << 1) & 0x1f]; - } - else - enc[3] = b32_tbl[(p[n + 1] << 4) & 0x1f]; - } - else - enc[1] = b32_tbl[(p[n] << 2) & 0x1f]; - - s = xs_str_cat(s, enc); - } - - return s; -} - - -xs_str *xs_base32_enc(const xs_val *data, int sz) -/* encodes data to base32 */ -{ - return xs_base32_enc_tbl(data, sz, xs_b32_tbl); -} - - -xs_str *xs_base32hex_enc(const xs_val *data, int sz) -/* encodes data to base32 with HEX alphabet (RFC4648) */ -{ - return xs_base32_enc_tbl(data, sz, xs_b32hex_tbl); -} - - -xs_val *xs_base32_dec_tbl(const xs_str *data, int *size, const char *b32_tbl) -/* decodes data from base32 using a table */ -{ - xs_val *s = NULL; - int sz = 0; - char *p; - - p = (char *)data; - - /* size of data must be a multiple of 8 */ - if (strlen(p) % 8) - return NULL; - - for (p = (char *)data; *p; p += 8) { - int cs[8]; - int n; - unsigned char tmp[5]; - - for (n = 0; n < 8; n++) { - char *ss = strchr(b32_tbl, p[n]); - - if (ss == NULL) { - /* not a base32 char */ - return xs_free(s); - } - - cs[n] = ss - b32_tbl; - } - - n = 0; - - /* #0 byte */ - tmp[n++] = cs[0] << 3 | cs[1] >> 2; - - if (cs[2] != 32) { - /* #1 byte */ - tmp[n++] = (cs[1] & 0x3) << 6 | cs[2] << 1 | (cs[3] & 0x10) >> 4; - - if (cs[4] != 32) { - /* #2 byte */ - tmp[n++] = (cs[3] & 0xf) << 4 | cs[4] >> 1; - - if (cs[5] != 32) { - /* #3 byte */ - tmp[n++] = (cs[4] & 0x1) << 7 | cs[5] << 2 | cs[6] >> 3; - - if (cs[7] != 32) { - /* #4 byte */ - tmp[n++] = (cs[6] & 0x7) << 5 | cs[7]; - } - } - } - } - - /* must be done manually because data can be pure binary */ - s = xs_realloc(s, _xs_blk_size(sz + n)); - memcpy(s + sz, tmp, n); - sz += n; - } - - /* asciiz it to use it as a string */ - s = xs_realloc(s, _xs_blk_size(sz + 1)); - s[sz] = '\0'; - - *size = sz; - - return s; -} - - -xs_val *xs_base32_dec(const xs_str *data, int *size) -/* decodes data from base32 */ -{ - return xs_base32_dec_tbl(data, size, xs_b32_tbl); -} - - -xs_val *xs_base32hex_dec(const xs_str *data, int *size) -/* decodes data from base32 with HEX alphabet (RFC4648) */ -{ - return xs_base32_dec_tbl(data, size, xs_b32hex_tbl); -} - - /** base64 */ static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -383,38 +219,6 @@ int xs_is_base64(const char *str) } -/** utf-8 **/ - -xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint) -/* encodes an Unicode codepoint to utf8 */ -{ - unsigned char tmp[4]; - int n = 0; - - if (cpoint < 0x80) - tmp[n++] = cpoint & 0xff; - else - if (cpoint < 0x800) { - tmp[n++] = 0xc0 | (cpoint >> 6); - tmp[n++] = 0x80 | (cpoint & 0x3f); - } - else - if (cpoint < 0x10000) { - tmp[n++] = 0xe0 | (cpoint >> 12); - tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f); - tmp[n++] = 0x80 | (cpoint & 0x3f); - } - else - if (cpoint < 0x200000) { - tmp[n++] = 0xf0 | (cpoint >> 18); - tmp[n++] = 0x80 | ((cpoint >> 12) & 0x3f); - tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f); - tmp[n++] = 0x80 | (cpoint & 0x3f); - } - - return xs_append_m(str, (char *)tmp, n); -} - #endif /* XS_IMPLEMENTATION */ #endif /* _XS_ENCDEC_H */ @@ -12,6 +12,7 @@ xs_str *xs_str_time(time_t t, const char *fmt, int local); time_t xs_parse_time(const char *str, const char *fmt, int local); #define xs_parse_localtime(str, fmt) xs_parse_time(str, fmt, 1) #define xs_parse_utctime(str, fmt) xs_parse_time(str, fmt, 0) +xs_str *xs_str_time_diff(time_t time_diff); #ifdef XS_IMPLEMENTATION @@ -37,6 +38,18 @@ xs_str *xs_str_time(time_t t, const char *fmt, int local) } +xs_str *xs_str_time_diff(time_t time_diff) +/* returns time_diff in seconds to 'human' units (d:hh:mm:ss) */ +{ + int secs = time_diff % 60; + int mins = (time_diff /= 60) % 60; + int hours = (time_diff /= 60) % 24; + int days = (time_diff /= 24); + + return xs_fmt("%d:%02d:%02d:%02d", days, hours, mins, secs); +} + + char *strptime(const char *s, const char *format, struct tm *tm); time_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 @@ +/* copyright (c) 2022 - 2023 grunfink / MIT license */ + +#ifndef _XS_UNICODE_H + +#define _XS_UNICODE_H + + xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint); + + +#ifdef XS_IMPLEMENTATION + +/** utf-8 **/ + +xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint) +/* encodes an Unicode codepoint to utf8 */ +{ + unsigned char tmp[4]; + int n = 0; + + if (cpoint < 0x80) + tmp[n++] = cpoint & 0xff; + else + if (cpoint < 0x800) { + tmp[n++] = 0xc0 | (cpoint >> 6); + tmp[n++] = 0x80 | (cpoint & 0x3f); + } + else + if (cpoint < 0x10000) { + tmp[n++] = 0xe0 | (cpoint >> 12); + tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f); + tmp[n++] = 0x80 | (cpoint & 0x3f); + } + else + if (cpoint < 0x200000) { + tmp[n++] = 0xf0 | (cpoint >> 18); + tmp[n++] = 0x80 | ((cpoint >> 12) & 0x3f); + tmp[n++] = 0x80 | ((cpoint >> 6) & 0x3f); + tmp[n++] = 0x80 | (cpoint & 0x3f); + } + + return xs_append_m(str, (char *)tmp, n); +} + +#endif /* XS_IMPLEMENTATION */ + +#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 */ |