diff options
| -rw-r--r-- | activitypub.c | 6 | ||||
| -rw-r--r-- | data.c | 69 | ||||
| -rw-r--r-- | httpd.c | 2 | ||||
| -rw-r--r-- | main.c | 6 | ||||
| -rw-r--r-- | snac.h | 3 |
5 files changed, 86 insertions, 0 deletions
diff --git a/activitypub.c b/activitypub.c index d699fee..5fb60ba 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -3377,6 +3377,12 @@ void process_queue_item(xs_dict *q_item) | |||
| 3377 | rss_poll_hashtags(); | 3377 | rss_poll_hashtags(); |
| 3378 | } | 3378 | } |
| 3379 | else | 3379 | else |
| 3380 | if (strcmp(type, "fsck") == 0) { | ||
| 3381 | srv_log(xs_fmt("started deferred data integrity check")); | ||
| 3382 | data_fsck(); | ||
| 3383 | srv_log(xs_fmt("finished deferred data integrity check")); | ||
| 3384 | } | ||
| 3385 | else | ||
| 3380 | srv_log(xs_fmt("unexpected q_item type '%s'", type)); | 3386 | srv_log(xs_fmt("unexpected q_item type '%s'", type)); |
| 3381 | } | 3387 | } |
| 3382 | 3388 | ||
| @@ -3605,6 +3605,17 @@ void enqueue_collect_outbox(snac *user, const char *actor_id) | |||
| 3605 | } | 3605 | } |
| 3606 | 3606 | ||
| 3607 | 3607 | ||
| 3608 | void enqueue_fsck(void) | ||
| 3609 | /* enqueues an fsck */ | ||
| 3610 | { | ||
| 3611 | xs *qmsg = _new_qmsg("fsck", "", 0); | ||
| 3612 | const char *ntid = xs_dict_get(qmsg, "ntid"); | ||
| 3613 | xs *fn = xs_fmt("%s/queue/%s.json", srv_basedir, ntid); | ||
| 3614 | |||
| 3615 | qmsg = _enqueue_put(fn, qmsg); | ||
| 3616 | } | ||
| 3617 | |||
| 3618 | |||
| 3608 | int was_question_voted(snac *user, const char *id) | 3619 | int was_question_voted(snac *user, const char *id) |
| 3609 | /* returns true if the user voted in this poll */ | 3620 | /* returns true if the user voted in this poll */ |
| 3610 | { | 3621 | { |
| @@ -4362,3 +4373,61 @@ const char *lang_str(const char *str, const snac *user) | |||
| 4362 | 4373 | ||
| 4363 | return n_str; | 4374 | return n_str; |
| 4364 | } | 4375 | } |
| 4376 | |||
| 4377 | |||
| 4378 | /** integrity checks **/ | ||
| 4379 | |||
| 4380 | void data_fsck(void) | ||
| 4381 | { | ||
| 4382 | xs *list = user_list(); | ||
| 4383 | const char *uid; | ||
| 4384 | |||
| 4385 | xs_list_foreach(list, uid) { | ||
| 4386 | snac user; | ||
| 4387 | |||
| 4388 | if (!user_open(&user, uid)) | ||
| 4389 | continue; | ||
| 4390 | |||
| 4391 | { | ||
| 4392 | /* iterate all private posts and check that non-public posts | ||
| 4393 | from this user are also linked into the public directory, | ||
| 4394 | to avoid the don't-fucking-delete-my-own-private-posts purge bug */ | ||
| 4395 | |||
| 4396 | xs *priv_spec = xs_fmt("%s/private/""*.json", user.basedir); | ||
| 4397 | xs *posts = xs_glob(priv_spec, 0, 0); | ||
| 4398 | const char *priv_fn; | ||
| 4399 | |||
| 4400 | xs_list_foreach(posts, priv_fn) { | ||
| 4401 | xs *pub_fn = xs_replace(priv_fn, "/private/", "/public/"); | ||
| 4402 | |||
| 4403 | /* already there? look no more */ | ||
| 4404 | if (mtime(pub_fn)) | ||
| 4405 | continue; | ||
| 4406 | |||
| 4407 | /* read the post */ | ||
| 4408 | FILE *f; | ||
| 4409 | if ((f = fopen(priv_fn, "r")) == NULL) | ||
| 4410 | continue; | ||
| 4411 | |||
| 4412 | xs *post = xs_json_load(f); | ||
| 4413 | fclose(f); | ||
| 4414 | |||
| 4415 | if (!xs_is_dict(post)) | ||
| 4416 | continue; | ||
| 4417 | |||
| 4418 | const char *attr_to = get_atto(post); | ||
| 4419 | |||
| 4420 | if (!xs_is_string(attr_to) || strcmp(attr_to, user.actor) != 0) { | ||
| 4421 | /* not from this user */ | ||
| 4422 | continue; | ||
| 4423 | } | ||
| 4424 | |||
| 4425 | /* link */ | ||
| 4426 | snac_debug(&user, 1, xs_fmt("fsck: fixed missing link %s", xs_dict_get(post, "id"))); | ||
| 4427 | link(priv_fn, pub_fn); | ||
| 4428 | } | ||
| 4429 | } | ||
| 4430 | |||
| 4431 | user_free(&user); | ||
| 4432 | } | ||
| 4433 | } | ||
| @@ -805,6 +805,8 @@ static void *background_thread(void *arg) | |||
| 805 | 805 | ||
| 806 | srv_log(xs_fmt("background thread started")); | 806 | srv_log(xs_fmt("background thread started")); |
| 807 | 807 | ||
| 808 | enqueue_fsck(); | ||
| 809 | |||
| 808 | while (p_state->srv_running) { | 810 | while (p_state->srv_running) { |
| 809 | int cnt = 0; | 811 | int cnt = 0; |
| 810 | 812 | ||
| @@ -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 | ||
| @@ -299,6 +299,7 @@ void enqueue_webmention(const xs_dict *msg); | |||
| 299 | void enqueue_notify_webhook(snac *user, const xs_dict *noti, int retries); | 299 | void enqueue_notify_webhook(snac *user, const xs_dict *noti, int retries); |
| 300 | void enqueue_collect_replies(snac *user, const char *post); | 300 | void enqueue_collect_replies(snac *user, const char *post); |
| 301 | void enqueue_collect_outbox(snac *user, const char *actor_id); | 301 | void enqueue_collect_outbox(snac *user, const char *actor_id); |
| 302 | void enqueue_fsck(void); | ||
| 302 | 303 | ||
| 303 | int was_question_voted(snac *user, const char *id); | 304 | int was_question_voted(snac *user, const char *id); |
| 304 | 305 | ||
| @@ -477,3 +478,5 @@ xs_str *rss_from_timeline(snac *user, const xs_list *timeline, | |||
| 477 | const char *title, const char *link, const char *desc); | 478 | const char *title, const char *link, const char *desc); |
| 478 | void rss_to_timeline(snac *user, const char *url); | 479 | void rss_to_timeline(snac *user, const char *url); |
| 479 | void rss_poll_hashtags(void); | 480 | void rss_poll_hashtags(void); |
| 481 | |||
| 482 | void data_fsck(void); | ||