summaryrefslogtreecommitdiff
path: root/upgrade.c
blob: d5e5f0c5d1dbbd2b9c523e509707376248e571a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* snac - A simple, minimalistic ActivityPub instance */
/* copyright (c) 2022 grunfink - MIT license */

#include "xs.h"
#include "xs_io.h"
#include "xs_json.h"
#include "xs_glob.h"

#include "snac.h"

#include <sys/stat.h>


int db_upgrade(d_char **error)
{
    int ret = 1;
    int changed = 0;
    double f = 0.0;

    for (;;) {
        char *layout = xs_dict_get(srv_config, "layout");
        double nf;

        f = nf = xs_number_get(layout);

        if (!(f < db_layout))
            break;

        srv_log(xs_fmt("db_upgrade %1.1lf < %1.1lf", f, db_layout));

        if (f < 2.0) {
            *error = xs_fmt("ERROR: unsupported old disk layout %1.1lf\n", f);
            ret    = 0;
            break;
        }
        else
        if (f < 2.1) {
            xs *dir = xs_fmt("%s/object", srv_basedir);
            mkdir(dir, 0755);

            nf = 2.1;
        }
        else
        if (f < 2.2) {
            xs *users = user_list();
            char *p, *v;

            p = users;
            while (xs_list_iter(&p, &v)) {
                snac snac;

                if (user_open(&snac, v)) {
                    xs *spec = xs_fmt("%s/actors/" "*.json", snac.basedir);
                    xs *list = xs_glob(spec, 0, 0);
                    char *g, *fn;

                    g = list;
                    while (xs_list_iter(&g, &fn)) {
                        xs *l   = xs_split(fn, "/");
                        char *b = xs_list_get(l, -1);
                        xs *dir = xs_fmt("%s/object/%c%c", srv_basedir, b[0], b[1]);
                        xs *nfn = xs_fmt("%s/%s", dir, b);

                        mkdir(dir, 0755);
                        rename(fn, nfn);
                    }

                    xs *odir = xs_fmt("%s/actors", snac.basedir);
                    rmdir(odir);

                    user_free(&snac);
                }
            }

            nf = 2.2;
        }

        if (f < nf) {
            f          = nf;
            xs *nv     = xs_number_new(f);
            srv_config = xs_dict_set(srv_config, "layout", nv);

            srv_log(xs_fmt("db_upgrade converted to version %1.1lf", f));
            changed++;
        }
        else
            break;
    }

    if (f > db_layout) {
        *error = xs_fmt("ERROR: unknown future version %lf\n", f);
        ret    = 0;
    }

    if (changed) {
        /* upgrade the configuration file */
        xs *fn = xs_fmt("%s/server.json", srv_basedir);
        FILE *f;

        if ((f = fopen(fn, "w")) != NULL) {
            xs *j = xs_json_dumps_pp(srv_config, 4);
            fwrite(j, strlen(j), 1, f);
            fclose(f);

            srv_log(xs_fmt("upgraded db %s after %d changes", fn, changed));
        }
        else
            ret = 0;
    }

    return ret;
}