summaryrefslogtreecommitdiff
path: root/mastoapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'mastoapi.c')
-rw-r--r--mastoapi.c109
1 files changed, 57 insertions, 52 deletions
diff --git a/mastoapi.c b/mastoapi.c
index 2bf5fdc..852713e 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -175,7 +175,7 @@ int oauth_get_handler(const xs_dict *req, const char *q_path,
175 return 0; 175 return 0;
176 176
177 int status = 404; 177 int status = 404;
178 xs_dict *msg = xs_dict_get(req, "q_vars"); 178 const xs_dict *msg = xs_dict_get(req, "q_vars");
179 xs *cmd = xs_replace_n(q_path, "/oauth", "", 1); 179 xs *cmd = xs_replace_n(q_path, "/oauth", "", 1);
180 180
181 srv_debug(1, xs_fmt("oauth_get_handler %s", q_path)); 181 srv_debug(1, xs_fmt("oauth_get_handler %s", q_path));
@@ -239,7 +239,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
239 239
240 int status = 404; 240 int status = 404;
241 241
242 char *i_ctype = xs_dict_get(req, "content-type"); 242 const char *i_ctype = xs_dict_get(req, "content-type");
243 xs *args = NULL; 243 xs *args = NULL;
244 244
245 if (i_ctype && xs_startswith(i_ctype, "application/json")) { 245 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
@@ -568,10 +568,10 @@ xs_dict *mastoapi_account(const xs_dict *actor)
568 acct = xs_dict_append(acct, "uri", id); 568 acct = xs_dict_append(acct, "uri", id);
569 569
570 xs *avatar = NULL; 570 xs *avatar = NULL;
571 xs_dict *av = xs_dict_get(actor, "icon"); 571 const xs_dict *av = xs_dict_get(actor, "icon");
572 572
573 if (xs_type(av) == XSTYPE_DICT) { 573 if (xs_type(av) == XSTYPE_DICT) {
574 char *url = xs_dict_get(av, "url"); 574 const char *url = xs_dict_get(av, "url");
575 575
576 if (url != NULL) 576 if (url != NULL)
577 avatar = xs_dup(url); 577 avatar = xs_dup(url);
@@ -584,7 +584,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
584 acct = xs_dict_append(acct, "avatar_static", avatar); 584 acct = xs_dict_append(acct, "avatar_static", avatar);
585 585
586 xs *header = NULL; 586 xs *header = NULL;
587 xs_dict *hd = xs_dict_get(actor, "image"); 587 const xs_dict *hd = xs_dict_get(actor, "image");
588 588
589 if (xs_type(hd) == XSTYPE_DICT) 589 if (xs_type(hd) == XSTYPE_DICT)
590 header = xs_dup(xs_dict_get(hd, "url")); 590 header = xs_dup(xs_dict_get(hd, "url"));
@@ -596,12 +596,13 @@ xs_dict *mastoapi_account(const xs_dict *actor)
596 acct = xs_dict_append(acct, "header_static", header); 596 acct = xs_dict_append(acct, "header_static", header);
597 597
598 /* emojis */ 598 /* emojis */
599 xs_list *p; 599 const xs_list *p;
600 if (!xs_is_null(p = xs_dict_get(actor, "tag"))) { 600 if (!xs_is_null(p = xs_dict_get(actor, "tag"))) {
601 xs *eml = xs_list_new(); 601 xs *eml = xs_list_new();
602 xs_dict *v; 602 xs_dict *v;
603 int c = 0;
603 604
604 while (xs_list_iter(&p, &v)) { 605 while (xs_list_next(p, &v, &c)) {
605 const char *type = xs_dict_get(v, "type"); 606 const char *type = xs_dict_get(v, "type");
606 607
607 if (!xs_is_null(type) && strcmp(type, "Emoji") == 0) { 608 if (!xs_is_null(type) && strcmp(type, "Emoji") == 0) {
@@ -640,7 +641,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
640 641
641 /* dict of validated links */ 642 /* dict of validated links */
642 xs_dict *val_links = NULL; 643 xs_dict *val_links = NULL;
643 xs_dict *metadata = xs_stock(XSTYPE_DICT); 644 const xs_dict *metadata = xs_stock(XSTYPE_DICT);
644 snac user = {0}; 645 snac user = {0};
645 646
646 if (xs_startswith(id, srv_baseurl)) { 647 if (xs_startswith(id, srv_baseurl)) {
@@ -654,19 +655,20 @@ xs_dict *mastoapi_account(const xs_dict *actor)
654 if (xs_is_null(val_links)) 655 if (xs_is_null(val_links))
655 val_links = xs_stock(XSTYPE_DICT); 656 val_links = xs_stock(XSTYPE_DICT);
656 657
657 while (xs_list_iter(&p, &v)) { 658 int c = 0;
658 char *type = xs_dict_get(v, "type"); 659 while (xs_list_next(p, &v, &c)) {
659 char *name = xs_dict_get(v, "name"); 660 const char *type = xs_dict_get(v, "type");
660 char *value = xs_dict_get(v, "value"); 661 const char *name = xs_dict_get(v, "name");
662 const char *value = xs_dict_get(v, "value");
661 663
662 if (!xs_is_null(type) && !xs_is_null(name) && 664 if (!xs_is_null(type) && !xs_is_null(name) &&
663 !xs_is_null(value) && strcmp(type, "PropertyValue") == 0) { 665 !xs_is_null(value) && strcmp(type, "PropertyValue") == 0) {
664 xs *val_date = NULL; 666 xs *val_date = NULL;
665 667
666 char *url = xs_dict_get(metadata, name); 668 const char *url = xs_dict_get(metadata, name);
667 669
668 if (!xs_is_null(url) && xs_startswith(url, "https:/" "/")) { 670 if (!xs_is_null(url) && xs_startswith(url, "https:/" "/")) {
669 xs_number *verified_time = xs_dict_get(val_links, url); 671 const xs_number *verified_time = xs_dict_get(val_links, url);
670 if (xs_type(verified_time) == XSTYPE_NUMBER) { 672 if (xs_type(verified_time) == XSTYPE_NUMBER) {
671 time_t t = xs_number_get(verified_time); 673 time_t t = xs_number_get(verified_time);
672 674
@@ -695,7 +697,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
695} 697}
696 698
697 699
698xs_str *mastoapi_date(char *date) 700xs_str *mastoapi_date(const char *date)
699/* converts an ISO 8601 date to whatever format Mastodon uses */ 701/* converts an ISO 8601 date to whatever format Mastodon uses */
700{ 702{
701 xs_str *s = xs_crop_i(xs_dup(date), 0, 19); 703 xs_str *s = xs_crop_i(xs_dup(date), 0, 19);
@@ -710,13 +712,13 @@ xs_dict *mastoapi_poll(snac *snac, const xs_dict *msg)
710{ 712{
711 xs_dict *poll = xs_dict_new(); 713 xs_dict *poll = xs_dict_new();
712 xs *mid = mastoapi_id(msg); 714 xs *mid = mastoapi_id(msg);
713 xs_list *opts = NULL; 715 const xs_list *opts = NULL;
714 xs_val *v; 716 xs_val *v;
715 int num_votes = 0; 717 int num_votes = 0;
716 xs *options = xs_list_new(); 718 xs *options = xs_list_new();
717 719
718 poll = xs_dict_append(poll, "id", mid); 720 poll = xs_dict_append(poll, "id", mid);
719 char *date = xs_dict_get(msg, "endTime"); 721 const char *date = xs_dict_get(msg, "endTime");
720 if (date == NULL) 722 if (date == NULL)
721 date = xs_dict_get(msg, "closed"); 723 date = xs_dict_get(msg, "closed");
722 if (date == NULL) 724 if (date == NULL)
@@ -741,7 +743,8 @@ xs_dict *mastoapi_poll(snac *snac, const xs_dict *msg)
741 poll = xs_dict_append(poll, "multiple", xs_stock(XSTYPE_TRUE)); 743 poll = xs_dict_append(poll, "multiple", xs_stock(XSTYPE_TRUE));
742 } 744 }
743 745
744 while (xs_list_iter(&opts, &v)) { 746 int c = 0;
747 while (xs_list_next(opts, &v, &c)) {
745 const char *title = xs_dict_get(v, "name"); 748 const char *title = xs_dict_get(v, "name");
746 const char *replies = xs_dict_get(v, "replies"); 749 const char *replies = xs_dict_get(v, "replies");
747 750
@@ -794,7 +797,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
794 797
795 xs *idx = NULL; 798 xs *idx = NULL;
796 xs *ixc = NULL; 799 xs *ixc = NULL;
797 char *tmp; 800 const char *tmp;
798 xs *mid = mastoapi_id(msg); 801 xs *mid = mastoapi_id(msg);
799 802
800 xs_dict *st = xs_dict_new(); 803 xs_dict *st = xs_dict_new();
@@ -851,9 +854,9 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
851 xs *matt = xs_list_new(); 854 xs *matt = xs_list_new();
852 855
853 while (xs_list_iter(&p, &v)) { 856 while (xs_list_iter(&p, &v)) {
854 char *type = xs_dict_get(v, "type"); 857 const char *type = xs_dict_get(v, "type");
855 char *href = xs_dict_get(v, "href"); 858 const char *href = xs_dict_get(v, "href");
856 char *name = xs_dict_get(v, "name"); 859 const char *name = xs_dict_get(v, "name");
857 860
858 if (xs_match(type, "image/*|video/*|Image|Video")) { /* */ 861 if (xs_match(type, "image/*|video/*|Image|Video")) { /* */
859 xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt)); 862 xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt));
@@ -879,7 +882,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
879 xs *ml = xs_list_new(); 882 xs *ml = xs_list_new();
880 xs *htl = xs_list_new(); 883 xs *htl = xs_list_new();
881 xs *eml = xs_list_new(); 884 xs *eml = xs_list_new();
882 xs_list *tag = xs_dict_get(msg, "tag"); 885 const xs_list *tag = xs_dict_get(msg, "tag");
883 int n = 0; 886 int n = 0;
884 887
885 xs *tag_list = NULL; 888 xs *tag_list = NULL;
@@ -897,7 +900,8 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
897 tag = tag_list; 900 tag = tag_list;
898 xs_dict *v; 901 xs_dict *v;
899 902
900 while (xs_list_iter(&tag, &v)) { 903 int c = 0;
904 while (xs_list_next(tag, &v, &c)) {
901 const char *type = xs_dict_get(v, "type"); 905 const char *type = xs_dict_get(v, "type");
902 906
903 if (xs_is_null(type)) 907 if (xs_is_null(type))
@@ -1006,7 +1010,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
1006 xs *irt_mid = mastoapi_id(irto); 1010 xs *irt_mid = mastoapi_id(irto);
1007 st = xs_dict_set(st, "in_reply_to_id", irt_mid); 1011 st = xs_dict_set(st, "in_reply_to_id", irt_mid);
1008 1012
1009 char *at = NULL; 1013 const char *at = NULL;
1010 if (!xs_is_null(at = get_atto(irto))) { 1014 if (!xs_is_null(at = get_atto(irto))) {
1011 xs *at_md5 = xs_md5_hex(at, strlen(at)); 1015 xs *at_md5 = xs_md5_hex(at, strlen(at));
1012 st = xs_dict_set(st, "in_reply_to_account_id", at_md5); 1016 st = xs_dict_set(st, "in_reply_to_account_id", at_md5);
@@ -1118,7 +1122,7 @@ int process_auth_token(snac *snac, const xs_dict *req)
1118/* processes an authorization token, if there is one */ 1122/* processes an authorization token, if there is one */
1119{ 1123{
1120 int logged_in = 0; 1124 int logged_in = 0;
1121 char *v; 1125 const char *v;
1122 1126
1123 /* if there is an authorization field, try to validate it */ 1127 /* if there is an authorization field, try to validate it */
1124 if (!xs_is_null(v = xs_dict_get(req, "authorization")) && xs_startswith(v, "Bearer ")) { 1128 if (!xs_is_null(v = xs_dict_get(req, "authorization")) && xs_startswith(v, "Bearer ")) {
@@ -1156,7 +1160,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1156 return 0; 1160 return 0;
1157 1161
1158 int status = 404; 1162 int status = 404;
1159 xs_dict *args = xs_dict_get(req, "q_vars"); 1163 const xs_dict *args = xs_dict_get(req, "q_vars");
1160 xs *cmd = xs_replace_n(q_path, "/api", "", 1); 1164 xs *cmd = xs_replace_n(q_path, "/api", "", 1);
1161 1165
1162 snac snac1 = {0}; 1166 snac snac1 = {0};
@@ -1182,7 +1186,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1182 acct = xs_dict_append(acct, "source", src); 1186 acct = xs_dict_append(acct, "source", src);
1183 1187
1184 xs *avatar = NULL; 1188 xs *avatar = NULL;
1185 char *av = xs_dict_get(snac1.config, "avatar"); 1189 const char *av = xs_dict_get(snac1.config, "avatar");
1186 1190
1187 if (xs_is_null(av) || *av == '\0') 1191 if (xs_is_null(av) || *av == '\0')
1188 avatar = xs_fmt("%s/susie.png", srv_baseurl); 1192 avatar = xs_fmt("%s/susie.png", srv_baseurl);
@@ -1193,7 +1197,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1193 acct = xs_dict_append(acct, "avatar_static", avatar); 1197 acct = xs_dict_append(acct, "avatar_static", avatar);
1194 1198
1195 xs *header = NULL; 1199 xs *header = NULL;
1196 char *hd = xs_dict_get(snac1.config, "header"); 1200 const char *hd = xs_dict_get(snac1.config, "header");
1197 1201
1198 if (!xs_is_null(hd)) 1202 if (!xs_is_null(hd))
1199 header = xs_dup(hd); 1203 header = xs_dup(hd);
@@ -1203,7 +1207,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1203 acct = xs_dict_append(acct, "header", header); 1207 acct = xs_dict_append(acct, "header", header);
1204 acct = xs_dict_append(acct, "header_static", header); 1208 acct = xs_dict_append(acct, "header_static", header);
1205 1209
1206 xs_dict *metadata = xs_dict_get(snac1.config, "metadata"); 1210 const xs_dict *metadata = xs_dict_get(snac1.config, "metadata");
1207 if (xs_type(metadata) == XSTYPE_DICT) { 1211 if (xs_type(metadata) == XSTYPE_DICT) {
1208 xs *fields = xs_list_new(); 1212 xs *fields = xs_list_new();
1209 xs_str *k; 1213 xs_str *k;
@@ -1217,7 +1221,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1217 while (xs_dict_next(metadata, &k, &v, &c)) { 1221 while (xs_dict_next(metadata, &k, &v, &c)) {
1218 xs *val_date = NULL; 1222 xs *val_date = NULL;
1219 1223
1220 xs_number *verified_time = xs_dict_get(val_links, v); 1224 const xs_number *verified_time = xs_dict_get(val_links, v);
1221 if (xs_type(verified_time) == XSTYPE_NUMBER) { 1225 if (xs_type(verified_time) == XSTYPE_NUMBER) {
1222 time_t t = xs_number_get(verified_time); 1226 time_t t = xs_number_get(verified_time);
1223 1227
@@ -1283,13 +1287,13 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1283 else 1287 else
1284 if (strcmp(cmd, "/v1/accounts/lookup") == 0) { /** **/ 1288 if (strcmp(cmd, "/v1/accounts/lookup") == 0) { /** **/
1285 /* lookup an account */ 1289 /* lookup an account */
1286 char *acct = xs_dict_get(args, "acct"); 1290 const char *acct = xs_dict_get(args, "acct");
1287 1291
1288 if (!xs_is_null(acct)) { 1292 if (!xs_is_null(acct)) {
1289 xs *s = xs_strip_chars_i(xs_dup(acct), "@"); 1293 xs *s = xs_strip_chars_i(xs_dup(acct), "@");
1290 xs *l = xs_split_n(s, "@", 1); 1294 xs *l = xs_split_n(s, "@", 1);
1291 char *uid = xs_list_get(l, 0); 1295 const char *uid = xs_list_get(l, 0);
1292 char *host = xs_list_get(l, 1); 1296 const char *host = xs_list_get(l, 1);
1293 1297
1294 if (uid && (!host || strcmp(host, xs_dict_get(srv_config, "host")) == 0)) { 1298 if (uid && (!host || strcmp(host, xs_dict_get(srv_config, "host")) == 0)) {
1295 snac user; 1299 snac user;
@@ -1624,7 +1628,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1624 1628
1625 /* get the tag */ 1629 /* get the tag */
1626 xs *l = xs_split(cmd, "/"); 1630 xs *l = xs_split(cmd, "/");
1627 char *tag = xs_list_get(l, -1); 1631 const char *tag = xs_list_get(l, -1);
1628 1632
1629 xs *timeline = tag_search(tag, 0, limit); 1633 xs *timeline = tag_search(tag, 0, limit);
1630 xs *out = xs_list_new(); 1634 xs *out = xs_list_new();
@@ -1664,7 +1668,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1664 /* get the list id */ 1668 /* get the list id */
1665 if (logged_in) { 1669 if (logged_in) {
1666 xs *l = xs_split(cmd, "/"); 1670 xs *l = xs_split(cmd, "/");
1667 char *list = xs_list_get(l, -1); 1671 const char *list = xs_list_get(l, -1);
1668 1672
1669 xs *timeline = list_timeline(&snac1, list, 0, 2048); 1673 xs *timeline = list_timeline(&snac1, list, 0, 2048);
1670 xs *out = xs_list_new(); 1674 xs *out = xs_list_new();
@@ -1744,7 +1748,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1744 xs *out = xs_list_new(); 1748 xs *out = xs_list_new();
1745 xs_list *p = l; 1749 xs_list *p = l;
1746 xs_dict *v; 1750 xs_dict *v;
1747 xs_list *excl = xs_dict_get(args, "exclude_types[]"); 1751 const xs_list *excl = xs_dict_get(args, "exclude_types[]");
1748 1752
1749 while (xs_list_iter(&p, &v)) { 1753 while (xs_list_iter(&p, &v)) {
1750 xs *noti = notify_get(&snac1, v); 1754 xs *noti = notify_get(&snac1, v);
@@ -1876,7 +1880,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1876 if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/ 1880 if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/
1877 if (logged_in) { 1881 if (logged_in) {
1878 xs *l = xs_split(cmd, "/"); 1882 xs *l = xs_split(cmd, "/");
1879 char *p = xs_list_get(l, -1); 1883 const char *p = xs_list_get(l, -1);
1880 1884
1881 if (p) { 1885 if (p) {
1882 if (strcmp(p, "accounts") == 0) { 1886 if (strcmp(p, "accounts") == 0) {
@@ -1910,7 +1914,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1910 xs_list *v; 1914 xs_list *v;
1911 1915
1912 while (xs_list_next(lol, &v, &c)) { 1916 while (xs_list_next(lol, &v, &c)) {
1913 char *id = xs_list_get(v, 0); 1917 const char *id = xs_list_get(v, 0);
1914 1918
1915 if (id && strcmp(id, p) == 0) { 1919 if (id && strcmp(id, p) == 0) {
1916 xs *d = xs_dict_new(); 1920 xs *d = xs_dict_new();
@@ -2314,7 +2318,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2314 2318
2315 int status = 404; 2319 int status = 404;
2316 xs *args = NULL; 2320 xs *args = NULL;
2317 char *i_ctype = xs_dict_get(req, "content-type"); 2321 const char *i_ctype = xs_dict_get(req, "content-type");
2318 2322
2319 if (i_ctype && xs_startswith(i_ctype, "application/json")) { 2323 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
2320 if (!xs_is_null(payload)) 2324 if (!xs_is_null(payload))
@@ -2487,7 +2491,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2487 mid = MID_TO_MD5(mid); 2491 mid = MID_TO_MD5(mid);
2488 2492
2489 if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) { 2493 if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) {
2490 char *id = xs_dict_get(msg, "id"); 2494 const char *id = xs_dict_get(msg, "id");
2491 2495
2492 if (op == NULL) { 2496 if (op == NULL) {
2493 /* no operation (?) */ 2497 /* no operation (?) */
@@ -2593,7 +2597,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2593 if (strcmp(cmd, "/v1/push/subscription") == 0) { /** **/ 2597 if (strcmp(cmd, "/v1/push/subscription") == 0) { /** **/
2594 /* I don't know what I'm doing */ 2598 /* I don't know what I'm doing */
2595 if (logged_in) { 2599 if (logged_in) {
2596 char *v; 2600 const char *v;
2597 2601
2598 xs *wpush = xs_dict_new(); 2602 xs *wpush = xs_dict_new();
2599 2603
@@ -2765,7 +2769,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2765 const char *id = xs_dict_get(msg, "id"); 2769 const char *id = xs_dict_get(msg, "id");
2766 const char *atto = get_atto(msg); 2770 const char *atto = get_atto(msg);
2767 2771
2768 xs_list *opts = xs_dict_get(msg, "oneOf"); 2772 const xs_list *opts = xs_dict_get(msg, "oneOf");
2769 if (opts == NULL) 2773 if (opts == NULL)
2770 opts = xs_dict_get(msg, "anyOf"); 2774 opts = xs_dict_get(msg, "anyOf");
2771 2775
@@ -2773,7 +2777,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2773 } 2777 }
2774 else 2778 else
2775 if (strcmp(op, "votes") == 0) { 2779 if (strcmp(op, "votes") == 0) {
2776 xs_list *choices = xs_dict_get(args, "choices[]"); 2780 const xs_list *choices = xs_dict_get(args, "choices[]");
2777 2781
2778 if (xs_is_null(choices)) 2782 if (xs_is_null(choices))
2779 choices = xs_dict_get(args, "choices"); 2783 choices = xs_dict_get(args, "choices");
@@ -2781,7 +2785,8 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2781 if (xs_type(choices) == XSTYPE_LIST) { 2785 if (xs_type(choices) == XSTYPE_LIST) {
2782 xs_str *v; 2786 xs_str *v;
2783 2787
2784 while (xs_list_iter(&choices, &v)) { 2788 int c = 0;
2789 while (xs_list_next(choices, &v, &c)) {
2785 int io = atoi(v); 2790 int io = atoi(v);
2786 const xs_dict *o = xs_list_get(opts, io); 2791 const xs_dict *o = xs_list_get(opts, io);
2787 2792
@@ -2843,12 +2848,12 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2843 if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/ 2848 if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/
2844 if (logged_in) { 2849 if (logged_in) {
2845 xs *l = xs_split(cmd, "/"); 2850 xs *l = xs_split(cmd, "/");
2846 char *op = xs_list_get(l, -1); 2851 const char *op = xs_list_get(l, -1);
2847 char *id = xs_list_get(l, -2); 2852 const char *id = xs_list_get(l, -2);
2848 2853
2849 if (op && id && xs_is_hex(id)) { 2854 if (op && id && xs_is_hex(id)) {
2850 if (strcmp(op, "accounts") == 0) { 2855 if (strcmp(op, "accounts") == 0) {
2851 xs_list *accts = xs_dict_get(args, "account_ids[]"); 2856 const xs_list *accts = xs_dict_get(args, "account_ids[]");
2852 int c = 0; 2857 int c = 0;
2853 char *v; 2858 char *v;
2854 2859
@@ -2888,7 +2893,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
2888 2893
2889 int status = 404; 2894 int status = 404;
2890 xs *args = NULL; 2895 xs *args = NULL;
2891 char *i_ctype = xs_dict_get(req, "content-type"); 2896 const char *i_ctype = xs_dict_get(req, "content-type");
2892 2897
2893 if (i_ctype && xs_startswith(i_ctype, "application/json")) { 2898 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
2894 if (!xs_is_null(payload)) 2899 if (!xs_is_null(payload))
@@ -2921,13 +2926,13 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
2921 if (xs_startswith(cmd, "/v1/lists/")) { 2926 if (xs_startswith(cmd, "/v1/lists/")) {
2922 if (logged_in) { 2927 if (logged_in) {
2923 xs *l = xs_split(cmd, "/"); 2928 xs *l = xs_split(cmd, "/");
2924 char *p = xs_list_get(l, -1); 2929 const char *p = xs_list_get(l, -1);
2925 2930
2926 if (p) { 2931 if (p) {
2927 if (strcmp(p, "accounts") == 0) { 2932 if (strcmp(p, "accounts") == 0) {
2928 /* delete account from list */ 2933 /* delete account from list */
2929 p = xs_list_get(l, -2); 2934 p = xs_list_get(l, -2);
2930 xs_list *accts = xs_dict_get(args, "account_ids[]"); 2935 const xs_list *accts = xs_dict_get(args, "account_ids[]");
2931 int c = 0; 2936 int c = 0;
2932 char *v; 2937 char *v;
2933 2938
@@ -2971,7 +2976,7 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
2971 2976
2972 int status = 404; 2977 int status = 404;
2973 xs *args = NULL; 2978 xs *args = NULL;
2974 char *i_ctype = xs_dict_get(req, "content-type"); 2979 const char *i_ctype = xs_dict_get(req, "content-type");
2975 2980
2976 if (i_ctype && xs_startswith(i_ctype, "application/json")) { 2981 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
2977 if (!xs_is_null(payload)) 2982 if (!xs_is_null(payload))