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