commit c541296

grunfink  ·  2025-09-07 06:03:38 +0000 UTC
parent fdcd7b9
New command-line option 'fsck'.
3 files changed,  +66, -0
M data.c
M main.c
M snac.h
M data.c
+58, -0
 1@@ -4362,3 +4362,61 @@ const char *lang_str(const char *str, const snac *user)
 2 
 3     return n_str;
 4 }
 5+
 6+
 7+/** integrity checks **/
 8+
 9+void data_fsck(void)
10+{
11+    xs *list = user_list();
12+    const char *uid;
13+
14+    xs_list_foreach(list, uid) {
15+        snac user;
16+
17+        if (!user_open(&user, uid))
18+            continue;
19+
20+        {
21+            /* iterate all private posts and check that non-public posts
22+               from this user are also linked into the public directory,
23+               to avoid the don't-fucking-delete-my-own-private-posts purge bug */
24+
25+            xs *priv_spec = xs_fmt("%s/private/""*.json", user.basedir);
26+            xs *posts = xs_glob(priv_spec, 0, 0);
27+            const char *priv_fn;
28+
29+            xs_list_foreach(posts, priv_fn) {
30+                xs *pub_fn = xs_replace(priv_fn, "/private/", "/public/");
31+
32+                /* already there? look no more */
33+                if (mtime(pub_fn))
34+                    continue;
35+
36+                /* read the post */
37+                FILE *f;
38+                if ((f = fopen(priv_fn, "r")) == NULL)
39+                    continue;
40+
41+                xs *post = xs_json_load(f);
42+                fclose(f);
43+
44+                if (!xs_is_dict(post))
45+                    continue;
46+
47+                const char *attr_to = get_atto(post);
48+
49+                if (!xs_is_string(attr_to) || strcmp(attr_to, user.actor) != 0) {
50+                    /* not from this user */
51+                    continue;
52+                }
53+
54+                /* link */
55+                snac_log(&user, xs_fmt("fsck: fixed missing link %s", xs_dict_get(post, "id")));
56+                link(priv_fn, pub_fn);
57+            }
58+        }
59+
60+        user_free(&user);
61+    }
62+}
M main.c
+6, -0
 1@@ -34,6 +34,7 @@ int usage(const char *cmd)
 2         "httpd {basedir}                      Starts the HTTPD daemon\n"
 3         "purge {basedir}                      Purges old data\n"
 4         "state {basedir}                      Prints server state\n"
 5+        "fsck {basedir}                       Performs a non-destructive data integrity check\n"
 6         "webfinger {basedir} {account}        Queries about an account (@user@host or actor url)\n"
 7         "queue {basedir} {uid}                Processes a user queue\n"
 8         "follow {basedir} {uid} {actor}       Follows an actor\n"
 9@@ -200,6 +201,11 @@ int main(int argc, char *argv[])
10         return 0;
11     }
12 
13+    if (strcmp(cmd, "fsck") == 0) { /** **/
14+        data_fsck();
15+        return 0;
16+    }
17+
18     if ((user = GET_ARGV()) == NULL)
19         return usage(cmd);
20 
M snac.h
+2, -0
1@@ -477,3 +477,5 @@ xs_str *rss_from_timeline(snac *user, const xs_list *timeline,
2                         const char *title, const char *link, const char *desc);
3 void rss_to_timeline(snac *user, const char *url);
4 void rss_poll_hashtags(void);
5+
6+void data_fsck(void);