blob: fdfcb423a99aa9c621dbf40001ccc9fcbad98ada [file] [log] [blame]
Jeremy Kerrd66195c2016-03-16 17:24:51 +08001
2#include <err.h>
3#include <fcntl.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <strings.h>
9#include <unistd.h>
10
11#include <sys/mman.h>
12#include <sys/stat.h>
13
Jeremy Kerre440a402016-03-17 16:34:14 +080014static const char *config_default_filename = SYSCONFDIR "/obmc-console.conf";
Jeremy Kerrd66195c2016-03-16 17:24:51 +080015
16struct config_item {
17 char *name;
18 char *value;
19 struct config_item *next;
20};
21
22struct config {
23 struct config_item *items;
24};
25
26const char *config_get_value(struct config *config, const char *name)
27{
28 struct config_item *item;
29
30 for (item = config->items; item; item = item->next)
31 if (!strcasecmp(item->name, name))
32 return item->value;
33
34 return NULL;
35}
36
37static void config_parse(struct config *config, char *buf)
38{
39 struct config_item *item;
40 char *name, *value;
41 char *p, *line;
42 int rc;
43
44 for (p = NULL, line = strtok_r(buf, "\n", &p); line;
45 line = strtok_r(NULL, "\n", &p)) {
46
47 /* trim leading space */
48 for (;*line == ' ' || *line == '\t'; line++)
49 ;
50
51 /* skip comments */
52 if (*line == '#')
53 continue;
54
55 name = value = NULL;
56
57 rc = sscanf(line, "%m[^ =] = %ms ", &name, &value);
58 if (rc != 2 || !strlen(name) || !strlen(value)) {
59 free(name);
60 free(value);
61 continue;
62 }
63
64 /* create a new item and add to our list */
65 item = malloc(sizeof(*item));
66 item->name = name;
67 item->value = value;
68 item->next = config->items;
69 config->items = item;
70 }
71}
72
Jeremy Kerr6c8d7812016-03-17 15:05:45 +080073static struct config *config_init_fd(int fd, const char *filename)
Jeremy Kerrd66195c2016-03-16 17:24:51 +080074{
75 struct config *config;
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080076 size_t size, len;
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080077 char *buf;
Jeremy Kerr6c8d7812016-03-17 15:05:45 +080078 int rc;
Jeremy Kerrd66195c2016-03-16 17:24:51 +080079
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080080 size = 4096;
81 len = 0;
82 buf = malloc(size + 1);
Jeremy Kerr6c8d7812016-03-17 15:05:45 +080083 config = NULL;
Jeremy Kerrd66195c2016-03-16 17:24:51 +080084
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080085 for (;;) {
86 rc = read(fd, buf + len, size - len);
Jeremy Kerrd66195c2016-03-16 17:24:51 +080087 if (rc < 0) {
Jeremy Kerr6c8d7812016-03-17 15:05:45 +080088 warn("Can't read from configuration file %s", filename);
89 goto out_free;
Jeremy Kerrd66195c2016-03-16 17:24:51 +080090
91 } else if (!rc) {
92 break;
93 }
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080094 len += rc;
95 if (len == size) {
96 size <<= 1;
97 buf = realloc(buf, size + 1);
98 }
Jeremy Kerrd66195c2016-03-16 17:24:51 +080099
100 }
101 buf[len] = '\0';
102
Jeremy Kerrd66195c2016-03-16 17:24:51 +0800103 config = malloc(sizeof(*config));
104 config->items = NULL;
105
106 config_parse(config, buf);
107
Jeremy Kerr6c8d7812016-03-17 15:05:45 +0800108out_free:
Jeremy Kerrd66195c2016-03-16 17:24:51 +0800109 free(buf);
Jeremy Kerr6c8d7812016-03-17 15:05:45 +0800110 return config;
111}
112
113struct config *config_init(const char *filename)
114{
115 struct config *config;
116 int fd;
117
118 if (!filename)
119 filename = config_default_filename;
120
121 fd = open(filename, O_RDONLY);
122 if (fd < 0) {
123 warn("Can't open configuration file %s", filename);
124 return NULL;
125 }
126
127 config = config_init_fd(fd, filename);
128
129 close(fd);
Jeremy Kerrd66195c2016-03-16 17:24:51 +0800130
131 return config;
Jeremy Kerrd66195c2016-03-16 17:24:51 +0800132}
133
134void config_fini(struct config *config)
135{
136 struct config_item *item, *next;
137
138 for (item = config->items; item; item = next) {
139 next = item->next;
140 free(item->name);
141 free(item->value);
142 free(item);
143 }
144
145 free(config);
146}
Jeremy Kerr6c8d7812016-03-17 15:05:45 +0800147
148#ifdef CONFIG_TEST
149int main(void)
150{
151 struct config_item *item;
152 struct config *config;
153
154 config = config_init_fd(STDIN_FILENO, "<stdin>");
155 if (!config)
156 return EXIT_FAILURE;
157
158 for (item = config->items; item; item = item->next)
159 printf("%s: %s\n", item->name, item->value);
160
161 config_fini(config);
162
163 return EXIT_SUCCESS;
164
165}
166#endif