Add configuration file loading and parsing
[src/drm-lease-manager.git] / drm-lease-manager / lease-config.c
1 /* Copyright 2021 IGEL Co., Ltd.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "lease-config.h"
17 #include "log.h"
18 #include "toml/toml.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #define CONFIG_ERROR(x, ...) ERROR_LOG("%s: " x, filename, ##__VA_ARGS__)
23
24 int parse_config(char *filename, struct lease_config **parsed_config)
25 {
26         struct lease_config *config = NULL;
27         int nconfigs = 0;
28         char parse_error[160];
29
30         FILE *fp = fopen(filename, "r");
31         if (!fp)
32                 return 0;
33
34         toml_table_t *t_config =
35             toml_parse_file(fp, parse_error, sizeof parse_error);
36         if (!t_config) {
37                 CONFIG_ERROR("configuration file parse error: %s\n",
38                              parse_error);
39                 return 0;
40         }
41
42         toml_array_t *leases = toml_array_in(t_config, "lease");
43         if (!leases) {
44                 CONFIG_ERROR(
45                     "Invalid config - cannot find any 'lease' configs");
46         }
47         nconfigs = toml_array_nelem(leases);
48         config = calloc(nconfigs, sizeof *config);
49
50         for (int i = 0; i < toml_array_nelem(leases); i++) {
51                 toml_table_t *lease = toml_table_at(leases, i);
52
53                 toml_datum_t name = toml_string_in(lease, "name");
54                 if (!name.ok) {
55                         CONFIG_ERROR("Invalid lease name in entry #%d\n", i);
56                         continue;
57                 }
58
59                 config[i].lease_name = name.u.s;
60
61                 toml_array_t *conns = toml_array_in(lease, "connectors");
62                 if (conns) {
63                         config[i].cnames = toml_array_nelem(conns);
64                         config[i].connector_names =
65                             calloc(config[i].cnames, sizeof(char *));
66                         for (int j = 0; j < config[i].cnames; j++) {
67                                 toml_datum_t conn = toml_string_at(conns, j);
68                                 if (!conn.ok) {
69                                         CONFIG_ERROR("Non string connector "
70                                                      "name in lease: %s\n",
71                                                      config[i].lease_name);
72                                         goto out;
73                                 }
74                                 config[i].connector_names[j] = conn.u.s;
75                         }
76                 }
77         }
78
79         toml_free(t_config);
80         *parsed_config = config;
81         return nconfigs;
82 out:
83         free(config);
84         return 0;
85 }
86
87 void release_config(int num_leases, struct lease_config *config)
88 {
89         for (int i = 0; i < num_leases; i++) {
90                 struct lease_config *c = &config[i];
91                 free(c->lease_name);
92                 for (int j = 0; j < c->cnames; j++)
93                         free(c->connector_names[j]);
94                 free(c->connector_names);
95         }
96         free(config);
97 }