blob: 6665677ad77a7be50ec91a2ddab64d1583f5ab13 [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;
76 struct stat statbuf;
77 size_t len, i;
78 char *buf;
79 int fd, rc;
80
81 if (!filename)
82 filename = config_default_filename;
83
84 fd = open(filename, O_RDONLY);
85 if (fd < 0) {
86 warn("Can't open configuration file %s", filename);
87 return NULL;
88 }
89
90 rc = fstat(fd, &statbuf);
91 if (rc) {
92 warn("Can't stat %s", filename);
93 goto err_close;
94 }
95
96 len = statbuf.st_size;
97
98 buf = malloc(len + 1);
99 for (i = 0; i < len;) {
100 rc = read(fd, buf + i, len - i);
101 if (rc < 0) {
102 warn("Can't read configuration file %s", filename);
103 goto err_free;
104
105 } else if (!rc) {
106 break;
107 }
108 i += rc;
109
110 }
111 buf[len] = '\0';
112
113 close(fd);
114
115 config = malloc(sizeof(*config));
116 config->items = NULL;
117
118 config_parse(config, buf);
119
120 free(buf);
121
122 return config;
123
124err_free:
125 free(buf);
126err_close:
127 close(fd);
128 return NULL;
129}
130
131void config_fini(struct config *config)
132{
133 struct config_item *item, *next;
134
135 for (item = config->items; item; item = next) {
136 next = item->next;
137 free(item->name);
138 free(item->value);
139 free(item);
140 }
141
142 free(config);
143}