1 /* Copyright (C) 2016-2018 Shengyu Zhang <i@silverrainz.me>
2 *
3 * This file is part of Srain.
4 *
5 * Srain is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20 * @file reader.c
21 * @brief Configuration readers for various config structures
22 * @author Shengyu Zhang <i@silverrainz.me>
23 * @version 0.06.3
24 * @date 2018-02-16
25 */
26
27 #include <glib.h>
28 #include <libconfig.h>
29
30 #include "core/core.h"
31 #include "config/config.h"
32 #include "config/password.h"
33 #include "i18n.h"
34 #include "utils.h"
35 #include "log.h"
36
37 /* Libconfig helpers */
38 static int config_lookup_string_ex(const config_t *config, const char *path, char **value);
39 static int config_setting_lookup_string_ex(const config_setting_t *config, const char *name, char **value);
40 static char* config_setting_get_string_elem_ex(const config_setting_t *setting, int index);
41 static int config_lookup_bool_ex(const config_t *config, const char *name, bool *value);
42 static int config_setting_lookup_bool_ex(const config_setting_t *config, const char *name, bool *value);
43
44 /* Configuration readers for various config structures */
45 static SrnRet read_log_config_from_cfg(config_t *cfg, SrnLoggerConfig *log_cfg);
46 static SrnRet read_log_targets_from_log(config_setting_t *log, const char *name, GList **lst);
47
48 static SrnRet read_application_config_from_cfg(config_t *cfg, SrnApplicationConfig *app_cfg);
49
50 static SrnRet read_server_config_list_from_cfg(config_t *cfg, GList **srv_cfg_list);
51 static SrnRet read_server_config_from_server(config_setting_t *server, SrnServerConfig *cfg);
52 static SrnRet read_server_config_from_server_list(config_setting_t *server_list, SrnServerConfig *cfg, const char *srv_name);
53 static SrnRet read_server_config_from_cfg(config_t *cfg, SrnServerConfig *srv_cfg, const char *srv_name);
54
55 static SrnRet read_chat_config_from_chat(config_setting_t *chat, SrnChatConfig *cfg);
56 static SrnRet read_chat_config_from_chat_list(config_setting_t *chat_list, SrnChatConfig *cfg, const char *chat_name);
57 static SrnRet read_chat_config_from_cfg(config_t *cfg, SrnChatConfig *chat_cfg, const char *srv_name, const char *chat_name);
58
59 static SrnRet read_user_config_from_user(config_setting_t *user, SrnUserConfig *cfg);
60
61 /*****************************************************************************
62 * Exported functions
63 *****************************************************************************/
64
srn_config_manager_read_log_config(SrnConfigManager * mgr,SrnLoggerConfig * cfg)65 SrnRet srn_config_manager_read_log_config(SrnConfigManager *mgr,
66 SrnLoggerConfig *cfg){
67 SrnRet ret;
68
69 ret = read_log_config_from_cfg(&mgr->system_cfg, cfg);
70 if (!RET_IS_OK(ret)){
71 return RET_ERR(_("Error occurred while reading log config in %1$s: %2$s"),
72 config_setting_source_file(config_root_setting(&mgr->system_cfg)),
73 RET_MSG(ret));
74 }
75 ret = read_log_config_from_cfg(&mgr->user_cfg, cfg);
76 if (!RET_IS_OK(ret)){
77 return RET_ERR(_("Error occurred while reading log config in %1$s: %2$s"),
78 config_setting_source_file(config_root_setting(&mgr->user_cfg)),
79 RET_MSG(ret));
80 }
81
82 return SRN_OK;
83 }
84
srn_config_manager_read_application_config(SrnConfigManager * mgr,SrnApplicationConfig * cfg)85 SrnRet srn_config_manager_read_application_config(SrnConfigManager *mgr,
86 SrnApplicationConfig *cfg){
87 SrnRet ret;
88
89 ret = read_application_config_from_cfg(&mgr->system_cfg, cfg);
90 if (!RET_IS_OK(ret)){
91 return RET_ERR(_("Error occurred while reading application config in %1$s: %2$s"),
92 config_setting_source_file(config_root_setting(&mgr->system_cfg)),
93 RET_MSG(ret));
94 }
95 ret = read_application_config_from_cfg(&mgr->user_cfg, cfg);
96 if (!RET_IS_OK(ret)){
97 return RET_ERR(_("Error occurred while reading application config in %1$s: %2$s"),
98 config_setting_source_file(config_root_setting(&mgr->user_cfg)),
99 RET_MSG(ret));
100 }
101
102 return SRN_OK;
103 }
104
srn_config_manager_read_server_config_list(SrnConfigManager * mgr,GList ** srv_cfg_list)105 SrnRet srn_config_manager_read_server_config_list(SrnConfigManager *mgr,
106 GList **srv_cfg_list){
107 SrnRet ret;
108
109 ret = read_server_config_list_from_cfg(&mgr->system_cfg, srv_cfg_list);
110 if (!RET_IS_OK(ret)){
111 return RET_ERR(_("Error occurred while reading server list config in %1$s: %2$s"),
112 config_setting_source_file(config_root_setting(&mgr->system_cfg)),
113 RET_MSG(ret));
114 }
115 ret = read_server_config_list_from_cfg(&mgr->user_cfg, srv_cfg_list);
116 if (!RET_IS_OK(ret)){
117 return RET_ERR(_("Error occurred while reading server list config in %1$s: %2$s"),
118 config_setting_source_file(config_root_setting(&mgr->user_cfg)),
119 RET_MSG(ret));
120 }
121
122 return SRN_OK;
123 }
124
srn_config_manager_read_server_config(SrnConfigManager * mgr,SrnServerConfig * cfg,const char * srv_name)125 SrnRet srn_config_manager_read_server_config(SrnConfigManager *mgr,
126 SrnServerConfig *cfg, const char *srv_name){
127 SrnRet ret;
128
129 ret = read_server_config_from_cfg(&mgr->system_cfg, cfg, srv_name);
130 if (!RET_IS_OK(ret)){
131 return RET_ERR(_("Error occurred while reading server config in %1$s: %2$s"),
132 config_setting_source_file(config_root_setting(&mgr->system_cfg)),
133 RET_MSG(ret));
134 }
135 ret = read_server_config_from_cfg(&mgr->user_cfg, cfg, srv_name);
136 if (!RET_IS_OK(ret)){
137 return RET_ERR(_("Error occurred while reading server config in %1$s: %2$s"),
138 config_setting_source_file(config_root_setting(&mgr->user_cfg)),
139 RET_MSG(ret));
140 }
141 ret = srn_config_manager_lookup_server_password(mgr, &cfg->password, srv_name);
142 if (!RET_IS_OK(ret)){
143 WARN_FR(_("Error occurred while looking up server password: %1$s"),
144 RET_MSG(ret));
145 }
146 ret = srn_config_manager_lookup_user_password(mgr,
147 &cfg->user->login->password, srv_name, cfg->user->nick);
148 if (!RET_IS_OK(ret)){
149 WARN_FR(_("Error occurred while looking up user password: %1$s"),
150 RET_MSG(ret));
151 }
152
153 return SRN_OK;
154 }
155
srn_config_manager_read_server_config_by_addr(SrnConfigManager * mgr,SrnServerConfig * cfg,SrnServerAddr * addr)156 SrnRet srn_config_manager_read_server_config_by_addr(SrnConfigManager *mgr,
157 SrnServerConfig *cfg, SrnServerAddr *addr){
158 GList *lst;
159 GList *cfg_lst;
160 SrnRet ret;
161 SrnServerConfig *tmp;
162
163 cfg_lst = NULL;
164 ret = srn_config_manager_read_server_config_list(mgr, &cfg_lst);
165 tmp = NULL;
166 if (!RET_IS_OK(ret)){
167 goto FIN;
168 }
169
170 lst = cfg_lst;
171 while (lst) {
172 GList *addr_lst;
173
174 tmp = srn_server_config_new();
175 // Do not read config to cfg until the address is found
176 ret = srn_config_manager_read_server_config(mgr, tmp, lst->data);
177 if (!RET_IS_OK(ret)){
178 goto FIN;
179 }
180
181 addr_lst = tmp->addrs;
182 while (addr_lst){
183 if (srn_server_addr_equal(addr, addr_lst->data)){
184 ret = srn_config_manager_read_server_config(mgr, cfg, lst->data);
185 goto FIN;
186 }
187 addr_lst = g_list_next(addr_lst);
188 }
189
190 srn_server_config_free(tmp);
191 tmp = NULL;
192 lst = g_list_next(lst);
193 }
194
195 ret = SRN_ERR;
196 FIN:
197 if (cfg_lst) {
198 g_list_free_full(cfg_lst, g_free);
199 }
200 if (tmp) {
201 srn_server_config_free(tmp);
202 }
203 return ret;
204 }
205
srn_config_manager_read_chat_config(SrnConfigManager * mgr,SrnChatConfig * cfg,const char * srv_name,const char * chat_name)206 SrnRet srn_config_manager_read_chat_config(SrnConfigManager *mgr,
207 SrnChatConfig *cfg, const char *srv_name, const char *chat_name){
208 SrnRet ret;
209
210 ret = read_chat_config_from_cfg(&mgr->system_cfg, cfg, srv_name, chat_name);
211 if (!RET_IS_OK(ret)){
212 return RET_ERR(_("Error occurred while reading chat config in %1$s: %2$s"),
213 config_setting_source_file(config_root_setting(&mgr->system_cfg)),
214 RET_MSG(ret));
215 }
216
217 ret = read_chat_config_from_cfg(&mgr->user_cfg, cfg, srv_name, chat_name);
218 if (!RET_IS_OK(ret)){
219 return RET_ERR(_("Error occurred while reading chat config in %1$s: %2$s"),
220 config_setting_source_file(config_root_setting(&mgr->user_cfg)),
221 RET_MSG(ret));
222 }
223
224 // In fact we don't known whether this chat is channel
225 ret = srn_config_manager_lookup_channel_password(mgr,
226 &cfg->password, srv_name, chat_name);
227 if (!RET_IS_OK(ret)){
228 WARN_FR(_("Error occurred while looking up channel password: %1$s"),
229 RET_MSG(ret));
230 }
231
232 return SRN_OK;
233 }
234
235 /*****************************************************************************
236 * Static functions
237 *****************************************************************************/
238
read_log_config_from_cfg(config_t * cfg,SrnLoggerConfig * log_cfg)239 static SrnRet read_log_config_from_cfg(config_t *cfg, SrnLoggerConfig *log_cfg){
240 SrnRet ret;
241 config_setting_t *log;
242
243 log = config_lookup(cfg, "log");
244 if (log){
245 config_setting_lookup_bool_ex(log, "prompt-color", &log_cfg->prompt_color);
246 config_setting_lookup_bool_ex(log, "prompt-file", &log_cfg->prompt_file);
247 config_setting_lookup_bool_ex(log, "prompt-function", &log_cfg->prompt_function);
248 config_setting_lookup_bool_ex(log, "prompt-line", &log_cfg->prompt_line);
249
250 ret = read_log_targets_from_log(log, "debug-targets", &log_cfg->debug_targets);
251 if (!RET_IS_OK(ret)) return ret;
252 ret = read_log_targets_from_log(log, "info-targets", &log_cfg->info_targets);
253 if (!RET_IS_OK(ret)) return ret;
254 ret = read_log_targets_from_log(log, "warn-targets", &log_cfg->warn_targets);
255 if (!RET_IS_OK(ret)) return ret;
256 ret = read_log_targets_from_log(log, "error-targets", &log_cfg->error_targets);
257 if (!RET_IS_OK(ret)) return ret;
258 }
259
260 return SRN_OK;
261 }
262
read_log_targets_from_log(config_setting_t * log,const char * name,GList ** lst)263 static SrnRet read_log_targets_from_log(config_setting_t *log, const char *name,
264 GList **lst){
265 config_setting_t *targets;
266
267 targets = config_setting_lookup(log, name);
268 if (!targets) return SRN_OK;
269
270 int count = config_setting_length(targets);
271 for (int i = 0; i < count; i++){
272 const char *val;
273 config_setting_t *target;
274
275 target = config_setting_get_elem(targets, i);
276 if (!target) break;
277
278 val = config_setting_get_string(target);
279 if (!val) continue;
280
281 *lst = g_list_append(*lst, g_strdup(val));
282 }
283
284 return SRN_OK;
285 }
read_application_config_from_cfg(config_t * cfg,SrnApplicationConfig * app_cfg)286 static SrnRet read_application_config_from_cfg(config_t *cfg,
287 SrnApplicationConfig *app_cfg){
288 config_lookup_string_ex(cfg, "id", &app_cfg->id);
289 config_lookup_string_ex(cfg, "theme", &app_cfg->ui->theme);
290 config_lookup_bool_ex(cfg, "csd", &app_cfg->ui->window.csd);
291 config_lookup_bool_ex(cfg, "send-on-ctrl-enter",
292 &app_cfg->ui->window.send_on_ctrl_enter);
293 config_lookup_bool_ex(cfg, "exit-on-close",
294 &app_cfg->ui->window.exit_on_close);
295
296 /* Read auto connect server list */
297 config_setting_t *auto_connect;
298 auto_connect = config_lookup(cfg, "auto-connect");
299 if (auto_connect){
300 for (int i = 0; i < config_setting_length(auto_connect); i++){
301 const char *val;
302 config_setting_t *server;
303
304 server = config_setting_get_elem(auto_connect, i);
305 if (!server) continue;
306 val = config_setting_get_string(server);
307 if (!val) continue;
308
309 app_cfg->auto_connect_srv_list = g_list_append(
310 app_cfg->auto_connect_srv_list, g_strdup(val));
311 }
312 }
313
314 return SRN_OK;
315 }
316
read_server_config_list_from_cfg(config_t * cfg,GList ** srv_cfg_list)317 static SrnRet read_server_config_list_from_cfg(config_t *cfg,
318 GList **srv_cfg_list){
319 config_setting_t *server_list;
320
321 server_list = config_lookup(cfg, "server-list");
322 if (server_list){
323 for (int i = 0, count = config_setting_length(server_list); i < count; i++){
324 char *name = NULL;
325 config_setting_t *server;
326
327 server = config_setting_get_elem(server_list, i);
328 if (!server) break;
329
330 if (config_setting_lookup_string_ex(server, "name", &name) != CONFIG_TRUE) {
331 return RET_ERR(_("server-list[%1$d] doesn't have a name"), i);
332 }
333 if (name) {
334 GList *lst;
335
336 lst = *srv_cfg_list;
337 while (lst) {
338 if (g_ascii_strcasecmp(name, lst->data) == 0){
339 break;
340 }
341 lst = g_list_next(lst);
342 }
343 if (!lst){
344 *srv_cfg_list = g_list_append(*srv_cfg_list, name);
345 }
346 }
347 }
348 }
349
350 return SRN_OK;
351 }
352
read_server_config_from_server(config_setting_t * server,SrnServerConfig * cfg)353 static SrnRet read_server_config_from_server(config_setting_t *server,
354 SrnServerConfig *cfg){
355 /* Read server meta info,
356 * NOTE: Server password is not stored in configuration file */
357 config_setting_lookup_string_ex(server, "name", &cfg->name);
358 config_setting_lookup_bool_ex(server, "tls", &cfg->irc->tls);
359 config_setting_lookup_bool_ex(server, "tls-noverify", &cfg->irc->tls_noverify);
360 config_setting_lookup_string_ex(server, "encoding", &cfg->irc->encoding);
361 if (cfg->irc->tls_noverify) {
362 cfg->irc->tls = TRUE;
363 }
364
365 /* Read server.addrs */
366 config_setting_t *addrs;
367 addrs = config_setting_lookup(server, "addresses");
368 if (addrs){
369 for (int i = 0, count = config_setting_length(addrs); i < count; i++){
370 char *addr;
371
372 addr = config_setting_get_string_elem_ex(addrs, i);
373 if (addr){
374 SrnRet ret;
375 SrnServerAddr *srv_addr;
376
377 srv_addr = srn_server_addr_new_from_string(addr);
378 ret = srn_server_config_add_addr(cfg, srv_addr);
379 g_free(addr);
380
381 if (!RET_IS_OK(ret)){
382 srn_server_addr_free(srv_addr);
383 return ret;
384 }
385 }
386 }
387 }
388
389 /* Read server.user */
390 config_setting_t *user;
391 user = config_setting_lookup(server, "user");
392 if (user){
393 SrnRet ret;
394 ret = read_user_config_from_user(user, cfg->user);
395 if (!RET_IS_OK(ret)){
396 return ret;
397 }
398 }
399
400 /* Read auto join chat list */
401 config_setting_t *auto_join;
402 auto_join = config_setting_lookup(server, "auto-join");
403 if (auto_join){
404 for (int i = 0; i < config_setting_length(auto_join); i++){
405 const char *val;
406 config_setting_t *chat;
407
408 chat = config_setting_get_elem(auto_join, i);
409 if (!chat) continue;
410 val = config_setting_get_string(chat);
411 if (!val) continue;
412
413 cfg->auto_join_chat_list = g_list_append(
414 cfg->auto_join_chat_list, g_strdup(val));
415 }
416 }
417
418 /* Read autorun command list */
419 config_setting_t *cmds;
420 cmds = config_setting_lookup(server, "auto-run");
421 if (cmds){
422 for (int i = 0; i < config_setting_length(cmds); i++){
423 const char *val;
424 config_setting_t *cmd;
425
426 cmd = config_setting_get_elem(cmds, i);
427 if (!cmd) continue;
428 val = config_setting_get_string(cmd);
429 if (!val) continue;
430
431 cfg->auto_run_cmd_list = g_list_append(cfg->auto_run_cmd_list,
432 g_strdup(val));
433 }
434 }
435
436 return SRN_OK;
437 }
438
read_server_config_from_server_list(config_setting_t * server_list,SrnServerConfig * cfg,const char * srv_name)439 static SrnRet read_server_config_from_server_list(config_setting_t *server_list,
440 SrnServerConfig *cfg, const char *srv_name){
441 int count;
442 SrnRet ret;
443
444 count = config_setting_length(server_list);
445 for (int i = 0; i < count; i++){
446 const char *name = NULL;
447 config_setting_t *server;
448
449 server = config_setting_get_elem(server_list, i);
450 if (!server) break;
451
452 config_setting_lookup_string(server, "name", &name);
453 if (g_strcmp0(srv_name, name) != 0) continue;
454
455 DBG_FR("Read: server-list.[name = %s], srv_name: %s", name, srv_name);
456 ret = read_server_config_from_server(server, cfg);
457 if (!RET_IS_OK(ret)) return ret;
458 }
459
460 return SRN_OK;
461 }
462
read_server_config_from_cfg(config_t * cfg,SrnServerConfig * srv_cfg,const char * srv_name)463 static SrnRet read_server_config_from_cfg(config_t *cfg, SrnServerConfig *srv_cfg,
464 const char *srv_name){
465 SrnRet ret;
466 config_setting_t *server;
467
468 /* Read server */
469 server = config_lookup(cfg, "server");
470 if (server){
471 DBG_FR("Read: server, srv_name: %s", srv_name);
472 ret = read_server_config_from_server(server, srv_cfg);
473 if (!RET_IS_OK(ret)) return ret;
474 }
475
476 /* Read server_list[name = srv_name] */
477 config_setting_t *server_list;
478
479 server_list = config_lookup(cfg, "server-list");
480 if (server_list){
481 ret = read_server_config_from_server_list(server_list, srv_cfg, srv_name);
482 if (!RET_IS_OK(ret)) return ret;
483 }
484
485 return SRN_OK;
486 }
487
read_chat_config_from_chat(config_setting_t * chat,SrnChatConfig * cfg)488 static SrnRet read_chat_config_from_chat(config_setting_t *chat, SrnChatConfig *cfg){
489 config_setting_lookup_bool_ex(chat, "notify", &cfg->ui->notify);
490 config_setting_lookup_bool_ex(chat, "show-topic", &cfg->ui->show_topic);
491 config_setting_lookup_bool_ex(chat, "show-avatar", &cfg->ui->show_avatar);
492 config_setting_lookup_bool_ex(chat, "show-user-list", &cfg->ui->show_user_list);
493 config_setting_lookup_bool_ex(chat, "render-mirc-color", &cfg->render_mirc_color);
494 config_setting_lookup_bool_ex(chat, "preview-url", &cfg->ui->preview_url);
495 config_setting_lookup_bool_ex(chat, "auto-preview-url", &cfg->ui->auto_preview_url);
496 config_setting_lookup_string_ex(chat, "nick-completion-suffix", &cfg->ui->nick_completion_suffix);
497
498 /* Read autorun command list */
499 config_setting_t *cmds;
500 cmds = config_setting_lookup(chat, "auto-run");
501 if (cmds){
502 for (int i = 0; i < config_setting_length(cmds); i++){
503 const char *val;
504 config_setting_t *cmd;
505
506 cmd = config_setting_get_elem(cmds, i);
507 if (!cmd) continue;
508 val = config_setting_get_string(cmd);
509 if (!val) continue;
510
511 cfg->auto_run_cmd_list = g_list_append(cfg->auto_run_cmd_list,
512 g_strdup(val));
513 }
514 }
515
516 return SRN_OK;
517 }
518
read_chat_config_from_chat_list(config_setting_t * chat_list,SrnChatConfig * cfg,const char * chat_name)519 static SrnRet read_chat_config_from_chat_list(config_setting_t *chat_list,
520 SrnChatConfig *cfg, const char *chat_name){
521 SrnRet ret;
522
523 for (int i = 0, count = config_setting_length(chat_list); i < count; i++){
524 const char *name = NULL;
525 config_setting_t *chat;
526
527 chat = config_setting_get_elem(chat_list, i);
528 if (!chat) break;
529 if (config_setting_lookup_string(chat, "name", &name) != CONFIG_TRUE){
530 continue;
531 }
532 if (g_strcmp0(chat_name, name) != 0) continue;
533
534 DBG_FR("Read: chat-list.%s, chat_name: %s", name, chat_name);
535 ret = read_chat_config_from_chat(chat, cfg);
536 if (!RET_IS_OK(ret)) return ret;
537 }
538
539 return SRN_OK;
540 }
541
read_chat_config_from_cfg(config_t * cfg,SrnChatConfig * chat_cfg,const char * srv_name,const char * chat_name)542 static SrnRet read_chat_config_from_cfg(config_t *cfg, SrnChatConfig *chat_cfg,
543 const char *srv_name, const char *chat_name){
544 SrnRet ret;
545
546 /* Read server.chat */
547 config_setting_t *chat;
548
549 chat = config_lookup(cfg, "server.chat");
550 if (chat){
551 DBG_FR("Read: server.chat, srv_name: %s, chat_name: %s", srv_name, chat_name);
552 ret = read_chat_config_from_chat(chat, chat_cfg);
553 if (!RET_IS_OK(ret)) return ret;
554 }
555
556 /* Read server.chat_list[name = chat_name] */
557 if (chat_name){
558 config_setting_t *chat_list;
559
560 chat_list = config_lookup(cfg, "server.chat-list");
561 if (chat_list){
562 ret = read_chat_config_from_chat_list(chat_list, chat_cfg, chat_name);
563 if (!RET_IS_OK(ret)) return ret;
564 }
565 }
566
567 if (srv_name){
568 config_setting_t *server_list;
569
570 server_list = config_lookup(cfg, "server-list");
571 if (server_list){
572 for (int i = 0, count = config_setting_length(server_list); i < count; i++){
573 const char *name = NULL;
574 config_setting_t *server;
575 config_setting_t *chat;
576
577 server = config_setting_get_elem(server_list, i);
578 if (!server) break;
579
580 config_setting_lookup_string(server, "name", &name);
581 if (g_strcmp0(srv_name, name) != 0) continue;
582
583 /* Read server_list.[name = srv_name].chat */
584 chat = config_setting_lookup(server, "chat");
585 if (chat){
586 DBG_FR("Read server-list.[name = %s].chat, srv_name: %s, chat_name: %s",
587 name, srv_name, chat_name);
588 ret = read_chat_config_from_chat(chat, chat_cfg);
589 if (!RET_IS_OK(ret)) return ret;
590 }
591
592 /* Read server_list.[name = srv_name].chat_list[name = chat_name] */
593 if (chat_name){
594 config_setting_t *chat_list;
595
596 chat_list = config_setting_lookup(server, "server.chat-list");
597 if (chat_list){
598 ret = read_chat_config_from_chat_list(chat_list, chat_cfg, chat_name);
599 if (!RET_IS_OK(ret)) return ret;
600 }
601 }
602 }
603 }
604 }
605
606 return SRN_OK;
607 }
608
read_user_config_from_user(config_setting_t * user,SrnUserConfig * cfg)609 static SrnRet read_user_config_from_user(config_setting_t *user, SrnUserConfig *cfg){
610 config_setting_t *login;
611
612 // Read user.login
613 // NOTE: Login password is not stored in configuration file
614 login = config_setting_lookup(user, "login");
615 if (login) {
616 const char *method = NULL;
617
618 config_setting_lookup_string(login, "method", &method);
619 cfg->login->method = srn_login_method_from_string(method);
620
621 config_setting_lookup_string_ex(login, "certificate", &cfg->login->cert_file);
622 }
623
624 config_setting_lookup_string_ex(user, "nickname", &cfg->nick);
625 config_setting_lookup_string_ex(user, "username", &cfg->username);
626 config_setting_lookup_string_ex(user, "realname", &cfg->realname);
627
628 config_setting_lookup_string_ex(user, "part-message", &cfg->part_message);
629 config_setting_lookup_string_ex(user, "kick-message", &cfg->kick_message);
630 config_setting_lookup_string_ex(user, "away-message", &cfg->away_message);
631 config_setting_lookup_string_ex(user, "quit-message", &cfg->quit_message);
632
633 return SRN_OK;
634 }
635
636 /**
637 * @brief Wrapper of config_lookup_string(), This function will allocate a new
638 * string, you should free it by yourself
639 *
640 * @param config
641 * @param path
642 * @param value
643 *
644 * @return
645 */
config_lookup_string_ex(const config_t * config,const char * path,char ** value)646 static int config_lookup_string_ex(const config_t *config, const char *path, char **value){
647 int ret;
648 const char *constval = NULL;
649
650 ret = config_lookup_string(config, path, &constval);
651 if (ret == CONFIG_TRUE){
652 str_assign(value, constval);
653 }
654
655 return ret;
656 }
657
658 /**
659 * @brief Wrapper of config_setting_lookup_string(), This function will
660 * allocate a new string, you should free it by yourself
661 *
662 * @param config
663 * @param path
664 * @param value
665 *
666 * @return
667 */
config_setting_lookup_string_ex(const config_setting_t * config,const char * name,char ** value)668 static int config_setting_lookup_string_ex(const config_setting_t *config,
669 const char *name, char **value){
670 int ret;
671 const char *constval = NULL;
672
673 ret = config_setting_lookup_string(config, name, &constval);
674 if (ret == CONFIG_TRUE){
675 str_assign(value, constval);
676 }
677
678 return ret;
679 }
680
config_setting_get_string_elem_ex(const config_setting_t * setting,int index)681 static char* config_setting_get_string_elem_ex(const config_setting_t *setting,
682 int index){
683 return g_strdup(config_setting_get_string_elem(setting, index));
684 }
685
config_lookup_bool_ex(const config_t * config,const char * name,bool * value)686 static int config_lookup_bool_ex(const config_t *config, const char *name,
687 bool *value){
688 int intval;
689 int ret;
690
691 ret = config_lookup_bool(config, name, &intval);
692 if (ret == CONFIG_TRUE){
693 *value = (bool)intval;
694 }
695
696 return ret;
697 }
698
699 /**
700 * @brief Wrapper of config_setting_lookup_bool(), The "bool" in libconfig is
701 * actually an integer, This function transform it to fit bool (alias of
702 * gboolean) defined in "srain.h"
703 *
704 * @param config
705 * @param name
706 * @param value
707 *
708 * @return
709 */
config_setting_lookup_bool_ex(const config_setting_t * config,const char * name,bool * value)710 static int config_setting_lookup_bool_ex(const config_setting_t *config,
711 const char *name, bool *value){
712 int intval;
713 int ret;
714
715 ret = config_setting_lookup_bool(config, name, &intval);
716 if (ret == CONFIG_TRUE){
717 *value = (bool)intval;
718 }
719
720 return ret;
721 }
722