-
Notifications
You must be signed in to change notification settings - Fork 3
/
config.c
116 lines (94 loc) · 2.4 KB
/
config.c
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
113
114
115
116
/* SPDX-License-Identifier: BSD-3-Clause */
#include "ucentral.h"
enum {
CONFIG_UUID,
__CONFIG_MAX,
};
static const struct blobmsg_policy config_policy[__CONFIG_MAX] = {
[CONFIG_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_INT32 },
};
static struct blob_attr *config_tb[__CONFIG_MAX];
static struct blob_buf cfg;
struct blob_buf rejected;
time_t uuid_applied = 0;
time_t uuid_latest = 0;
time_t uuid_active = 0;
void
config_rejected(struct blob_attr *b)
{
struct blob_attr *a;
size_t rem;
blob_buf_init(&rejected, 0);
blobmsg_for_each_attr(a, b, rem)
blobmsg_add_blob(&rejected, a);
}
static time_t
config_load(const char *path)
{
struct stat s;
blob_buf_init(&rejected, 0);
blob_buf_init(&cfg, 0);
if (!blobmsg_add_json_from_file(&cfg, path) || !stat("/tmp/bad.config", &s)) {
ULOG_ERR("failed to load %s\n", path);
unlink("/tmp/bad.config");
return -1;
}
memset(config_tb, 0, sizeof(config_tb));
blobmsg_parse(config_policy, __CONFIG_MAX, config_tb, blob_data(cfg.head), blob_len(cfg.head));
if (config_tb[CONFIG_UUID])
return blobmsg_get_u32(config_tb[CONFIG_UUID]);
return 0;
}
static void
config_apply(uint32_t id)
{
if (uuid_latest && (uuid_latest == uuid_applied)) {
configure_reply(0, "Already applied.", uuid_latest, id);
return;
}
ULOG_INFO("applying cfg:%" PRIu64 "\n", uuid_latest);
apply_run(id);
}
void
config_init(int apply, uint32_t id)
{
char path[PATH_MAX] = { };
char link[PATH_MAX] = { };
struct stat s;
glob_t gl;
int config_id;
uuid_active = 0;
snprintf(path, PATH_MAX, "%s/ucentral.cfg.*", UCENTRAL_CONFIG);
if (glob(path, 0, NULL, &gl))
return;
if (!gl.gl_pathc)
goto out;
config_id = config_load(gl.gl_pathv[gl.gl_pathc - 1]);
if (config_id > 0) {
uuid_latest = config_id;
if (apply)
config_apply(id);
} else {
configure_reply(2, "failed to load/parse the configuration", 0, uuid_latest);
unlink(gl.gl_pathv[gl.gl_pathc - 1]);
}
snprintf(path, PATH_MAX, "%s/ucentral.active", UCENTRAL_CONFIG);
if (readlink(path, link, PATH_MAX - 1) < 0) {
ULOG_INFO("no active symlink found\n");
goto out;
}
snprintf(path, PATH_MAX, "%s/%s", UCENTRAL_CONFIG, basename(link));
if (stat(path, &s)) {
ULOG_INFO("active config not found\n");
goto out;
}
uuid_active = config_load(path);
out:
globfree(&gl);
ULOG_INFO("config_init latest:%" PRIu64 " active:%" PRIu64"\n", uuid_latest, uuid_active);
}
void
config_deinit(void)
{
blob_buf_free(&cfg);
}