summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar grunfink2025-09-07 08:03:38 +0200
committerGravatar grunfink2025-09-07 08:03:38 +0200
commitc541296f25f2c67bbefe5a9a93c5ee6e20ef7012 (patch)
tree63f533cccdaeb05c49fc52d43f32cc05dda237ac
parentBumped version. (diff)
downloadsnac2-c541296f25f2c67bbefe5a9a93c5ee6e20ef7012.tar.gz
snac2-c541296f25f2c67bbefe5a9a93c5ee6e20ef7012.tar.xz
snac2-c541296f25f2c67bbefe5a9a93c5ee6e20ef7012.zip
New command-line option 'fsck'.
Diffstat (limited to '')
-rw-r--r--data.c58
-rw-r--r--main.c6
-rw-r--r--snac.h2
3 files changed, 66 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)
4362 4362
4363 return n_str; 4363 return n_str;
4364} 4364}
4365
4366
4367/** integrity checks **/
4368
4369void data_fsck(void)
4370{
4371 xs *list = user_list();
4372 const char *uid;
4373
4374 xs_list_foreach(list, uid) {
4375 snac user;
4376
4377 if (!user_open(&user, uid))
4378 continue;
4379
4380 {
4381 /* iterate all private posts and check that non-public posts
4382 from this user are also linked into the public directory,
4383 to avoid the don't-fucking-delete-my-own-private-posts purge bug */
4384
4385 xs *priv_spec = xs_fmt("%s/private/""*.json", user.basedir);
4386 xs *posts = xs_glob(priv_spec, 0, 0);
4387 const char *priv_fn;
4388
4389 xs_list_foreach(posts, priv_fn) {
4390 xs *pub_fn = xs_replace(priv_fn, "/private/", "/public/");
4391
4392 /* already there? look no more */
4393 if (mtime(pub_fn))
4394 continue;
4395
4396 /* read the post */
4397 FILE *f;
4398 if ((f = fopen(priv_fn, "r")) == NULL)
4399 continue;
4400
4401 xs *post = xs_json_load(f);
4402 fclose(f);
4403
4404 if (!xs_is_dict(post))
4405 continue;
4406
4407 const char *attr_to = get_atto(post);
4408
4409 if (!xs_is_string(attr_to) || strcmp(attr_to, user.actor) != 0) {
4410 /* not from this user */
4411 continue;
4412 }
4413
4414 /* link */
4415 snac_log(&user, xs_fmt("fsck: fixed missing link %s", xs_dict_get(post, "id")));
4416 link(priv_fn, pub_fn);
4417 }
4418 }
4419
4420 user_free(&user);
4421 }
4422}
diff --git a/main.c b/main.c
index f767355..19cfe1a 100644
--- a/main.c
+++ b/main.c
@@ -34,6 +34,7 @@ int usage(const char *cmd)
34 "httpd {basedir} Starts the HTTPD daemon\n" 34 "httpd {basedir} Starts the HTTPD daemon\n"
35 "purge {basedir} Purges old data\n" 35 "purge {basedir} Purges old data\n"
36 "state {basedir} Prints server state\n" 36 "state {basedir} Prints server state\n"
37 "fsck {basedir} Performs a non-destructive data integrity check\n"
37 "webfinger {basedir} {account} Queries about an account (@user@host or actor url)\n" 38 "webfinger {basedir} {account} Queries about an account (@user@host or actor url)\n"
38 "queue {basedir} {uid} Processes a user queue\n" 39 "queue {basedir} {uid} Processes a user queue\n"
39 "follow {basedir} {uid} {actor} Follows an actor\n" 40 "follow {basedir} {uid} {actor} Follows an actor\n"
@@ -200,6 +201,11 @@ int main(int argc, char *argv[])
200 return 0; 201 return 0;
201 } 202 }
202 203
204 if (strcmp(cmd, "fsck") == 0) { /** **/
205 data_fsck();
206 return 0;
207 }
208
203 if ((user = GET_ARGV()) == NULL) 209 if ((user = GET_ARGV()) == NULL)
204 return usage(cmd); 210 return usage(cmd);
205 211
diff --git a/snac.h b/snac.h
index e4f5262..dd5cc5f 100644
--- a/snac.h
+++ b/snac.h
@@ -477,3 +477,5 @@ xs_str *rss_from_timeline(snac *user, const xs_list *timeline,
477 const char *title, const char *link, const char *desc); 477 const char *title, const char *link, const char *desc);
478void rss_to_timeline(snac *user, const char *url); 478void rss_to_timeline(snac *user, const char *url);
479void rss_poll_hashtags(void); 479void rss_poll_hashtags(void);
480
481void data_fsck(void);