Fawkes API Fawkes Development Version
mod_config.cpp
1
2/***************************************************************************
3 * mod_config.cpp - OpenPRS config module
4 *
5 * Created: Fri Sep 05 13:00:11 2014
6 * Copyright 2014 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * Read the full text in the LICENSE.GPL file in the doc directory.
20 */
21
22// this must come first due to a define of enqueue in OpenPRS' slistPack_f.h
23#include <config/netconf.h>
24#include <netcomm/fawkes/client.h>
25#include <plugins/openprs/mod_utils.h>
26
27#include <memory>
28#include <oprs_f-pub.h>
29
30using namespace fawkes;
31
32extern "C" void finalize();
33
34// Global variables
35FawkesNetworkClient * g_fnet_client = NULL;
36NetworkConfiguration *g_config = NULL;
37
38extern "C" Term *
39action_config_load(TermList terms)
40{
41 Term *prefix;
42 ACTION_ASSERT_ARG_LENGTH("config-load", terms, 1);
43 ACTION_SET_AND_ASSERT_ARG_TYPE("config-load", prefix, terms, 1, STRING);
44
45#if __cplusplus >= 201103L
46 std::unique_ptr<Configuration::ValueIterator> v(g_config->search(prefix->u.string));
47#else
48 std::auto_ptr<Configuration::ValueIterator> v(g_config->search(prefix->u.string));
49#endif
50 while (v->next()) {
51 TermList tl = sl_make_slist();
52 tl = build_term_list(tl, build_string(v->path()));
53
54 if (v->is_uint()) {
55 tl = build_term_list(tl, build_id(declare_atom("UINT")));
56 if (v->is_list()) {
57 TermList ll = sl_make_slist();
58 std::vector<unsigned int> uints = v->get_uints();
59 for (size_t i = 0; i < uints.size(); ++i) {
60 ll = build_term_list(ll, build_long_long(uints[i]));
61 }
62 tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
63 } else {
64 tl = build_term_list(tl, build_long_long(v->get_uint()));
65 }
66 } else if (v->is_int()) {
67 tl = build_term_list(tl, build_id(declare_atom("INT")));
68 if (v->is_list()) {
69 TermList ll = sl_make_slist();
70 std::vector<int> ints = v->get_ints();
71 for (size_t i = 0; i < ints.size(); ++i) {
72 ll = build_term_list(ll, build_integer(ints[i]));
73 }
74 tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
75 } else {
76 tl = build_term_list(tl, build_integer(v->get_int()));
77 }
78 } else if (v->is_float()) {
79 tl = build_term_list(tl, build_id(declare_atom("FLOAT")));
80 if (v->is_list()) {
81 TermList ll = sl_make_slist();
82 std::vector<float> floats = v->get_floats();
83 for (size_t i = 0; i < floats.size(); ++i) {
84 ll = build_term_list(ll, build_float(floats[i]));
85 }
86 tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
87 } else {
88 tl = build_term_list(tl, build_float(v->get_float()));
89 }
90 } else if (v->is_bool()) {
91 tl = build_term_list(tl, build_id(declare_atom("BOOL")));
92 if (v->is_list()) {
93 TermList ll = sl_make_slist();
94 std::vector<bool> bools = v->get_bools();
95 for (size_t i = 0; i < bools.size(); ++i) {
96 ll = build_term_list(ll, bools[i] ? build_t() : build_nil());
97 }
98 tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
99 } else {
100 tl = build_term_list(tl, v->get_bool() ? build_t() : build_nil());
101 }
102 } else if (v->is_string()) {
103 tl = build_term_list(tl, build_id(declare_atom("STRING")));
104 if (v->is_list()) {
105 TermList ll = sl_make_slist();
106 std::vector<std::string> strings = v->get_strings();
107 for (size_t i = 0; i < strings.size(); ++i) {
108 ll = build_term_list(ll, build_string(strings[i].c_str()));
109 }
110 tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
111 } else {
112 tl = build_term_list(tl, build_string(v->get_string().c_str()));
113 }
114 } else {
115 fprintf(stderr,
116 "Warn[config-load]: value at '%s' of unknown type '%s'",
117 v->path(),
118 v->type());
119 }
120
121 add_external_fact((char *)"confval", tl);
122 }
123
124 TermList tl = sl_make_slist();
125 tl = build_term_list(tl, build_string(prefix->u.string));
126 add_external_fact((char *)"config-loaded", tl);
127
128 ACTION_FINAL();
129}
130
131extern "C" PBoolean
132pred_string_prefix_p(TermList terms)
133{
134 Term *str, *prefix;
135 ACTION_ASSERT_B_ARG_LENGTH("string-prefix-p", terms, 2);
136 ACTION_SET_AND_ASSERT_B_ARG_TYPE("string-prefix-p", str, terms, 1, STRING);
137 ACTION_SET_AND_ASSERT_B_ARG_TYPE("string-prefix-p", prefix, terms, 2, STRING);
138
139 return (strncmp(str->u.string, prefix->u.string, strlen(prefix->u.string)) == 0);
140}
141
142extern "C" Term *
143func_string_remove_prefix(TermList terms)
144{
145 Term *str, *prefix;
146 ACTION_ASSERT_ARG_LENGTH("string-remove-prefix", terms, 2);
147 ACTION_SET_AND_ASSERT_ARG_TYPE("string-remove-prefix", str, terms, 1, STRING);
148 ACTION_SET_AND_ASSERT_ARG_TYPE("string-remove-prefix", prefix, terms, 2, STRING);
149
150 if (!pred_string_prefix_p(terms))
151 return build_string(str->u.string);
152
153 if (strlen(prefix->u.string) >= strlen(str->u.string))
154 return build_string("");
155
156 return build_string(&str->u.string[strlen(prefix->u.string)]);
157}
158
159/** Entry function for the OpenPRS module. */
160extern "C" void
161init()
162{
163 printf("*** LOADING mod_config\n");
164
165 std::string fawkes_host;
166 unsigned short fawkes_port = 0;
167 get_fawkes_host_port(fawkes_host, fawkes_port);
168
169 printf("Connecting to Fawkes at %s:%u\n", fawkes_host.c_str(), fawkes_port);
170 try {
171 g_fnet_client = new FawkesNetworkClient(fawkes_host.c_str(), fawkes_port);
172 g_fnet_client->connect();
173 g_config = new NetworkConfiguration(g_fnet_client);
174 g_config->set_mirror_mode(true);
175 } catch (Exception &e) {
176 fprintf(stderr, "Error: cannot establish network connection: %s\n", e.what_no_backtrace());
177 }
178
179 make_and_declare_action("config-load", action_config_load, 1);
180 make_and_declare_eval_pred("string-prefix-p", pred_string_prefix_p, 2, FALSE);
181 make_and_declare_eval_funct("string-remove-prefix", func_string_remove_prefix, 2);
182 add_user_end_kernel_hook(finalize);
183}
184
185/** Finalization function for the OpenPRS module. */
186extern "C" void
187finalize()
188{
189 printf("*** DESTROYING mod_config\n");
190 delete g_config;
191 g_config = NULL;
192 delete g_fnet_client;
193 g_fnet_client = NULL;
194}
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
Simple Fawkes network client.
Definition: client.h:52
void connect()
Connect to remote.
Definition: client.cpp:424
Remote configuration via Fawkes net.
Definition: netconf.h:50
ValueIterator * search(const char *path)
Iterator with search results.
Definition: netconf.cpp:1384
virtual void set_mirror_mode(bool mirror)
Enable or disable mirror mode.
Definition: netconf.cpp:1269
Fawkes library namespace.