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 <netcomm/fawkes/client.h>
24 
25 #include <plugins/openprs/mod_utils.h>
26 #include <config/netconf.h>
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 
39 extern "C"
40 Term *
41 action_config_load(TermList terms)
42 {
43  Term *prefix;
44  ACTION_ASSERT_ARG_LENGTH("config-load", terms, 1);
45  ACTION_SET_AND_ASSERT_ARG_TYPE("config-load", prefix, terms, 1, STRING);
46 
47 #if __cplusplus >= 201103L
48  std::unique_ptr<Configuration::ValueIterator> v(g_config->search(prefix->u.string));
49 #else
50  std::auto_ptr<Configuration::ValueIterator> v(g_config->search(prefix->u.string));
51 #endif
52  while (v->next()) {
53  TermList tl = sl_make_slist();
54  tl = build_term_list(tl, build_string(v->path()));
55 
56 
57  std::string type = "";
58  std::string value = v->get_as_string();
59 
60  if (v->is_uint()) {
61  tl = build_term_list(tl, build_id(declare_atom("UINT")));
62  if (v->is_list()) {
63  TermList ll = sl_make_slist();
64  std::vector<unsigned int> uints = v->get_uints();
65  for (size_t i = 0; i < uints.size(); ++i) {
66  ll = build_term_list(ll, build_long_long(uints[i]));
67  }
68  tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
69  } else {
70  tl = build_term_list(tl, build_long_long(v->get_uint()));
71  }
72  } else if (v->is_int()) {
73  tl = build_term_list(tl, build_id(declare_atom("INT")));
74  if (v->is_list()) {
75  TermList ll = sl_make_slist();
76  std::vector<int> ints = v->get_ints();
77  for (size_t i = 0; i < ints.size(); ++i) {
78  ll = build_term_list(ll, build_integer(ints[i]));
79  }
80  tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
81  } else {
82  tl = build_term_list(tl, build_integer(v->get_int()));
83  }
84  } else if (v->is_float()) {
85  tl = build_term_list(tl, build_id(declare_atom("FLOAT")));
86  if (v->is_list()) {
87  TermList ll = sl_make_slist();
88  std::vector<float> floats = v->get_floats();
89  for (size_t i = 0; i < floats.size(); ++i) {
90  ll = build_term_list(ll, build_float(floats[i]));
91  }
92  tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
93  } else {
94  tl = build_term_list(tl, build_float(v->get_float()));
95  }
96  } else if (v->is_bool()) {
97  tl = build_term_list(tl, build_id(declare_atom("BOOL")));
98  if (v->is_list()) {
99  TermList ll = sl_make_slist();
100  std::vector<bool> bools = v->get_bools();
101  for (size_t i = 0; i < bools.size(); ++i) {
102  ll = build_term_list(ll, bools[i] ? build_t() : build_nil());
103  }
104  tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
105  } else {
106  tl = build_term_list(tl, v->get_bool() ? build_t() : build_nil());
107  }
108  } else if (v->is_string()) {
109  tl = build_term_list(tl, build_id(declare_atom("STRING")));
110  if (v->is_list()) {
111  TermList ll = sl_make_slist();
112  std::vector<std::string> strings = v->get_strings();
113  for (size_t i = 0; i < strings.size(); ++i) {
114  ll = build_term_list(ll, build_string(strings[i].c_str()));
115  }
116  tl = build_term_list(tl, build_term_l_list_from_c_list(ll));
117  } else {
118  tl = build_term_list(tl, build_string(v->get_string().c_str()));
119  }
120  } else {
121  fprintf(stderr, "Warn[config-load]: value at '%s' of unknown type '%s'",
122  v->path(), v->type());
123  }
124 
125  add_external_fact((char *)"confval", tl);
126  }
127 
128  TermList tl = sl_make_slist();
129  tl = build_term_list(tl, build_string(prefix->u.string));
130  add_external_fact((char *)"config-loaded", tl);
131 
132  ACTION_FINAL();
133 }
134 
135 
136 extern "C"
137 PBoolean
138 pred_string_prefix_p(TermList terms)
139 {
140  Term *str, *prefix;
141  ACTION_ASSERT_B_ARG_LENGTH("string-prefix-p", terms, 2);
142  ACTION_SET_AND_ASSERT_B_ARG_TYPE("string-prefix-p", str, terms, 1, STRING);
143  ACTION_SET_AND_ASSERT_B_ARG_TYPE("string-prefix-p", prefix, terms, 2, STRING);
144 
145  return (strncmp(str->u.string, prefix->u.string, strlen(prefix->u.string)) == 0);
146 }
147 
148 extern "C"
149 Term *
150 func_string_remove_prefix(TermList terms)
151 {
152  Term *str, *prefix;
153  ACTION_ASSERT_ARG_LENGTH("string-remove-prefix", terms, 2);
154  ACTION_SET_AND_ASSERT_ARG_TYPE("string-remove-prefix", str, terms, 1, STRING);
155  ACTION_SET_AND_ASSERT_ARG_TYPE("string-remove-prefix", prefix, terms, 2, STRING);
156 
157  if (! pred_string_prefix_p(terms))
158  return build_string(str->u.string);
159 
160  if (strlen(prefix->u.string) >= strlen(str->u.string))
161  return build_string("");
162 
163  return build_string(&str->u.string[strlen(prefix->u.string)]);
164 }
165 
166 
167 /** Entry function for the OpenPRS module. */
168 extern "C"
169 void init()
170 {
171  printf("*** LOADING mod_config\n");
172 
173  std::string fawkes_host;
174  unsigned short fawkes_port = 0;
175  get_fawkes_host_port(fawkes_host, fawkes_port);
176 
177  printf("Connecting to Fawkes at %s:%u\n", fawkes_host.c_str(), fawkes_port);
178  try {
179  g_fnet_client = new FawkesNetworkClient(fawkes_host.c_str(), fawkes_port);
180  g_fnet_client->connect();
181  g_config = new NetworkConfiguration(g_fnet_client);
182  g_config->set_mirror_mode(true);
183  } catch (Exception &e) {
184  fprintf(stderr, "Error: cannot establish network connection: %s\n",
185  e.what_no_backtrace());
186  }
187 
188  make_and_declare_action("config-load", action_config_load, 1);
189  make_and_declare_eval_pred("string-prefix-p", pred_string_prefix_p, 2, FALSE);
190  make_and_declare_eval_funct("string-remove-prefix", func_string_remove_prefix, 2);
191  add_user_end_kernel_hook(finalize);
192 }
193 
194 /** Finalization function for the OpenPRS module. */
195 extern "C"
196 void finalize()
197 {
198  printf("*** DESTROYING mod_config\n");
199  delete g_config;
200  g_config = NULL;
201  delete g_fnet_client;
202  g_fnet_client = NULL;
203 }
Simple Fawkes network client.
Definition: client.h:52
Fawkes library namespace.
void connect()
Connect to remote.
Definition: client.cpp:417
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:686
virtual void set_mirror_mode(bool mirror)
Enable or disable mirror mode.
Definition: netconf.cpp:1324
ValueIterator * search(const char *path)
Iterator with search results.
Definition: netconf.cpp:1448
Remote configuration via Fawkes net.
Definition: netconf.h:49