Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
netconf.cpp
1 
2 /***************************************************************************
3  * netconf.cpp - Fawkes remote configuration access via Fawkes net
4  *
5  * Created: Sun Jan 07 15:04:41 2007
6  * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <config/netconf.h>
25 #include <config/net_messages.h>
26 #include <config/sqlite.h>
27 #include <config/net_list_content.h>
28 
29 #include <core/threading/mutex.h>
30 #include <core/threading/interruptible_barrier.h>
31 #include <netcomm/fawkes/client.h>
32 #include <netcomm/fawkes/message.h>
33 #include <netcomm/utils/exceptions.h>
34 
35 #include <logging/liblogger.h>
36 #include <utils/misc/string_conversions.h>
37 
38 #ifndef _GNU_SOURCE
39 #define _GNU_SOURCE
40 #endif
41 #include <cstring>
42 #include <cstdlib>
43 
44 namespace fawkes {
45 
46 /** @class CannotEnableMirroringException <config/netconf.h>
47  * Thrown if enabling mirror mode failed.
48  */
49 
50 /** Constructor.
51  * @param msg message describing the problem
52  */
54  : Exception("Could not enable mirroring: %s", msg)
55 {
56 }
57 
58 
59 /** @class NetworkConfiguration <config/netconf.h>
60  * Remote configuration via Fawkes net.
61  * This implementation of the Configuration interface allows for remote access
62  * to a Fawkes process implemented using the ConfigurationManager.
63  *
64  * The network configuration can operator in two modes. In mirror and in non-mirror
65  * mode. The non-mirror mode is recommended if only a few operations have to be
66  * carried out like getting only a very few values or setting a single value.
67  * The mirror mode is for longer usage periods and on-the-fly updates. In mirror
68  * mode the complete configuration is copied once from the Fawkes process and then
69  * all updates are incorporated into the local database. You can register change
70  * handlers to be notified as soon as someone modifies a value.
71  *
72  */
73 
74 /** Constructor.
75  * @param c Fawkes network client (thread).
76  * @param mirror_timeout_sec timeout in seconds for initiating mirroring
77  */
79  unsigned int mirror_timeout_sec)
80 {
81  __mirror_timeout_sec = mirror_timeout_sec;
82  __connected = c->connected();
83  this->c = c;
84  try {
85  c->register_handler(this, FAWKES_CID_CONFIGMANAGER);
86  } catch (Exception &e) {
87  e.append("Failed to register for config manager component on network client");
88  throw;
89  }
90  mutex = new Mutex();
91  msg = NULL;
92  __mirror_mode = false;
93  __mirror_mode_before_connection_dead = false;
94  __mirror_init_barrier = NULL;
95 }
96 
97 
98 /** Destructor. */
100 {
101  set_mirror_mode(false);
102  c->deregister_handler(FAWKES_CID_CONFIGMANAGER);
103  if (msg != NULL) {
104  msg->unref();
105  }
106  delete __mirror_init_barrier;
107  delete mutex;
108 }
109 
110 
111 /** Load configuration.
112  * This is a noop for the NetworkConfiguration.
113  * @param name name of the host-based database. This should be a name of the form
114  * hostname.db, where hostname is the unqualified part of the hostname.
115  * @param defaults_name name of the default database. Should be defaults.db
116  * @param tag optional tag to restore
117  */
118 void
119 NetworkConfiguration::load(const char *name,
120  const char *defaults_name,
121  const char *tag)
122 {
123 }
124 
125 
126 /** Copy all values from the given configuration.
127  * All values from the given configuration are copied. Old values are not erased
128  * so that the copied values will overwrite existing values, new values are
129  * created, but values existent in current config but not in the copie config
130  * will remain unchanged.
131  * @param copyconf configuration to copy
132  */
133 void
135 {
136  copyconf->lock();
137  Configuration::ValueIterator *i = copyconf->iterator();
138  while ( i->next() ) {
139  if ( i->is_float() ) {
140  set_float(i->path(), i->get_float());
141  } else if ( i->is_int() ) {
142  set_int(i->path(), i->get_int());
143  } else if ( i->is_uint() ) {
144  set_uint(i->path(), i->get_uint());
145  } else if ( i->is_bool() ) {
146  set_bool(i->path(), i->get_bool());
147  } else if ( i->is_string() ) {
148  std::string s = i->get_string();
149  set_string(i->path(), s);
150  }
151  }
152  delete i;
153  copyconf->unlock();
154 }
155 
156 
157 void
159 {
160  mutex->lock();
161 
162  mutex->unlock();
163 }
164 
165 
166 std::list<std::string>
168 {
169  mutex->lock();
170  std::list<std::string> l;
171  mutex->unlock();
172  return l;
173 }
174 
175 
176 bool
178 {
179  ValueIterator *i = get_value(path);
180  bool rv = i->valid();
181  delete i;
182  return rv;
183 }
184 
185 
186 bool
188 {
189  ValueIterator *i = get_value(path);
190  bool rv = i->is_default();
191  delete i;
192  return rv;
193 }
194 
195 
196 /** Get type of field.
197  * @param path path
198  * @return string of type
199  */
200 std::string
202 {
203  std::string s = "";
204  mutex->lock();
205  if ( __mirror_mode ) {
206  s = mirror_config->get_type(path);
207  mutex->unlock();
208  } else {
209  mutex->unlock();
211  s = i->type();
212  delete i;
213  }
214  return s;
215 }
216 
217 
218 bool
220 {
221  return (get_type(path) == "float");
222 }
223 
224 
225 bool
227 {
228  return (get_type(path) == "unsigned int");
229 }
230 
231 
232 bool
234 {
235  return (get_type(path) == "int");
236 }
237 
238 
239 bool
241 {
242  return (get_type(path) == "bool");
243 }
244 
245 
246 bool
248 {
249  return (get_type(path) == "string");
250 }
251 
252 
253 void
254 NetworkConfiguration::send_get(const char *path, unsigned int msgid)
255 {
256  if ( ! __connected ) {
257  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
258  "client connection is not alive");
259  }
260  config_getval_msg_t *g = (config_getval_msg_t *)calloc(1, sizeof(config_getval_msg_t));
261  strncpy(g->cp.path, path, CONFIG_MSG_PATH_LENGTH);
262  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
263  msgid,
264  g, sizeof(config_getval_msg_t));
265  c->enqueue_and_wait(omsg);
266 
267  if ( msg == NULL ) {
268  mutex->unlock();
269  throw NullPointerException("NetworkConfiguration::send_get: msg == NULL");
270  }
271 
272  if ( msg->msgid() != msgid ) {
273  msg->unref();
274  msg = NULL;
275  mutex->unlock();
276  throw TypeMismatchException("NetworkConfiguration::send_get: msg type not float");
277  }
278 }
279 
280 
281 float
283 {
284  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
285  throw OutOfBoundsException("NetworkConfiguration::get_float: "
286  "Maximum length for path exceeded");
287  }
288  if ( ! __connected ) {
289  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
290  "client connection is not alive");
291  }
292 
293  float f;
294  mutex->lock();
295 
296  if ( __mirror_mode ) {
297  try {
298  f = mirror_config->get_float(path);
299  } catch (Exception &e) {
300  e.append("NetworkConfiguration[mirroring]::get_float: exception in mirror database");
301  mutex->unlock();
302  throw;
303  }
304  } else {
305  try {
306  send_get(path, MSG_CONFIG_GET_FLOAT);
307 
309  f = fm->f;
310 
311  msg->unref();
312  msg = NULL;
313 
314  } catch (Exception &e) {
315  e.append("NetworkConfiguration::get_float: Fetching float failed");
316  if ( msg != NULL ) {
317  msg->unref();
318  msg = NULL;
319  }
320  mutex->unlock();
321  throw;
322  }
323  }
324 
325  mutex->unlock();
326 
327  return f;
328 }
329 
330 
331 unsigned int
333 {
334  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
335  throw OutOfBoundsException("NetworkConfiguration::get_uint: "
336  "Maximum length for path exceeded");
337  }
338  if ( ! __connected ) {
339  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
340  "client connection is not alive");
341  }
342 
343  unsigned int u;
344  mutex->lock();
345 
346  if ( __mirror_mode ) {
347  try {
348  u = mirror_config->get_uint(path);
349  } catch (Exception &e) {
350  e.append("NetworkConfiguration[mirroring]::get_uint: exception in mirror database");
351  mutex->unlock();
352  throw;
353  }
354  } else {
355  try {
356  send_get(path, MSG_CONFIG_GET_UINT);
357 
359  u = um->u;
360 
361  msg->unref();
362  msg = NULL;
363 
364  } catch (Exception &e) {
365  e.append("NetworkConfiguration::get_uint: Fetching unsigned int failed");
366  if ( msg != NULL ) {
367  msg->unref();
368  msg = NULL;
369  }
370  mutex->unlock();
371  throw;
372  }
373  }
374 
375  mutex->unlock();
376 
377  return u;
378 }
379 
380 
381 int
383 {
384  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
385  throw OutOfBoundsException("NetworkConfiguration::get_int: "
386  "Maximum length for path exceeded");
387  }
388  if ( ! __connected ) {
389  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
390  "client connection is not alive");
391  }
392 
393  int i;
394  mutex->lock();
395 
396  if ( __mirror_mode ) {
397  try {
398  i = mirror_config->get_int(path);
399  } catch (Exception &e) {
400  e.append("NetworkConfiguration[mirroring]::get_int: exception in mirror database");
401  mutex->unlock();
402  throw;
403  }
404  } else {
405  try {
406  send_get(path, MSG_CONFIG_GET_INT);
407 
409  i = im->i;
410 
411  msg->unref();
412  msg = NULL;
413 
414  } catch (Exception &e) {
415  e.append("NetworkConfiguration::get_int: Fetching int failed");
416  if ( msg != NULL ) {
417  msg->unref();
418  msg = NULL;
419  }
420  mutex->unlock();
421  throw;
422  }
423  }
424 
425  mutex->unlock();
426 
427  return i;
428 }
429 
430 
431 bool
433 {
434  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
435  throw OutOfBoundsException("NetworkConfiguration::get_bool: "
436  "Maximum length for path exceeded");
437  }
438  if ( ! __connected ) {
439  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
440  "client connection is not alive");
441  }
442 
443  bool b;
444  mutex->lock();
445 
446  if ( __mirror_mode ) {
447  try {
448  b = mirror_config->get_bool(path);
449  } catch (Exception &e) {
450  e.append("NetworkConfiguration[mirroring]::get_bool: exception in mirror database");
451  mutex->unlock();
452  throw;
453  }
454  } else {
455  try {
456  send_get(path, MSG_CONFIG_GET_BOOL);
457 
459  b = (bm->b != 0);
460 
461  msg->unref();
462  msg = NULL;
463 
464  } catch (Exception &e) {
465  e.append("NetworkConfiguration::get_bool: Fetching bool failed");
466  if ( msg != NULL ) {
467  msg->unref();
468  msg = NULL;
469  }
470  mutex->unlock();
471  throw;
472  }
473  }
474 
475  mutex->unlock();
476 
477  return b;
478 }
479 
480 
481 std::string
483 {
484  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
485  throw OutOfBoundsException("NetworkConfiguration::get_string: "
486  "Maximum length for path exceeded");
487  }
488  if ( ! __connected ) {
489  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
490  "client connection is not alive");
491  }
492 
493  std::string s;
494  mutex->lock();
495 
496  if ( __mirror_mode ) {
497  try {
498  s = mirror_config->get_string(path);
499  } catch (Exception &e) {
500  e.append("NetworkConfiguration[mirroring]::get_string: exception in mirror database");
501  mutex->unlock();
502  throw;
503  }
504  } else {
505  try {
506  send_get(path, MSG_CONFIG_GET_STRING);
507 
509  s = sm->s;
510 
511  msg->unref();
512  msg = NULL;
513 
514  } catch (Exception &e) {
515  e.append("NetworkConfiguration::get_string: Fetching int failed");
516  if ( msg != NULL ) {
517  msg->unref();
518  msg = NULL;
519  }
520  mutex->unlock();
521  throw;
522  }
523  }
524 
525  mutex->unlock();
526 
527  return s;
528 }
529 
530 
531 std::string
533 {
534  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
535  throw OutOfBoundsException("NetworkConfiguration::get_comment: "
536  "Maximum length for path exceeded");
537  }
538  if ( ! __connected ) {
539  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
540  "client connection is not alive");
541  }
542 
543  std::string s;
544  mutex->lock();
545 
546  if ( __mirror_mode ) {
547  try {
548  s = mirror_config->get_comment(path);
549  } catch (Exception &e) {
550  e.append("NetworkConfiguration[mirroring]::get_comment: exception in mirror database");
551  mutex->unlock();
552  throw;
553  }
554  } else {
555  try {
556  send_get(path, MSG_CONFIG_GET_COMMENT);
557 
559  s = sm->s;
560 
561  msg->unref();
562  msg = NULL;
563 
564  } catch (Exception &e) {
565  e.append("NetworkConfiguration::get_comment: Fetching int failed");
566  if ( msg != NULL ) {
567  msg->unref();
568  msg = NULL;
569  }
570  mutex->unlock();
571  throw;
572  }
573  }
574 
575  mutex->unlock();
576 
577  return s;
578 }
579 
580 
581 std::string
583 {
584  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
585  throw OutOfBoundsException("NetworkConfiguration::get_default_comment: "
586  "Maximum length for path exceeded");
587  }
588  if ( ! __connected ) {
589  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
590  "client connection is not alive");
591  }
592 
593  std::string s;
594  mutex->lock();
595 
596  if ( __mirror_mode ) {
597  try {
598  s = mirror_config->get_default_comment(path);
599  } catch (Exception &e) {
600  e.append("NetworkConfiguration[mirroring]::get_default_comment: "
601  "exception in mirror database");
602  mutex->unlock();
603  throw;
604  }
605  } else {
606  try {
607  send_get(path, MSG_CONFIG_GET_DEFAULT_COMMENT);
608 
610  s = sm->s;
611 
612  msg->unref();
613  msg = NULL;
614 
615  } catch (Exception &e) {
616  e.append("NetworkConfiguration::get_comment: Fetching int failed");
617  if ( msg != NULL ) {
618  msg->unref();
619  msg = NULL;
620  }
621  mutex->unlock();
622  throw;
623  }
624  }
625 
626  mutex->unlock();
627 
628  return s;
629 }
630 
631 
634 {
635  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
636  throw OutOfBoundsException("NetworkConfiguration::get_value: "
637  "Maximum length for path exceeded");
638  }
639  if ( ! __connected ) {
640  throw ConnectionDiedException("NetworkConfiguration: Cannot send get, "
641  "client connection is not alive");
642  }
643 
645  mutex->lock();
646 
647  if ( __mirror_mode ) {
648  try {
649  i = mirror_config->get_value(path);
650  } catch (Exception &e) {
651  e.append("NetworkConfiguration[mirroring]::get_float: exception in mirror database");
652  mutex->unlock();
653  throw;
654  }
655  } else {
657  strncpy(g->cp.path, path, CONFIG_MSG_PATH_LENGTH);
658  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
659  MSG_CONFIG_GET_VALUE,
660  g, sizeof(config_getval_msg_t));
661  c->enqueue_and_wait(omsg);
662 
663  if ( msg == NULL ) {
664  mutex->unlock();
665  throw NullPointerException("NetworkConfiguration::get_value: msg == NULL");
666  }
667 
668  i = new NetConfValueIterator(msg);
669 
670  msg->unref();
671  msg = NULL;
672  }
673 
674  mutex->unlock();
675 
676  return i;
677 }
678 
679 
680 void
681 NetworkConfiguration::set_float_internal(unsigned int msg_type,
682  const char *path, float f)
683 {
684  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
685  throw OutOfBoundsException("NetworkConfiguration::set_float: "
686  "Maximum length for path exceeded");
687  }
688  if ( ! __connected ) {
689  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
690  "client connection is not alive");
691  }
692 
693  mutex->lock();
694  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
695  msg_type,
696  sizeof(config_float_value_msg_t));
697  config_float_value_msg_t *fm = omsg->msg<config_float_value_msg_t>();
698  strncpy(fm->cp.path, path, CONFIG_MSG_PATH_LENGTH);
699  fm->f = f;
700  c->enqueue_and_wait(omsg);
701  if ( ! __mirror_mode && (msg != NULL) ) {
702  msg->unref();
703  msg = NULL;
704  }
705  mutex->unlock();
706 }
707 
708 
709 void
710 NetworkConfiguration::set_float(const char *path, float f)
711 {
712  set_float_internal(MSG_CONFIG_SET_FLOAT, path, f);
713 }
714 
715 
716 void
717 NetworkConfiguration::set_default_float(const char *path, float f)
718 {
719  set_float_internal(MSG_CONFIG_SET_DEFAULT_FLOAT, path, f);
720 }
721 
722 
723 void
724 NetworkConfiguration::set_uint_internal(unsigned int msg_type,
725  const char *path, unsigned int uint)
726 {
727  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
728  throw OutOfBoundsException("NetworkConfiguration::set_uint: "
729  "Maximum length for path exceeded");
730  }
731  if ( ! __connected ) {
732  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
733  "client connection is not alive");
734  }
735 
736  mutex->lock();
737  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
738  msg_type,
739  sizeof(config_uint_value_msg_t));
740  config_uint_value_msg_t *m = omsg->msg<config_uint_value_msg_t>();
741  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
742  m->u = uint;
743  c->enqueue_and_wait(omsg);
744  if ( ! __mirror_mode && (msg != NULL) ) {
745  msg->unref();
746  msg = NULL;
747  }
748  mutex->unlock();
749 }
750 
751 
752 void
753 NetworkConfiguration::set_uint(const char *path, unsigned int uint)
754 {
755  set_uint_internal(MSG_CONFIG_SET_UINT, path, uint);
756 }
757 
758 
759 void
760 NetworkConfiguration::set_default_uint(const char *path, unsigned int uint)
761 {
762  set_uint_internal(MSG_CONFIG_SET_DEFAULT_UINT, path, uint);
763 }
764 
765 
766 void
767 NetworkConfiguration::set_int_internal(unsigned int msg_type,
768  const char *path, int i)
769 {
770  if ( ! __connected ) {
771  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
772  "client connection is not alive");
773  }
774 
775  mutex->lock();
776  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
777  msg_type,
778  sizeof(config_int_value_msg_t));
779  config_int_value_msg_t *m = omsg->msg<config_int_value_msg_t>();
780  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
781  m->i = i;
782  c->enqueue_and_wait(omsg);
783  if ( ! __mirror_mode && (msg != NULL) ) {
784  msg->unref();
785  msg = NULL;
786  }
787  mutex->unlock();
788 }
789 
790 
791 void
792 NetworkConfiguration::set_int(const char *path, int i)
793 {
794  set_int_internal(MSG_CONFIG_SET_INT, path, i);
795 }
796 
797 
798 void
800 {
801  set_int_internal(MSG_CONFIG_SET_DEFAULT_INT, path, i);
802 }
803 
804 
805 void
806 NetworkConfiguration::set_bool_internal(unsigned int msg_type,
807  const char *path, bool b)
808 {
809  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
810  throw OutOfBoundsException("NetworkConfiguration::set_bool: "
811  "Maximum length for path exceeded");
812  }
813  if ( ! __connected ) {
814  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
815  "client connection is not alive");
816  }
817 
818  mutex->lock();
819  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
820  msg_type,
821  sizeof(config_bool_value_msg_t));
822  config_bool_value_msg_t *m = omsg->msg<config_bool_value_msg_t>();
823  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
824  m->b = (b ? 1 : 0);
825  c->enqueue_and_wait(omsg);
826  if ( ! __mirror_mode && (msg != NULL) ) {
827  msg->unref();
828  msg = NULL;
829  }
830  mutex->unlock();
831 }
832 
833 
834 void
835 NetworkConfiguration::set_bool(const char *path, bool b)
836 {
837  set_bool_internal(MSG_CONFIG_SET_BOOL, path, b);
838 }
839 
840 
841 void
842 NetworkConfiguration::set_default_bool(const char *path, bool b)
843 {
844  set_bool_internal(MSG_CONFIG_SET_DEFAULT_BOOL, path, b);
845 }
846 
847 
848 void
849 NetworkConfiguration::set_string_internal(unsigned int msg_type,
850  const char *path,
851  const char *s)
852 {
853  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
854  throw OutOfBoundsException("NetworkConfiguration::set_string: "
855  "Maximum length for path exceeded");
856  }
857  if ( ! __connected ) {
858  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
859  "client connection is not alive");
860  }
861 
862  mutex->lock();
863  size_t s_length = strlen(s);
864  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
865  msg_type,
866  sizeof(config_string_value_msg_t) + s_length);
867  config_string_value_msg_t *m = omsg->msgge<config_string_value_msg_t>();
868  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
869  strcpy(m->s, s);
870  c->enqueue_and_wait(omsg);
871  if ( ! __mirror_mode && (msg != NULL) ) {
872  msg->unref();
873  msg = NULL;
874  }
875  mutex->unlock();
876 }
877 
878 
879 void
880 NetworkConfiguration::set_string(const char *path, const char *s)
881 {
882  set_string_internal(MSG_CONFIG_SET_STRING, path, s);
883 }
884 
885 
886 void
887 NetworkConfiguration::set_default_string(const char *path, const char *s)
888 {
889  set_string_internal(MSG_CONFIG_SET_DEFAULT_STRING, path, s);
890 }
891 
892 
893 void
894 NetworkConfiguration::set_string(const char *path, std::string &s)
895 {
896  set_string_internal(MSG_CONFIG_SET_STRING, path, s.c_str());
897 }
898 
899 
900 void
901 NetworkConfiguration::set_default_string(const char *path, std::string &s)
902 {
903  set_string_internal(MSG_CONFIG_SET_DEFAULT_STRING, path, s.c_str());
904 }
905 
906 
907 void
908 NetworkConfiguration::set_comment_internal(unsigned int msg_type,
909  const char *path,
910  const char *s)
911 {
912  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
913  throw OutOfBoundsException("NetworkConfiguration::set_comment: "
914  "Maximum length for path exceeded");
915  }
916  if ( ! __connected ) {
917  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
918  "client connection is not alive");
919  }
920 
921  mutex->lock();
922  size_t s_length = strlen(s);
923  size_t sl = sizeof(config_comment_msg_t) + s_length;
924 
925  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
926  msg_type, sl);
927  config_comment_msg_t *m = omsg->msgge<config_comment_msg_t>();
928  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
929  m->s_length = s_length;
930  strcpy(m->s, s);
931  c->enqueue_and_wait(omsg);
932  if ( ! __mirror_mode && (msg != NULL) ) {
933  msg->unref();
934  msg = NULL;
935  }
936  mutex->unlock();
937 }
938 
939 
940 void
941 NetworkConfiguration::set_comment(const char *path, const char *comment)
942 {
943  set_comment_internal(MSG_CONFIG_SET_COMMENT, path, comment);
944 }
945 
946 
947 void
948 NetworkConfiguration::set_default_comment(const char *path, const char *comment)
949 {
950  set_comment_internal(MSG_CONFIG_SET_DEFAULT_COMMENT, path, comment);
951 }
952 
953 
954 void
955 NetworkConfiguration::set_comment(const char *path, std::string &comment)
956 {
957  set_comment_internal(MSG_CONFIG_SET_COMMENT, path, comment.c_str());
958 }
959 
960 
961 void
962 NetworkConfiguration::set_default_comment(const char *path, std::string &comment)
963 {
964  set_comment_internal(MSG_CONFIG_SET_DEFAULT_COMMENT, path, comment.c_str());
965 }
966 
967 
968 void
969 NetworkConfiguration::erase_internal(const char *path, bool is_default)
970 {
971  if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) {
972  throw OutOfBoundsException("NetworkConfiguration::erase: "
973  "Maximum length for path exceeded");
974  }
975  if ( ! __connected ) {
976  throw ConnectionDiedException("NetworkConfiguration: Cannot set value, "
977  "client connection is not alive");
978  }
979 
980  mutex->lock();
981  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
982  MSG_CONFIG_ERASE_VALUE,
983  sizeof(config_erase_value_msg_t));
984  config_erase_value_msg_t *m = omsg->msg<config_erase_value_msg_t>();
985  m->cp.is_default = is_default ? 1 : 0;
986  strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH);
987  c->enqueue_and_wait(omsg);
988  if ( ! __mirror_mode && (msg != NULL) ) {
989  msg->unref();
990  msg = NULL;
991  }
992  mutex->unlock();
993 }
994 
995 
996 void
998 {
999  erase_internal(path, /*default */ false);
1000 }
1001 
1002 
1003 void
1005 {
1006  erase_internal(path, /*default */ true);
1007 }
1008 
1009 
1010 /** We are no longer registered in Fawkes network client.
1011  * Ignored.
1012  * @param id the id of the calling client
1013  */
1014 void
1015 NetworkConfiguration::deregistered(unsigned int id) throw()
1016 {
1017 }
1018 
1019 
1020 void
1022  unsigned int id) throw()
1023 {
1024  if ( m->cid() == FAWKES_CID_CONFIGMANAGER ) {
1025 
1026  if ( __mirror_mode ) {
1027  switch (m->msgid()) {
1028  case MSG_CONFIG_LIST:
1029  // put all values into mirror database
1030  {
1031  mirror_config->transaction_begin();
1032  ConfigListContent *clc = m->msgc<ConfigListContent>();
1033  while ( clc->has_next() ) {
1034  size_t cle_size = 0;
1035  config_list_entity_header_t *cle = clc->next(&cle_size);
1036  switch ( cle->type ) {
1037  case MSG_CONFIG_FLOAT_VALUE:
1038  if ( cle_size == sizeof(config_list_float_entity_t) ) {
1040  if ( cle->cp.is_default ) {
1041  mirror_config->set_default_float(cle->cp.path, clev->f);
1042  } else {
1043  mirror_config->set_float(cle->cp.path, clev->f);
1044  }
1045  }
1046  break;
1047 
1048  case MSG_CONFIG_INT_VALUE:
1049  if ( cle_size == sizeof(config_list_int_entity_t) ) {
1051  if ( cle->cp.is_default ) {
1052  mirror_config->set_default_int(cle->cp.path, clev->i);
1053  } else {
1054  mirror_config->set_int(cle->cp.path, clev->i);
1055  }
1056  }
1057  break;
1058 
1059  case MSG_CONFIG_UINT_VALUE:
1060  if ( cle_size == sizeof(config_list_uint_entity_t) ) {
1062  if ( cle->cp.is_default ) {
1063  mirror_config->set_default_uint(cle->cp.path, clev->u);
1064  } else {
1065  mirror_config->set_uint(cle->cp.path, clev->u);
1066  }
1067  }
1068  break;
1069 
1070  case MSG_CONFIG_BOOL_VALUE:
1071  if ( cle_size == sizeof(config_list_bool_entity_t) ) {
1073  if ( cle->cp.is_default ) {
1074  mirror_config->set_default_bool(cle->cp.path, clev->b != 0);
1075  } else {
1076  mirror_config->set_bool(cle->cp.path, clev->b != 0);
1077  }
1078  }
1079  break;
1080 
1081  case MSG_CONFIG_STRING_VALUE:
1082  if ( cle_size >= sizeof(config_list_string_entity_t) ) {
1084  if ( cle->cp.is_default ) {
1085  mirror_config->set_default_string(cle->cp.path, clev->s);
1086  } else {
1087  mirror_config->set_string(cle->cp.path, clev->s);
1088  }
1089  }
1090  break;
1091 
1092  case MSG_CONFIG_COMMENT_VALUE:
1093  if ( cle_size >= sizeof(config_list_comment_entity_t) ) {
1095  if ( cle->cp.is_default ) {
1096  mirror_config->set_default_comment(cle->cp.path, clev->s);
1097  } else {
1098  mirror_config->set_comment(cle->cp.path, clev->s);
1099  }
1100  } else {
1101  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: ignoring bad comment");
1102  }
1103  break;
1104  }
1105  }
1106  mirror_config->transaction_commit();
1107  delete clc;
1108  }
1109 
1110  // add all change handlers
1111  for (ChangeHandlerMultimap::const_iterator j = _change_handlers.begin(); j != _change_handlers.end(); ++j) {
1112  _ch_range = _change_handlers.equal_range((*j).first);
1113  for (ChangeHandlerMultimap::const_iterator i = _ch_range.first; i != _ch_range.second; ++i) {
1114  mirror_config->add_change_handler((*i).second);
1115  }
1116  }
1117  // initial answer received -> wake up set_mirror_mode()
1118  if (__mirror_init_barrier) __mirror_init_barrier->wait();
1119  break;
1120 
1121  case MSG_CONFIG_VALUE_ERASED:
1122  try {
1124  if (em->cp.is_default == 1) {
1125  mirror_config->erase_default(em->cp.path);
1126  } else {
1127  mirror_config->erase(em->cp.path);
1128  }
1129  } catch (Exception &e) {
1130  // Just ignore silently
1131  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: erasing failed");
1132  }
1133  break;
1134 
1135  case MSG_CONFIG_FLOAT_VALUE:
1136  try {
1138  if (fm->cp.is_default == 1) {
1139  mirror_config->set_default_float(fm->cp.path, fm->f);
1140  } else {
1141  mirror_config->set_float(fm->cp.path, fm->f);
1142  }
1143  } catch (TypeMismatchException &e) {
1144  // Just ignore silently
1145  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid float received");
1146  }
1147  break;
1148 
1149  case MSG_CONFIG_UINT_VALUE:
1150  try {
1152  if (um->cp.is_default == 1) {
1153  mirror_config->set_default_uint(um->cp.path, um->u);
1154  } else {
1155  mirror_config->set_uint(um->cp.path, um->u);
1156  }
1157  } catch (TypeMismatchException &e) {
1158  // Just ignore silently
1159  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid uint received");
1160  }
1161  break;
1162 
1163  case MSG_CONFIG_INT_VALUE:
1164  try {
1166  if (im->cp.is_default == 1) {
1167  mirror_config->set_default_int(im->cp.path, im->i);
1168  } else {
1169  mirror_config->set_int(im->cp.path, im->i);
1170  }
1171  } catch (TypeMismatchException &e) {
1172  // Just ignore silently
1173  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid int received");
1174  }
1175  break;
1176 
1177  case MSG_CONFIG_BOOL_VALUE:
1178  try {
1180  if (bm->cp.is_default == 1) {
1181  mirror_config->set_default_bool(bm->cp.path, (bm->b != 0));
1182  } else {
1183  mirror_config->set_bool(bm->cp.path, (bm->b != 0));
1184  }
1185  } catch (TypeMismatchException &e) {
1186  // Just ignore silently
1187  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid bool received");
1188  }
1189  break;
1190 
1191  case MSG_CONFIG_STRING_VALUE:
1192  try {
1194  if (sm->cp.is_default == 1) {
1195  mirror_config->set_default_string(sm->cp.path, sm->s);
1196  } else {
1197  mirror_config->set_string(sm->cp.path, sm->s);
1198  }
1199  } catch (TypeMismatchException &e) {
1200  // Just ignore silently
1201  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid string received");
1202  }
1203  break;
1204 
1205  case MSG_CONFIG_COMMENT_VALUE:
1206  try {
1207  config_comment_msg_t *cm = m->msgge<config_comment_msg_t>();
1208  if (cm->cp.is_default == 1) {
1209  mirror_config->set_default_comment(cm->cp.path, cm->s);
1210  } else {
1211  mirror_config->set_comment(cm->cp.path, cm->s);
1212  }
1213  } catch (TypeMismatchException &e) {
1214  // Just ignore silently
1215  LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid string received");
1216  }
1217  break;
1218  }
1219  } else {
1220  msg = m;
1221  msg->ref();
1222  }
1223  }
1224 }
1225 
1226 
1227 void
1229 {
1230  __connected = false;
1231  __mirror_mode_before_connection_dead = __mirror_mode;
1232  set_mirror_mode(false);
1233  mutex->unlock(); //Just in case...
1234 }
1235 
1236 
1237 void
1239 {
1240  __connected = true;
1241  set_mirror_mode(__mirror_mode_before_connection_dead);
1242 }
1243 
1244 
1245 void
1247 {
1249 
1250  if ( __mirror_mode ) {
1251  mirror_config->add_change_handler(h);
1252  }
1253 }
1254 
1255 
1256 void
1258 {
1260  if ( __mirror_mode ) {
1261  mirror_config->rem_change_handler(h);
1262  }
1263 }
1264 
1265 
1266 /** Enable or disable mirror mode.
1267  * @param mirror true to enable mirror mode, false to disable
1268  */
1269 void
1271 {
1272  if ( mirror ) {
1273  if ( ! __mirror_mode ) {
1274 
1275  if ( ! __connected ) {
1276  throw CannotEnableMirroringException("Client connection is dead");
1277  }
1278 
1279  mirror_config = new SQLiteConfiguration();
1280  mirror_config->load(":memory:", ":memory:");
1281 
1282  __mirror_init_barrier = new InterruptibleBarrier(2);
1283  mutex->lock();
1284 
1285  __mirror_mode = true;
1286 
1287  // subscribe
1288  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
1289  MSG_CONFIG_SUBSCRIBE);
1290  c->enqueue(omsg);
1291 
1292  // wait until all data has been received (or timeout)
1293  if (! __mirror_init_barrier->wait(__mirror_timeout_sec, 0)) {
1294  // timeout
1295  delete mirror_config;
1296  __mirror_init_barrier = NULL;
1297  delete __mirror_init_barrier;
1298  mutex->unlock();
1299  throw CannotEnableMirroringException("Didn't receive data in time");
1300  }
1301  mutex->unlock();
1302  delete __mirror_init_barrier;
1303  __mirror_init_barrier = NULL;
1304  }
1305  } else {
1306  if ( __mirror_mode ) {
1307  __mirror_mode = false;
1308  // unsubscribe
1309  if ( __connected ) {
1310  FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
1311  MSG_CONFIG_UNSUBSCRIBE);
1312  c->enqueue(omsg);
1313  }
1314 
1315  // delete local temporary mirror database
1316  delete mirror_config;
1317  }
1318  }
1319 }
1320 
1321 
1322 void
1324 {
1325  mutex->lock();
1326 }
1327 
1328 
1329 bool
1331 {
1332  return mutex->try_lock();
1333 }
1334 
1335 
1336 void
1338 {
1339  mutex->unlock();
1340 }
1341 
1342 
1345 {
1346  if ( __mirror_mode ) {
1347  return mirror_config->iterator();
1348  } else {
1349  throw Exception("NetworkConfiguration: Iterating only supported in mirror mode");
1350  }
1351 }
1352 
1353 
1356 {
1357  if ( __mirror_mode ) {
1358  return mirror_config->iterator_default();
1359  } else {
1360  throw Exception("NetworkConfiguration: Iterating only supported in mirror mode");
1361  }
1362 }
1363 
1364 
1367 {
1368  if ( __mirror_mode ) {
1369  return mirror_config->iterator_hostspecific();
1370  } else {
1371  throw Exception("NetworkConfiguration: Iterating only supported in mirror mode");
1372  }
1373 }
1374 
1375 
1378 {
1379  if ( __mirror_mode ) {
1380  return mirror_config->search(path);
1381  } else {
1382  throw Exception("NetworkConfiguration: Searching only supported in mirror mode");
1383  }
1384 }
1385 
1386 
1387 /** @class NetworkConfiguration::NetConfValueIterator <config/netconf.h>
1388  * Network configuration value iterator.
1389  * @author Tim Niemueller
1390  */
1391 
1392 
1393 /** Constructor.
1394  * @param i internal other iterator, for instance form local mirrored database.
1395  */
1397 {
1398  // not interesting in this case, but anyway...
1399  iterated_once = false;
1400  this->i = i;
1401  msg = NULL;
1402  _path = NULL;
1403 }
1404 
1405 
1406 /** Constructor.
1407  * Returns invalid iterator.
1408  */
1410 {
1411  // not interesting in this case, but anyway...
1412  iterated_once = false;
1413  i = NULL;
1414  msg = NULL;
1415  _path = NULL;
1416 }
1417 
1418 
1419 /** Constructor.
1420  * Internally holds a message. Only this one value is accessible.
1421  * @param m message
1422  */
1424 {
1425  i = NULL;
1426  msg = NULL;
1427  iterated_once = false;
1428  _path = NULL;
1429 
1430  if ( (m->cid() == FAWKES_CID_CONFIGMANAGER) &&
1431  (m->msgid() >= MSG_CONFIG_VALUE_BEGIN) &&
1432  (m->msgid() <= MSG_CONFIG_VALUE_END) &&
1433  (m->payload_size() > sizeof(config_descriptor_t)) ) {
1434  msg = m;
1435  msg->ref();
1436  // extract path
1437  // all messages start with config_descriptor!
1438  _path = (char *)malloc(CONFIG_MSG_PATH_LENGTH + 1);
1439  _path[CONFIG_MSG_PATH_LENGTH] = 0;
1441  strncpy(_path, cd->path, CONFIG_MSG_PATH_LENGTH);
1442  } else {
1443  // invalid value, maybe path does not exist!
1444  }
1445 }
1446 
1447 
1448 /** Destructor. */
1450 {
1451  delete i;
1452  if ( msg != NULL ) msg->unref();
1453  if ( _path != NULL) free(_path);
1454 }
1455 
1456 
1457 bool
1459 {
1460  if ( i == NULL) {
1461  if ( (msg == NULL) || iterated_once ) {
1462  return false;
1463  } else {
1464  iterated_once = true;
1465  return true;
1466  }
1467  } else {
1468  return i->next();
1469  }
1470 }
1471 
1472 
1473 bool
1475 {
1476  return ( (i != NULL) || (msg != NULL) );
1477 }
1478 
1479 
1480 const char *
1482 {
1483  if ( i == NULL ) {
1484  if ( msg == NULL ) {
1485  throw NullPointerException("You may not access path on invalid iterator");
1486  } else {
1487  return _path;
1488  }
1489  } else {
1490  return i->path();
1491  }
1492 }
1493 
1494 
1495 const char *
1497 {
1498  if ( i == NULL ) {
1499  if ( msg == NULL ) {
1500  throw NullPointerException("You may not access path on invalid iterator");
1501  }
1502 
1503  switch (msg->msgid()) {
1504  case MSG_CONFIG_FLOAT_VALUE: return "float";
1505  case MSG_CONFIG_UINT_VALUE: return "unsigned int";
1506  case MSG_CONFIG_INT_VALUE: return "int";
1507  case MSG_CONFIG_BOOL_VALUE: return "bool";
1508  case MSG_CONFIG_STRING_VALUE: return "string";
1509  default:
1510  throw NullPointerException("Unknown type in NetConfValueIterator");
1511  }
1512  } else {
1513  return i->type();
1514  }
1515 }
1516 
1517 
1518 bool
1520 {
1521  if ( i == NULL ) {
1522  if ( msg == NULL ) {
1523  throw NullPointerException("You may not access value methods on invalid iterator");
1524  }
1525  return (msg->msgid() == MSG_CONFIG_FLOAT_VALUE);
1526  } else {
1527  return i->is_float();
1528  }
1529 }
1530 
1531 
1532 bool
1534 {
1535  if ( i == NULL ) {
1536  if ( msg == NULL ) {
1537  throw NullPointerException("You may not access value methods on invalid iterator");
1538  }
1539  return (msg->msgid() == MSG_CONFIG_UINT_VALUE);
1540  } else {
1541  return i->is_float();
1542  }
1543 }
1544 
1545 
1546 bool
1548 {
1549  if ( i == NULL ) {
1550  if ( msg == NULL ) {
1551  throw NullPointerException("You may not access value methods on invalid iterator");
1552  }
1553  return (msg->msgid() == MSG_CONFIG_INT_VALUE);
1554  } else {
1555  return i->is_int();
1556  }
1557 }
1558 
1559 
1560 bool
1562 {
1563  if ( i == NULL ) {
1564  if ( msg == NULL ) {
1565  throw NullPointerException("You may not access value methods on invalid iterator");
1566  }
1567  return (msg->msgid() == MSG_CONFIG_BOOL_VALUE);
1568  } else {
1569  return i->is_bool();
1570  }
1571 }
1572 
1573 
1574 bool
1576 {
1577  if ( i == NULL ) {
1578  if ( msg == NULL ) {
1579  throw NullPointerException("You may not access value methods on invalid iterator");
1580  }
1581  return (msg->msgid() == MSG_CONFIG_STRING_VALUE);
1582  } else {
1583  return i->is_string();
1584  }
1585 }
1586 
1587 
1588 bool
1590 {
1591  if ( i == NULL ) {
1592  if ( msg == NULL ) {
1593  throw NullPointerException("You may not access value methods on invalid iterator");
1594  } else {
1595  unsigned int msgid = msg->msgid();
1596  switch (msgid) {
1597  case MSG_CONFIG_FLOAT_VALUE:
1598  {
1600  return m->cp.is_default;
1601  }
1602  case MSG_CONFIG_UINT_VALUE:
1603  {
1605  return m->cp.is_default;
1606  }
1607  case MSG_CONFIG_INT_VALUE:
1608  {
1610  return m->cp.is_default;
1611  }
1612  case MSG_CONFIG_BOOL_VALUE:
1613  {
1615  return m->cp.is_default;
1616  }
1617  case MSG_CONFIG_STRING_VALUE:
1618  {
1620  return m->cp.is_default;
1621  }
1622  }
1623 
1624  throw TypeMismatchException("NetworkConfiguration: Neither in mirror mode nor "
1625  "iterator to value message");
1626  }
1627  } else {
1628  return i->is_default();
1629  }
1630 }
1631 
1632 
1633 float
1635 {
1636  if ( i == NULL ) {
1637  if ( msg == NULL ) {
1638  throw NullPointerException("You may not access value methods on invalid iterator");
1639  }
1640  if (msg->msgid() == MSG_CONFIG_FLOAT_VALUE) {
1642  return fm->f;
1643  } else {
1644  throw TypeMismatchException("NetConfValueIterator::get_float: type mismatch");
1645  }
1646  } else {
1647  return i->get_float();
1648  }
1649 }
1650 
1651 
1652 unsigned int
1654 {
1655  if ( i == NULL ) {
1656  if ( msg == NULL ) {
1657  throw NullPointerException("You may not access value methods on invalid iterator");
1658  }
1659  if (msg->msgid() == MSG_CONFIG_UINT_VALUE) {
1661  return um->u;
1662  } else {
1663  throw TypeMismatchException("NetConfValueIterator::get_uint: type mismatch");
1664  }
1665  } else {
1666  return i->get_int();
1667  }
1668 }
1669 
1670 
1671 int
1673 {
1674  if ( i == NULL ) {
1675  if ( msg == NULL ) {
1676  throw NullPointerException("You may not access value methods on invalid iterator");
1677  }
1678  if (msg->msgid() == MSG_CONFIG_INT_VALUE) {
1680  return im->i;
1681  } else {
1682  throw TypeMismatchException("NetConfValueIterator::get_int: type mismatch");
1683  }
1684  } else {
1685  return i->get_int();
1686  }
1687 }
1688 
1689 
1690 bool
1692 {
1693  if ( i == NULL ) {
1694  if ( msg == NULL ) {
1695  throw NullPointerException("You may not access value methods on invalid iterator");
1696  }
1697  if (msg->msgid() == MSG_CONFIG_BOOL_VALUE) {
1699  return (bm->b != 0);
1700  } else {
1701  throw TypeMismatchException("NetConfValueIterator::get_bool: type mismatch");
1702  }
1703  } else {
1704  return i->get_bool();
1705  }
1706 }
1707 
1708 
1709 std::string
1711 {
1712  if ( i == NULL ) {
1713  if ( msg == NULL ) {
1714  throw NullPointerException("You may not access value methods on invalid iterator");
1715  }
1716  if (msg->msgid() == MSG_CONFIG_STRING_VALUE) {
1718  return sm->s;
1719  } else {
1720  throw TypeMismatchException("NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1721  MSG_CONFIG_STRING_VALUE, msg->msgid());
1722  }
1723  } else {
1724  return i->get_string();
1725  }
1726 }
1727 
1728 
1729 std::string
1731 {
1732  if ( i == NULL ) {
1733  if ( msg == NULL ) {
1734  throw NullPointerException("You may not access value methods on "
1735  "invalid iterator");
1736  }
1737  if (msg->msgid() == MSG_CONFIG_STRING_VALUE) {
1739  return sm->s;
1740  } else if (msg->msgid() == MSG_CONFIG_BOOL_VALUE) {
1742  return (bm->b != 0) ? "true" : "false";
1743  } else if (msg->msgid() == MSG_CONFIG_INT_VALUE) {
1745  return StringConversions::to_string(im->i);
1746  } else if (msg->msgid() == MSG_CONFIG_UINT_VALUE) {
1748  return StringConversions::to_string(im->u);
1749  } else if (msg->msgid() == MSG_CONFIG_FLOAT_VALUE) {
1751  return StringConversions::to_string(fm->f);
1752  } else {
1753  throw Exception("NetConfValueIterator::get_as_string: unknown type");
1754  }
1755  } else {
1756  return i->get_as_string();
1757  }
1758 }
1759 
1760 
1761 std::string
1763 {
1764  if ( i == NULL ) {
1765  if ( msg == NULL ) {
1766  throw NullPointerException("You may not access value methods on invalid iterator");
1767  }
1768  if (msg->msgid() == MSG_CONFIG_COMMENT_VALUE) {
1770  return cm->s;
1771  } else {
1772  throw TypeMismatchException("NetConfValueIterator::get_comment: type mismatch");
1773  }
1774  } else {
1775  return i->get_comment();
1776  }
1777 }
1778 
1779 } // end namespace fawkes
config_descriptor_t cp
value descriptor
Definition: net_messages.h:121
virtual std::string get_comment() const
Get comment of value.
Definition: netconf.cpp:1762
virtual void connection_died(unsigned int id)
Client connection died.
Definition: netconf.cpp:1228
NetworkConfiguration(FawkesNetworkClient *c, unsigned int mirror_timeout_sec=15)
Constructor.
Definition: netconf.cpp:78
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
Definition: netconf.cpp:1246
virtual bool exists(const char *path)
Check if a given value exists.
Definition: netconf.cpp:177
config_descriptor_t cp
value descriptor
Definition: net_messages.h:127
uint32_t is_default
1 if value is a default value, 0 otherwise, only for get response
Definition: net_messages.h:94
virtual bool is_default() const
Check if current value was read from the default config.
Definition: netconf.cpp:1589
virtual ValueIterator * iterator()=0
Iterator for all values.
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
Definition: sqlite.cpp:1164
virtual std::list< std::string > tags()
List of tags.
Definition: netconf.cpp:167
ValueIterator * iterator()
Iterator for all values.
Definition: sqlite.cpp:1934
virtual int get_int(const char *path)
Get value from configuration which is of type int.
Definition: sqlite.cpp:1127
virtual bool is_default(const char *path)
Check if a value was read from the default config.
Definition: netconf.cpp:187
virtual bool is_string(const char *path)
Check if a value is of type string.
Definition: netconf.cpp:247
void enqueue_and_wait(FawkesNetworkMessage *message, unsigned int timeout_sec=15)
Enqueue message to send and wait for answer.
Definition: client.cpp:579
Simple Fawkes network client.
Definition: client.h:51
void unref()
Decrement reference count and conditionally delete this instance.
Definition: refcount.cpp:99
virtual ~NetworkConfiguration()
Destructor.
Definition: netconf.cpp:99
virtual void set_float(const char *path, float f)
Set new value in configuration of type float.
Definition: netconf.cpp:710
virtual void tag(const char *tag)
Tag this configuration version.
Definition: netconf.cpp:158
virtual ValueIterator * get_value(const char *path)
Get value from configuration.
Definition: netconf.cpp:633
Config list float entity.
Definition: net_messages.h:178
virtual bool is_uint(const char *path)
Check if a value is of type unsigned int.
Definition: netconf.cpp:226
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
Definition: sqlite.cpp:1146
virtual const char * type() const =0
Type of value.
Configuration storage using SQLite.
Definition: sqlite.h:39
virtual void inbound_received(FawkesNetworkMessage *msg, unsigned int id)
Called for incoming messages.
Definition: netconf.cpp:1021
virtual bool next()
Check if there is another element and advance to this if possible.
Definition: netconf.cpp:1458
virtual bool is_bool() const =0
Check if current value is a bool.
config_descriptor_t cp
value descriptor
Definition: net_messages.h:153
virtual bool is_int() const
Check if current value is a int.
Definition: netconf.cpp:1547
config_list_entity_header_t * next(size_t *size)
Get next plugin from list.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
void * payload() const
Get payload buffer.
Definition: message.cpp:321
virtual void set_default_bool(const char *path, bool b)
Set new default value in configuration of type bool.
Definition: netconf.cpp:842
Get value message.
Definition: net_messages.h:100
virtual std::string get_as_string() const
Get value as string.
Definition: netconf.cpp:1730
void register_handler(FawkesNetworkClientHandler *handler, unsigned int component_id)
Register handler.
Definition: client.cpp:620
virtual void load(const char *filename, const char *defaults_filename, const char *tag=NULL)
Load configuration.
Definition: netconf.cpp:119
Interface for configuration change handling.
void lock()
Lock the config.
Definition: netconf.cpp:1323
char path[CONFIG_MSG_PATH_LENGTH]
path to config value.
Definition: net_messages.h:93
void enqueue(FawkesNetworkMessage *message)
Enqueue message to send.
Definition: client.cpp:561
Representation of a message that is sent over the network.
Definition: message.h:75
virtual std::string get_default_comment(const char *path)
Get comment of value at given path.
Definition: sqlite.cpp:950
ValueIterator * search(const char *path)
Iterator with search results.
Definition: sqlite.cpp:2004
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
Definition: sqlite.cpp:1104
ValueIterator * iterator()
Iterator for all values.
Definition: netconf.cpp:1344
unsigned short int msgid() const
Get message type ID.
Definition: message.cpp:301
Config list content.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual float get_float() const =0
Get float value.
virtual unsigned int get_uint() const =0
Get unsigned int value.
A NULL pointer was supplied where not allowed.
Definition: software.h:34
Config list int entity.
Definition: net_messages.h:190
void unlock()
Unlock the config.
Definition: netconf.cpp:1337
virtual float get_float(const char *path)
Get value from configuration which is of type float.
Definition: netconf.cpp:282
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
Definition: netconf.cpp:482
virtual bool is_float() const =0
Check if current value is a float.
virtual bool get_bool() const
Get bool value.
Definition: netconf.cpp:1691
virtual bool is_float(const char *path)
Check if a value is of type float.
Definition: netconf.cpp:219
virtual int get_int(const char *path)
Get value from configuration which is of type int.
Definition: netconf.cpp:382
virtual std::string get_type(const char *path)
Get type of field.
Definition: netconf.cpp:201
virtual std::string get_comment(const char *path)
Get comment of value at given path.
Definition: sqlite.cpp:920
virtual bool is_int() const =0
Check if current value is a int.
virtual bool is_bool() const
Check if current value is a bool.
Definition: netconf.cpp:1561
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
virtual bool valid() const
Check if the current element is valid.
Definition: netconf.cpp:1474
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
Definition: netconf.cpp:432
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
Definition: netconf.cpp:1257
ValueIterator * iterator_default()
Iterator for all default values.
Definition: netconf.cpp:1355
bool wait(unsigned int timeout_sec, unsigned int timeout_nanosec)
Wait for other threads.
virtual bool get_bool() const =0
Get bool value.
virtual bool is_int(const char *path)
Check if a value is of type int.
Definition: netconf.cpp:233
Config list bool entity.
Definition: net_messages.h:196
Config list unsigned int entity.
Definition: net_messages.h:184
uint32_t type
type of entity, uses MSG_CONFIG_*_VALUE message IDs
Definition: net_messages.h:173
config_descriptor_t cp
value descriptor
Definition: net_messages.h:145
virtual int get_int() const =0
Get int value.
virtual void load(const char *filename, const char *defaults_filename, const char *tag=NULL)
Load configuration.
Definition: sqlite.cpp:611
bool has_next()
Check if more list elements are available.
virtual int get_int() const
Get int value.
Definition: netconf.cpp:1672
size_t payload_size() const
Get payload size.
Definition: message.cpp:311
virtual std::string get_comment(const char *path)
Get comment of value at given path.
Definition: netconf.cpp:532
String value message.
Definition: net_messages.h:144
virtual void set_default_uint(const char *path, unsigned int uint)
Set new default value in configuration of type unsigned int.
Definition: netconf.cpp:760
char s[2]
string value, 0-terminated
Definition: net_messages.h:147
MT * msgge() const
Get correctly casted payload.
Definition: message.h:134
virtual bool is_string() const =0
Check if current value is a string.
virtual float get_float(const char *path)
Get value from configuration which is of type float.
Definition: sqlite.cpp:1085
virtual std::string get_type(const char *path)
Get type of value at given path.
Definition: sqlite.cpp:886
virtual void set_comment(const char *path, std::string &comment)
Set new comment for existing value.
Definition: netconf.cpp:955
Base class for exceptions in Fawkes.
Definition: exception.h:36
config_descriptor_t cp
value descriptor
Definition: net_messages.h:133
virtual unsigned int get_uint() const
Get unsigned int value.
Definition: netconf.cpp:1653
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
Definition: config.cpp:496
void ref()
Increment reference count.
Definition: refcount.cpp:70
config_descriptor_t cp
value descriptor
Definition: net_messages.h:116
virtual bool is_uint() const =0
Check if current value is a unsigned int.
virtual void erase(const char *path)
Erase the given value from the configuration.
Definition: netconf.cpp:997
Basic config descriptor.
Definition: net_messages.h:92
Unsigned int value message.
Definition: net_messages.h:126
virtual std::string get_string() const =0
Get string value.
ValueIterator * iterator_hostspecific()
Iterator for all host-specific values.
Definition: netconf.cpp:1366
bool connected() const
Check if connection is alive.
Definition: client.cpp:797
virtual void set_default_float(const char *path, float f)
Set new default value in configuration of type float.
Definition: netconf.cpp:717
virtual bool is_float() const
Check if current value is a float.
Definition: netconf.cpp:1519
virtual void set_mirror_mode(bool mirror)
Enable or disable mirror mode.
Definition: netconf.cpp:1270
virtual void set_bool(const char *path, bool b)
Set new value in configuration of type bool.
Definition: netconf.cpp:835
virtual const char * path() const =0
Path of value.
virtual bool valid() const =0
Check if the current element is valid.
static void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: liblogger.cpp:160
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:120
virtual void copy(Configuration *copyconf)
Copy all values from the given configuration.
Definition: netconf.cpp:134
config_descriptor_t cp
Config descriptor.
Definition: net_messages.h:172
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
Definition: netconf.cpp:332
Thrown if the connection died during an operation.
Definition: exceptions.h:31
virtual void unlock()=0
Unlock the config.
virtual void connection_established(unsigned int id)
Client has established a connection.
Definition: netconf.cpp:1238
virtual ValueIterator * get_value(const char *path)
Get value from configuration.
Definition: sqlite.cpp:1185
ValueIterator * iterator_default()
Iterator for all default values.
Definition: sqlite.cpp:1948
Thrown if enabling mirror mode failed.
Definition: netconf.h:42
MT * msg() const
Get correctly casted payload.
Definition: message.h:115
Integer value message.
Definition: net_messages.h:132
Value erased message.
Definition: net_messages.h:115
Config list entity header.
Definition: net_messages.h:171
ValueIterator * iterator_hostspecific()
Iterator for all host-specific values.
Definition: sqlite.cpp:1961
virtual void set_default_int(const char *path, int i)
Set new default value in configuration of type int.
Definition: netconf.cpp:799
virtual std::string get_default_comment(const char *path)
Get comment of value at given path.
Definition: netconf.cpp:582
Iterator interface to iterate over config values.
Definition: config.h:68
Network configuration value iterator.
Definition: netconf.h:114
virtual std::string get_string() const
Get string value.
Definition: netconf.cpp:1710
Config list comment entity.
Definition: net_messages.h:209
virtual void set_int(const char *path, int i)
Set new value in configuration of type int.
Definition: netconf.cpp:792
void deregister_handler(unsigned int component_id)
Deregister handler.
Definition: client.cpp:639
virtual float get_float() const
Get float value.
Definition: netconf.cpp:1634
char s[2]
comment, 0-terminated
Definition: net_messages.h:155
virtual bool is_default() const =0
Check if current value was read from the default config.
int32_t b
0 is false, everything else is true
Definition: net_messages.h:198
void lock()
Lock this mutex.
Definition: mutex.cpp:89
virtual const char * path() const
Path of value.
Definition: netconf.cpp:1481
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
Definition: config.cpp:479
char s[2]
Comment value, 0-terminated.
Definition: net_messages.h:212
bool try_lock()
Try to lock the config.
Definition: netconf.cpp:1330
config_descriptor_t cp
value descriptor
Definition: net_messages.h:101
unsigned short int cid() const
Get component ID.
Definition: message.cpp:291
virtual bool is_uint() const
Check if current value is a unsigned int.
Definition: netconf.cpp:1533
virtual bool is_bool(const char *path)
Check if a value is of type bool.
Definition: netconf.cpp:240
virtual const char * type() const
Type of value.
Definition: netconf.cpp:1496
config_descriptor_t cp
value descriptor
Definition: net_messages.h:139
char s[2]
string value, 0-terminated
Definition: net_messages.h:205
Mutex mutual exclusion lock.
Definition: mutex.h:32
virtual void set_default_comment(const char *path, std::string &comment)
Set new default comment for existing default configuration value.
Definition: netconf.cpp:962
Index out of bounds.
Definition: software.h:88
virtual void deregistered(unsigned int id)
We are no longer registered in Fawkes network client.
Definition: netconf.cpp:1015
Interface for configuration handling.
Definition: config.h:63
virtual bool is_string() const
Check if current value is a string.
Definition: netconf.cpp:1575
virtual void set_default_string(const char *path, std::string &s)
Set new default value in configuration of type string.
Definition: netconf.cpp:901
ValueIterator * search(const char *path)
Iterator with search results.
Definition: netconf.cpp:1377
virtual void set_uint(const char *path, unsigned int uint)
Set new value in configuration of type unsigned int.
Definition: netconf.cpp:753
static std::string to_string(unsigned int i)
Convert unsigned int value to a string.
Config list string entity.
Definition: net_messages.h:202
Boolean value message.
Definition: net_messages.h:138
CannotEnableMirroringException(const char *msg)
Constructor.
Definition: netconf.cpp:53
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
virtual void lock()=0
Lock the config.
virtual void set_string(const char *path, std::string &s)
Set new value in configuration of type string.
Definition: netconf.cpp:894
virtual void erase_default(const char *path)
Erase the given default value from the configuration.
Definition: netconf.cpp:1004