Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * netconf.cpp - Fawkes remote configuration access via Fawkes net 00004 * 00005 * Created: Sun Jan 07 15:04:41 2007 00006 * Copyright 2006-2009 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <config/netconf.h> 00025 #include <config/net_messages.h> 00026 #include <config/sqlite.h> 00027 #include <config/net_list_content.h> 00028 00029 #include <core/threading/mutex.h> 00030 #include <core/threading/interruptible_barrier.h> 00031 #include <netcomm/fawkes/client.h> 00032 #include <netcomm/fawkes/message.h> 00033 #include <netcomm/utils/exceptions.h> 00034 00035 #include <utils/logging/liblogger.h> 00036 00037 #ifndef _GNU_SOURCE 00038 #define _GNU_SOURCE 00039 #endif 00040 #include <cstring> 00041 #include <cstdlib> 00042 00043 namespace fawkes { 00044 00045 /** @class CannotEnableMirroringException <config/netconf.h> 00046 * Thrown if enabling mirror mode failed. 00047 */ 00048 00049 /** Constructor. 00050 * @param msg message describing the problem 00051 */ 00052 CannotEnableMirroringException::CannotEnableMirroringException(const char *msg) 00053 : Exception("Could not enable mirroring: %s", msg) 00054 { 00055 } 00056 00057 00058 /** @class NetworkConfiguration <config/netconf.h> 00059 * Remote configuration via Fawkes net. 00060 * This implementation of the Configuration interface allows for remote access 00061 * to a Fawkes process implemented using the ConfigurationManager. 00062 * 00063 * The network configuration can operator in two modes. In mirror and in non-mirror 00064 * mode. The non-mirror mode is recommended if only a few operations have to be 00065 * carried out like getting only a very few values or setting a single value. 00066 * The mirror mode is for longer usage periods and on-the-fly updates. In mirror 00067 * mode the complete configuration is copied once from the Fawkes process and then 00068 * all updates are incorporated into the local database. You can register change 00069 * handlers to be notified as soon as someone modifies a value. 00070 * 00071 */ 00072 00073 /** Constructor. 00074 * @param c Fawkes network client (thread). 00075 * @param mirror_timeout_sec timeout in seconds for initiating mirroring 00076 */ 00077 NetworkConfiguration::NetworkConfiguration(FawkesNetworkClient *c, 00078 unsigned int mirror_timeout_sec) 00079 { 00080 __mirror_timeout_sec = mirror_timeout_sec; 00081 __connected = c->connected(); 00082 this->c = c; 00083 try { 00084 c->register_handler(this, FAWKES_CID_CONFIGMANAGER); 00085 } catch (Exception &e) { 00086 e.append("Failed to register for config manager component on network client"); 00087 throw; 00088 } 00089 mutex = new Mutex(); 00090 msg = NULL; 00091 __mirror_mode = false; 00092 __mirror_mode_before_connection_dead = false; 00093 __mirror_init_barrier = NULL; 00094 } 00095 00096 00097 /** Destructor. */ 00098 NetworkConfiguration::~NetworkConfiguration() 00099 { 00100 set_mirror_mode(false); 00101 c->deregister_handler(FAWKES_CID_CONFIGMANAGER); 00102 if (msg != NULL) { 00103 msg->unref(); 00104 } 00105 delete __mirror_init_barrier; 00106 delete mutex; 00107 } 00108 00109 00110 /** Load configuration. 00111 * This is a noop for the NetworkConfiguration. 00112 * @param name name of the host-based database. This should be a name of the form 00113 * hostname.db, where hostname is the unqualified part of the hostname. 00114 * @param defaults_name name of the default database. Should be defaults.db 00115 * @param tag optional tag to restore 00116 */ 00117 void 00118 NetworkConfiguration::load(const char *name, 00119 const char *defaults_name, 00120 const char *tag) 00121 { 00122 } 00123 00124 00125 /** Copy all values from the given configuration. 00126 * All values from the given configuration are copied. Old values are not erased 00127 * so that the copied values will overwrite existing values, new values are 00128 * created, but values existent in current config but not in the copie config 00129 * will remain unchanged. 00130 * @param copyconf configuration to copy 00131 */ 00132 void 00133 NetworkConfiguration::copy(Configuration *copyconf) 00134 { 00135 copyconf->lock(); 00136 Configuration::ValueIterator *i = copyconf->iterator(); 00137 while ( i->next() ) { 00138 if ( i->is_float() ) { 00139 set_float(i->path(), i->get_float()); 00140 } else if ( i->is_int() ) { 00141 set_int(i->path(), i->get_int()); 00142 } else if ( i->is_uint() ) { 00143 set_uint(i->path(), i->get_uint()); 00144 } else if ( i->is_bool() ) { 00145 set_bool(i->path(), i->get_bool()); 00146 } else if ( i->is_string() ) { 00147 std::string s = i->get_string(); 00148 set_string(i->path(), s); 00149 } 00150 } 00151 delete i; 00152 copyconf->unlock(); 00153 } 00154 00155 00156 void 00157 NetworkConfiguration::tag(const char *tag) 00158 { 00159 mutex->lock(); 00160 00161 mutex->unlock(); 00162 } 00163 00164 00165 std::list<std::string> 00166 NetworkConfiguration::tags() 00167 { 00168 mutex->lock(); 00169 std::list<std::string> l; 00170 mutex->unlock(); 00171 return l; 00172 } 00173 00174 00175 bool 00176 NetworkConfiguration::exists(const char *path) 00177 { 00178 ValueIterator *i = get_value(path); 00179 bool rv = i->valid(); 00180 delete i; 00181 return rv; 00182 } 00183 00184 00185 bool 00186 NetworkConfiguration::is_default(const char *path) 00187 { 00188 ValueIterator *i = get_value(path); 00189 bool rv = i->is_default(); 00190 delete i; 00191 return rv; 00192 } 00193 00194 00195 /** Get type of field. 00196 * @param path path 00197 * @return string of type 00198 */ 00199 std::string 00200 NetworkConfiguration::get_type(const char *path) 00201 { 00202 std::string s = ""; 00203 mutex->lock(); 00204 if ( __mirror_mode ) { 00205 s = mirror_config->get_type(path); 00206 mutex->unlock(); 00207 } else { 00208 mutex->unlock(); 00209 Configuration::ValueIterator *i = get_value(path); 00210 s = i->type(); 00211 delete i; 00212 } 00213 return s; 00214 } 00215 00216 00217 bool 00218 NetworkConfiguration::is_float(const char *path) 00219 { 00220 return (get_type(path) == "float"); 00221 } 00222 00223 00224 bool 00225 NetworkConfiguration::is_uint(const char *path) 00226 { 00227 return (get_type(path) == "unsigned int"); 00228 } 00229 00230 00231 bool 00232 NetworkConfiguration::is_int(const char *path) 00233 { 00234 return (get_type(path) == "int"); 00235 } 00236 00237 00238 bool 00239 NetworkConfiguration::is_bool(const char *path) 00240 { 00241 return (get_type(path) == "bool"); 00242 } 00243 00244 00245 bool 00246 NetworkConfiguration::is_string(const char *path) 00247 { 00248 return (get_type(path) == "string"); 00249 } 00250 00251 00252 void 00253 NetworkConfiguration::send_get(const char *path, unsigned int msgid) 00254 { 00255 if ( ! __connected ) { 00256 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00257 "client connection is not alive"); 00258 } 00259 config_getval_msg_t *g = (config_getval_msg_t *)calloc(1, sizeof(config_getval_msg_t)); 00260 strncpy(g->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00261 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00262 msgid, 00263 g, sizeof(config_getval_msg_t)); 00264 c->enqueue_and_wait(omsg); 00265 00266 if ( msg == NULL ) { 00267 mutex->unlock(); 00268 throw NullPointerException("NetworkConfiguration::send_get: msg == NULL"); 00269 } 00270 00271 if ( msg->msgid() != msgid ) { 00272 msg->unref(); 00273 msg = NULL; 00274 mutex->unlock(); 00275 throw TypeMismatchException("NetworkConfiguration::send_get: msg type not float"); 00276 } 00277 } 00278 00279 00280 float 00281 NetworkConfiguration::get_float(const char *path) 00282 { 00283 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00284 throw OutOfBoundsException("NetworkConfiguration::get_float: " 00285 "Maximum length for path exceeded"); 00286 } 00287 if ( ! __connected ) { 00288 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00289 "client connection is not alive"); 00290 } 00291 00292 float f; 00293 mutex->lock(); 00294 00295 if ( __mirror_mode ) { 00296 try { 00297 f = mirror_config->get_float(path); 00298 } catch (Exception &e) { 00299 e.append("NetworkConfiguration[mirroring]::get_float: exception in mirror database"); 00300 mutex->unlock(); 00301 throw; 00302 } 00303 } else { 00304 try { 00305 send_get(path, MSG_CONFIG_GET_FLOAT); 00306 00307 config_float_value_msg_t *fm = msg->msg<config_float_value_msg_t>(); 00308 f = fm->f; 00309 00310 msg->unref(); 00311 msg = NULL; 00312 00313 } catch (Exception &e) { 00314 e.append("NetworkConfiguration::get_float: Fetching float failed"); 00315 if ( msg != NULL ) { 00316 msg->unref(); 00317 msg = NULL; 00318 } 00319 mutex->unlock(); 00320 throw; 00321 } 00322 } 00323 00324 mutex->unlock(); 00325 00326 return f; 00327 } 00328 00329 00330 unsigned int 00331 NetworkConfiguration::get_uint(const char *path) 00332 { 00333 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00334 throw OutOfBoundsException("NetworkConfiguration::get_uint: " 00335 "Maximum length for path exceeded"); 00336 } 00337 if ( ! __connected ) { 00338 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00339 "client connection is not alive"); 00340 } 00341 00342 unsigned int u; 00343 mutex->lock(); 00344 00345 if ( __mirror_mode ) { 00346 try { 00347 u = mirror_config->get_uint(path); 00348 } catch (Exception &e) { 00349 e.append("NetworkConfiguration[mirroring]::get_uint: exception in mirror database"); 00350 mutex->unlock(); 00351 throw; 00352 } 00353 } else { 00354 try { 00355 send_get(path, MSG_CONFIG_GET_UINT); 00356 00357 config_uint_value_msg_t *um = msg->msg<config_uint_value_msg_t>(); 00358 u = um->u; 00359 00360 msg->unref(); 00361 msg = NULL; 00362 00363 } catch (Exception &e) { 00364 e.append("NetworkConfiguration::get_uint: Fetching unsigned int failed"); 00365 if ( msg != NULL ) { 00366 msg->unref(); 00367 msg = NULL; 00368 } 00369 mutex->unlock(); 00370 throw; 00371 } 00372 } 00373 00374 mutex->unlock(); 00375 00376 return u; 00377 } 00378 00379 00380 int 00381 NetworkConfiguration::get_int(const char *path) 00382 { 00383 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00384 throw OutOfBoundsException("NetworkConfiguration::get_int: " 00385 "Maximum length for path exceeded"); 00386 } 00387 if ( ! __connected ) { 00388 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00389 "client connection is not alive"); 00390 } 00391 00392 int i; 00393 mutex->lock(); 00394 00395 if ( __mirror_mode ) { 00396 try { 00397 i = mirror_config->get_int(path); 00398 } catch (Exception &e) { 00399 e.append("NetworkConfiguration[mirroring]::get_int: exception in mirror database"); 00400 mutex->unlock(); 00401 throw; 00402 } 00403 } else { 00404 try { 00405 send_get(path, MSG_CONFIG_GET_INT); 00406 00407 config_int_value_msg_t *im = msg->msg<config_int_value_msg_t>(); 00408 i = im->i; 00409 00410 msg->unref(); 00411 msg = NULL; 00412 00413 } catch (Exception &e) { 00414 e.append("NetworkConfiguration::get_int: Fetching int failed"); 00415 if ( msg != NULL ) { 00416 msg->unref(); 00417 msg = NULL; 00418 } 00419 mutex->unlock(); 00420 throw; 00421 } 00422 } 00423 00424 mutex->unlock(); 00425 00426 return i; 00427 } 00428 00429 00430 bool 00431 NetworkConfiguration::get_bool(const char *path) 00432 { 00433 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00434 throw OutOfBoundsException("NetworkConfiguration::get_bool: " 00435 "Maximum length for path exceeded"); 00436 } 00437 if ( ! __connected ) { 00438 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00439 "client connection is not alive"); 00440 } 00441 00442 bool b; 00443 mutex->lock(); 00444 00445 if ( __mirror_mode ) { 00446 try { 00447 b = mirror_config->get_bool(path); 00448 } catch (Exception &e) { 00449 e.append("NetworkConfiguration[mirroring]::get_bool: exception in mirror database"); 00450 mutex->unlock(); 00451 throw; 00452 } 00453 } else { 00454 try { 00455 send_get(path, MSG_CONFIG_GET_BOOL); 00456 00457 config_bool_value_msg_t *bm = msg->msg<config_bool_value_msg_t>(); 00458 b = (bm->b != 0); 00459 00460 msg->unref(); 00461 msg = NULL; 00462 00463 } catch (Exception &e) { 00464 e.append("NetworkConfiguration::get_bool: Fetching bool failed"); 00465 if ( msg != NULL ) { 00466 msg->unref(); 00467 msg = NULL; 00468 } 00469 mutex->unlock(); 00470 throw; 00471 } 00472 } 00473 00474 mutex->unlock(); 00475 00476 return b; 00477 } 00478 00479 00480 std::string 00481 NetworkConfiguration::get_string(const char *path) 00482 { 00483 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00484 throw OutOfBoundsException("NetworkConfiguration::get_string: " 00485 "Maximum length for path exceeded"); 00486 } 00487 if ( ! __connected ) { 00488 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00489 "client connection is not alive"); 00490 } 00491 00492 std::string s; 00493 mutex->lock(); 00494 00495 if ( __mirror_mode ) { 00496 try { 00497 s = mirror_config->get_string(path); 00498 } catch (Exception &e) { 00499 e.append("NetworkConfiguration[mirroring]::get_string: exception in mirror database"); 00500 mutex->unlock(); 00501 throw; 00502 } 00503 } else { 00504 try { 00505 send_get(path, MSG_CONFIG_GET_STRING); 00506 00507 config_string_value_msg_t *sm = msg->msgge<config_string_value_msg_t>(); 00508 s = sm->s; 00509 00510 msg->unref(); 00511 msg = NULL; 00512 00513 } catch (Exception &e) { 00514 e.append("NetworkConfiguration::get_string: Fetching int failed"); 00515 if ( msg != NULL ) { 00516 msg->unref(); 00517 msg = NULL; 00518 } 00519 mutex->unlock(); 00520 throw; 00521 } 00522 } 00523 00524 mutex->unlock(); 00525 00526 return s; 00527 } 00528 00529 00530 std::string 00531 NetworkConfiguration::get_comment(const char *path) 00532 { 00533 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00534 throw OutOfBoundsException("NetworkConfiguration::get_comment: " 00535 "Maximum length for path exceeded"); 00536 } 00537 if ( ! __connected ) { 00538 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00539 "client connection is not alive"); 00540 } 00541 00542 std::string s; 00543 mutex->lock(); 00544 00545 if ( __mirror_mode ) { 00546 try { 00547 s = mirror_config->get_comment(path); 00548 } catch (Exception &e) { 00549 e.append("NetworkConfiguration[mirroring]::get_comment: exception in mirror database"); 00550 mutex->unlock(); 00551 throw; 00552 } 00553 } else { 00554 try { 00555 send_get(path, MSG_CONFIG_GET_COMMENT); 00556 00557 config_comment_msg_t *sm = msg->msgge<config_comment_msg_t>(); 00558 s = sm->s; 00559 00560 msg->unref(); 00561 msg = NULL; 00562 00563 } catch (Exception &e) { 00564 e.append("NetworkConfiguration::get_comment: Fetching int failed"); 00565 if ( msg != NULL ) { 00566 msg->unref(); 00567 msg = NULL; 00568 } 00569 mutex->unlock(); 00570 throw; 00571 } 00572 } 00573 00574 mutex->unlock(); 00575 00576 return s; 00577 } 00578 00579 00580 std::string 00581 NetworkConfiguration::get_default_comment(const char *path) 00582 { 00583 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00584 throw OutOfBoundsException("NetworkConfiguration::get_default_comment: " 00585 "Maximum length for path exceeded"); 00586 } 00587 if ( ! __connected ) { 00588 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00589 "client connection is not alive"); 00590 } 00591 00592 std::string s; 00593 mutex->lock(); 00594 00595 if ( __mirror_mode ) { 00596 try { 00597 s = mirror_config->get_default_comment(path); 00598 } catch (Exception &e) { 00599 e.append("NetworkConfiguration[mirroring]::get_default_comment: " 00600 "exception in mirror database"); 00601 mutex->unlock(); 00602 throw; 00603 } 00604 } else { 00605 try { 00606 send_get(path, MSG_CONFIG_GET_DEFAULT_COMMENT); 00607 00608 config_comment_msg_t *sm = msg->msgge<config_comment_msg_t>(); 00609 s = sm->s; 00610 00611 msg->unref(); 00612 msg = NULL; 00613 00614 } catch (Exception &e) { 00615 e.append("NetworkConfiguration::get_comment: Fetching int failed"); 00616 if ( msg != NULL ) { 00617 msg->unref(); 00618 msg = NULL; 00619 } 00620 mutex->unlock(); 00621 throw; 00622 } 00623 } 00624 00625 mutex->unlock(); 00626 00627 return s; 00628 } 00629 00630 00631 Configuration::ValueIterator * 00632 NetworkConfiguration::get_value(const char *path) 00633 { 00634 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00635 throw OutOfBoundsException("NetworkConfiguration::get_value: " 00636 "Maximum length for path exceeded"); 00637 } 00638 if ( ! __connected ) { 00639 throw ConnectionDiedException("NetworkConfiguration: Cannot send get, " 00640 "client connection is not alive"); 00641 } 00642 00643 Configuration::ValueIterator *i; 00644 mutex->lock(); 00645 00646 if ( __mirror_mode ) { 00647 try { 00648 i = mirror_config->get_value(path); 00649 } catch (Exception &e) { 00650 e.append("NetworkConfiguration[mirroring]::get_float: exception in mirror database"); 00651 mutex->unlock(); 00652 throw; 00653 } 00654 } else { 00655 config_getval_msg_t *g = (config_getval_msg_t *)calloc(1, sizeof(config_getval_msg_t)); 00656 strncpy(g->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00657 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00658 MSG_CONFIG_GET_VALUE, 00659 g, sizeof(config_getval_msg_t)); 00660 c->enqueue_and_wait(omsg); 00661 00662 if ( msg == NULL ) { 00663 mutex->unlock(); 00664 throw NullPointerException("NetworkConfiguration::get_value: msg == NULL"); 00665 } 00666 00667 i = new NetConfValueIterator(msg); 00668 00669 msg->unref(); 00670 msg = NULL; 00671 } 00672 00673 mutex->unlock(); 00674 00675 return i; 00676 } 00677 00678 00679 void 00680 NetworkConfiguration::set_float_internal(unsigned int msg_type, 00681 const char *path, float f) 00682 { 00683 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00684 throw OutOfBoundsException("NetworkConfiguration::set_float: " 00685 "Maximum length for path exceeded"); 00686 } 00687 if ( ! __connected ) { 00688 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00689 "client connection is not alive"); 00690 } 00691 00692 mutex->lock(); 00693 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00694 msg_type, 00695 sizeof(config_float_value_msg_t)); 00696 config_float_value_msg_t *fm = omsg->msg<config_float_value_msg_t>(); 00697 strncpy(fm->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00698 fm->f = f; 00699 c->enqueue_and_wait(omsg); 00700 if ( ! __mirror_mode && (msg != NULL) ) { 00701 msg->unref(); 00702 msg = NULL; 00703 } 00704 mutex->unlock(); 00705 } 00706 00707 00708 void 00709 NetworkConfiguration::set_float(const char *path, float f) 00710 { 00711 set_float_internal(MSG_CONFIG_SET_FLOAT, path, f); 00712 } 00713 00714 00715 void 00716 NetworkConfiguration::set_default_float(const char *path, float f) 00717 { 00718 set_float_internal(MSG_CONFIG_SET_DEFAULT_FLOAT, path, f); 00719 } 00720 00721 00722 void 00723 NetworkConfiguration::set_uint_internal(unsigned int msg_type, 00724 const char *path, unsigned int uint) 00725 { 00726 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00727 throw OutOfBoundsException("NetworkConfiguration::set_uint: " 00728 "Maximum length for path exceeded"); 00729 } 00730 if ( ! __connected ) { 00731 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00732 "client connection is not alive"); 00733 } 00734 00735 mutex->lock(); 00736 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00737 msg_type, 00738 sizeof(config_uint_value_msg_t)); 00739 config_uint_value_msg_t *m = omsg->msg<config_uint_value_msg_t>(); 00740 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00741 m->u = uint; 00742 c->enqueue_and_wait(omsg); 00743 if ( ! __mirror_mode && (msg != NULL) ) { 00744 msg->unref(); 00745 msg = NULL; 00746 } 00747 mutex->unlock(); 00748 } 00749 00750 00751 void 00752 NetworkConfiguration::set_uint(const char *path, unsigned int uint) 00753 { 00754 set_uint_internal(MSG_CONFIG_SET_UINT, path, uint); 00755 } 00756 00757 00758 void 00759 NetworkConfiguration::set_default_uint(const char *path, unsigned int uint) 00760 { 00761 set_uint_internal(MSG_CONFIG_SET_DEFAULT_UINT, path, uint); 00762 } 00763 00764 00765 void 00766 NetworkConfiguration::set_int_internal(unsigned int msg_type, 00767 const char *path, int i) 00768 { 00769 if ( ! __connected ) { 00770 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00771 "client connection is not alive"); 00772 } 00773 00774 mutex->lock(); 00775 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00776 msg_type, 00777 sizeof(config_int_value_msg_t)); 00778 config_int_value_msg_t *m = omsg->msg<config_int_value_msg_t>(); 00779 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00780 m->i = i; 00781 c->enqueue_and_wait(omsg); 00782 if ( ! __mirror_mode && (msg != NULL) ) { 00783 msg->unref(); 00784 msg = NULL; 00785 } 00786 mutex->unlock(); 00787 } 00788 00789 00790 void 00791 NetworkConfiguration::set_int(const char *path, int i) 00792 { 00793 set_int_internal(MSG_CONFIG_SET_INT, path, i); 00794 } 00795 00796 00797 void 00798 NetworkConfiguration::set_default_int(const char *path, int i) 00799 { 00800 set_int_internal(MSG_CONFIG_SET_DEFAULT_INT, path, i); 00801 } 00802 00803 00804 void 00805 NetworkConfiguration::set_bool_internal(unsigned int msg_type, 00806 const char *path, bool b) 00807 { 00808 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00809 throw OutOfBoundsException("NetworkConfiguration::set_bool: " 00810 "Maximum length for path exceeded"); 00811 } 00812 if ( ! __connected ) { 00813 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00814 "client connection is not alive"); 00815 } 00816 00817 mutex->lock(); 00818 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00819 msg_type, 00820 sizeof(config_bool_value_msg_t)); 00821 config_bool_value_msg_t *m = omsg->msg<config_bool_value_msg_t>(); 00822 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00823 m->b = (b ? 1 : 0); 00824 c->enqueue_and_wait(omsg); 00825 if ( ! __mirror_mode && (msg != NULL) ) { 00826 msg->unref(); 00827 msg = NULL; 00828 } 00829 mutex->unlock(); 00830 } 00831 00832 00833 void 00834 NetworkConfiguration::set_bool(const char *path, bool b) 00835 { 00836 set_bool_internal(MSG_CONFIG_SET_BOOL, path, b); 00837 } 00838 00839 00840 void 00841 NetworkConfiguration::set_default_bool(const char *path, bool b) 00842 { 00843 set_bool_internal(MSG_CONFIG_SET_DEFAULT_BOOL, path, b); 00844 } 00845 00846 00847 void 00848 NetworkConfiguration::set_string_internal(unsigned int msg_type, 00849 const char *path, 00850 const char *s) 00851 { 00852 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00853 throw OutOfBoundsException("NetworkConfiguration::set_string: " 00854 "Maximum length for path exceeded"); 00855 } 00856 if ( ! __connected ) { 00857 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00858 "client connection is not alive"); 00859 } 00860 00861 mutex->lock(); 00862 size_t s_length = strlen(s); 00863 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00864 msg_type, 00865 sizeof(config_string_value_msg_t) + s_length); 00866 config_string_value_msg_t *m = omsg->msgge<config_string_value_msg_t>(); 00867 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00868 strcpy(m->s, s); 00869 c->enqueue_and_wait(omsg); 00870 if ( ! __mirror_mode && (msg != NULL) ) { 00871 msg->unref(); 00872 msg = NULL; 00873 } 00874 mutex->unlock(); 00875 } 00876 00877 00878 void 00879 NetworkConfiguration::set_string(const char *path, const char *s) 00880 { 00881 set_string_internal(MSG_CONFIG_SET_STRING, path, s); 00882 } 00883 00884 00885 void 00886 NetworkConfiguration::set_default_string(const char *path, const char *s) 00887 { 00888 set_string_internal(MSG_CONFIG_SET_DEFAULT_STRING, path, s); 00889 } 00890 00891 00892 void 00893 NetworkConfiguration::set_string(const char *path, std::string &s) 00894 { 00895 set_string_internal(MSG_CONFIG_SET_STRING, path, s.c_str()); 00896 } 00897 00898 00899 void 00900 NetworkConfiguration::set_default_string(const char *path, std::string &s) 00901 { 00902 set_string_internal(MSG_CONFIG_SET_DEFAULT_STRING, path, s.c_str()); 00903 } 00904 00905 00906 void 00907 NetworkConfiguration::set_comment_internal(unsigned int msg_type, 00908 const char *path, 00909 const char *s) 00910 { 00911 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00912 throw OutOfBoundsException("NetworkConfiguration::set_comment: " 00913 "Maximum length for path exceeded"); 00914 } 00915 if ( ! __connected ) { 00916 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00917 "client connection is not alive"); 00918 } 00919 00920 mutex->lock(); 00921 size_t s_length = strlen(s); 00922 size_t sl = sizeof(config_comment_msg_t) + s_length; 00923 00924 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00925 msg_type, sl); 00926 config_comment_msg_t *m = omsg->msgge<config_comment_msg_t>(); 00927 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00928 m->s_length = s_length; 00929 strcpy(m->s, s); 00930 c->enqueue_and_wait(omsg); 00931 if ( ! __mirror_mode && (msg != NULL) ) { 00932 msg->unref(); 00933 msg = NULL; 00934 } 00935 mutex->unlock(); 00936 } 00937 00938 00939 void 00940 NetworkConfiguration::set_comment(const char *path, const char *comment) 00941 { 00942 set_comment_internal(MSG_CONFIG_SET_COMMENT, path, comment); 00943 } 00944 00945 00946 void 00947 NetworkConfiguration::set_default_comment(const char *path, const char *comment) 00948 { 00949 set_comment_internal(MSG_CONFIG_SET_DEFAULT_COMMENT, path, comment); 00950 } 00951 00952 00953 void 00954 NetworkConfiguration::set_comment(const char *path, std::string &comment) 00955 { 00956 set_comment_internal(MSG_CONFIG_SET_COMMENT, path, comment.c_str()); 00957 } 00958 00959 00960 void 00961 NetworkConfiguration::set_default_comment(const char *path, std::string &comment) 00962 { 00963 set_comment_internal(MSG_CONFIG_SET_DEFAULT_COMMENT, path, comment.c_str()); 00964 } 00965 00966 00967 void 00968 NetworkConfiguration::erase_internal(const char *path, bool is_default) 00969 { 00970 if ( strlen(path) > CONFIG_MSG_PATH_LENGTH ) { 00971 throw OutOfBoundsException("NetworkConfiguration::erase: " 00972 "Maximum length for path exceeded"); 00973 } 00974 if ( ! __connected ) { 00975 throw ConnectionDiedException("NetworkConfiguration: Cannot set value, " 00976 "client connection is not alive"); 00977 } 00978 00979 mutex->lock(); 00980 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 00981 MSG_CONFIG_ERASE_VALUE, 00982 sizeof(config_erase_value_msg_t)); 00983 config_erase_value_msg_t *m = omsg->msg<config_erase_value_msg_t>(); 00984 m->cp.is_default = is_default ? 1 : 0; 00985 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH); 00986 c->enqueue_and_wait(omsg); 00987 if ( ! __mirror_mode && (msg != NULL) ) { 00988 msg->unref(); 00989 msg = NULL; 00990 } 00991 mutex->unlock(); 00992 } 00993 00994 00995 void 00996 NetworkConfiguration::erase(const char *path) 00997 { 00998 erase_internal(path, /*default */ false); 00999 } 01000 01001 01002 void 01003 NetworkConfiguration::erase_default(const char *path) 01004 { 01005 erase_internal(path, /*default */ true); 01006 } 01007 01008 01009 /** We are no longer registered in Fawkes network client. 01010 * Ignored. 01011 * @param id the id of the calling client 01012 */ 01013 void 01014 NetworkConfiguration::deregistered(unsigned int id) throw() 01015 { 01016 } 01017 01018 01019 void 01020 NetworkConfiguration::inbound_received(FawkesNetworkMessage *m, 01021 unsigned int id) throw() 01022 { 01023 if ( m->cid() == FAWKES_CID_CONFIGMANAGER ) { 01024 01025 if ( __mirror_mode ) { 01026 switch (m->msgid()) { 01027 case MSG_CONFIG_LIST: 01028 // put all values into mirror database 01029 { 01030 mirror_config->transaction_begin(); 01031 ConfigListContent *clc = m->msgc<ConfigListContent>(); 01032 while ( clc->has_next() ) { 01033 size_t cle_size = 0; 01034 config_list_entity_header_t *cle = clc->next(&cle_size); 01035 switch ( cle->type ) { 01036 case MSG_CONFIG_FLOAT_VALUE: 01037 if ( cle_size == sizeof(config_list_float_entity_t) ) { 01038 config_list_float_entity_t *clev = (config_list_float_entity_t *)cle; 01039 if ( cle->cp.is_default ) { 01040 mirror_config->set_default_float(cle->cp.path, clev->f); 01041 } else { 01042 mirror_config->set_float(cle->cp.path, clev->f); 01043 } 01044 } 01045 break; 01046 01047 case MSG_CONFIG_INT_VALUE: 01048 if ( cle_size == sizeof(config_list_int_entity_t) ) { 01049 config_list_int_entity_t *clev = (config_list_int_entity_t *)cle; 01050 if ( cle->cp.is_default ) { 01051 mirror_config->set_default_int(cle->cp.path, clev->i); 01052 } else { 01053 mirror_config->set_int(cle->cp.path, clev->i); 01054 } 01055 } 01056 break; 01057 01058 case MSG_CONFIG_UINT_VALUE: 01059 if ( cle_size == sizeof(config_list_uint_entity_t) ) { 01060 config_list_uint_entity_t *clev = (config_list_uint_entity_t *)cle; 01061 if ( cle->cp.is_default ) { 01062 mirror_config->set_default_uint(cle->cp.path, clev->u); 01063 } else { 01064 mirror_config->set_uint(cle->cp.path, clev->u); 01065 } 01066 } 01067 break; 01068 01069 case MSG_CONFIG_BOOL_VALUE: 01070 if ( cle_size == sizeof(config_list_bool_entity_t) ) { 01071 config_list_bool_entity_t *clev = (config_list_bool_entity_t *)cle; 01072 if ( cle->cp.is_default ) { 01073 mirror_config->set_default_bool(cle->cp.path, clev->b != 0); 01074 } else { 01075 mirror_config->set_bool(cle->cp.path, clev->b != 0); 01076 } 01077 } 01078 break; 01079 01080 case MSG_CONFIG_STRING_VALUE: 01081 if ( cle_size >= sizeof(config_list_string_entity_t) ) { 01082 config_list_string_entity_t *clev = (config_list_string_entity_t *)cle; 01083 if ( cle->cp.is_default ) { 01084 mirror_config->set_default_string(cle->cp.path, clev->s); 01085 } else { 01086 mirror_config->set_string(cle->cp.path, clev->s); 01087 } 01088 } 01089 break; 01090 01091 case MSG_CONFIG_COMMENT_VALUE: 01092 if ( cle_size >= sizeof(config_list_comment_entity_t) ) { 01093 config_list_comment_entity_t *clev = (config_list_comment_entity_t *)cle; 01094 if ( cle->cp.is_default ) { 01095 mirror_config->set_default_comment(cle->cp.path, clev->s); 01096 } else { 01097 mirror_config->set_comment(cle->cp.path, clev->s); 01098 } 01099 } else { 01100 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: ignoring bad comment"); 01101 } 01102 break; 01103 } 01104 } 01105 mirror_config->transaction_commit(); 01106 delete clc; 01107 } 01108 01109 // add all change handlers 01110 for (ChangeHandlerMultimap::const_iterator j = _change_handlers.begin(); j != _change_handlers.end(); ++j) { 01111 _ch_range = _change_handlers.equal_range((*j).first); 01112 for (ChangeHandlerMultimap::const_iterator i = _ch_range.first; i != _ch_range.second; ++i) { 01113 mirror_config->add_change_handler((*i).second); 01114 } 01115 } 01116 // initial answer received -> wake up set_mirror_mode() 01117 if (__mirror_init_barrier) __mirror_init_barrier->wait(); 01118 break; 01119 01120 case MSG_CONFIG_VALUE_ERASED: 01121 try { 01122 config_value_erased_msg_t *em = m->msg<config_value_erased_msg_t>(); 01123 if (em->cp.is_default == 1) { 01124 mirror_config->erase_default(em->cp.path); 01125 } else { 01126 mirror_config->erase(em->cp.path); 01127 } 01128 } catch (Exception &e) { 01129 // Just ignore silently 01130 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: erasing failed"); 01131 } 01132 break; 01133 01134 case MSG_CONFIG_FLOAT_VALUE: 01135 try { 01136 config_float_value_msg_t *fm = m->msg<config_float_value_msg_t>(); 01137 if (fm->cp.is_default == 1) { 01138 mirror_config->set_default_float(fm->cp.path, fm->f); 01139 } else { 01140 mirror_config->set_float(fm->cp.path, fm->f); 01141 } 01142 } catch (TypeMismatchException &e) { 01143 // Just ignore silently 01144 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid float received"); 01145 } 01146 break; 01147 01148 case MSG_CONFIG_UINT_VALUE: 01149 try { 01150 config_uint_value_msg_t *um = m->msg<config_uint_value_msg_t>(); 01151 if (um->cp.is_default == 1) { 01152 mirror_config->set_default_uint(um->cp.path, um->u); 01153 } else { 01154 mirror_config->set_uint(um->cp.path, um->u); 01155 } 01156 } catch (TypeMismatchException &e) { 01157 // Just ignore silently 01158 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid uint received"); 01159 } 01160 break; 01161 01162 case MSG_CONFIG_INT_VALUE: 01163 try { 01164 config_int_value_msg_t *im = m->msg<config_int_value_msg_t>(); 01165 if (im->cp.is_default == 1) { 01166 mirror_config->set_default_int(im->cp.path, im->i); 01167 } else { 01168 mirror_config->set_int(im->cp.path, im->i); 01169 } 01170 } catch (TypeMismatchException &e) { 01171 // Just ignore silently 01172 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid int received"); 01173 } 01174 break; 01175 01176 case MSG_CONFIG_BOOL_VALUE: 01177 try { 01178 config_bool_value_msg_t *bm = m->msg<config_bool_value_msg_t>(); 01179 if (bm->cp.is_default == 1) { 01180 mirror_config->set_default_bool(bm->cp.path, (bm->b != 0)); 01181 } else { 01182 mirror_config->set_bool(bm->cp.path, (bm->b != 0)); 01183 } 01184 } catch (TypeMismatchException &e) { 01185 // Just ignore silently 01186 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid bool received"); 01187 } 01188 break; 01189 01190 case MSG_CONFIG_STRING_VALUE: 01191 try { 01192 config_string_value_msg_t *sm = m->msgge<config_string_value_msg_t>(); 01193 if (sm->cp.is_default == 1) { 01194 mirror_config->set_default_string(sm->cp.path, sm->s); 01195 } else { 01196 mirror_config->set_string(sm->cp.path, sm->s); 01197 } 01198 } catch (TypeMismatchException &e) { 01199 // Just ignore silently 01200 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid string received"); 01201 } 01202 break; 01203 01204 case MSG_CONFIG_COMMENT_VALUE: 01205 try { 01206 config_comment_msg_t *cm = m->msgge<config_comment_msg_t>(); 01207 if (cm->cp.is_default == 1) { 01208 mirror_config->set_default_comment(cm->cp.path, cm->s); 01209 } else { 01210 mirror_config->set_comment(cm->cp.path, cm->s); 01211 } 01212 } catch (TypeMismatchException &e) { 01213 // Just ignore silently 01214 LibLogger::log_warn("NetworkConfiguration", "[mirroring]::inboundReceived: invalid string received"); 01215 } 01216 break; 01217 } 01218 } else { 01219 msg = m; 01220 msg->ref(); 01221 } 01222 } 01223 } 01224 01225 01226 void 01227 NetworkConfiguration::connection_died(unsigned int id) throw() 01228 { 01229 __connected = false; 01230 __mirror_mode_before_connection_dead = __mirror_mode; 01231 set_mirror_mode(false); 01232 mutex->unlock(); //Just in case... 01233 } 01234 01235 01236 void 01237 NetworkConfiguration::connection_established(unsigned int id) throw() 01238 { 01239 __connected = true; 01240 set_mirror_mode(__mirror_mode_before_connection_dead); 01241 } 01242 01243 01244 void 01245 NetworkConfiguration::add_change_handler(ConfigurationChangeHandler *h) 01246 { 01247 Configuration::add_change_handler(h); 01248 01249 if ( __mirror_mode ) { 01250 mirror_config->add_change_handler(h); 01251 } 01252 } 01253 01254 01255 void 01256 NetworkConfiguration::rem_change_handler(ConfigurationChangeHandler *h) 01257 { 01258 Configuration::rem_change_handler(h); 01259 if ( __mirror_mode ) { 01260 mirror_config->rem_change_handler(h); 01261 } 01262 } 01263 01264 01265 /** Enable or disable mirror mode. 01266 * @param mirror true to enable mirror mode, false to disable 01267 */ 01268 void 01269 NetworkConfiguration::set_mirror_mode(bool mirror) 01270 { 01271 if ( mirror ) { 01272 if ( ! __mirror_mode ) { 01273 01274 if ( ! __connected ) { 01275 throw CannotEnableMirroringException("Client connection is dead"); 01276 } 01277 01278 mirror_config = new SQLiteConfiguration(); 01279 mirror_config->load(":memory:", ":memory:"); 01280 01281 __mirror_init_barrier = new InterruptibleBarrier(2); 01282 mutex->lock(); 01283 01284 __mirror_mode = true; 01285 01286 // subscribe 01287 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 01288 MSG_CONFIG_SUBSCRIBE); 01289 c->enqueue(omsg); 01290 01291 // wait until all data has been received (or timeout) 01292 if (! __mirror_init_barrier->wait(__mirror_timeout_sec, 0)) { 01293 // timeout 01294 delete mirror_config; 01295 __mirror_init_barrier = NULL; 01296 delete __mirror_init_barrier; 01297 mutex->unlock(); 01298 throw CannotEnableMirroringException("Didn't receive data in time"); 01299 } 01300 mutex->unlock(); 01301 delete __mirror_init_barrier; 01302 __mirror_init_barrier = NULL; 01303 } 01304 } else { 01305 if ( __mirror_mode ) { 01306 __mirror_mode = false; 01307 // unsubscribe 01308 if ( __connected ) { 01309 FawkesNetworkMessage *omsg = new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, 01310 MSG_CONFIG_UNSUBSCRIBE); 01311 c->enqueue(omsg); 01312 } 01313 01314 // delete local temporary mirror database 01315 delete mirror_config; 01316 } 01317 } 01318 } 01319 01320 01321 void 01322 NetworkConfiguration::lock() 01323 { 01324 mutex->lock(); 01325 } 01326 01327 01328 bool 01329 NetworkConfiguration::try_lock() 01330 { 01331 return mutex->try_lock(); 01332 } 01333 01334 01335 void 01336 NetworkConfiguration::unlock() 01337 { 01338 mutex->unlock(); 01339 } 01340 01341 01342 Configuration::ValueIterator * 01343 NetworkConfiguration::iterator() 01344 { 01345 if ( __mirror_mode ) { 01346 return mirror_config->iterator(); 01347 } else { 01348 throw Exception("NetworkConfiguration: Iterating only supported in mirror mode"); 01349 } 01350 } 01351 01352 01353 Configuration::ValueIterator * 01354 NetworkConfiguration::iterator_default() 01355 { 01356 if ( __mirror_mode ) { 01357 return mirror_config->iterator_default(); 01358 } else { 01359 throw Exception("NetworkConfiguration: Iterating only supported in mirror mode"); 01360 } 01361 } 01362 01363 01364 Configuration::ValueIterator * 01365 NetworkConfiguration::iterator_hostspecific() 01366 { 01367 if ( __mirror_mode ) { 01368 return mirror_config->iterator_hostspecific(); 01369 } else { 01370 throw Exception("NetworkConfiguration: Iterating only supported in mirror mode"); 01371 } 01372 } 01373 01374 01375 Configuration::ValueIterator * 01376 NetworkConfiguration::search(const char *path) 01377 { 01378 if ( __mirror_mode ) { 01379 return mirror_config->search(path); 01380 } else { 01381 throw Exception("NetworkConfiguration: Searching only supported in mirror mode"); 01382 } 01383 } 01384 01385 01386 /** @class NetworkConfiguration::NetConfValueIterator <config/netconf.h> 01387 * Network configuration value iterator. 01388 * @author Tim Niemueller 01389 */ 01390 01391 01392 /** Constructor. 01393 * @param i internal other iterator, for instance form local mirrored database. 01394 */ 01395 NetworkConfiguration::NetConfValueIterator::NetConfValueIterator(Configuration::ValueIterator *i) 01396 { 01397 // not interesting in this case, but anyway... 01398 iterated_once = false; 01399 this->i = i; 01400 msg = NULL; 01401 _path = NULL; 01402 } 01403 01404 01405 /** Constructor. 01406 * Returns invalid iterator. 01407 */ 01408 NetworkConfiguration::NetConfValueIterator::NetConfValueIterator() 01409 { 01410 // not interesting in this case, but anyway... 01411 iterated_once = false; 01412 i = NULL; 01413 msg = NULL; 01414 _path = NULL; 01415 } 01416 01417 01418 /** Constructor. 01419 * Internally holds a message. Only this one value is accessible. 01420 * @param m message 01421 */ 01422 NetworkConfiguration::NetConfValueIterator::NetConfValueIterator(FawkesNetworkMessage *m) 01423 { 01424 i = NULL; 01425 msg = NULL; 01426 iterated_once = false; 01427 _path = NULL; 01428 01429 if ( (m->cid() == FAWKES_CID_CONFIGMANAGER) && 01430 (m->msgid() >= MSG_CONFIG_VALUE_BEGIN) && 01431 (m->msgid() <= MSG_CONFIG_VALUE_END) && 01432 (m->payload_size() > sizeof(config_descriptor_t)) ) { 01433 msg = m; 01434 msg->ref(); 01435 // extract path 01436 // all messages start with config_descriptor! 01437 _path = (char *)malloc(CONFIG_MSG_PATH_LENGTH + 1); 01438 _path[CONFIG_MSG_PATH_LENGTH] = 0; 01439 config_descriptor_t *cd = (config_descriptor_t *)msg->payload(); 01440 strncpy(_path, cd->path, CONFIG_MSG_PATH_LENGTH); 01441 } else { 01442 // invalid value, maybe path does not exist! 01443 } 01444 } 01445 01446 01447 /** Destructor. */ 01448 NetworkConfiguration::NetConfValueIterator::~NetConfValueIterator() 01449 { 01450 delete i; 01451 if ( msg != NULL ) msg->unref(); 01452 if ( _path != NULL) free(_path); 01453 } 01454 01455 01456 bool 01457 NetworkConfiguration::NetConfValueIterator::next() 01458 { 01459 if ( i == NULL) { 01460 if ( (msg == NULL) || iterated_once ) { 01461 return false; 01462 } else { 01463 iterated_once = true; 01464 return true; 01465 } 01466 } else { 01467 return i->next(); 01468 } 01469 } 01470 01471 01472 bool 01473 NetworkConfiguration::NetConfValueIterator::valid() 01474 { 01475 return ( (i != NULL) || (msg != NULL) ); 01476 } 01477 01478 01479 const char * 01480 NetworkConfiguration::NetConfValueIterator::path() 01481 { 01482 if ( i == NULL ) { 01483 if ( msg == NULL ) { 01484 throw NullPointerException("You may not access path on invalid iterator"); 01485 } else { 01486 return _path; 01487 } 01488 } else { 01489 return i->path(); 01490 } 01491 } 01492 01493 01494 const char * 01495 NetworkConfiguration::NetConfValueIterator::type() 01496 { 01497 if ( i == NULL ) { 01498 if ( msg == NULL ) { 01499 throw NullPointerException("You may not access path on invalid iterator"); 01500 } 01501 01502 switch (msg->msgid()) { 01503 case MSG_CONFIG_FLOAT_VALUE: return "float"; 01504 case MSG_CONFIG_UINT_VALUE: return "unsigned int"; 01505 case MSG_CONFIG_INT_VALUE: return "int"; 01506 case MSG_CONFIG_BOOL_VALUE: return "bool"; 01507 case MSG_CONFIG_STRING_VALUE: return "string"; 01508 default: 01509 throw NullPointerException("Unknown type in NetConfValueIterator"); 01510 } 01511 } else { 01512 return i->type(); 01513 } 01514 } 01515 01516 01517 bool 01518 NetworkConfiguration::NetConfValueIterator::is_float() 01519 { 01520 if ( i == NULL ) { 01521 if ( msg == NULL ) { 01522 throw NullPointerException("You may not access value methods on invalid iterator"); 01523 } 01524 return (msg->msgid() == MSG_CONFIG_FLOAT_VALUE); 01525 } else { 01526 return i->is_float(); 01527 } 01528 } 01529 01530 01531 bool 01532 NetworkConfiguration::NetConfValueIterator::is_uint() 01533 { 01534 if ( i == NULL ) { 01535 if ( msg == NULL ) { 01536 throw NullPointerException("You may not access value methods on invalid iterator"); 01537 } 01538 return (msg->msgid() == MSG_CONFIG_UINT_VALUE); 01539 } else { 01540 return i->is_float(); 01541 } 01542 } 01543 01544 01545 bool 01546 NetworkConfiguration::NetConfValueIterator::is_int() 01547 { 01548 if ( i == NULL ) { 01549 if ( msg == NULL ) { 01550 throw NullPointerException("You may not access value methods on invalid iterator"); 01551 } 01552 return (msg->msgid() == MSG_CONFIG_INT_VALUE); 01553 } else { 01554 return i->is_int(); 01555 } 01556 } 01557 01558 01559 bool 01560 NetworkConfiguration::NetConfValueIterator::is_bool() 01561 { 01562 if ( i == NULL ) { 01563 if ( msg == NULL ) { 01564 throw NullPointerException("You may not access value methods on invalid iterator"); 01565 } 01566 return (msg->msgid() == MSG_CONFIG_BOOL_VALUE); 01567 } else { 01568 return i->is_bool(); 01569 } 01570 } 01571 01572 01573 bool 01574 NetworkConfiguration::NetConfValueIterator::is_string() 01575 { 01576 if ( i == NULL ) { 01577 if ( msg == NULL ) { 01578 throw NullPointerException("You may not access value methods on invalid iterator"); 01579 } 01580 return (msg->msgid() == MSG_CONFIG_STRING_VALUE); 01581 } else { 01582 return i->is_string(); 01583 } 01584 } 01585 01586 01587 bool 01588 NetworkConfiguration::NetConfValueIterator::is_default() 01589 { 01590 if ( i == NULL ) { 01591 if ( msg == NULL ) { 01592 throw NullPointerException("You may not access value methods on invalid iterator"); 01593 } else { 01594 unsigned int msgid = msg->msgid(); 01595 switch (msgid) { 01596 case MSG_CONFIG_FLOAT_VALUE: 01597 { 01598 config_float_value_msg_t *m = msg->msg<config_float_value_msg_t>(); 01599 return m->cp.is_default; 01600 } 01601 case MSG_CONFIG_UINT_VALUE: 01602 { 01603 config_uint_value_msg_t *m = msg->msg<config_uint_value_msg_t>(); 01604 return m->cp.is_default; 01605 } 01606 case MSG_CONFIG_INT_VALUE: 01607 { 01608 config_int_value_msg_t *m = msg->msg<config_int_value_msg_t>(); 01609 return m->cp.is_default; 01610 } 01611 case MSG_CONFIG_BOOL_VALUE: 01612 { 01613 config_bool_value_msg_t *m = msg->msg<config_bool_value_msg_t>(); 01614 return m->cp.is_default; 01615 } 01616 case MSG_CONFIG_STRING_VALUE: 01617 { 01618 config_string_value_msg_t *m = msg->msgge<config_string_value_msg_t>(); 01619 return m->cp.is_default; 01620 } 01621 } 01622 01623 throw TypeMismatchException("NetworkConfiguration: Neither in mirror mode nor " 01624 "iterator to value message"); 01625 } 01626 } else { 01627 return i->is_default(); 01628 } 01629 } 01630 01631 01632 float 01633 NetworkConfiguration::NetConfValueIterator::get_float() 01634 { 01635 if ( i == NULL ) { 01636 if ( msg == NULL ) { 01637 throw NullPointerException("You may not access value methods on invalid iterator"); 01638 } 01639 if (msg->msgid() == MSG_CONFIG_FLOAT_VALUE) { 01640 config_float_value_msg_t *fm = msg->msg<config_float_value_msg_t>(); 01641 return fm->f; 01642 } else { 01643 throw TypeMismatchException("NetConfValueIterator::get_float: type mismatch"); 01644 } 01645 } else { 01646 return i->get_float(); 01647 } 01648 } 01649 01650 01651 unsigned int 01652 NetworkConfiguration::NetConfValueIterator::get_uint() 01653 { 01654 if ( i == NULL ) { 01655 if ( msg == NULL ) { 01656 throw NullPointerException("You may not access value methods on invalid iterator"); 01657 } 01658 if (msg->msgid() == MSG_CONFIG_UINT_VALUE) { 01659 config_uint_value_msg_t *um = msg->msg<config_uint_value_msg_t>(); 01660 return um->u; 01661 } else { 01662 throw TypeMismatchException("NetConfValueIterator::get_uint: type mismatch"); 01663 } 01664 } else { 01665 return i->get_int(); 01666 } 01667 } 01668 01669 01670 int 01671 NetworkConfiguration::NetConfValueIterator::get_int() 01672 { 01673 if ( i == NULL ) { 01674 if ( msg == NULL ) { 01675 throw NullPointerException("You may not access value methods on invalid iterator"); 01676 } 01677 if (msg->msgid() == MSG_CONFIG_INT_VALUE) { 01678 config_int_value_msg_t *im = msg->msg<config_int_value_msg_t>(); 01679 return im->i; 01680 } else { 01681 throw TypeMismatchException("NetConfValueIterator::get_int: type mismatch"); 01682 } 01683 } else { 01684 return i->get_int(); 01685 } 01686 } 01687 01688 01689 bool 01690 NetworkConfiguration::NetConfValueIterator::get_bool() 01691 { 01692 if ( i == NULL ) { 01693 if ( msg == NULL ) { 01694 throw NullPointerException("You may not access value methods on invalid iterator"); 01695 } 01696 if (msg->msgid() == MSG_CONFIG_BOOL_VALUE) { 01697 config_bool_value_msg_t *bm = msg->msg<config_bool_value_msg_t>(); 01698 return (bm->b != 0); 01699 } else { 01700 throw TypeMismatchException("NetConfValueIterator::get_bool: type mismatch"); 01701 } 01702 } else { 01703 return i->get_bool(); 01704 } 01705 } 01706 01707 01708 std::string 01709 NetworkConfiguration::NetConfValueIterator::get_string() 01710 { 01711 if ( i == NULL ) { 01712 if ( msg == NULL ) { 01713 throw NullPointerException("You may not access value methods on invalid iterator"); 01714 } 01715 if (msg->msgid() == MSG_CONFIG_STRING_VALUE) { 01716 config_string_value_msg_t *sm = msg->msgge<config_string_value_msg_t>(); 01717 return sm->s; 01718 } else { 01719 throw TypeMismatchException("NetConfValueIterator::get_string: type mismatch, expected %u, got %u", 01720 MSG_CONFIG_STRING_VALUE, msg->msgid()); 01721 } 01722 } else { 01723 return i->get_string(); 01724 } 01725 } 01726 01727 01728 std::string 01729 NetworkConfiguration::NetConfValueIterator::get_comment() 01730 { 01731 if ( i == NULL ) { 01732 if ( msg == NULL ) { 01733 throw NullPointerException("You may not access value methods on invalid iterator"); 01734 } 01735 if (msg->msgid() == MSG_CONFIG_COMMENT_VALUE) { 01736 config_comment_msg_t *cm = msg->msgge<config_comment_msg_t>(); 01737 return cm->s; 01738 } else { 01739 throw TypeMismatchException("NetConfValueIterator::get_comment: type mismatch"); 01740 } 01741 } else { 01742 return i->get_comment(); 01743 } 01744 } 01745 01746 } // end namespace fawkes