commit c3b5057

default  ·  2024-02-15 18:24:10 +0000 UTC
parent b75e44a
New function verify_links().
3 files changed,  +113, -0
M main.c
M snac.h
M main.c
+5, -0
 1@@ -247,6 +247,11 @@ int main(int argc, char *argv[])
 2         return 0;
 3     }
 4 
 5+    if (strcmp(cmd, "verify_links") == 0) { /** **/
 6+        verify_links(&snac);
 7+        return 0;
 8+    }
 9+
10     if (strcmp(cmd, "timeline") == 0) { /** **/
11 #if 0
12         xs *list = local_list(&snac, XS_ALL);
M snac.h
+2, -0
1@@ -330,3 +330,5 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
2                           const char *payload, int p_size,
3                           char **body, int *b_size, char **ctype);
4 void mastoapi_purge(void);
5+
6+void verify_links(snac *user);
+106, -0
  1@@ -8,6 +8,8 @@
  2 #include "xs_openssl.h"
  3 #include "xs_random.h"
  4 #include "xs_glob.h"
  5+#include "xs_curl.h"
  6+#include "xs_regex.h"
  7 
  8 #include "snac.h"
  9 
 10@@ -407,3 +409,107 @@ int deluser(snac *user)
 11 
 12     return ret;
 13 }
 14+
 15+
 16+void verify_links(snac *user)
 17+/* verifies a user's links */
 18+{
 19+    xs_dict *p = xs_dict_get(user->config, "metadata");
 20+    char *k, *v;
 21+    int changed = 0;
 22+
 23+    while (p && xs_dict_iter(&p, &k, &v)) {
 24+        /* not an https link? skip */
 25+        if (!xs_startswith(v, "https:/" "/"))
 26+            continue;
 27+
 28+        int status;
 29+        xs *req = NULL;
 30+        xs *payload = NULL;
 31+        int p_size = 0;
 32+
 33+        req = xs_http_request("GET", v, NULL, NULL, 0, &status,
 34+            &payload, &p_size, 0);
 35+
 36+        if (!valid_status(status))
 37+            continue;
 38+
 39+        /* extract the links */
 40+        xs *ls = xs_regex_select(payload, "< *(a|link) +[^>]+>");
 41+
 42+        xs_list *lp = ls;
 43+        char *ll;
 44+
 45+        while (xs_list_iter(&lp, &ll)) {
 46+            /* extract href and rel */
 47+            xs *r = xs_regex_select(ll, "(href|rel) *= *(\"[^\"]*\"|'[^']*')");
 48+
 49+            /* must have both attributes */
 50+            if (xs_list_len(r) != 2)
 51+                continue;
 52+
 53+            xs *href = NULL;
 54+            int is_rel_me = 0;
 55+            xs_list *pr = r;
 56+            char *ar;
 57+
 58+            while (xs_list_iter(&pr, &ar)) {
 59+                xs *nq = xs_dup(ar);
 60+
 61+                nq = xs_replace_i(nq, "\"", "");
 62+                nq = xs_replace_i(nq, "'", "");
 63+
 64+                xs *r2 = xs_split_n(nq, "=", 1);
 65+                if (xs_list_len(r2) != 2)
 66+                    continue;
 67+
 68+                xs *ak = xs_strip_i(xs_dup(xs_list_get(r2, 0)));
 69+                xs *av = xs_strip_i(xs_dup(xs_list_get(r2, 1)));
 70+
 71+                if (strcmp(ak, "href") == 0)
 72+                    href = xs_dup(av);
 73+                else
 74+                if (strcmp(ak, "rel") == 0) {
 75+                    /* split the value by spaces */
 76+                    xs *vbs = xs_split(av, " ");
 77+
 78+                    /* is any of it "me"? */
 79+                    if (xs_list_in(vbs, "me") != -1)
 80+                        is_rel_me = 1;
 81+                }
 82+            }
 83+
 84+            /* after all this acrobatics, do we have an href and a rel="me"? */
 85+            if (href != NULL && is_rel_me) {
 86+                /* is it the same as the actor? */
 87+                if (strcmp(href, user->actor) == 0) {
 88+                    /* got it! */
 89+                    xs *verified_at = xs_str_utctime(0, ISO_DATE_SPEC);
 90+
 91+                    user->links = xs_dict_set(user->links, v, verified_at);
 92+
 93+                    changed++;
 94+
 95+                    snac_log(user, xs_fmt("verify_links: %s at %s", v, verified_at));
 96+                }
 97+            }
 98+        }
 99+    }
100+
101+    if (changed) {
102+        FILE *f;
103+
104+        /* update the links.json file */
105+        xs *fn = xs_fmt("%s/links.json", user->basedir);
106+        xs *bfn = xs_fmt("%s.bak", fn);
107+
108+        rename(fn, bfn);
109+
110+        if ((f = fopen(fn, "w")) != NULL) {
111+            xs_json_dump(user->links, 4, f);
112+            fclose(f);
113+        }
114+        else
115+            rename(bfn, fn);
116+    }
117+}