lib/pb-config: Add config_copy
[petitboot] / lib / pb-config / pb-config.c
1
2 #include <string.h>
3
4 #include <log/log.h>
5 #include <types/types.h>
6 #include <talloc/talloc.h>
7
8 #include "pb-config.h"
9
10 #include "storage.h"
11
12 void                            *config_ctx;
13 static struct config            *config;
14 static struct config_storage    *storage;
15
16
17 void config_set_defaults(struct config *config)
18 {
19         config->autoboot_enabled = true;
20         config->autoboot_timeout_sec = 10;
21         config->network.interfaces = NULL;
22         config->network.n_interfaces = 0;
23         config->network.dns_servers = NULL;
24         config->network.n_dns_servers = 0;
25
26         config->n_boot_priorities = 2;
27         config->boot_priorities = talloc_array(config, struct boot_priority,
28                                                 config->n_boot_priorities);
29         config->boot_priorities[0].type = DEVICE_TYPE_NETWORK;
30         config->boot_priorities[1].type = DEVICE_TYPE_DISK;
31
32 }
33
34 static struct interface_config *config_copy_interface(struct config *ctx,
35                 struct interface_config *src)
36 {
37         struct interface_config *dest = talloc(ctx, struct interface_config);
38
39         memcpy(dest->hwaddr, src->hwaddr, sizeof(src->hwaddr));
40         dest->ignore = src->ignore;
41
42         if (dest->ignore)
43                 return dest;
44
45         dest->method = src->method;
46
47         switch (src->method) {
48         case CONFIG_METHOD_DHCP:
49                 break;
50         case CONFIG_METHOD_STATIC:
51                 dest->static_config.address =
52                         talloc_strdup(dest, src->static_config.address);
53                 dest->static_config.gateway =
54                         talloc_strdup(dest, src->static_config.gateway);
55                 break;
56         }
57
58         return dest;
59 }
60
61 struct config *config_copy(void *ctx, const struct config *src)
62 {
63         struct config *dest;
64         unsigned int i;
65
66         dest = talloc(ctx, struct config);
67         dest->autoboot_enabled = src->autoboot_enabled;
68         dest->autoboot_timeout_sec = src->autoboot_timeout_sec;
69
70         dest->network.n_interfaces = src->network.n_interfaces;
71         dest->network.interfaces = talloc_array(dest, struct interface_config *,
72                                         dest->network.n_interfaces);
73         dest->network.n_dns_servers = src->network.n_dns_servers;
74         dest->network.dns_servers = talloc_array(dest, const char *,
75                                         dest->network.n_dns_servers);
76
77         for (i = 0; i < src->network.n_interfaces; i++)
78                 dest->network.interfaces[i] = config_copy_interface(dest,
79                                 src->network.interfaces[i]);
80
81         for (i = 0; i < src->network.n_dns_servers; i++)
82                 dest->network.dns_servers[i] = talloc_strdup(dest,
83                                 src->network.dns_servers[i]);
84
85         dest->n_boot_priorities = src->n_boot_priorities;
86         dest->boot_priorities = talloc_array(dest, struct boot_priority,
87                         src->n_boot_priorities);
88
89         for (i = 0; i < src->n_boot_priorities; i++)
90                 dest->boot_priorities[i].type = src->boot_priorities[i].type;
91
92         return dest;
93 }
94
95 void dump_config(struct config *config);
96 void dump_config(struct config *config)
97 {
98         unsigned int i;
99
100         pb_log("configuration:\n");
101
102         if (config->autoboot_enabled)
103                 pb_log(" autoboot: enabled, %d sec\n",
104                                 config->autoboot_timeout_sec);
105         else
106                 pb_log(" autoboot: disabled\n");
107
108         if (config->network.n_interfaces || config->network.n_dns_servers)
109                 pb_log(" network configuration:\n");
110
111         for (i = 0; i < config->network.n_interfaces; i++) {
112                 struct interface_config *ifconf =
113                         config->network.interfaces[i];
114
115                 pb_log("  interface %02x:%02x:%02x:%02x:%02x:%02x\n",
116                                 ifconf->hwaddr[0], ifconf->hwaddr[1],
117                                 ifconf->hwaddr[2], ifconf->hwaddr[3],
118                                 ifconf->hwaddr[4], ifconf->hwaddr[5]);
119
120                 if (ifconf->ignore) {
121                         pb_log("   ignore\n");
122                         continue;
123                 }
124
125                 if (ifconf->method == CONFIG_METHOD_DHCP) {
126                         pb_log("   dhcp\n");
127
128                 } else if (ifconf->method == CONFIG_METHOD_STATIC) {
129                         pb_log("   static:\n");
130                         pb_log("    ip:  %s\n", ifconf->static_config.address);
131                         pb_log("    gw:  %s\n", ifconf->static_config.gateway);
132
133                 }
134         }
135         for (i = 0; i < config->network.n_dns_servers; i++)
136                 pb_log("  dns server %s\n", config->network.dns_servers[i]);
137 }
138
139 int config_init(void *ctx)
140 {
141         config_ctx = talloc_new(ctx);
142
143         config = talloc(config_ctx, struct config);
144         config_set_defaults(config);
145
146         storage = create_powerpc_nvram_storage(config);
147
148         storage->load(storage, config);
149
150         dump_config(config);
151
152         return 0;
153 }
154
155 int config_set(struct config *newconfig)
156 {
157         int rc;
158
159         if (!storage || !storage->save)
160                 return -1;
161
162         if (newconfig == config)
163                 return 0;
164
165         pb_log("new configuration data received\n");
166         dump_config(newconfig);
167
168         rc = storage->save(storage, newconfig);
169
170         if (!rc)
171                 config = talloc_steal(config_ctx, newconfig);
172         else
173                 pb_log("error saving new configuration; changes lost\n");
174
175         return rc;
176 }
177
178 /* A non-exported function to allow the test infrastructure to initialise
179  * (and change) the configuration variables */
180 struct parser_test;
181 struct config __attribute__((unused)) *test_config_init(
182                 struct parser_test *test);
183 struct config *test_config_init(struct parser_test *test)
184 {
185         config = talloc(test, struct config);
186         config_set_defaults(config);
187         return config;
188 }
189
190 const struct config *config_get(void)
191 {
192         return config;
193 }
194
195 void config_set_autoboot(bool autoboot_enabled)
196 {
197         config->autoboot_enabled = autoboot_enabled;
198
199         pb_log("set autoboot: %s\n",
200                         config->autoboot_enabled ? "enabled" : "disabled");
201 }
202
203 int config_fini(void)
204 {
205         talloc_free(config_ctx);
206         return 0;
207 }