]> git.proxmox.com Git - mirror_corosync.git/blame - exec/coroparse.c
coropase: Set a poll_period value for wd monitor
[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
8a45e2b1 57#include <corosync/list.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;
107 struct list_head list;
108};
109
110struct main_cp_cb_data {
8a45e2b1
JF
111 int ringnumber;
112 char *bindnetaddr;
113 char *mcastaddr;
114 char *broadcast;
115 int mcastport;
116 int ttl;
117
118 struct list_head logger_subsys_items_head;
119 char *subsys;
120 char *logging_daemon_name;
121 struct list_head member_items_head;
6d0b0b14
JF
122
123 int node_number;
124 int ring0_addr_added;
8a45e2b1
JF
125};
126
127static int read_config_file_into_icmap(
bc47c583 128 const char **error_string, icmap_map_t config_map);
2f552719
SD
129static char error_string_response[512];
130
8a45e2b1
JF
131static int uid_determine (const char *req_user)
132{
133 int pw_uid = 0;
134 struct passwd passwd;
135 struct passwd* pwdptr = &passwd;
136 struct passwd* temp_pwd_pt;
137 char *pwdbuffer;
005e7fd3 138 int pwdlinelen, rc;
86b074dc
JF
139 long int id;
140 char *ep;
141
142 id = strtol(req_user, &ep, 10);
143 if (*ep == '\0' && id >= 0 && id <= UINT_MAX) {
144 return (id);
145 }
8a45e2b1
JF
146
147 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
148
149 if (pwdlinelen == -1) {
150 pwdlinelen = 256;
151 }
152
153 pwdbuffer = malloc (pwdlinelen);
154
005e7fd3
AB
155 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
156 char *n;
157
158 pwdlinelen *= 2;
159 if (pwdlinelen <= 32678) {
160 n = realloc (pwdbuffer, pwdlinelen);
161 if (n != NULL) {
162 pwdbuffer = n;
163 continue;
52f88d04
JF
164 }
165 }
005e7fd3
AB
166 }
167 if (rc != 0) {
168 free (pwdbuffer);
169 sprintf (error_string_response, "getpwnam_r(): %s", strerror(rc));
170 return (-1);
171 }
172 if (temp_pwd_pt == NULL) {
52f88d04 173 free (pwdbuffer);
8a45e2b1
JF
174 sprintf (error_string_response,
175 "The '%s' user is not found in /etc/passwd, please read the documentation.",
176 req_user);
177 return (-1);
178 }
179 pw_uid = passwd.pw_uid;
180 free (pwdbuffer);
181
182 return pw_uid;
183}
184
185static int gid_determine (const char *req_group)
186{
7c8e83ac 187 int corosync_gid = 0;
8a45e2b1
JF
188 struct group group;
189 struct group * grpptr = &group;
190 struct group * temp_grp_pt;
191 char *grpbuffer;
005e7fd3 192 int grplinelen, rc;
86b074dc
JF
193 long int id;
194 char *ep;
195
196 id = strtol(req_group, &ep, 10);
197 if (*ep == '\0' && id >= 0 && id <= UINT_MAX) {
198 return (id);
199 }
8a45e2b1
JF
200
201 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
202
203 if (grplinelen == -1) {
204 grplinelen = 256;
205 }
206
207 grpbuffer = malloc (grplinelen);
208
005e7fd3
AB
209 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
210 char *n;
211
212 grplinelen *= 2;
213 if (grplinelen <= 32678) {
214 n = realloc (grpbuffer, grplinelen);
215 if (n != NULL) {
216 grpbuffer = n;
217 continue;
52f88d04
JF
218 }
219 }
005e7fd3
AB
220 }
221 if (rc != 0) {
222 free (grpbuffer);
223 sprintf (error_string_response, "getgrnam_r(): %s", strerror(rc));
224 return (-1);
225 }
226 if (temp_grp_pt == NULL) {
52f88d04 227 free (grpbuffer);
8a45e2b1
JF
228 sprintf (error_string_response,
229 "The '%s' group is not found in /etc/group, please read the documentation.",
230 req_group);
231 return (-1);
232 }
7c8e83ac 233 corosync_gid = group.gr_gid;
8a45e2b1 234 free (grpbuffer);
2f552719 235
7c8e83ac 236 return corosync_gid;
8a45e2b1 237}
3ffb151a
FDN
238static char *strchr_rs (const char *haystack, int byte)
239{
240 const char *end_address = strchr (haystack, byte);
241 if (end_address) {
242 end_address += 1; /* skip past { or = */
8a45e2b1
JF
243
244 while (*end_address == ' ' || *end_address == '\t')
245 end_address++;
3ffb151a
FDN
246 }
247
248 return ((char *) end_address);
249}
250
bc47c583 251int coroparse_configparse (icmap_map_t config_map, const char **error_string)
2f552719 252{
bc47c583 253 if (read_config_file_into_icmap(error_string, config_map)) {
2f552719
SD
254 return -1;
255 }
256
257 return 0;
258}
259
663489d2 260static char *remove_whitespace(char *string, int remove_colon_and_brace)
2f552719 261{
8a45e2b1
JF
262 char *start;
263 char *end;
2f552719 264
8a45e2b1
JF
265 start = string;
266 while (*start == ' ' || *start == '\t')
267 start++;
268
269 end = start+(strlen(start))-1;
663489d2 270 while ((*end == ' ' || *end == '\t' || (remove_colon_and_brace && (*end == ':' || *end == '{'))) && end > start)
2f552719
SD
271 end--;
272 if (end != start)
273 *(end+1) = '\0';
274
275 return start;
276}
277
ae229831 278
ae229831 279
2f552719 280static int parse_section(FILE *fp,
8a45e2b1 281 char *path,
ae229831 282 const char **error_string,
66172a50 283 int depth,
aab55a00 284 enum main_cp_cb_data_state state,
8a45e2b1 285 parser_cb_f parser_cb,
bc47c583 286 icmap_map_t config_map,
8a45e2b1 287 void *user_data)
2f552719
SD
288{
289 char line[512];
290 int i;
291 char *loc;
99db3567 292 int ignore_line;
8a45e2b1
JF
293 char new_keyname[ICMAP_KEYNAME_MAXLEN];
294
295 if (strcmp(path, "") == 0) {
aab55a00 296 parser_cb("", NULL, NULL, &state, PARSER_CB_START, error_string, config_map, user_data);
8a45e2b1 297 }
2f552719 298
94b64352
JF
299 while (fgets (line, sizeof (line), fp)) {
300 if (strlen(line) > 0) {
301 if (line[strlen(line) - 1] == '\n')
302 line[strlen(line) - 1] = '\0';
303 if (strlen (line) > 0 && line[strlen(line) - 1] == '\r')
304 line[strlen(line) - 1] = '\0';
305 }
2f552719
SD
306 /*
307 * Clear out white space and tabs
308 */
309 for (i = strlen (line) - 1; i > -1; i--) {
310 if (line[i] == '\t' || line[i] == ' ') {
311 line[i] = '\0';
312 } else {
313 break;
314 }
315 }
99db3567
JF
316
317 ignore_line = 1;
318 for (i = 0; i < strlen (line); i++) {
319 if (line[i] != '\t' && line[i] != ' ') {
320 if (line[i] != '#')
321 ignore_line = 0;
322
323 break;
324 }
325 }
2f552719
SD
326 /*
327 * Clear out comments and empty lines
328 */
99db3567 329 if (ignore_line) {
2f552719
SD
330 continue;
331 }
332
333 /* New section ? */
283011c6 334 if ((loc = strchr_rs (line, '{'))) {
663489d2 335 char *section = remove_whitespace(line, 1);
aab55a00 336 enum main_cp_cb_data_state newstate;
2f552719
SD
337
338 loc--;
339 *loc = '\0';
8a45e2b1 340
675da757
JF
341 if (strlen(path) + strlen(section) + 1 >= ICMAP_KEYNAME_MAXLEN) {
342 *error_string = "parser error: Start of section makes total cmap path too long";
343 return -1;
344 }
8a45e2b1
JF
345 strcpy(new_keyname, path);
346 if (strcmp(path, "") != 0) {
347 strcat(new_keyname, ".");
ae229831 348 }
8a45e2b1 349 strcat(new_keyname, section);
ae229831 350
aab55a00
CC
351 /* Only use the new state for items further down the stack */
352 newstate = state;
353 if (!parser_cb(new_keyname, NULL, NULL, &newstate, PARSER_CB_SECTION_START, error_string, config_map, user_data)) {
8a45e2b1
JF
354 return -1;
355 }
356
aab55a00 357 if (parse_section(fp, new_keyname, error_string, depth + 1, newstate, parser_cb, config_map, user_data))
2f552719 358 return -1;
663489d2
JF
359
360 continue ;
2f552719
SD
361 }
362
363 /* New key/value */
283011c6 364 if ((loc = strchr_rs (line, ':'))) {
2f552719
SD
365 char *key;
366 char *value;
367
368 *(loc-1) = '\0';
663489d2
JF
369 key = remove_whitespace(line, 1);
370 value = remove_whitespace(loc, 0);
8a45e2b1 371
675da757
JF
372 if (strlen(path) + strlen(key) + 1 >= ICMAP_KEYNAME_MAXLEN) {
373 *error_string = "parser error: New key makes total cmap path too long";
374 return -1;
375 }
8a45e2b1
JF
376 strcpy(new_keyname, path);
377 if (strcmp(path, "") != 0) {
378 strcat(new_keyname, ".");
379 }
380 strcat(new_keyname, key);
381
aab55a00 382 if (!parser_cb(new_keyname, key, value, &state, PARSER_CB_ITEM, error_string, config_map, user_data)) {
8a45e2b1 383 return -1;
ae229831 384 }
663489d2
JF
385
386 continue ;
2f552719
SD
387 }
388
8236a087 389 if (strchr_rs (line, '}')) {
66172a50
JF
390 if (depth == 0) {
391 *error_string = "parser error: Unexpected closing brace";
392
393 return -1;
394 }
395
aab55a00 396 if (!parser_cb(path, NULL, NULL, &state, PARSER_CB_SECTION_END, error_string, config_map, user_data)) {
8a45e2b1
JF
397 return -1;
398 }
399
2f552719
SD
400 return 0;
401 }
402 }
403
8a45e2b1 404 if (strcmp(path, "") != 0) {
66172a50 405 *error_string = "parser error: Missing closing brace";
2f552719
SD
406 return -1;
407 }
408
8a45e2b1 409 if (strcmp(path, "") == 0) {
aab55a00 410 parser_cb("", NULL, NULL, &state, PARSER_CB_END, error_string, config_map, user_data);
8a45e2b1
JF
411 }
412
2f552719
SD
413 return 0;
414}
415
4e9716ed 416static int safe_atoq_range(icmap_value_types_t value_type, long long int *min_val, long long int *max_val)
0929dcb6 417{
4e9716ed
JF
418 switch (value_type) {
419 case ICMAP_VALUETYPE_INT8: *min_val = INT8_MIN; *max_val = INT8_MAX; break;
420 case ICMAP_VALUETYPE_UINT8: *min_val = 0; *max_val = UINT8_MAX; break;
421 case ICMAP_VALUETYPE_INT16: *min_val = INT16_MIN; *max_val = INT16_MAX; break;
422 case ICMAP_VALUETYPE_UINT16: *min_val = 0; *max_val = UINT16_MAX; break;
423 case ICMAP_VALUETYPE_INT32: *min_val = INT32_MIN; *max_val = INT32_MAX; break;
424 case ICMAP_VALUETYPE_UINT32: *min_val = 0; *max_val = UINT32_MAX; break;
425 default:
426 return (-1);
427 }
428
429 return (0);
430}
431
432/*
433 * Convert string str to long long int res. Type of result is target_type and currently only
434 * ICMAP_VALUETYPE_[U]INT[8|16|32] is supported.
435 * Return 0 on success, -1 on failure.
436 */
437static int safe_atoq(const char *str, long long int *res, icmap_value_types_t target_type)
438{
439 long long int val;
440 long long int min_val, max_val;
0929dcb6
JF
441 char *endptr;
442
443 errno = 0;
444
4e9716ed 445 val = strtoll(str, &endptr, 10);
0929dcb6
JF
446 if (errno == ERANGE) {
447 return (-1);
448 }
449
450 if (endptr == str) {
451 return (-1);
452 }
453
454 if (*endptr != '\0') {
455 return (-1);
456 }
457
4e9716ed
JF
458 if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
459 return (-1);
460 }
461
462 if (val < min_val || val > max_val) {
463 return (-1);
464 }
465
0929dcb6
JF
466 *res = val;
467 return (0);
468}
469
6825c1d3
JF
470static int str_to_ull(const char *str, unsigned long long int *res)
471{
472 unsigned long long int val;
473 char *endptr;
474
475 errno = 0;
476
477 val = strtoull(str, &endptr, 10);
478 if (errno == ERANGE) {
479 return (-1);
480 }
481
482 if (endptr == str) {
483 return (-1);
484 }
485
486 if (*endptr != '\0') {
487 return (-1);
488 }
489
490 *res = val;
491 return (0);
492}
0929dcb6 493
8a45e2b1
JF
494static int main_config_parser_cb(const char *path,
495 char *key,
496 char *value,
aab55a00 497 enum main_cp_cb_data_state *state,
8a45e2b1
JF
498 enum parser_cb_type type,
499 const char **error_string,
bc47c583 500 icmap_map_t config_map,
8a45e2b1 501 void *user_data)
ae229831 502{
4e9716ed
JF
503 int ii;
504 long long int val;
505 long long int min_val, max_val;
506 icmap_value_types_t val_type = ICMAP_VALUETYPE_BINARY;
6825c1d3 507 unsigned long long int ull;
8a45e2b1
JF
508 int add_as_string;
509 char key_name[ICMAP_KEYNAME_MAXLEN];
0929dcb6 510 static char formated_err[256];
8a45e2b1
JF
511 struct main_cp_cb_data *data = (struct main_cp_cb_data *)user_data;
512 struct key_value_list_item *kv_item;
513 struct list_head *iter, *iter_next;
514 int uid, gid;
515
516 switch (type) {
517 case PARSER_CB_START:
518 memset(data, 0, sizeof(struct main_cp_cb_data));
aab55a00 519 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1
JF
520 break;
521 case PARSER_CB_END:
522 break;
523 case PARSER_CB_ITEM:
524 add_as_string = 1;
525
aab55a00 526 switch (*state) {
8a45e2b1
JF
527 case MAIN_CP_CB_DATA_STATE_NORMAL:
528 break;
eb3d49ef
FDN
529 case MAIN_CP_CB_DATA_STATE_PLOAD:
530 if ((strcmp(path, "pload.count") == 0) ||
531 (strcmp(path, "pload.size") == 0)) {
4e9716ed
JF
532 val_type = ICMAP_VALUETYPE_UINT32;
533 if (safe_atoq(value, &val, val_type) != 0) {
eb3d49ef
FDN
534 goto atoi_error;
535 }
4e9716ed 536 icmap_set_uint32_r(config_map, path, val);
eb3d49ef
FDN
537 add_as_string = 0;
538 }
539 break;
8a45e2b1
JF
540 case MAIN_CP_CB_DATA_STATE_QUORUM:
541 if ((strcmp(path, "quorum.expected_votes") == 0) ||
542 (strcmp(path, "quorum.votes") == 0) ||
10098dba 543 (strcmp(path, "quorum.last_man_standing_window") == 0) ||
8a45e2b1 544 (strcmp(path, "quorum.leaving_timeout") == 0)) {
4e9716ed
JF
545 val_type = ICMAP_VALUETYPE_UINT32;
546 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
547 goto atoi_error;
548 }
4e9716ed 549 icmap_set_uint32_r(config_map, path, val);
8a45e2b1
JF
550 add_as_string = 0;
551 }
552
9589611d 553 if ((strcmp(path, "quorum.two_node") == 0) ||
ff6a43ed 554 (strcmp(path, "quorum.expected_votes_tracking") == 0) ||
2d7a8ab2 555 (strcmp(path, "quorum.allow_downscale") == 0) ||
e8d0af0b 556 (strcmp(path, "quorum.wait_for_all") == 0) ||
b41372c6 557 (strcmp(path, "quorum.auto_tie_breaker") == 0) ||
769fc913 558 (strcmp(path, "quorum.last_man_standing") == 0)) {
4e9716ed
JF
559 val_type = ICMAP_VALUETYPE_UINT8;
560 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
561 goto atoi_error;
562 }
4e9716ed 563 icmap_set_uint8_r(config_map, path, val);
8a45e2b1
JF
564 add_as_string = 0;
565 }
566 break;
cb5fd775
FDN
567 case MAIN_CP_CB_DATA_STATE_QDEVICE:
568 if ((strcmp(path, "quorum.device.timeout") == 0) ||
17488909 569 (strcmp(path, "quorum.device.sync_timeout") == 0) ||
cb5fd775 570 (strcmp(path, "quorum.device.votes") == 0)) {
4e9716ed
JF
571 val_type = ICMAP_VALUETYPE_UINT32;
572 if (safe_atoq(value, &val, val_type) != 0) {
cb5fd775
FDN
573 goto atoi_error;
574 }
4e9716ed 575 icmap_set_uint32_r(config_map, path, val);
cb5fd775
FDN
576 add_as_string = 0;
577 }
86dd11b2 578 if ((strcmp(path, "quorum.device.master_wins") == 0)) {
4e9716ed
JF
579 val_type = ICMAP_VALUETYPE_UINT8;
580 if (safe_atoq(value, &val, val_type) != 0) {
86dd11b2
FDN
581 goto atoi_error;
582 }
4e9716ed 583 icmap_set_uint8_r(config_map, path, val);
86dd11b2
FDN
584 add_as_string = 0;
585 }
ce9c69da 586 break;
8a45e2b1
JF
587 case MAIN_CP_CB_DATA_STATE_TOTEM:
588 if ((strcmp(path, "totem.version") == 0) ||
589 (strcmp(path, "totem.nodeid") == 0) ||
590 (strcmp(path, "totem.threads") == 0) ||
591 (strcmp(path, "totem.token") == 0) ||
58176d67 592 (strcmp(path, "totem.token_coefficient") == 0) ||
8a45e2b1
JF
593 (strcmp(path, "totem.token_retransmit") == 0) ||
594 (strcmp(path, "totem.hold") == 0) ||
595 (strcmp(path, "totem.token_retransmits_before_loss_const") == 0) ||
596 (strcmp(path, "totem.join") == 0) ||
597 (strcmp(path, "totem.send_join") == 0) ||
598 (strcmp(path, "totem.consensus") == 0) ||
599 (strcmp(path, "totem.merge") == 0) ||
600 (strcmp(path, "totem.downcheck") == 0) ||
601 (strcmp(path, "totem.fail_recv_const") == 0) ||
602 (strcmp(path, "totem.seqno_unchanged_const") == 0) ||
603 (strcmp(path, "totem.rrp_token_expired_timeout") == 0) ||
604 (strcmp(path, "totem.rrp_problem_count_timeout") == 0) ||
605 (strcmp(path, "totem.rrp_problem_count_threshold") == 0) ||
606 (strcmp(path, "totem.rrp_problem_count_mcast_threshold") == 0) ||
607 (strcmp(path, "totem.rrp_autorecovery_check_timeout") == 0) ||
608 (strcmp(path, "totem.heartbeat_failures_allowed") == 0) ||
609 (strcmp(path, "totem.max_network_delay") == 0) ||
610 (strcmp(path, "totem.window_size") == 0) ||
611 (strcmp(path, "totem.max_messages") == 0) ||
612 (strcmp(path, "totem.miss_count_const") == 0) ||
613 (strcmp(path, "totem.netmtu") == 0)) {
4e9716ed
JF
614 val_type = ICMAP_VALUETYPE_UINT32;
615 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
616 goto atoi_error;
617 }
4e9716ed 618 icmap_set_uint32_r(config_map,path, val);
8a45e2b1
JF
619 add_as_string = 0;
620 }
6825c1d3
JF
621 if (strcmp(path, "totem.config_version") == 0) {
622 if (str_to_ull(value, &ull) != 0) {
623 goto atoi_error;
624 }
bc47c583 625 icmap_set_uint64_r(config_map, path, ull);
6825c1d3
JF
626 add_as_string = 0;
627 }
dd588d00
JF
628 if (strcmp(path, "totem.ip_version") == 0) {
629 if ((strcmp(value, "ipv4") != 0) &&
630 (strcmp(value, "ipv6") != 0)) {
631 *error_string = "Invalid ip_version type";
632
633 return (0);
634 }
635 }
8cdd2fc4
JF
636 if (strcmp(path, "totem.crypto_type") == 0) {
637 if ((strcmp(value, "nss") != 0) &&
20c58715
FDN
638 (strcmp(value, "aes256") != 0) &&
639 (strcmp(value, "aes192") != 0) &&
640 (strcmp(value, "aes128") != 0) &&
641 (strcmp(value, "3des") != 0)) {
8cdd2fc4
JF
642 *error_string = "Invalid crypto type";
643
644 return (0);
645 }
646 }
ab1675f0
JF
647 if (strcmp(path, "totem.crypto_cipher") == 0) {
648 if ((strcmp(value, "none") != 0) &&
20c58715
FDN
649 (strcmp(value, "aes256") != 0) &&
650 (strcmp(value, "aes192") != 0) &&
651 (strcmp(value, "aes128") != 0) &&
652 (strcmp(value, "3des") != 0)) {
ab1675f0
JF
653 *error_string = "Invalid cipher type";
654
655 return (0);
656 }
657 }
658 if (strcmp(path, "totem.crypto_hash") == 0) {
659 if ((strcmp(value, "none") != 0) &&
e57b5b9e 660 (strcmp(value, "md5") != 0) &&
4a2d5036 661 (strcmp(value, "sha1") != 0) &&
4a2d5036
FDN
662 (strcmp(value, "sha256") != 0) &&
663 (strcmp(value, "sha384") != 0) &&
664 (strcmp(value, "sha512") != 0)) {
ab1675f0
JF
665 *error_string = "Invalid hash type";
666
667 return (0);
668 }
669 }
a919908e
SD
670 break;
671
3cd4f9a1
JF
672 case MAIN_CP_CB_DATA_STATE_QB:
673 if (strcmp(path, "qb.ipc_type") == 0) {
674 if ((strcmp(value, "native") != 0) &&
675 (strcmp(value, "shm") != 0) &&
676 (strcmp(value, "socket") != 0)) {
677 *error_string = "Invalid qb ipc_type";
678
679 return (0);
680 }
681 }
682 break;
683
8a45e2b1
JF
684 case MAIN_CP_CB_DATA_STATE_INTERFACE:
685 if (strcmp(path, "totem.interface.ringnumber") == 0) {
4e9716ed
JF
686 val_type = ICMAP_VALUETYPE_UINT8;
687 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
688 goto atoi_error;
689 }
690
4e9716ed 691 data->ringnumber = val;
8a45e2b1
JF
692 add_as_string = 0;
693 }
694 if (strcmp(path, "totem.interface.bindnetaddr") == 0) {
695 data->bindnetaddr = strdup(value);
696 add_as_string = 0;
697 }
698 if (strcmp(path, "totem.interface.mcastaddr") == 0) {
699 data->mcastaddr = strdup(value);
700 add_as_string = 0;
701 }
702 if (strcmp(path, "totem.interface.broadcast") == 0) {
703 data->broadcast = strdup(value);
704 add_as_string = 0;
705 }
706 if (strcmp(path, "totem.interface.mcastport") == 0) {
4e9716ed
JF
707 val_type = ICMAP_VALUETYPE_UINT16;
708 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
709 goto atoi_error;
710 }
4e9716ed 711 data->mcastport = val;
8a45e2b1
JF
712 add_as_string = 0;
713 }
714 if (strcmp(path, "totem.interface.ttl") == 0) {
4e9716ed
JF
715 val_type = ICMAP_VALUETYPE_UINT8;
716 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
717 goto atoi_error;
718 }
4e9716ed 719 data->ttl = val;
8a45e2b1
JF
720 add_as_string = 0;
721 }
722 break;
723 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
724 if (strcmp(key, "subsys") == 0) {
725 data->subsys = strdup(value);
726 if (data->subsys == NULL) {
727 *error_string = "Can't alloc memory";
728
729 return (0);
730 }
731 } else {
732 kv_item = malloc(sizeof(*kv_item));
733 if (kv_item == NULL) {
734 *error_string = "Can't alloc memory";
735
736 return (0);
737 }
738 memset(kv_item, 0, sizeof(*kv_item));
739
740 kv_item->key = strdup(key);
741 kv_item->value = strdup(value);
742 if (kv_item->key == NULL || kv_item->value == NULL) {
743 free(kv_item);
744 *error_string = "Can't alloc memory";
745
746 return (0);
747 }
748 list_init(&kv_item->list);
749 list_add(&kv_item->list, &data->logger_subsys_items_head);
750 }
751 add_as_string = 0;
752 break;
753 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
754 if (strcmp(key, "subsys") == 0) {
755 data->subsys = strdup(value);
756 if (data->subsys == NULL) {
757 *error_string = "Can't alloc memory";
758
759 return (0);
760 }
761 } else if (strcmp(key, "name") == 0) {
762 data->logging_daemon_name = strdup(value);
763 if (data->logging_daemon_name == NULL) {
764 *error_string = "Can't alloc memory";
765
766 return (0);
767 }
768 } else {
769 kv_item = malloc(sizeof(*kv_item));
770 if (kv_item == NULL) {
771 *error_string = "Can't alloc memory";
772
773 return (0);
774 }
775 memset(kv_item, 0, sizeof(*kv_item));
776
777 kv_item->key = strdup(key);
778 kv_item->value = strdup(value);
779 if (kv_item->key == NULL || kv_item->value == NULL) {
780 free(kv_item);
781 *error_string = "Can't alloc memory";
782
783 return (0);
784 }
785 list_init(&kv_item->list);
786 list_add(&kv_item->list, &data->logger_subsys_items_head);
787 }
788 add_as_string = 0;
789 break;
790 case MAIN_CP_CB_DATA_STATE_UIDGID:
791 if (strcmp(key, "uid") == 0) {
792 uid = uid_determine(value);
793 if (uid == -1) {
794 *error_string = error_string_response;
795 return (0);
796 }
f837f95d 797 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 798 uid);
bc47c583 799 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
800 add_as_string = 0;
801 } else if (strcmp(key, "gid") == 0) {
802 gid = gid_determine(value);
803 if (gid == -1) {
804 *error_string = error_string_response;
805 return (0);
806 }
f837f95d 807 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 808 gid);
bc47c583 809 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
810 add_as_string = 0;
811 } else {
812 *error_string = "uidgid: Only uid and gid are allowed items";
813 return (0);
814 }
815 break;
816 case MAIN_CP_CB_DATA_STATE_MEMBER:
817 if (strcmp(key, "memberaddr") != 0) {
818 *error_string = "Only memberaddr is allowed in member section";
819
820 return (0);
821 }
822
823 kv_item = malloc(sizeof(*kv_item));
824 if (kv_item == NULL) {
825 *error_string = "Can't alloc memory";
826
827 return (0);
828 }
829 memset(kv_item, 0, sizeof(*kv_item));
830
831 kv_item->key = strdup(key);
832 kv_item->value = strdup(value);
833 if (kv_item->key == NULL || kv_item->value == NULL) {
834 free(kv_item);
835 *error_string = "Can't alloc memory";
836
837 return (0);
838 }
839 list_init(&kv_item->list);
840 list_add(&kv_item->list, &data->member_items_head);
841 add_as_string = 0;
842 break;
6d0b0b14
JF
843 case MAIN_CP_CB_DATA_STATE_NODELIST:
844 break;
845 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
846 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.%s", data->node_number, key);
847 if ((strcmp(key, "nodeid") == 0) ||
848 (strcmp(key, "quorum_votes") == 0)) {
4e9716ed
JF
849 val_type = ICMAP_VALUETYPE_UINT32;
850 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
851 goto atoi_error;
852 }
853
4e9716ed 854 icmap_set_uint32_r(config_map, key_name, val);
6d0b0b14
JF
855 add_as_string = 0;
856 }
857
858 if (strcmp(key, "ring0_addr") == 0) {
859 data->ring0_addr_added = 1;
860 }
861
862 if (add_as_string) {
bc47c583 863 icmap_set_string_r(config_map, key_name, value);
6d0b0b14
JF
864 add_as_string = 0;
865 }
866 break;
39cd6b3d 867 case MAIN_CP_CB_DATA_STATE_RESOURCES:
868 if (strcmp(key, "watchdog_timeout") == 0) {
869 val_type = ICMAP_VALUETYPE_UINT32;
870 if (safe_atoq(value, &val, val_type) != 0) {
871 goto atoi_error;
872 }
873 icmap_set_uint32_r(config_map,path, val);
874 add_as_string = 0;
875 }
876 break;
877 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
39cd6b3d 878 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
879 if (strcmp(key, "poll_period") == 0) {
880 if (str_to_ull(value, &ull) != 0) {
881 goto atoi_error;
882 }
883 icmap_set_uint64_r(config_map,path, ull);
884 add_as_string = 0;
885 }
886 break;
887 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
39cd6b3d 888 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
889 if (strcmp(key, "poll_period") == 0) {
890 if (str_to_ull(value, &ull) != 0) {
891 goto atoi_error;
892 }
893 icmap_set_uint64_r(config_map,path, ull);
894 add_as_string = 0;
895 }
896 break;
ae229831
JF
897 }
898
8a45e2b1 899 if (add_as_string) {
bc47c583 900 icmap_set_string_r(config_map, path, value);
8a45e2b1
JF
901 }
902 break;
903 case PARSER_CB_SECTION_START:
904 if (strcmp(path, "totem.interface") == 0) {
aab55a00 905 *state = MAIN_CP_CB_DATA_STATE_INTERFACE;
8a45e2b1
JF
906 data->ringnumber = 0;
907 data->mcastport = -1;
908 data->ttl = -1;
909 list_init(&data->member_items_head);
910 };
911 if (strcmp(path, "totem") == 0) {
aab55a00 912 *state = MAIN_CP_CB_DATA_STATE_TOTEM;
8a45e2b1 913 };
3cd4f9a1 914 if (strcmp(path, "qb") == 0) {
aab55a00 915 *state = MAIN_CP_CB_DATA_STATE_QB;
3cd4f9a1 916 }
8a45e2b1 917 if (strcmp(path, "logging.logger_subsys") == 0) {
aab55a00 918 *state = MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS;
8a45e2b1
JF
919 list_init(&data->logger_subsys_items_head);
920 data->subsys = NULL;
921 }
922 if (strcmp(path, "logging.logging_daemon") == 0) {
aab55a00 923 *state = MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON;
8a45e2b1
JF
924 list_init(&data->logger_subsys_items_head);
925 data->subsys = NULL;
926 data->logging_daemon_name = NULL;
927 }
928 if (strcmp(path, "uidgid") == 0) {
aab55a00 929 *state = MAIN_CP_CB_DATA_STATE_UIDGID;
ae229831 930 }
8a45e2b1 931 if (strcmp(path, "totem.interface.member") == 0) {
aab55a00 932 *state = MAIN_CP_CB_DATA_STATE_MEMBER;
8a45e2b1
JF
933 }
934 if (strcmp(path, "quorum") == 0) {
aab55a00 935 *state = MAIN_CP_CB_DATA_STATE_QUORUM;
8a45e2b1 936 }
cb5fd775 937 if (strcmp(path, "quorum.device") == 0) {
aab55a00 938 *state = MAIN_CP_CB_DATA_STATE_QDEVICE;
cb5fd775 939 }
6d0b0b14 940 if (strcmp(path, "nodelist") == 0) {
aab55a00 941 *state = MAIN_CP_CB_DATA_STATE_NODELIST;
6d0b0b14
JF
942 data->node_number = 0;
943 }
944 if (strcmp(path, "nodelist.node") == 0) {
aab55a00 945 *state = MAIN_CP_CB_DATA_STATE_NODELIST_NODE;
6d0b0b14
JF
946 data->ring0_addr_added = 0;
947 }
39cd6b3d 948 if (strcmp(path, "resources") == 0) {
949 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
950 }
951 if (strcmp(path, "resources.system") == 0) {
952 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
953 }
954 if (strcmp(path, "resources.system.memory_used") == 0) {
955 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED;
956 }
957 if (strcmp(path, "resources.process") == 0) {
958 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
959 }
960 if (strcmp(path, "resources.process.memory_used") == 0) {
961 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED;
962 }
8a45e2b1
JF
963 break;
964 case PARSER_CB_SECTION_END:
aab55a00 965 switch (*state) {
8a45e2b1
JF
966 case MAIN_CP_CB_DATA_STATE_INTERFACE:
967 /*
968 * Create new interface section
969 */
970 if (data->bindnetaddr != NULL) {
971 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr",
972 data->ringnumber);
bc47c583 973 icmap_set_string_r(config_map, key_name, data->bindnetaddr);
8a45e2b1
JF
974
975 free(data->bindnetaddr);
976 data->bindnetaddr = NULL;
8a45e2b1
JF
977 }
978
979 if (data->mcastaddr != NULL) {
980 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr",
981 data->ringnumber);
bc47c583 982 icmap_set_string_r(config_map, key_name, data->mcastaddr);
8a45e2b1
JF
983
984 free(data->mcastaddr);
985 data->mcastaddr = NULL;
986 }
987
988 if (data->broadcast != NULL) {
989 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast",
990 data->ringnumber);
bc47c583 991 icmap_set_string_r(config_map, key_name, data->broadcast);
8a45e2b1
JF
992
993 free(data->broadcast);
994 data->broadcast = NULL;
995 }
996
997 if (data->mcastport > -1) {
998 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport",
999 data->ringnumber);
bc47c583 1000 icmap_set_uint16_r(config_map, key_name, data->mcastport);
8a45e2b1
JF
1001 }
1002
1003 if (data->ttl > -1) {
1004 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl",
1005 data->ringnumber);
bc47c583 1006 icmap_set_uint8_r(config_map, key_name, data->ttl);
8a45e2b1
JF
1007 }
1008
4e9716ed 1009 ii = 0;
8a45e2b1
JF
1010 for (iter = data->member_items_head.next;
1011 iter != &data->member_items_head; iter = iter_next) {
1012 kv_item = list_entry(iter, struct key_value_list_item, list);
1013
1014 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u",
4e9716ed 1015 data->ringnumber, ii);
bc47c583 1016 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1017
1018 iter_next = iter->next;
1019
1020 free(kv_item->value);
1021 free(kv_item->key);
1022 free(kv_item);
4e9716ed 1023 ii++;
8a45e2b1
JF
1024 }
1025
3cd4f9a1 1026 break;
8a45e2b1
JF
1027 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
1028 if (data->subsys == NULL) {
1029 *error_string = "No subsys key in logger_subsys directive";
1030
1031 return (0);
1032 }
1033
1034 for (iter = data->logger_subsys_items_head.next;
1035 iter != &data->logger_subsys_items_head; iter = iter_next) {
1036 kv_item = list_entry(iter, struct key_value_list_item, list);
1037
1038 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s",
aab55a00 1039 data->subsys, kv_item->key);
bc47c583 1040 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1041
1042 iter_next = iter->next;
1043
1044 free(kv_item->value);
1045 free(kv_item->key);
1046 free(kv_item);
1047 }
1048
1049 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1050 data->subsys);
bc47c583 1051 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1052
1053 free(data->subsys);
1054
8a45e2b1
JF
1055 break;
1056 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
1057 if (data->logging_daemon_name == NULL) {
1058 *error_string = "No name key in logging_daemon directive";
1059
1060 return (0);
1061 }
1062
1063 for (iter = data->logger_subsys_items_head.next;
1064 iter != &data->logger_subsys_items_head; iter = iter_next) {
1065 kv_item = list_entry(iter, struct key_value_list_item, list);
1066
1067 if (data->subsys == NULL) {
1068 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1069 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1070 "logging.%s",
1071 kv_item->key);
1072 } else {
1073 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1074 "logging.logging_daemon.%s.%s",
1075 data->logging_daemon_name, kv_item->key);
1076 }
1077 } else {
1078 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1079 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1080 "logging.logger_subsys.%s.%s",
1081 data->subsys,
1082 kv_item->key);
1083 } else {
1084 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1085 "logging.logging_daemon.%s.%s.%s",
1086 data->logging_daemon_name, data->subsys,
1087 kv_item->key);
1088 }
1089 }
bc47c583 1090 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1091
1092 iter_next = iter->next;
1093
1094 free(kv_item->value);
1095 free(kv_item->key);
1096 free(kv_item);
1097 }
1098
1099 if (data->subsys == NULL) {
1100 if (strcmp(data->logging_daemon_name, "corosync") != 0) {
1101 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name",
1102 data->logging_daemon_name);
bc47c583 1103 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1104 }
1105 } else {
1106 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1107 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1108 data->subsys);
bc47c583 1109 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1110
1111 } else {
1112 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.subsys",
1113 data->logging_daemon_name, data->subsys);
bc47c583 1114 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1115 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name",
1116 data->logging_daemon_name, data->subsys);
bc47c583 1117 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1118 }
1119 }
1120
1121 free(data->subsys);
1122 free(data->logging_daemon_name);
1123
6d0b0b14
JF
1124 break;
1125 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
1126 if (!data->ring0_addr_added) {
1127 *error_string = "No ring0_addr specified for node";
1128
1129 return (0);
1130 }
1131 data->node_number++;
aab55a00
CC
1132 break;
1133 case MAIN_CP_CB_DATA_STATE_NORMAL:
1134 case MAIN_CP_CB_DATA_STATE_PLOAD:
1135 case MAIN_CP_CB_DATA_STATE_UIDGID:
1136 case MAIN_CP_CB_DATA_STATE_MEMBER:
1137 case MAIN_CP_CB_DATA_STATE_QUORUM:
1138 case MAIN_CP_CB_DATA_STATE_QDEVICE:
1139 case MAIN_CP_CB_DATA_STATE_NODELIST:
1140 case MAIN_CP_CB_DATA_STATE_TOTEM:
1141 case MAIN_CP_CB_DATA_STATE_QB:
6d0b0b14 1142 break;
39cd6b3d 1143 case MAIN_CP_CB_DATA_STATE_RESOURCES:
1144 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
1145 break;
1146 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
1147 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1148 break;
1149 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
1150 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1151 break;
1152 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
1153 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1154 break;
1155 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
1156 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1157 break;
8a45e2b1
JF
1158 }
1159 break;
ae229831
JF
1160 }
1161
8a45e2b1 1162 return (1);
0929dcb6
JF
1163
1164atoi_error:
4e9716ed
JF
1165 min_val = max_val = 0;
1166 /*
1167 * This is really assert, because developer ether doesn't set val_type correctly or
1168 * we've got here after some nasty memory overwrite
1169 */
1170 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1171
0929dcb6 1172 snprintf(formated_err, sizeof(formated_err),
4e9716ed
JF
1173 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1174 key, min_val, max_val, value);
0929dcb6
JF
1175 *error_string = formated_err;
1176
1177 return (0);
8a45e2b1
JF
1178}
1179
1180static int uidgid_config_parser_cb(const char *path,
1181 char *key,
1182 char *value,
aab55a00 1183 enum main_cp_cb_data_state *state,
8a45e2b1
JF
1184 enum parser_cb_type type,
1185 const char **error_string,
bc47c583 1186 icmap_map_t config_map,
8a45e2b1
JF
1187 void *user_data)
1188{
1189 char key_name[ICMAP_KEYNAME_MAXLEN];
1190 int uid, gid;
1191
1192 switch (type) {
1193 case PARSER_CB_START:
1194 break;
1195 case PARSER_CB_END:
1196 break;
1197 case PARSER_CB_ITEM:
1198 if (strcmp(path, "uidgid.uid") == 0) {
1199 uid = uid_determine(value);
1200 if (uid == -1) {
1201 *error_string = error_string_response;
1202 return (0);
1203 }
f837f95d 1204 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 1205 uid);
bc47c583 1206 icmap_set_uint8_r(config_map, key_name, 1);
92ead610 1207 } else if (strcmp(path, "uidgid.gid") == 0) {
8a45e2b1
JF
1208 gid = gid_determine(value);
1209 if (gid == -1) {
1210 *error_string = error_string_response;
1211 return (0);
1212 }
f837f95d 1213 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 1214 gid);
bc47c583 1215 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1 1216 } else {
ae229831 1217 *error_string = "uidgid: Only uid and gid are allowed items";
8a45e2b1 1218 return (0);
ae229831 1219 }
8a45e2b1
JF
1220 break;
1221 case PARSER_CB_SECTION_START:
1222 if (strcmp(path, "uidgid") != 0) {
3b8365e8 1223 *error_string = "uidgid: Can't add subsection different than uidgid";
8a45e2b1
JF
1224 return (0);
1225 };
1226 break;
1227 case PARSER_CB_SECTION_END:
1228 break;
ae229831 1229 }
2f552719 1230
8a45e2b1 1231 return (1);
ae229831
JF
1232}
1233
8a45e2b1 1234static int read_uidgid_files_into_icmap(
bc47c583
CC
1235 const char **error_string,
1236 icmap_map_t config_map)
ae229831
JF
1237{
1238 FILE *fp;
1239 const char *dirname;
1240 DIR *dp;
1241 struct dirent *dirent;
2290913d 1242 struct dirent *entry;
1bd8aba6 1243 char filename[PATH_MAX + FILENAME_MAX + 1];
ae229831 1244 int res = 0;
2290913d
AS
1245 size_t len;
1246 int return_code;
1e0d40cd 1247 struct stat stat_buf;
aab55a00 1248 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1 1249 char key_name[ICMAP_KEYNAME_MAXLEN];
ae229831 1250
2135d91c 1251 dirname = COROSYSCONFDIR "/uidgid.d";
ae229831
JF
1252 dp = opendir (dirname);
1253
1254 if (dp == NULL)
1255 return 0;
1256
427fdd45 1257 len = offsetof(struct dirent, d_name) + FILENAME_MAX + 1;
eda1e364 1258
2290913d 1259 entry = malloc(len);
eda1e364 1260 if (entry == NULL) {
c2a39cb8
JF
1261 res = 0;
1262 goto error_exit;
eda1e364 1263 }
2290913d
AS
1264
1265 for (return_code = readdir_r(dp, entry, &dirent);
1266 dirent != NULL && return_code == 0;
1267 return_code = readdir_r(dp, entry, &dirent)) {
1268
1e0d40cd 1269 snprintf(filename, sizeof (filename), "%s/%s", dirname, dirent->d_name);
966f461b
JF
1270 res = stat (filename, &stat_buf);
1271 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
ae229831
JF
1272
1273 fp = fopen (filename, "r");
1274 if (fp == NULL) continue;
1275
8a45e2b1
JF
1276 key_name[0] = 0;
1277
aab55a00 1278 res = parse_section(fp, key_name, error_string, 0, state, uidgid_config_parser_cb, config_map, NULL);
ae229831
JF
1279
1280 fclose (fp);
1281
1282 if (res != 0) {
1283 goto error_exit;
1284 }
1285 }
1286 }
1287
1288error_exit:
2290913d 1289 free (entry);
ae229831
JF
1290 closedir(dp);
1291
1292 return res;
1293}
2f552719 1294
8a45e2b1
JF
1295/* Read config file and load into icmap */
1296static int read_config_file_into_icmap(
bc47c583
CC
1297 const char **error_string,
1298 icmap_map_t config_map)
2f552719
SD
1299{
1300 FILE *fp;
23c64c64 1301 const char *filename;
2f552719
SD
1302 char *error_reason = error_string_response;
1303 int res;
8a45e2b1
JF
1304 char key_name[ICMAP_KEYNAME_MAXLEN];
1305 struct main_cp_cb_data data;
aab55a00 1306 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
2f552719
SD
1307
1308 filename = getenv ("COROSYNC_MAIN_CONFIG_FILE");
1309 if (!filename)
2135d91c 1310 filename = COROSYSCONFDIR "/corosync.conf";
2f552719
SD
1311
1312 fp = fopen (filename, "r");
23c64c64 1313 if (fp == NULL) {
20f3331d 1314 char error_str[100];
37e17e7a 1315 const char *error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
870046d0 1316 snprintf (error_reason, sizeof(error_string_response),
3131601c 1317 "Can't read file %s reason = (%s)",
00434a4f 1318 filename, error_ptr);
2f552719
SD
1319 *error_string = error_reason;
1320 return -1;
1321 }
1322
8a45e2b1
JF
1323 key_name[0] = 0;
1324
aab55a00 1325 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
2f552719
SD
1326
1327 fclose(fp);
1328
ae229831 1329 if (res == 0) {
bc47c583 1330 res = read_uidgid_files_into_icmap(error_string, config_map);
ae229831
JF
1331 }
1332
94b64352
JF
1333 if (res == 0) {
1334 snprintf (error_reason, sizeof(error_string_response),
3131601c 1335 "Successfully read main configuration file '%s'.", filename);
94b64352
JF
1336 *error_string = error_reason;
1337 }
2f552719
SD
1338
1339 return res;
1340}