]> git.proxmox.com Git - mirror_corosync.git/blame - exec/coroparse.c
coroparse: Fix remove_whitespace end condition
[mirror_corosync.git] / exec / coroparse.c
CommitLineData
2f552719 1/*
bc47c583 2 * Copyright (c) 2006-2013 Red Hat, Inc.
2f552719
SD
3 *
4 * All rights reserved.
5 *
6 * Author: Patrick Caulfield (pcaulfie@redhat.com)
8a45e2b1 7 * Jan Friesse (jfriesse@redhat.com)
2f552719
SD
8 *
9 * This software licensed under BSD license, the text of which follows:
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
34 */
031c02f5
FDN
35
36#include <config.h>
37
2f552719
SD
38#include <sys/types.h>
39#include <sys/uio.h>
40#include <sys/socket.h>
1e0d40cd 41#include <sys/stat.h>
2f552719
SD
42#include <sys/un.h>
43#include <netinet/in.h>
44#include <arpa/inet.h>
45#include <unistd.h>
46#include <fcntl.h>
47#include <stdlib.h>
48#include <stdio.h>
49#include <errno.h>
2f552719 50#include <string.h>
ae229831 51#include <dirent.h>
6fd822c4 52#include <limits.h>
2290913d 53#include <stddef.h>
8a45e2b1
JF
54#include <grp.h>
55#include <pwd.h>
2f552719 56
b4c06e52 57#include <qb/qblist.h>
37e17e7a 58#include <qb/qbutil.h>
00434a4f 59#define LOGSYS_UTILS_ONLY 1
8ad583a5 60#include <corosync/logsys.h>
6f5e3293 61#include <corosync/icmap.h>
e1f53138 62
f763d3ba 63#include "main.h"
2f552719
SD
64#include "util.h"
65
8a45e2b1
JF
66enum parser_cb_type {
67 PARSER_CB_START,
68 PARSER_CB_END,
69 PARSER_CB_SECTION_START,
70 PARSER_CB_SECTION_END,
71 PARSER_CB_ITEM,
72};
73
8a45e2b1
JF
74enum main_cp_cb_data_state {
75 MAIN_CP_CB_DATA_STATE_NORMAL,
76 MAIN_CP_CB_DATA_STATE_TOTEM,
77 MAIN_CP_CB_DATA_STATE_INTERFACE,
78 MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS,
79 MAIN_CP_CB_DATA_STATE_UIDGID,
80 MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON,
81 MAIN_CP_CB_DATA_STATE_MEMBER,
82 MAIN_CP_CB_DATA_STATE_QUORUM,
cb5fd775 83 MAIN_CP_CB_DATA_STATE_QDEVICE,
6d0b0b14
JF
84 MAIN_CP_CB_DATA_STATE_NODELIST,
85 MAIN_CP_CB_DATA_STATE_NODELIST_NODE,
3cd4f9a1 86 MAIN_CP_CB_DATA_STATE_PLOAD,
39cd6b3d 87 MAIN_CP_CB_DATA_STATE_QB,
88 MAIN_CP_CB_DATA_STATE_RESOURCES,
89 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM,
90 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS,
91 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED,
92 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
8a45e2b1
JF
93};
94
aab55a00
CC
95typedef int (*parser_cb_f)(const char *path,
96 char *key,
97 char *value,
98 enum main_cp_cb_data_state *state,
99 enum parser_cb_type type,
100 const char **error_string,
101 icmap_map_t config_map,
102 void *user_data);
103
8a45e2b1
JF
104struct key_value_list_item {
105 char *key;
106 char *value;
b4c06e52 107 struct qb_list_head list;
8a45e2b1
JF
108};
109
110struct main_cp_cb_data {
268cde6e 111 int linknumber;
8a45e2b1
JF
112 char *bindnetaddr;
113 char *mcastaddr;
114 char *broadcast;
115 int mcastport;
116 int ttl;
268cde6e
CC
117 int knet_link_priority;
118 int knet_ping_interval;
119 int knet_ping_timeout;
120 int knet_ping_precision;
7cec6a13
CC
121 int knet_pong_count;
122 int knet_pmtud_interval;
c0f1d576 123 char *knet_transport;
8a45e2b1 124
b4c06e52 125 struct qb_list_head logger_subsys_items_head;
8a45e2b1
JF
126 char *subsys;
127 char *logging_daemon_name;
b4c06e52 128 struct qb_list_head member_items_head;
6d0b0b14
JF
129
130 int node_number;
8a45e2b1
JF
131};
132
133static int read_config_file_into_icmap(
bc47c583 134 const char **error_string, icmap_map_t config_map);
2f552719
SD
135static char error_string_response[512];
136
8a45e2b1
JF
137static int uid_determine (const char *req_user)
138{
139 int pw_uid = 0;
140 struct passwd passwd;
141 struct passwd* pwdptr = &passwd;
142 struct passwd* temp_pwd_pt;
143 char *pwdbuffer;
005e7fd3 144 int pwdlinelen, rc;
86b074dc
JF
145 long int id;
146 char *ep;
147
148 id = strtol(req_user, &ep, 10);
f05d1c92 149 if (*req_user != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
86b074dc
JF
150 return (id);
151 }
8a45e2b1
JF
152
153 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
154
155 if (pwdlinelen == -1) {
156 pwdlinelen = 256;
157 }
158
159 pwdbuffer = malloc (pwdlinelen);
160
005e7fd3
AB
161 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
162 char *n;
163
164 pwdlinelen *= 2;
165 if (pwdlinelen <= 32678) {
166 n = realloc (pwdbuffer, pwdlinelen);
167 if (n != NULL) {
168 pwdbuffer = n;
169 continue;
52f88d04
JF
170 }
171 }
005e7fd3
AB
172 }
173 if (rc != 0) {
174 free (pwdbuffer);
175 sprintf (error_string_response, "getpwnam_r(): %s", strerror(rc));
176 return (-1);
177 }
178 if (temp_pwd_pt == NULL) {
52f88d04 179 free (pwdbuffer);
8a45e2b1
JF
180 sprintf (error_string_response,
181 "The '%s' user is not found in /etc/passwd, please read the documentation.",
182 req_user);
183 return (-1);
184 }
185 pw_uid = passwd.pw_uid;
186 free (pwdbuffer);
187
188 return pw_uid;
189}
190
191static int gid_determine (const char *req_group)
192{
7c8e83ac 193 int corosync_gid = 0;
8a45e2b1
JF
194 struct group group;
195 struct group * grpptr = &group;
196 struct group * temp_grp_pt;
197 char *grpbuffer;
005e7fd3 198 int grplinelen, rc;
86b074dc
JF
199 long int id;
200 char *ep;
201
202 id = strtol(req_group, &ep, 10);
f05d1c92 203 if (*req_group != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
86b074dc
JF
204 return (id);
205 }
8a45e2b1
JF
206
207 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
208
209 if (grplinelen == -1) {
210 grplinelen = 256;
211 }
212
213 grpbuffer = malloc (grplinelen);
214
005e7fd3
AB
215 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
216 char *n;
217
218 grplinelen *= 2;
219 if (grplinelen <= 32678) {
220 n = realloc (grpbuffer, grplinelen);
221 if (n != NULL) {
222 grpbuffer = n;
223 continue;
52f88d04
JF
224 }
225 }
005e7fd3
AB
226 }
227 if (rc != 0) {
228 free (grpbuffer);
229 sprintf (error_string_response, "getgrnam_r(): %s", strerror(rc));
230 return (-1);
231 }
232 if (temp_grp_pt == NULL) {
52f88d04 233 free (grpbuffer);
8a45e2b1
JF
234 sprintf (error_string_response,
235 "The '%s' group is not found in /etc/group, please read the documentation.",
236 req_group);
237 return (-1);
238 }
7c8e83ac 239 corosync_gid = group.gr_gid;
8a45e2b1 240 free (grpbuffer);
2f552719 241
7c8e83ac 242 return corosync_gid;
8a45e2b1 243}
3ffb151a
FDN
244static char *strchr_rs (const char *haystack, int byte)
245{
246 const char *end_address = strchr (haystack, byte);
247 if (end_address) {
248 end_address += 1; /* skip past { or = */
8a45e2b1
JF
249
250 while (*end_address == ' ' || *end_address == '\t')
251 end_address++;
3ffb151a
FDN
252 }
253
254 return ((char *) end_address);
255}
256
bc47c583 257int coroparse_configparse (icmap_map_t config_map, const char **error_string)
2f552719 258{
bc47c583 259 if (read_config_file_into_icmap(error_string, config_map)) {
2f552719
SD
260 return -1;
261 }
262
263 return 0;
264}
265
663489d2 266static char *remove_whitespace(char *string, int remove_colon_and_brace)
2f552719 267{
8a45e2b1
JF
268 char *start;
269 char *end;
2f552719 270
8a45e2b1
JF
271 start = string;
272 while (*start == ' ' || *start == '\t')
273 start++;
274
275 end = start+(strlen(start))-1;
663489d2 276 while ((*end == ' ' || *end == '\t' || (remove_colon_and_brace && (*end == ':' || *end == '{'))) && end > start)
2f552719 277 end--;
7a4725f9
JF
278 if (*end != '\0')
279 *(end + 1) = '\0';
2f552719
SD
280
281 return start;
282}
283
ae229831 284
ae229831 285
2f552719 286static int parse_section(FILE *fp,
8a45e2b1 287 char *path,
ae229831 288 const char **error_string,
66172a50 289 int depth,
aab55a00 290 enum main_cp_cb_data_state state,
8a45e2b1 291 parser_cb_f parser_cb,
bc47c583 292 icmap_map_t config_map,
8a45e2b1 293 void *user_data)
2f552719
SD
294{
295 char line[512];
296 int i;
297 char *loc;
99db3567 298 int ignore_line;
8a45e2b1
JF
299 char new_keyname[ICMAP_KEYNAME_MAXLEN];
300
301 if (strcmp(path, "") == 0) {
aab55a00 302 parser_cb("", NULL, NULL, &state, PARSER_CB_START, error_string, config_map, user_data);
8a45e2b1 303 }
2f552719 304
94b64352
JF
305 while (fgets (line, sizeof (line), fp)) {
306 if (strlen(line) > 0) {
20bd68b3
JF
307 /*
308 * Check if complete line was read. Use feof to handle files
309 * without ending \n at the end of the file
310 */
311 if ((line[strlen(line) - 1] != '\n') && !feof(fp)) {
312 *error_string = "parser error: Line too long";
313 return -1;
314 }
315
94b64352
JF
316 if (line[strlen(line) - 1] == '\n')
317 line[strlen(line) - 1] = '\0';
318 if (strlen (line) > 0 && line[strlen(line) - 1] == '\r')
319 line[strlen(line) - 1] = '\0';
320 }
2f552719
SD
321 /*
322 * Clear out white space and tabs
323 */
324 for (i = strlen (line) - 1; i > -1; i--) {
325 if (line[i] == '\t' || line[i] == ' ') {
326 line[i] = '\0';
327 } else {
328 break;
329 }
330 }
99db3567
JF
331
332 ignore_line = 1;
333 for (i = 0; i < strlen (line); i++) {
334 if (line[i] != '\t' && line[i] != ' ') {
335 if (line[i] != '#')
336 ignore_line = 0;
337
338 break;
339 }
340 }
2f552719
SD
341 /*
342 * Clear out comments and empty lines
343 */
99db3567 344 if (ignore_line) {
2f552719
SD
345 continue;
346 }
347
348 /* New section ? */
283011c6 349 if ((loc = strchr_rs (line, '{'))) {
663489d2 350 char *section = remove_whitespace(line, 1);
aab55a00 351 enum main_cp_cb_data_state newstate;
2f552719
SD
352
353 loc--;
354 *loc = '\0';
8a45e2b1 355
675da757
JF
356 if (strlen(path) + strlen(section) + 1 >= ICMAP_KEYNAME_MAXLEN) {
357 *error_string = "parser error: Start of section makes total cmap path too long";
358 return -1;
359 }
8a45e2b1
JF
360 strcpy(new_keyname, path);
361 if (strcmp(path, "") != 0) {
362 strcat(new_keyname, ".");
ae229831 363 }
8a45e2b1 364 strcat(new_keyname, section);
ae229831 365
aab55a00
CC
366 /* Only use the new state for items further down the stack */
367 newstate = state;
368 if (!parser_cb(new_keyname, NULL, NULL, &newstate, PARSER_CB_SECTION_START, error_string, config_map, user_data)) {
8a45e2b1
JF
369 return -1;
370 }
371
aab55a00 372 if (parse_section(fp, new_keyname, error_string, depth + 1, newstate, parser_cb, config_map, user_data))
2f552719 373 return -1;
663489d2
JF
374
375 continue ;
2f552719
SD
376 }
377
378 /* New key/value */
283011c6 379 if ((loc = strchr_rs (line, ':'))) {
2f552719
SD
380 char *key;
381 char *value;
382
383 *(loc-1) = '\0';
663489d2
JF
384 key = remove_whitespace(line, 1);
385 value = remove_whitespace(loc, 0);
8a45e2b1 386
675da757
JF
387 if (strlen(path) + strlen(key) + 1 >= ICMAP_KEYNAME_MAXLEN) {
388 *error_string = "parser error: New key makes total cmap path too long";
389 return -1;
390 }
8a45e2b1
JF
391 strcpy(new_keyname, path);
392 if (strcmp(path, "") != 0) {
393 strcat(new_keyname, ".");
394 }
395 strcat(new_keyname, key);
396
aab55a00 397 if (!parser_cb(new_keyname, key, value, &state, PARSER_CB_ITEM, error_string, config_map, user_data)) {
8a45e2b1 398 return -1;
ae229831 399 }
663489d2
JF
400
401 continue ;
2f552719
SD
402 }
403
8236a087 404 if (strchr_rs (line, '}')) {
66172a50
JF
405 if (depth == 0) {
406 *error_string = "parser error: Unexpected closing brace";
407
408 return -1;
409 }
410
aab55a00 411 if (!parser_cb(path, NULL, NULL, &state, PARSER_CB_SECTION_END, error_string, config_map, user_data)) {
8a45e2b1
JF
412 return -1;
413 }
414
2f552719
SD
415 return 0;
416 }
417 }
418
8a45e2b1 419 if (strcmp(path, "") != 0) {
66172a50 420 *error_string = "parser error: Missing closing brace";
2f552719
SD
421 return -1;
422 }
423
8a45e2b1 424 if (strcmp(path, "") == 0) {
aab55a00 425 parser_cb("", NULL, NULL, &state, PARSER_CB_END, error_string, config_map, user_data);
8a45e2b1
JF
426 }
427
2f552719
SD
428 return 0;
429}
430
4e9716ed 431static int safe_atoq_range(icmap_value_types_t value_type, long long int *min_val, long long int *max_val)
0929dcb6 432{
4e9716ed
JF
433 switch (value_type) {
434 case ICMAP_VALUETYPE_INT8: *min_val = INT8_MIN; *max_val = INT8_MAX; break;
435 case ICMAP_VALUETYPE_UINT8: *min_val = 0; *max_val = UINT8_MAX; break;
436 case ICMAP_VALUETYPE_INT16: *min_val = INT16_MIN; *max_val = INT16_MAX; break;
437 case ICMAP_VALUETYPE_UINT16: *min_val = 0; *max_val = UINT16_MAX; break;
438 case ICMAP_VALUETYPE_INT32: *min_val = INT32_MIN; *max_val = INT32_MAX; break;
439 case ICMAP_VALUETYPE_UINT32: *min_val = 0; *max_val = UINT32_MAX; break;
440 default:
441 return (-1);
442 }
443
444 return (0);
445}
446
447/*
448 * Convert string str to long long int res. Type of result is target_type and currently only
449 * ICMAP_VALUETYPE_[U]INT[8|16|32] is supported.
450 * Return 0 on success, -1 on failure.
451 */
452static int safe_atoq(const char *str, long long int *res, icmap_value_types_t target_type)
453{
454 long long int val;
455 long long int min_val, max_val;
0929dcb6
JF
456 char *endptr;
457
458 errno = 0;
459
4e9716ed 460 val = strtoll(str, &endptr, 10);
0929dcb6
JF
461 if (errno == ERANGE) {
462 return (-1);
463 }
464
465 if (endptr == str) {
466 return (-1);
467 }
468
469 if (*endptr != '\0') {
470 return (-1);
471 }
472
4e9716ed
JF
473 if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
474 return (-1);
475 }
476
477 if (val < min_val || val > max_val) {
478 return (-1);
479 }
480
0929dcb6
JF
481 *res = val;
482 return (0);
483}
484
6825c1d3
JF
485static int str_to_ull(const char *str, unsigned long long int *res)
486{
487 unsigned long long int val;
488 char *endptr;
489
490 errno = 0;
491
492 val = strtoull(str, &endptr, 10);
493 if (errno == ERANGE) {
494 return (-1);
495 }
496
497 if (endptr == str) {
498 return (-1);
499 }
500
501 if (*endptr != '\0') {
502 return (-1);
503 }
504
505 *res = val;
506 return (0);
507}
0929dcb6 508
8a45e2b1
JF
509static int main_config_parser_cb(const char *path,
510 char *key,
511 char *value,
aab55a00 512 enum main_cp_cb_data_state *state,
8a45e2b1
JF
513 enum parser_cb_type type,
514 const char **error_string,
bc47c583 515 icmap_map_t config_map,
8a45e2b1 516 void *user_data)
ae229831 517{
4e9716ed
JF
518 int ii;
519 long long int val;
520 long long int min_val, max_val;
521 icmap_value_types_t val_type = ICMAP_VALUETYPE_BINARY;
6825c1d3 522 unsigned long long int ull;
8a45e2b1
JF
523 int add_as_string;
524 char key_name[ICMAP_KEYNAME_MAXLEN];
0929dcb6 525 static char formated_err[256];
8a45e2b1
JF
526 struct main_cp_cb_data *data = (struct main_cp_cb_data *)user_data;
527 struct key_value_list_item *kv_item;
1f90c31b 528 struct qb_list_head *iter, *tmp_iter;
8a45e2b1 529 int uid, gid;
ffb759cd
JF
530 cs_error_t cs_err;
531
532 cs_err = CS_OK;
8a45e2b1
JF
533
534 switch (type) {
535 case PARSER_CB_START:
536 memset(data, 0, sizeof(struct main_cp_cb_data));
aab55a00 537 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1
JF
538 break;
539 case PARSER_CB_END:
540 break;
541 case PARSER_CB_ITEM:
542 add_as_string = 1;
543
aab55a00 544 switch (*state) {
8a45e2b1
JF
545 case MAIN_CP_CB_DATA_STATE_NORMAL:
546 break;
eb3d49ef
FDN
547 case MAIN_CP_CB_DATA_STATE_PLOAD:
548 if ((strcmp(path, "pload.count") == 0) ||
549 (strcmp(path, "pload.size") == 0)) {
4e9716ed
JF
550 val_type = ICMAP_VALUETYPE_UINT32;
551 if (safe_atoq(value, &val, val_type) != 0) {
eb3d49ef
FDN
552 goto atoi_error;
553 }
ffb759cd
JF
554 if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
555 goto icmap_set_error;
556 }
eb3d49ef
FDN
557 add_as_string = 0;
558 }
559 break;
8a45e2b1
JF
560 case MAIN_CP_CB_DATA_STATE_QUORUM:
561 if ((strcmp(path, "quorum.expected_votes") == 0) ||
562 (strcmp(path, "quorum.votes") == 0) ||
10098dba 563 (strcmp(path, "quorum.last_man_standing_window") == 0) ||
8a45e2b1 564 (strcmp(path, "quorum.leaving_timeout") == 0)) {
4e9716ed
JF
565 val_type = ICMAP_VALUETYPE_UINT32;
566 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
567 goto atoi_error;
568 }
ffb759cd
JF
569 if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
570 goto icmap_set_error;
571 }
8a45e2b1
JF
572 add_as_string = 0;
573 }
574
9589611d 575 if ((strcmp(path, "quorum.two_node") == 0) ||
ff6a43ed 576 (strcmp(path, "quorum.expected_votes_tracking") == 0) ||
2d7a8ab2 577 (strcmp(path, "quorum.allow_downscale") == 0) ||
e8d0af0b 578 (strcmp(path, "quorum.wait_for_all") == 0) ||
b41372c6 579 (strcmp(path, "quorum.auto_tie_breaker") == 0) ||
769fc913 580 (strcmp(path, "quorum.last_man_standing") == 0)) {
4e9716ed
JF
581 val_type = ICMAP_VALUETYPE_UINT8;
582 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
583 goto atoi_error;
584 }
ffb759cd
JF
585 if ((cs_err = icmap_set_uint8_r(config_map, path, val)) != CS_OK) {
586 goto icmap_set_error;
587 }
8a45e2b1
JF
588 add_as_string = 0;
589 }
590 break;
cb5fd775
FDN
591 case MAIN_CP_CB_DATA_STATE_QDEVICE:
592 if ((strcmp(path, "quorum.device.timeout") == 0) ||
17488909 593 (strcmp(path, "quorum.device.sync_timeout") == 0) ||
cb5fd775 594 (strcmp(path, "quorum.device.votes") == 0)) {
4e9716ed
JF
595 val_type = ICMAP_VALUETYPE_UINT32;
596 if (safe_atoq(value, &val, val_type) != 0) {
cb5fd775
FDN
597 goto atoi_error;
598 }
ffb759cd
JF
599 if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
600 goto icmap_set_error;
601 }
cb5fd775
FDN
602 add_as_string = 0;
603 }
86dd11b2 604 if ((strcmp(path, "quorum.device.master_wins") == 0)) {
4e9716ed
JF
605 val_type = ICMAP_VALUETYPE_UINT8;
606 if (safe_atoq(value, &val, val_type) != 0) {
86dd11b2
FDN
607 goto atoi_error;
608 }
ffb759cd
JF
609 if ((cs_err = icmap_set_uint8_r(config_map, path, val)) != CS_OK) {
610 goto icmap_set_error;
611 }
86dd11b2
FDN
612 add_as_string = 0;
613 }
ce9c69da 614 break;
8a45e2b1
JF
615 case MAIN_CP_CB_DATA_STATE_TOTEM:
616 if ((strcmp(path, "totem.version") == 0) ||
617 (strcmp(path, "totem.nodeid") == 0) ||
618 (strcmp(path, "totem.threads") == 0) ||
619 (strcmp(path, "totem.token") == 0) ||
58176d67 620 (strcmp(path, "totem.token_coefficient") == 0) ||
8a45e2b1 621 (strcmp(path, "totem.token_retransmit") == 0) ||
3f7d2cf6 622 (strcmp(path, "totem.token_warning") == 0) ||
8a45e2b1
JF
623 (strcmp(path, "totem.hold") == 0) ||
624 (strcmp(path, "totem.token_retransmits_before_loss_const") == 0) ||
625 (strcmp(path, "totem.join") == 0) ||
626 (strcmp(path, "totem.send_join") == 0) ||
627 (strcmp(path, "totem.consensus") == 0) ||
628 (strcmp(path, "totem.merge") == 0) ||
629 (strcmp(path, "totem.downcheck") == 0) ||
630 (strcmp(path, "totem.fail_recv_const") == 0) ||
631 (strcmp(path, "totem.seqno_unchanged_const") == 0) ||
632 (strcmp(path, "totem.rrp_token_expired_timeout") == 0) ||
633 (strcmp(path, "totem.rrp_problem_count_timeout") == 0) ||
634 (strcmp(path, "totem.rrp_problem_count_threshold") == 0) ||
635 (strcmp(path, "totem.rrp_problem_count_mcast_threshold") == 0) ||
636 (strcmp(path, "totem.rrp_autorecovery_check_timeout") == 0) ||
637 (strcmp(path, "totem.heartbeat_failures_allowed") == 0) ||
638 (strcmp(path, "totem.max_network_delay") == 0) ||
639 (strcmp(path, "totem.window_size") == 0) ||
640 (strcmp(path, "totem.max_messages") == 0) ||
641 (strcmp(path, "totem.miss_count_const") == 0) ||
7cec6a13 642 (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
16f616b6 643 (strcmp(path, "totem.knet_compression_threshold") == 0) ||
8a45e2b1 644 (strcmp(path, "totem.netmtu") == 0)) {
4e9716ed
JF
645 val_type = ICMAP_VALUETYPE_UINT32;
646 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
647 goto atoi_error;
648 }
ffb759cd
JF
649 if ((cs_err = icmap_set_uint32_r(config_map,path, val)) != CS_OK) {
650 goto icmap_set_error;
651 }
8a45e2b1
JF
652 add_as_string = 0;
653 }
16f616b6
CC
654 if (strcmp(path, "totem.knet_compression_level") == 0) {
655 val_type = ICMAP_VALUETYPE_INT32;
656 if (safe_atoq(value, &val, val_type) != 0) {
657 goto atoi_error;
658 }
ffb759cd
JF
659 if ((cs_err = icmap_set_int32_r(config_map, path, val)) != CS_OK) {
660 goto icmap_set_error;
661 }
16f616b6
CC
662 add_as_string = 0;
663 }
6825c1d3
JF
664 if (strcmp(path, "totem.config_version") == 0) {
665 if (str_to_ull(value, &ull) != 0) {
666 goto atoi_error;
667 }
ffb759cd
JF
668 if ((cs_err = icmap_set_uint64_r(config_map, path, ull)) != CS_OK) {
669 goto icmap_set_error;
670 }
6825c1d3
JF
671 add_as_string = 0;
672 }
dd588d00
JF
673 if (strcmp(path, "totem.ip_version") == 0) {
674 if ((strcmp(value, "ipv4") != 0) &&
675 (strcmp(value, "ipv6") != 0)) {
676 *error_string = "Invalid ip_version type";
677
678 return (0);
679 }
680 }
8cdd2fc4
JF
681 if (strcmp(path, "totem.crypto_type") == 0) {
682 if ((strcmp(value, "nss") != 0) &&
20c58715
FDN
683 (strcmp(value, "aes256") != 0) &&
684 (strcmp(value, "aes192") != 0) &&
685 (strcmp(value, "aes128") != 0) &&
686 (strcmp(value, "3des") != 0)) {
8cdd2fc4
JF
687 *error_string = "Invalid crypto type";
688
689 return (0);
690 }
691 }
ab1675f0
JF
692 if (strcmp(path, "totem.crypto_cipher") == 0) {
693 if ((strcmp(value, "none") != 0) &&
20c58715
FDN
694 (strcmp(value, "aes256") != 0) &&
695 (strcmp(value, "aes192") != 0) &&
696 (strcmp(value, "aes128") != 0) &&
697 (strcmp(value, "3des") != 0)) {
ab1675f0
JF
698 *error_string = "Invalid cipher type";
699
700 return (0);
701 }
702 }
703 if (strcmp(path, "totem.crypto_hash") == 0) {
704 if ((strcmp(value, "none") != 0) &&
e57b5b9e 705 (strcmp(value, "md5") != 0) &&
4a2d5036 706 (strcmp(value, "sha1") != 0) &&
4a2d5036
FDN
707 (strcmp(value, "sha256") != 0) &&
708 (strcmp(value, "sha384") != 0) &&
709 (strcmp(value, "sha512") != 0)) {
ab1675f0
JF
710 *error_string = "Invalid hash type";
711
712 return (0);
713 }
714 }
a919908e
SD
715 break;
716
3cd4f9a1
JF
717 case MAIN_CP_CB_DATA_STATE_QB:
718 if (strcmp(path, "qb.ipc_type") == 0) {
719 if ((strcmp(value, "native") != 0) &&
720 (strcmp(value, "shm") != 0) &&
721 (strcmp(value, "socket") != 0)) {
722 *error_string = "Invalid qb ipc_type";
723
724 return (0);
725 }
726 }
727 break;
728
8a45e2b1 729 case MAIN_CP_CB_DATA_STATE_INTERFACE:
268cde6e 730 if (strcmp(path, "totem.interface.linknumber") == 0) {
4e9716ed
JF
731 val_type = ICMAP_VALUETYPE_UINT8;
732 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
733 goto atoi_error;
734 }
735
268cde6e 736 data->linknumber = val;
8a45e2b1
JF
737 add_as_string = 0;
738 }
739 if (strcmp(path, "totem.interface.bindnetaddr") == 0) {
740 data->bindnetaddr = strdup(value);
741 add_as_string = 0;
742 }
743 if (strcmp(path, "totem.interface.mcastaddr") == 0) {
744 data->mcastaddr = strdup(value);
745 add_as_string = 0;
746 }
747 if (strcmp(path, "totem.interface.broadcast") == 0) {
748 data->broadcast = strdup(value);
749 add_as_string = 0;
750 }
751 if (strcmp(path, "totem.interface.mcastport") == 0) {
4e9716ed
JF
752 val_type = ICMAP_VALUETYPE_UINT16;
753 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
754 goto atoi_error;
755 }
4e9716ed 756 data->mcastport = val;
8a45e2b1
JF
757 add_as_string = 0;
758 }
759 if (strcmp(path, "totem.interface.ttl") == 0) {
4e9716ed
JF
760 val_type = ICMAP_VALUETYPE_UINT8;
761 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
762 goto atoi_error;
763 }
4e9716ed 764 data->ttl = val;
8a45e2b1
JF
765 add_as_string = 0;
766 }
268cde6e
CC
767 if (strcmp(path, "totem.interface.knet_link_priority") == 0) {
768 val_type = ICMAP_VALUETYPE_UINT8;
769 if (safe_atoq(value, &val, val_type) != 0) {
770 goto atoi_error;
771 }
772 data->knet_link_priority = val;
773 add_as_string = 0;
774 }
775 if (strcmp(path, "totem.interface.knet_ping_interval") == 0) {
776 val_type = ICMAP_VALUETYPE_UINT32;
777 if (safe_atoq(value, &val, val_type) != 0) {
778 goto atoi_error;
779 }
780 data->knet_ping_interval = val;
781 add_as_string = 0;
782 }
783 if (strcmp(path, "totem.interface.knet_ping_timeout") == 0) {
784 val_type = ICMAP_VALUETYPE_UINT32;
785 if (safe_atoq(value, &val, val_type) != 0) {
786 goto atoi_error;
787 }
788 data->knet_ping_timeout = val;
789 add_as_string = 0;
790 }
791 if (strcmp(path, "totem.interface.knet_ping_precision") == 0) {
792 val_type = ICMAP_VALUETYPE_UINT32;
793 if (safe_atoq(value, &val, val_type) != 0) {
794 goto atoi_error;
795 }
796 data->knet_ping_precision = val;
797 add_as_string = 0;
798 }
7cec6a13
CC
799 if (strcmp(path, "totem.interface.knet_pong_count") == 0) {
800 val_type = ICMAP_VALUETYPE_UINT32;
801 if (safe_atoq(value, &val, val_type) != 0) {
802 goto atoi_error;
803 }
804 data->knet_pong_count = val;
805 add_as_string = 0;
806 }
c0f1d576
CC
807 if (strcmp(path, "totem.interface.knet_transport") == 0) {
808 val_type = ICMAP_VALUETYPE_STRING;
809 data->knet_transport = strdup(value);
810 add_as_string = 0;
811 }
8a45e2b1
JF
812 break;
813 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
814 if (strcmp(key, "subsys") == 0) {
815 data->subsys = strdup(value);
816 if (data->subsys == NULL) {
817 *error_string = "Can't alloc memory";
818
819 return (0);
820 }
821 } else {
822 kv_item = malloc(sizeof(*kv_item));
823 if (kv_item == NULL) {
824 *error_string = "Can't alloc memory";
825
826 return (0);
827 }
828 memset(kv_item, 0, sizeof(*kv_item));
829
830 kv_item->key = strdup(key);
831 kv_item->value = strdup(value);
832 if (kv_item->key == NULL || kv_item->value == NULL) {
833 free(kv_item);
834 *error_string = "Can't alloc memory";
835
836 return (0);
837 }
b4c06e52
MJ
838 qb_list_init(&kv_item->list);
839 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
840 }
841 add_as_string = 0;
842 break;
843 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
844 if (strcmp(key, "subsys") == 0) {
845 data->subsys = strdup(value);
846 if (data->subsys == NULL) {
847 *error_string = "Can't alloc memory";
848
849 return (0);
850 }
851 } else if (strcmp(key, "name") == 0) {
852 data->logging_daemon_name = strdup(value);
853 if (data->logging_daemon_name == NULL) {
854 *error_string = "Can't alloc memory";
855
856 return (0);
857 }
858 } else {
859 kv_item = malloc(sizeof(*kv_item));
860 if (kv_item == NULL) {
861 *error_string = "Can't alloc memory";
862
863 return (0);
864 }
865 memset(kv_item, 0, sizeof(*kv_item));
866
867 kv_item->key = strdup(key);
868 kv_item->value = strdup(value);
869 if (kv_item->key == NULL || kv_item->value == NULL) {
870 free(kv_item);
871 *error_string = "Can't alloc memory";
872
873 return (0);
874 }
b4c06e52
MJ
875 qb_list_init(&kv_item->list);
876 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
877 }
878 add_as_string = 0;
879 break;
880 case MAIN_CP_CB_DATA_STATE_UIDGID:
881 if (strcmp(key, "uid") == 0) {
882 uid = uid_determine(value);
883 if (uid == -1) {
884 *error_string = error_string_response;
885 return (0);
886 }
f837f95d 887 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 888 uid);
ffb759cd
JF
889 if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
890 goto icmap_set_error;
891 }
8a45e2b1
JF
892 add_as_string = 0;
893 } else if (strcmp(key, "gid") == 0) {
894 gid = gid_determine(value);
895 if (gid == -1) {
896 *error_string = error_string_response;
897 return (0);
898 }
f837f95d 899 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 900 gid);
ffb759cd
JF
901 if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
902 goto icmap_set_error;
903 }
8a45e2b1
JF
904 add_as_string = 0;
905 } else {
906 *error_string = "uidgid: Only uid and gid are allowed items";
907 return (0);
908 }
909 break;
910 case MAIN_CP_CB_DATA_STATE_MEMBER:
911 if (strcmp(key, "memberaddr") != 0) {
912 *error_string = "Only memberaddr is allowed in member section";
913
914 return (0);
915 }
916
917 kv_item = malloc(sizeof(*kv_item));
918 if (kv_item == NULL) {
919 *error_string = "Can't alloc memory";
920
921 return (0);
922 }
923 memset(kv_item, 0, sizeof(*kv_item));
924
925 kv_item->key = strdup(key);
926 kv_item->value = strdup(value);
927 if (kv_item->key == NULL || kv_item->value == NULL) {
928 free(kv_item);
929 *error_string = "Can't alloc memory";
930
931 return (0);
932 }
b4c06e52
MJ
933 qb_list_init(&kv_item->list);
934 qb_list_add(&kv_item->list, &data->member_items_head);
8a45e2b1
JF
935 add_as_string = 0;
936 break;
6d0b0b14
JF
937 case MAIN_CP_CB_DATA_STATE_NODELIST:
938 break;
939 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
940 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.%s", data->node_number, key);
941 if ((strcmp(key, "nodeid") == 0) ||
942 (strcmp(key, "quorum_votes") == 0)) {
4e9716ed
JF
943 val_type = ICMAP_VALUETYPE_UINT32;
944 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
945 goto atoi_error;
946 }
947
ffb759cd
JF
948 if ((cs_err = icmap_set_uint32_r(config_map, key_name, val)) != CS_OK) {
949 goto icmap_set_error;
950 }
6d0b0b14
JF
951 add_as_string = 0;
952 }
953
6d0b0b14 954 if (add_as_string) {
ffb759cd
JF
955 if ((cs_err = icmap_set_string_r(config_map, key_name, value)) != CS_OK) {
956 goto icmap_set_error;
957 };
6d0b0b14
JF
958 add_as_string = 0;
959 }
960 break;
39cd6b3d 961 case MAIN_CP_CB_DATA_STATE_RESOURCES:
962 if (strcmp(key, "watchdog_timeout") == 0) {
963 val_type = ICMAP_VALUETYPE_UINT32;
964 if (safe_atoq(value, &val, val_type) != 0) {
965 goto atoi_error;
966 }
ffb759cd
JF
967 if ((cs_err = icmap_set_uint32_r(config_map,path, val)) != CS_OK) {
968 goto icmap_set_error;
969 }
39cd6b3d 970 add_as_string = 0;
971 }
972 break;
973 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
39cd6b3d 974 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
975 if (strcmp(key, "poll_period") == 0) {
976 if (str_to_ull(value, &ull) != 0) {
977 goto atoi_error;
978 }
ffb759cd
JF
979 if ((cs_err = icmap_set_uint64_r(config_map,path, ull)) != CS_OK) {
980 goto icmap_set_error;
981 }
39cd6b3d 982 add_as_string = 0;
983 }
984 break;
985 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
39cd6b3d 986 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
987 if (strcmp(key, "poll_period") == 0) {
988 if (str_to_ull(value, &ull) != 0) {
989 goto atoi_error;
990 }
ffb759cd
JF
991 if ((cs_err = icmap_set_uint64_r(config_map,path, ull)) != CS_OK) {
992 goto icmap_set_error;
993 }
39cd6b3d 994 add_as_string = 0;
995 }
996 break;
ae229831
JF
997 }
998
8a45e2b1 999 if (add_as_string) {
ffb759cd
JF
1000 if ((cs_err = icmap_set_string_r(config_map, path, value)) != CS_OK) {
1001 goto icmap_set_error;
1002 }
8a45e2b1
JF
1003 }
1004 break;
1005 case PARSER_CB_SECTION_START:
1006 if (strcmp(path, "totem.interface") == 0) {
aab55a00 1007 *state = MAIN_CP_CB_DATA_STATE_INTERFACE;
268cde6e 1008 data->linknumber = 0;
8a45e2b1
JF
1009 data->mcastport = -1;
1010 data->ttl = -1;
268cde6e
CC
1011 data->knet_link_priority = -1;
1012 data->knet_ping_interval = -1;
1013 data->knet_ping_timeout = -1;
1014 data->knet_ping_precision = -1;
7cec6a13 1015 data->knet_pong_count = -1;
c0f1d576 1016 data->knet_transport = NULL;
b4c06e52 1017 qb_list_init(&data->member_items_head);
8a45e2b1
JF
1018 };
1019 if (strcmp(path, "totem") == 0) {
aab55a00 1020 *state = MAIN_CP_CB_DATA_STATE_TOTEM;
8a45e2b1 1021 };
3cd4f9a1 1022 if (strcmp(path, "qb") == 0) {
aab55a00 1023 *state = MAIN_CP_CB_DATA_STATE_QB;
3cd4f9a1 1024 }
8a45e2b1 1025 if (strcmp(path, "logging.logger_subsys") == 0) {
aab55a00 1026 *state = MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS;
b4c06e52 1027 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
1028 data->subsys = NULL;
1029 }
1030 if (strcmp(path, "logging.logging_daemon") == 0) {
aab55a00 1031 *state = MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON;
b4c06e52 1032 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
1033 data->subsys = NULL;
1034 data->logging_daemon_name = NULL;
1035 }
1036 if (strcmp(path, "uidgid") == 0) {
aab55a00 1037 *state = MAIN_CP_CB_DATA_STATE_UIDGID;
ae229831 1038 }
8a45e2b1 1039 if (strcmp(path, "totem.interface.member") == 0) {
aab55a00 1040 *state = MAIN_CP_CB_DATA_STATE_MEMBER;
8a45e2b1
JF
1041 }
1042 if (strcmp(path, "quorum") == 0) {
aab55a00 1043 *state = MAIN_CP_CB_DATA_STATE_QUORUM;
8a45e2b1 1044 }
cb5fd775 1045 if (strcmp(path, "quorum.device") == 0) {
aab55a00 1046 *state = MAIN_CP_CB_DATA_STATE_QDEVICE;
cb5fd775 1047 }
6d0b0b14 1048 if (strcmp(path, "nodelist") == 0) {
aab55a00 1049 *state = MAIN_CP_CB_DATA_STATE_NODELIST;
6d0b0b14
JF
1050 data->node_number = 0;
1051 }
1052 if (strcmp(path, "nodelist.node") == 0) {
aab55a00 1053 *state = MAIN_CP_CB_DATA_STATE_NODELIST_NODE;
6d0b0b14 1054 }
39cd6b3d 1055 if (strcmp(path, "resources") == 0) {
1056 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1057 }
1058 if (strcmp(path, "resources.system") == 0) {
1059 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1060 }
1061 if (strcmp(path, "resources.system.memory_used") == 0) {
1062 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED;
1063 }
1064 if (strcmp(path, "resources.process") == 0) {
1065 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1066 }
1067 if (strcmp(path, "resources.process.memory_used") == 0) {
1068 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED;
1069 }
8a45e2b1
JF
1070 break;
1071 case PARSER_CB_SECTION_END:
aab55a00 1072 switch (*state) {
8a45e2b1
JF
1073 case MAIN_CP_CB_DATA_STATE_INTERFACE:
1074 /*
1075 * Create new interface section
1076 */
1077 if (data->bindnetaddr != NULL) {
1078 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr",
268cde6e 1079 data->linknumber);
ffb759cd 1080 cs_err = icmap_set_string_r(config_map, key_name, data->bindnetaddr);
8a45e2b1
JF
1081
1082 free(data->bindnetaddr);
1083 data->bindnetaddr = NULL;
ffb759cd
JF
1084
1085 if (cs_err != CS_OK) {
1086 goto icmap_set_error;
1087 }
8a45e2b1
JF
1088 }
1089
1090 if (data->mcastaddr != NULL) {
1091 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr",
268cde6e 1092 data->linknumber);
ffb759cd 1093 cs_err = icmap_set_string_r(config_map, key_name, data->mcastaddr);
8a45e2b1
JF
1094
1095 free(data->mcastaddr);
1096 data->mcastaddr = NULL;
ffb759cd
JF
1097
1098 if (cs_err != CS_OK) {
1099 goto icmap_set_error;
1100 }
8a45e2b1
JF
1101 }
1102
1103 if (data->broadcast != NULL) {
1104 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast",
268cde6e 1105 data->linknumber);
ffb759cd 1106 cs_err = icmap_set_string_r(config_map, key_name, data->broadcast);
8a45e2b1
JF
1107
1108 free(data->broadcast);
1109 data->broadcast = NULL;
ffb759cd
JF
1110
1111 if (cs_err != CS_OK) {
1112 goto icmap_set_error;
1113 }
8a45e2b1
JF
1114 }
1115
1116 if (data->mcastport > -1) {
1117 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport",
268cde6e 1118 data->linknumber);
ffb759cd
JF
1119 if ((cs_err = icmap_set_uint16_r(config_map, key_name,
1120 data->mcastport)) != CS_OK) {
1121 goto icmap_set_error;
1122 }
8a45e2b1
JF
1123 }
1124
1125 if (data->ttl > -1) {
1126 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl",
268cde6e 1127 data->linknumber);
ffb759cd
JF
1128 if ((cs_err = icmap_set_uint8_r(config_map, key_name, data->ttl)) != CS_OK) {
1129 goto icmap_set_error;
1130 }
8a45e2b1 1131 }
268cde6e
CC
1132 if (data->knet_link_priority > -1) {
1133 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_link_priority",
1134 data->linknumber);
ffb759cd
JF
1135 if ((cs_err = icmap_set_uint8_r(config_map, key_name,
1136 data->knet_link_priority)) != CS_OK) {
1137 goto icmap_set_error;
1138 }
268cde6e
CC
1139 }
1140 if (data->knet_ping_interval > -1) {
1141 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_interval",
1142 data->linknumber);
ffb759cd
JF
1143 if ((cs_err = icmap_set_uint32_r(config_map, key_name,
1144 data->knet_ping_interval)) != CS_OK) {
1145 goto icmap_set_error;
1146 }
268cde6e
CC
1147 }
1148 if (data->knet_ping_timeout > -1) {
1149 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_timeout",
1150 data->linknumber);
ffb759cd
JF
1151 if ((cs_err = icmap_set_uint32_r(config_map, key_name,
1152 data->knet_ping_timeout)) != CS_OK) {
1153 goto icmap_set_error;
1154 }
268cde6e
CC
1155 }
1156 if (data->knet_ping_precision > -1) {
1157 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_precision",
1158 data->linknumber);
ffb759cd
JF
1159 if ((cs_err = icmap_set_uint32_r(config_map, key_name,
1160 data->knet_ping_precision)) != CS_OK) {
1161 goto icmap_set_error;
1162 }
268cde6e 1163 }
7cec6a13
CC
1164 if (data->knet_pong_count > -1) {
1165 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_pong_count",
1166 data->linknumber);
ffb759cd
JF
1167 if ((cs_err = icmap_set_uint32_r(config_map, key_name,
1168 data->knet_pong_count)) != CS_OK) {
1169 goto icmap_set_error;
1170 }
7cec6a13 1171 }
c0f1d576
CC
1172 if (data->knet_transport) {
1173 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_transport",
1174 data->linknumber);
ffb759cd 1175 cs_err = icmap_set_string_r(config_map, key_name, data->knet_transport);
c0f1d576 1176 free(data->knet_transport);
ffb759cd
JF
1177
1178 if (cs_err != CS_OK) {
1179 goto icmap_set_error;
1180 }
c0f1d576 1181 }
8a45e2b1 1182
4e9716ed 1183 ii = 0;
b4c06e52 1184
1f90c31b 1185 qb_list_for_each_safe(iter, tmp_iter, &(data->member_items_head)) {
b4c06e52 1186 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1187
1188 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u",
268cde6e 1189 data->linknumber, ii);
ffb759cd 1190 cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1191
8a45e2b1
JF
1192 free(kv_item->value);
1193 free(kv_item->key);
1194 free(kv_item);
4e9716ed 1195 ii++;
ffb759cd
JF
1196
1197 if (cs_err != CS_OK) {
1198 goto icmap_set_error;
1199 }
8a45e2b1
JF
1200 }
1201
3cd4f9a1 1202 break;
8a45e2b1
JF
1203 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
1204 if (data->subsys == NULL) {
1205 *error_string = "No subsys key in logger_subsys directive";
1206
1207 return (0);
1208 }
1209
1f90c31b 1210 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1211 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1212
1213 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s",
aab55a00 1214 data->subsys, kv_item->key);
ffb759cd 1215 cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1216
1217 free(kv_item->value);
1218 free(kv_item->key);
1219 free(kv_item);
ffb759cd
JF
1220
1221 if (cs_err != CS_OK) {
1222 goto icmap_set_error;
1223 }
8a45e2b1
JF
1224 }
1225
1226 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1227 data->subsys);
ffb759cd 1228 cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1229
1230 free(data->subsys);
1231
ffb759cd
JF
1232 if (cs_err != CS_OK) {
1233 goto icmap_set_error;
1234 }
8a45e2b1
JF
1235 break;
1236 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
1237 if (data->logging_daemon_name == NULL) {
1238 *error_string = "No name key in logging_daemon directive";
1239
1240 return (0);
1241 }
1242
1f90c31b 1243 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1244 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1245
1246 if (data->subsys == NULL) {
1247 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1248 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1249 "logging.%s",
1250 kv_item->key);
1251 } else {
1252 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1253 "logging.logging_daemon.%s.%s",
1254 data->logging_daemon_name, kv_item->key);
1255 }
1256 } else {
1257 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1258 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1259 "logging.logger_subsys.%s.%s",
1260 data->subsys,
1261 kv_item->key);
1262 } else {
1263 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1264 "logging.logging_daemon.%s.%s.%s",
1265 data->logging_daemon_name, data->subsys,
1266 kv_item->key);
1267 }
1268 }
ffb759cd 1269 cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1270
8a45e2b1
JF
1271 free(kv_item->value);
1272 free(kv_item->key);
1273 free(kv_item);
ffb759cd
JF
1274
1275 if (cs_err != CS_OK) {
1276 goto icmap_set_error;
1277 }
8a45e2b1
JF
1278 }
1279
1280 if (data->subsys == NULL) {
1281 if (strcmp(data->logging_daemon_name, "corosync") != 0) {
1282 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name",
1283 data->logging_daemon_name);
ffb759cd 1284 cs_err = icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1285 }
1286 } else {
1287 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1288 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1289 data->subsys);
ffb759cd 1290 cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1291
1292 } else {
1293 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.subsys",
1294 data->logging_daemon_name, data->subsys);
ffb759cd
JF
1295 cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
1296
1297 if (cs_err != CS_OK) {
1298 free(data->subsys);
1299 free(data->logging_daemon_name);
1300
1301 goto icmap_set_error;
1302 }
8a45e2b1
JF
1303 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name",
1304 data->logging_daemon_name, data->subsys);
ffb759cd 1305 cs_err = icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1306 }
1307 }
1308
1309 free(data->subsys);
1310 free(data->logging_daemon_name);
1311
ffb759cd
JF
1312 if (cs_err != CS_OK) {
1313 goto icmap_set_error;
1314 }
6d0b0b14
JF
1315 break;
1316 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
6d0b0b14 1317 data->node_number++;
aab55a00
CC
1318 break;
1319 case MAIN_CP_CB_DATA_STATE_NORMAL:
1320 case MAIN_CP_CB_DATA_STATE_PLOAD:
1321 case MAIN_CP_CB_DATA_STATE_UIDGID:
1322 case MAIN_CP_CB_DATA_STATE_MEMBER:
1323 case MAIN_CP_CB_DATA_STATE_QUORUM:
1324 case MAIN_CP_CB_DATA_STATE_QDEVICE:
1325 case MAIN_CP_CB_DATA_STATE_NODELIST:
1326 case MAIN_CP_CB_DATA_STATE_TOTEM:
1327 case MAIN_CP_CB_DATA_STATE_QB:
6d0b0b14 1328 break;
39cd6b3d 1329 case MAIN_CP_CB_DATA_STATE_RESOURCES:
1330 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
1331 break;
1332 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
1333 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1334 break;
1335 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
1336 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1337 break;
1338 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
1339 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1340 break;
1341 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
1342 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1343 break;
8a45e2b1
JF
1344 }
1345 break;
ae229831
JF
1346 }
1347
8a45e2b1 1348 return (1);
0929dcb6
JF
1349
1350atoi_error:
4e9716ed
JF
1351 min_val = max_val = 0;
1352 /*
1353 * This is really assert, because developer ether doesn't set val_type correctly or
1354 * we've got here after some nasty memory overwrite
1355 */
1356 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1357
0929dcb6 1358 snprintf(formated_err, sizeof(formated_err),
4e9716ed
JF
1359 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1360 key, min_val, max_val, value);
0929dcb6
JF
1361 *error_string = formated_err;
1362
ffb759cd
JF
1363 return (0);
1364
1365icmap_set_error:
1366 if (snprintf(formated_err, sizeof(formated_err),
1367 "Can't store key \"%s\" into icmap, returned error is %s",
1368 key, cs_strerror(cs_err)) >= sizeof(formated_err)) {
1369 *error_string = "Can't format parser error message";
1370 } else {
1371 *error_string = formated_err;
1372 }
1373
0929dcb6 1374 return (0);
8a45e2b1
JF
1375}
1376
1377static int uidgid_config_parser_cb(const char *path,
1378 char *key,
1379 char *value,
aab55a00 1380 enum main_cp_cb_data_state *state,
8a45e2b1
JF
1381 enum parser_cb_type type,
1382 const char **error_string,
bc47c583 1383 icmap_map_t config_map,
8a45e2b1
JF
1384 void *user_data)
1385{
1386 char key_name[ICMAP_KEYNAME_MAXLEN];
1387 int uid, gid;
ffb759cd
JF
1388 static char formated_err[256];
1389 cs_error_t cs_err;
1390
1391 cs_err = CS_OK;
8a45e2b1
JF
1392
1393 switch (type) {
1394 case PARSER_CB_START:
1395 break;
1396 case PARSER_CB_END:
1397 break;
1398 case PARSER_CB_ITEM:
1399 if (strcmp(path, "uidgid.uid") == 0) {
1400 uid = uid_determine(value);
1401 if (uid == -1) {
1402 *error_string = error_string_response;
1403 return (0);
1404 }
f837f95d 1405 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 1406 uid);
ffb759cd
JF
1407 if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
1408 goto icmap_set_error;
1409 }
92ead610 1410 } else if (strcmp(path, "uidgid.gid") == 0) {
8a45e2b1
JF
1411 gid = gid_determine(value);
1412 if (gid == -1) {
1413 *error_string = error_string_response;
1414 return (0);
1415 }
f837f95d 1416 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 1417 gid);
ffb759cd
JF
1418 if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
1419 goto icmap_set_error;
1420 }
8a45e2b1 1421 } else {
ae229831 1422 *error_string = "uidgid: Only uid and gid are allowed items";
8a45e2b1 1423 return (0);
ae229831 1424 }
8a45e2b1
JF
1425 break;
1426 case PARSER_CB_SECTION_START:
1427 if (strcmp(path, "uidgid") != 0) {
3b8365e8 1428 *error_string = "uidgid: Can't add subsection different than uidgid";
8a45e2b1
JF
1429 return (0);
1430 };
1431 break;
1432 case PARSER_CB_SECTION_END:
1433 break;
ae229831 1434 }
2f552719 1435
8a45e2b1 1436 return (1);
ffb759cd
JF
1437
1438icmap_set_error:
1439 if (snprintf(formated_err, sizeof(formated_err),
1440 "Can't store key \"%s\" into icmap, returned error is %s",
1441 key, cs_strerror(cs_err)) >= sizeof(formated_err)) {
1442 *error_string = "Can't format parser error message";
1443 } else {
1444 *error_string = formated_err;
1445 }
1446
1447 return (0);
ae229831
JF
1448}
1449
8a45e2b1 1450static int read_uidgid_files_into_icmap(
bc47c583
CC
1451 const char **error_string,
1452 icmap_map_t config_map)
ae229831
JF
1453{
1454 FILE *fp;
1455 const char *dirname;
1456 DIR *dp;
1457 struct dirent *dirent;
1bd8aba6 1458 char filename[PATH_MAX + FILENAME_MAX + 1];
ae229831 1459 int res = 0;
1e0d40cd 1460 struct stat stat_buf;
aab55a00 1461 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1 1462 char key_name[ICMAP_KEYNAME_MAXLEN];
ae229831 1463
2135d91c 1464 dirname = COROSYSCONFDIR "/uidgid.d";
ae229831
JF
1465 dp = opendir (dirname);
1466
1467 if (dp == NULL)
1468 return 0;
1469
c83e6c7e
BL
1470 for (dirent = readdir(dp);
1471 dirent != NULL;
1472 dirent = readdir(dp)) {
2290913d 1473
1e0d40cd 1474 snprintf(filename, sizeof (filename), "%s/%s", dirname, dirent->d_name);
966f461b
JF
1475 res = stat (filename, &stat_buf);
1476 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
ae229831
JF
1477
1478 fp = fopen (filename, "r");
1479 if (fp == NULL) continue;
1480
8a45e2b1
JF
1481 key_name[0] = 0;
1482
aab55a00 1483 res = parse_section(fp, key_name, error_string, 0, state, uidgid_config_parser_cb, config_map, NULL);
ae229831
JF
1484
1485 fclose (fp);
1486
1487 if (res != 0) {
1488 goto error_exit;
1489 }
1490 }
1491 }
1492
1493error_exit:
1494 closedir(dp);
1495
1496 return res;
1497}
2f552719 1498
8a45e2b1
JF
1499/* Read config file and load into icmap */
1500static int read_config_file_into_icmap(
bc47c583
CC
1501 const char **error_string,
1502 icmap_map_t config_map)
2f552719
SD
1503{
1504 FILE *fp;
23c64c64 1505 const char *filename;
2f552719
SD
1506 char *error_reason = error_string_response;
1507 int res;
8a45e2b1
JF
1508 char key_name[ICMAP_KEYNAME_MAXLEN];
1509 struct main_cp_cb_data data;
aab55a00 1510 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
2f552719
SD
1511
1512 filename = getenv ("COROSYNC_MAIN_CONFIG_FILE");
1513 if (!filename)
2135d91c 1514 filename = COROSYSCONFDIR "/corosync.conf";
2f552719
SD
1515
1516 fp = fopen (filename, "r");
23c64c64 1517 if (fp == NULL) {
20f3331d 1518 char error_str[100];
37e17e7a 1519 const char *error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
870046d0 1520 snprintf (error_reason, sizeof(error_string_response),
3131601c 1521 "Can't read file %s reason = (%s)",
00434a4f 1522 filename, error_ptr);
2f552719
SD
1523 *error_string = error_reason;
1524 return -1;
1525 }
1526
8a45e2b1
JF
1527 key_name[0] = 0;
1528
aab55a00 1529 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
2f552719
SD
1530
1531 fclose(fp);
1532
ae229831 1533 if (res == 0) {
bc47c583 1534 res = read_uidgid_files_into_icmap(error_string, config_map);
ae229831
JF
1535 }
1536
94b64352
JF
1537 if (res == 0) {
1538 snprintf (error_reason, sizeof(error_string_response),
3131601c 1539 "Successfully read main configuration file '%s'.", filename);
94b64352
JF
1540 *error_string = error_reason;
1541 }
2f552719
SD
1542
1543 return res;
1544}