diff options
| -rw-r--r-- | RELEASE_NOTES.md | 2 | ||||
| -rw-r--r-- | activitypub.c | 10 | ||||
| -rw-r--r-- | data.c | 29 | ||||
| -rw-r--r-- | html.c | 5 | ||||
| -rw-r--r-- | httpd.c | 3 | ||||
| -rw-r--r-- | po/de_DE.po | 10 | ||||
| -rw-r--r-- | snac.h | 4 | ||||
| -rw-r--r-- | utils.c | 2 | ||||
| -rw-r--r-- | xs_curl.h | 18 |
9 files changed, 61 insertions, 22 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d89bee6..7dfb332 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # Release Notes | 1 | # Release Notes |
| 2 | 2 | ||
| 3 | ## UNRELEASED | 3 | ## 2.84 |
| 4 | 4 | ||
| 5 | Implemented more scopes to match other ActivityPub implementations (public, unlisted, followers-only and direct message) (contributed by byte). | 5 | Implemented more scopes to match other ActivityPub implementations (public, unlisted, followers-only and direct message) (contributed by byte). |
| 6 | 6 | ||
diff --git a/activitypub.c b/activitypub.c index 2d53cbe..0368ac8 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -3660,8 +3660,9 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 3660 | uid = xs_list_get(l, 1); | 3660 | uid = xs_list_get(l, 1); |
| 3661 | if (!user_open(&snac, uid)) { | 3661 | if (!user_open(&snac, uid)) { |
| 3662 | /* invalid user */ | 3662 | /* invalid user */ |
| 3663 | srv_debug(1, xs_fmt("activitypub_get_handler bad user %s", uid)); | 3663 | status = grave(uid, 0) ? HTTP_STATUS_GONE : HTTP_STATUS_NOT_FOUND; |
| 3664 | return HTTP_STATUS_NOT_FOUND; | 3664 | srv_debug(1, xs_fmt("activitypub_get_handler bad user %s %d", uid, status)); |
| 3665 | return status; | ||
| 3665 | } | 3666 | } |
| 3666 | 3667 | ||
| 3667 | p_path = xs_list_get(l, 2); | 3668 | p_path = xs_list_get(l, 2); |
| @@ -3854,8 +3855,9 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path, | |||
| 3854 | const char *uid = xs_list_get(l, 1); | 3855 | const char *uid = xs_list_get(l, 1); |
| 3855 | if (!user_open(&snac, uid)) { | 3856 | if (!user_open(&snac, uid)) { |
| 3856 | /* invalid user */ | 3857 | /* invalid user */ |
| 3857 | srv_debug(1, xs_fmt("activitypub_post_handler bad user %s", uid)); | 3858 | status = grave(uid, 0) ? HTTP_STATUS_GONE : HTTP_STATUS_NOT_FOUND; |
| 3858 | return HTTP_STATUS_NOT_FOUND; | 3859 | srv_debug(1, xs_fmt("activitypub_post_handler bad user %s %d", uid, status)); |
| 3860 | return status; | ||
| 3859 | } | 3861 | } |
| 3860 | 3862 | ||
| 3861 | /* if it has a digest, check it now, because | 3863 | /* if it has a digest, check it now, because |
| @@ -3137,6 +3137,35 @@ int instance_failure(const char *url, int op) | |||
| 3137 | } | 3137 | } |
| 3138 | 3138 | ||
| 3139 | 3139 | ||
| 3140 | int grave(const char *objid, int op) | ||
| 3141 | /* the graveyeard of deleted objects */ | ||
| 3142 | { | ||
| 3143 | int ret = 0; | ||
| 3144 | xs *dir = xs_fmt("%s/grave", srv_basedir); | ||
| 3145 | xs *md5 = xs_md5_hex(objid, strlen(objid)); | ||
| 3146 | xs *fn = xs_fmt("%s/%s", dir, md5); | ||
| 3147 | FILE *f; | ||
| 3148 | |||
| 3149 | switch (op) { | ||
| 3150 | case 0: /** check **/ | ||
| 3151 | ret = mtime(fn) > 0.0 ? 1 : 0; | ||
| 3152 | break; | ||
| 3153 | |||
| 3154 | case 1: /** add **/ | ||
| 3155 | mkdirx(dir); | ||
| 3156 | |||
| 3157 | if ((f = fopen(fn, "w")) != NULL) { | ||
| 3158 | fprintf(f, "%s\n", objid); | ||
| 3159 | fclose(f); | ||
| 3160 | } | ||
| 3161 | |||
| 3162 | break; | ||
| 3163 | } | ||
| 3164 | |||
| 3165 | return ret; | ||
| 3166 | } | ||
| 3167 | |||
| 3168 | |||
| 3140 | /** notifications **/ | 3169 | /** notifications **/ |
| 3141 | 3170 | ||
| 3142 | xs_str *notify_check_time(snac *snac, int reset) | 3171 | xs_str *notify_check_time(snac *snac, int reset) |
| @@ -3822,8 +3822,9 @@ int html_get_handler(const xs_dict *req, const char *q_path, | |||
| 3822 | 3822 | ||
| 3823 | if (!uid || !user_open(&snac, uid)) { | 3823 | if (!uid || !user_open(&snac, uid)) { |
| 3824 | /* invalid user */ | 3824 | /* invalid user */ |
| 3825 | srv_debug(1, xs_fmt("html_get_handler bad user %s", uid)); | 3825 | status = grave(uid, 0) ? HTTP_STATUS_GONE : HTTP_STATUS_NOT_FOUND; |
| 3826 | return HTTP_STATUS_NOT_FOUND; | 3826 | srv_debug(1, xs_fmt("html_get_handler bad user %s %d", uid, status)); |
| 3827 | return status; | ||
| 3827 | } | 3828 | } |
| 3828 | 3829 | ||
| 3829 | user = &snac; /* for L() */ | 3830 | user = &snac; /* for L() */ |
| @@ -598,6 +598,9 @@ void httpd_connection(FILE *f) | |||
| 598 | if (status == HTTP_STATUS_NOT_FOUND) | 598 | if (status == HTTP_STATUS_NOT_FOUND) |
| 599 | body = xs_str_new("<h1>404 Not Found (" USER_AGENT ")</h1>"); | 599 | body = xs_str_new("<h1>404 Not Found (" USER_AGENT ")</h1>"); |
| 600 | 600 | ||
| 601 | if (status == HTTP_STATUS_GONE) | ||
| 602 | body = xs_str_new("<h1>410 Gone (" USER_AGENT ")</h1>"); | ||
| 603 | |||
| 601 | if (status == HTTP_STATUS_BAD_REQUEST && body != NULL) | 604 | if (status == HTTP_STATUS_BAD_REQUEST && body != NULL) |
| 602 | body = xs_str_new("<h1>400 Bad Request (" USER_AGENT ")</h1>"); | 605 | body = xs_str_new("<h1>400 Bad Request (" USER_AGENT ")</h1>"); |
| 603 | 606 | ||
diff --git a/po/de_DE.po b/po/de_DE.po index 147f7ac..bb6876c 100644 --- a/po/de_DE.po +++ b/po/de_DE.po | |||
| @@ -782,20 +782,20 @@ msgstr "en fr es de_DE" | |||
| 782 | 782 | ||
| 783 | #: html.c:460 | 783 | #: html.c:460 |
| 784 | msgid "Visibility: " | 784 | msgid "Visibility: " |
| 785 | msgstr "" | 785 | msgstr "Sichtbarkeit" |
| 786 | 786 | ||
| 787 | #: html.c:468 | 787 | #: html.c:468 |
| 788 | msgid "Public" | 788 | msgid "Public" |
| 789 | msgstr "" | 789 | msgstr "Öffentlich" |
| 790 | 790 | ||
| 791 | #: html.c:477 | 791 | #: html.c:477 |
| 792 | msgid "Unlisted" | 792 | msgid "Unlisted" |
| 793 | msgstr "" | 793 | msgstr "Ungelistete" |
| 794 | 794 | ||
| 795 | #: html.c:486 | 795 | #: html.c:486 |
| 796 | msgid "Followers-only" | 796 | msgid "Followers-only" |
| 797 | msgstr "" | 797 | msgstr "Nur Follower" |
| 798 | 798 | ||
| 799 | #: html.c:495 | 799 | #: html.c:495 |
| 800 | msgid "Direct Message" | 800 | msgid "Direct Message" |
| 801 | msgstr "" | 801 | msgstr "Direktnachricht" |
| @@ -1,7 +1,7 @@ | |||
| 1 | /* snac - A simple, minimalistic ActivityPub instance */ | 1 | /* snac - A simple, minimalistic ActivityPub instance */ |
| 2 | /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ | 2 | /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ |
| 3 | 3 | ||
| 4 | #define VERSION "2.84-dev" | 4 | #define VERSION "2.84" |
| 5 | 5 | ||
| 6 | #define USER_AGENT "snac/" VERSION | 6 | #define USER_AGENT "snac/" VERSION |
| 7 | 7 | ||
| @@ -288,6 +288,8 @@ xs_list *content_search(snac *user, const char *regex, | |||
| 288 | int actor_failure(const char *actor, int op); | 288 | int actor_failure(const char *actor, int op); |
| 289 | int instance_failure(const char *url, int op); | 289 | int instance_failure(const char *url, int op); |
| 290 | 290 | ||
| 291 | int grave(const char *objid, int op); | ||
| 292 | |||
| 291 | void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries); | 293 | void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries); |
| 292 | void enqueue_shared_input(const xs_dict *msg, const xs_dict *req, int retries); | 294 | void enqueue_shared_input(const xs_dict *msg, const xs_dict *req, int retries); |
| 293 | void enqueue_output_raw(const char *keyid, const char *seckey, | 295 | void enqueue_output_raw(const char *keyid, const char *seckey, |
| @@ -454,6 +454,8 @@ int deluser(snac *user) | |||
| 454 | } | 454 | } |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | grave(user->uid, 1); | ||
| 458 | |||
| 457 | rm_rf(user->basedir); | 459 | rm_rf(user->basedir); |
| 458 | 460 | ||
| 459 | return ret; | 461 | return ret; |
| @@ -54,10 +54,10 @@ struct _payload_data { | |||
| 54 | int offset; | 54 | int offset; |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | static int _data_callback(void *buffer, size_t size, | 57 | static size_t _data_callback(void *buffer, size_t size, |
| 58 | size_t nitems, struct _payload_data *pd) | 58 | size_t nitems, struct _payload_data *pd) |
| 59 | { | 59 | { |
| 60 | int sz = size * nitems; | 60 | size_t sz = size * nitems; |
| 61 | 61 | ||
| 62 | /* open space */ | 62 | /* open space */ |
| 63 | pd->size += sz; | 63 | pd->size += sz; |
| @@ -71,14 +71,14 @@ static int _data_callback(void *buffer, size_t size, | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | 73 | ||
| 74 | static int _post_callback(char *buffer, size_t size, | 74 | static size_t _post_callback(char *buffer, size_t size, |
| 75 | size_t nitems, struct _payload_data *pd) | 75 | size_t nitems, struct _payload_data *pd) |
| 76 | { | 76 | { |
| 77 | /* size of data left */ | 77 | /* size of data left */ |
| 78 | int sz = pd->size - pd->offset; | 78 | size_t sz = pd->size - pd->offset; |
| 79 | 79 | ||
| 80 | /* if it's still bigger than the provided space, trim */ | 80 | /* if it's still bigger than the provided space, trim */ |
| 81 | if (sz > (int) (size * nitems)) | 81 | if (sz > (size_t) (size * nitems)) |
| 82 | sz = size * nitems; | 82 | sz = size * nitems; |
| 83 | 83 | ||
| 84 | memcpy(buffer, pd->data + pd->offset, sz); | 84 | memcpy(buffer, pd->data + pd->offset, sz); |
| @@ -125,11 +125,11 @@ xs_dict *xs_http_request(const char *method, const char *url, | |||
| 125 | 125 | ||
| 126 | /* store response headers here */ | 126 | /* store response headers here */ |
| 127 | curl_easy_setopt(curl, CURLOPT_HEADERDATA, &response); | 127 | curl_easy_setopt(curl, CURLOPT_HEADERDATA, &response); |
| 128 | curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, _header_callback); | 128 | curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_read_callback) _header_callback); |
| 129 | 129 | ||
| 130 | struct _payload_data ipd = { NULL, 0, 0 }; | 130 | struct _payload_data ipd = { NULL, 0, 0 }; |
| 131 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ipd); | 131 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ipd); |
| 132 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _data_callback); | 132 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_read_callback) _data_callback); |
| 133 | 133 | ||
| 134 | if (strcmp(method, "POST") == 0 || strcmp(method, "PUT") == 0) { | 134 | if (strcmp(method, "POST") == 0 || strcmp(method, "PUT") == 0) { |
| 135 | CURLoption curl_method = method[1] == 'O' ? CURLOPT_POST : CURLOPT_UPLOAD; | 135 | CURLoption curl_method = method[1] == 'O' ? CURLOPT_POST : CURLOPT_UPLOAD; |
| @@ -147,7 +147,7 @@ xs_dict *xs_http_request(const char *method, const char *url, | |||
| 147 | pd.offset = 0; | 147 | pd.offset = 0; |
| 148 | 148 | ||
| 149 | curl_easy_setopt(curl, CURLOPT_READDATA, &pd); | 149 | curl_easy_setopt(curl, CURLOPT_READDATA, &pd); |
| 150 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, _post_callback); | 150 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback) _post_callback); |
| 151 | } | 151 | } |
| 152 | } | 152 | } |
| 153 | 153 | ||
| @@ -232,7 +232,7 @@ int xs_smtp_request(const char *url, const char *user, const char *pass, | |||
| 232 | curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt); | 232 | curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt); |
| 233 | 233 | ||
| 234 | curl_easy_setopt(curl, CURLOPT_READDATA, &pd); | 234 | curl_easy_setopt(curl, CURLOPT_READDATA, &pd); |
| 235 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, _post_callback); | 235 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback) _post_callback); |
| 236 | curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); | 236 | curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); |
| 237 | 237 | ||
| 238 | res = curl_easy_perform(curl); | 238 | res = curl_easy_perform(curl); |