From 6b632e1ee9450f12c51442264e402753f8dfe325 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 30 Apr 2023 06:01:08 +0200 Subject: Bumped version. --- snac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'snac.h') diff --git a/snac.h b/snac.h index fe7adfb..a17d33f 100644 --- a/snac.h +++ b/snac.h @@ -1,7 +1,7 @@ /* snac - A simple, minimalistic ActivityPub instance */ /* copyright (c) 2022 - 2023 grunfink / MIT license */ -#define VERSION "2.29" +#define VERSION "2.30-dev" #define USER_AGENT "snac/" VERSION -- cgit v1.2.3 From ede4d6f2dc8f862337724054dcfeb31cbaa89bcc Mon Sep 17 00:00:00 2001 From: default Date: Sun, 30 Apr 2023 06:39:55 +0200 Subject: Some instance timeline work. --- data.c | 13 +++++++++++-- mastoapi.c | 52 +++++++++++++++++++++++----------------------------- snac.h | 8 ++++---- 3 files changed, 38 insertions(+), 35 deletions(-) (limited to 'snac.h') diff --git a/data.c b/data.c index db42ece..60c4b26 100644 --- a/data.c +++ b/data.c @@ -1046,7 +1046,7 @@ xs_list *timeline_top_level(snac *snac, xs_list *list) } -d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show) +xs_list *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show) /* returns a timeline (with all entries) */ { int c_max; @@ -1064,7 +1064,7 @@ d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int sho } -d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show) +xs_list *timeline_list(snac *snac, const char *idx_name, int skip, int show) /* returns a timeline (only top level entries) */ { xs *list = timeline_simple_list(snac, idx_name, skip, show); @@ -1073,6 +1073,15 @@ d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show) } +xs_list *timeline_instance_list(int skip, int show) +/* returns the timeline for the full instance */ +{ + xs *idx = xs_fmt("%s/public.idx", srv_basedir); + + return index_list_desc(idx, skip, show); +} + + /** following **/ /* this needs special treatment and cannot use the object db as is, diff --git a/mastoapi.c b/mastoapi.c index 001c0bc..92acd41 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1038,9 +1038,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (strcmp(cmd, "/v1/timelines/public") == 0) { /* the public timeline (public timelines for all users) */ - /* this is an ugly kludge: first users in the list get all the fame */ - - const char *limit_s = xs_dict_get(args, "limit"); + const char *limit_s = xs_dict_get(args, "limit"); int limit = 0; int cnt = 0; @@ -1050,44 +1048,40 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (limit == 0) limit = 20; - xs *out = xs_list_new(); - xs *users = user_list(); - xs_list *p = users; - xs_str *uid; - - while (xs_list_iter(&p, &uid) && cnt < limit) { - snac user; + xs *timeline = timeline_instance_list(0, limit); + xs *out = xs_list_new(); + xs_list *p = timeline; + xs_str *md5; - if (user_open(&user, uid)) { - xs *timeline = timeline_simple_list(&user, "public", 0, 4); - xs_list *p2 = timeline; - xs_str *v; + while (xs_list_iter(&p, &md5) && cnt < limit) { + xs *msg = NULL; - while (xs_list_iter(&p2, &v) && cnt < limit) { - xs *msg = NULL; + /* get the entry */ + if (!valid_status(object_get_by_md5(md5, &msg))) + continue; - /* get the entry */ - if (!valid_status(timeline_get_by_md5(&user, v, &msg))) - continue; + /* discard non-Notes */ + if (strcmp(xs_dict_get(msg, "type"), "Note") != 0) + continue; - /* discard non-Notes */ - if (strcmp(xs_dict_get(msg, "type"), "Note") != 0) - continue; + /* get the uid */ + xs *l = xs_split(xs_dict_get(msg, "attributedTo"), "/"); + const char *uid = xs_list_get(l, -1); - /* discard entries not by this user */ - if (!xs_startswith(xs_dict_get(msg, "id"), user.actor)) - continue; + if (!xs_is_null(uid)) { + snac user; + if (user_open(&user, uid)) { /* convert the Note into a Mastodon status */ xs *st = mastoapi_status(&user, msg); - if (st != NULL) { + if (st != NULL) out = xs_list_append(out, st); - cnt++; - } + + user_free(&user); } - user_free(&user); + cnt++; } } diff --git a/snac.h b/snac.h index a17d33f..5478933 100644 --- a/snac.h +++ b/snac.h @@ -105,14 +105,14 @@ int timeline_touch(snac *snac); int timeline_here(snac *snac, const char *md5); int timeline_get_by_md5(snac *snac, const char *md5, xs_dict **msg); int timeline_del(snac *snac, char *id); -d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show); -d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show); +xs_list *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show); +xs_list *timeline_list(snac *snac, const char *idx_name, int skip, int show); int timeline_add(snac *snac, char *id, char *o_msg); void timeline_admire(snac *snac, char *id, char *admirer, int like); xs_list *timeline_top_level(snac *snac, xs_list *list); - -d_char *local_list(snac *snac, int max); +xs_list *local_list(snac *snac, int max); +xs_list *timeline_instance_list(int skip, int show); int following_add(snac *snac, const char *actor, const xs_dict *msg); int following_del(snac *snac, const char *actor); -- cgit v1.2.3 From cfa0df3ac5a8b62539a3d1830414ec3d81d24f5d Mon Sep 17 00:00:00 2001 From: default Date: Sun, 30 Apr 2023 07:00:49 +0200 Subject: The instance timeline now works. --- mastoapi.c | 29 +++++++++++------------------ snac.h | 4 ++-- 2 files changed, 13 insertions(+), 20 deletions(-) (limited to 'snac.h') diff --git a/mastoapi.c b/mastoapi.c index 92acd41..5c4e27f 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1036,7 +1036,12 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(cmd, "/v1/timelines/public") == 0) { - /* the public timeline (public timelines for all users) */ + /* the instance public timeline (public timelines for all users) */ + + /* NOTE: this api call needs no authorization; but, + I need a logged-in user in mastoapi_status() for + is_msg_public() and the liked/boosted flags, + so it will silently fail for pure public access */ const char *limit_s = xs_dict_get(args, "limit"); int limit = 0; @@ -1053,7 +1058,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, xs_list *p = timeline; xs_str *md5; - while (xs_list_iter(&p, &md5) && cnt < limit) { + while (logged_in && xs_list_iter(&p, &md5) && cnt < limit) { xs *msg = NULL; /* get the entry */ @@ -1064,23 +1069,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (strcmp(xs_dict_get(msg, "type"), "Note") != 0) continue; - /* get the uid */ - xs *l = xs_split(xs_dict_get(msg, "attributedTo"), "/"); - const char *uid = xs_list_get(l, -1); - - if (!xs_is_null(uid)) { - snac user; - - if (user_open(&user, uid)) { - /* convert the Note into a Mastodon status */ - xs *st = mastoapi_status(&user, msg); - - if (st != NULL) - out = xs_list_append(out, st); - - user_free(&user); - } + /* convert the Note into a Mastodon status */ + xs *st = mastoapi_status(&snac1, msg); + if (st != NULL) { + out = xs_list_append(out, st); cnt++; } } diff --git a/snac.h b/snac.h index 5478933..10e8c4c 100644 --- a/snac.h +++ b/snac.h @@ -127,8 +127,8 @@ int is_muted(snac *snac, const char *actor); void hide(snac *snac, const char *id); int is_hidden(snac *snac, const char *id); -int actor_add(snac *snac, const char *actor, d_char *msg); -int actor_get(snac *snac, const char *actor, d_char **data); +int actor_add(snac *snac, const char *actor, xs_dict *msg); +int actor_get(snac *snac, const char *actor, xs_dict **data); int static_get(snac *snac, const char *id, d_char **data, int *size); void static_put(snac *snac, const char *id, const char *data, int size); -- cgit v1.2.3 From 4595a3685992a8f31b86cca0ecf10e286dec52eb Mon Sep 17 00:00:00 2001 From: default Date: Mon, 1 May 2023 17:20:49 +0200 Subject: Partial support for mastoapi unfavourite / unreblog. --- data.c | 2 +- mastoapi.c | 9 +++++++-- snac.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'snac.h') diff --git a/data.c b/data.c index e038f81..67f5751 100644 --- a/data.c +++ b/data.c @@ -827,7 +827,7 @@ int object_unadmire(const char *id, const char *actor, int like) status = index_del(fn, actor); - srv_debug(1, + srv_debug(0, xs_fmt("object_unadmire (%s) %s %s %d", like ? "Like" : "Announce", actor, fn, status)); return status; diff --git a/mastoapi.c b/mastoapi.c index 3d0a939..72d9579 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1670,7 +1670,11 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, } else if (strcmp(op, "unfavourite") == 0) { - /* snac does not support Undo+Like */ + /* partial support: as the original Like message + is not stored anywhere here, it's not possible + to send an Undo + Like; the only thing done here + is to delete the actor from the list of likes */ + object_unadmire(id, snac.actor, 1); } else if (strcmp(op, "reblog") == 0) { @@ -1685,7 +1689,8 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, } else if (strcmp(op, "unreblog") == 0) { - /* snac does not support Undo+Announce */ + /* partial support: see comment in 'unfavourite' */ + object_unadmire(id, snac.actor, 0); } else if (strcmp(op, "bookmark") == 0) { diff --git a/snac.h b/snac.h index 10e8c4c..a162618 100644 --- a/snac.h +++ b/snac.h @@ -83,6 +83,7 @@ int object_del_if_unref(const char *id); double object_ctime_by_md5(const char *md5); double object_ctime(const char *id); int object_admire(const char *id, const char *actor, int like); +int object_unadmire(const char *id, const char *actor, int like); int object_likes_len(const char *id); int object_announces_len(const char *id); -- cgit v1.2.3 From 511f5062b7df26c47409c88649f24d68bbd43ccb Mon Sep 17 00:00:00 2001 From: default Date: Thu, 4 May 2023 09:19:26 +0200 Subject: Deleted real unused parameters. --- activitypub.c | 4 ++-- data.c | 2 +- html.c | 15 +++++++-------- snac.h | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) (limited to 'snac.h') diff --git a/activitypub.c b/activitypub.c index b20ae0f..13b1ce2 100644 --- a/activitypub.c +++ b/activitypub.c @@ -109,7 +109,7 @@ int actor_request(snac *snac, const char *actor, xs_dict **data) if (valid_status(status2)) { /* renew data */ - status = actor_add(snac, actor, payload); + status = actor_add(actor, payload); if (data != NULL) { *data = payload; @@ -1121,7 +1121,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) else if (strcmp(type, "Update") == 0) { if (strcmp(utype, "Person") == 0) { - actor_add(snac, actor, xs_dict_get(msg, "object")); + actor_add(actor, xs_dict_get(msg, "object")); snac_log(snac, xs_fmt("updated actor %s", actor)); } diff --git a/data.c b/data.c index edeb676..f03fd71 100644 --- a/data.c +++ b/data.c @@ -1349,7 +1349,7 @@ int is_hidden(snac *snac, const char *id) } -int actor_add(snac *snac, const char *actor, xs_dict *msg) +int actor_add(const char *actor, xs_dict *msg) /* adds an actor */ { return object_add_ow(actor, msg); diff --git a/html.c b/html.c index 9d6fbc6..2aa6514 100644 --- a/html.c +++ b/html.c @@ -79,7 +79,7 @@ xs_str *actor_name(xs_dict *actor) } -d_char *html_actor_icon(snac *snac, d_char *os, char *actor, +xs_str *html_actor_icon(xs_str *os, char *actor, const char *date, const char *udate, const char *url, int priv) { xs *s = xs_str_new(NULL); @@ -168,7 +168,7 @@ d_char *html_msg_icon(snac *snac, d_char *os, char *msg) date = xs_dict_get(msg, "published"); udate = xs_dict_get(msg, "updated"); - os = html_actor_icon(snac, os, actor, date, udate, url, priv); + os = html_actor_icon(os, actor, date, udate, url, priv); } return os; @@ -983,7 +983,7 @@ d_char *html_entry(snac *snac, d_char *os, char *msg, int local, } -d_char *html_user_footer(snac *snac, d_char *s) +xs_str *html_user_footer(xs_str *s) { xs *s1 = xs_fmt( "
\n" @@ -1064,7 +1064,7 @@ d_char *html_timeline(snac *snac, char *list, int local, int skip, int show, int s = xs_str_cat(s, s1); } - s = html_user_footer(snac, s); + s = html_user_footer(s); s = xs_str_cat(s, "\n\n"); @@ -1088,8 +1088,7 @@ d_char *html_people_list(snac *snac, d_char *os, d_char *list, const char *heade if (valid_status(actor_get(snac, actor_id, &actor))) { s = xs_str_cat(s, "
\n"); - s = html_actor_icon(snac, s, actor, xs_dict_get(actor, "published"), NULL, NULL, 0); - + s = html_actor_icon(s, actor, xs_dict_get(actor, "published"), NULL, NULL, 0); /* content (user bio) */ char *c = xs_dict_get(actor, "summary"); @@ -1182,7 +1181,7 @@ d_char *html_people(snac *snac) s = html_people_list(snac, s, wers, L("People that follows you"), "e"); - s = html_user_footer(snac, s); + s = html_user_footer(s); s = xs_str_cat(s, "\n\n"); @@ -1277,7 +1276,7 @@ xs_str *html_notifications(snac *snac) s = xs_str_cat(s, s1); } - s = html_user_footer(snac, s); + s = html_user_footer(s); s = xs_str_cat(s, "\n\n"); diff --git a/snac.h b/snac.h index a162618..54c8e51 100644 --- a/snac.h +++ b/snac.h @@ -128,7 +128,7 @@ int is_muted(snac *snac, const char *actor); void hide(snac *snac, const char *id); int is_hidden(snac *snac, const char *id); -int actor_add(snac *snac, const char *actor, xs_dict *msg); +int actor_add(const char *actor, xs_dict *msg); int actor_get(snac *snac, const char *actor, xs_dict **data); int static_get(snac *snac, const char *id, d_char **data, int *size); -- cgit v1.2.3 From 753eadfd1775545c5bfb4110ad2ba7cb61df9588 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 4 May 2023 09:25:09 +0200 Subject: Added some const here and there. --- activitypub.c | 6 +++--- data.c | 2 +- html.c | 6 ++++-- httpd.c | 2 +- snac.h | 14 ++++++++------ 5 files changed, 17 insertions(+), 13 deletions(-) (limited to 'snac.h') diff --git a/activitypub.c b/activitypub.c index 13b1ce2..86d33df 100644 --- a/activitypub.c +++ b/activitypub.c @@ -1426,7 +1426,7 @@ int process_queue(void) /** HTTP handlers */ -int activitypub_get_handler(d_char *req, char *q_path, +int activitypub_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype) { int status = 200; @@ -1519,8 +1519,8 @@ int activitypub_get_handler(d_char *req, char *q_path, } -int activitypub_post_handler(d_char *req, char *q_path, - d_char *payload, int p_size, +int activitypub_post_handler(const xs_dict *req, const char *q_path, + char *payload, int p_size, char **body, int *b_size, char **ctype) /* processes an input message */ { diff --git a/data.c b/data.c index f03fd71..72b63f8 100644 --- a/data.c +++ b/data.c @@ -1814,7 +1814,7 @@ static xs_dict *_new_qmsg(const char *type, const xs_val *msg, int retries) } -void enqueue_input(snac *snac, xs_dict *msg, xs_dict *req, int retries) +void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries) /* enqueues an input message */ { xs *qmsg = _new_qmsg("input", msg, retries); diff --git a/html.c b/html.c index 2aa6514..3ba7930 100644 --- a/html.c +++ b/html.c @@ -1289,7 +1289,8 @@ xs_str *html_notifications(snac *snac) } -int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char **ctype) +int html_get_handler(const xs_dict *req, const char *q_path, + char **body, int *b_size, char **ctype) { char *accept = xs_dict_get(req, "accept"); int status = 404; @@ -1546,7 +1547,8 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char * } -int html_post_handler(d_char *req, char *q_path, d_char *payload, int p_size, +int html_post_handler(const xs_dict *req, const char *q_path, + char *payload, int p_size, char **body, int *b_size, char **ctype) { int status = 0; diff --git a/httpd.c b/httpd.c index 70083a1..5520457 100644 --- a/httpd.c +++ b/httpd.c @@ -43,7 +43,7 @@ d_char *nodeinfo_2_0(void) } -int server_get_handler(d_char *req, char *q_path, +int server_get_handler(xs_dict *req, char *q_path, char **body, int *b_size, char **ctype) /* basic server services */ { diff --git a/snac.h b/snac.h index 54c8e51..5279453 100644 --- a/snac.h +++ b/snac.h @@ -155,7 +155,7 @@ void inbox_add(const char *inbox); void inbox_add_by_actor(const xs_dict *actor); xs_list *inbox_list(void); -void enqueue_input(snac *snac, xs_dict *msg, xs_dict *req, int retries); +void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries); void enqueue_output_raw(const char *keyid, const char *seckey, xs_dict *msg, xs_str *inbox, int retries); void enqueue_output(snac *snac, xs_dict *msg, xs_str *inbox, int retries); @@ -187,7 +187,7 @@ int check_signature(snac *snac, xs_dict *req, xs_str **err); void httpd(void); int webfinger_request(const char *qs, char **actor, char **user); -int webfinger_get_handler(d_char *req, char *q_path, +int webfinger_get_handler(xs_dict *req, char *q_path, char **body, int *b_size, char **ctype); const char *default_avatar_base64(void); @@ -220,17 +220,19 @@ int process_user_queue(snac *snac); void process_queue_item(xs_dict *q_item); int process_queue(void); -int activitypub_get_handler(d_char *req, char *q_path, +int activitypub_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype); -int activitypub_post_handler(d_char *req, char *q_path, +int activitypub_post_handler(const xs_dict *req, const char *q_path, char *payload, int p_size, char **body, int *b_size, char **ctype); d_char *not_really_markdown(const char *content); d_char *sanitize(const char *str); -int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char **ctype); -int html_post_handler(d_char *req, char *q_path, d_char *payload, int p_size, +int html_get_handler(const xs_dict *req, const char *q_path, + char **body, int *b_size, char **ctype); +int html_post_handler(const xs_dict *req, const char *q_path, + char *payload, int p_size, char **body, int *b_size, char **ctype); int snac_init(const char *_basedir); -- cgit v1.2.3 From d3a36218a6ebfc951ff38c410ac1c29ec15c3c7f Mon Sep 17 00:00:00 2001 From: default Date: Fri, 5 May 2023 09:54:41 +0200 Subject: Implemented 'Ping' and 'Pong' activities. According to https://humungus.tedunangst.com/r/honk/v/tip/f/docs/ping.txt --- activitypub.c | 41 ++++++++++++++++++++++++++++++++++++++--- main.c | 14 ++++++++++++++ snac.h | 2 ++ 3 files changed, 54 insertions(+), 3 deletions(-) (limited to 'snac.h') diff --git a/activitypub.c b/activitypub.c index 0d5439d..6127dab 100644 --- a/activitypub.c +++ b/activitypub.c @@ -437,7 +437,8 @@ void process_tags(snac *snac, const char *content, d_char **n_content, d_char ** /** messages **/ -d_char *msg_base(snac *snac, char *type, char *id, char *actor, char *date, char *object) +xs_dict *msg_base(snac *snac, const char *type, const char *id, + const char *actor, const char *date, const char *object) /* creates a base ActivityPub message */ { xs *did = NULL; @@ -467,7 +468,7 @@ d_char *msg_base(snac *snac, char *type, char *id, char *actor, char *date, char } } - d_char *msg = xs_dict_new(); + xs_dict *msg = xs_dict_new(); msg = xs_dict_append(msg, "@context", "https:/" "/www.w3.org/ns/activitystreams"); msg = xs_dict_append(msg, "type", type); @@ -845,6 +846,28 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, } +xs_dict *msg_ping(snac *user, const char *rcpt) +/* creates a Ping message (https://humungus.tedunangst.com/r/honk/v/tip/f/docs/ping.txt) */ +{ + xs_dict *msg = msg_base(user, "Ping", "@dummy", user->actor, NULL, NULL); + + msg = xs_dict_append(msg, "to", rcpt); + + return msg; +} + + +xs_dict *msg_pong(snac *user, const char *rcpt, const char *object) +/* creates a Pong message (https://humungus.tedunangst.com/r/honk/v/tip/f/docs/ping.txt) */ +{ + xs_dict *msg = msg_base(user, "Pong", "@dummy", user->actor, NULL, object); + + msg = xs_dict_append(msg, "to", rcpt); + + return msg; +} + + void notify(snac *snac, xs_str *type, xs_str *utype, xs_str *actor, xs_dict *msg) /* notifies the user of relevant events */ { @@ -1147,7 +1170,19 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) snac_debug(snac, 1, xs_fmt("ignored 'Delete' for unknown object %s", object)); } else - snac_debug(snac, 1, xs_fmt("process_message type '%s' ignored", type)); + if (strcmp(type, "Pong") == 0) { + snac_log(snac, xs_fmt("'Pong' received from %s", actor)); + } + else + if (strcmp(type, "Ping") == 0) { + snac_log(snac, xs_fmt("'Ping' requested from %s", actor)); + + xs *rsp = msg_pong(snac, actor, xs_dict_get(msg, "id")); + + enqueue_output_by_actor(snac, rsp, actor, 0); + } + else + snac_debug(snac, 1, xs_fmt("process_input_message type '%s' ignored", type)); if (do_notify) { notify(snac, type, utype, actor, msg); diff --git a/main.c b/main.c index 6a0bb74..b8fc97b 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,7 @@ int usage(void) printf("actor {basedir} {uid} {url} Requests an actor\n"); printf("note {basedir} {uid} {'text'} Sends a note to followers\n"); printf("resetpwd {basedir} {uid} Resets the password of a user\n"); + printf("ping {basedir} {uid} {actor} Pings an actor\n"); return 1; } @@ -228,6 +229,19 @@ int main(int argc, char *argv[]) return 0; } + if (strcmp(cmd, "ping") == 0) { + xs *msg = msg_ping(&snac, url); + + enqueue_output_by_actor(&snac, msg, url, 0); + + if (dbglevel) { + xs *j = xs_json_dumps_pp(msg, 4); + printf("%s\n", msg); + } + + return 0; + } + if (strcmp(cmd, "request") == 0) { int status; xs *data = NULL; diff --git a/snac.h b/snac.h index 5279453..7d4b8f4 100644 --- a/snac.h +++ b/snac.h @@ -203,6 +203,8 @@ d_char *msg_undo(snac *snac, char *object); d_char *msg_delete(snac *snac, char *id); d_char *msg_actor(snac *snac); xs_dict *msg_update(snac *snac, xs_dict *object); +xs_dict *msg_ping(snac *user, const char *rcpt); +xs_dict *msg_pong(snac *user, const char *rcpt, const char *object); int activitypub_request(snac *snac, const char *url, xs_dict **data); int actor_request(snac *snac, const char *actor, xs_dict **data); -- cgit v1.2.3 From 6a1cc55676eaf18ecadb42b86474aaef73cf9805 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 7 May 2023 08:54:54 +0200 Subject: Version 2.30 RELEASED. --- snac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'snac.h') diff --git a/snac.h b/snac.h index 7d4b8f4..782ae51 100644 --- a/snac.h +++ b/snac.h @@ -1,7 +1,7 @@ /* snac - A simple, minimalistic ActivityPub instance */ /* copyright (c) 2022 - 2023 grunfink / MIT license */ -#define VERSION "2.30-dev" +#define VERSION "2.30" #define USER_AGENT "snac/" VERSION -- cgit v1.2.3