]>
Commit | Line | Data |
---|---|---|
3efd4195 LP |
1 | /*-*- Mode: C; c-basic-offset: 8 -*-*/ |
2 | ||
3 | #include <assert.h> | |
4 | #include <errno.h> | |
5 | #include <string.h> | |
6 | ||
7 | #include "name.h" | |
8 | #include "strv.h" | |
9 | #include "conf-parser.h" | |
10 | #include "load-fragment.h" | |
16354eff | 11 | #include "log.h" |
3efd4195 | 12 | |
42f4e3c4 | 13 | static int config_parse_deps( |
3efd4195 LP |
14 | const char *filename, |
15 | unsigned line, | |
16 | const char *section, | |
17 | const char *lvalue, | |
18 | const char *rvalue, | |
19 | void *data, | |
20 | void *userdata) { | |
21 | ||
22 | Set **set = data; | |
23 | Name *name = userdata; | |
24 | char *w; | |
25 | size_t l; | |
26 | char *state; | |
27 | ||
28 | assert(filename); | |
29 | assert(lvalue); | |
30 | assert(rvalue); | |
31 | assert(data); | |
32 | ||
33 | FOREACH_WORD(w, &l, rvalue, state) { | |
34 | char *t; | |
35 | int r; | |
36 | Name *other; | |
37 | ||
38 | if (!(t = strndup(w, l))) | |
39 | return -ENOMEM; | |
40 | ||
41 | r = manager_load_name(name->meta.manager, t, &other); | |
42 | free(t); | |
43 | ||
44 | if (r < 0) | |
45 | return r; | |
46 | ||
47 | if (!*set) | |
48 | if (!(*set = set_new(trivial_hash_func, trivial_compare_func))) | |
49 | return -ENOMEM; | |
50 | ||
51 | if ((r = set_put(*set, other)) < 0) | |
52 | return r; | |
53 | } | |
54 | ||
55 | return 0; | |
56 | } | |
57 | ||
42f4e3c4 | 58 | static int config_parse_names( |
87d1515d LP |
59 | const char *filename, |
60 | unsigned line, | |
61 | const char *section, | |
62 | const char *lvalue, | |
63 | const char *rvalue, | |
64 | void *data, | |
65 | void *userdata) { | |
66 | ||
67 | Set **set = data; | |
68 | Name *name = userdata; | |
69 | char *w; | |
70 | size_t l; | |
71 | char *state; | |
72 | ||
73 | assert(filename); | |
74 | assert(lvalue); | |
75 | assert(rvalue); | |
76 | assert(data); | |
77 | ||
78 | FOREACH_WORD(w, &l, rvalue, state) { | |
79 | char *t; | |
80 | int r; | |
81 | Name *other; | |
82 | ||
83 | if (!(t = strndup(w, l))) | |
84 | return -ENOMEM; | |
85 | ||
86 | other = manager_get_name(name->meta.manager, t); | |
87 | ||
88 | if (other) { | |
89 | ||
90 | if (other != name) { | |
91 | ||
5cb5a6ff | 92 | if (other->meta.load_state != NAME_STUB) { |
87d1515d LP |
93 | free(t); |
94 | return -EEXIST; | |
95 | } | |
96 | ||
7fad411c | 97 | if ((r = name_merge(name, other)) < 0) { |
87d1515d LP |
98 | free(t); |
99 | return r; | |
100 | } | |
101 | } | |
102 | ||
103 | } else { | |
104 | ||
105 | if (!*set) | |
106 | if (!(*set = set_new(trivial_hash_func, trivial_compare_func))) { | |
107 | free(t); | |
108 | return -ENOMEM; | |
109 | } | |
110 | ||
111 | if ((r = set_put(*set, t)) < 0) { | |
112 | free(t); | |
113 | return r; | |
114 | } | |
11dd41ce LP |
115 | |
116 | t = NULL; | |
87d1515d LP |
117 | } |
118 | ||
119 | free(t); | |
120 | } | |
121 | ||
122 | return 0; | |
123 | } | |
124 | ||
42f4e3c4 LP |
125 | static int config_parse_listen( |
126 | const char *filename, | |
127 | unsigned line, | |
128 | const char *section, | |
129 | const char *lvalue, | |
130 | const char *rvalue, | |
131 | void *data, | |
132 | void *userdata) { | |
133 | ||
16354eff | 134 | int r; |
542563ba LP |
135 | SocketPort *p; |
136 | Socket *s; | |
16354eff | 137 | |
42f4e3c4 LP |
138 | assert(filename); |
139 | assert(lvalue); | |
140 | assert(rvalue); | |
141 | assert(data); | |
142 | ||
542563ba LP |
143 | s = (Socket*) data; |
144 | ||
145 | if (!(p = new0(SocketPort, 1))) | |
146 | return -ENOMEM; | |
147 | ||
148 | if (streq(lvalue, "ListenFIFO")) { | |
149 | p->type = SOCKET_FIFO; | |
150 | ||
151 | if (!(p->path = strdup(rvalue))) { | |
152 | free(p); | |
153 | return -ENOMEM; | |
154 | } | |
155 | } else { | |
156 | p->type = SOCKET_SOCKET; | |
157 | ||
158 | if ((r = socket_address_parse(&p->address, rvalue)) < 0) { | |
159 | log_error("[%s:%u] Failed to parse address value: %s", filename, line, rvalue); | |
160 | free(p); | |
161 | return r; | |
162 | } | |
163 | ||
164 | if (streq(lvalue, "ListenStream")) | |
165 | p->address.type = SOCK_STREAM; | |
166 | else if (streq(lvalue, "ListenDatagram")) | |
167 | p->address.type = SOCK_DGRAM; | |
168 | else { | |
169 | assert(streq(lvalue, "ListenSequentialPacket")); | |
170 | p->address.type = SOCK_SEQPACKET; | |
171 | } | |
172 | ||
173 | if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) { | |
174 | free(p); | |
175 | return -EPROTONOSUPPORT; | |
176 | } | |
16354eff LP |
177 | } |
178 | ||
542563ba LP |
179 | p->fd = -1; |
180 | LIST_PREPEND(SocketPort, s->ports, p); | |
181 | ||
16354eff | 182 | return 0; |
42f4e3c4 LP |
183 | } |
184 | ||
542563ba | 185 | static int config_parse_bind( |
42f4e3c4 LP |
186 | const char *filename, |
187 | unsigned line, | |
188 | const char *section, | |
189 | const char *lvalue, | |
190 | const char *rvalue, | |
191 | void *data, | |
192 | void *userdata) { | |
193 | ||
542563ba LP |
194 | int r; |
195 | Socket *s; | |
42f4e3c4 LP |
196 | |
197 | assert(filename); | |
198 | assert(lvalue); | |
199 | assert(rvalue); | |
200 | assert(data); | |
201 | ||
542563ba LP |
202 | s = (Socket*) data; |
203 | ||
204 | if ((r = parse_boolean(rvalue)) < 0) { | |
205 | log_error("[%s:%u] Failed to parse bind IPv6 only value: %s", filename, line, rvalue); | |
206 | return r; | |
16354eff | 207 | } |
42f4e3c4 | 208 | |
542563ba LP |
209 | s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH; |
210 | ||
42f4e3c4 LP |
211 | return 0; |
212 | } | |
213 | ||
3efd4195 LP |
214 | int name_load_fragment(Name *n) { |
215 | ||
5cb5a6ff | 216 | static const char* const section_table[_NAME_TYPE_MAX] = { |
42f4e3c4 LP |
217 | [NAME_SERVICE] = "Service", |
218 | [NAME_TIMER] = "Timer", | |
219 | [NAME_SOCKET] = "Socket", | |
220 | [NAME_MILESTONE] = "Milestone", | |
221 | [NAME_DEVICE] = "Device", | |
222 | [NAME_MOUNT] = "Mount", | |
223 | [NAME_AUTOMOUNT] = "Automount", | |
224 | [NAME_SNAPSHOT] = "Snapshot" | |
225 | }; | |
226 | ||
3efd4195 | 227 | const ConfigItem items[] = { |
542563ba LP |
228 | { "Names", config_parse_names, &n->meta.names, "Meta" }, |
229 | { "Description", config_parse_string, &n->meta.description, "Meta" }, | |
230 | { "Requires", config_parse_deps, n->meta.dependencies+NAME_REQUIRES, "Meta" }, | |
231 | { "SoftRequires", config_parse_deps, n->meta.dependencies+NAME_SOFT_REQUIRES, "Meta" }, | |
232 | { "Wants", config_parse_deps, n->meta.dependencies+NAME_WANTS, "Meta" }, | |
233 | { "Requisite", config_parse_deps, n->meta.dependencies+NAME_REQUISITE, "Meta" }, | |
234 | { "SoftRequisite", config_parse_deps, n->meta.dependencies+NAME_SOFT_REQUISITE, "Meta" }, | |
235 | { "Conflicts", config_parse_deps, n->meta.dependencies+NAME_CONFLICTS, "Meta" }, | |
236 | { "Before", config_parse_deps, n->meta.dependencies+NAME_BEFORE, "Meta" }, | |
237 | { "After", config_parse_deps, n->meta.dependencies+NAME_AFTER, "Meta" }, | |
238 | { "ListenStream", config_parse_listen, &n->socket, "Socket" }, | |
239 | { "ListenDatagram", config_parse_listen, &n->socket, "Socket" }, | |
240 | { "ListenSequentialPacket", config_parse_listen, &n->socket, "Socket" }, | |
241 | { "ListenFIFO", config_parse_listen, &n->socket, "Socket" }, | |
242 | { "BindIPv6Only", config_parse_bind, &n->socket, "Socket" }, | |
243 | { "Backlog", config_parse_unsigned, &n->socket.backlog, "Socket" }, | |
3efd4195 LP |
244 | { NULL, NULL, NULL, NULL } |
245 | }; | |
246 | ||
42f4e3c4 LP |
247 | const |
248 | ||
87d1515d | 249 | char *t; |
3efd4195 | 250 | int r; |
87d1515d | 251 | void *state; |
42f4e3c4 | 252 | const char *sections[3]; |
3efd4195 LP |
253 | |
254 | assert(n); | |
5cb5a6ff | 255 | assert(n->meta.load_state == NAME_STUB); |
3efd4195 | 256 | |
42f4e3c4 LP |
257 | sections[0] = "Meta"; |
258 | sections[1] = section_table[n->meta.type]; | |
259 | sections[2] = NULL; | |
260 | ||
87d1515d | 261 | SET_FOREACH(t, n->meta.names, state) |
42f4e3c4 | 262 | if ((r = config_parse(t, sections, items, n)) < 0) |
3efd4195 LP |
263 | goto fail; |
264 | ||
87d1515d | 265 | r = 0; |
3efd4195 LP |
266 | |
267 | fail: | |
87d1515d | 268 | return r; |
3efd4195 | 269 | } |