blob: ee820dbc1e996a3b2e7b8b27461285530e6e61ef [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
14static const char *config_default_filename = SYSCONFDIR "/openbmc-console.conf";
15
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
73struct config *config_init(const char *filename)
74{
75 struct config *config;
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080076 size_t size, len;
Jeremy Kerrd66195c2016-03-16 17:24:51 +080077 int fd, rc;
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080078 char *buf;
Jeremy Kerrd66195c2016-03-16 17:24:51 +080079
80 if (!filename)
81 filename = config_default_filename;
82
83 fd = open(filename, O_RDONLY);
84 if (fd < 0) {
85 warn("Can't open configuration file %s", filename);
86 return NULL;
87 }
88
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080089 size = 4096;
90 len = 0;
91 buf = malloc(size + 1);
Jeremy Kerrd66195c2016-03-16 17:24:51 +080092
Jeremy Kerr2eb56f52016-03-17 14:55:14 +080093 for (;;) {
94 rc = read(fd, buf + len, size - len);
Jeremy Kerrd66195c2016-03-16 17:24:51 +080095 if (rc < 0) {
96 warn("Can't read configuration file %s", filename);
97 goto err_free;
98
99 } else if (!rc) {
100 break;
101 }
Jeremy Kerr2eb56f52016-03-17 14:55:14 +0800102 len += rc;
103 if (len == size) {
104 size <<= 1;
105 buf = realloc(buf, size + 1);
106 }
Jeremy Kerrd66195c2016-03-16 17:24:51 +0800107
108 }
109 buf[len] = '\0';
110
111 close(fd);
112
113 config = malloc(sizeof(*config));
114 config->items = NULL;
115
116 config_parse(config, buf);
117
118 free(buf);
119
120 return config;
121
122err_free:
123 free(buf);
124err_close:
125 close(fd);
126 return NULL;
127}
128
129void config_fini(struct config *config)
130{
131 struct config_item *item, *next;
132
133 for (item = config->items; item; item = next) {
134 next = item->next;
135 free(item->name);
136 free(item->value);
137 free(item);
138 }
139
140 free(config);
141}