aboutsummaryrefslogtreecommitdiff
path: root/data.c
diff options
context:
space:
mode:
authorgrunfink <grunfink@comam.es>2025-09-07 08:03:38 +0200
committergrunfink <grunfink@comam.es>2025-09-07 08:03:38 +0200
commitc541296f25f2c67bbefe5a9a93c5ee6e20ef7012 (patch)
tree63f533cccdaeb05c49fc52d43f32cc05dda237ac /data.c
parentfdcd7b953aacd31ad32e51317ed70962b76784df (diff)
New command-line option 'fsck'.
Diffstat (limited to 'data.c')
-rw-r--r--data.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/data.c b/data.c
index b36e31e..4ec5642 100644
--- a/data.c
+++ b/data.c
@@ -4362,3 +4362,61 @@ const char *lang_str(const char *str, const snac *user)
return n_str;
}
+
+
+/** integrity checks **/
+
+void data_fsck(void)
+{
+ xs *list = user_list();
+ const char *uid;
+
+ xs_list_foreach(list, uid) {
+ snac user;
+
+ if (!user_open(&user, uid))
+ continue;
+
+ {
+ /* iterate all private posts and check that non-public posts
+ from this user are also linked into the public directory,
+ to avoid the don't-fucking-delete-my-own-private-posts purge bug */
+
+ xs *priv_spec = xs_fmt("%s/private/""*.json", user.basedir);
+ xs *posts = xs_glob(priv_spec, 0, 0);
+ const char *priv_fn;
+
+ xs_list_foreach(posts, priv_fn) {
+ xs *pub_fn = xs_replace(priv_fn, "/private/", "/public/");
+
+ /* already there? look no more */
+ if (mtime(pub_fn))
+ continue;
+
+ /* read the post */
+ FILE *f;
+ if ((f = fopen(priv_fn, "r")) == NULL)
+ continue;
+
+ xs *post = xs_json_load(f);
+ fclose(f);
+
+ if (!xs_is_dict(post))
+ continue;
+
+ const char *attr_to = get_atto(post);
+
+ if (!xs_is_string(attr_to) || strcmp(attr_to, user.actor) != 0) {
+ /* not from this user */
+ continue;
+ }
+
+ /* link */
+ snac_log(&user, xs_fmt("fsck: fixed missing link %s", xs_dict_get(post, "id")));
+ link(priv_fn, pub_fn);
+ }
+ }
+
+ user_free(&user);
+ }
+}