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 
30 using namespace fawkes;
31 
32 extern "C" void finalize();
33 
34 // Global variables
35 FawkesNetworkClient * g_fnet_client = NULL;
36 NetworkConfiguration *g_config = NULL;
37 
38 extern "C" Term *
39 action_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 
131 extern "C" PBoolean
132 pred_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 
142 extern "C" Term *
143 func_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. */
160 extern "C" void
161 init()
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. */
186 extern "C" void
187 finalize()
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 }
fawkes::NetworkConfiguration::set_mirror_mode
virtual void set_mirror_mode(bool mirror)
Enable or disable mirror mode.
Definition: netconf.cpp:1269
fawkes::FawkesNetworkClient::connect
void connect()
Connect to remote.
Definition: client.cpp:424
fawkes::NetworkConfiguration
Remote configuration via Fawkes net.
Definition: netconf.h:50
fawkes
Fawkes library namespace.
fawkes::NetworkConfiguration::search
ValueIterator * search(const char *path)
Iterator with search results.
Definition: netconf.cpp:1384
fawkes::Exception::what_no_backtrace
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
fawkes::FawkesNetworkClient
Simple Fawkes network client.
Definition: client.h:52
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36