LogService-2.7.0/000755 000765 000765 00000000000 11576373446 015216 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/AUTHORS000644 000765 000765 00000000203 11576373445 016260 0ustar00bdepardobdepardo000000 000000 Georg Hoesch (hoesch@in.tum.de) Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) Raphael Bolze (Raphael.Bolze@ens-lyon.fr) LogService-2.7.0/ChangeLog000644 000765 000765 00000002231 11576373445 016765 0ustar00bdepardobdepardo000000 000000 Changes: v2.7 - POA name has been changed to bidirLogService - SIGTERM and SIGINT can be used to properly shut down LogService v2.6.1 - a few bug fixes and code improvement v2.6 - use of forwarder for log service (add the LogORBMgr class and the right idl and implementations) - Fix static compilation problem (manual ar ruv liblog.a .o) v2.3 - modify some string decalaration to avoid warning from gcc v2.2 - migrate from autotools to cmake building process v2.1 - add DIETLogTool v2.0 - changed the behavior when a component is signing in: When trying to add a new component, we check if the name of the component exists and if the component is reachable + if the name already exists: - if the component is reachable, then we do not connect the new component - else we consider that the component is lost, and we delete the old component ant add the new one + else add the component The components have to implement a new method: test(), used to test if the component is reachable v1.0 First version. Filtering by tags and components, dynamic attachment of tools and components, autogenerated names, stored systemstate. LogService-2.7.0/Cmake/000755 000765 000765 00000000000 11576373445 016235 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/CMakeLists.txt000644 000765 000765 00000012052 11576373462 017754 0ustar00bdepardobdepardo000000 000000 project( LOGSERVICE ) cmake_minimum_required( VERSION 2.6 ) set(LOGSERVICE_MAJOR_VERSION 2) set(LOGSERVICE_MINOR_VERSION 7) set(LOGSERVICE_REVISION_VERSION 0) set(LOGSERVICE_VERSION ${LOGSERVICE_MAJOR_VERSION}.${LOGSERVICE_MINOR_VERSION}.${LOGSERVICE_REVISION_VERSION}) #-------------- PLATFORM SPECIFIC COMPILATION FLAGS ----------------------- # Requires CMake >= 2.4.7 string( COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "AIX" AIX ) string( COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Darwin" APPLE ) string( COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Linux" LINUX ) string( COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "SunOS" SUNOS ) string( COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "FreeBSD" FREEBSD ) if( AIX ) message( STATUS "XXX System name Aix" ) add_definitions( -D__aix__ ) elseif( APPLE ) message( STATUS "XXX System name Darwin" ) add_definitions( -D__darwin__ ) elseif( LINUX ) message( STATUS "XXX System name Linux" ) add_definitions( -D__linux__ ) elseif( SUNOS ) message( STATUS "XXX System name SunOS" ) add_definitions( -D__sunos__ ) elseif( FREEBSD ) message( STATUS "XXX System name FreeBSD" ) add_definitions( -D__freebsd__ ) endif() # --------------------- DEPENDENCIES TOWARDS EXTERNAL PACKAGES ------------- # Path to additional modules (i.e. used by FIND_PACKAGE commands making # reference to non CMake defined "standard" modules): set( CMAKE_MODULE_PATH ${LOGSERVICE_SOURCE_DIR}/Cmake ) # ---------------- SET THE LINKER SEARCH PATH (RPATH) ---------------------- set( CMAKE_INSTALL_RPATH_USE_LINK_PATH ON CACHE BOOL "Whether to set an rpath for dynamic libraries." ) set( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib CACHE STRING "Rpath set at install stage." FORCE ) # --------------------- DEPENDENCIES TOWARDS OmniORB ----------------------- # To remove an issue with Cmake internal rpath tool if (NOT BUILT_SHARED_LIBS) set(CMAKE_NO_BUILTIN_CHRPATH 1) endif () # because x86_64 can't link static libraries to shared libraries # and from 2.5, this is what is done in DIET # see http://www.mail-archive.com/cross-lfs%40linuxfromscratch.org/msg00411.html # You will get these messages on x86_64 any place that libtool tries to use a static (.a) library in a .la, and as it says, it can't link. These "recompile with -fPIC" messages fall into three types - # (i) recompile the current package with -fPIC # (ii) fix a broken symlink (I had a dangling symlink for ncurses in my scripts, because of a typo - on x86 libtool couldn't find the .so but took the .a and ran with it, on x86_64 it barfed). # (iii) convert a Makefile to use .la instead of .a (very uncommon). # Note: CMAKE_SYSTEM_PROCESSOR return the equivalent of uname -p, note uname -m if (UNIX AND NOT WIN32) find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) if (CMAKE_UNAME) exec_program(uname ARGS -m OUTPUT_VARIABLE SYSTEM_PROC_TYPE) set(SYSTEM_PROC_TYPE ${SYSTEM_PROC_TYPE} CACHE INTERNAL "processor type (i386 and x86_64)") if (SYSTEM_PROC_TYPE MATCHES "x86_64|amd64") # TODO: Should be done only for libraries build add_definitions(-fPIC) endif() endif() endif() # Are libraries dynamic libraries as opposed to library archives ? # Note: this variable is a cmake internal. option(BUILD_SHARED_LIBS "Build libraries as shared libraries." ON) # --------------------- DEPENDENCIES TOWARDS OmniORB ----------------------- find_package( OmniORB ) if (OMNIORB4_FOUND) add_definitions(-D__OMNIORB4__) if (BUILD_SHARED_LIBS) # Link DIET to OmniORB shared libs set(OMNIORB4_LIBRARIES ${OMNIORB4_LIBRARIES_sh}) else () # Link DIET to OmniORB static libs set(OMNIORB4_LIBRARIES ${OMNIORB4_LIBRARIES_st}) endif () else () message("omniORB installation was not found. Please provide OMNIORB4_DIR:") message(" - through the GUI when working with ccmake, ") message(" - as a command line argument when working with cmake e.g. ") message(" cmake .. -DOMNIORB4_DIR:PATH=/usr/local/omniORB-4.0.7 ") message("Note: the following message is triggered by cmake on the first ") message(" undefined necessary PATH variable (e.g. OMNIORB4_INCLUDE_DIR).") message(" Providing OMNIORB4_DIR (as above described) is probably the") message(" simplest solution unless you have a really customized/odd") message(" omniORB installation...") set(OMNIORB4_DIR "" CACHE PATH "Root of omniORB install tree.") endif () # ------------------------- BACKGROUND OPTION ---------------------------- option( LOGSERVICE_BACKGROUND "Add the background support..." ON ) if( LOGSERVICE_BACKGROUND ) add_definitions( -DHAVE_BACKGROUND ) endif() if (UNIX AND NOT WIN32) find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) if (CMAKE_UNAME) exec_program(uname ARGS -m OUTPUT_VARIABLE SYSTEM_PROC_TYPE) set(SYSTEM_PROC_TYPE ${SYSTEM_PROC_TYPE} CACHE INTERNAL "processor type (i386 and x86_64)") if (SYSTEM_PROC_TYPE MATCHES "x86_64|amd64") # TODO: Should be done only for libraries build add_definitions(-fPIC) endif() endif() endif() set (AR_DIR ${CMAKE_MODULE_PATH}) find_package (AR) add_subdirectory( src ) add_subdirectory( docs/man ) LogService-2.7.0/docs/000755 000765 000765 00000000000 11576373446 016146 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/INSTALL000644 000765 000765 00000024457 11576373445 016262 0ustar00bdepardobdepardo000000 000000 This is a text help for LogService installation, extracted from the User's Manual. Dependencies General remarks on LogService platform dependencies LogService is itself written in C/C++ and for limited parts in java. LogService is based on CORBA and thus depends on the chosen CORBA implementation. Thus, we could expect LogService to be effective on any platform offering decent version of such compilers. Nevertheless, if you encounter installation difficulties don't hesitate to post on DIET's users mailing list: \verb+diet-usr@listes.ens-lyon.fr+ (for the archives refer to \url{http://graal.ens-lyon.fr/DIET/mail-lists.html}). Note that LogService has no dependencies with DIET, but it has been developped in order to be used with DIET. The DIET team support the developpment of LogService. If you find a bug in LogService, please don't hesitate to submit a bug report on \url{http://graal.ens-lyon.fr/bugzilla}. If you have multiple bugs to report, please make multiple submissions, rather than submitting multiple bugs in a single report. Hardware dependencies LogService is fully tested on Linux/i386 and Linux/i686 platforms. LogService is known to be effective on Linux/Sparc, Linux/i64, Linux/amd64, Linux/Alpha, Linux/PowerPC AIX/powerPC and MacOS/PowerPC platforms. Supported Compilers LogService is supported on GCC with versions ranging from 3.2.X to 4.1.X. Note that due to omniORB 4 requirements towards thread-safe management of exception handling, compiling LogService with gcc requires at least gcc-2.96. LogService is supported also on XL C/C++ compiler (IBM). Operating System dependencies LogService is fully tested on Linux [with varying distributions like Debian, Red Hat Enterprise Linux (REL-ES-3), Fedora Core (5)], on AIX (5.3) and on MacOSX (Darwin 8). Software dependencies CORBA is used for all communications inside the platform. The implementations of CORBA currently supported in LogService is omniORB 4 which itself depends on Python. NB: We have noticed that some problems occur with Python 2.3: the C++ code generated by idl could not be compiled. It has been patched in LogService, but some warnings may still appear. omniORB 4 itself also depends on OpenSSL in case you wish to secure your LogService platform. If you want to deploy a secure LogService platform, SSL support is not yet implemented in LogService, but an easy way to do so is to deploy LogService over a VPN. In order to deploy CORBA services with omniORB, a configuration file and a log directory are required for a complete description of the services. Their paths can be given to omniORB either at runtime (through the well-known environment variables $OMNIORB_CONFIG and $OMNINAMES_LOGDIR), and/or at omniORB compile time (with the --with-omniORB-config and --with-omniNames-logdir options). Compiling the platform LogService compilation process moved away from the traditional autotools way of things to a tool named cmake (mainly to benefit from cmake's built-in regression tests mechanism). Before compiling LogService itself, first install the above mentioned dependencies. Then untar the LogService archive and change current directory to its root directory. Obtaining and installing cmake per se LogService requires using cmake at least version 2.4.7. For many popular distributions cmake is incorporated by default or at least apt-get (or whatever your distro package installer might be) is cmake aware. Still, in case you need to install an up-to-date version cmake's official site distributes many binary versions (alas packaged as tarballs) which are made available at http://www.cmake.org/HTML/Download.html. Optionally, you can download the sources and recompile them: this simple process (./bootstrap; make; make install) is described at http://www.cmake.org/HTML/Install.html. Configuring LogService's compilation: cmake quick instruction If you are already experienced with cmake then using it to compile LogService should provide no surprise. LogService respects cmake's best practices e.g. by clearly separating the source tree from the binary tree (or compile tree), by exposing the main configuration optional flag variables prefixed by LOGSERVICE_ and by hiding away the technical variables) and by not postponing configuration difficulties (in particular the handling of external dependencies like libraries) to compile stage. Cmake classically provides two ways for setting configuration parameters in order to generate the makefiles in the form of two commands ccmake and cmake (the first one has an extra "c" character): -- ccmake [options] in order to specify the parameters interactively through a GUI interface -- cmake [options] [-D:=] in order to define the parameters with the -D flag directly from the command line. In the above syntax description of both commands, specifies a path to the top level of the source tree (i.e. the directory where the top level CMakeLists.txt file is to be encountered). Also the current working directory will be used as the root of the build tree for the project (out of source building is generally encouraged especially when working on a CVS tree). Here is a short list of cmake internal parameters that are worth mentioning: -- CMAKE_BUILD_TYPE controls the type of build mode among which Debug will produce binaries and libraries with the debugging information -- CMAKE_VERBOSE_MAKEFILE is a Boolean parameter which when set to ON will generate makefiles without the .SILENT directive. This is useful for watching the invoked commands and their arguments in case things go wrong. -- CMAKE_C[XX]_FLAGS* is a family of parameters used for the setting and the customization of various C/C++ compiler options. -- CMAKE_INSTALL_PREFIX variable defines the location of the install directory (defaulted to /usr/local on un*x). This is cmake's portable equivalent of the autotools configure's --prefix= option. Eventually, here is a short list of ccmake interface tips: -- when lost, look at the bottom lines of the interface which always summarizes ccmake's most pertinent options (corresponding keyboard shortcuts) depending on your current context -- hitting the "h" key will direct you ccmake embedded tutorial and a list of keyboard shortcuts (as mentioned in the bottom lines, hit "e" to exit) -- up/down navigation among parameter items can be achieved with the up/down arrows -- when on a parameter item, the line in inverted colors (close above the bottom of the screen) contains a short description of the selected parameter as well as the set of possible/recommended values -- toggling of boolean parameters is made with enter -- press enter to edit path variables -- when editing a PATH typed parameter the TAB keyboard shortcut provides an emacs-like (or bash-like) automatic path completion. -- toggling of advanced mode (press "t") reveals hidden parameters A ccmake walk-through for the impatients Assume that LOGSERVICE_HOME represents a path to the top level directory of LogService sources. This LogService sources directories tree can be obtained by LogService users by expanding the LogService current source level distribution tarball. But for the developers this directories tree simply corresponds to the directory GRAAL/devel/diet/diet-contrib/LogService of a cvs checkout of the LogService sources hierarchy. Additionally, assume we created a build tree directory and cd to it (in the example below we chose LOGSERVICE_HOME/build as build tree, but feel free to follow your conventions): -- cd LOGSERVICE_HOME/build -- ccmake .. to enter the GUI -- press c (equivalent of bootstrap.sh of the autotools) -- toggle the desired options e.g. LOGSERVICE_BACKGROUND -- specify the CMAKE_INSTALL_PREFIX parameter (if you wish to install in a directory different from /usr/local, -- press c again, for checking required dependencies check all the parameters preceded with the * (star) character whose value was automatically retrieved by cmake. -- provide the required information i.e. fill in the proper values for all parameters whose value is terminated by NOT-FOUND -- iterate the above process of parameter checking, toggle/specification and configuration until all configuration information is satisfied -- press g to generate the makefile -- press q to exit ccmake -- make in order to classically launch the compilation process -- make install when installation is required LogService's main configuration flags Here are the main configuration flags: -- OMNIORB4_DIR is the path to the omniORB4 installation directory (only relevant when omniORB4 was not installed in /usr/local). -- LOGSERVICE_BACKGROUND Add the background support Example: cmake .. -DOMNIORB4_DIR:PATH=$HOME/local/omniORB-4.0.7 Compiling and installing Summarizing the configuration choices Once the configuration is properly made one can check the choices made by looking the little summary proposed by cmake. This summary should look like ([...] denotes eluded portions): ~/LogService > ./cmake .. -- XXX System name Linux -- Configuring done -- Generating done -- Build files have been written to: /home/diet/devel/LOGSERVICE/logservice-cvs/build A more complete, yet technical, way of making sure is to check the content of the file named CMakeCache.txt (generated by cmake in the directory from which cmake was invocated). When exchanging with the developers list it is a recommendable practice to join the content of this file which summarizes your options and also the automatic package/library detections made by cmake. Compiling stage You are now done with the configuration stage (equivalent of both the bootstrap.sh and ./configure stage of the autotools). You are now back to your platform level development tools i.e. +make when working on Unices. Hence you can now proceed with the compiling process by launching make. LogService-2.7.0/LICENCE_eng000644 000765 000765 00000051151 11576373445 017036 0ustar00bdepardobdepardo000000 000000 CeCILL FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat à l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble The purpose of this Free Software license agreement is to grant users the right to modify and redistribute the software governed by this license within the framework of an open source distribution model. The exercising of these rights is conditional upon certain obligations for users so as to preserve this status for all subsequent redistributions. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Software by any or all Contributors, as well as any or all Internal Modules. Module: means a set of sources files including their documentation that enables supplementary functions or services in addition to those offered by the Software. External Module: means any or all Modules, not derived from the Software, so that this Module and the Software run in separate address spaces, with one calling the other when they are run. Internal Module: means any or all Module, connected to the Software so that they both execute in the same address space. GNU GPL: means the GNU General Public License version 2 or any subsequent version, as published by the Free Software Foundation Inc. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS The right to make Contributions includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. The Licensee is authorized to make any or all Contributions to the Software provided that it includes an explicit notice that it is the author of said Contribution and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows future Licensees unhindered access to the full Source Code of the Software by indicating how to access it, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE When the Licensee makes a Contribution to the Software, the terms and conditions for the distribution of the resulting Modified Software become subject to all the provisions of this Agreement. The Licensee is authorized to distribute the Modified Software, in source code or object code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the object code of the Modified Software is redistributed, the Licensee allows future Licensees unhindered access to the full source code of the Modified Software by indicating how to access it, it being understood that the additional cost of acquiring the source code shall not exceed the cost of transferring the data. 5.3.3 DISTRIBUTION OF EXTERNAL MODULES When the Licensee has developed an External Module, the terms and conditions of this Agreement do not apply to said External Module, that may be distributed under a separate license agreement. 5.3.4 COMPATIBILITY WITH THE GNU GPL The Licensee can include a code that is subject to the provisions of one of the versions of the GNU GPL in the Modified or unmodified Software, and distribute that entire code under the terms of the same version of the GNU GPL. The Licensee can include the Modified or unmodified Software in a code that is subject to the provisions of one of the versions of the GNU GPL, and distribute that entire code under the terms of the same version of the GNU GPL. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE CONTRIBUTIONS The Licensee who develops a Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE EXTERNAL MODULES The Licensee who develops an External Module is the owner of the intellectual property rights over this External Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution. 6.4 JOINT PROVISIONS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis-à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version, subject to the provisions of Article 5.3.4. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 2.0 dated 2006-09-05. LogService-2.7.0/LICENCE_fr000644 000765 000765 00000051733 11576373445 016702 0ustar00bdepardobdepardo000000 000000 CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL Avertissement Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes préside à sa rédaction: * d'une part, le respect des principes de diffusion des logiciels libres: accès au code source, droits étendus conférés aux utilisateurs, * d'autre part, la désignation d'un droit applicable, le droit français, auquel elle est conforme, tant au regard du droit de la responsabilité civile que du droit de la propriété intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel. Les auteurs de la licence CeCILL (pour Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) sont: Commissariat à l'Energie Atomique - CEA, établissement public de recherche à caractère scientifique, technique et industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. Centre National de la Recherche Scientifique - CNRS, établissement public à caractère scientifique et technologique, dont le siège est situé 3 rue Michel-Ange, 75794 Paris cedex 16. Institut National de Recherche en Informatique et en Automatique - INRIA, établissement public à caractère scientifique et technologique, dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex. Préambule Ce contrat est une licence de logiciel libre dont l'objectif est de conférer aux utilisateurs la liberté de modification et de redistribution du logiciel régi par cette licence dans le cadre d'un modèle de diffusion en logiciel libre. L'exercice de ces libertés est assorti de certains devoirs à la charge des utilisateurs afin de préserver ce statut au cours des redistributions ultérieures. L'accessibilité au code source et les droits de copie, de modification et de redistribution qui en découlent ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limitée et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concédants successifs qu'une responsabilité restreinte. A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc à des développeurs ou des professionnels avertis possédant des connaissances informatiques approfondies. Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve de le conserver en l'état, sans ajout ni suppression de clauses. Ce contrat est susceptible de s'appliquer à tout logiciel dont le titulaire des droits patrimoniaux décide de soumettre l'exploitation aux dispositions qu'il contient. Article 1 - DEFINITIONS Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une lettre capitale, auront la signification suivante: Contrat: désigne le présent contrat de licence, ses éventuelles versions postérieures et annexes. Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas échéant sa documentation, dans leur état au moment de l'acceptation du Contrat par le Licencié. Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et éventuellement de Code Objet et le cas échéant sa documentation, dans leur état au moment de leur première diffusion sous les termes du Contrat. Logiciel Modifié: désigne le Logiciel modifié par au moins une Contribution. Code Source: désigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accès est nécessaire en vue de modifier le Logiciel. Code Objet: désigne les fichiers binaires issus de la compilation du Code Source. Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial. Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le Contrat. Contributeur: désigne le Licencié auteur d'au moins une Contribution. Concédant: désigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat. Contribution: désigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans le Logiciel par tout Contributeur, ainsi que tout Module Interne. Module: désigne un ensemble de fichiers sources y compris leur documentation qui permet de réaliser des fonctionnalités ou services supplémentaires à ceux fournis par le Logiciel. Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce Module et le Logiciel s'exécutent dans des espaces d'adressage différents, l'un appelant l'autre au moment de leur exécution. Module Interne: désigne tout Module lié au Logiciel de telle sorte qu'ils s'exécutent dans le même espace d'adressage. GNU GPL: désigne la GNU General Public License dans sa version 2 ou toute version ultérieure, telle que publiée par Free Software Foundation Inc. Parties: désigne collectivement le Licencié et le Concédant. Ces termes s'entendent au singulier comme au pluriel. Article 2 - OBJET Le Contrat a pour objet la concession par le Concédant au Licencié d'une licence non exclusive, cessible et mondiale du Logiciel telle que définie ci-après à l'article 5 pour toute la durée de protection des droits portant sur ce Logiciel. Article 3 - ACCEPTATION 3.1 L'acceptation par le Licencié des termes du Contrat est réputée acquise du fait du premier des faits suivants: * (i) le chargement du Logiciel par tout moyen notamment par téléchargement à partir d'un serveur distant ou par chargement à partir d'un support physique; * (ii) le premier exercice par le Licencié de l'un quelconque des droits concédés par le Contrat. 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spécificités du Logiciel, à la restriction de garantie et à la limitation à un usage par des utilisateurs expérimentés a été mis à disposition du Licencié préalablement à son acceptation telle que définie à l'article 3.1 ci dessus et le Licencié reconnaît en avoir pris connaissance. Article 4 - ENTREE EN VIGUEUR ET DUREE 4.1 ENTREE EN VIGUEUR Le Contrat entre en vigueur à la date de son acceptation par le Licencié telle que définie en 3.1. 4.2 DUREE Le Contrat produira ses effets pendant toute la durée légale de protection des droits patrimoniaux portant sur le Logiciel. Article 5 - ETENDUE DES DROITS CONCEDES Le Concédant concède au Licencié, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la durée du Contrat dans les conditions ci-après détaillées. Par ailleurs, si le Concédant détient ou venait à détenir un ou plusieurs brevets d'invention protégeant tout ou partie des fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas opposer les éventuels droits conférés par ces brevets aux Licenciés successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concédant s'engage à faire reprendre les obligations du présent alinéa aux cessionnaires. 5.1 DROIT D'UTILISATION Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant aux domaines d'application, étant ci-après précisé que cela comporte: 1. la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme. 2. le chargement, l'affichage, l'exécution, ou le stockage du Logiciel sur tout support. 3. la possibilité d'en observer, d'en étudier, ou d'en tester le fonctionnement afin de déterminer les idées et principes qui sont à la base de n'importe quel élément de ce Logiciel; et ceci, lorsque le Licencié effectue toute opération de chargement, d'affichage, d'exécution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat. 5.2 DROIT D'APPORTER DES CONTRIBUTIONS Le droit d'apporter des Contributions comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en résultant. Le Licencié est autorisé à apporter toute Contribution au Logiciel sous réserve de mentionner, de façon explicite, son nom en tant qu'auteur de cette Contribution et la date de création de celle-ci. 5.3 DROIT DE DISTRIBUTION Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le marché à titre onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé. Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou non, à des tiers dans les conditions ci-après détaillées. 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION Le Licencié est autorisé à distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le Code Objet du Logiciel est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au Code Source complet du Logiciel en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du Code Source ne devra pas excéder le simple coût de transfert des données. 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE Lorsque le Licencié apporte une Contribution au Logiciel, les conditions de distribution du Logiciel Modifié en résultant sont alors soumises à l'intégralité des dispositions du Contrat. Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de code source ou de code objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le code objet du Logiciel Modifié est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au code source complet du Logiciel Modifié en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du code source ne devra pas excéder le simple coût de transfert des données. 5.3.3 DISTRIBUTION DES MODULES EXTERNES Lorsque le Licencié a développé un Module Externe les conditions du Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué sous un contrat de licence différent. 5.3.4 COMPATIBILITE AVEC LA LICENCE GNU GPL Le Licencié peut inclure un code soumis aux dispositions d'une des versions de la licence GNU GPL dans le Logiciel modifié ou non et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis aux dispositions d'une des versions de la licence GNU GPL et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Article 6 - PROPRIETE INTELLECTUELLE 6.1 SUR LE LOGICIEL INITIAL Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la faculté de modifier les conditions de diffusion de ce Logiciel Initial. Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi par le Contrat et ce, pour la durée visée à l'article 4.2. 6.2 SUR LES CONTRIBUTIONS Le Licencié qui a développé une Contribution est titulaire sur celle-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable. 6.3 SUR LES MODULES EXTERNES Le Licencié qui a développé un Module Externe est titulaire sur celui-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable et reste libre du choix du contrat régissant sa diffusion. 6.4 DISPOSITIONS COMMUNES Le Licencié s'engage expressément: 1. à ne pas supprimer ou modifier de quelque manière que ce soit les mentions de propriété intellectuelle apposées sur le Logiciel; 2. à reproduire à l'identique lesdites mentions de propriété intellectuelle sur les copies du Logiciel modifié ou non. Le Licencié s'engage à ne pas porter atteinte, directement ou indirectement, aux droits de propriété intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et à prendre, le cas échéant, à l'égard de son personnel toutes les mesures nécessaires pour assurer le respect des dits droits de propriété intellectuelle du Titulaire et/ou des Contributeurs. Article 7 - SERVICES ASSOCIES 7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de prestations d'assistance technique ou de maintenance du Logiciel. Cependant le Concédant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors déterminés dans un acte séparé. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilité du Concédant qui les propose. 7.2 De même, tout Concédant est libre de proposer, sous sa seule responsabilité, à ses licenciés une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, dans les conditions qu'il souhaite. Cette garantie et les modalités financières de son application feront l'objet d'un acte séparé entre le Concédant et le Licencié. Article 8 - RESPONSABILITE 8.1 Sous réserve des dispositions de l'article 8.2, le Licencié a la faculté, sous réserve de prouver la faute du Concédant concerné, de solliciter la réparation du préjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve. 8.2 La responsabilité du Concédant est limitée aux engagements pris en application du Contrat et ne saurait être engagée en raison notamment: (i) des dommages dus à l'inexécution, totale ou partielle, de ses obligations par le Licencié, (ii) des dommages directs ou indirects découlant de l'utilisation ou des performances du Logiciel subis par le Licencié et (iii) plus généralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressément que tout préjudice financier ou commercial (par exemple perte de données, perte de bénéfices, perte d'exploitation, perte de clientèle ou de commandes, manque à gagner, trouble commercial quelconque) ou toute action dirigée contre le Licencié par un tiers, constitue un dommage indirect et n'ouvre pas droit à réparation par le Concédant. Article 9 - GARANTIE 9.1 Le Licencié reconnaît que l'état actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vérifier toutes les utilisations ni de détecter l'existence d'éventuels défauts. L'attention du Licencié a été attirée sur ce point sur les risques associés au chargement, à l'utilisation, la modification et/ou au développement et à la reproduction du Logiciel qui sont réservés à des utilisateurs avertis. Il relève de la responsabilité du Licencié de contrôler, par tous moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. 9.2 Le Concédant déclare de bonne foi être en droit de concéder l'ensemble des droits attachés au Logiciel (comprenant notamment les droits visés à l'article 5). 9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le Concédant sans autre garantie, expresse ou tacite, que celle prévue à l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractère sécurisé, innovant ou pertinent. En particulier, le Concédant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'équipement du Licencié et sa configuration logicielle ni qu'il remplira les besoins du Licencié. 9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le Logiciel ne porte pas atteinte à un quelconque droit de propriété intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de propriété. Ainsi, le Concédant exclut toute garantie au profit du Licencié contre les actions en contrefaçon qui pourraient être diligentées au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Néanmoins, si de telles actions sont exercées contre le Licencié, le Concédant lui apportera son aide technique et juridique pour sa défense. Cette aide technique et juridique est déterminée au cas par cas entre le Concédant concerné et le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage toute responsabilité quant à l'utilisation de la dénomination du Logiciel par le Licencié. Aucune garantie n'est apportée quant à l'existence de droits antérieurs sur le nom du Logiciel et sur l'existence d'une marque. Article 10 - RESILIATION 10.1 En cas de manquement par le Licencié aux obligations mises à sa charge par le Contrat, le Concédant pourra résilier de plein droit le Contrat trente (30) jours après notification adressée au Licencié et restée sans effet. 10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concédées antérieurement à la résiliation du Contrat resteront valides sous réserve qu'elles aient été effectuées en conformité avec le Contrat. Article 11 - DISPOSITIONS DIVERSES 11.1 CAUSE EXTERIEURE Aucune des Parties ne sera responsable d'un retard ou d'une défaillance d'exécution du Contrat qui serait dû à un cas de force majeure, un cas fortuit ou une cause extérieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du réseau électrique ou de télécommunication, la paralysie du réseau liée à une attaque informatique, l'intervention des autorités gouvernementales, les catastrophes naturelles, les dégâts des eaux, les tremblements de terre, le feu, les explosions, les grèves et les conflits sociaux, l'état de guerre... 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intéressée à s'en prévaloir ultérieurement. 11.3 Le Contrat annule et remplace toute convention antérieure, écrite ou orale, entre les Parties sur le même objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet à l'égard des Parties à moins d'être faite par écrit et signée par leurs représentants dûment habilités. 11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat s'avèrerait contraire à une loi ou à un texte applicable, existants ou futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les amendements nécessaires pour se conformer à cette loi ou à ce texte. Toutes les autres dispositions resteront en vigueur. De même, la nullité, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraîner la nullité de l'ensemble du Contrat. 11.5 LANGUE Le Contrat est rédigé en langue française et en langue anglaise, ces deux versions faisant également foi. Article 12 - NOUVELLES VERSIONS DU CONTRAT 12.1 Toute personne est autorisée à copier et distribuer des copies de ce Contrat. 12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé et ne peut être modifié que par les auteurs de la licence, lesquels se réservent le droit de publier périodiquement des mises à jour ou de nouvelles versions du Contrat, qui posséderont chacune un numéro distinct. Ces versions ultérieures seront susceptibles de prendre en compte de nouvelles problématiques rencontrées par les logiciels libres. 12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra faire l'objet d'une diffusion ultérieure que sous la même version du Contrat ou une version postérieure, sous réserve des dispositions de l'article 5.3.4. Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE 13.1 Le Contrat est régi par la loi française. Les Parties conviennent de tenter de régler à l'amiable les différends ou litiges qui viendraient à se produire par suite ou à l'occasion du Contrat. 13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter de leur survenance et sauf situation relevant d'une procédure d'urgence, les différends ou litiges seront portés par la Partie la plus diligente devant les Tribunaux compétents de Paris. Version 2.0 du 2006-09-05. LogService-2.7.0/manual.pdf000644 000765 000765 00000611711 11576373445 017174 0ustar00bdepardobdepardo000000 000000 %PDF-1.4 %Çì¢ 5 0 obj <> stream xœÅXKoÜF ¾oû#t«d'Ã!çuLÒæÐÆ{+z°ãÚ-jçå8iÿ}I¤áhµv)$ÊjøúÈäè]g tVþLÿ¾ºÝ=}»ë»ÝøkÝOËÓ_»w;˜þc§ÓÝ÷H#S„îpµƒé8d0.u²×nw¿ö/†½31º@ý›Á‚ ÷×õñL“ >ô¿{v*Ẕ/ÏBÎýGQAõÊcHÖúþÕ½C1ŒÎdÂþVÞCÎÔŸ{0Ö§äú×ƒËÆ»˜ûûjkzõ7E)Xúíð#‡Æ‘&“CÀ$±e2„9u{°ÑXê—Õ³aO,‚Ø_°"@7º 1åþÃ@¢€$Œ þd'Å8…ÙwdÛ¡žœL;mzÏlÚ›P ¿µXë|b<Å5‚ÀpÎOgÃÞ³LÀ°«bäÙ –É9,ƒ‰à3C‰ ÿao¬ÌÑP’79Qyïmò"ƒ•P‚@ä‘Ä(áæì#;²wÎ :íÓ¨"c!®ŽÎ n%â,æ½$k  zÐ(“’Ì÷b  ¾¿Üºã'Ê)-.Px Öê/Š8X©E“’*P2hl]0mž/޼­âo«øÍ¢¾*H‡“´¬Ì””$Àm ªJÛfrdµP»dŒwf`Î%qEÏ&ÑKÌz,ãŸø±»ñôx0NDe¥&òúpQùu¾¼/ŽY7qæ8WK–“#å³Ê·77—¸Á~ø%;Rßé³'ËèÅp¢àg+ˆ_‘Ùä¸h›Nݲd|âöêð¦¨ä…,þ[ÈÆB¡œº.Ì‚+ÌÔ>5•gó×[ê+NÚç:ŒŸHDÕOÕ#-r”l¯ÓíŸ2ÊÉ“z­ ¹À‘Gb~¬Fàh§yýqà|Y¼úíf•yUV"|4ÌUƒH ;N!è|ËÐ"6;´ôÉ`M I³¦¾o#DbǃfÝÑúÔŒÔzÎÌçÄ?`ôÊb WŒÑ·ÃàåÞÃSÑvºg™CÕ=Cb\ 8Œû­6qSz| jmú{¹¼­"•´U÷Q…ËÁyÞ¹:Z?–ɺõ­¸¶ZÇù¥r¿±8ÍEÙFøª$WŽã{RË«³ÊÐ/]bEäIɆÛÜV±á*>¶’é6w})¯©ÏDØ!WCÿ³\.:¯‡áŒÀÉÞ¹±alŽzAL·g~5µµ¶×·4~ÙÁ_Ï|‹Ç΋o‹ó¾êïõœ¹ÌW÷ÐÐÔúJïðdR*­ÃY\îVnd²_­¹è3zlXùfímËå£Rúвïó^ã¹:oãS*e¶Éî˜Á^µ1Eu%j%_ê½t<ºeM—youÁß×JÙ¼M¼1Èéäμ ¦ï¶*ƒí6ÑÞ]VÃq]AÇc˜Mñ:³¹‹\l2³ÎÛõŒ¯Û騡î68úiÝÅÛUâÕงSfIF>%}æÜ–pVëòx´VÏm6'Î?|J_s.U‹nÕ°C2Þ?ü9ii cÛ²ŠãG·“Ý`jJÓí{ÌK»L¨±ŠfÍ3zõÁh¢“"Ùç“à|k¨Ik:·oCÔ É ‚Í¢Ù$ž¾ê¸H¾:¾óÉG—²™6 )¥—»_v¶»æ¿ÿT¨®endstream endobj 6 0 obj 1592 endobj 19 0 obj <> stream xœåWËr5Ýß-?p—Òb„ÔzïH'N <Ì… aÇNac’ñ†_çô¼ÔcOåšÀŽr•-k¤îÓݧz½µÆm-ÿŒO.7ŸçíÙÛM¿»uÛ/çÕ¯›×7þcÇÓÛû;\À¿ÅÔ”|Ùî^nÜxÞYoÊ6•jû—›ŸÔº &ïÕ¡î¬!OÅzu¬ÉdëlRßkgÈÅÕcŒ«o°ÊÖÖª¾ÖÖÄh­‹?ïž°VZhõÙèݽ€"Â¥à)We´75ÚǽiØ Åye§½QâÂŽnÙ9kª«uü@£…¼{ºTµÓ]29å´0i/¾§ÐëR¬I=Ÿ‘¾aóàÔ‰¦l2ìWçºóÑ›‹°iF=®x¯ÜÉgl°4`øVGv}eáÒÍOtMò>æE”tG&z¢ÈFûLÁµ§X8Çøc n 6á.[|Rt41T—&©.j±ß벇º8ã(D8 Þ¡hI}¦CIX:u æT8T½Ð[ù(\üjæÅ 6¡2¹9 Á4ÇÞNÑôœ¢#…›œ¥äÔÛ^~I¤~o›oz+£eœýYø„¹fÂÄ”£[³Ø#źIÝ3ÅNµ"ÒþÙ a64€Ò¶ÞÕZ‘úȹ\c»ü_C-% 6 ¢×4_Ï¿€˜¶ÿ[»Ödu¼‰Ï9©‹9 ?h²ÌK§®f:·}™p2_êd\±#€<ÓÍGsb¯&9º•Îëù+É~ÔÈ<ð¬L¢>G=Ð2à+¤Ey‘¢wÌòÿ:Ca½ ãÄöž ƇÞV@©kL'@›$0æäb ¨O0/yª}JÇŒ8!Š%â8ñç˜i•Î4Ô›:ï›=òÄKž°Z‡ÜY¯šWsYìùRöºRRõ·IÉ·¨»‘’®WfR{“•’Š}rÚx‚t‚¶­p3SR­òÜ‚‘ÁZ ¢Ëî4*dµ¹ˆƒYtH-–{¹÷HûæåᒳɫäËÆ§F”#æ¢`j· .4¡QçCvÜ(?NÄ"êê¾d“nvËÖÈ~`MH 2 G­6pD‡´œlPàk÷¿ô~Z«ç-I¯°KLY·Ö€†i(x'¯ôyÝÚÚjjþÑ”½k7/9¹¸`þvv­Š,f³ºä?-“µU¥±ÀfJë½÷b¹ê›ß)xîöÈ0Œš/K3L0aÌû¦§ ŸQ Sÿ„ðàŒGk•žo3À?D¼TÔœ‡F ËÿútpYÂE ÞÝX˜ØmàÕìðAˆa*üà·¨âƒsª÷²ò_rë#ÎaK)# ùA®`¨Ÿ¨¾¯/ôŒ¯, uÌKȋטÂD<מ«Iê¯ÛÓîG½ÃfurÐÂ}Õ¡qðº™<ÒeoÁaÂ~H“d N Ó/k”iÛTy:׫­œUÞ©•ãè§´ò=§*¶,Â7ÍLÓÈxÕ×E¼ à"”®Z(s¦á à@6O<V+ù1¸@OwÎû;9pý ¬4ä½ à17ì£åÑ21;$É#ñýÞðHG©aËv:¤&Ä„e“3™¦×4°—Rz‡»Íw»=Ãï¿rb'endstream endobj 20 0 obj 1213 endobj 26 0 obj <> stream xœí\Û’·}gå#ø8“*Â×WÙQÙ‰R޾¹ò KÖJ%í®%9Rùïsœ`.$‡—]‘¶KUÖhpôAwŸî¦ß/¥PKÉš¿_Ü.¾ú·_Þ|\¤·KµüG÷ôvñ~¡šȦ÷òÉÂRAÆéåúÕB5Ý£ÞI½tÁ/×·‹«¯k)yR¦º¯•°ÞÄXÝÕ¤„RVW¿ÖZH£c¨~Æ“w OM«TEëÇz%iåÈþwýw¬ŽÍ£ÀËk| /»~¶XÿõÇJÕ«h‚ÁTß×Fx)±è§Z+ám ,µrÂ+«µXÒ:´®¬ÊšP½áfôÃ覧׮ú\¯´°¤uÚ€QVh|ñú%¾Ñ`›ŠŒWܲÚ4­xK6†M7ô¤^Z$Qõœ?Ê"iùµ0ÊY*×Îûò„³ˆØô}»NJ ­¬·›V+£-·üKjöŠÒða_¬³û3pº<á•‘J˜åJ)ì‚OzóYFÂl•ÀúÑàŸ½’Îaáj][•Ãö^óéš MÚ@ƒ£Õ_òÛw<ÞÊ`±UÞ`ŒÖ£«Â’˜VD&ßGt´Rj]ýÖI1¿›|[¯¼Œ"Æ.WëI#œ¶ §¶_þÄ,e¢(¼V-ŽÚ† “(À‡Á }L·€T€h#w¦÷.€A¤¥ÒA´ ºï:ÞòűD΀|EZhR¾èpWâ­ÁÁßµ/Qò‘ÑjIøx%R{´‰'áb<ôì\ö¡yt†ÃºÐ-2@y¶ýnº'HÓzˆ;tÕ¯O6&ôæM’½…µïË~,tÛz3$ ʶpžÐ) ýŸh†ÉŠ®¹ÍlܲÒÏOÏÛå L”#VÑ“0Îÿ.du±7ßn¿ùZÒa 0OáIÂWRQÁCjÛßu£G¦ŸEþcðÎtƒ Â}éÓ½¾‰³ €·'A0 Xαz¾9éýeë°Å%dÿNƒ+zÞåéw+’¼9MrÝr½XOršfæýV„2hžÖ’E™ÂB|®á3:@°Ñü2#áM7{›z|Át¬—/ÈGñ#pmã$P@ˆ+2 @ÍÈ bº°¯D™ƒWsä"B|™A|Ö}è3ôw™–e̲ _²uh R¾|U'f€ºg* 46íD µ¶çº­À`‡· `­úŽ @уFÄßÏ"þ¥Ê¦ÝÄgëݯlÊÓÓ¶;GÐë_¨ôIà[­|aòúÿË=ù¦[©¤äó‘ü©Neã øÑ!^Á:u`º‘c¦û£wÑÞTß×囥öƒ©°ÿ?à†”ÒˈyQk/¼Àß²;Àì~K0hRË£=؈;ã®Y‚_R‹Ÿ¦ÄÀ'¤ûV~ ´[Ï*£ˆ/Þ õUbaÒ_ÌHëMO®ÆL†/æ/f7ùO’Ù:†ZØ)¤­R¸`tÐËiÜìŒ3žÍcìE­A~ …™ÙLn­nÊ@l¤dË7˜y €Ú¬çÝø@åá-P»kÀõpê ׸°Wƒ¬)´é²Wñ8{eæ;?{Ég¥ÞÈ".z²Ë FÞM£rRë5ëËhGÁqgÍ 8ÎGÍnè—ü#¸@[‚›çÅÔ˜­€ßj£C“ÙÊ·|ûáÒ(F”ÆP§#)‚/8_ÐŽ{¸JJs’sOºð®Ë æ\hñ+Ï A¦?7Á-¦@ÅË×å×ÚmUA‹s¸õmÝÅPÿŸ‚i†ë ×,¹òV;“>DKýâ;R=n÷#+BiÄßÖ‹ryƒÿþG(A®endstream endobj 27 0 obj 2356 endobj 31 0 obj <> stream xœ½]I“%·q¾á¿Ð7¾¶§K…ðMTÈa˲$SãðAô¡‡ãYÌÙÄшÿzgb)d¢oé…Á²ùª $rùrCýùj]ÔÕŠÿÔÿ~ÿîÉ/¾ W¯>=É¿^©«ÛþúáÉŸŸ¨ú?k½ûê›gð@¼Rv1Öë«g/Ÿ¨z{rKð«¾ò1\={÷äOu}£”‹7‡ß_߬KÔ«vîð×k£ç;üϵ†GTЇáÖeukÄËxk´kЇ7pƒS*êv«2‡Ÿ®W1*ïþûÙo`.J_Å%yø)O&-ðßß>yö:üG2)¹®íbUþðjûë×7n±Æ‚ጴ‡™¬‹MÉ[3ñKP.Á<Ì’,üsø.Ã)à”ntÒ0€+×óì?Á!,ΘÃ-^_ÿàˆ.À$n´^ŒÑt>oóm‹ ŽÞúºÌM[ã´[ñz4yð2ï¹ü/ûÅiwx‡K‡ûü¶tç4ÞÐÜgÌæ‡wêp?t„l<¼úÙ£§#éܪÖÕ’;Ÿ—ÇÕšŸûHä©Bz ò‹:}ÛÖ„ùØÿØ» ß_4RL^óæÙEµh ìúì0¨H™¾´åúÆ:`Ëhÿ .Á¸Õl›cöi–—'c }ç§²µÉZrkãXqå>ó>!ºûÍÄqÚn+ÛhŒ³§ï1¸.nŒ ¼ôÓµ[’²«®,•¸.iÜ R ReÊel!{~¦2­£ÜÑïûªÿø^ºÞÂ=¹©›ÊbYMŠeoêÆªChµ˜u"צ{yíÐZ™`òZ°¶Ó¤,Sƒh÷˹†‹:º¾_ëzfW ²±ªƒîýñd:ûõû²sÛ ÆÄVƒÆƒ-¿¥lÒèE½îƒ,þ_S-fa7ìjN2çÇJA¥9o¶—n¤ËÛ| _ÖUñ§ i‘7³ÔZ‡œÑÄö5å©Jd7{;,D/iMD®ûâ÷–;µ›'•´°ßl*ú¨ÊÇaË~›²~$´‰–ˆ&ô^ã9ÕL;]î†C•nÑjGÉÎ0ù,BYi~¯Oz5…ô…4Æ“ñÏ·›¡œsr³d”“ó¨%3Ê,FEþ£'sDâ€$‹Ú˜ix»uS0(Lî, sÕzÆ øHôºÙ[•!†…‡µ³¯¶íù£ DcU„úD¢—ˆ0˜ô4–Þïªä%Ò÷Ћ2,Z¼¥uÒÈWY0µ³¢š`¾DóícU¢6…®D?àÓ°© 1?Ž gDè"®ñiy>ú0—À¼ÿLTúø]>6NÒt&äý]¾^ùÙ.wñçA¥n¬ STâó¿Úä{P‰Á› Šº%£¬ðØw °Û·òýê÷ý`që¾eáV)•í#Ðw›b×d!@déãý3nbˆ¬`±›‚Õ÷{E†Ây›âPäß]ã».’VÞç|+0gÁ`Éš¬v Ó¥žÞÊwpÄ&¸V€’¢j¦ÂúÁÍýº€¹‰Ùz…t›¯‡|î—É‹d[a³]bæ.drtâM|Á=sçFÖ8w7ÓÎgU-¦ç¢$ßÎ)e(Œìh´;à_ðÕá™d’»P1„m\B_sG|Ë}§VEGËŒv{tÞM4lnO÷FŒûÉÏ®Á'/ÝÍØfó¿ß@‚e‚߬*",ØÜ5xî³¶EX'§ÌínQ¶>¸GA­¸N0 &Æl1p’O*/èÙ6Ÿ‘“²nù‚KÃÉlõ-•´ì™ÃRȺï³dÌûð²Ñ6@Ücé2ax œÔ‘oæhÖW”“ð×–Eò¯×°ÞÕy'zŸ}ˈùÞéçjøpÿ¢Ê Ú2Óþ²ÝGs`¯2_„­Ð‘›ÑŽ‘9sg£¨gQžM…˜½"Çë]ެPMáç~ëÜRŒ| ¯¢aâ jˆà¿,Ú¼D2!`#z¸@ Å¯‰aÚ¼cV î\!§‘i+'æg†û@󫤓ŒÌÅP1ƒ¯ª…´÷K|^ƒ1Ó‡?TšPß4™«%A\p#¢áÖI8§•óTe6'9nËðN½ßÓ"䕎 8Ò?ÆÇÆÑ¢Òáøæ¢ Õ$ÒsW¶›ˆ„½Àpê³?"P 0”?üTÛj#:®Z•±s-ŹK3†øfpaã`ŒWøBûƒè¢"Ùî(ÉÇÙãYrtr®QTÊû³¤GnS¿!ÓAÌu\æ`¶™jz¶e\ ÕO°o*}LÒâóÀ{þÑ©½y@!8­àÚ·ƒÚÇŸ–ÑW}Œß3±í)o›¡Œ“R7ÅП>C%[0’ÞŽjÀ`:ud¢ykœ8Q†+·M$¾Áí~aG2f)óœ,FÌõ_òðTÅX£›†Š™û$dÄÀ³Ó‹Òƒùn÷0`#ù¹âNu–Að@YÍ-õj™æzFÞLª4~ØP›”­“QäÌ«´àK@9á2 plj°œkii\Áz È7¾Åë°,Ï'}Qò€Çο_I×Ê&Á³v†ò7Rt¼$b⡎^K`TDüˆÓ¢Z©8H#gõ_Q…1ícÛó*éÄ™¥ÒIÓB›(t¶ïâG˜ùÅ÷E^û'j¨ñ­1,‹ xÒ%´Ý`¬Ë‹ÿ¾IŒ”uN‹o,2zž(c{°EòüSÍsiÎw2iÀJïÚt¶'ý=âŸoQ £ €èº{ÛQl†3m#Jz½ß6‹¶ÌYÀ>#ÞV‚“VÕÁ4F€ƒ†U=ˆ~<ÓåÈË8 {PŽ`ÖöÓ¶Kb ðu§ÇÜܯà¤ΙtíT×ÌòüTp›—ã×Í˹Ȣ¶&ŒéVàãÂq޻ʘ ‚êß^Ž×½!ˆæó)â¨çF¥¶E‰?ØUÉÊIeÑØÃw?Jñ‹¿£–R"ï>škIô®ÐOʺÍY “®i\Tíz“IïÄl—¨R7— NT¦Q˜Ê€×g‘æ£'ŬXÙæC ‚ þñä$\àÁÔ̰Hr[2ÓõíÁÀ.D²å¸ rŒCT.Ýø‹h›*^‚‚˜ýÏ"`^/[àî ™:é d§E‹Ò8C‹¡»Fùà‰”½Ø+Lv¬¶¢û'jŸÚË¢–NaˆZ¶dÏi¢ê²ÅT+•ìÑé›ÅD±§Öã`Ćm‹ v˜(u7`Ç C]ÝÑô²šx!eêm ûÕ.cUO›þ‹šœgØ´eì°ÙÍ¡ÇÔЇ3ùû¹Ä$C±f®iZ²°5n”·hr\d.oÍçÅ ¿f_þ¢„º”»Š©ƒÅöCÍWÇ]&‚2}](ï&hôw®%)“æyZë‰þÈÎr>SÈÀkæ}ÖÒŽ‹zJŠ=ô†íöÐÒЂðzð¬˜ElÃ÷ZîÊoGŸ6aß™,Sr°ñ.Vd,%*æ°n`Ñ*ü»|†c~å{.^5v7ïøØï¹%îȃ°¤Yf°áòëJ1†sC~³ëÇ€G-ˆýù*‰ÚˆˆÃ€@³ä]CDÐRgh!e‰|“DŸXÛIå#‹!°€Ñ[|]â0†æó–NˆÎhÕJ£;ËÓ4(Q)¹<7ž%툰@£JPm¨–FœÀ:ÍHüüT“]wP·;;ôÍ;\*-3„³ÍÀ?œ'Uhϸ¢ÅÅ6ÄC“\9Àµëï(/;¦¸DÏ…)Øâ:» ”f¢U.Ä.cõU…v;ìÊ@v1p•²F<–@ÁQŸK‹ï+Fäîv*=)µmQ['úS½´DGœ_Ù9¹g¨â©ºùg,â̵¤Cßtóî/ÐV·Ý(žn)*ú3˜W¼™að2Oš(‘¶ûyhx€¸QÆD4š&>üºÇ¯$¤Á“35ƒÀS ™övï-qD3fR*59hy/ÈóvWÛ¬†hköX]jÉXåøâªÀ¶¢^wÍJ.µ˜‡:Q…ÀÃ([WjÚ‹6·ôÅ4b{&Û“.ŠT=%-Ïv"ÂTrd'[Œ°*ÛêOÓ–×BªÖȵvßÜÔ—ßž@¨ä"¸k†8“Þ.©jéJp‚›¼ñØÙžœƒ®B—,عUPú܃Bb&7U¹õ3Ý E“£„8\ÇÑŸ–”?V Z=ñMB©Ö–­D ò@S·R¥î˲w"­T¬Çu¸‰•Ýò*Ú2yýT¢öCî‡ü+±ËÝXvöeAH±;‡ól9H,§Ÿ»]ßùWÌ–´ÞŒ­rå¢w\ùc©¦ÀЗMàý‰ùRwwÄ´BÁK,q1kïö%Äwq‡žwˆ’bL” u54=ßý¿< c$?;»Ìâfzh qH\¹”[lìNq¨ßël®:Úd«ýÊdãÅ6íœSÇ_Ýv½gZºõ“šHÐTª®»ÄkW”e³{,ã߯Q/ºä 8'%ÝújILKhâXµ¸"dÞ›pïAAcbs£ãþ6v©ÞÂÃp•vk&Æ.êQE»cØz>Ó%?\—¢q+¨Î»§Økµ\] KÛžÃdu5ý%âºx ´Œ­ª¯÷§¤‰Æ·ž dÒ²™ÒV<:\ùl"5‰Yrú”"e7FpÚ’Dwšú$­(ÒÓÞK¦ïh7†=Ã)âéžÜMË™n7™ïÛIºvEF½{©73gâŠ-‹ °J­¸fPa€P×RØüˆ.Z"螀©b!OTÐ~Œ’‡ŸW=0 ¯lxÀ’Ù:Ù2{I ñ±KLþEh%ï±R²~·ª$—É©b. Z¡S•ÑkéþM¡²Øù1¢5æ^ü‹ZÇÊQz»cv•"X<µ«É Svéaƒõµ&3-W_ù´úÚ>z|y‘Ñg˜¸®*K¼T9ƒ­ÈH}¶–{ÙÌÂTÓîNs$UóWb ‘9rR*CÇÎH”ûeëi”]ÏôDˆìðt;C§„‹úN·ª1(SŽC.¢óI¥;‹?­X·)³FÍfÝEièr…\¼ªEÊ^^Ú{[ 1—eU]s ʽ"ÍGõ²ô˾Ùï ·iKL$z€ì¬€Lã“G5ÊJªý‚ð« !‰œV†î†²•Ƴ ­ŠtOŸ÷€ØÌËЬÐß;¡Í/³`q~áªeç‘JõKC­ÈVú‹¤> ÂD£)Õƒ6ç6R_‡”Gœ,Ú½‡¿HkùÏTFjŠ|šâ¬.§ä3?§OÙ(5?¾õð !‘Ûq=¼šm«B~Œµbî@'÷Rƒ{õªaßQʉö»E±È§´rÄ^k努·¨§I¥‹.@)` –ƫώ KѱB_íþ‡ƒÞ8Øëwű½eM»\Êæ€˜«e&ªNEØéüü#[ Ì» –ܸwØÞ·yOJ(?–;ý7µ[¿ ý‹û5lÆÏ:ç Ãñ]4íX‰ìhX­€?À°sz8V㦬œ—!>†üÝ`Î¥dMùñ#ÌPäÚ*7æ`'I5ñ³ãd…vEÖaÙâÆw;ƒ¿ÖaÉM:æÔš›I·Ií&:«ã°EÐÿYÇCÞ›“9-Ÿ¦wêxNñdÞ·[½ïÖfÉ#ÃZz»ßÏi‰D_Ùä ãêEéS¸jä½ £Õ­?ÅAoä„w´[å——ˆié¤ÕîŒ/¿ŒÝ’²Ñ³E£~¯!•{}7"ƒ(£ÅóÅ<ó‡QÖš+ž¼KÇTTf°2Ÿ¨÷¡~@ûÊÏ ˜¬”ÏDÊÁÊURêþŸo0ôŸnÑí5`ŸÕ˜œœFBù\í‰_óY6€ÀnF@KhToÔ6á2Õâ‚UY}ãi!:Gw·ëýsAËu•ϾӨSK-tR©ïÎóÇ9»<ðéáEo2.‚ec¯VÀâëòÉ"X5€“ŒÂ5P¥ Ãç~ê\ºj,š…úÛÛütÔå(LÐ °}…øð¨µ­î_­ˆSxJ†­˜sÚ[òãîñh1ô‰UÓÚñkG¶·¢,ê—[D°—ŸH17ÉCí÷㱉b” ¤¢õIþ”ëÒÖ/&¤Jœ“;tdô€áp\Ï9_Y ¢ F=½ÞÚ}0à\ÍÅ©¢Ðûô}µÃR 4ÍÀä³ZÓP^‹~Ó¼³šÆ»%F¥“tÞ[³¯h”¡u% A:)uÒú³ƒpœ|Eq…™4óXºˆÂx±g|D™bÓxG|Ö¨î âízޏB¾36\:v>Üñ«“/ç“§»×7žS3°žõk3ó^n~`)‚8?å†ð6w ë»&æ§üÇeŸx*Ÿ5 =; YÏbèíÔ¤ŸJìÚïHª>XÁ{ MÇ*9·Í´p<ÃA5KsA/#z¹¢úÁJ´Ë‡¹?³¡üÛ~PýéÚx£B!+‡exP;s¯™ã4ô6ñªœ|–R¢Bói—v1w>µ ñ ê`ôþ6|‚ê䔞)36~Rʸńï'©5W»–ûÞá´l™ÉB‚Ÿusv»ú>£¥hƒ)ˆ†P Ì0\6è M3¬‚-Y¯Ï¨ é“‹R”bÌ`+¢]f¬T„8¥”'ÞJ³…[‰zÇ?àáÔ êãÓ0ª'Ê §Ê·ç2É@ªý‚Ñ9âõ»ÞH¥ô&ä$ÃÏY »œÃNÒÿUàØ$ñ2®á uø*ü8ðúPà|!±kp‚MY¢­&ݤ|Z¤ÄÄú+æcç§ãQ«Æ•ãì³STë/Þ%) Íyå‡MåñžHœVèÉHž+óOKù>váýG䬞ä…_²“:"ßWÅàv9¨‰}KÊ,½2£Òܾ̰c<éÿBk³ v¦\Ÿ»IY FŠ‘Üz4©zÓ9˜OK­>Ls±Ç®nLÝ‹OƳÓðëgOþãÉzõ þýÿR%ÙÎendstream endobj 32 0 obj 6305 endobj 40 0 obj <> stream xœ½]I“Çq¾Ãˆð_˜f˜f×^å›ä",Ká0›èHˆ€E,Ü@ÿÞ™µfUeu¿‡ˆ ß¼×]]Kîùeö7û&nvü—ÿÿÍ›G_|én^þô(~{#nþ³~úîÑDþcÏWßüáÜ äß‚µÊß<ûö‘È׳9»ËëÝͳ7þvûüNoZ)ín¿¿»7›öRúñõÚ‚†·ÿ‡ŸÌîÍí7w;ŽlE¾[ {ûóݽÜtÆ‘ ßÕŸßÞÝ+½o»µý—å1‡ßw³yëÉí?Á—Âmîö}»ð'øÕì»”ôË66Ý×u˜8ŒÞŒÒdì·wRljß=ùßï,Ì„Ûa…fû®ÛwéÉÂðw¼€‡H»Ù º‡À“Õ&½ºýçÙ‚°ÎܾJóV^份•ýᦰIeÚè¿ÞÝÛÍ 'm^«t!CPJÑÍëÜ”§¤v2÷_îþ÷ÙŸÁ7DòìEý-î“ô°ÉøŒ`ax®÷RnJIOh¡}Ê'#v~#_´Ÿ·»{mÄ&vyûŒß ´RšÄoÉ ïêÂ¾Ž¿;¯òÀTz¦pòoð|Äæ¤HçFÛõ¦€šÈ’ç·}ûg²Ã¥jqi¡`mËñÛD .ýø}“FÅ-É,Î4í¸5š<Ïç>Ð=Ì"ˆÒ9•]Åà`p±Õ’°ØËú‰üÜV»3€EÁ¸~ lû-~»f-³ê·ñ€(~vIbÔ¦aãÝÆÈ&hLÞnÂïÞ.ruŽ'ïA0n»—H\JnfW Ÿ­pó9ãLi¬Ú¾|Á_D†?•Kïð™ ŒàŸ‰¢Iïqó"+ÃH]x™,¹ÝòuÛ’÷mÈ#ÉfÍÀmaixûºËmeí`È€m’O¥í@쯇Ʊ_ÖOS‰¬kÔûÆqû悼df‘¹Ò8Ê{?N-‰ö:5Iž¹DYç©z]y»î½räèÀìoü¹ibótx÷Bl»UÏð]UÓe}Vå*C$JZŸ Nöë»—6 (í9§}aRÛMY›™Ç$ú•\Êí‚OËFµíEy¯@£‹YÜgi"X-qÏŽUÈÄOR)ØOHˆ?…ÉÞlj‹h²¬óóÔ›t €@ÃJ Ç´ B€ßâfúMtÄðŽ ¨™;^g¦NåCÒÕ•»_âãÂæA6¼â†~YŸüŠ[+.A;gžßÔï“äSJP› ÊŽô”ïQO¿£¦F¤ª°Ö˜é´OmrJ÷#Q+MåÄÛf°öÙS2èĶÍò ÒÑû;ƒ 'ÕÞÛ©•4wãhT²Æ×q*©(Ù¬r~C%kíæác»;[}º*¡278ddº•h)úøÍ¨°€èÎSÍ‹t me‘Æ7ø;·Öa¡W6{ž¡n“&Xt5nˆA[ ÐØÒÁ™ú›0ÎÎ\" "c0ØeáíkÄBeÉ—¸Q`§+j|hV »'¬ÛÊðU/99Pñ_ðr þ˜ñ¬Õù?£LÁS4[K¦ð0R.Ña¸ÞFç9~í9MŒýr'÷¨µÉÑíz³Š3Ø‘2{?ÓÁ™ wèe˜xøŒ ¥›§œw•X¿á…ÿà,Ҟ‰¹÷ä7 îâD8·—É2BÇsmaázÎ-,Ï»—åîÞ0J–'ø–¶Ðï$q½Ç¶íØ Æ€ɱô Œ¾É P’ÔoòN£›tÜh6QÎ^I(e0ϽŠrróÁl›•1úÍÈ §áØ^á=pB{GsÏ9.ç ÕÄ‘ÆÁö$KQÏè½{ð/VP¸«º„¿…^ÑÀ¨ÉÚnN»"'©w7Ñ^4ãQy ©E“†¥h²íÇúäìÑ/8$ d¶i é?ÀM2•äCЛ×u¾ëY”cð€ÚR“áß%nÕ°»¯²6q›n!|Ú¼¡÷¸}Éí`§xØõѬ¯[oùg¢¿`úRh8©Ì6#h˜‚pÈ÷\˜çDŠ]lªÅ’&®í÷¸6© è”æèÝ㥰_º1`¶ë䮈ÎFEÕy6~‰[Õ¼”W[#>øÁ)À€›ƒ®Š!«ÎÊz×1`¾© ¯ÎþáØDÍÚ>5¦$ÊúÃßñt“wµygúù¦™íç+ß‚‘,Ci•Ù2GZ%'¶Œ¬`S,ˆ¬9xø;ˆnÃZ ÅI ð½33="ƒLñ\4•‘I+‚»)EáÄþñ”2# wæáT&;ú =Lfó$Ñfmvý6!Õ†ÝP¾c‹uÆhTå³³ª(Û'¾ÞThg'^uƒÆR^FtâmÈTíè·òk¶wÓ¡õï_aX”»Èc4+vÚð™&±ž$B²$œaíÝž²iLÕ4˶} (Ú/]ŒýO/bÔe-“MG^|$ÌaÚ Ô„ÝIœ°Äü*_)Üá€O–¡8¤¶ƒQân0ùýÌÜçÁ#ÜvÍ…Ö{!U¼qI5é|S§¯ËÊÌuæe"åaÛÑqµ?“›¾Kš_=OÁ2ü¤>¼¬,¨ ÛûÃÏï”ØD¥K|%.‰Óæ?ÅLãô–0ÑÄï²?kSdãŸG£¶Ø4Ù”Ÿ²|ò­Q•~ÇŸßsÒ£ñÑ‹áç•«Äà’” ]›èk¢C¨—¥õæàžÿ{msÊìªTgïWá¡;q³øCŽ7¢?ŸÎÏšÁ5Ë»“™C†rJsF”;(ÚIÐ{s0GyÈÅOo¾HUUö˜ÉOêhšçÕ²©ÅÆS'ÆqÚ{3™«÷Ùõ0Žy¶¡ãôZ6ï() ·åƒ„¡^çlÍN£%9Ù¦9zȹ­5©8Æu§I냳¹‘á*93·(Wf!5¸Î1%4Oö•…K"O8µÙލ)È'¸ ð$ô17“F]ŸÄÁlôƒ;”… 0sÌ€©%´ &Ë”—Ö]°‰ (´ŸÛ–—„z ‹Ð‚»Éh^ÐŒøäãy­E$ ý =ølÒ¹€2 13˜Áó²ÙSyQvuˆLƒ±)gy«éI77ô&t—r{Î æ:ÏšÆ[„ææ¥Gw´5c, ¦-PfôÂ)þx‚’œôÊ6äì" ÒÒX?°zz"@,§:FÿKòoí:â á8¬Ü˜øwu턤’½ÝV“=Ô"ƒÙ I¨~Lïõ…äu{Ih8‹>·SùJDëõÖàa0‘ßM•¶8%ŠH£ãUÛ›.͔҄行àâô¡rS‹m°AâÙªçBÿs45zwËŒ\ï\‚å,ܘ©5{œWhøè¸ZfÎã˜$xÏÿFDÖúÓ›h‰Û´o° ./ ÁçºÂÂS/9`C™ÍÔðå!©£Î$1nÙÞ„g–ÃE]1C:•žw¹P*jŽiS~gÀ¢d)µ"ä{79ÏU†*Éî›×¢Så9ƒÚëȵ¾R¯¦0´s9¬ƒ+é™kÏkù”êÐ$ÉIÄd†˜{žÒJÔ;™wëׂ›ncî^–ˆT &cÒGaKÂciÐçÜÉSûRºè‚¨ím™Œü%¡{©ÄeÁ‡qúj>ÛxåM޼ç8šUàc:<H_—ðgÐ;ÜÉ`ðöTU¥ÁÉÖc^8Z£ßEî2AVÐÏ‘_ frÄ´~«šJ‰°€Â¯R°„¥â¯.EF}Í©mÆ9{‘q`ŽH:} ¤2¼ræRä»j¥ÀBñ=¹@!Yê›Ä¯ƒžój×»ÖO[Ià)Bì@<á'té€ZUŠ’ÏT?è6AÒѪ>JÝ$]¡w V_Éù¯YÍ„2Ì&1ZÚÉѪMã×Ôæ•Wï éÑü±æ“£•b G“%*æC…f–*WvA%cÂD‰{:>eÕPI šºK21ÎãoÃÚ=ùÅývØÐçõçÇåÖVâA¡ÆƒØbGBµ|aÍ {ñ_미çª6&K»º³G"Y+ùëa™Ñtv²xQ2aû"Tl·K_6ÂÓFO«tÕfüEÛ:—ýÏx=§RŸN¿Gq, b9è1‡ ‡< ë®6õZÁƒâ³õqÙ—æ¤3f!É\EN¹ššÚcŸr–±–ç³^àíÊ)gP2§ª\(¬úk'|.[;¦ÅéC‘mž©t+ÐBÅ&°–uD¹èxH¨ãzsB=2ds–}áìMNàQ¨§ôØjî&!²™*Ws_:É>±Z±¯¯ÓœGK­0ÎIì| ù=T9²hWÈÌ™ï«ÑßѾ“¨ >¡†{‡ÈѺqÀà¥Õ§³].ò~ìÁž]jp’ÚkYäÛ¸5´+?òiÛŽñ/(Öʈ¢ÇY{¬Û;SJ,ª§injj¤Ÿõºv¶ËÅ‘1Ï ã”'Ò¼‰[ÓW–.é`’DÜÐÖðØ%gègëi€—µï2 JqBƒYûZŸXáGKss]ðÀ„mÚe ¸SÕþ¹jDZž&ÕÁV„à—¯Ø€7Ëz˜¸y¤«}ç+K÷r„Mó²œà%—¾̛߇]:÷šå¸¾¸j¿`ÖÛ9 l¦zöâßÖ‚^ÁemŸ&nB—ðŒÅs²Î†%ª„–KwÛÉKLÝÜQ…­Y0û¡@J.ùÈàUy‡µ.ÝT׈®ã`¢] SÔKàµÆ©›bvkä„Ù­K=C|õ#†úµ¯€¦ÍY=—4&10Šn+4bÝ …ÒMË)õC.TƒAîìÂ2‡CIŽS[7`à4DÆuÄýiK…z†ÐÚmB4ƒÕ°ýjŸk|›”±–o Ì‰™À4¯Ià ð÷Œ—¼½ µ֬ɥUÔÙß”¾0s±hŽ·Ä}0â hà¼ÉoÊv^U e–_ãcIåÇuˆØóy­Â.9.ÄVwe…ÚÁµ‘•’%.]Õ"+¦ZH6–´]äu…Kq%2œ¬MçbœH ÇóÓ˼p9¿>^çfŠnÆŽŽNo‡ôòP-ˆiP»×|`Ëæ(VÜÍ>x|ºŠ}¢(O5ÿ’ç©JþOs'7ÕHí›7®ë‰r‡°OU(8úEÌ4¯‚ÉÖCm9õP5adÒ\ ôncRérj4¸,°N“74ÕÃ6|ƒÓƒìµ¼¨¤5+áfÕÆ£ÉÐ… êjjƒq*ðªd‘GÕL}£2|ÔØÈ#º;¼¬/Mx7HË#صŠ{„·ÈIuÇ´Û=O–Á1ÄØD+µ}QLÄè3ÆÊðØïÉXÝ$ÄÔ ×SÿÖ]„ˆÔ6m¸¯Is ¶úO ýfÔŒ1({í{®p>“by‘4'ßX¥Ú!£'¬’ó‡ÚcrÁ¼î_Z}õf*o€iå]zÆ  ˜Åizfttv]Dwñ¤w·C¬ðªt9è. ‘3nqÑcEs/Ÿ:6y/ ÆÔ®nÿ .µÍxËÁɘµSþTÁ1nqi,ShW±ÜcF9×3Ø0A°+¾~–\ñÞŒ‹oWãM˜Þ¹È-…Y†¼Š­ ¡Ëø$/]{š×hÞ,’›ö^Õ0‹¸jñ&òê"OpE!áõPùAäP?’†Bø°E­,”N`•¢-Ñ~ù}hlà›š"¥‘ïHc·c²(nY¿Ç‡ƒòïøõ{ª¸CúôA>µž³›2¶-D{ðn™Âø¹aÜW·m-ËpLj»˜aþËö¿í˃wœôÖ@²5tŸB”ÉéÊû»;üÛÍÙ%Õòþê®-{iÅ} ‹¡è¬ Kíþt…™°ã¶|®ëS2SѺ_pB¨-¬fÇn|rº¡­:ãŸÎà ¿+¶¾£õì|N±4Hä»Mü¦sö{xíEgn£¤u0zO=²åáGuÖ±· |”0u”‘‚b(ÙÐàÚô"]ˆè4j•É[t»A{ư ÀàÍ¿©Ô=½-½Œ„. ø›Q͘Ûx-Û@#xRŽ­ŽÛ@s@Gþm“—”MG+^Êö/9xomÅç皯u˜$?êªÂêx@—E.ò.~RÔÕ„")ùâK#%cdŒ%X|o ±Øe„:bX½w‡ƒÅ~eØ3¤ê}Ô»ÇåK½äWbaá?Ÿ@G9 ½Yíc LÀ™T>_¾Ä2ˆù…ñ%íò…viœ4vúJEp|›[ºÙÇVȰNÐR,¢–„JÚ›²#G=ȵW¥žß«µ#’³•÷9†påâôjß3by ÁY4õ¤'I÷H¦ƒÉŠž=é³½$.Ÿ Çó·Ëåv£[kÄÔ¿hîÞÙì‚jþNÿ¨œÓ¶ ½X¬Ï¨÷@NÊJû:›øî#5t¤Mo Iî£^y"L½òØÀi³Þ VÈèS•ÈU(ËŸýE IÉ«uQJb‡¿êÏ{°¬$OSx; |©)xzªkŽU¯…|åèIŸÈœMZI½©i’OÒµ¥ˆæ°x›AÛv®šŒ°m“9Ax…–ï/̦5%±Lʄ퀔—ǽ½¬/UÓsðþ˹´Ç÷ ¹ØGۢݼ†ñ`,¦{fëïr¬ð¨|¨.Ÿ"•®%h4½³üÌôŒ…3|³Òá¡]¨Ë;Éúc” –<_WÌ7 ?A©–˜¤9çÇ2¾tZ†»œ‘u}ü/»qËÊټʩÃ\ÿ>ö‹§O=†Qƒì14*Ö[èÑ,^èN¶çêÁ1Zò]¬Êí}Þ¤P„W6E]4!ºkB¬}ÊÞk´‚K±›ÁÙÂRã=|öè¿í7/á¿ÿ&˜d‡endstream endobj 41 0 obj 6776 endobj 47 0 obj <> stream xœÕ]Y$Çqöó˜°ÿ¼iÚØ©­<+sA) ¤¬Ã×Ѓé’#.e.w–Ç’\ðÏ;"ÏȬȮêžӆ²*8¾8ë›ëy×3þ/ýûù×WOÿ²\¿øî*üz-®ÿ­üõÕÕ7W"ýŸ9Ý}ýÞs äµ›¼µÊ]?ÿâJ¤ûÅì'c¯­[®Ÿ}õŸ7¿>Ü*£'9»›ïj2ó,åÍßá/ofgn¾>ÜΓQÊ.îæõáÖLÚImn^–þã9-Æ“ñ÷=i¥…%7¾‰£•7ßn夽7 ySó ií䤡wÞãDíäáòë—uNáQÚ [—Éi™çŒoýö+™Å<ëô.cäÍgõ:]“€ƒÁê•v0Ê‘‰æ§[?˜îƒöÎÙö:¾R.žÎ7ÏøIyqói¹^çñ÷vž\;$Íísø N׊ô“³’lÁ9O³]È€»´­Z4§Z®wø¯ç¿»’ÚN(åùG äàA™½Å÷˜I4ë½£sÜ*a™Y9b"£+¼å6³ÑðòeRN]BÄ 6³™fcÜðQ!éÿ˜ 䚘ÝP ¦1#…©C/dÂi¼§š­'â¬Åó$Þ »ÞêÑó¸ÃÌ(^6ûŸ`ª’4+©àéÌõ¯O;nÓí€ ™ ìÂe•(ªöOˆp\šô®„Ÿ Œ\ÌIØ3ë… ¥`F½F½ð-^mmy®®oìaZB~kö%×_d­aÈÊYžgLŽhŽ0Ve†¼ç´É—¬ ‹  vA»ÂÅþÇ•€°øï²ó„5,¡ ˆn`ž×ÃÖ;;Øxç.il qž7W¶>óMUÞuqdЄ:O Ôù5r±ˆ/‰‹\ çвhœ³‚…ÜU& ZyñÎ>I‚Ôð¬L¹èV p”U¥}?Œ¬2Y¡c úð’èXØòéÞ#"8΀­§™P«žaœ-w–AKøø|å& á®eö_+1ÈùUÍT”˜„—¾AÍqŸÅÒM*<¿Ûœ h—'– ?+Þu™_[•¡¼ŸŒ ‚èMVÚ5¨IÀ£’Ù³º‘…™¸JiZ–“Xæ#«n¯ˆøEo¥tŠoKÜgÍ`sï¬ëŒ눈,jîd]dfÑjŽUh ¶&â$@~›®ÊNUõ¡xzry/vkvÎÝ°Ž `™æä…Ìb6ùG×hµ3TÃp<ü§ýUEŒÄ{{ €`?ŒÚÊx-¢¤>“´2¢+³ÙúÄv•_F…ˆœ^÷³’l½‘ƒ÷¶€@Çbí^!Û Ö"mÔmÀŒp‚s$TMò7ýé_”j‚¼ÀãÆ#¬‡GÄøç<¿xö5Ô—Lx€…Ä,§³_ñk¹Ö¸‘¬NŠõÁr>}bH(Yîr>ØßµwE­üþêù¿ì;Q†dy•LÞÔá¯cxÂøuÀ¥:8¬eø/³²ÄpÐ|¨O|ƒ¢và€ |ʦD²Ðm®èŠY ‚},> T×ñHœöF:ŽžÀÚñ^$ò(LD«W; B_|ÂUXkûúj8,øyvÒ³³®Íeú~ÅÏ€Tô|™ŽËIÞ¶GÒ•((å Um$ž½1[,PI„wk濊€¬´ËC‘­‚×5œs,Ÿ#º+¹1“Ù'#È.TÜø~ÑÇaò«!›p€C@ሠÒHË­žÝ´Ì"x%_pŒHMýBò¶oÇë™2¸z‹ë¾‹³õ^5øãVƒTW—zr;“¶áe µ‚>#žÞ6O&l´¿ ã<øJ-iÉ0»Z©¸ád ˜²Uß-Ô‚µxY+>ª¦MõѽŒ7âk»ú95 ¯&I¡÷9"²ð3ˆO½ÑcC3½=Z 䑞xéNƒ\HBzÑYGnì7 ‚ëÂæL•{ Ë± ­ÌZS šº=I1 >p` 2JË7ÒçåÏÎo© Îw¡Žd׸qp¦‹-KƒÚ\˜äÊìhOŸ–´F‡ëXñ”QsÜS_­¨lª+Þ[T2â. Û’›ä:g3¾ê¥ò*,Z¬³/gÂEɦüªŒ.^jÇOŽÚ|Im©UNà pþç OÕÊÙ²‹†éàêÉ)áwŽ·©ªM6%ü•‚L´@ ÁZb޳€;Ç üØÛ\|ç¿°c1òˆÒkÙ´ÊoÉ®æ Vž&ZàuÝ1Æ­,¨¿ñ§h6\ÚÉ6è·Áí€-ظ…€{ÈÊ»ìE‰Ì¦=ÎÈ^ Ážx—¹’OM!N &Çå®^=j)ßÊeŽé#;ÉRþ¸ñäM2©æñçAÊN`_0e$‡-—çö<*…|SiáMË3Âwåãº0Š»(›áÉéÈ-Ö,ýx3 ê·‡àN›üØ$ òzà Hxƒå(æÎÎO¾IöÀ)1ÆŸÒš`Å4Æ€+Í+q‚D£–fŽ’bQà†k×§áÞÍn¨ÙF aŸv Ø q”'XgdÁ>õG¥á`Ùp"çã+†^'ï[$*-ÚbƒpÂ’±Ì”¡¹n$XÙ¿1¬s#œ™ê8Ë£Ý$ ÌeÔZšŽì€Û´ùmœô,@ ûޏ"ãÓÐÉÇu#îIô‹Æ\d-àªÙjèì|±¤#\¨`¡Aš!«QÅý—TÝ0P®!¥º† -Y~}_sÊ)ò\ÞtË$Hj­ˆ\âãZ‹![’Ö5–d_ëò ÔÉ ™áaµ{ÿV,í¹d~w ªÍý†§"¼mùzÇ©àÌ«¢Má̰¿m8sƒõjϹ–³¦áÌÝ) DE>©Šõ³úk›¹º™r¶eÛW{)£d3¼U4ݶÏÌÄTÔû’4y¼RìÇR'éŠÂ"—Ù•§³år/î™èz Ú÷âY:;¸ÏHDE¶ÅKqä8ð¯&÷nmŠ ï;Çÿ ú­À’¼FbW.åCÙ(Š•zX´Yó¦ü&Ø|‰yc¯’›ÙñÙÉ&‹©á¤ìiÕ +€Ø•’GÒèêZ$WÞBHnƒ“ꯇäLOa¶œ°ÑCÁ‰±'tª"²¥á˜Gå¡5p%r´µ3Ù^$¤æ€dŒ‘??Œñ*ôñj€ ¾U¿¬är Wg–ÆJ”¶¹âx½QeÞ#¼™SûÑâM§~€£Ô¼=wz2f'bl·þà4\{[LI± éwvhòn4ªì ׉3(>$¶ÛÏ ƒ8n¶¥âå²ÑÑÚ@h”<Üx®!&Þš`––:W†ím³ÂyÅŠl^ÓÖ ·f÷§¥Vç™™Ôµ† VR=LÜ}«îôÙs>ÉqºÃí­(”êF„~yTªg?:;z‡Ü,îØ×“M|ʹ Ø¦Pl>rÿ_'ä;cÊã¸ü!Õ‚ëéÛ$Îz«s‡¦­FÝ:çcjzrV'òÛX'&¹neÈ‚}ß»Žþh¤Ë5k­Krr¼ææjÊè׌œH¶gÜëaŸÖßIæúcž¶Œš+nêø;Èã/º€œhleßaÇbäL,­Z>‹½¦qÚ ¬.“ëvf3TÙr8šñZ7)Qr­šDÚAãƒQC,ŠMçα‘Uó0±½M‚Ó±6•ÚL¶Võrõ›}å@Øw·îM·ªè Eib ²†ÿ±«þØÍlæšûÕzZ·ôÕ“¨#Q(pÎZÞÚn4¦sÉqÿŠH슞Äj]µ3I»?ê6A,-.Íyªc×lò[ljÙä½á:ñmO æH^n/¾òóæ­ý†Ž)®äêØoÖŒºîMŠ_6{vÔQDÒrçÜǃê<¤Í‰íÖ¨Œþ°´\às˜cEÌ KÛhí¤ÖQ™´?%OAã瘎[8Ÿ:¶5NÅJú…pÊKâv›F£iIµÐnÛ4Û[Ëq—±^zžnŒEÌäH3›ÜˆK‰‘Ý•vŠ'lšªºF4|÷åÌïÏò}|²,R`J²VÏ®î½ùZ9"žÓèCDª±ÉÿG¢PÙ¥¶]–ΚoüçGA™Ó¦¶f*V¥!’FçiL„ÙZs¤Õ÷ø#Fí°’A% "ê³+K‰aĆԈviluðSfÚ}qüë·'0~=ÈhMY>bPk5ðØ„”mଟÇáE^N¨nß厛4ëà,nÅϯþ|õ͵t¡qé|}«á‰\©á_…uøá–÷>ºzúÑ®¿ÿöÍß®žþõZ\=ýÿóÞ¿¿ÿ|ô›ë¸úà£ë?Ÿø©– ®„Ú¬ø‚öþ5êˆäàÏ,>Õd{Ã:zõ­™{Gßg}»ÕwôvA|ÖÅ[‰\!Òïž“$Ál—þ.}Ä©î|¸>KB÷ºº1´©Sem¥V~pb™|±¦YTIÄZ»ßS¸¨]Cþ‹lêJ{7Hׂµ=ØDu¶ûo×–êbý=Çû\1‘n>|ñPLT.?K=¹€úþX\^G”l^ÒØ©“,¹Guêlå§mÆÅê"»/­Ð<žÚyhþD 8øü ¸•þ\aÜXø Ð—øQýˆÂk…ÂkðŠqòQ¹Î²«Qpd•ë½ÙÂÆ"ôhôUJa›%rú ¸+~¿Êgî2¥>` úsËaÖ…5cKÑ¡Çá0l< ÈzÉ>%µ¸:JýO¥À¹‰?ã|ö%3¸ëš Æ­?ÜyœÒ˜÷ÆÖøXFÕ²µXé©ñ$ºí@j]Âx—. ¨y~\ã 0¥„÷ÄÄ)F-6Riû P”kl9që£@;ÇX®Sº›¸ÝJ;csìå¢ ú‚]¾þ,ÅÁŽë‡ZöïrÑ›V/?·‡³ÉÄÇ\tnwq#“Ãj@!XǤåÆáîQR¹ü$•´™H6ÅÞF_Öà «ÎÓ”)Çþf4]I˨fW_æ{§ÁÎ*¯.ìr÷Q¾ƒíþ¨6;&_`ÏnáL1ÚOtº³Vû–Ó}”šQkhÊV}å‹T)/ùâŸpð~̪|·<é5N;ÐP!ôñØçafüNô<Ñ»Žc‹ãÎ?Žä0ŒJ&ísø’Úâ»Í°Fªl|hÄ.Õ‘ »»œ41…,ÌŸ%¸ûb8í÷Å6œ Lž,íGxV-õõž% d3ù‚‘ïM§åÄCÒáAÏã':”_Ò.~Zð‘}&ͧÇr]™*€ŸË,äÛ'md=æÜ" rÅç— {¦<¥Á1+æ"ß“e=ö7ìèKÊ“™)µ` $\;hÖ0ûù 'xô"Ø’-Lk­M)÷Déºüðu˜®jáu‘ô¤g±ú{Ïîñ‡Í&XA­ÅêâX¶"ŽÑžå見þÚ­©{>íœp÷ãø pÍ®›œ‚Ó?ž Ä$Íh_ßß”Ù]å4ØØeR©GÄÑ„ÛøÑ–GoœCCL¨7v@s+[»¢-#½j˜*mŠìްÁMpRh®©É ›ÓÚÜ­š ¢”Ó]RÁ=§R¸Oì•jhÇf=rŽè.…i%6²¸EçºÍžÿóä×.Œ,#I‹E4¿Þ3ÃÉ6–™ÃLü]žçÊd×!ò\Sb?s¾Eú ä›©Å9Ì\»vÓ©]‡‰ÝÉ±ÑÆMÏ×ݽ÷(ëìZì$°7Ù£ü•ʵ¦Y›’Áý’?-Ùn¨$ͽº§’»ÐÌÅsˆ6%ãÍòððL¡‚ò–ÆÒ2ò÷ÄÒ½Û̘¿Á}¼Ë×—…6°«‘¦7ÇÂó5*Ä\õoU1KAn}þ :®×bÖÖ9.s ãñ¬Ö["Îýœyaà#j>¨r1ØNa].Æ8ÝÄÙK³Ãeoh§µ÷özkNà“db´ Ô÷ÔÖt0a¶&-}QÉ~͇«ºãQiã6É1ËsRh4á,¬„¿a;`‘FJ/;©Š¸ ³N»Žy‰;ô5À&+Ññ ܺT%¨6±“î‡ÅAι¥øÊçëðßÿ¬ãÿ¤endstream endobj 48 0 obj 7290 endobj 52 0 obj <> stream xœÕ=i“·qßUòöCªüž­n@©|ÐeY1m9ÒÆ•T”rñp¹K‰¢h%>ÝÀ ºô¼·»Ü•+Å*rˆ\¾¼ïOæIÌøgù÷ñ«{÷¿'ÏÞÜË­'êä÷õéå½ïï©å?óòõÉ'gÐ!ž(;ëõÉÙÓ{jù<¹)øYŸøNÎ^ÝûÏÙŸ*¥ÃäÍîËýé+½{Œïc0ÞQ§ÿ:û—15%ç2Ä´žâÉÙƒ{g¿Î@‚³˜çúL{ÓÜNeØwŸæ9MÀeæOÕýîÕÞÀœÚ†Ýk˜È¯5¬£v?ÏQ'Ï[/ê§Ï8°U§Š§vò6%»{^߇p‚£™=œ‘8¤èÖùóRßæOFÀFµ8,»·>BXsôV—îNÅTà ôIœ’÷&fÔñˆ³½›’‚1a§pnQ[WÖ€ x^ódçY»+±“ÅìOß”^&ª<{òA{XôI 'æ§ \ˆ˜)Yø+žñÃt)X2À&Òlž·´&6féï=ŸpÚD€( (½~XB´ô°mx|z:°uv·L©CÂ×8% =ž‘Æ9]XFÂ÷ynŽx®õ˲Øäš‡ºÐ8å4œmN#hùì Pïs~¶Éa¯æÉi£ëÖ¶êÓ}áéYíñCm{(<×ï¦Úö]}º¨OoêÓ)lÂ;]:çÆŸëÓe:ÓÐOëÓí¢sÏjÛ—õéóúth>#k°lŸOò¶]Ö¶wµí¢tÑŽ-õ²¾}ÈFÉß) [Zëóú!Ä+ú°Ž(˜žÁÖ€€ B"?¶S0<Qlb¸‡8î€ÓÌ×ÔÐUPƲ÷8+ànnNpQI¥TæË؆„”Y‡¾ëµã”D„ø¯ fð-©¬_>ÁþfªÔËѾI$•óÚçv;›¼[öeËq´w“p¼¶Ò¢ïA¢e6òrolÆööY²â‡ËŒ m¿BfæÌ aݘööÐîkdYÑ8åO ƒO;K°|µ×~ÒÀÄßÒ `× #pƒàlY ¬¸³A9öo@éZ[A‰l4*³ì5zÍ‘°Í:°ï³=b‰vÀJì…¡U^‘*›^@c|ˆœ±‰ q3Èš4n=0“Î~90ØÏr`†½äçUÀ®Ló!*-у¾àDX*¾s l5©¤‘ L³³æ.4.0| ‰Dr£ÆLn $[j+CÐŽpyûØIfóP’ñ™×µ­có¹í~ÇÌ gZßß}QÛ¾ªm_×§Oê[âyojü¶¶Ï~,‹§•S_êñLè1 ²â».[ w²ƒýv’Ʉޛ¨ UÀ0ͨ™QÀ€ÝHŽ»µäÎê j Èqˆò91 ä²váöZâ=Dâ«Z]K ë’V%¨â}yIÖ7ƒ#“䜠.49ÁT4–àX0FKª+1=Ý”#*Ñ¢¼[÷œUë:)ûešIqVQù=§Ú‘íÑâËŽ¨æŒ MëëLçvAd\xHàcܨ6pÌe6Ï€[—z9ð‚ɶ¯ŸK" Þ€‹5"cÁ2&ui$·q ,ªÀ%;ÍÿSQPä5.nÙ÷å}hiA« X½‘…<îØ>€8Ú ˆnæo…™ðODK´æ^×Ï|ãÔ‚Îéþcpj£R½EìA zW‰ÌÎW‚U»DÒgðh³àÚ_+~áqÊ{å<ß’Þ½¸jWÉFÐ'|h”Bú´!¢DŒBØÊEÂ{Qåbí]ÐLÁ)~´¾,¶˜4P†tœUÙ:áä`¡e ï>¬9F[&"jÁÌ`·ÙÁ\s= ¶f)ޔ̶úÄû¹…6¾•Oú[aMÉycŽná”Ó/F$LŒhQÿ¡,› *ô:XÝP}o©”gÒHŠ´È€Hµ ËLQà äõ±ujF<„´Da!.ô ¦O-¦—-´ªÞqL}O$Î$aÍl§‘Ä0PÑdd(CÃ0€K›yÞK $¿¸²Þâ’ÄJPÎÈfNK< m­Eɲ"é°û¹pèÅ;Çø, QÛßT–Ò¾m< Ó{Âóúå´.³àRù즸ÄÄ;;Y‰ÉИ÷&³Bûb¿*I@‘5ŠtÃŒ`MsIª4SÕaûÚø ê&­”©C"ø3 õÓ¬ßÅeÓ=S6E¸O«À% ,ZN»ÐMÈa¾õׯK2¸ÕÀ> z\pȃáB†Lƒ7ùUVCMŠ×E›E8uå™?•){äŽ4ü’Ø¤Ò ÊfØög‘HGÛhß™U€ÍÇ?¥C½2* A3üM{a<øá<{1Þœ@%Øâ)¿:ì\Ô‚¯¬áwnà ~r(uÅFó—AFi_לÁ@Êèqx…^¹ÑTNa³' <ÑÃ}'1ÂA©œ€¬™¬pœû®’r¼Ç‡Ás€ñÐP½Ù²x_y?låxj‡dK^`ìfÑûÂ"X{@Ü)1À®õ¬ì]Ïèhf½×°kFŠüÈõJ«Ôô3~gA/÷Ì´5½W¸œc³ÍÀJüUµ˜,j]/ /1iÒÕ tÙ‹±V}<çòiˆœå"«‰Lu —û!~ÄÚè‰jjƒg‚ÉÉUË܇π6ù´4Æ-hÕ5~^2©á0줼ë©z @?Ä̤‡÷Õ#úÍI€|ìÙ |ö’ë¦÷h䘠›u(±È.Ñäå~"~wÞÚ´a=Ñ_zۼł±eT£¶VRü¾ö~Ûq–ê{ï»ÀéYб ¬ý:Ær"rìØ¡ß}f€¦ /:£óËýJ&Jà`·ü˜}“€õBQ­Û‡õxc!$cNöÆÂçzß‘ó“­0 6sMdûí¸¤Â3n ó.Ó†é]‹Á³N“Ì_Úk(îÅoXP çFKÙ†$`Ok›”Òq0iàYJ<çÛ݆[oÝð;ÉŽi|NÉ Ž'LÁy8©õíF€±|7­¢íÓf(X0 4éŒRÒËaÛL‰² <ùäå´‘øeÛ`ˆwáµ¶Mø¢yhÏyØ?£›rfÇ·ûU°2ŽS• ªw¢Bø&ÑJT Âo² ÐIW’ч^: ãÃÅÌ꜊9%!Ìj'%'·i'Žf Y×Ô†£AîuÂ.ž ç„æýó†²-ÉÒ‹5Ðf7\t˜:ŒË ¾]Ô:{ÿä(Áƒê&XéÕUŽb•8LlÍ’ãÚ‡Ò@·„S·£1í£õIg÷?ö¿g¤ZðÇÄ™>Ð…í 9ñØ6QeÂŒjáÎuŒÆù¦€ÎR¤¨àÓ¥|zZò˜o§:†±Î¬ŒŒÐ"¥W--®È£\‹<ˇ=¥Ax j4{çùË#qò¹csÞ5sŸIp 7j lÌ„6N[Í’<®z´¬BNæ%b–p´QnóÐ=nC€Ï¥u¶Ž?PÔ¦‚RV½›\žLß6Lqdý‚K\  Ó[&‰'/gî<²~Ý "4…ëw Š¼]ÜoßÕ¶wB?ëÛ^œb›À¦–¾m9EŸÃÛ`ü®¶Õ¶?Ô§c…š#°áNÇÿ¬Jÿ¾–£Ö¢déßÕrä6^ËѦã[)Ùš@r°’#ÌLgå¸Ï´dÿ>¢ Ì¢åIRVàÏû`ДШH8¯j€ hz;¨«,›sHå@v¼ §<ïã´.?Ño¥q i€‰ŽÉ¿Än–Åç@®ÏÛ‰ÏyãQöµ_1I¯z.™–¼Ò7è¥z–rwAíÌ¥e‚¤4Òíi%S©­¯0™Âb>QPoär•¾,¶56®ž/M“6š:¨a -b-Ilδ9,}ÁÂ#b/š|Ó¶ûéhœÊ#þ ¶îÖ†ª¾îx\í‚6LØâÐ¥|¸˜5bI\æÛ?¶Ã´Lå0{QÖ±,u¢Æ› ó™¹ÙYBD~#w•ŽðÈz\b¸cÚPCØù«×+ú¦ ùÄo§`ñ]íÑK7A¦åï6MÄÍ*“Ãu)ï!Ó°®/×&ú8ÔL¶„$~Ï…ÚD¿¨µä°Yða9ãNœ0¦l\kÐì=9Õ¦XÂù˜r=³@d+p*a3798åœ(sD ò ÌHvÍ<|´Ké äk CgõüÃuÈ ôx0~s½aòM.{œSjF¿`_<+޵èP=t°Îd5_`™>g†#NSÄD 䀯˜Ø œø›]VâbÙ×áѠآŸ—IƒŠÅÑRª_ÐFG¨äoó ‘ 5ƒá³) BD7…rìë—$e<Šˆe*Ñ(´Šyú—ä`×HÕ!ÅYÆ)jªÚÊ«’,jQy…L÷yPÑÊɾ¨ÄõMÅ]*Ù¥b³?×·TÚû©Ðã/~ÕaÓCb°dY÷jBvXÉSÔ墺{Û ¶lRfX,…¹ ̹N†®³*^¹ÚžÐŸÍ¡ÊYà“îƒë ¬èGð pM?7ÜŸ}8æE’çXúË o⥰V™ÿ’Ň„²é©}NŸ÷rÞM+Ç ÞÏà`“ÅXýÍŽ¾¨ÛÜlöðØ÷VÊ×…‹ž¢»(@Z¼`[®v"Lv¢[ÄkúwñåXÈüX‹+ÒÌ¥"p9©Ö^euöDÏ¢ŠâÒ˜Ùa}ö’4$­ç¬õmTéK¾)ï æ»aŒÍué}²œK²g©­ýgÚ*4 Å|0ƒlç~‚m€Ý[Ãed–0³MðÕ©úJ¯O§XˆZÇùâ\MIàvLê¼ÓúÝ(Ò4äâ"™Óý€7b­ªG, M–Þ!W © €!}ˆ)?M%øå©¦ Õ¶»'äýÑ} 'SVÈîÝ&©Ä_´µ­a‚±ËÁ%&Á,ùH[A^I¬v¼5½ñØfÉn„•MÊnŸœˆÅž¾É²îsOº˜ös¯ˆ Y—LI>G„;Z˜×“îÉ+Ûvà ³€Æ©üe©>=фև®SX6‰j&àæºñÕ·±:8 ¿©>×Ë‘üÀg¯”¼àÏWõ.5.9ŠaB3Ld,Ì‘n¥ùz‰¶â× âËÇc`þœ^ëGíû‹Úö7Òú™éý¨¾¥t@r×TCù0ðK­•|³ÇªŽ„ëeN…2*¢dE»9®6&byÇ”WÒÞG\´†×{JŠ{­žŒŽ%ù&åì0$,X]%á"_–`e×-Z^ÆÃ®÷Žû´áªµÓGk§Å™b:îðÁP…+Xñ+'—('M"÷BGþó 1e‡cGL¹­#¦Üögæmjˆ©ëñ—Úö;Á`ÿƒÐ£#¦lÎo“À[¦LJ ê×ÚãºÎ«9i“fNÂùSz¨ßä¾”±þ0š ·}\¥„ qÿ4#º lYäÜ2$$òYÞýï^£ÔJ”ÙCXCrÆzçß@Ë¢>Iç¢Mãç}¼?À@YÔ•KÕ«¦Ñ–ø,Zc]t¬«jŠtWF(º˜@ó¢/Φ²÷72΄x­¨bÝÑãKœY\ÓÑÒ¡‡“U®1íÛr»¡oœ}ÆYU.õ8Eß¡_Üë áÕv9t馃/ÒEë’•@ý“ÌKžO)aª I*p»kÛï·xfÇ[ÿع6±â4ÞƒúÝa¼? jÑçµÇo…yÿý¥6ö"¦ŠE\­G²ÁÒ€M ìcY?~Š>þ˜ÃQ[±iS)'ÞkÓPKþp(³`¾¡)tݵ¡0*ûåÏTºXçÌÕVëDwáÔBtö uqyø¿Ã8…vjŽ;ÉÒ;žQ jõ `ñ^¼Ng•½¡R ]‘ã«&ÍôºŽB´˜¥ïÎkÅÚH¦“ü>EQ°.áÃV7ëXVˆÅôË,Ë­w$ü¿‘”ýý•VùޓȽp¸È×r?ÅŽš'²3…Z0¹I?^`·yûÔ¢I$ñ=uÛã¹x9UwÛ’Ñ~-ªE'‚øZºwctÜß‘ ÀÞÔ,PwìÅQbD•í·ꇢ>)õõ‰b¾ã„Ë Í+I›×IHn¢þ²­áŠdt°ÌòÍgí~íìó­YÛºº>ìî×e™x½*[GÄÓòr㌶÷í°²l ¬D~QL4ço1SRö×”ã–ËûÉ#ú¶…MîR3ß;—(¼Ž¹xP;;2ùcy®Ó.b×,Ü,jÅ`ŒT›Ð'úXµbMâÍˬQ7.Wâšd5ïéÒã—˜h?)6Š WM½\—Þå'Ý |:(è¢-òíæ|i«ˆ9;m”«$Ÿ´ìÆJLwKÇõJ(3&lJˆåQ*õ¯Ӿälá㎢ñVÕi!ìúIvmäxO¯ÂŠWIJfà±k{X Ûè‰pÛ ×ñ¶FªÔ©bÅòUiåÆ%¿}Ç÷²oñFèmö…”^ñª„N(-)qt×óÀBÛÈO½1U]‹….ˆ½QØtº@R¸}[¤•W} ãök¹äìEé¾=–ëz§ »©·$'$ÖØv´ìOüëÈùÌÌ=Ec´÷ ¬iå37×ÁEÑ/ż7‚h¥È©mî4Þq¿¸‡|P,¸ÂsaÊ fû­.¹vûö¼èÑÌ}¶‹r=©ß¢oæ3 oÏXW±Þªo£lS1Ê3CÔ5ÞïTœr…^áLs{Îtô.½6 ¾#ró•!oÞKªÀD\“K¤?Å ¡Äã<ø.³;ÎÄ›˜y&;`:RËá`y½Ê×ö-Rí4cKÐ#¬ò/´\çž•å*+‘’ðŽå<“(„’G‰>d¨Ø›>5Ô}ë|óN|5úˆïB›Zô†9™ÁÝõ²®f®]ëj@—™—;Ϙ;$áÇîÈp'‡ôý{’Ö¦G4[!7 '.…èä^áY1.ÚWÞÅÍbƒW¬ï -Õ¤ˆH7ð‰—AH×9Èü‹7…K×N ~%£¹«TDm/*Äu±|‘…˜ jÔãÖÈB_ïyóùµ2²e§ß[çj\|U’Ú¯пb±í‹…¤Ê¦Î_@nóƒŽq—š› çQƒ§+jßÞÏ ½¿€]lËÛô#3{êþVèøËæÅ¢ÙÚ®7ìåÛã¤òàzeñø#¿¨~ôí’­°ºç‘•™ƒÉ-§@  ü™ëƒ”PòÇ6˜)ýðPnû¤¶ÙúDI+Ÿ £|}„*¼ÈÜ׻ǭä=^‘=­k[Dóçõ:¦ï|6¹·¹hž€{$nðdLü–„]&üÛô’yµß ¹~Ú¨¹Â@¾è¢ÓݪÄ^~#tºde׉A™_.)'Z5泯ÖBLÑÁÄã³õÇná'”ÐUK²ëH¥šh¶ÅV“›{$Ð…èÆ¸ÒeÃjÌ<^M3VlÇÖ;éÞ\Y‰)å©sz柌Ýïb‹±ìü¤«§Y TðNÍóúÖ_ÂK‰Ý±ý×m`ý7jÄ¥Ÿûˆ[ÑCâ¬OÓ ®é«õÈ<ƒ-7vÝ1Ưê(T•Ú1ß.ëïëÚc“ùÒù»/Û¾]/eµ|\{Pn åþó~M¿ýÇî­”â[scºêZJâÝÌ*à%µ¦Ii¤ßû¤c¸ šÚ´ðÃî7òrÛi-×%¸Q¹®bm…çD¬ÿë/+SñöÉìAvWÓWÞ—tkÁm÷Wëg3[ºòOoÎü·3*g³ëîò‡¹ÂŒ²Y¾~u2»› ÍŒJh³UT:P@'§9´ pÑ¥0ï\N$D`ûÌw´xq7ÝÕÚÿðJM° [•+íÍVå¦k©êB@V9‡òø?e3i7¸…»_êîëî]†WªþX~L¦ÞÃÜÜËM¼9þ ]Ñh› æú›46>øñ×il…tÏÃ.D$¯#°è£˜td$Ñ”:ð³Ž~ N¨\ýýG\"+‰r .Πàå/ÅK³·²lÐ:Ž~3òºäuÝä@æX~C„Š!ÿŽŸ ìwü®0Ƙ³ ??»÷¯÷æ“gð÷ÿÍ­?endstream endobj 53 0 obj 6785 endobj 59 0 obj <> stream xœÝ]YGröóXXÿ…l@݆ºTyg-°’VÖrWòJâØû ñ7µÏ‘Äïˆ<#³"»{ÈáÊ6Å:òˆŒó‹Èì—›y›ÿ¤ï?;ûô{·yüú,Ü݈Í_ÊÕÓ³—g"ýgNoo>?‡üFˆi1FnΉôúb&gg¹±ÞmΟý°U»=t3ϳ5Ûi7O^9éÌVîöBH=©íwxÓÌF/Û«œ¬3rûS}ñþNúI*a¶Ow{åçÉJ½}½“Ò‹7Û7»½ž¬ö‹ÜÞÝ©iqf–ÛW»½œœÔRäçË¢ïœÿ-äÆO‹µÊ‡QÛ þýúìüߨžï¼äì·Ï¡­&£%ôÿγ”ØŽœ ã =i¥……~f¼gux® üF|·~ÿr··“§¶7“öR˜ŒSÜ››œ2Ì ®hôA}ó!Ls±ðõ3$¢Q@ ÃËÝ_Ö7Ù’áÅ1K·Ðça f*Æ6a)±MeÔ¤í²ýegp@ÎÉ×ObïÊ òùU½™)büöÑÎNÂÏÞ’7qpfÆÐБÂuo†I'‚ˆy©!?Á~ܤ…Û¾¨½_”!—oî–¾‘ZÀ=0ž‡øñ2)ëh“W;dàŸÉ{àêóÀÇH=O³Õ"`S8àTn¾u@á æ£à©“X$OëËÚöchÛÍ“\:G2âç…pÃ0}\éš8 &ì 0%x`DâISfíŽÍS¦¾°Ù8jX‡íÏ; T’‹Š„wBéJ;Gº^áØzþˆ<ÿ}]”a¥¨ 壟¥Øì…†õšE\¯Éb¿ÑÜ/“ÍëútÎ úC#iô$ôbQ Äd¼ Û;X¢TÉ"é@Syd%棇(ƒæ„…{Âò:G»Iâ(SÿÓnï-,>ˆÉya‚'Tìµ[ _±ý¢<ÿ+ÜÜ~ÊÅÃC»ý:æPnû¾ÏâpAŸÁZJÂùtùœÆ ÉZê~ŽšÍIKÚ¹Ïaž60‰^vO¿Æ±2÷šö[÷€©ŸžÂÓøµšPÓßÛIóJ¿Å›f0Œ¯qjt ñDì*‹Þ>¬FŽN(}‚ëåPcøí·ð˜5`õ*Ò•«ÌEå,`\™,³mVânÔ7Å.óÅÓ GÆVP‚´tŪüêPx; A¥,óH©—™àØ@äg°¨ cð ˆCщ™M«Q<ÈbøêãòjµZÍŠ$›õs1žÔb₸ÅÉ ‡4pSÃbh <¬gGÉç¥MÖèP^ŒÑ6+5§3äfÖœJð¢ÅZÑz³6t'JœQ´.*°ÓšË½ËÊï\®‰–>æ„bÙž÷†dü«üTÌem}­«‚{2MÆÕ8 ¹ßê ªóŒ?öo’¡ÍF±ÌUåæ«·€æ‹ÈyºÅÛí' Ò`®glî슜gè²›OѬ˜Y.3`A8ÏwÆÀ'Ò ò·_àg/OlNmå ð E![-ˆÁºÀYÍ%kœìLì’v I`>v)Š›±4•îã„4*ZZœ]ê¶á£2è:»)RžÃ·ùæ£j†Ë›¬qÓ¬–Òùj‰£C h§\}Îí¢ŽZô,g þù$A_Tipœ‰düÎÊå‰7-}ŠúÅ‚l€:lÌZ =ß¡S!µ#ÂòüD~wbÒ„ãánXVßêoTÿ‹jÔ ÄRNÀž¨Iè^£Í1:Îl‹›Œm–œö™yíEU‹Äz„P‚_t‰f ȼ4&¥ïG·±@áÇÚOu6j;UWf¬_ Aög³ðDÑYxsLõ_2ÎÚJޏ6b=ÓPãök&?¶pý …/[fà-_c~e!#”ZÅÕd9îyuQîdk¹Z&ekÑë{j‹o£—´,KôӤ µõÓxíE¤–Í¢KÆÓ‰Í@Y½ þ©†u•UÆyèèVw°Æ7•¹.CCNÙØXþ:ÈÚ•×»…Šÿ t1ýlàú"h@§y\ÍíØ[pÎpê„U·±ª5|u y°h#´Õ²¦ˆUÏ0i‰¢©=ÛIˆr…±¼ý«íö!º.ˆ0δƒËã·õÕˆf ÀùÚÈÛ,ˆõƒ±UýÚ+í,6ÿq‡ÓÔ¸=¬jìš Ò¬–Vç­!”Ë"…Æ-ˆŽ|üƯ ½ý{q3q«²Ëª4º-&гë߇údÉ­‡O yÑËòBžMÙÈâ4|“‰ØK¼Ùƒf0Åòªä!@µ"k9ÔMáUŒRÖœxLZ* ’r¨yˆš|H PÜ67¾ÇÕô~rž´^5RE1{¯í yaƒ ‹ù ĶšˆŒHV… ª½%KŽ„MOœ(4ŸDdŽƒq¢ÞTJµz³ÉF`sèD)P6ðâ Lj3,™OPDRFuNž÷ý?Šã„£Háûú!‰0Ôg?–,©¬ý æ:ùÆÑC(4‰¹ `Y”ò1ø¤UKw>xLF«ãÂÞY cû¤ST¶àM`V j[°ókoBÑõ–lÚ¤rúb êàøµéP«7ƒI ‚èÉGW¬ÑªF %@—ŠqPAÔ¼"­gÞ/&1å(q¨)‘UV¦V‚œMÖPƒpª’ŒÁ›ð¦D¥ÇL&¥!bèFQ[6)Êi{~ÕH×›Ddj¢9ö–Oþ[L ̼8Šò@%âãÀÝ J ü)‘7Úàs÷Øñæ_XêéV{}( —Æ”zÊ 9ÖÃÀ4 Ø;Ì@4Ú//à‡VoY@0p~ÂüÇg5×TŸgÊHŠÄrŽìBó—¤Ó{Å…«G Ë-v~LÖ`…(ãx¹¸fQRã OTR/¨-à ;Ó«jÍæ6rFÜÚ|ÇFXÏàlhQµ†ÕK˜=jG£Ñ÷¸q@¾ ¼`Mžÿ1´öPä’z ôÕËÐs.H+·\+”åʇILSâ6wœ*ÄØoknñcÌc.Mh¤ƒä˜Þ–дGšÒZÀ¼ ‰y,j¸VëëFå4GEZeÝ"—àª5_CNòP™ '«–$†.Š!µ—Oã, ›°}ª£ác&o)nðëèÒÒŸ•j3“õªrï=ò¨,[­.ËûÕ=Ç1: N+%dl,øOĤIKxÔG» râ,©-+2’iT¢†¨B ár€×1ó&ï–B;Ìz/Ó–0(ËœiŒŸ„Ùɦ€ª^rÐ.;A·öÀ;¬‰˜³š—À-ІˆMZ#rQN=Üe@½'Œ¹ Ô–¦'l¾éwÍ‘ÅtX}ÌlÜ8ƒ°ÕuD!¸cŠeuìO“ßÑ^@;°ˆ0¡„² öB©&Á%9&ºÍ`=hU” ÁæØ@'É딞‡§\qÛÙj>IjÜÔ<¢Ÿw`e‹úâ¤ó½CÒÙÅŠ†]@·‚ëŸùåß(,×KÈ‚+o}CYÄnÿФ³B³øvyŠf¹Ã˜×ÏNÈ\h%1Ú=¯¯|ÆZOvxC/ä­v‚#úòü컳—KæÍ^Ã…š†´íæVë]?¿uöé­o6o^]=<ûôoqöéŸð¯Ï¿ýþ¹õÇÍ?}ykóݰöµv.~U`«ŒY6Ú"$ë_É l,Î*ø€÷@L"¶·Y/"TâDV_VPž²9:¯`Þ;y (§°~ðQŒ…µ­6G¬‹2:ÞlBÒÞàhrwíºqvÀ d¼R‘«:'¦ªÏq}¸;ZoövÛÔêÓ§³Ùn´2Ö4º¡¤ÉŽZê÷Îþ‡Ø·ž}ˆ`Î’·²>~bŠ#6{`[½«Zƒu”"—X2/ï\∅!rÖÖ) A vn…&W”–@Ûà''g_Uc*'Azܵääæ ¬€± ŽÎ,Ä¡“ÙXðÚ& ÊŠ÷ Ë;[ÖzT€”]"l] hœYµyjv¿‹G›ÊKì€\_î°*Ó[ŠÕBû'iä3[½3D˜àŒÖ’ê'Z4aej²âY+y¿¬Ž>%á’¿¶ÔâØ’òÛÊs.'¹ 8À¿ï ‚–òÅäeÂw¢S,2ÊQªÊÃài4ú²F£W\óL D‚RãR¬ŠÂ`¡7V¶" #öt]ºÐÐ1ï“\á!ØDJ­ ¥ñT®(¡&-À+˜´ZÇr#²d4—Nr²ÚË÷œ­T-X°=È÷ç²}sÊĈ JÑRŽmåìÇì 8³†m¡NŸ§úˆ øæ À¦ˆP“,äqc¼ÆZ/·”,?y3e’2b²R³mAßÛhMgËTyd¼'í\ú ꌉS Ô•ÁØÄÚd•–”·4ýÆUúãA5~\ƒ8\‹Õ!¢:Ñq‡>ÀÊÕa ,ÿ¢Z¤ˆz©Ê¢4»¸éãó„h—ÅдEªyOìeET1YÆÐQvÊ“c«YLœQŠ#©GyŽU-À¼$&¸C‰Þ!Iì;í£<¹åãòø_Éè>ŽÑËÒˆ'Šñû#Øÿ‹š‘o«¤Â8Õ„à·üHÒr½%ŽÄæ×Àp1:„šz< s¤EF·’ÅšS´-LDO6Üœ ±]ì’ =ÆØ[¨ê0Ñé _õUU¦Sœk—‡4ï¤:ŽkE ¬w“š…Zéf3tP1µó¤~×p7Á‚1‰å¥J˜* <&ÇÁ7˜úK‚Å”ñ|xO¥•œR‰<¾¸k¸gìîÜRïtZ͈‘“L ƒÐТÔ'ÔÁÄ+ÍBÏÕi°ˆ˜+ttw9QF×-Ü®Y?ÓS„©«x}J3ÊŒW¢sSÀnZÓñÏp‹¡æl„ºÜiÙÈ•³ü6›µ?H –eÖÈý÷med¿m ‹¥;l¸«~£êw6OÚYø’_„=Í¿üµ&ÁËÍ`“²ûÑÃÀl©ºh CÚçÉCYÄ;g·"ðøÂVD5‡ø–rÙ²HbÙ2× %.ÙXÓ']†í³œ¢²üÇËÆÙJyb¹]Ï×96"7yâî ð ®Çßì0 7‹]K®OÊÿª¥­V ÅÈ(%°Î#~D"{XZüÏí¥¾pu×9å¶n1îÜ5UòùcÜ#†äK«¬ŽróÇPkŒª½ßí’úL$1ëÁ¶¨Î»ZÏ­ +e‘Ñ´ÐT|ž!‰ÁšH3à˜„ )ºË}Å/¿û‚”ÏžRD¶ÞÝÜUü”ݦèoÊULF~ý%Û¢`¡°wQ_ÃMÇ–}òUÓ¸ô‡U‰§Ñt&û PâïTyr‚ŸGlŸØn9a£VrY‰KP½ˆãx÷ gŒTEë~á6Nëon¹ã °Pt+0ä1ï¥]—´ ê„‚žP…êõ» tÃq~#÷gñ:±@ Xó5¿|i{–öÌÓBñ‹Æ­caë¨úœt–6ë×÷7WͲ·Ö€ÕzÆ|Ö \¾vþ¤Î“©akÝ3e¥â½v±fC¡*ŒÝ¾¨Zrˆw¸6~,sˆjÂò|üTuÝFŽ+kñi™–.­ðº»…$õy÷ŠÍä£û¦tˆAïqƈ˜=3%+P_Õ>ÛÞëÁÖÓ3‡Þdw[éc F›ŒNh09­Ç.„Ã&áMƒ¥r<—Æ”Ž!õ¶dŽäDBâ¤iôÂLBË5¨š-`¨méâ?)gÆk=î k»lãC´„Åo<´ñ<¦õã+¾-˜ö L Õt¿õĬ+iojëdÚ¬8ð ÙJ·+*[ùf†s5Çt˜$êpæO Eøó.†Qq³IU÷5Bªc¿ÝxÇPñüüöʰãåïÈj’Àæ𒃯RpmšßcªSkº©‰€AWYÖÁÈ5‘Å-&“Å,ïF•8D,†åÚ݆°é…;ÿŸÍC\ñÐA jé‚£"¨è~À>¾Í©®ÿw ¼÷ŒÈ¹ܪUáGê}•ZûÝY›u„GbÞÖ]0 ­c÷]+!R±§0b<+äævè<Ä’)XÈC¶)¼`Ý1çõ±ßwÏÝ'*Ä nU¡ä.ß"L(£¤Zƒ+a-¯sü1‰4mŒFÖ%VI.¤¡{kŽKUäˆä’`Ì|@‚3£(ðÄîâ¹S’äqŠ ù6Íl^Mvœ{ü®“ïîçu”\PÜ›’qœŠtn­ô_E¼ÙsöØãwËzÞ "‚§q[[×_‚ )KêïœÆ½üGrhÜ"q:JV°VÓéÉn:Î… d8°q£ÌAGìU”7©Å@ilÙi×!D®uñÙ0¨’ƒMÐ6å5"/)]kSqá('øã 36¦Q—ƒ;ô“«Á.m8´§uëqL]iS×»×d ÷c…L·ô…4iâWúo„£5¹)íŠë{ZYAPÌZ!ô‡srµÑ«p³k¥–ëp>WïmÈÁ¹Æt滑‘2ÞøŸP˜\”\~:8q¶x¨dš#‰$ŽèŒšó“’ì4`I£pÞŽ,xÜÀ?ûa Ÿ¡Ôá9Lï¹ç5ü‘aP>ÅÍï&~PCtwyÞùn5‘ç¼×*oZ£buO¨'æ¶=? !ÁÅ7¢Ïîk`·RÔã‚'Bgÿ¹¯qVqõ„h¬Ò½H{=ª˜9´­;h{œÒëp´ßâ$—P®àotÇ@ªv{×ôj{渖ù´¡u}jRbåÿ‰~.cÀQ¾*$G”2²ßC[$¦äOd"h5+Lì‰K+ºâóUsˆyt ÑdÙ+{¸ ¯GÅÝ:ç”VQ¸‘Ã[|Û_aA0^˜PDìV7sB¸µ@Œ>€¹ãòóÑYnxPá^Í&üh{¬Z»Ía9ˆŸÂŠÆ‹ ÄY ØÃ £®u˜Eem ´NJ¦\,=ÏïÎÝÜÒÛ+Tg«ÜžÌ`’*±ÝÙŸxB»‹ŽÊ‚+¬óøs¶w‚¿ªkE«¢i€ÇT`Wçh—Åü¶D¾N”ZTsºÇ_p¤Vˆ9¢…ã‰õjçÒÐýK[tÓ1 ö€‡YxäOZ[ûaü™kU¼ÄSä˜4F.™4xxs" 2Áð´9/á”~êÃv"ü¡—xÐÉ Ê¨­ú~2ê‰T­‰ŠÁòšßuÁƒÏÿDÅ-Þ–§êÍ(˜´'nha>~]Ûno¦5½d–€ðÖ3f2÷™?9<ÿf)ñ× ¯£T‚ÿÔ "ñ1Óâ]B½õ½ËuÏ„x¯+>b>~}˜™_3Ͱ\øˆ!wÀ/§÷à û?¦$oMoÐrÒêxÔ¢ ?²‰ZºÄ5•£÷ÞßtÞ<†¿ÿ}'øendstream endobj 60 0 obj 6701 endobj 68 0 obj <> stream xœí[é\ÅÏç ÄHùÀ Ê<÷}OØ€pb˜ ù€²÷<{x/gåOUŸÕïõÌî RY²Û=}TW×ñ«êzïflà3†Ò¿{';O^ÚÙÑåNèñÙßJëíλžþÃÒèÙÓ]˜`äÌÞ2Îg»‡;<÷z°†‰™±vÐb¶{²óýüû…˜äÜÎ?-­ÛÒ:-­×¥uRZ«ÒÚ+­ÝÎŒ£ÒzÑ™{YZW¥õCný°û×?(ǘ›í¾ØÙýèûùŸK-átNÍß— µó¸CÁMo`=ÜYíÜÿE\Xj-ñ?ä(=6\ÖoJç5áC!§®sÜ;Â%éœÞÅU‡Æ3rªBĪ¡,­}Ò9BåÄ~ç׫Î.S~âŽ.òÕ¼s›NßiS‰>¬ :ïX/÷Õ‚ÒÅÝà¨H’µªßvéü÷щª»Ÿu(~VZ/Këyi=íÌý±c>éœç“ï¼önÊ»tä§žõ]G~Þm=!áIåçW3þ¬²”`páTÖO;§|_~Tr´q†(ÇA‡o—[yNg ò¾skÒ*«eè©÷áÈ´¯.}Eæ–CuvÞ¯Œ¥–¯ÎFVÜ€‹ÜÝXN?-ÓoKnôaHíï:&oÝa_Ï@¬; xq—Ú[›Å½JЧÖÏRü‘BU#S Ê—ý®3îgíÿä¥Ô3÷#ŒB¼#ôà¹÷™ jw8K3®îuñÅ’s©içŸ/¼ŒÕAw±ƒPJ#ä€1Œ+.ÈK¦%ùÄ Ò)+J¦ÁãœÃ€¥ô Æ8ð OÌ+QÖ>%s> í£ø; cí®›U®|Ør¤L^_;¼¦tzpÒä,wÕ2ŽÄZï\d¨e”¡ üÒT¯ˆÆLÀp ` $8föQ¸ÐµW{jïyí|£<8Z¡Ó€Ð{SÇ’Þ‹Ú{Û®zkïªöžÖ^à£rf°Ž#PÈȺg±i™»¸Ôœ ÎJú„²0vB]¬ÒÆÖÅ‚£,œÌ äúÁ L½×Þ¡ö~Tzƒ}“ƒ³ÞN®ï¢»ÏOÝÞ½v÷t}„ÍäàWµ÷¸ö®jïií=j(­œ¹¨œy(mSÎðÚëk¯¨½¯^uÙÈk¯©½®öÂ<;0…²5t·‹¬‚¨‹Emãª1_ñ̉]ÔX㽑ØÉ/<¨i8¿åƒbyeÀ+Æh°+?-ðÚµ6´s/6¥—UŒ˜¹õê4,쬑ea©óhœˆ!彤Ûõw¾D˽½— |ÜFs” ›ícSrÁ%ÎRÊz®bІ¹¨Nàá¤óxJ¬@D‹–M3%ç_C¯{k Ý.D Ê@Ûª;—:{êÀF;TÐ4}o:£¤Hs"Í‘o±ó58[«É¦(éŒwnÚ.…¼4`îaø"©x`¥´’.ð‹dä€gó¶Ør”9'ùÀ¼KìQÐnÞØƒ×[!×-xت^[<µç |‡AŠŒõ”¨‹Äß|)Røt( Óóù=ø°ò{Ü)Irzʬ¼ò¡–<®,kîaBôiâóñتåmƒ_W¹\õ"âZùŒ“ a@W)WQJ¸Á^«Éx#NàJ9¬y‹¿BÓõ…ííBà­©àp$Hôn )›*²ÎA=¢ÝÂUt¯÷¨l9šÄAê”h5Q&Qz“´Z—ÝÁÔíWdÓtiÆ("µ×UÒëúD¼ˆQÑBºç]bÖ ¤m‚t‰wÁcÀõ¦:iµÏ:¼`i&m ‡ræ0’ƒ†–´^CËCȆÎ[ @Lj¬ÃÒNx®¬4Ë8ÔdÆ@dó*Òû(+hÊ¡ò:Oª;û˜s W”0”":3£¼ÇD <ðººç0ž‘ÀûWÊó)>ªÍgDx‰ÚÀQÚÂ.Dkˆ§ŠÇ2èÁT¶JEª²ÆÇ ëï7kê!VG]¿@¤qsS¿ <ºS³ÁnvPžhX!Ñ%§¤¢“Þãï ·¢æä¬jN•÷Ø2V¶†¯PEÄy=r³Á(_-zQ˜£Va"cêfä°ñæ˜Ö„Cä€ôÔç”+þ⼨óeÏÈn`sõ†…ìÐ –†%>Áð„3¡QBs4vÙ!qÝõÙ‚g¸”2°”«+l›A j¯ˆ½8¯þ"“m½"°Õ7•¥bHŸŽ_ËÈÀŠ„Ø㔂êý¾¥$—ý1üÔ¡‘C€š#*Å(É×tì¿bþZY½‚ „‡4zÏìfb³/ §E¿«-R7÷AŽ1qÆ£¬Aq#çµêÅ/D5ÈÕ‘ÐüNÙ* WÕ‚ú¤Óª\(Pu~n¿ë¿*-˜ì•>`Û˜Õ£°qx%H¯”ìQ`6¸·î’S¤P©p»«ÓDí¥”Ü)“!ˆ´ L+Ÿª¢l„žÄ4•ßkŒ—}ˆOHæ_}8Ú¼H)xšpM6B¾bâÌ6X‚dËQ!ªˆi2ÔYqöáÌì¬V•è7΄/k*ÍJ—DD¾±zxY¨gI ³›ûŒ!ìft™¶Où²xºÕ<( ÐEvI o~'Â?IÄgÈ,ð ßJoFÉ_: @ÞÔ››æÚ¸x5º.6,ãónªj5 LrIt²I`Ü?qwã ;Ev·˜¦ãÂHâ¡®›ƒHî]уHŠšÕUßMmt’„oô¼!¬Ö· ‡b`LÁ¹[KU÷etËcéîB‡‡ýãø°]›<ƒ^ ¢cV€fs@Y*¼b/^°©.?Wâ’§¨­ Y$XII^%ɳç!ül<  áU•ó(6™ÓL¥DEšÀ= ð‡Îüý Š}­ø(7¬]@>9ÓlTóìñÝ, ¯ÀˆÎ×P5 ¿‚ãÔS;©l°ÓÒ Úb(Ç‘Ž SÊX6‹/*¾í-4°÷Ðñ@¥Ý…¿%à\·x I9/ãʸKÜ^ öTªSÍBlÛ H$C.z×¥]Ø£±Øw€ ç““7®É6wïuL] pÝvÌì¶%ïnÚõ³•’,6Vl@C%Ån7º ØÓr°H÷ ˜ ž>à[¿á†à±*ÃäT#c¦¦G ÉA/þ¼ˆxŒ1”áê~N šå¬ÝSuAòWýdÝÎC`íšyÇ=¯Ô«esWÄ}Ý}Án_¥?ÛÝùfçÝ Ð„ •´ð„ºâ{çf‚)¬ÁBݧÏwž<ÿrvuq}°óäŸ3¾óä üëé×ÏàŸçŸÎþ°óÙóÙ7‹vG5©h—{Ô$Üw 5»'•æË1ÍùQ¹K3€‘@ëcÓ,8\†ih¾Zl{ò˜*ˆÒ¥€§Ñâk¸ÌšO:ëô ©`ýæ-÷  ØjvŸè×4:Ê:‹±µ¼Ò:åNÀ$Pè@¬m¶}1s[¹¤ï´Äp%ÔÈd|cL;d/à.Õèô{BÞ3† ÝQ kÙà¢w ë*úû$FGåÏ1ºð“m'{%„ÈݪÃñ0z“Á v† †2Õ†~¿É‹—dˆõô †÷ÊAv4ßðäEðC›ÄȨ¤£ë¥x q//¡±ÁY)6;AYIJX8è?Ô r8Çœ}pâÝ éÄŠôAh¸Þ_äÏ-Õp¸Ôµ¨¦Šö‡-°O^·)@hÍ,êV-Ç8ŠÈÄåñ,DÔîn™ÃL_yW{Ö­ ;©UaçÛÊÆH„ï´—Ô8=«&+„^Rñ¶¢®ÂbJÆÊ¶".Ìz]Š–®(‰Øi… •o]ŒÍA f?ìDe®˜«ÇÇ¥BÇAk?^Ôj°®—¦¼&ѦK IãzÂÕ& ^wrqi·\ v ]¶a$\ô›ÚþUð|ø:ä`CVã¸~eF6ß;ÑÑâÚý{º˜M‚À2¤5òô’£ö#¥ebÀ’k,'ÎI½NÑ6-þž‰v*¨÷ÈŒR.^Ëækév~Ýø6²z+Ÿv¬‡«%Þ×#Ýõ…ÍÒ€Ê £çÿ¦UÑnÐt¡¥zÓY¡ÒAÊå{ŸÕí·×©¾µÚ}ûý‘Oèå aÛÎ?vöÛ^+ÿ#é+²±}“û–á×O‹æÙR/ï+yM:§­ÿ_É/¸’ÝÃE‡['ɽ/\~û[ÊÆáà––Ä¦%B›ö:fšò»»zKº@ðèL÷3 ÁýáÉ6ŽÇÖÞU 5 A›76A´t:ž(:DôA„¬Òã £‰íü¶³î¿"øVC„¦Ú›‚rQùûmA¹Â·€R X§YÞºp½?.0à¡ð‡îFžý— úY1éá•6”âõÖº+D›“ël׸ÊmÃØ¨+b(I±¾Ç¢ßf¡Agl_æƒéVX¤h&õ0ã'œ‰Æ|&N8<,5DˆÁÊ‹ÀåZ0àóéË ›Áßÿô‘+endstream endobj 69 0 obj 4309 endobj 77 0 obj <> stream xœÝ]ëoGrÏgâ€ü û-ËÀO¿{O’¬Àºè|w6ƒ$°%ŠÔæ–”MJv„üó©êÇtuOõìêAûàÍöô£º¿ztó§Í8ˆÍˆÿKÿÿòæäËoÝæúþ$¼ÝˆÍ¿ÌO=ùéD¤Œ©õæñ9| ôf&+­Þœ_ˆÔ^ŒÓ`ìÆz·9¿9ù~ûèôLêipfû»Óq˜ä4y¿Ý¿=•ÐjôzûêôL Öa·wÐÔLƒzûæôÌ ÞO“ÚÞâ[9ŒRmÃWf²bûºôõ ׃åvO:ûùTŠAH#è{œ |Iû¿Š½Ù–YÅþ½³ªô/¶/cO ¾ŠLB˜íÍ©€'-ýöGhªaF“ðæO»ÊßßžJ3ŒBN0(ô?úÿa;Oà¢ô¿¿?=SƒöN„n¥¶ƒsšN†6Þ“A.q>°GÞö—fí`•¨¥åAÿá'®a•²ê/ç¿?‘“”î9¿† *!…JcáÛë2©w¥pŒÊh1QÄaL`GÖr[:ûáWã¥Ýv—f¦€CÿëT °7Å1bãH}7ù°SVZ-îƒM¿{è*ÑÉ™6UÁWd W¹\õ™ý ìæLȸðÂÝ…;¯gb—q†Ó3 Ì m·ÏNÏ`3j†ôv00å°¦ ‰`(‰ˆ üXä‡o°X¾L;;‘©’_‘Û¬F­·/bCá¶ïãLF ÒÌK¸tGx:O\ÎB¡ôfÓ´­Zf~J“¶Vow„a— ü½ lÏHl½}ŽóUʃ´‘)Tþ®tF¶“Ðègèk˜RnG89‹’éh‘‹y²O¯Ë`ÌÌ}ÕUøpôYR`L5ÊÁù°!0¸r½/óK2«• â‰Ý€²©î–pê4÷ 3ÔØ… j½†=½žßbOÏOþ|òÓF8Å¿ù–fá7Ö¡ÂôhW?;ùòÙ6oïÞ½:ùòß6âä˯ñ?ÿôþïÙW›¿;yúló箩ç™mŒVc&Ú˜}™ð®Lø¾¼};¿íÏÝ­ü¯0wcIæþ¶"kkU±íXv%_©ÁJì*Hˆ·Šj6³¿`0¼v6ø–Wˆg8 °½£šÉ"EÎ(”84±Þ×E=½[è£EÅìYQì“.Ý0 ŸT¢1–šdÚ Êë¾É×Q½½,ú‡tí–ãŸí–œjLqØ&£}šØµ&'¯IUUÕXá°Z‡{26 B…¬…¦i¢ßE3 O_Ň’.¦U,áN*ˆiêB‚5EaÐrÊìø¤HØ›òxÝ8!õ™·åñUi{ÛŠkx䇸-R~ÕÊ~x¼>uÃh¤“À¡óË»òÕþt¬7ᥓ2µì ¥¨‰L*åDš_j02f2Tâ6‘·Dø. Wín9Ä“dÒ € \H’8Èyy1x¡•^1gƃüKb<³]×µ]¸šû‰Þ€Òý蘭1êcnÿ›8É…“‹06>»BŸ¸úƒˆmQ‡½˜eaž"ÜËcðU—ˆearL`§igÚYáὨb}MÑÁüðx‚%X¬”ªŠp^àørUß !òøÙO#Ž8¸k @­Ý¤fVe3Þ•­Ÿ!‰«7 Üwn+(‘Ýãt3j1[E/kƒEH%=ØŠ÷£¶”£¬Ý&ŒÈÂ;²ç„ƒ²ºµjÈBMce&¿9~rþ߃ìëaTþºŸÞÎO¯æ§»ùéj~º˜Ÿ^’/ÎŒ^có|~ùf~ºžŸž0ƒpS¸c†Û3½”1næ§™_oŒ{fÀp>þ'¿D*ú ¿äælÖÃ(G2¯ù»×ÌHwËÕ`Wsq^®Î‘›íK†JŸŸù ´|~äx¥tøŽ#â=ÓãÝj‡(*Fá?XÒ|žE}Ã0Õ óítã\Ü~7Ù)n?þ™¹œ@ÿFWü5ó-7ÕÛ¡L«H>1¸aï™§ òño2ÑcwÒÒá3\YÐ;fZ̤9õs öLeüÿdÆÚ1«}Å~q¶üù€ ~~ä´V‰q@«åЇ'£r¼W¾gæÄqZMªd>¹yí˜wÌdÖ ä±< >?þ¥ÚjBt€‡>Å"ñ/W)ôÔ6þÿ±~³ÜÖ#‰Á'j÷%T®¤— p¬’ïr*ö¬:™Ìªëäú…ð}™ôÏ ÕË:/éÐÈÝ÷«Rxÿ1£n®˜'Ž÷x0ïܱjý†!:×îÅê\Y¥¿þÉåõv–GäßÏ­‡Õ§¿Ð¾IRŠŽ„£Îù¨(f÷Ô8` “Ïîݶ‘Ù6tK>+î챎hRŽ|Ixb‘hhS…«ƒÅÔɸ¸ƒT†8¿¤ƒœ TS7Ú9;š$kxÅEvn©ûJêN²§»£ÉXd4™I$"ÁGø‡ª ª2¡nÕt®dLJnw$(€Ä²ƒ—¶“W½‹Ê ,·±¥4!Ç 0-+ÇAón¥²‰!3Ý_ ²Ìi­d²À{OH®vƒUUÀ˜/CÚÓ©+áUN]Yg·|^þ¨Øo¨ªQ¤h‘ ˆ¹"’Ä: !Ô'eÏ[9¸k~P œ§ÎÐyhŸ8ÅL’”ý¬Hù‚× Ul?X§º±ÞHôyaÂÜ¥K½^‰NEy‘Ÿä⊹ʔÝR² YkWÅKˆG%)«RãWy%kƒtý©4H¿‚USyBûŒƒÀ’>%¼µO)Uè«â®:[,‘¢“éX==.‘+å­V.uXgù¤ÃÔáQº=4õ ïKçBa|UÙà%˜·ŸO§ÐyJ‹Ýe„ác͸\Òr·ç«°D¨‚3«¨~YÞòXŽU®!ÇÐ`ÃÛ%rœË*C-æ8†¯n¹ZÌãqãY¢C »P¿ê+ýöØÒÄ(À3Ð5h¸.2*} êÛ‘âŨ8‹¢ˆ©ö,šÂ?´+.­š&,;}8˜†è[öcÊëÁ‰æ @m¹ýü¢22oÙ²˜MHÞ/pÃbý­ ËÓ£è8Ñžªê«¾úÉ¢²0ŒŠŽô•¼y˜wGYlª| sƒÄ&@æ}8ÿF«LæˆD¤«›äÂpä…̆ã¢ýÜ«% UÓá"‘‡ ›ñ‡ˆHâ*Sã&w(‚Mº§.*óÄàÎåÐWt A”³-HZˆôÆF×Ü u©…Ý¥’9Wkâl(̲ãA÷²¤sOJêAV¸·Axjú]ú’x¢F×'˜I·(/O…òÎÁžEIê±Ü_ÿ¥i†óó%Û˜-"ßíç"í©B®ÂøaÄ"m/Ç$.?ó-Ç­ø8Š {SÞ.´ù /"¸áí7lMø ׫ãe.Ê[I÷á‘Ká;2_™åØ´=¿åø²`òýkéŽÏpÈ={›Àƒu„)̇ïáx¡±!prŒ–ÃG˜ÓSå7°BÏ[m·ñ\‰ç¯‚Ë*WnH—<|r„ ö,lLÝêêÈêlµR–fÃSè vÞ(Š÷×"J³‡.äQ¥4›&ªCÔ^ØD”{¼+ ¾ã¨Òðü2ά@ùµ¨]Q[Åôòå^N?7“´Æ¡‚ õʹƒþóƒ…}AñÃëNÿm˜"xz•.­»†£ôÂð~¯û–ñr×ó5ù˜s[†Uq þÆ]°¯Ù–÷Û¬¹köÁ÷$¦ð±ÞZ€9G9kðhßxk D«m—¯ãWK|ûùo$(½ŒÁ5wº'‘#¬ü‘b”•UnOâ|µm™ç+ÖŸ9"´³ýLIvF߃ƒíÑ|Ü éhÔïb¾\¢ÜØÆ!É늓àxZŸE€çŒô­9ÆÍBV”‚–D–±RíÉT•FVù¿”mÖ£1ò²º/íu}ŠgÓ‘ÅÐ/cÐ’^QËzÀ·»ËvmrÀäl4£Ia*á*ƒ½#º¿Njَ‰B~’¸7Eé­Ê‹a<'4Çêɲ?½8ÞÇ5Î×ä!°ÈƲ‘Tô©¬®’ŠAEó¬ìZÅWb3¶¶8…&ârëÐÄ!ÿíÁsjÇëùìÉkb–Ipýž5ªü ëÑÎuËRž§ ©T+úô¢À@ÒÒ»QU¶dq]·“Åc‡ úÓõIý Í¢WJõÒÚ-c²!Xª–w,xÑZyàÄ6jp^»pɉë‚9öB$…‡H+~þÕmŽ %¸ªè’U§¥º9Ô`^&uoLs=†D;÷«œyèe:¦p+0J®×³ŸJã-.k¥ü]y{Çj„êÚ8¦mO9<Š‘ ±ºà£È1¡*-Ñ»NEËŠÅ­ò=tŸk¾ÎÊN\˜bæž%†±¹M0Îkåv˜tÛGUN#TÑ1€ùÛ^W/¯¢‘ìT»zÔµÌU¸Ð ¼ îYÖb ÷°Æ¨a:×€·ÆE+ØeËB­`¶Û¶ªš!ƒObs'žâñ„²Å@.¶yB ² {ª úŒk x‘¢‰jw·äIx¬Pe1fÆ%R2›KO+ øãs¹í´ÂÏ!êÂÖ¯’ Ä/§ƒ7Uù+ùùò¦¿èÍŠCñ1ë7•]BÓ¯Eç:¨¼”nÁvYáÁ8K—˜Ôò<‹U8g£‰÷3ÎfꎛK ‹ÎÝNX¬<ÖúS`"‰§ìXcs Š’Ñô¡PJÂq²µ¥Ömè¿:T–o…"tu%ñr}õnÕ­Üv¾êÆý>_\‘¦íˆ£ =T¨wÛVªvÉ¡õ^L1ÐçLüìšÕMŽ^%P£Sj>×ÜŒS•ÆÌWàÏÜ·¯ÓΉIJÉŽ:t˜`.½™è™†7Ñ€‹ƒ¥+¼J*¦š/”Iµ_¸Ž£K¿(Æ!îC}J8i›Kuš2°V žˆåì±×VÒÏJyDQÚäç GªÚûs mtË¥R½º¿oÉŠ»6‚Ó ÆÃà š¾e1ö[ö-¹M‘Ü%¹»ùLÌU°ál¡éænÿœF{K1ŸVfwL`ј­cÎÊw¼þBz°¤-ÅÒ&ŽþÁŸ¼!¿Âño%T8Bp“Pþ8 Lcù²°SUÊ´/ÐõÍì‡uÏ+€B£®zsZ!8LSµ*öv‚tŒS§»ApÒ³b?èDvŠ‹²¬QÝßcÿÜwt4ŒÀ;Ç_¤­¨ÊƒªJæèrYÙ¹”‚½ìÿ›ÜÊ@8/Ðûs¼² ^*'àÍäBYo+ã2_ÿ†Ó™¦GŒÞTc$]cmë²|‰=ÂŒ“Ó`U•j ~pTî~ 2G3-èÁògSº)ÅOD†È1r8‡Úßæt"Å,<‹øn͹;®G˜ ªüƒ¦ }×N2'صBÍÔDÑ…ñj'Ïñ˜¶ÝœáJ.—˜™j¬â¡ôdÜ\ÃÿO@endstream endobj 78 0 obj 5647 endobj 84 0 obj <> stream xœí]Y“7röó„~D¿±ÇR 7~)…M­¤ÝåŽíiÃAqÈaKMÅkÍÝðwfâJ PÝ3¹Žp(B,V£p$òü2þº™'±™ñ¿ôçãçgwºÍÕë3z»›ß•§_Î~=é/sj½¹wXµqSp³›‹§g"µ³ž¤ßXï6ÏÏ~Øþp®§Y á¶Óѧ?ç§?_|s&íçÙo.¾=»øç¶ïJ«ëò´/O—üKlþrÐèEyº*O?n‡ wÆ(üËöuyù¦<½:Ñwùøñ`ÎÏËÓËÁ¯µ›'ƒwu ß—§Gƒžë·?ž—Çá$~ &|qäì,lþ²Òçý`•ÏÔ-»Žú×ÑrÖvË«I8ù}·¾¨+i—§@ȼÞs¨¬ü_ƒ‘÷GÇã_ìŒõ“öd@vÊNÞƒÔ_\‚ ß” 7œàûîÒ°»ÂÇ8ú­¸¸Q.ocx‰ñßêÔüdDr³+càÜþ‡·¹ûPèM˜‚•V“ÞT®ÅÁ’fÛ_œïæÉ†`•Ù™§ Cð¦·ÓRMÒXàë…´øVLÖaŠbòAK¬¶3С¼ ¼³*?SgÀûzV“òjûô¦à tû¶þÎ>{GPA5ädL°b»¿¦!‚&¶UB „ƒ9ši¶r{]æðÇ2“Õ!v`gàçgu€¼0pŠø¹rš5MK´Êó…Çik¥Óji*l®Ø«“ð°ûe~¬«J£Î/ÀÖ©í_ôv—È' 3„=Qöä êïûºåwTS;+p0Ù÷ç; ÖÐ’[ÊIƒÄy§u[«“ì)4³UôJÃ}ê_;N–8)%C·o;å5­ûQ·›ÒBw@8 ŒŸ¬°¬‡gõ÷¼,-º·-©[¶sµ¯t fO⣊‚Œ‹ú ¨ƒúø’ñxÚµ@̸ÓZV×Èk Ó=°Åãúk7ÅêŒ00öû‹Fàr‘-£BÈ"P)=­:,d·ðÖnRjû-vªû–mÅUaÆûŒŸTnNrшcŠ–™¥˜Œ3ìåÛÊ^õó* #Å×éQ&…æì«A[Ò¯#dßÕ±¯¾ÊåBÝàP¯è›E*‚ŒOÓ¬E:16*“Åwç@1"ªVfR³ZNö"RC€f\pH/ lÚ‰CfÍØ»’¬»¶arа¾¼F^…­Ò+"“4lK•®hÓÚ‹¬|*V‡‘À¤ÙÆ 1 | $5¨b¨ÙA†O‹}u8œGCèfn˜À¼›/Q/?;4âøèPéE}¼ª`—ëóyyÙZ¥'­Be p† (4²Ä¤îj$A‡Êkð•§Í¨Û®wçÆÒ“\@™”°Y¿«J«øLXW/ë¬×Œ‘šåä|à²4¶×KĶcâ2 ËQ5Khe,w0U}tÁTÛÐ^ŒØB‚Ý-†îuÝê÷‘E´nøâq}û¬¾}U¯‡Ÿ1&ûkmðdÁdôú“픑Èf ~.¸8õä®ó^V’Ötè»æþ-•@£Ú_Öa‡æ€õ„ÌŒÀæÒz¢Ò‚æÅ|è,FÏ÷ŒÁØ Ñó±רjæ9BWнÕ2øU9eV„!SE¬û–qª~E8¢’œMo®JW­52Ž´¸ßÜ6².ãüfï׿GÆÌÏUùÕ ­æ¾·à½{Å$îJœÒ.ø:QËMÌ¡±FÒÁ4@™×—Ì…IƒÙ9qp|{ÀZˆo@Uç­tºÝšíÂ{ˆØ&^væ¨QŒ[•¶ÈÆÌã(&é¸joì–°³RJLsp·üH€é/d,‚ÌÊ5:>›' ›Q.±›u¶Ùg´lý¥|z?=¾­fŠñ(n" 4ì>w›I42¸Z»æ”EÍÆòš›Ál<‰£ŠÙ|:ãS¾š†ŽzG²HÓEUâLŸ3Cò†iö[¹0³b˜©þ›¢:Ï}áÖ)@L'ØËÌYvÍ)EÃÚ/$! ö‚<%Wã5fiA@°t´S|è¦L|ß]yK˜Aj*JXõ¡˜Ÿ—Ä â„.O ô¬9×_Õî³øiá”–ð‡fÅhÀ½KÞÃØå׳Åí_ñ+Á^Ž›.M"î5k€á¤¶êѨÀͬk¸+·Pkt•e'û¸!s|4Æ)H–¥U)y˸]‹ÆÊ1Ø1%'ëÛè©Ô@t"Gao+ƒFæCsã0øI#¸Ù´Có0‘Ò®€ñ÷ÙTN±±öÈZ€—ìn$+iÑÅ(eækB§Š¤±—cKÁb/æ·e=ì“î~rð:F Êš†Ñ÷—µ¨ –˜¦8„aTˆ[÷¡ˆ—Hº±—ØA5I|’ý(øTä+ìü$lèÁ|è¨ð`½‚ú86eçAýšqÿ«è:À6ôFyܬW 1ë4¡s&„v-Zróت|ý&‡°Ýb'Ô<…`)¤”ºzÀÃ8—ÈîÖ5/ÇMfÒê<Õ‘dÓ Bvuñíb—F&$Å@”ØZ²oˆ LŠúr@ÐÂýÞ5 ·/®¾e!ä£úöPßÞ¯oÙhÏëÛ—‹ 4Žj|qr ÃäÄùÁ²è8™îå~ ›E5b¥Z½ÌC` Bs¶ ÙÈ^¿ÿ”æÄ xÆ´˜ü%Ä‚ ׆ŽÊ® P¥sÏÀ÷E´º>C4¥ý"EâagÏõDL¥Þ~$°AM~¢b‹±U¾úÓЄ5è% PÁî;zøÔ¢°g$òý9hd¿]f  Œb»Éë”Ñ» blTæ¡°Ñ1ÿ ÃSàCÚt=ÑE{/<7Fz–Ã4l:‡ÎóDßVÁ/ˆX.|Jöå†\µ½Ãì7üù6‡&ˆÈnà°€S¿În´·jq_f3à÷«3a ÆßÞYX¹ê¤S¯ÙFÓdˆ¾:Šû±³› ¶h{g:Š\O‘‰Ì¿0AhsV$¬¡±ÐŒ#>-küŸö"7IÌFsž¾ÌûkV ü´šƒ‚Lìû§Ïq‘Ž~‡ÿ¥ñ +~ýGFœ«]aß#&ÍìÊ\Æ6ªn=UÄ<4Zs.LÅ¿d9ÇýxÛO§‹b™8%ÿ^ 1ƒzüäVê¹Äí ºNÛ èšê(K+?9V>Š|økõ–™€ìÇs†Á»•Ò(*ƒ@ÌJ^ð× -3Ù,É\%ó wÎvqQÅl =–¶aï92þ¤›Ä`µ~ ±,áË@òmmX-¢ç,ïtYæ0CCHåjÁÒÌc|â¢ÑÊä)vB€z01X@]É£¦…W²£Nùº„‡6NnÄ\H×R{ ³mʱ&Ha­{k‚Hß,ǸkŠN,ðï ¨¸•…¤ ±˜“³Ø,+ŸžÔ„õ›úöûúöQ?÷ŸÝ"Ï Š%íqÛ/Î/~>ÛiôàOõ‘ºr¥eÁ/…hÊ*:ð„œ¨Æ'\ÖŸV¾a=X[€Ú×Mã̬ßþ<¹eލLÎäz›àõ¶±zòú˜\Á¡&b“–†7µ#y¤U§4‘ð2àTsàª)mÏIcQñtû¨ðé–¥íT#Ž X¡ÑŠ3›¨170†™Ñk œbì„ešQÛ%´uëxŽØ÷3»Ä‹?ÄJ¼HU.#4V&·Ë¯xƒÙñJÅD{džš Kt½sXFzMÈ‹N2(<,ɉ™;ç"ªÚ_h=,Ô Ö‡<ào·‘±ÜÍú6„‘ƃµ´<b½æ"¹u$K‚­S`î±.Aj3mðù'£VÊÊ(x¼åß!Œ8 ÕÅ«-à†ì´<šôaÆ!?k¹¿ñk¼Ý€§è”7¤ç÷5ÙH_".¬”ú7i=KµÙ•櫇p ìé“>?³Ó°CÑ–ASýsÒ;_dá…·^e£TTѦʕ#¶C2͘Z©d’ÇɤâqêÒ¼ºoKØ‚ò± WÙâ•nìèò,È!LãXÝ18Æu6€fºmŠ…›OZŠbfiŸT™Êø§ð–`×e:±ltkWâÛ E¶Öˆÿ}][MßÃâ< q•Zå™eã¸bY·iܺ+IJÍÍ „ˆpà9âéuç^†nΰº¹p žØ –ôÈo,Zvë’‡åËh‡>yI(–T B´GªbÈ>iUs$?—z–hPц$}@æJ¨zkfÅý7r-™qد'üh~#×¼XG™=0!à °XX®øñiì¢1¡`!qáz1^Ђ֨Za¼¢Äº«’œîE=WϹ͖|ÕËÆ"ÃY7`¬¹sÅÔMTwn;LE4ÆNóƒc ƒÛ²JbŸ7Ñ75U×úZf¿KY†á®Ôf*ãFàºü„vs2«Læe|LJíÚð3Mµõ´†^Ìø(\Xñ,G]GòÕ)%Ñé<ñ”äöá3 Û/2®Ç/:ȧ慟mPŠ×ù>†I€‡ƒ í*CñNt âbWR?ûrˆÇv}ætízÓ3LðÊɶ‡ç{ð>æÔŸq5MØ‚£¸ ËW]9º•ó É«¬³áW›¬&ØsõåG9ßGð‘XLLÓ}«5Tlûw8á·(¤Ì§{ó´™×ó*¿ÄL–E LQ/¦‚§›Cç´Š«´. CзÉ|>eAf°’ûÐZš€\É5N{"ÅÊÕ5V(€É컬j{yX WÓ™Ü.QÖ˜C¤àâ}FãÒSæJ·N@–»ÚÃëV:/Œ.mX‡W–wÿ0îWŒÓ‡­mðžûEì£Èsó’.¥ÞìBeñ>VY¿:…ƒžß‹$Q‚%¡ózÇëÃ17­s“¿Èµü¢"­ú`@Ä¿‘€Ð½\rUBJõC[±Ô–”ŠxûCòÆo$䵉N:Ò=*·ÈYêUÔ†ˆjd½kÕ?RX‘ìZ9ˆéýà–Úó7ŸÕh%©zÄ›Å'µ™CcŽSã¹üík,6Š—7J‘Äߡ٠µž|Z+9Zyˆ 2Ç+‡S\6ÙgMÓœ¦k?yJ…Œ H '<& À²RKöëuñ/ÐÝônùçGG©í~*OoLÓÞ<Ÿî¼?Þõ½£~èuìmk:õûëFx"GGxAúƒX¾ tC;þK÷œÝ}ðÝæÍ«·OÎîþçFœÝý7üß½?܇?|µù§³¯lþ¸zV:1X¿fE˜¹4ãE â}]jb0<P¢ò— "sÔP ñŒñh»-à#+œ‚¡¢Ès‹ÁyþÑ“ø‘%7ü5ë`‡îÒG uÀ„—©ÃÚIÊ9^a’>¹} a¥%ƒ¿yŽà•Ÿã7` Ù¯¨Ñœ™uÔÛØ‘o^’9RÚƒ+ F<–9=*Ÿ×I>é§!PŽZxÕ,øc· ëIŸ®.ˆzê¤gúgà|8º ìh±"#´H+òFö+r2­ÎŸOq‡¬@ï[‚AHOðM—öÚ—€ëAb nN3•‹ÿÊÇÿ3Õ‚©¾AÌW8:Üž¾«?×—wËEæ ”Múæ]Ù.l'è`Œ?Ê\le•¹Og®ŸãcÍ")p‚q•ÕŸK]Ž|¿u.<î¨è:{¢xp¢8`ìÎ…+øÿÿ®À@îendstream endobj 85 0 obj 6199 endobj 95 0 obj <> stream xœÕ][“·uÎóF?bÞ8“Ò´w ò$‘’MGrlj]NJr¹(.µk–¤–KʬüùœƒëèÙåEQÊUV³ËÁ¹ŸØŸ7óÄ63þ/þ÷ÉÕÙgÌæòÕ™»a›ÿÈO?ý|Æâ?æØzóÅ9|ÀäÆMNs-7ç?ž±ØžÍnRz£­Ùœ_}·ýëNLÌH³}¶›'dzvût·g“ÖŠéíóîÛ7;Φ٠N_^ïö’éiæ|{³ã“RN³¦WÉÅÄåöjÇ&ë$·Û»½š¬µ&dÛCù<üîS¹ûÙࣞ¤ÕZ¦ñ…Û'å1¾ÕÂn~®lf–¶}Í0 Lë1ö«&É8™WÝTÀ`¦X˼.óà#áÜĤг•‘~]sËÓm8 &¦º)”øç¦&-¡ÁóWÓ,Œ$=’ÅEB`_äm™&Ž3kX&ö*&k¤d¤¼cŠRáf÷·ó?œ •À2çÀ%ð f2JÐ-9~ _ 1inpÓpM°N©ó¤L+ìª.í «Ör|‹@ ˜¬6®a€´Ø_vÀHÂE‡"¿_x¢ks Ä0Îâ¢ö‚I ìfÏxXW—Qq[·“†Ý_c åø‚%¬‘#\aDl9Ãèl[±·(If(2‚ëÉjYä÷ú|QF:N@> lmÏwûy2ólSo@&º`¿µayØËEiBÈý¼¼MÓpªÏØ„ò¤ƒ×¥ƒ"#Ïp |âjÐU¡2îh½™*1Ò OÂ*%Á)ÏÒÍ£™ÝöXÞ~S_•ÇËÒöQyû´<>Y¼Å¶‡òöM÷³ëÜ6,¢ÖÄÆM<­ˆ+>9U ÍóD$–5(ƒ@/ÁÝ@¡YÈŸa¼0“%==+‚B>ºÁ–F`Àÿ\‡lÄ)72Û`hD •ç nÀð¤ dÈÎ,,ùPDêeáô#‘”®Ì:Ì‚Šùæ5ˆìla:Ø’1³}´¼T´åã"3Ov° ÷li%è½*hÀÀ(gZA§ÀÖQ΄š½ÂݛΩ&ÿ×,_8«éBˆñBbZ‹¤Ýþ#«g"6Äô$Mnú&3™­ˆ¢'=an5²—ÀíÕS•Ûi+–Ö\^/vÌNÌ* jºè!²Öà{«¬Â4KâÑ·odµ¡ßƒ$*¶(5™c/q–lʆÏsx¶±‰Û´IºÇËJaó›ïô¬úvyDMÀ G|WY@£) KͶ¨|ÞzZ 5Aíi%²nuÇ™fÅ>¬ÕâvöF™ Uï w°ËÂôð©£gί—“ ÃÄÂ0O:_>ï<=íÐòæ®ËÜ~¿Í½-Ÿ¼&ƒìˆ¾yµJþ^‡(JLÁ¹ÝÿØÙÏ«>-ŒDGÞƒVDƒvk’|“Ÿ^‘i§§G«ð´³ø7]áØC Ê‚“¥¼ êI˜¤›>ü¨yÛwùñß)/îqô=x¶ø=xù¢3«WÙÿ²ùo“‘G›ƒÛ¢gžÅí7&‹@÷¢óôUgÁÇaº 5"päòßOiŠ߃¯èð>ޏ¡±NïÀ ×q¯:÷TÉGá•ߢ0žâ•÷šìûð]€·’MàEDÓq½²Ÿ¾«/Ó‘›²ˆâ7ô:ü¼óEyz&+£ØM31q­~[ìvKÝÿ]n5­>ýöѦÐÔÄývï™ñÞlNÎ;9-T¿šÑO)Í9ãðµOÝÙÙšT¼,oï·?ÿöyy{SÞ^—·Ë[’–<ïŽö¢×¶›IéÆÕǹߡZP’DË\}Œµ¥ÅH5dХГ²u„MZ˜p3ÎU}K`O"á4BNlâdqåÎMF “DkÙa& V´õN¶éa’ò]ì¤\ì¤o»ØIÿHvò~iKF»*/ét0Kà §ƒEf’§¿.xšÁ`ûÙ,'¦ÛÝÿ0™âôÕ´Û;¬ Í Ê&!@X¶‡Ÿ#T¸ÕBí"›”ï“’"‹+QŠ!m0ÿ€ ò{¿ôHóI)Q[²*˜•έA &ø• ™«ež‡"Ó&ì^)*$®au=ü쳓W󺮬¨·”6&»Re'ý`Œ~)§ MQcÊKÚIh*…ýÊN]äi*©+)âüV4H¬R«U'…Ù)1\c(8úŒkbç²ÜEZ±á渮J¥ž­4\ÚrÝV[„žìâᢥ‡—‡Às|æD²ŸTY,2/ä£NÕ0c}$¬9ç€ã´fT.ÇT±/¥R)Æ Eapò2 BÂŒk=ii('Ó„1ŠWÐ^TÙ]"xas- UÛÐ`®’¾‡SYÙkü œ6áê4¦Ÿ°¡H_aJK/3KE؈·øRÁã¯ïµbæ¤*B"x•‹N3å²ÎÓ¦ ïK±‰4#› à¤%RXÀT`ÇO®É;Ë–O\)I‹#ê™0\™ó}"žÕü—VcQ_Õþ +)Voÿ ÉÙÌeÖ@ÜÔ*&°×T™´:ˆ$”‚´ÐA^èú=|º Á@ ·=Æ™,QXbgLœ¶ÑxMËž^Hí¤Ô=Iù’HDQWF@fÑ·5EÂûuž’³¨ååênÃæÞ*CLDò^žb׋ ^€ÿ_‹ì–ùÊkZFM¹°M¥ò(0?rÌÖ¨¥nìê9Ú‘b•øXeÈÏá®&-v©uýÉ€å:íL ýžP(°¸Åš!&H€PZ­ÆæC@À •‰˜ÖÝû¤¼mÊÝÔ–Ñ,æùÚh?ùÙJŸÙAíý@FÆj28Ì»E(ÒeS’Hâbñˆ2ðUy{èF$BYJ>~¿%Ï»U‰Ñ`=H0ùþ0ê#* Uf±"ZªiØi@ÊÌV¨‚¤¸YÓ1–úòüìÏg?oðžFøt’ÄÈþûäê싇gŸ=üfssýúéÙgݰ³Ï~ÿ÷ÅŸîÃ>ØüËÙ—7b0›íL9+àšõÌõ0¯Ä÷™¿ùÀª%¬X†TÙÿ]¸ÒQs ‘*·{0vÈóà¬n‡dæÉ²¦â[ƒl0É ¼QÅG©9Ï,žÇÎV5‹SÔ‚“IĘӳzÚ C=<¢(Ub&¬àΡaÔq· ±©f#˜'ŽoÍ ?ª|RFZªÍEé=ˆµ”ĺ²tÇ:$tP-+ Á7tÖ'NàÑ–ìH¼D˜âÜIJ&¬™2bq‰rh÷§õU#§û¹×‰_HF’*Š5Ít Tˆp‘Ž>s'W|ñ«V48ïÊ­€^ ŽÃ$”M´ºJ% 7¤1õ2ð°à’*þÇÍN‘”A4¾W8oçå¨ö¼p,I/¯ —U-ãÏeR½ˆì@*³½ É nì ÿ·ó‰e«vHü òë×`‘À}Y8.ôjœß ±³lû¦0çá¢Ç "Ë ü‹m¿ÄÎؘ:è‘0À³˜C2†¸yø. €_NVõë!T€&ÉZ˶meµ©u4`CTªºð³#òýŒW—ï‰ÊÓRa7Èî,x4ÀΜîvFvóFž6­w‘`ò[ôI×0äèÀc^1“ã(ôýED\7pµMf[ąºðã•ŒŠŸ×ÔK~Ü‘´ôIíFÙ#E´í*{’|öñ‹05ŒÒï(·ª¡d˜»âƒÀåå"*íB¨‹} ¨ýJUù| ìËÛ"}~cÀƒD•„‰H¸·;‹ÈSø5EHaÑYHbÒÆME"|¼O,ÈÂ#ÉY›Ö£ÂLØ#$ªLÐ1¥8¤Ä[¥ã·!{ÁªLcN(H:ÜEíöp úr€Ì<ä¬ûíœLun,Ìkt¨tÕW csF¡_%„E—àˆÔ–¾=VĪbX1'ñV.Ü‘àN‡Ð‚äoþsñˆÁÒ×·˜¿’X_ÿøóÿÄ6óÿ¼LúÁⱉ‘–G²Aç¥í—åí£ÛDƒêWY6¢í ­úëR$é³/ËÛ>…þ»4 «þ¯–X¾Á·-±š·Ýl豜_E}þÅú¼‹fœk|âG¥ºM¢ó«n%üM·íWåí"àß.m5>¦Eüë”ÕØU€/Ì´@³,“¤ÇnÖYÑÌJ/•óº°)Iž>+Ÿ/>kÒ¯«Ù¢ÛäE``,Lp(zy£Qz‚¡¶Íj¼%ôh«0àŸÅbö¡E}Iä—~â¨>´Ä5÷çrNUŸXÔ1l’î6¡5É«r`{0"C§<§cuÙqú<“ ‹ìØÂ—GŠhãQöý³1eæ4Dëù<‡b=ϧB…õÌôR2žvfrs—9½/¤Ð—Ý•Ôh{É&ZF:ýŠ'§¤öø˜.Σ®Äd‹¢x.`ys•oQˆ‘ƒ3?[sÊHŽvFw‚ _`GÜøe!ºn;pãÌGƒJr…»²ë1ÊMp4AÂØ`´¡×qZKœïWÁU×àӤơ}MKz èDZ·_•™öOæÒ‚t­öœû+û! a¢¦ uðïàÊ Üñ‚ W¤1ñiE.hžòéýtfæ…5AèØ$M|¶ÚÄ+fŽºÕÏ”€åö§x;³¡*€1„Í\˜*oMl‡<ijÎoS§µ„u@òóäò]ÀDå~íousáÇóØ•sª†žœn$Hì ÉS¤²Ÿv¯&5Àˤ}®ôGz³²û]©KøðAyKxvQ«Žßžb¼( Î[mèß^vñ5 N|‚ÿ-ò`‰ÔúÄ»àÊÍ!DÀä„mñ¼kÈÜa ŒŠVHJ'*%Eí9óE}¡~BWåY4_V;Ç$+0" €VTŒGòH <ÐN]þîaì4uGsÛøR€©»fò)ÞÏ#ã¼Ñ•c)Ú^žFò’Ëú Єgyçä€ËDS´•Äì%˜eùv È!Ã&n;&Êqµ æƒY²Ûèü}Ú;VwAZJE  ‚Ñ–Õ%(iÜ&|ÎÁüóZ—–¯¨Þ°nŠéMW+-åMÛ²dàe´I´‘áô5Ò‹TK»fÍÒ]LÆ.Üõ12mÐTEýUM‹êX‡1ï‘K¨–"ѨbÔ<îÑ|c–à•g5€=$kP¶õ4ïç>?L®mP á-¡Hºñj¥NÖ·L´)¢É©¿*Â{dýLîÃ"Äú'¹å¤sÑ—¤×6ô½¿¾G¾ç«fF]dáä³—Hq"Ñ‹Ä~…<ÐÊ!Pû¥Š¢Ë¤U©[V– WI{Z¦½Ohi›+Tºù(tÿâe#‡t‰“°£ä塾hQrZ%ǽê}ÜcõT·YùˆÙB&¨kOÍw£€ò9Fmd÷ Û` âökŽÑ;³"1'8 2¬Dñ˜•áô˜UHû—8za݃X@çr€µïWÃA0DýªdUs³ñÇ/Zä;èš;*äÂÂi[|!¶¡ïº ç¾úJeÅ#c¬õùö>‰¤8ú°:òÙBS0eå$~4ßâ~¬:Faœ[cÀ«›x}3b¦ýýV5Öwtr<\H„8jÍ#¿1ðäšKÑ:¶†¨Õ—X«°G„Ý‘"©Òu]h:»Kš½¶¹œÃò'¼‡^áýæ¯ÔBÄ<¸©«>!žšJ|ÀX "5Í¥Aþ²³ÞÁ½Õ Âî~‰ŽŠºŽ×©‰Hl±<EÊAÄékU7£È4î»cå°\!š±ðe{f Ç_òÐ>©.$X¥Þ$À—äxó‡½Î2Cu}Kê?):€·8@øŠSÆl¯ ,–Êó2'å3Ý÷ªéžâ*= × ªrÓžæ‹kFƒRñد¹ELzg_èÁa‚î¤[§ª49ªÑG¦ö/W­"—|—ßè8¢œÅ„ÑÛ“xÓ‘Óe%¯X¹ƒF8=±•dº²ÝV}cÓ¦!\¨r‹>^ )6‰§äqr;^McÀ ×¾id•"8.›šÈ+àðOY“g—×gÔ× è­Ïéî9ÃÄM# xRÍŽoÉ ©óñó}ð x­¦æßa èÓ•/LÖò¢v[[Äo•z¢à?ü®à÷#ÌØñ~=5Ñ£•ï˜Wä >¤ÜÖ ¿Ñ’&ÖáyÜÃ,†Å–6#H;kõßà~·ÁUi°ð¢WÒ–Ï{éО)Ú ©*„p°[U0jQÎŽd* R‰2>*ØÑ«?ÌÌÐoЉ˜äöêÆ€Å4ÍyÃxX³Ï[Eòj®‰9ÇÌI"ÑÚk"0é~ ç ¶Š„‡Å 0àQ¥ƒ$$lu¹,™XîÆ[Ä, LôÛSIŽÓµª”Ù4û Š÷®Q&–ox,'^nÙ¬ò 3ôn+ŒŽ§@Åu-äaàÈ”ôvð{UÀãÕ™JÚ½]¾vã®S`㌿?J+Ù0©]\±Ni–ÈÒQlx{oÁÐÅuõ½~Ûµ „w×yS†¸7%ˆµY9ԘΠÿDúnΈE°t]e&†øæ;•¾RD'xSölÎŒ·gØ<+æùÙµjs7ÑNÒ”y—t\©êzl‘F¼Xµ4DŸòQB-b4XßžcÚݯQ¢ÎÞÅ`±hà5ðî+a4¸m°…Ê_ŠõÌ3€P(ª%ŒE¸¿Ýè,¹ïå2þ÷|Çf˜œ /J‰Pÿã± õ.vVÎäìÿlCÏÌo÷õ\ã¸H_Iˆ?áš íÀ‰Iãþ ©Â­ˆNÌJwoáÉH't6 ñ£ßŇëË;þÉ ¯A¨•CT´Ç'#:‰i˜L:F¤ ØøSy|ÊAòý*ÏwÁªV#¤ñƒ %gxûý6«‘U…¬x<—pyKv-Rä ÕwE«e0lVû‡:¼TAº"“ßïR¨–7èƒýU GÃýÁ»bÀ³lå Da*/\ç”þžK"æØxa‘IŽx»ÐjÜÅÑ•µ¤ž±z—¤Ý¨b´Ò²:›³p*Ó}ᨬWþêDXÕéHÈÇ[Ûpa1«å½gþðsU)`YMN™{ÚE•[‰'÷«Ò4: Á!ð7¡ŽùŠ&Ûz*ÞÉ¡§¨æ>â%/ùn¦ö¨h2Qi½ùâ \¡adˆÍ|€¤X¨*Ýõ±®OP8¸¢äM$gšJ}@À;¨q<ÚXŸ¢žó8WkI§Þ%žèÉýUuAˆLМ„ƒ‘kôúËÒ‡ø_X©Ñþ¯H­QOWòÓ¦õ¯Q ±àCïîëÿÕ+Œ’Èg·’<뢜ÚÀR1XÞ ž¿'Vëþÿ|IÁendstream endobj 96 0 obj 5978 endobj 100 0 obj <> stream xœÝ†óžá?¯ÆA¬Fü/ýýá|ïà[·:½Ú£Ö•XýÇôõÓÞÏ{"ýcL½Wa€Ð«0+­^¾Ø©0ƒ³£\YïV‡ç{ß­/7Â"·~»‘bÒˆõÉf_ Öaׯ6ûvÐ^‹°~·Ù‚U†7o_oä`L°4N™qίKãÙZdÞÓïÞ £ë£Í¾¼A­Ÿ—WЧul<[Š ú¡€øWõƒszýb£ë78©R¨õEùL£¬JÚÑëõö2Nëtõ`ÄŠ&£C…j®ãòù5|ç•Rl§Ó¬ß¯i3^…õ÷›iÙ~w€zgׇˆY7Ž>£+N»Åɼ‡æiøúÅ;{ÇVÛîvðƒSƒ ±/d2¡Mü—ïödа+à Ãcà™H‡ 7»ÃÎ1Î% [z¾‘fŨ×ï±ÑÊ%¢Z%Cb °OLÄúN¥”Åú²,ìhÖOè¬ÇùF`§Ö/ã¬tü÷‹jµŒ§‹ Ä×þf_Ò„Ñã®÷Ó¶÷…Œ ÓÖ &Ô’3¹y€­¸r ‘=ü ’ûš | àK£màœÆœM»%!ƒ’ªÑ ÖÚ¾€o¥Ý¢Ò€Œ -=_qxÙÂQ‹wI$ôàuâIÜWÑ ÖêàøÉ£¨@ ’ÞYâ€Àå€n€˜ âüsÀ90¨—‰üIý¡ ˆ6ü” <ÌÂ4ÄEQ+ÇØA­-vnÄm­¿BZƒlI­¨½Ö ¤²†zjKje[ð÷²@¼cÛ+8c°Ñ&’ ¿Kr {­_—Æ؈ºY³Ag’üݸæu"„Sn¼F14½ê’­´Knµ˜sxÒ…R£6sœŽÿ‹£‚C\o[ŽjtÃ`¤Z³ʲ¥çYÚ¿a·‹æÊÿ¿#†Q" ZgÅ´¤`;°â6’DéÀº2Š1[—·.p’EÞv" Í Ô=_5zzÖ¡ #]ƒR+uÑ5[TÙ#øÁ.[ÓQáS” °¼ ŸØhPñYüY+ÿLäñBˆh=âøÆpÇ©no·§åû,ªRÁG2F¬Ü ÐÔ`Þ$c4¦QHfÅB`¿_ž?ÎØÑƒ6’#Ãíã%—»}é-0£k,bÀ‡¾~YæÚ€¶l‰Æ&ÒÍ:4ŒÆZQL@KÛÊ1 ª“\%ü¹4ƒ®­r§¸C¥—M.‘[TµQ©IªšqT&}ög0VFIˆ’ÎD Bø¾õveaoÊôRü TTÜ“½ Ö\ºØ»öiHþ(ÕjêÞå4’. 6ÅáZ(«`ÓfýãäH’iã¨jÓ ,|ƒ>.òrYÄ #tmѶCkÈZ3¡áó¸‚*uèa ÝCðÞcþ¤ÝiÂই5ú/xXcCŠçÌöñ*îÓ+ͽ]FäÖ®‘Hìг%Ó"–<ÛŒiu*cÝ~½Û>/#™†èª ô6õH¤!K¶Ä“ O30ÎynQ-èqÐÒ®k÷YûAñ¶â0%°ý¦ì¡øu#$ãhùòÌ,§ùA"çÚ L¿²“®räm)Ò qÖó2 ¶»œÕ„=}@€©PôjçkQN¤K'5¥GÍà ÷ؘÃÚ˜ák¬Ì.ëĘ)MÖÇßBjÁ[AÛß™¥„@Û÷xw[Æ>W±·Õ ÷Hˆ+¼ÉN§SýùF RŸè¿èË€©ûv Ř øÙÖ[μ3KIn9 ¢,øa‘€#®1§" ‡»øLì[ÇŽ˜èU4CÒ~ÉvhÛçÉÖá"/*/‹þDÆ’ó3­Jâò¦LéàöÆ%Ëa ‡³V5ªo©¢ów0Ù‡´ìh4#vï7Ø]€Ï‚:NÀé®aËN…i>B¨!¯‹­q™l 0qm²DDµ1hŠE¢/·ãÖ?;ÓÛ*Ž`gî<£ÏKþ™Ý¢Ëž@°„K7aÛmÉç/áÈYÖ«n1²‰&Y3u{ļ Іu%Ž¿ê‡h…§&jªÈæ2YœQ‚ÄS&Ì*¶ÿ7“8OL<ù^Œ7ã”à3Nx”×üXç- šáÈßîò¦’E÷b“çO«EÏßCž¿½àý‚ëU`ŒÌ·BšßWåx ˜[S)iæsߪܨ¢1å¾ gþ[ªP±›v¹Â ÐÕï§t&'bIû©¾] @'¿|ý'e¬ø”'¾–| ÀòÂf–‘Ìñ,úèŠAíÚƒ—lìr* ÏtO©Jzpf&æÇ:Lu¹Ô9eêìÑÄUOÑžª"Æ^€HßÕ/z"—ócuò ô60.ÍÕ3m•J±fâ*åçn0 ŠIȜɖ,KlSi6JÆ«ÉçîíEäÑ/T 5Ú,˜‰”|ÒŠ ãÑ;óIXž Èi§c–‚Z¥­ÄˆB©Õá³½ÃϾ[E€)…á_ÂLNŽŽ¸O(R+ŠŽ«3q3£º“âNDòY`P÷¯pW£¾-n@ ÕMƒRá1¥GþŒrs‹˜èÀÜxE˜éþQâ 4Á(P«(c䔟p Ð'gÁ;T@—üÙx47@pë1—ýõ8¸N£f¿_”éO`zðKp: â'€OougÁ믓Òád/ì-im´Ú=nÞ‡‰ º°ü¨>:33=æÞÕôÙYê¶ìœ=‰ÿGì ì¡M Òß#›Xñ1,3`ðØÌû§€³ÿ¶‚³fgT½ÞÞ;5õP±æcósßÁ(fä2çì»õó×ènÚ=1»õUÞ#³ÏOŒîÂìçî–„¹{d"ÌËiPÀöCX=Œæ“@ò8ówí"í —7îÕOê»Û3Ÿ±¸½ñ˜½øŒé®: Ý“`&¨…±Àº>˜jj%R¸XÉIa@…ÄËH…1ø¦¼ î3ì³{ ÓÙXŽYeÙâÉ+.¡ov¼¹Lo8cÿ=Ï÷¥F˜%E~ØH9èx€Ñ0oªnPmÿ:»»€ŠŠ©/ÌÆPéðÑ#,µÁtÇVJ @ôQŸä 8T³¤i7ÊKòþÚ¥øâ5™^U1§x Õ5+‘ vu(Å•ý뽫 Y ¾Lt¿7+Èk0·­%/Åç¡×Ìç˜ò¿9ÿ8Œîƒh›Xÿȵ+»ºs¹¤£ÊqB¹DrýMº‡·(—¡‹Û¥815pSº¥ÍñüB%6“ Sîq× ‚Oµ@‚˜)`—åªì-¿J‚üä4øN…94ej–Möëø™àׯJþƒ {˜ìš¥Ë“­9OWâ`žR{ßnèªöí_7ÏèµàZW¨ƒµ+‘Žó×ìø–ªGý“?·d°¼!¶:‡–Ë,°h”s+ë{š:8ÒÇSJ³ÒzTZ_•ÖÏàJOÜÛë{ZZxfKÐg†šâUiý, 3X‡1µ^µKÐ0T6¹ùoÓ']&­rIóTضˆ—Üú?¥õ¼´Îoû".<ÞS7/ñuiýíÔJ O%÷æóÒú¦´¾XÜ™`h‡1úÿ¶B=¸]1‘{ËÍ0„\•ÖÓÒ:ty•AÅøäewµ‹ÒzÒm}]Zÿ¸qX,¦MâÏ´ÆA2fº /@êß§‚jõàm>)ã¿)ŸßN}\Z?/ŸfŸØ÷ªE2“B&ôÔ÷b&øÉèx\ú¾ÁMhçEÂýš oÍu452Ü2Ôà!–ôŒøûEð’Þ:(zë ",ŒŽãžióŠNY{0wUf`üwVÁ˜uÜ]–`¼ò"/a9ö{KØ9;²%å/».f8mH9é¹À —]ÕÉtœµæ›¿*{;ªÀ¡ ÙÀ[_Ï>›Õ¶­b¡Ï7¥ïë²´¡ªŒTX­t±«Éi]Q•¡|W:Ô{Ì­w©Ð_cÁÄ™wÑLL½nQÐê i³“Š|Ö“±Ôú¬«ÙØnÚÓça—Œ¹Ð®+nÌö&3$>X}÷‘ÄÔèiâJp†&Ì<)?ÏT'µÎT'µÎTgk?©ê¬¶›O»è¾£©ï£wæýs£·ÚîÍèm<ý—ﺲ×ï;ÌôϲWqÚá¬ÚâÔÌ%ò/ði J‡ð‡9»ÌÖž¹–s~{Vd> c’ýÒúû.áOJ+#ñq—¡Þ”Ö•Úïà ¹+<×çh¹lgk¹¯ÕdÉê”Öƒbõžµ{Ο٢3%zuG`¦½3ir‡'-¹#ÐK&OÒǽÅ{³Õ>¢ÛaRᢃÂRCCTAË:ƒ–Z¯óÚa µmæáÚÿ%6¦›ÆÊÑqäì› H·¹Ì0Yc@$žWÁ6+—ì'âÍâÇR9W`7Ý*¼ôfýJ8Aõ ÷v¥Œt×ÁešcQ–ÊçÇžÍyQ'ð«ŽõítÂwU%Û¶=ر:)ì¦zOÒF®zе¤ëãó)U4ö‹"—¦­2Ü”«î&{ÙmEð#UÀ ›Š^”Ìœ1`·+µ²ñš¡²`!Ú¢É,"Í{$Óyf_óe@îGÌnHµڼLJ™ò»œmÜò*Æíʘé¬~ÿÅ'x7Þbè¿þÓ=í¸íÓuwÝí$CÕ#ƒSyluÚïQ¸d÷€©†ÍáíeÃýÔ¯–Sç…;‡rºsx¸Áª¨1²Þ´ñdfµ›F-] ¼•+—_Îùðë„ì¶x~èbV7™çׂÏ¥zm~kšìÎiðEÍù=ƒö¥;ܺ›Õu®-ñ¯ƒ/Ý"H¥ÝÇNXÍ…¼—ó½¾~Î`™ªöiéØ.󱟮 /àMn^Ó£éù v=_ôx)È讀ÁÄõ¨¸`Õ+±úš.†òš«-ù)îùÅÛpÉ~ ïñ¥ªÉ†Cx†uMbDûö1L8^±Ä°ÏxnÂaQ ¤°RŒêÎéõ-À-ÊkW Ü(Ž ‘š 9—ŠÞ¥G' '•³ôÄðð&VÒYº|†ÈC EŽ#>ZƒOƲA'q¥:ðõ#LÐ Ob麫µƒ„ŒN£ÓÃ3¾ Æ~¾œG(­•àŽ¼72Á£éå\ë„ Ã1PaJ ý%H ûl ³A™k!£ª½»@†¿Î S £CÄÕçäŽÓWºG^Ñ{ŸÈfóƒiú6ö ‚þ¹)ü(â5ÉÝÞ–Õ ¦Ÿ#€£–÷Ah¬â±>iã4c¢´zýcùŒ£Àždx‘)Žj¨Í,æ šÓf:—ˆI7ªI-M*i\ÂÿÿöU.¼endstream endobj 101 0 obj 5426 endobj 107 0 obj <> stream xœÕ]Y“7röóx#üúÉêÞàq½Š¥MY»Ú‰Ø‡]?PqÔb“Cñ”þ½3q&P@wÅQØ¡©T‘Èã˘Ÿ7lá†ÿ¤ÿ>{yñð;»¹y{Þnøæ¿ÊÓ‹‹Ÿ/xú–Zo¾º‚¸ÚøÅaÔæêùOí9ó‹6ãìæêåÅ?¶_ï8ü¿×n»³»4‹rŠûíÛÝ¥ÄG»}OB,FÁ“X´ö†oܱŠïÛþ?sµ8aÉï·»KC[nðQ/Îy/·l*nÄöåN˜íûÚKN{QƳÛý«ÐÀY#㈒ .qD¾#¡Ç4a“Ûãwœ-†©íó\œURÑi"ÎÂà0‚\ ·í_ðwm4ÓÛowÜÁܤÙ~ Ÿ ΄úŸ«ÿ¼øÓÕÅ_/~ÞÈHÚKXéFX)á„j1wç«Ç³y÷æýÿ¾áÿŒÿúê/à?ÿcó/z¼ùëwJX²MW;'íÎÄuV“5¾iǬ“™˜–ëíMiðl³ÐÊøL?#ÝöY%%¡êþÃNð…y¥:ZKfT{Zz%;tôº@·d³ž"U³v:å„¡$‹u{’Ü/ Öò‡’Ò1ž–åyY€7°Av—l±Œ9`0²†W;¡&•üg¤ð[ÂÈOk_‡ = ØS8˜ °#ù¨vÙÛÉܽ……o÷ß d¦÷uÙµ-™é²C†ºäŽ•üæ’‹ÍÕuØZX˜ñÞHÝK–t‹ç®‘„}œsÀóu#û*±O«È‘¶·dÓ€ÿpp#Ïñ-쀲sAÇé(¾=Ô¾nð-ì+¬yÍLu{˜Öd.D*É ªv¨-³"Jß6-¡Sî=ù¼R|8Nܧ¸9ï+1k[Jm$¥p ª¯— 6Î+áÈP×.Š_m?î$[ô#60À×a[2©ÈĈ„¹%‹ý¸Uhm9&KŒûÏmaÐ/NŠÐßVZ·ˆHË 7÷{ÿ¬¶ˆ-2\‘u~ñ î„`íàTR›öÿÜ•É>ˆÂÖuÉÌði\ÞŒÿp:6X ˜Ù¬©/Ô9&I¡=”q×0 ’}_ûJ¢ž¯‡³¹N³Ñ*onüœXã}‡ŽÚ4ëͲ‘ {¦€Pb®‚ó÷3˳·MůïÏryèGYPǽÌ[š(PUáxBºÄ%õ1ˆõ²»´hßAÿDÈâÀTSÅHTÉáW¤|ÉÝxäÌ!º˜)›Ì!D Èö 32ìâ÷Ð,ÙZUXD>»¥Ÿ»A×¶¹0yòûuwÀkØøÇ,&Ô ©Œ-LU ô¬r3Âù¯†œO>«‚Œ¬áÚ €JFI{“ï‰Í:è6âKTšjÝõ‡:…C£¶sP”\¬nLQ»SÁîWvJ .4ýj¬ W°€Ì mIºB¤Õï×#ù¥£^gr7sj„ D–9èjMÏ ø=‘2ÁüÙQ\uHÈFxæ»àÂÂÊdK|žÃ0æ]TØ o,]³m#«ø‡úöÕÚà =U,%QkNˆJº"ÃðÐ]ÒµWìucЂ„G{e»8n=`‹O!¥æðý†¸WÜ 4ÃaЍX«'BV\£ùjmqž÷>_í×L·G”ñ±øž³ùZ©‚óxßóµÀ骙peØ¢Í9At4ÀYºâÊŒõI«íŠ+ï Và×ävôIÚf…a Ò EÿÝob…{˜ár˜²²L†'+ªß·‚¯”?ÇDÈgP¸å”am–Ö•¸Msɳ=ê ‡¹DD¡/¼x?Ô@+\°òîF_Qu#ùÅ‚^8û€tYP½žíñA#-ÕÜ4„–l½ÞþZ]ûËW‹•ºS±­ß‘(Ý `b‚ɘ ùiå·0QÜï[P¸÷:­H1wB ¬€-º3,^µ€÷æ·×‹þ\·÷Eª~Saòg “KrèZw)h©Î‰æ`PsŠ>~.F"´:ÉÅÕŸÀ=zøÛÀ|AþêKpÆœõvsõäâêÿؘ@3YØx=°Dðµ ÷H6XŸö%ˆ-•P÷%?îq$Î|’gCà~e`WÜAÝxä»üEí—Á”t2}¡Dîøìž¸aë/6B8íTހ—€WŸ`ßZ¸@ü]qê1·|´ Ž37š ýj¶q2‰7¸¦¹­Ó9äéD:¶†øÁ)&2!¿Âiâ/ç%(ÞVúˆsˆ[•”„æʽÇßÅŠš°=1TŸ”—‡ëô•Þ¾bá8çƒñ™¬ã; Ô"ƒ3î:HœÝ‚_«°u@0²êž°-ɬ_ÏÔ`^àQ5˜§`óºlqÏâgíºŒÀ-l%Dz¾HÑ€–«Jà{`¹cÑ$œö§“bp0jòâJ€»§ ®yŒ.ƒT6ˆL„ÓE;䥣ڛÌ*7Í54=ìŽ ü¤W²äaZCŒ›¦X–¨ª?Ûà ¢á³/èô8†Ö¬aIl¢í{ç{f-,ßv®•'ÒÄ„ `ÑY”“2pp¡ Áý™²óòRCH¢«C/úÙð¦âÖRq"“Ù½ûlÐ7&­«!Z¡Aã·´ÎýÈúÒèì«äz A'Ûê6 Œo…)ò?G7 ‰AÜ¿=ÍQéû¼Ý öu©¯«ÈM ‘Ž; @•^–Ì k p>ØT\ZiPÀ–ÉÆ`Oåm„Í\/È…„Í©Jä5Qï¤ ê  G:—(®˜2Û•÷‹Ÿ="щ#µtžç+¾ÀÁ mÝL€büM©‰ÐÔ¯^Çxæ!; Ô€¸AÀ rA'˜C×bxŠ!j>ZäpèǦF’?-–$GS=òì°)H‰6‚ô4”¼Q 0ÓÈx–ƒ¡& ŒzØ8…ãT8ÀÀï·™&A¾ÛgƼ°Ò¶Óhì¾Q€¹³( i]ÅÌUlâè¬boÍÄ(ûÖ¦§´'1±¡ÅÀ—à?e'™Œ„y<§/Š%65l–…Ϻµ ±F7F6“²ZeZÜaM _õ®utKt2BwNö(&V1Kñuî½ëðeì’¬yœDo£þ9Þ¥ÑoR8kä¹X„.lŒF¦YÉ>y`†Eù“2•R/‘âZô ºlS–9’í¦¡V¬–½¼mæq’„=b((®¾ÈKšÓѹ‘À)N}&¥°ÖÊxF{„Zœ%ˆõgmÂ!÷@LÐØ¸E |O¾x­ƒï ~&u™ Nž3ÆÀ7[ C^ð .)`Ïí·øl„BªJxö—ÉÑwRÁLC'´@ïˆëœÀÌwí©6ýñ² Ü]}ýËU°Ô )¼GùÀב¤[ˆôP;¥ÜÔç‘‹,#µw‘NlZ7©¨6~sߟŽ¨Þ½©(c¥X·žöv -rå‹hÔÆX- ó•dup¾Eµò숦$Ñ–×Cm4®'XáÁBâD Y4j® Ci—¹/ü+¶D]%Á±›¨=šœ¬×b+º`ß¿4®*²3ó 7Ú¢Z`$¸¡ßb%`˜ýÔ@-ÊOEÚN¹–íjM¡L ä²f"IMô¥ uöªEÊcež„Éf~ù5Î@ÁvÔümw0¬Vñå„&÷ÆŸå (;®Cå¾SL2 zݶ°KÄx¹+U“ijÑ;ØEŠºÞÆ˜…Ó"# ¶ÇLF•Vz °æ8kJ˜Ÿx‚9R&$­„©²Ý„Ùi¹)yM=Rj?/ Çh†Í5› 5ã錤.ÉLX‘™32sô0FÓìƒmtÙÃUÏ9 úÁOO¼ §eÔp‚Q6®zIOÐ8{‡†Ûðh½V!–Þ>ªo¨o_Õ·ïâ£eAŸå·Oëã¡>>ªmÉh/ëãëúx[Û¾ÚÁr•u‰#®†q;j;Ý\`‹§ï{s·‹9¾·N©†‰åídoÍf]ÓB#Áýøá+çHcËwe¡•`MF¨Ë¥;y£Pv D¨PЦØÇ…W9˜B°¯&¢~Ø*Xÿ´^«3Ü) šô?·ÛÚ“XwÂ6(%V¬kÏÑQ¶@ŠYTahUýŠÀ×­ÑÖ¿äêëúö›úøv(Yß ;{¶z‹m ë}~ö¦´±žƒ=”ÞP+´tE¿(Òã¡ô¾¬^«öNmÅ­• ±+ãPÞ>¯ûžÀA2ßSò€ù°Vª˜Þ•—·=!g2Ì9e‡¹‡J/Kãå$’@¸_Æ!Žo³œÔÎ ÓKQR±‰”ÏMŠúôJ’Ü jѥœÅ3탧åï†ö›È¬¯ÓùË\&˜s HÏÂ# Ã(BNC§£‰cWåz—!“¼—¸¼A=&kzJm‰{ŠŒg4&‡æAqD0[Ÿò¾V5¸~˜Èz&¤•FŸ`ìEˆwcÿues"‡8¡À`¿`lûb¨‡®W=têëm+ì&–´ƒë[^=ìâI•k,-;‚¡ðœšëÄÀ*aŤ±Co ×Çp.‰•#mºYaŽ^4yåݡ͵ŠOì7’@*Òu%Ö!íÇýPœ›â†òö{¸Ê!]à½V½è«²ÍM™ÉRN” cQ°É1‰Î}IÁö›~rã`U› %¥Æ %¼*&REV›2Á¬)¬é£éá¾ êXJ—$^*N$¦ÐLÉyV¬Õ@1ܧ¨2Y)YÌ8Ó5ˆN 1€~¯zÍ…P½,´¢/sN….˜ Ãé¡oí”clY˜Ñþ²žy>H©w•ª puÒLàiIÿK2ZWI‘ Q„çinsµ*x‹Æ²5âèÝÙæb²sHûSqýaIÞØX!áAP “Â÷}ŽèêæðÏ8“6:ÙÖäQ…å`›I Ý“¸ ã<7z?âJ”m[†µ4Ï3Ë>ÑÁŠV³FÆëJätÄjáÜ·ñ6ÜÌRÊÎè’g†\íIÒ òü æâ#<Ö`¨tæ„)'²„o‚Ó_d±v•}êß*ûÔ Ú!×XÊ´ØítuRáÚ‡õíGÂ×4gÑFÌ’ÝêOl E g”ŸP–lÉO¨fQ†ô>9p‹¬ñKö;Õ°°îÉVšˆ—ÉÙ äúŽ«X3Ÿ`j·æ£_ÐÚXPNFºé«&cŠÂ…ñù#Yêà.“òa›Šà’½¯…?£SE­ú§çšã1iº,Kµ˜é×Q¦·©ºTJ/èå”#ô¡‚:¯¦ŽIª' óF2ë×Ñçäq úŽüSUi©´`;åÚõïkî µRQÜ(¶b¾ßŒc,ãÂÎ>é)yÈVÍf"ûH~gIÛ—ÂÓG¤ê9N¢É#u=[4ð¶c?£ÅTMM[ÞìOht¶*‰`#ñÙù“®ÄHãÊ’þpS¨$µZ¤Ë¸Õ9(ôÃóm:þbí„C;²œVöù›,‘ãüÍ5,V…„¼l å¢sx–ý½ÌK-V,‘ÖëIä÷M„ã¶)©ƒâ¡(»ôÓ¤$?2NMîEXG;'ÿh‘¸i’2är¨•[Ô ”ÒÕ²¿sÎULKee-”ÊŠ{-•ýˆ«aÒ6 S¡¬ó"ÜÃÁFUÞÎÊgŸCïVȸ¡e!iRJ ÒÀªcÀHOé=ýùºö¼8eò¯F JBÃÝ0‡Ì±Ìux$äé;:†õ¸E1(ÕD…º#ùÁƨ&éG«;Kwµ,-ÀÈ”¯WFã9¿Ñòˉ®\Eøa¼!ƒÎËÙ%ã¡V¶É0ÆÂu;«[è´Xœ7Ç9ÇQYâïO}•`~rÓ YÏ8°EÃ+¯Êå/ŒžW‹JP’nšfB@œÊŒ¯‰ô¿_Ôp—O€ÔS1¸Ä+ª¦´uR,¸¬+,9|dµ™ä‰²+*Ç'ÁZNo=ŒÝ KÌ$¼?; :NXì¼J7öžm$\Öd“ê™Ìд - oÄkå X#($F„ÆœE8púLY0^üô@õóºa-Óbµi÷ÔËñS¬Ì5‹× Øêί—g’OøV2¬"àq=ú0¿™qÁå&t´53=ÿ •»›;3g<º1åÍàK;ß¾tq¨À¦*@æ'|G§ÌÈÏãè8™T^ª?ëð#º‰x¶íÔ‰—(üÞi7QÀ“CÎMº.Òj<+²€q†­¶‰•ŒYhÞ¦Ò‚êçj´ ×``2µI~ï_swÈYØ‹t ˆ—ûB¨¿¹Ð.r«¢‹zŽSÀ åN^ÑRO8§,3™1±ŠËvL›NÜœÝWÜØ>Üž&O_§:¼&NUëšSófrJ=·Ýûeé åùñUB+â~Öß'J ž5øŸO)A›Pv3Û’LfL$ ’o‰Iã#ôP ÀÍý×à8Þq.ÁixtÀ¹»kÉyùý:ð‡¥V±áM[%ÃçÏr”ÌBýµ¦9‹ÿÛEÕd€(]L:J&¬ W¨Loz <¥%½!'è0±DK­ó%Bº™ê!m¨UnÁm4CþD)"}UÄ9Oè·Añ¼êö^šª<¥aÆÇS+õ{·­Õ«ß:bþEoäkOãÛS?/¿©¨o­yð^>¸’îäÍÃí¥Tí¹´pÝ)ÓX—°ä ]•jÁµb:îOáÌÿaÜØ¹1"«£’ëa·XkÝdeÆ7KO uÜÏn˸‹½Š8ƒ™OÊmzî“Æ­ãk …%¦+ï`‡ÞŸ’¯æ`nª™r¿éŒšo®æ=¯üÓ0н¦eºpå”;ògðhøTô‚~¬êxºìŒëÜ1¯ð2±õÕSÄc2’Óã˜ÝeY_ÆÓuÒ̬CìŠÇJëpRF4µïÇê™pZ ¹ìå®ýa]N¼JÚ¼Uq@R,Fî³F§°ªÒsq‰ÛÂ'ö$o6W­häËYu< QÒZxÀÜ%Àêkí{ôN«Épê=©x³M<»fHüf\|Z´W Ç)žqß{­AèÒõIWJÓôÜy¢“Jˆ „Ý0»DçN.WÊfÍÏþ¥8Å=;·Ýéh"gaüïØÕ«ˆÎLUïÆÊÖ@ä´Ó‡¤Ë1cK8›Ê¦¥5_¢#QÇϬá»K>V!çKÈÑŸ#Ô.<Ã9j zºqvB&kžÙYçðó~Îˬ(O¢º”þ42Bª(/[d$]¸ód„÷1k;$B;"#´ÂîXú5ÕŽÒµŒ 8ÊñF-¨O4ö/"@>uÅÖår=d(6/€Ix¹_ý3KM¹ÍB‹UÁÿ¨F­Ìð<åž®Õü-¸(§7;\ôÉææ,\dãvçà"íB¡Â%8ñÿ  ˜0,Dµ:+Ã) ì)¿ò!5}Ý.j°|žYW€¹TÂß­1ª-'ÜYþFäGµ°×uÅGƒ2âQ**Î@èæât[8¸—\˜RqÎI)&çU)wDR¨½Žý¡¼•’Ý{ž`|ÑÌYPª#û­ºòs碆Ũí=ÐpMeiKŠñýmùB˜¨ÔÓš9ï ô<ýâY”ÞŽ~,D¥Û¤Ôêl²C·}s©ó Ôõ>$ÜDUèS.£`›ø÷ÿ"¹3|endstream endobj 108 0 obj 6406 endobj 112 0 obj <> stream xœµ\[o·îóþŠyˮѥy¿EXµ[· 8ò… ­d5»’-ËMûïûÎp†3Ã_D!@4{†±ûDÖ.hàï3i“0eKW@\ËÊ(‘[Pê#ââ%A.…Mø˜¡È+ 4« ÑÈJ†šÇt Óú¼…Íy+X— # ¨—mýÕ^ÐÍ\¦¹ÜS),÷JØ«y‚·ž* íC ¿1²A‚ì3õ:BÒ¬%ˆ ±eíÚÅýŒÖ¢'xdAîò¦yÒâV·{AÇ%˜Ëd:b÷JØkGm s¬áݳP€ÄIE@çÌÖò6wé,š<Ímwh²•ƦO³Ò3̸ŸÉ7gy•?sµŒÎÑÈÓv3±`B\I ‚¿.fni?¹ig•!]fÐ݇vÖ˜Öb^O³µE,³ž6WjÚ[PO;ò%uÌÅ8.*m–E=’õŸŒ^5¡N õ†TW©Øzw©-m€º´>¶ÖsH7« éö©±Tí¬1­E™ìP2|íÆIõÒ¯ ‰¹s)§2ñ„JØ«ÙÝ)I;)Ý€ç%*K@$% aÖœ«,µMi-Ú}¾_žv¦ž(õ—4q\‚¹ÜI¦#v¯„½–Ý5W‚<ªON %zÍñ|Ò¥§‹RnBfÉâij·ñxp=Mâ/h`ÊûL¸‰0eSW@LVÖ¬{ÓǹÃáÜ’WÔÒˆFÇ7o¬”,êN0Gƒ´@ŸEßM 8©ñÓ¥h|BhÑÒä¾0ÈÐÙ6Vö‡¹füÏEœtÄ#j ®µòAHÇ|“˜ɶ"pC;‰%HÇM tLZ½HBKÖî'÷ÖÎÐ=‰µ Z˜ó?q"PÙÚUPWkñ„ äF–+TŽÔ„ô/ÛžC(úÔPÄ)E€ä¾–#…ÅFfLeyw§k<⼋{¶ø]°z‡7WÁŒý™€yŽtx0W+äh',~)ëx]USΕ/†=È3¡²XÁusCgØžÄÐÌØŸ 8‘çHõVsuCã‚sfi­ãY¡Œ›9¤›U†tBi…þc$D?æÓö¶’w›[¾öpÙ“Ù;ÓÄ\‚¹”S™>aóGb¯fw+-³Ž0À¡ñƒ¥Egr¬F…ìâWãlŒ?ôñÕÅŠøÙÀjîiû¶1SÖ…â'óýŒÖ¢Ý Ö·½•Á—§SFª÷„êv/hb.Á\î©LGì^ {µNÍPÕ@Ôy<0‚êÑ¢þ7‘–$¾öíñ–v½óvgFƒ^†€u[E} Ž>#îg”–»5ø··ÙjŸ±©^ŸÏõP`&äT¤#zäÕjt¬hM ÕjWOv šüiÚ$ÚÊxp%¸˜q 8g pÖøqqJh±HOga{“ƒ)O'ΞÊä%5Ì%˜ 9éH™^yµðnàgp&ã¡S7:)˜ÓñÂ²Ï ʱÝûIÇ蟨¯ôÒÓñ§ýŒÐrlïŽv³éÔªõk†¯ƒ¤ãNûÙ1®êñ¿ ªãRÎ4“Ä>þë ¯îNær¯h™S8eh‡<ãfÒ åÚdû)¥Ï:ÑM> ŽÒ£{"“j8Îÿ\êN¢OXüQ¸«5ìžÖt¤è³!Þú ñaÒQá !“iJhùC|{´ª··¤ÏV(8žÊÞ%-`&t’èHÛ^9Yüç÷„ÁT‰Üâ鈧Šù§…Ô>À' ZÐì¸QB'£óÓ[$3f-Aè+}vJmJj±ž0ÎQãПéZ´'žäHWI G¹Ÿ‹¼|€¯òz=ƒ×q±?f¦Áˉ÷€D{˜³‰§°:‰¦TûÓv¤½±u\Xö©¬]Ò@™÷¹´Ë'øj`&;·¯š&ÅÑùlÔÚT“ÒÑæîòÌp’¿¹H—£> ÷²z/ý4I[¼WïuAÑŽÓ¡æþ^A<ð¬èÆ wH'û»YñZ–¥ÝÕ½˜Lï,rX¼ ²ÝBÛ|ûýë55`…¾J/z,‰F¥ì ôŠ-Þ»”Â!vëÙ½Ëöt»Ðèïýø¢ää }âA4ÿìŸ~;Î…nèJ…Dã8².¹\¼Éáã…şׯ6ý¦Wv}s½ÙÒxÆúㆃTØj}¿Ù¢_ñZ„õn³Uh^¼µkÇzïÖÚlµ6èPÃút³Eÿ¢<ë»×u?ôd³…‰9÷V.´·h}Ôúvƒ¼Èhé×ï6[Ú*1Ütïiþ-I%½³jN^ÈœüPyD‘_ÏþÑÚè}#œ¢¨Ji0‡îKçkÝd²íe_!\ó×».Ü|iè$0 º“ð(ÓÈ’i^ÒPcIÿ…jX ËCj3ÕY§ ºžÀžÐÒç%­rºƒvÖ7™NÁ¤BȰ٠ɷ#+ºoª×Wº(§•ÎŒ“Yü÷ l§P e¶Ï^_œtf´ÊçÊ[ïùOq ÓÞk2ž{Ú¢ÄöŠâÍ%tmÉ5çÜš5ÛÐÅ^'Y+à(¶ù®€“ºÈ2 pcòf•²{2,a„Ó­âÉzèc«Éý&b÷2Ø ¦­rž‘žî2^®L{½fÎApØÐ®‚Ô.º¼CNðb4 eLAË™×DLQìÔ2gì^cúNi7õP(tæìÙÏëo‰-ÎdZ‡FØdÊ€%Õ:“1¢_‡X]ÙûÖi¹àn@Ð-Dáˆ+ehÏQ!!(ãʦE_41‡üÂjº´3Í\许à†Pö–P!’ó_wt1Md>ünxÿ®¸Š3ªå7²Vxp¤Eg>¬Ì`à†‘o¤ %©+Al¸¯ljø½ìVv·áxîÒJ%¼]>§äFˆ)&:gz¼nä¼ ºo‡Ç‡aìý=÷ÃãÉ”šGÞ„ì=ô]qÀíÆ¡Ðp^ŒYÐ9)f1ŸfŒÐxGgj°§éñþÅëÕó×ß5÷w«ç?5bõüïô¿ߟàÏë¿6X½|ÝÏcŽ.Öe‚›ßà ϻ©rZZ¼tU—îêvÆbð!M÷°±ŒQá .SD¶.%A%CçBNÈ\œ—ðoéajÄFjOE‹öb#ã¶´¤æK’Þó ׿Šä…)ı”?("FËórIºÚ©E¾ÔϧÁ¦óyåéâËßg³.ɽ%ݡ˖r–Cng™…ÖO±U¶Pâ²§È=JœÙÈ›÷Cþ8"K"ˆñàbžN!Jº¡4á©Z0H²¬^Ê$Ëyö8Kºyþ·¡‹€ ‚ý‘èb,—GC_‡¿7‚e_6¢·/…8`)lÄuÃFÿþsâTÿeOMÀÓÅ`PÙÐé¦h½×ˆÛøïy`©£´h6”þ¦wË^rêŽXýJØoãendstream endobj 113 0 obj 3747 endobj 122 0 obj <> stream xœí][s$·uÎ3£1ožI‰½¸_üK–ìM¤²,³*q(r—;ÙÙ%Å]JÖ¿Ï9¸4Ð@‡â*yH¹,µšh48—ï\çÇ ›ø†áÿÒ¿¯Þ½øÞnn>œ…»¾ù÷ùêíÙg<ýK£7_\À\müä0jsñúŒ§ñ^OÖ0±1În.Þýçvÿ~Ç&/œ5rûaw.'å”ݾÚóÉéåö~wnà¦V|ûq'&m˜S8RY9 )ãMí ß¾ 3yï>¯,Ÿ”pÛ«8•æf{»;דsf}·ã“óZóíÝî\ȉkáéßßWså ÞçÞz®Œ¸³øpí&W­ðMù¬ò1ÿuño¸•¬Ú©áó`s.®a;¾„¹&o½V¸š|ù.^Zæq¹ïËå«2–ÜýX.¿)—û2öCol\o}’ð¥ð)ó‚§Ý¹õa’íËÝ9›¤fJÒí9²%a‘ŽM0lºä‚ËtžsM&ØV21èñË"1Ø-™à ÇIŸç2ÒejSÜ'1Vn/Ëb"]˜‚Þ½)—õ\J -—Ö%ÆÞ” È»Èç>”%¦i ÓðX¤1nûs•×öhì\05q±9‡ÿ‡Sû:±cð¾}9øCºk-¥—Wåî}¹ûm¹{ÙÒa{÷¦Ü}UîÞ—»/»3|ÜÙ‰)ëø` ¯ñïVH‘Þþ~…7ˆ[²BÆÀÄÀ±™ŠãY: W"Ž®A2X³ÍdaŒ¢„wU.ɱïÚ >qÆ]C¤P™±žMV :-¡‹HŽ(ѲIJ¸í­»b® °€V*Ù™W²'·/ü°'¤ 4!œ‡}–ƒu‘)>kIöPFþ²åo¤ç};m¤m1ŠùIÃÞþa|ΙÀ×Lj=y>~¸å"˜prÒŒ÷ù¥z? 5¨‚}¾ºÚš;¤ ð“)¦/3Ê»f]†ÂúÕ$½„C¶‹sŒT—”nò M>™ê’RMQqIi&‰R ¬åw¸t…¤(q>&•'‹í:!ÀÂM@=&°€Ã>m‰{ÖÀ\ŸÊ ój«§ó#…þûŠq3å‡\7{{ ¯Ì#É—r |ðKÜ*¡ÜP„H¡&aõøýšíIéM2†2›eZ™Ä„K¹#LKØä×È0G_ǼÃÉä„O´IÜ–Yá{ˆ;¹¤Á–{«= 4Èyë¾õ<}쬠.KïÔ-sp‚›â¾}øwa=(G¼†» @$sN*Ê!xOÑ(î=‡å0÷>>¶'Œ†{ÏQJêíϸrËšý€ÃþØíq£¬žéœÂ™*¡Óz*hƒ;ÿŽ;ö6(Q‹w$/Ü8oôßÄÒÈS‡_P‰ áÛ³Úø%2_a l+þÅ3 ÿ¡…-ýicñ’`â7e,pU.ß–Ë‹26>æ”R?.Ë€ëUØàl›¿èsØ3à$_DØ4ørÍ”詾mµÓ×GA$™–Lp=Œß ^8-q- € þ bÁ©!£$uÒ=l‡ä1 ¬o &»íBÁ/Û“w6K‹úÖ;´4Ò¾í]¹[ÙMAÚŽÙ!(âJU¡`üà¯.ÎþzöãFGkþæ6B(¼´@žBcù‹—g/^~»ùxÿðêìÅløÙ‹?ã?¾øîKø×Ë?nþéì«—›¿ çÆ»ÁÃæŒ1£á10Ã¥E°¢`2Û.‘±8È/°å@¸Uð.#DºÒ¸Rç¬RñHàʸÈ@€¾<ŠyœÝ oš™Î¥uÅ-Y ž°õÖÅìÅLàl `‹Gí>=”u€E€¬uºkò¹I¢€ºøæìâ_V!†³0·ào¢öûP›iî­CTgƒü Yôªæ ‡´ù~O" d œ;44#7èÖ+œØá\tµ&ÔÕ¶K l&*¾[•MI<8;@ë'ú‘â^åÍš)oÈŒ²–çú·Ðò]-Û;TØÜ2Xn£àòO¨°9°8¾·–*ì°Î…Âî¬þ¸Â“·ŽW©Aœ‚lÙgº1­7£ñ²÷|Ô/š- Ã@ «è6Àk1–+67¨~tþŒ‹®?û¶‡b:žk¼üPÆ®{®•®°ûÐ`ú·I”“å _w×{è­wé%^V­·Ÿ.7 Nk쥗Tk@àk…XzYñ&YÁUyþ˜›ÁSÞB’•$Rëg …]´V€Z„L~3ëmë7‹…¾.wMÀ:›(ÈÖy¨5=dò8|½³z\">Ü<ƒ] +g ,e0jYˆÒ–>–± QÚZÝÄ:^ò]=vlûì@ª Ø>ìÚ>@2 pà5SÏcüÀº—r€@7U±ÆÓD‚âU¸ìo‹Ó"G4 K9ÐÄ÷Ñ–6x¿ºÆV¶{HpxMÃÞ¤B/‘u‡ph„*h(j»´`'è[j/ˆpl&êë—ÛÆ›­Þ—¦à•…ù)H똭œ~ydÅïD\(탯$€µF?E Ø™8þR$ÀC }Qî>”»¯©°îùÇÖÏ^ÃÚ–wäŒÏaÝ7ÝsB^Q~âÆÔþÎN˜,ošW}$—û›®µQÃÐE“U2Év%›à@ˆÄʱV‡é;ÓãZÆ¿;@?¢cGÞt}‡F†õïôäY¥ßp%”¿ÜìFQ=»Q{kb=În„Ó>¼äøÀ£xÄëi2ÿI¦ žB–«iõ”|$fæ&íÅ£.Òr<Ãå TX~`;°?›%Þ»›Ù¸k\_·±¨Êâ„—uqf$åå à«.–!jîÝâîîvõ ¯ô`9L9p´ÿÛí .w@c1þ/¤£¯³á-S B@_<†AÏ¥ä“h"Ës°‰¨ :yÁ 2Úm¿‡… ÐT"ÌN•Bx4ÌÕ†¼$úÜ¶Š¿54„ h=—8íMQªds¼vLù!`-—™Š#êpÈðÖPÃ<6Lv Œ¦LM&¨t\j%¸ ä5'JĨ“T×çÉË —Oóá>Â{Msþ¨u)õ¦¤gLÛ] åï=f2ý®Ê•[¤xQ|5ô¨6ŽI*„¾)–>dbnÀ®±l+†íg_ç½ñ/'±Ñ&@ˆàâzÀxc–]Ò»û>ÑP[xžÚø ¹»ô@7vÖËî ÄÁñj6ÔˆM÷š¾,jW=K°ož±I "aQÑ[ ÷•<LÉÓú$FíAg°‹dqü{=&ïYÕK 3†ª@(uÛŸà‚Ã"Ã6­=|œ P\; ¡ÆN@HndF®eþ¶0å´Ô_x1`O´]ÚAPep¿óO–—>øþ5^Ç Ö§åÈ?S.ú2?dÉÄŒ{=CF½ç}„v™òÇõÿ™ já-!!™”¡úÀ/Lá¬cÒŸÿ¾-\„;ˆzƒóãŽBr·À‰n’Ù+âsÿû?¿–ù4?V²TúÓ6IŠy«NK—ïó Š1 ¼PˆæyŒ¸6*PeùÄyS¨í¯ü4Ó.'Á=Å´Ó£t¿]…ÙòÍX¢Ñ ¹ y™hx“èÇ}«üë¼Ì˜Ì¼´ëQŽYØf5æwjÄ!žnSŽ€>±ßnŸ +„9M=9­¾MÆ`õ|v,­¤šÙ­ôn,ì•ÓÔG”’ñã4á¯dΩxÉ™ÃЗX¦/^©›”ø&àóA'Á;m𯄬Çä "F÷”ô¾rdGÒÑ,@â=ú–¤Fº…²/k—˜ciÕK“ë\ƒfÜJq¦çiêFRØqλKB¦Xé¶wåzÍ9BþI9ý0¡ù_ò}Ùõ-/cÉS\¼é G}=šDÔt Q»q9°+ÖøÐjV9^]<ÌŒ£¨.ÑR6Á/vìCW\7Ò—\Œ‹$§Õ"Àî.CÌ ^wÅðýº¯KÅBV -qÀøN“#_€C2í{½ä@`ô9Óo†ü+9ú©eT˜Ï懲õÇÿó.~›é©b¿4ÁÑ‚ŠÒ^_ä*M5<üTnú¬DŽQF˩牺=rî9«Hù7§¤”÷â™"ç§Hì¾¼¡W:lU_ê<½t¸ à¦áš¸i’hAoä+Ž…ô/KÎüÁê¨K¶Õ ©|‡”ÿ$HÈhê~iñ¯@ìßK¿ë5“ G,YÏin¬sƒ(—b±#³þ@QÎ(TY‘QAc{!RèX zæ¦f#¡L€ÏÄÉD”(QŸD—OÒ@sRŒ³‚ÄVžH„C?ñ7@êIäõLEµÇBºd€>’ºuè¤í®åÑIÆH“…ë4«0„+iÍ;œ0°’·@!„¿Þác` ªå®’-¤Tä>–>úÂvÑ5 6$5zN¤j«V1`½7QRçÓÄì 8Ç”¤ùì‹7K’¦…hÌUÝ×]¦©‹Õd²ç ¾ ÿ‡Ù8Ï͉iÄñ Pë@¥¯˜)%Vz&‹xô²Ã])rêV”=¥’ÝÁ£f6£ž+;`³µ4î~$s„ØŒ©Œ½}®)4ƒÊ±¹ÃÚíSm…V‚‚l“Ò4zšZî¾äwíql¯0BUM*v CÔ¡Ñ4˜k%ؽŒ2c>KíNõ°Ôp¡ RFa¸c8HVe\xp 'dÈ­ï4~ ¯ú|—:LŒé:$·™ÕÖ°r ýê¸&æ22?lŒñ6ÙVST:Ö™í.9]£DÊ7ú± »H ZÏ=,tƒoš‚tY#T~ûg` Éadhã²ÈÃ÷Öçy/fmtJUBÖ'>’‡\=2+ñ+dg·ZqRSƒËR=J¿¨®ª"ÅMFrÕÐ"5=Q’B‹YŠñÈ|E´ý1Þn€‘•Ç.84Ó̳xU£›9¼€4_ ÂÃ!'Arª¥ÜÔEÏA¡þxÀѦÏ}§:„³XUÃÉ"ÍŒ‚!}묩%Í<º JÚ¬™¿HWŸn EºU†\ LŽã]…~}~t{S†É¤ ýðí+n& †YsbRUßyDqÁꎓYžvR‰’Å´æâ‰8±÷UÖBX¢'#¢Ú)[}W8˜´Ö îl›ÈVph8`3H Y¶ìË"w‹¥–ƒíØ‘I§t†È8GWf¥Wòg’N~LþLµÔë1n~²âò&äã*5>Lµ[u÷®eAŒ«œñÑ"×áI«Ó~=Kĸ†'±XˆZ<ÇdŠK¬›œ1¬Ì¯::“§£{ׇ~šó0Ï93 #èsº‰EeÌ^uykÝŒ™ŽN ô‰­Cå’WM9|Ä“âZp“RïÉ«®äºÜ%Q°¥GºqŽ\öfèz¤IJ9¡ŽäôË}¹B‘}[ æûP8ù«í¢X1è@âcÎDÝÅ‚@ÉQæ%šŠuo‰5¦ Q ê~%ò?´â"œßˆ„CVrmn6†a2g ;ñ¼ T¡qôÄ´÷¤šQâtûÐ…¡ßwEÌÕâ.Ž%¹ß¬ò~ÛmÉ«ê"s «) Kvg $HµaÿëEf-y¹m:÷l^A2”ä¦y+“rÓÐ!6ðæ¸76äŸL•XHï@l{@“J¤(æèÍ{|SÞ§ä= ƒ°Qª ¾1¸á'mWi¤f.ôú`°áÊ‹@¤,DÏä¨^Ë©R‘ù N"á@«Nn'þ­›ýL**"cO\' (ëb^$dÀå˜ GCD5†ÎÝ”¶¬ú‘#…f9uè¢ã÷ÛWÕ¤Àò`l¥?È@Œ|Î=$ þü —¯ &#ƒƒ Ä´9BÍ)ûK»¾Ì®[¡.¶îvœtÊ…Ý¢²ÂoUr8–ã¯Tv¥r{b>Þ§à4§¸¶Ê°(á©Òri1F†‡·øØª˜ô0 o-""a¯Óa ?´ÍÂ7š˜/]ÙË)*Íæ¤æA„üIê*¡·âš'J)H-04'å !ô¾ñ÷6ÂwØ Šx /BÍ…:FFæ Ò'+Á“-Ò7îÿQH1•³}g}»5Ƙ@qì …–¼Q’söH¡CàŠ‚±Øƒ<ì‹ sö’=RDÞu•Ȱ€Emƒi>±$DA%ÁM*¡ÁÖ3ê;’ne!P±«RP² gåÀQH"¿BÈÙ„é¸á4u“7=?·¬ëhÚ®,ê&_Íæ>æ±ÃÜ%צ/O>ÅjÑà,ÄÛt¥ }‡l&ê Ö“B 6f²†àÁØZ$˜¶ý’I :_wg ¸ké5lr|W›Û5¾Ä›9o÷ÑV`Ý]­$¢s¤­JÝ«=PÎÀª¢Ãpk¢WÙSÜ+ÔªJÜû)Ë ;¿Mƒíœ7½0|tÕ'n8©†¤Rt:FæbaÄÃåG[¤eG>¢)ÄÃ6›Šâ-‹uP5´AÎ^­NrP–#H®j&•§Ýw±ü@GNZ–¦6ápëEì6kœ«>ì†ÀÜßçjÕ¡KÝ{ogñSOK‘—6ÞK…‹u¤Pÿ©Aã­üç#Û|ôÆ0Ûhœ#é9+ds^§ÛÙ8j„k’'¿RL×§à9CfP‹‹V­—7ŒìVÊõó¿P•s.»3—¢–q³»N²Ãu.­ªb¿†4*Š!œ[©½9Ý5½Y0Lnûé„ oEXá°Î«;ui+ø«ŒÔCêñ¤ƒÐ`]šèÑ cëMMæ&¹Û>P#º„Fµzþÿ~Šî(>«Wû9~ÝæsÔ’$ëªêc£cž6?›+ekÆE½þxœ÷Xä®(¢Õ}«'^T<ólä•÷UË’®f¨r6ÒïU´žL…°%*±Sîå.ý°OCÿ™™K¿ÓÍ68ñ´¬éýˆ^å$Í6¡0'Sȶ+{úÝ…#ùí¿Öhb.îZ›È™“ªvh*ÛiºÂÝèGÂÊHÞ÷¹P™ (E[«õöjÙÝ|6êóÙ÷²êK…d“Néè!ÇxÔ~eŸó…µ}ÌOp?¦J‰¿©¨÷Mó–j€¼k•°ØÖpWUAÚÊ•pü£ˆc+ºr~vZåÅH~莭(*BW @Uî?Ë ÜDÁ‚ þ¨®ïWÖ/ªb °.þt£†¦ô,}~… EÝçÙNÅòÆÚCA¿<þw(´0õ}dxñI q·Rž„¼jh¬±æ£ß‰0â¬$r†S£-ºQ4‡{zˆ9íè+˜—mÖ¾PanƒSä+1¤–:ÌüY1Hâeû&¯<ÕÕªø jhö®ììùtI<}‘ß’"vá÷ûÄÒïì)dëG )ûUŽË]yIå>’ eÓ°%¼o¾#" ÌÒS=„q›‚T5Æž9£°e¿JÎÅsãîh¹ÉF×ÛñÄNÎϳÚHF‚¯j× 4ŽËnÉÌ`ZÓlðšx'Å[½ÄM¬[“¼Í ÉÁóá÷$—=MÆ¿BqIª+DZAï¤ÊrËK›Âguef3+(¶¹þ·´Uendstream endobj 123 0 obj 7279 endobj 4 0 obj <> /Contents 5 0 R >> endobj 18 0 obj <> /Contents 19 0 R >> endobj 25 0 obj <> /Contents 26 0 R >> endobj 30 0 obj <> /Contents 31 0 R >> endobj 39 0 obj <> /Contents 40 0 R >> endobj 46 0 obj <> /Contents 47 0 R >> endobj 51 0 obj <> /Contents 52 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 67 0 obj <> /Contents 68 0 R >> endobj 76 0 obj <> /Contents 77 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 94 0 obj <> /Contents 95 0 R >> endobj 99 0 obj <> /Contents 100 0 R >> endobj 106 0 obj <> /Contents 107 0 R >> endobj 111 0 obj <> /Contents 112 0 R >> endobj 121 0 obj <> /Contents 122 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 18 0 R 25 0 R 30 0 R 39 0 R 46 0 R 51 0 R 58 0 R 67 0 R 76 0 R 83 0 R 94 0 R 99 0 R 106 0 R 111 0 R 121 0 R ] /Count 16 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 16 0 obj <> endobj 17 0 obj <> endobj 23 0 obj <> endobj 24 0 obj <> endobj 28 0 obj <> endobj 29 0 obj <> endobj 37 0 obj <> endobj 38 0 obj <> endobj 44 0 obj <> endobj 45 0 obj <> endobj 49 0 obj <> endobj 50 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 65 0 obj <> endobj 66 0 obj <> endobj 74 0 obj <> endobj 75 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 92 0 obj <> endobj 93 0 obj <> endobj 97 0 obj <> endobj 98 0 obj <> endobj 104 0 obj <> endobj 105 0 obj <> endobj 109 0 obj <> endobj 110 0 obj <> endobj 118 0 obj <> endobj 119 0 obj <> endobj 117 0 obj <>/Length 29557>>stream xœìÝ{`ÍõãÇñ÷Ù}³¹ŒmBäVÊ%¹„ ‘¤ä’¨„\rÉ-¹¥tSèGr¿åÒMŠEH$÷û%úv—B»1³ûv.¿s¶asfÆÎù|ÞŸ÷y>þ²u¶sÞ§í¹×™³1Ùl6€ebNs  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"aN s  H˜SEœ(æ@‘0§Š„9P$Ì)€"ñˆ9e2™ô¾ €Œ$ùô·†|K®y}Q _2ÚºœÔ‘r{ììWÿ˜ÀuØ@–Oæ…® Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§%v€3ybÇœÔ#Oa´á§õ¨ØÙV-é9ô_ûŸJ÷ì=ïÿ*™œ.’øÇëµ>9`®0âpß–aÎÿYzÖ¤-§Í8(ªMñvâ^7ô>Ìÿýþé°/WìJ•šÍù¡U%?ßF#'vÌ)¡0¿mú‰¯v|¾ôØ¡Ãñ)!‚+6¨Þj`³ö-Kùðž(y £ 8­‡ÆNˆR¾~¦O=¿+?‹‹»”“³.ÝyÏSKTtÍ ¾~EœS6ó™o¾›:|ïŸéY/2§ôÇœ2 su™ñ[†-™ñu¢ýÞeB+”1%ž8{ÎѯêcúN^>г•<…цGœÖ#cç#„Yˆ[[ÌúöÞÊy/R„ØYNì~Ϧ؇;‘Õ»1ŸÌ\qÖV¼RÇ'2¿^xÆÊœÒsÊ@(ÌUßì¿EK½zÊêÑañ½Z—t|;ÊœôÓŒO_yÆ"Â{ü0à±êÞî¼Ý²‘§0ÚðˆÓzbìBÚµjp`ó–(SÕ—½58Ì7÷Ený‡Ÿ^±³˜ÓmÞþ^É7<§lñÇ_¬µòŸf­^œÛ´êÑO{ôüÃÌœÒsÊ@(ÌUdDÔâÝÿˆJ/ 1¸´Ïå×Ç||ï;ŸŸ_6kp¨'í)y £ 8­'Æ.°}ÏÙÑûX’ÏÍìÝ®R®&ä;Kêï«v~ñáñ#Gâ“ÍŽ¿ò¿%òއ5osw1ïüáO'ÍeŸÙÓÿ¡ 9ùÈ<öÝ vÆØÿT®ñôíTˉ‡õìò%}Fò»¿ÛÒ%·›„-%jUÏÅKwg \­Õ-üRÿþwÿžxûËžî9e|•ûû³¥l뢘SÒÄŽ9e ¦°…Éam¦Ï>$*½:læ@¾;¥08­'ÆÎ§Õ“TÝÿä¾—š¯ûÙìßøÝ¡/´Î Ò•±³þ·hñ WO[‹ß:xu—nÍþKÌš5c÷*×oÛÓnÉ~Só‰Ió†Ï?˜ý­xkò¶Ç§OÝiª÷þ¨×Ì~¼gzoÁ€ñ‰w42ý¼'¸ßÎr³¦íí5mâ&K­9#'v¶ß ó‰·Þ>ë¬(]sÔÚGZÜœ]ë…mF?±7J·Y9tH“HÛÓå­I»lÞ¥ƒoÜý•e/>¦¼â™ Öó›×îy Ƨ\·¯žzâ.ÿBþísJšØ1§ „¶0ÙÌîÝü»¿DDïm:W¹±D6(y £ 8­çÆ.HXþ™óÞÐÉÑ¢díW¶=Ò04«WÄ.õÔ»‘‹ÖÅx×ûÜøG‚/º[“wôš9e³9bÈÀùãÊf=7"oì„5æƒ÷ûû/äñ>‹¦Wt<Õš´õ±éÓöWþ–˜7â¯óGNêXÌq•©ÿÎm´xãÙ²w÷ow³—H99ûâ½êÌñFç\×hKÝÛwÆÄ™þm»/]T­˜HßûØ”‰;l¢|äŒï¯zéé®yb’~tûËí7ÿnm÷Ißþ÷+|®˜SÒÄŽ9e æz3Ë;¿ÿéq[xŸÞ³'ä÷K%T&Oa´á§õäØÙWÃéîÿ‹¿E©îOÍ›R9Øteì2ùaè}[ÿFêÛ2<÷§»íü—Kžö¯¨ýðâµõË8à];aþíÇ¡-·œ¹¥Åœ-÷:Iâ“ë²ó–,Sš~Õñ©%óËüõ‡¡­¶þW¥å¼ÍÍoö™¿lrßQ¢ÜÐýO·¹)wlñ+÷~JTˆœùãýUüsbôHï%s+]~^j®ØMnqâí¾ÚÜ|~ÿ‹_×7Ò™SÒÄŽ9e ¦°¬N}ÑûÃödúÞ}ÿ´eMnñ°_“ Sa´á§õìØ [Ê®µƒ»8'Jv\ýLßþ¦¼±Kݶ¢×?§‰ ÛÛÞš÷)Ö¸víNaõ§îzø6Gl®ŒH;½0òýo¢s²•qh]ÿ‡÷ùÙkŽŸ4_ð¥µÉŒímªú[ã>^Ôwì™Òýû/_ΞĜk ®9ñ`—:Åò\cê®U}»M¸mü‘'êçĮܨAsG†_¾icWyl‡Ÿ­ùöo1¨ßœ—Ë_ñÃÚ×Äœ’&vÌ)¡0…º—2Nü4¿ûªÍ'E`d뉋#«‡xÚ–2FqZã›ê{‡Î¸:MTm6cC«ªæ<±Kùþ“îOýa)à]לp°ËŽ*9ÅN¤:óåUæ»?õrkßS³ß<%¹åÊ#šØŽ™ñòW%ŸÞ9 cÅôÝ=§½¹Å¯ÕÊçžkâ˜-9×z×ä=îÊsUéû¿éßñÀyÓ-ã~îÕ¸xNì®ü㋱»,´ö¸Í‡]ßó˜SÒÄŽ9e 暬vþðFm¿¥‹²]ycJ²žôã|¹ÈSmxÄi=>vŽ'pÐlÕûã­Ao÷I˜\gÙ¾Œ‹·¯ìýøñÔZ“Y¿rn©RÎ73*æØ®XûË!mÚ¿½ ÞM×Fò–}{üœ*DÉš•*EN}ôáªÞiû¾îßé`‚ý?ûT}áp÷ÈRÙ­±]¾¸Ï¨SŽ?æùýÅYÒb×ö_¼`sšð*^£õ-JZÏÿvòÀáD›ð¿k|ßqý³Š[èØ9žañïâ¶‹Wÿ-Jvé6gÆ­%òo™åôâÏ'/=›ýïXXÏýcÿ°ð «â—uyŸÊw¿ðþÝå=åôòÄŽ9e &ÿÂXOxþîo~³ßƈЈà|ö–ï­Mƽ[¿¬}ÏJžÂhÃ#NKì.³žýuZ³åÛerúµVn_ùáñÇì-&ÿ°:UšöŒ|´k…¹?ÿÍv¾öÙü¥g.ØëpSõ~+Ÿxð/‘øûäzËv¦Qû¡÷×6 ¿˜¥‹Ï`!÷^4½Ò•?flN:¾lÛŸüïØñÄ4›ð*V¼JÓ;Ü´uÃà‹ïà:bç¸ôñ­cÚüð·ð¿{Îà;çûbrþ*áªw^…¦³~Ìõ¯ƒ)NžØ1§ „Âä_˜‹O»ºÊ÷ÎÝÒ¢¢§ý˜Szß@F2ÚºœÔ‘à Œ>§€HÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`t){‹õ¾ €Œ$ùôWiNQ _Fù¾a†‰TQ8Z,Ô?&p]LÒ|ú+6§¨ pyjã>êŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP(¸Ô“þŸôÍ¿Ÿ~÷N´8^rSf&éº%wib 0i}{¬ÑAíë•<,2¦Š{<\ëkÇu“'pÌ)éQ‰<µqõO(T œÙ{Ë´RCgûÏ~Ñd+YÚfJñŠOÉù拏%¾37±iMo3yÇœ’µAÑÉS÷Qÿ„B¹ÀY¼¾{>¬÷roû«´¿0nXÊ}wXý²¦Çø~÷qȤiÿØ_¨”¼ì›„¡šÞ´Ìt“U_›—¦W‹"Oà˜SÒ¢6p yjã>êŸP¨¸Øµ¡Í$ Û=oÄ.ékrú6{Ò‘àî‹ïÏ%:žÛ>7-”Ø _òŽ9%+j×§6î£þ …ZËðy»UøŒ¢X›øí阮{ç©ÓËKß3Ê?C˜_ü1vhUÇÑ­1Aî*y( mÙÁó~ËJL\pø?{m•š¤<7éB×ÛÄéMÁ¦}wÔ;]ˆÐiOKqŸÅ'ë½]~ÛÃñeÖÿ¿Û~õ2 Q¬BFÛ>‰¯öK/“u9ço¿ò ³˜âöÍ™ôí.ßӉޗÃ3µM62¥qXÎÿº¢!›å¼ïªw‚?üÚÿÈIÇÍÏŒl—2ì¹ä»sý=…5ÑwÍüà¥öËœðʰ¿ìk½¥nz‡^Iƒ;f†(ö¥BžÀ1§äDm¨«ÈS÷Qÿ„B©Àeürï}!'…¥ïÚ˜ u¯~¦$¿‘MÊ|vNT³éY³¯ý5ç­Yj·È|¶—iÑFË#O¦WóóÚ·"xíB„§¼ó¢éµçýîè–Ò¼Š-zoÐûë|,Â<úûØ5²®"çm3F4ÍÿÐÔ¼[j㊶¤?ý?ýÈÿ?!n>fÝp³_¾Ïf(ÜÚŬ-Õf@`¬!Õ2Ýf Èôú}ÿ¯ B„¥¾·1þ¡<ï톎 „ùß !J~#DñÌ÷f†{yýº#à¨ý*K¤MYߣ²ãb¶$¿ÉÊÌýÕ~;ÌgÞ,Núí8è(æ­CâÖ¼˜¢ùSnÝHžÀ1§¤Dm¨ËÈS÷Qÿ„B©ÀÅ~Q¦î³~"$õóýñMƒ ¸ ×æ>=7š¼šÄ^‘ZÚþi™ÐõöÐö{¡bògß&ÜSÒq!kL`F¥¶:™û÷jc«ã‘ÕûËîáÃ~4•»ýÕL‘ëmK¤ÍXÿXÅœûòô²2‘cüÌaÉkv%ÔÌ/p…{C‘æûZÓ°÷£Ä­ÏÅ~=:38+"¶ß9¦ÅþørÞ›qG0û,êþê!Qüþó«ßI¹50ëvdz¯6èK/¯º ÛV'ßâ#âÖ”®?Èß\-ñÛu‰uŠåÜ•I?wo_|¿9cêÞ¸'˹ì¥þä sJJÔ†Ú¸Œ<µqõO(T œé—©a÷ÍôÕ/lÛ”TŧÀK¾vß Q%qËæÄ[}uxìöÐ6QojôWOZr¾moñþ𡈠¯»Ïïÿ"%ââ·—O- kô’¯©qüO+SK™.¿m—c6 2_ºZó©b5*q\dNÙÛã¦üW˜7Þ¶ú8+ª=Z·Ôå3D- «?ÆWÔNØ»6¹¼w‘Žz°Ddûb1~és÷œ}$×ÏYã{5*µ9Í2dc̸šâ×éa­¦ù„t<{`~z±Ë—2EòûÇÏRµº9Ôïzÿ—ILžÀ1§dDm¨ëÈS÷Qÿ„B©À}=üÁ…Þ¢VžuÉ®òT†ìKþ½ ¬é>¢BÒÆ/Ôô¿T‡ìÏäKw†×ºGËöß-*>»ulæ¥OÞókËÔà'êœßÿMÊM—Ëbyzm̹¿çŸÐåŽÐ]Âü±êڮ¸k¼aîÛmNòŠ=ç•fvüÿJÚ^òÁýDÕľO¬î[”#\Ì}½ó‡V§„ç~R‚ÕëËÎe‡íµ'G¯íiIXWºAÿtŸÌ§çÄng.^Ð=l|òŽ9%#jCm\GžÚ¸ú'Jî·a-ßö¹ü9õKþòVø}³¼Eµ [7%U»\ók;cTº\‡ ]ÊöÝ%jŒÞÐÿòó(/|[æö~~öjûÖ&—»8ó¸m±Cªäº#/¾~ìÖØg«¸k¼¡p<ÀgÕ¬âó? øßY§£TIüasîÀÝÀLÛ”}b­I„f´´ä}˜mŠÛ°;F„õŒÛ59#0ÓçÓeFoÈJ`€å®æé-Z¦Ýß:½N9[žÀ1§dDm¨ëÈS÷Qÿ„B¥À‰skK×ào LûèйV!\Ðëû^Om2ù4?wdYZÉËßBÏ¿3¶¥ËË®Ãí¯G¯ïwíÀ½´=vpå \ÁohKöÑ9lÚ1!üÍmº¥FÞn -fó6‰Ô#!£ú8îŽ`ú¾GÙ§¶ôÄÎàög¾›õ-w‹×±5ÅÞYôí~ÇsB³•kžôúäć*©ñAt‘=+îx=úÛìO{‰wú“2ž÷³¥OÿþÜã/_,a]éšýým®ÜögÊ>þµÉéi ±&{Ûí¿å»À/>÷ÿÓžº2)m9ßJÛ_Tè^òŽ9%%jCm\FžÚ¸ú'JN˜}Þk>þ˜ðiœ°ý³ä›¯òüÐè/KGóO3eüß®¸§nÎz•¼Ùß·?b;ðnz®Ÿ23¼Íâ®ó×\~i!YÎúm]úÓÑhvÔÊG­ê|^žÀ1§äDm¨«ÈS÷Qÿ„B­ÀÙEm-ÙìÉ ³ÂVwôÙåÃ3œÛ[Ê/Åú<\b{ª¸©wÜ–‰y‰Äû¡oÙîLezÄíž’xñ"ÖxÿÍK¯<'DåÄ-[rÿ¸Ð!íp‰&íŠÅødLß÷øM¹ï-ÓŸN–ψ¬i °zý¼%`ûï¶ûú¦VõÏs™­O—}r½©ú¸˜MCÌý„“±È8攬¨ µq yjã>êŸP¨8aõÚõF™.ï9>ÑÊߟøÒð”6wZ³2gŽ÷ùáÓ “ÿ°ï:‰kV$Ö½ôøKâÀý1'¬ÅdqsÒ×ß_¨—õÍqK¼ß»CÆ[~öÉ,‘ºr_|“bE;B¦Ï‚áoÁ÷&|¹ ¹fÎÝbú÷›]òÉxkg\÷ŸEíÃ_=*j?÷éÈŒRÐÆ0¼uèWñÖNË£ç5SçãH¢À1§¤Em¨KÈS÷Qÿ„B¹À ÇwÍ+5hŠlö‹&[É0«ošWì…œç?Vh—°pZò¹Ÿ=*oàlæ3A½›—Ü’*¼+¦·ojñ9ç³ë{¿¨[“VÎ3OjUr¿M”ožÒö¾ä÷îuÃG"ãdРö%ן"Èܨif¹@SÔ/~»~³e°¶™·àIÇoLN:Ò¹CÈq«e2›Ôµ„ÙRb}íòµ¿QÉÎoX˜RAG‹2Ž9%3jCmŠNžÚ¸ú'*.KÚ)ÿ•}õ½ßÑß¼“³ŽR.ó®¦i{¦tªo¹òçš%œãǃ&½²j—w’¾a™÷vIzñ¹ÔÛŠ™Ï í÷–ÿQ©ÛÙ¯™ú!pÂñ0ÔwåÜ¿ö?|Úñ•Àl©Ó,µçमõ¬—Þ0寀÷ç[½Õï×(“ã–ùX+ÖÊx [ÒÐ'2ʨT7!Sà˜SÒ£6×q„,Ô&yjã>êŸP(8 Hä s P›<µqõO( Ü¥_ibãõz¼^òŽ9%1Ù>û<íõЧ6î£þ …j3åú|ãÏÚÿYòŽ9%+>ã<ùÏê§6î£þ …RsþL“í±”§½ÞÀä sJJÔF¶×˜<µqõO(” à2òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'ÈêŸP8 ?òŽ9¨MžÚ¸ú'YÓû&2’äÓ_±9¥÷Mdd”Oáf˜HP•Js €g"RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒŽHÐs €Ñ):cN0:"@gÌ)FG¤èŒ9Àèˆ1§‘ 3æ£#RtÆœ`tD €Î˜SŒÎ#"eo±Þ7‘$ŸþFŸSÈ—ÌŸ¶.'u¤\%«Åzß@2ö ɧ¿sJâ[èCžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹ ±œÉ;æ y £ ©#å*Äp&Oì˜S€zä)Œ6¤Ž”«;À™<±cNê‘§0Ú:R®BìgòÄŽ9¨GžÂhCêH¹Š±bg;Ø©N©ýÂÒgmÌĺÚÝî‹×[ úñGV§–1is‹4»²LÝá~¢ÎùýߤÜä­÷­Ñ<±cNi‰ÂhŒÂx©#å*Äîz®Wx—´–ñÏÿz‹5NX3/­±S‚<±cNi‰ÂhŒÂx©#å*ÄNæëÕ±ÓsJKFcÆCH)W!vò\ozªÉ/ЦñƒÏ‚¯ÔU±ÓåhE!Oì˜SZ¢0_)…ñRGÊU”Ž)jGÐÌw‚6ìòIs¼uhÕÌ–$ V½X®÷™æ³~vñ™Ÿú‹1 okûRF¾šØâ¿’ º&ÞvaÇÆ¤[|n v×¾êèåeêò jwvçhï‰CНüÙ+äþÄ–CÖœµ Ù3®æ¥k1íÑe¥—I]¾?¾YðÅWgú̾/|ÊŸÖ.+£g5ɺ°ÙkßòùŸì:æhu\ixŒ¶=GöÌó¹ú•v<{`~z1ÇýàýÝÜâ3–6 /k•ÈÔ/&¶ù#´žSìÎ zg^Ð×ÛüN^Ⱥ–Û3Ú=•øÜ“e q-F!Oì˜SZ¢0W-L!ò’ÿ•R˜üÈSmH)WQ6v6ÓñwKwœè—*DXôÈÛ,>I>û¿÷;™!Dµäå_%4+•u1³÷ÇO…ÝjTc½­Yú¥Lî 8š”>fŒiú?K­„½ë’Ë{_gì wÕçÖ”©=ÈÏ«aâÓçCÞ;c®[ÓZæžÄÇÿÚÿ[S­7£×õ²ä´%Ýwbó°wNÙÿdðmÌkur®ÝÔ©~ɃiKž»¿„ýeïµÏ† øÊË~õÕ§ßfËŒóݳË'Á~9·qVZ¸÷Õ®4aÁ¨Ì³÷ŠþaÏm´¿¹µV«ô;BEÔ1ÿµ>ÑǶ|±o®Ø™þ]Y²ÃðÀ!Š×H¿·¶Åë¬ïŽÍ¾±B”¸ïüÚ÷S*ûx-7úÿ]{òÄŽ9¥% “a‚ •—«\)…ɇ<…цԑrUc—þsHëûCþÖscg=bÉú–sþã.½ø¤{2nÛ[!&¿1´IŸ€D‘ùìê³cXµH÷ùâÙ2ÿñr¼ÁÅOòëŠ]!¯ú†Òwôõ·ùXÃ&}üARͬVq«K×ìïuï¹Cç<çÔ|2øÈâÑwg˜öú…ÙÐßœý-á»Ð»zd6Ž?°"5ÜK¤.Ñ´]±(a~nmìèº9ßôN9ÒéãÂ2hCÌ˵7;ß+u¼·-¥÷¼ 2Ÿ[—óæ6ÓÿÞ/Ý~¼#Ù—îóßÅ:5+qÈj½JÜ;ÝÍYW“y*pdûR_ƈº¯Ç¬îç¸yW»‘'vÌ)-Q˜| Süh¡ò"(L¡ÉSmH)WQ4v¦Ý##ýÌ˧iü¾å޵q‰½n û¤¦}tð\«¯M}"z}g*þÈÙ½sÓC.^Æz6 “ÐõÉ7»Â]uq‘¸±ôí}ümÂòÌú˜Wjç¼Oó©b7*ñS©”U{ÏßäxMìª2õ†ú¶˜‘`{¾ä¶ñWdÿ¤´iߘˆN˼jMŒ^ÛÇbïKF´ßÖ=>g…ùv¥.=Áê½ìáˆ1GDíÉÑk{:Œæ{¥BxmîÑó[Sp»³{¤—¸ô„ Ÿ·[†ÏøûÒý`:8.¢ý^~Íã÷|’çhqß”n4Ð?íæ¤[/Ôô¿Úµ‰<±cNi‰Âä[káò"(L¡ÉSmH)WQ3v>Sï ŸyRÜ95úë'-¹Ÿàh ìtW©Ù¨nõù¿æasÿMD­xØšëiŒ¦­Ê>¹Öä;áb õÏÿ¦Õ}%nq‹w!¯º–-§!©+Ä7¹ôè*Ógf«ð©™G|;º†ý€¦”í¾Öz§iÞ‹%ûkPúË ¶>‰ZÜÀo`½Òß$[»}ývÃ<;ù^Xäx_çØàŽ Ñßöµøòªï½»Ê‰›·$Þæ{éB¦Ã¯„·[ì]wjô{+Óü^jRf©¿ý1Y¢x;¼Í|1p}Ì«µm–3Aí–µ4¬ÑKï‡Ô죉Іi‘yfñÞû­_Œ°öü:zr½«ÍHä‰sJKæj…)L^…)4y £ ©#å*jÆ.1 G­Ð-fë«¢§Ý÷b©~c—ù8ND.ŠZÑÔ¯g­ÐÍfËÓkcÞÈûÞ®øñÝëøV|!¯º­5§·^Øþ]Rå\?“´£TÃÇ3î?whiZà!÷µ‰ërv߬tÛŽR  ¬0>z}KÒúÒw=íÔ5nïÌŒìÇfÉGC:· 9fþÕÓºuH¿ýfk1_a¦#3J.üÃiN]q¥‰Y÷ƒõɯ¢§æ~ôgeê¼x?¤d­€ÃÛÚõî=¶«Í@ä‰sJK&ßÂ2/‚š<…цԑr5c—äŸõ ÐöðgQ î¹òÜÐú¥W%ÚZõAC¿þw•^—bí¾:ú­y.öïâ°Æ¯8?v,Dì yÕ-¯Z[|ÀSõB7—HþzWB¹¯ÊÔíÛ|aô²vVص^©½â~žöLjˆGW˜Ú|½¤uÖCE‹÷'D<@µ<ÿý’”Š—®y­ëR¶ÿ®kÍ©œÇ»ÖGVDϼúcè´œ‡˜WDÍ,èN v.Ĝ҅ɧ0…΋ 0…&Oa´!u¤\EÍØeúLo>턨=%zm¼O/ˆj_¯äa‘õ›Wªú¼Ö4ìý(ÑbIÔ²6¹¿…mÚ1$Ɐ¼n$v…¼êšW€eõþ¬SÄÈæ±?ÄÕx#¢Ïfó¤Ý±½oÂìón›ð gR?ß‘´ýá°Ù§Óç8Û),ëM.~ÿ¿ýò¨w›åºyé¾o¶›÷ïµæTºïÍœ çF­z$Ï3ñòir~ïg)¹’»¦ô݃ü3J¤®ØäõÕce‡ìáOÅíü¿ŒÀK×0°IèÚÄü¹›B]upE0ý½ ¬é>Þ:WyJèòbIßm½p‡ã‡¡M‡_o·D \š´»w‰#uö|“\!ûý'ù÷½³ô†4k5ÑSê_¾yñ›K5ïxNˆÊ£c¶Œ¸úœ²y­ëÑÿSH‡³{ç§¿T»¿qMË|sùçn²n€·Oãó»?Ïû+ŒS}6¬÷)™^3Âñ#ÐÄÎ…øî”–(L>…)t^…)4y £ ©#å*ŠÆNdüÒ¶UȯÂÚq~쬎–ìOuó£ ]#ª<»il¦¿ÿ-/Óx”ŸÙ?}âÆs}ªe½Ã ï/Ÿ+3r£wfê þV˜B^uEHÿ¹x‹ûƒÏÕM>ìŸÖ%n߬œ'H%n½«g@Ä™§7øVóý³9 ³?`Ó:|òâægâ¾9£XV­â÷ì_Âôó S‰¬çF»ú•Æ­ m4 M˜‡­Š{þ©±xíœ\ºû|ß qù~Èü+¸CóâGm¶{'Ä-蓜Šïo^,3p¹#‚;?K)ïCì\‰9¥% “Oa Aa MžÂhCêH¹Š1cwÕw½bsŸÌÌúAcÓoKB;½ìŸ ÄMõÓšT³Zã|vmö‹¶‰ _-J®‘ýP1Å÷­öa³~±ÿÉrW›Œê!¦ß·2§½1ÄëÕ 7ôDÑB_uAEHñӸ̲³Ž·XýI»œo[£‚:Ö/yÐñÇ<¿¿ØîÌŠÒÍŸó·÷¹bÓÔ¦•Ĺßü¾ßï}ë³qón.ÞjŒŸMXšwI»oÀ…ÇO‡æ¥>ï=6~¯ýzl•êgT/!þ;î<6³ÿHÛâ·/ÿîfûÑN./Õ~T€ý¦UÎhZ˘áõË.ÿß.Q*mê7ñOÞb»ÆÑ BžØ1§´Daò-L!óÒ¯€¿a¤0yÉSmH)W1hì®&¬gܮɗ¾©nŠÙ4{^з»|£R„𲕫•þP÷¤¡OäùG¦,çý>žX|þj¿SöËYê?˜–nËc^K¼Êœ²¿ƒ$ŸUÓŠÏÿÂÿ—³&a²VŽL8.±SJ‰†]k\رÁñ/‹e‹?4wn±¯·ùžNr¼\>³ÙÃɃ‡¤Ô+]˜£ƒ<±cNi‰Âä_˜Âååí&ýÌ…ÉMžÂhCêH¹Š±b§™…5yÕ×ÔäÜñ•i%ô¾1О<±cN)‰Âx8y £ ©#å*Ƌݥ§1Ú\óúÍ«‚Nš3»<šbÊóúòåÊÝ<$vë¸L÷\¯§¿^nòÄŽ9¥5 £Æëå&Oa´!u¤\Å`±3åúœqÅŸSö—j˜P¾\xÿåq¯4³zg½>fS‰ö½Ší9sfÊqÓØ;lî¸^Oü³¡È;攦(Œqÿl(òFRGÊUŒ;çÏœ¢?ޱxmÖfFtöK}ŸMþ×oÇ1/û¯þLܯfõýózc’'vÌ)íP£¿Þ8ä)Œ6¤Ž”«)vnbñ:´Ö »VN{æãCq9/û†„Š´ ‰™Ù/zU½oøÒA-«ø¹ëúSŽÏjøâÎ{&,]pg KÞ!sJÌ)@=Ì)1§ÜÄš´sɘ®«OÛÿX¡Q·—ºÞµ2ŽbMŒ:¶êË&¬ÿ=EˆR‘c6iVÖÛ·ÀrâËá÷,}˜9åŒ9¥æàŒ9¥ æ”[Ø.™Óì•Mq«N·)Ÿ?~[È•Û#óä¦)ÌÞ›(‚Ú½¼ðÝ»‹;m“¢ß„¤õ¯÷|ú _ÁsÊ’™nóñ÷1ê]2§tÀœÔÜRs*—̳G?ülÕ§{~ú_|†ýEßâåÔoѧKLJn¼¼7l'w>ñ³ï6ýe¿Wh¥Ý»õ~×ÙÑ}^ú*¥â+ f=s“·°D/}¾ÿK¿ ¯êý·½Õþ–|¿ùdÿö½›Š7èÜòžÈ²Ùïß’ôûª/¿øpû‘#QÉf!JÝùà°ÇÛÜ]Ò;×ÛmîÐkæ!¿ÆË>|®ÌÎeÿ÷ÕÖmÿ$Ø/\,¼FÛvO½Ú¡Vo‘xàõZ¯0纶À&o~±nйMí{Ï>¹lá“§–L›´åDBP³KÆD:æ–%î›æ|±áÛcNq<É+°T¥FÛëÖ¶ñÅkgNé€9åL­÷nöE¡×¼2ÉüL¸‹ÿÇîò©»Ø$*Yö³ÞtÍwÓæ5ÞCÖ™.ñìøÌ±å]{[<sJAÌ©‹M9±ªçóKw§ Q²Z«ÚÃ|Rÿþßþ=Q™BTxz”ñwfƒÉrrÃ÷Ï;”,DHÅ;›W.žvú§ïÿH‰ìÞÝòé’=Ö*ÿ·húSa^æ˜u÷{÷'ðà+‹ßk\¸oýsô–!ÏÏø&Þ¾Œ*µ¨W5Ü”ðëÑGÏ Ü`ÊÛ/ö(ç›s¹¤>9y·¨>²“˜ÿmjóû›7ŽðO:}èÓõ‡ÿâösÖ=VIœÞ4ã›C›6lûÙ,*4z°m„_pÕ‡·,ç{a[çS÷zÝ>¶}Ò”Õq·T¯QòÎñc»Õñ³ÆìœÞfò±ösU¨Õ¨bÉóùß>ök’ýÞhñÞ¬•Êú{JÏ™Sõòÿ®‡A>ëŒ(ÝlÔÚçZÜœ=]¬¶½?ú‰o¢DÉ6+ßÒ$ÈdKÜ;°ÿĵ)¢F×·¾ê^ñ°l™ÿ0½ÓŒ±Ž7ÈÙ‰'Õ¿'ÍTsÞov*Y¸¯Ë–ÿôêoÖâw^=æ[ý³Þʳfö˜A?Ä{Uï·í­9ßåJÙÓµÛ¤ö3ß=cÆ Edÿt åôÆ—#ç7—|`Í{Cêû;N4iÐðù1yþ²/yO—''í²y—.uûàñ¯ ¬|ñ»n¿¿6pÔûgÅ­OûúÉêÙЖöל±ÏM9!*tžùcï*þÌ)•A><¤`1ÍÃgÒQã1ó†ûmîþàÂÍ)ÓÉ]^=–xýe³5imMùÞûˆ9uƒ˜S bNeI96ûîq›â½ëÌYüFçR—kbßO}ûNܘîßöµ¥‹ê%ì›ToÂÞ´b->]4ªyÐÅ Y¾< ßîÔ‹sJœY?ªáü?Eɶ_¿7¸ž¡Î‘ú뻑cÖÅøÖûþøGrÝëù½úMÙœ1dÖüq•³V^ÊÞǺMÜa5z¿»¡s¹K™5Ǭ}¨ß‚ã—¶N¾sêâÛ–dÆ}ª^¾C2Ï8tüÄQ­QÓº—ŸçeÚ8¦þÜßEÕÁ{§µ-ïÅœBäÃC Î)›øzªï3glÏ2©hê3Âg³…9uƒ˜S bN9dþòÉû>‹Õ‡îŸÚ&OL¬ñ+_è5ü—ìïÐÜü燃ï_íUkì‘IMCs}½M<4¹þk;“sv†íﯞkºø¤ï¼áÞµ|®-ß°lè}Ëÿ·84¥exžpþËŸö?Q{ðâµmË8¾?•3‰J?=mÁÕsý–…¤]]žü¿]¢Â ïÌVÞ»À9ôÈ›KæÖÊ÷ùé6sjBì…Ô4‹ãƒ?éÈôßùM”ïñÜǪû0§PDùðµç”)êÓÌ ^~5Å8~ùŠ-´¬hÙÈ2¬µÍ)u×¾d!ÿ²ïÀ&/sck£`û@SOæT0§ÄœrHÝ6¹×;Ó‚›M<8¦N±¼ÿi×ô¾]~Hh4þÈK·žÒûñ©¡÷OÙ3ìö \2G­n;`Ñÿ.~w*ç›:Åïÿêýa õó„97@¿½míÐ¼å´Æý¼kw¼k;u×àÛ (gÝ<îÝÙCÊåz–{ÎëË?çÙ >Ωr£æÎY1ÏõØRO®úì£ùßïÿ_‚õÊ[W®ûsgN¡È òá!…‚ç”MßèÓq¥)Uˆ°J¶Èr6Ÿ4ÓþŸL'ÍB”µ.ÁÒ¬Øõ]òúžŠ.˜SEÅœRsÊ!åû×»?uÀÚzòžgïÊóŸÒ÷ÏïßqýySíq?Oª³ÿõî=XʶŸ¶£ž÷vÅÎH>:µÞËÛ’Dõ·–Líî<;®~ ¸Dð=>§£|9“¨âKïÎ|ƒsêÊ·µ¥þ1ãÅÑÓþ² ߛ۴¹'²RDh ·I¤þ¾|ôêSÌ)¸ˆA><¤PàœJ?åÕúuï¿„èÐ/sV#‘ýMjK’iü›>‹cEX3ó¶ž¶Óu\’9¥1攂˜S©Û³¾íT¬é„Ccï¼â»S;§õéº5ůákG_¹ãÐä^Ýv¦•yà­ÝCjäþ«2sô7ö_øóÅa=·¹sŸ™ûlÞMF,ú¼eèÕâdMµ–ˆpürÏÔíoõ~|{jH³IÆÔ.v•Ëçpýœ²žÞðB£y¿ØêOŸóÒã—˰s\ÍÉÇlÌ)¸†A><¤PàœÚ½Ô÷ѧ†eßHkx®Õø#Þ çz¥úÙ>zÛÜ*ð:.ÉœÒsJAÌ)ó¯ŸmõéQuȾi”ËóÔ¥sËÇôõ»¸ùÑY[{•ÿåý­9ës×Ë?½~wñ\—J:úvƒ—L¼´3¬çV¾üôðcQ¶óÚÙ½ëæ{Ŷ”=ï?Ûy÷Ãý_žýÐMÿ®Öâ£ÓâÖg¾Õ:¢àš¹~N]ü»Î{&xþÎàËï1óøƒÛ|Íw§à"ùðBsÊ,¦¾ê;3VÜù”ùëf¶Ü¿ÖΚ`ê4Ú瀃^É|¹âu\’9¥1攂˜SYRþ7¯ÉØ qÞµf.šØ54÷ÖmëñôÔ­™Á]&-šUÛ?öÇ—ë¿}ÌRêÁ5 Õ¿ô#{¶Äï¦ôï½3EäÚÉ¿,jõüêSB”mõÂ×C#Ë]ùԇ̛Þn?{W¼(Ùuüüéõ‚3~_ÐdÔÚïZÓߟøxž¥’þçžÝ'ÃjGVÍù]Ÿ×9§ÚMXºðZsê‡I=»ïÉ(Óö­Ýƒ/×Íšx`Ä ×W^¢Ü“[æ>q+s Ee)0§ÒLFû¬MFe¾S#ï[¥y {ÞûËTñÀs™‹k^Ç%™ScN)ˆ9•-óŸ™#†NýG„6³~D³ò9¿ËéìÚÙ#l‰åºnœÓ³¦¯ý›ë7{·Å·ÉÀYŸ´«5¨2Oþ0ó‘Ù{£Íé¹ç”°¥þt\‡åZ„ªÞöÅ'î\·bÖo·&Eýôùç‹'l:‘!Ä­¼¹ºW-Ç?1c>³àùAoüa ®7à˱íjæüB¨Ìw¼ÓeʦSÞµÞZ8¡{XÖ*äœ2ÿ3mÈÐéÿ‰»†.Yݦ´wžË\ñ¶æ?V<Ûâ£S"⑯g÷®—uÕ–Ä_Þ2qabp‰3™Á-W.Ñ$9…"2ȇ‡ ˜S©^=Fxo±ˆ'žÏœV=ï[e˜Æ¾èóñ9ؼâ.[á/ÉœÒsJAž1§„WpxI?ç/¾,žØ­fÖï2HûgmÿlN^¥k´®]¡¤õüoÇ>gAwŸ2®_¥ì_¬™väã1}~Òþ§ð[ï¾çæbÉÿÞð›¥]ÿGϼ·äÐ;ÚtpÍÌþ‹÷Få¼ì],¸˜OÆ…„ŒìK¶ìùœGï¸ôK¦2¢6 3{}‚åÕ©RÎ?3êä±]ÿ8~{›¡o/hsSÎ/E(äœÉ[¦ôí±#Õ~E5kU.9uôÃU3ò[sÜæÞƒfnIÞuÚ×)ësáŸ]û‰ªøØÊQᓆ͵߿åë¶lÛ ÓØæ?ÁœÂ3ȇ‡ üîÔÀ1>ߤ‰‡Gf.¸=ï[¥y }Þ{Uªh=<óƒZ×qIæ”Æ˜S ò9u5yÓ¦9þø²Ï¿ød÷±ãgÓl«X™*M#Ü¥uÃ\ÿdž}$Z¿ä/·íI³Ÿò5šô~ò©~·ïúÔÛûEõ·—Lí–ggØÒ㎯\»~Õ¾cGÿ=—측¾¥ËUkܰEχ[ßqå³$þ¾råÊ·>kŸAÂV§nÓžíz[‰Ë9-윲¤¯ýßü¥¿_°_éMõû­|ùÁ[Ò¯ò¶Âšxâ»Iï}±êXT’ýÒ%o¹·Õ£/>Þü¶€ÔÃ_¼ÕïãƒÿY½+Ý?aCÏØ'™S¸qùðBsÊ"¦¿ê;-FÔîi^ÛüŠgDyµí}Xˆ!¯fŽ»ù:.ÉœÒsJAjÏ)­˜£¿nÛÿ½ÿ™j½ÿÉ›_ûòjbNá òá!…²oßG¾~>·YöŽ´æþÑ•Ø}>w/4eÙVL1G\Ç%™ScN)Hù9uéëâ¼»á×/œþQ”¥nË{k™ò¼¾|¹rnœß+û¯]½’¿^(4§ØRîb)8§2N{·ïõ«˜g5´e7Ço5Ége‚¨òyÓ#6ÿë¹$sJcÌ)©=§ì_/}ÕwÉŸÓ~y¡i)åË5í8auŸ;K7t¼>3~ßKc&||èÌ™+ÒzTöwÇõJøggjÌ)¶”äÃC ×úGf~ÛìÓéSS‚7U±6¹IX/ˆ]Ǽ¢m"¤¦å«ÁÖ~×wÉÂÌ©Ì(¯~ïzÈþmÃVÓ‰a¢X¨­löuyÛz?cí[Vý/š.ÁœRÂsÊùk¿ ¾cÝ;÷¡AîÏ~©ó£½Ò¢ý+ÆþŸo~dÕîyŠúþ õú+(0§npK¹3öÏЂCtÍ èËqó òQ!—Bü›}1¿›fëõío¦¨tûK¢\EëCÍ­C›Ú¼¯û’…™Séÿz7ÃëÔÕoòàW3_ºùŽê‰˜S RxN¹‹5þ·ïf~¶î›ŸND¥Ù_ô*^öÖÍ~®Ë=5 óMru}NéûRnks PsJAÌ)¸Š¡ç” þŽÏ=¹`Ny–v±9¸âNÓëõp攂˜SpCÏ)!ë¢bNyû¦¹t_Éðg¸ sJAÌ)¸ŠÑç”rQ1§<…óŽá;RêbN)ˆ9WQ`N ùs PsJAÌ)¸ŠsJH¶¨˜S€z˜S bNÁU”™SB¦EÅœÔÜRs ®¢Òœrœ¥èW㊀0§õ0§Äœ‚«¨6§ìŸþ&ý¿GÅœÔÜRs ®¢àœr\TçEÅœÔÜRÐÕæ”.7æÆ0§$¡Ò‡Íå9%t^TÌ)@=Ì)å;§—gN =s PsJAÌ)ÀÙ•sJ趨˜S€z˜S bNÎò™SBŸEÅœÔÜRs p–ÿœ:,*æ 攂˜S€³«Î)¡õ¢bNêaN)ˆ98+hN Ms PsJAÌ)ÀÙ5æ”ÐnQ1§õ0§Äœœ]{N s PsJAÌ)ÀY¡æ”ÐbQ1§õ0§ÄœœvN ·/*æ 攂˜S€³ë˜S½‹Š9¨‡9¥ æàìúæ”pã¢bNêaN)ˆ98»î9%ܵ¨˜S€z˜S bNÎndN ·,*æ 攂LEÿ¨è?ý]½¨˜S€z˜Sp-.]TÌ)@=Ì)(×-*æ æŽ‹s PsÊ]ד«¸Ç ƒ»ÔS¸bQ)0§ô¾ €Œdþ´u9©#¥¾ö»w©)ò˜0]ëc@ò9Dʯý.Ç]êYôþWh@_Dʯý.Ç]êqtýWh@_Dʯý.Ç]ê‰ôûWh@_Dʯý.Ç]ê¡túWh@_Dʯý.Ç]ê¹ôøWh@_Dʯý.Ç]êÑ4ÿWh@_Dʯý.Ç]êé´ýWh@_Dʯý.Ç] -ÿБràk¿Ëq—ÂA«…ôE¤øÚïrܥȡɿBú"R|íw9îR\æþ…ôÅœràk¿Ëq—"7ÿ+4 /æ”_û]Ž»WbQPsʯý.Ç]Š|°¨(Š9åÀ×~—ã.EþXTTÄœràk¿Ëq—âªXT”Üràk¿Ëq—¢ ,*jaN9ðµßå¸Kq ,* aN9ðµßå¸Kqm,*ª`N9ðµßå¸KQ(,*J`N9ðµßå¸KQX,*ÆÇœràk¿Ëq—â:°¨sʯý.Ç]ŠÂsü ÇE/|Ðsʯý.Ç]ŠÂsÌ)ûÇߣ`XÌ)¾ö»w) /gN þÖ€Q1§øÚïrÜ¥(¼ËsJ°¨sʯý.Ç]ŠÂË3§‹ €ñ0§øÚïrÜ¥(¼+ç”`Q0æ”_û]îÿÛ»ï0¹ÎúÐãgÊÎ6­diW›Ø¦Ú6¸00„b:$TÃ¥b:˜K5„¸˜‡À  `lº à<6ÓËCy€{©ˆ¶H«ímÊÝ‘ÖVI#½»óî»óùüãÝљљќß~=sv^)ÍkS™¢R"§êüì_vRš×8§2E$CNÕùÙ¿ì<¤4ï9•)* rªÎÏþeç!¥y‡Ë©LQ Su~ö/;)Í;BNeŠ XíäTŸýËÎCJóŽ˜SV¡V99Uçgÿ²óÒ¼¦rÊ*4À*&§êüì_vRš×lNeÞõV)9U·r?ûê–¡­Ür(ENeŠ XäTÝÊæ”–;֜ʰêÈ©:9­’S™¢V9U'§ Õs*STÀ*"§êä´ZxNeŠ X-äTœ‚V[–œÊ°*È©:9­¶\9•)* >9U'§ Õ–1§2ED&§êä´ÚòæT¦¨€˜äTœ‚V[öœÊœª“SÐj+‘S™¢âSur Zm…r*‹PTÖ’‚†Ú*0äTœ‚V[¹œÊZ]Tsh '§Úœ‚V[ÑœÊZZTsh@Nµ!9­¶Ò9•µ®¨æÐ€œjCr Z­9•µ¨¨æÐ€œjCr Z­59•µ¢¨æÐ€œjCr Z­e9•­xQ9Ì¡9Õ†ä´Z+s*[Ù¢r˜Crª É)hµçT¶‚Eå0‡äT’SÐj­Ï©l¥ŠÊa È©6$§ Õ¢äT¶"Eå0‡äT’SÐj±r*[þ¢r˜Crª É)hµˆ9•-sQ9Ì¡9Õ†ä´Zܜʖ³¨æÐ€œjCr Z-zNeËVTsh@Nµ!9­¶r*[ž¢r˜Crª É)hµU’SÙ2Uýús8€œjCr ZmõäT¶Eå0‡È©6$§§–+|½§÷]]7•Šƒ»¨ŽjåÔ…¹¿œžzúìBêw/ …ÎwmÜxI)ŸU&¾:4qjúûªÊ©LQÁr“SmHNÒÎξlì»!¿ôm©Z]—åvæ—¯|yúwŽ=¾œô]Œ$WzéÖ«æv|tnÝ‘6ýM÷ú ŽëýñžG]N­Ü.)*X>rª É©ÆÆ:7<¢¿÷W‹_Uf_6>ù¤Ùùãwß™J®øÍžÞ·®ïýáâãVyÿðè#+‘w59åâºmYÿÇ™#åT®pņþ—ôkÕ¹¿™Îp]GUN­è^)*X&rª É©jùΗoéÿd>+,L|nÇÄݪn0_èyîæã®Ëg}3;¿1:»)ÆN¦kWWÿ]6uv)§jùîÇnÛøË¹‰KG'ÎèØtFׂœZaŠ –…œjCrªß÷n¾÷†ŽÅjzÓÐŽgâí¼¡® ¯íªž;3ýȹJÏž‹ê'Z­{O×M…ÙÅokÕÛ-Ì=frâ9³åÞ½×Ë_>°í%¥ÚCv ^œõ¼±¯÷K¥úÆ}å¹ÇNŽ]4].ºÞ»¾ïc]ƒ¹¬X-?`jü­“³·ZÚ…Â7o}}Gí܃ïÊzÞÜ×{u©0µxiµ|ÎôÄE3ûuÆ‘wfïž¼»ÚõŽõë>[*îX|2Ô*wŸzõØä½÷‹ÈüzÖýsO÷×J…ñú­UN›Ÿ}ÚÄÄ“ç«ÅFwí7˜ë:Û¦ë÷}ÊÕf?±}ç9 ã\éÒžìqSó‹µ:Ñ)§ZDQA89Õ†äÔÁ Ù¼õ5YÏìÎïîœÝÐÜuj¹ŽÿÝ?ð÷¥ú[€wž›;¥’M;¾Z*ÎgÙí§v|nlnãÒ†ù«¶=§”995ÛÛ50=ý€Jm°ÔóÁ®b9«_Û}Sùkû·=³sñ‹ÊÿØ1üæ¹êî3ÝóŸëßúüÎúŸŸ49rÍøüúÝWêî¿çÆÎùÊä5CãgÔo2ÅÀ¶×ã¥vMWö¼2T.t?{ËÆ/çjçŒ}l¦RhvgnÙ“êƒv _:]éXºµž¿ÞzÜ·²êSG/ž_¼nî·½ý÷ÝPªVg/}JyϽÈý¡û¸GlìÊæß8´ãÙK/à5{ƒ?]¿å/×zxîÔ>äT‹)*!§Úœ:P¥Ð{ÞÖ ?Îªç ¾m¾¹{+½lëÀeùÚ}F‡>9SÉïýƒüu›¶>£+×=»óû;g×﹤Û3›c~×wG¦ouóvìÝ|Öî·ß=8òW7ŸÛ^.ô>l놟fóÿ²}äáõ·ÞnΩ«"÷à [Îë-æF¿·cfs³;sóž”ÇÿsxrŸ×‡ Þ¼õµÙw ^9])äJ¯Ù:ð‘|½Õ>¾ÿ­]Ù¿õ¹¹?›¾a|¡sß»vø”S)äT¦¨ €œjCrê@åâºoYÿó¬rÁðÐE M݃ùbßý¶ôý.[ø‡Áá'ïÿ‹~CÝwÝXÊ*“ן¾û¦=ͱO…Ôu üù¦úf_?í–¿s÷¹ØßÊ.~jýf—rjãôÈ·wÍ÷ìó·ŒuõŸ±©³R™ºrhìN…&wfiO¶M }l¡kïVù«¶=»”Ý~|è«“åj±ïþ[ú~›Í¿gûÈã÷?%¸{àÌÅ[[ûÎðÔñÙÞ»vø,Ê©Dr* **-E[“SmHN¨RèyÄÖã~”UŸ42øŽæ^šìÜt×þ®éÚ̧¶ÞgÿkLunüoýÝãµÙoßy¿}rêÔñ¡këm±d¢«ÿÔM‹iòá©“n¹r¾ëñÛ6Ý”-¼mpøü}rêŽãC_Þ纋¦KÇ5Ð3Z›ýèög•šÜ™¥=¹ÃøÐWö»µ¥Ëo71ôÕ‰òÜž»–Uï1;·uÿ[«:¯.å³êÔÇî¶Ï];ü vÈ©tr*;Æ¢ÒR´;9Õ†äÔArlëÿB.;s×àêoNÙb ¾©³\þìளö¿Ï3¥ãî5Ð3’Í}pûއì~Ãn)§Æ¯ªœS7 OxË•‘S§ ~ij¿›)m¸÷@ïp6÷¡í;Î.5¹3K{rPœíW?³{îÚaî|mæ²í£ÿ}Ÿœ:ü Ê©,©œÊŽº¨´È©v$§V¸|`ëKJYqnôÛ;f¶r³ÜP!ë¯Ô õW§6Þ­¿{joXì5Õ¹ñîýݵÙmßyÿ}_ È©SƇ®ÛÿÕ©[^vZü[îQjrgšªŸùÝwm²6sùöѳðÏ)§š•VNeGQTZ êäT’S öôŸu\g9«ÿ]N5+¹œÊš*ª$[ʺœ±åÖ½î=½Ý7” YýòN™Ÿ}üÔijf+G¼ê*&§Úœj$WzÖK YV™þÀÈØy•ïÇ\±çùÇ]Ϧwܰkî¸\é[>žÏî½kð²ýÞÌ¡ë¹ 3;¾½”ËSÙÞNXÚîÆ[žÔ/ÍíüþŽÙÍîLsõ“+]´eàß Ù½v ~jÿ·>gŠ]×+gÏ-Ü|N•œjVŠ9•¡¨’l)ër®”&×嬦ÝÀ‹»ës¥X-ß¾’÷Dmí̉‘Ë&šœ«œjCrª±ÉRßãú~¼øUmá©ããÏš™¿cµ~o*¹â7zÖ½i}ÏÏ·òä§GÆïU?#*÷‹¾ÍØýQOïÞõ¨¥üÊýW׆‡mêÊÊ/~åÒ«\Ë‘SYíîã#ÿ>¹4k&;ú·¹ï'YíÁ;ÿu¶šovgš­Ÿ_¯8g}G­6÷æ‘ÏXØó¹SÙ|¡ûÕ?¹;³.[ú¬fopi÷öÿ¨ˆÃ“S«Ä!ÆE’-e]ΕÓܺœõÏ´;gC©’-üÍίÞórT.ÿu›žÔW*gåW ¿(Ù–•SmHNÒXiÝK6®¿îædеêúÚÞÿsÝ<7þÑɳnùì€\ñß6 \Ô¹øÿ¹•»ÏÎß¾šK×— µ¬úc;>8µÐ½´Ý2äÔ©SÓÕÞžÿ*ÏÝo¾RÈwÜØÕ±3ËºæÆ¾¼sê¶µæw¦Éú©ßÚ'7\صxkµÛÌÏ^©Íç;nê,ŽgÙÆÙ]WŽNŸ|t¯NeãïÑß=¹ø.Ìß®V=o×è3 Íܯz7>§·¸°û›J¾øÛúKµÊ•=ÁÐQžúÀèÔíÒ|†¥›SYƒ¢J²¥¬Ë¹¢šZ—3×ñ¶-›ÿ©Pÿ5çk&Ëû\þöÍ›ßSlð+Ì ‘SmHNN-WøfwïǺ÷žWÑY-ßynö1ÓSO˜«t°u.ÿ­ž¾Þ½LÞôbDÔ*§ÏÍ>erâ‰û/lžSwÙ5øÑr×;úz?ßY[¼´Z¾ßôÄ&fök‹#ïLÓ9µûÂö¬{oo÷×: “»˜æ>5ùüéùþƒ®ØDŸ®Z¿ñU½¥Å ,UæÞ¸cçÓåÔž÷ùo³÷t´ô$SÙ~Eµû™x{r̬Ë]Î\ášÞžïå³»MM>t¿*r×oÚv~WnËÔÈ7Ææ»º^äT’S YÊ©›?^œT¥žSÙÍEU«%z˜[—sխ˹ï¿Îe[_V:ðÃùÒ"§Úœj¨vó£rÀÑ/?áøã÷Í©èû³,—'ùnQˆ5S7Kó0·.çê[—ó Åuß²þ'ÙÂEC#8w* «zHµŒœ:Øâ4¹åüªúzqÔVþj䄇ôìÉ©èû³Œ_·9—u9Wẜ{Ôr¥w ¼«#»õÔÈWÆæûŽæº«ŠœjCrêÿŒ_=¯èìµüÓŸVÉþ,ïåmDNÅe]ÎU¸.ç¢j¾ôÞMý—r¥ùñ/í˜<-¹'Ö>äT’S qîÔ!§â².ç*\—s¶ØýªM//fëæÆ?µsò.É=«ö'§Úœ‚V“S‘Y—s•­Ë¹³³ïi›ú~ËNšýÄØÌIé=¥$§Úœ‚V“S±Y—s­Ë9Ôµá1›z›Õî3¾ãÒÉù&Ñr•“SmHNA«É©è¬Ë¹JÖå/­ÔÀº_f•ÇŽŽ¼s¦R:ìÆ ‘SmHNA«É©ø¬Ë¹ Öå¬ä»ž¿eÓóÕ‡Ž¿¦Òqè-“#§Úœ‚V“S«u9c¯Ë™¿~ã–ó»óKÁz¬ÿŽ«“œjCr ZMN­Ö匸.g¥Ðû¨­~e•ò‰žC¥òäG§=-]Nµ!9­&§VërÆZ—sa霭C+OüÇðÄÓ|zÉ©6$§ Õä‡à³åÖ9Ն䴚œZVÛªÖå\SäT’SÐjr*¶Õ°N¥u9×29Ն䴚œŠÊºœÖå\qrª É)h59Å!8wjSmHNA«É)XÛäT’SÐjr Ö69Ն䴚œ‚µMNµ!9­&§`m“SmHNA«É)XÛäT’SÐjr Ö69Ն䴚œ‚µMNµ!9­&§`m“SmHNA«É)XÛäT’SÐjr Ö69Ն䴚œ‚µMNµ!9­&§`m“SmHNA«É)XÛäTZÙœ‘S°–É©6´r9‘œ‚5HNµ!9É)XƒäT’S‘œ‚5HNµ!9É)XƒäT’S‘œ‚5HNµ!9É)XƒäT’S‘œ‚5HNµ!9É)XƒäT’S‘œ‚5HNµ!9É)XƒäT’SÑZÈ)à «ù°]v«zHµŒœ‚ˆRÏ)CªNNADr H!U'§ "9¤Îª“S‘œRgHÕÉ)ˆHN©3¤êäD$§€ÔRur "’S@ê ©:9É) u†Tœ‚ˆä:CªNNADr H!U'§ "9¤Îª“S‘œRgHÕÉ)ˆHN©3¤êäD$§€ÔRur "’S@ê ©:9É) u†Tœ‚ˆä:CªNNADr H!U'§ "9¤Îª“S‘œRgHÕÉ)ˆHN©3¤êäD$§€ÔRur "’S@ê ©:9É) u†Tœ‚ˆäº$‡ÔQÕ´•Dh9$-É!UŸ­Wm޽°êäÎNõˆ–S@Ê’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§š–ûõ5…û~:×̦¯{Kùo·,ó“aø¦â™Êe'U¾ûšê­ò‡Ûrâù÷]™ÿüÏr¿›©»ù„Ú¹÷ª¾øÜê‰Ë»Gkœœˆ"É!%§š÷ÿn,<á ¹Ù½äves‹ÿíȶôÔövV©öŠ +Oì_濽¹œÊýþ¦ü£?”\ü²Ýf[-?™ûÕXýŠ'W?aåÌ®eÞ«5LND‘ä’SÇ®’{ß›ŠoùSvê_—¯}P­¸Â[39UÊ?æu…ïW³ÓXùðc«·®¿•úEîÿXøa%;åÑåkÏ«y‰ªIr Š$‡”œ:v«/§~öÙŽ})ËN¨Üøºêí {/ÿùçŠç^•ËŽ¯üçë«·)4¾.SQ$9¤äÔ±;rNå¶ÿ<÷îkó×þ"7´°ømmÓ¶ìþ÷¬¼ðµ;ø¦Û‘·l"§r¿ÿAþò_×ò·­½ð®ûíÏÄ g\’_ØP½ò­•»–‚ïx{SQ$9¤äÔ±;|NÕ²Ÿ^W|Ô¹™,Û|RíìãkÅÙÜwœû]9˶U?ùªÊ}{nËæOE?Øà׋wûp.;¡úõ×UNöêTsä@I)9uì›SsÈ?ð…_gÙ#Ÿ½ðž{f{^ªLæÞðÖ⇆³Í÷-íüZ_î(¶<öœªäÞÿÖâßÿ>;íñåk¼âoJ®r Š$‡”œ:v‡Í©o~¸ãq_ÏŠ§V¾ó²ê–}>]aôG…{¼7?Sª}ôåtŖǘSµì‡_,>⋹jõÓW¹WwÐ=n+r Š$‡”œ:v‡É©rö¯ïx÷pv—§•¿xßÚ¾o¯UÇr~yñ{YvÁë.:ñ(¶<–œªå¾wuá ŸÍÍk½¶ü··ÎšúÔ,v“SQ$9¤äÔ±;LNÍæžóòâUsÙ#/\xÿ©û_k6ÿÂW>3“=ø% ºÓQly´9U[È}棅ݔ˺ª¯½°rÁÉZêèÈ)€(’RrêØ&§fòO}iá?*Ù_±ðÎ;ì­ùÜ+_]üØxvöóÊ—ßµÖü–G•S•Éü;.)\ò›,Û\ý§—Vë_øèÉ)€(’RrêØöÕ©çþÏ╳ÙÃ_¶ð/§í­Ùü ^QøìLöÀ/|äô£Ø²ùœ*å/z{á£CYß©•_P½{ÏòÜÝv#§¢HrHÉ©cw˜œªdïz}Ç;‡²3Î/_uÎgDåñò³ìù¯_xÍŸÅ–MæTu&÷¿ÞV|ߟ²[Ý«ò™§WOô‹|ÇJND‘ä’SÇî°¿Ù÷v<úƬxJåÛ/«nݧ~†¿S<ë¹ùžÚå—Ïî:Š-›Ê©jvÕ¥Åç|7·á®åkŸ[û31@ND‘ä’SÇî°95ÿÇÂCÞÿE–=ê9å÷Üci¥¼òhî·¯Ënû°òWSë<š-›É©]?.Üç’ü®õÕSå/zoC“ä@I)9u쎴ÈÌ/¯/>ú¹±,»Õm«÷¾UVÏnúI~°–õÝ©ò¹çUO-Ý–GΩjîco+¾ò7YV¨¼9kðÊT1{îó*Oٜ޳4 9E’CJN»&Öìú?¹K®Î_ýËÜö¹Åï²ãO¬>ìœê îSÛ|`ìyË#çT%wÉŠo?Ì×^þÆÊKOïY…œˆ"É!%§ !9E’CJNµó†—¾8àq‹u9+CND‘ä’SGg±iny¸VÃ׬9E’CJN…ƒ;Æ+Rk—œˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’CJNACr Š$‡”œ‚†ä@I)9 É)€(’Rr ’SQ$9¤ä4$§¢HrHÉ)hHND‘ä’SМˆ"É!%§ !9E’Cjq¶ÆÞX¥=¢å4C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆLN©3¤€Èä:C ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚È)€ r ˆœ"§‚ü<» endstream endobj 120 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <> endobj 61 0 obj <> endobj 54 0 obj <> endobj 42 0 obj <> endobj 147 0 obj <> endobj 35 0 obj <> endobj 148 0 obj <> endobj 116 0 obj <> endobj 33 0 obj <> endobj 149 0 obj <> endobj 124 0 obj <> endobj 102 0 obj <> endobj 21 0 obj <> endobj 90 0 obj <> endobj 14 0 obj <> endobj 150 0 obj <> endobj 88 0 obj <> endobj 12 0 obj <> endobj 151 0 obj <> endobj 114 0 obj <> endobj 152 0 obj <> endobj 86 0 obj <> endobj 10 0 obj <> endobj 153 0 obj <> endobj 79 0 obj <> endobj 154 0 obj <> endobj 8 0 obj <> endobj 155 0 obj <> endobj 72 0 obj <> endobj 70 0 obj <> endobj 115 0 obj <> endobj 63 0 obj <> endobj 62 0 obj <> endobj 128 0 obj <>stream xœ±NþCMSL9$øøø‹Sø¶ù‚‹ ‹ ©ø%÷Z÷W÷Tns‚Copyright (c) 1997, 2009 American Mathematical Society (), with Reserved Font Name CMSL9.CMSL9Computer Modern$Æøˆø•S ¥©÷è÷Žèñ©¥Ÿ÷ Å÷€Äøù6÷…“;y†Œ‡Œ†‹pqulr|¢Â‹Å ó=±=’¹l„^û‚+"‹ ‹U£fžw¯f¬„µYû¿†‹Yg¨g¨ˆ¶ŠšŠŽŠ“‹§¤¢©¦w˜vS‹Mu/ÇQꆄ]ª©Ž™ŒŒŒ÷,¡Ì÷‹å‹÷ û¥e”m“r5‹ã‹ÓÎÐã•nûþ¥…ßx‹+‹@I9/u¡øCœ÷n–‘¡ûb—ª Ý  7Ÿ ¤‘ Ùk­¬ endstream endobj 55 0 obj <> endobj 129 0 obj <>stream xœ¥X TS׺>1ä䨨(Š­=‡ÖÖ:ÏÖ:\œD­(Š LIÈÀ Â£€€ È ¢8k©W©š:Ç¡­·Õ:_Û×êºÝ§os×z;ƒ$½êZï­·ÖYYÙkïóÿûÿö÷ÿ¿pèGðx'Q¤,’Êbå!Áb¥Û˜€±nSgÏž5ÁmÚ”)³ÝÜ#å!~7O?¥80ÂO‰án_JB•±nc払Jٜɓ£££'ùE(&IåÁóÇNp‹QŠÝÖ*åQ"·¥R‰Òm_D ›ys“Ì¿‹¤2•2Pîæ)Ê%A|î.ññ.’-Ž\"_ªX¦\®Zí·Êul€§hM WÐÚ`ñú/7„…oŒøÛÄI;&O6}ÆœOæÄÇ„1›E¬%>!ÖŸë‰ÑÄ—ÄgÄb áMŒ%6ヘ@,"&[ˆÅÄ$b 1™XJL!–S‰åÄ b:±’˜AÌ$VžÄ,b Áƒ‰!ÄB‰F8à šø€#‰YeÂH ~áIy?ôcûíê÷ß|Oþ‡)9ÿÎd$ …Û„õÔ,jÿIýóúÿ8 yÀ5Ÿ9†:ž4zvгÁMCØ!=N¬SÏÐQC›†þs˜ç°çÎã×:G:9†¾‹~ŸN¤¹ˆ]Žs5ƒ¹`xfà†Vó81^çþA§5%…*™ É©iáh@o¥k,©–°Ð:°—…<²¼´´ª€˜Õ=ÀI¤n¢@¬¡aõ ¼o6ij±$r€Ói4”¬ƒÂV8)ï ¥%s”žÚ4Êìž7ðžáZ#Ÿó€Gé_·½u[\h Ó]áÏ, ¤Ø§ÉêÔ½Ã6‚Ÿ“e ؇ ¨ÙÐüåöþ“'Ëk¤&HðªÓªqv«H³?NeàÁãð;P&¨±Í»YÂÛtì*ôþø¾ ¢´¶HñÔG¤Úâw/[CB ÉÐpT&PÙðøÃbFTìOpõc´Z+Ã`4‚2ö_d¹ÅC<«²ìÊ ÐÇÀ{h„J#ÿ"é>ãu½ªH›+˜MBòüã;烮NÝÇÞ®k:NRÆ5÷ŸAÃP }à`á½ê5áÁ²eãØÏP eð὆Å;|ƒÖÏb±³ ¼là}m„UÞNC§‰¿"LƒœÓóqÐ:<€¦Ð^7=¼tá굋žÓ¦zyx˜L$8`àuáñÛ|.†»C—ƒú0UzbH<£¬Ú^¿PÈñÑH´-‡ýЇÐ þô¼M’3"@d›Š}œ•¨©³ÿ€ŸÀ±?½¼_óc rªbóäûÀn@µƒÚ*“#$7À ¯é 5ò¡Éi»3ÞJ6GŒ=(Èñƒgþ†¶úÅIÄìM¾ä/Té­¶§Ê.–>þä7WÏ/›1mårÅ¢Î0}døÞ‹üóöç ëUEÙC ßû~gÀ3á84‚E½]4§z,„äô>ŽžZ‡Ý삸dàua%}ÇÐU 6(D‡3aM"Ý& ùé|‚ƒžŒäã‡ËÊX$òµ#í|²¬‡mbž/é_Ò¶ümî¢UW<¾n¸u»k¾—eóPj€›Íh 3ö`¼æÁv#AL» Sæ¹Ðâ8&ón†)Þd PZæî[S‹B˜Þþ¶0{UÛˆcÉÖ¢ÝmìS«e ³• -Ž»q Õp5ýÛåû`rƒÒJU««h¨J<úÅúÕ o_¶Ùâ9ØÌ~ºçÚ![i‹ñ­Ù!2=¼ÿ2Bcöáëhèòö¨\ f¼%*'2Þ”~&0[zUa¶œjsèCö%È ,6ð9wî#3»•‰i»˜Àª- Ö"õéÆNÅžT¶-ª!ãe|]æw°™ —ˆÇ¯ ÐfÒª3K¤€ÂE³S„j k)/+lØÍœŸÕ˜®sôOž oV”³ûäùËý V”€vª®¥áñãÜ•–É‘ÖÛ'B’™B ¼v#¬Àò†þ´®Î*EÈѦ:dê<±Çr@-Xð ~ÇÞyy»û˜ïü6GÛj5Y¡9¦tµTƒ36H¿Çäø ú­@ž¯+x®³¹¢‚,Nª7ƒhAå¼áe5Ž7šÏYÅõ£át›T¢é?VZD3s¿šñ5¥ÚHMŽº!¾~ÿjq$HŠÎ Ëf²|T¸˜¸ƒn=k¯€?¡Ç·šë¢õ¶Š“ñ‘V{zäƒDÐ篳}ñë{U »š4ضJ•P„d ›¥¿Ì’¯cì«<ÜÚL¿Ô› rÖüÄù ±™5Â7çóȉ—#ïìïÌoêbò"ªA% n¿½Þ¨0ˆgp˜°#|iKy¢W…»q—Ý:¼]|iàíå’øÜV| zÌóQ ²½uŠÜ† ²ÉÌúø³©Mê¯2÷`©Ž_—¤Ùš)§²ÉÍð°à”íAüô =‡îÖ`ÆŽè¹Å=µ?h«µe¸ZçJ+< T^¹šC8ÄPØAYð›jxbà}e4EÇ͇è»^w‘Û¶Ñ`¡¤&V¿·¹àÓ[ ŠõݱÐ5,š›…\·‚±Ô‚«ž/öÜ»}H7À<µ¯Ž…1¬ûU(AT@tpÜv ¨µþ­'kƒNZ¶Ð=|Øÿ¤á8¸NЮ³b1Õ¤,¡aM ˜E;P‘é„}Å÷Sòòþ»­@GÁáä#(€#Qº Ib¿c!ŽDX+ê%ì×W¤æq߾ɜ^@F[4©šygÑBÎï.Jÿ2B ¶¾sækÛþÐlÝôª‚m#ÎÑ"×O°:êq^*b˜¥Hc’kmàöx]øŒbâT€Ÿ³;§¬ÔPXQâD’qxçš‚„òL6? ‡ ¶ q®Ò™I!ј2iÑg"¯yCÖµì9¥ù…% œÂˆÇšÞÇ8ÅìI)Ú…ßmÄü€¢W®Ú¬¼D ²•óÔU€$IžUXåšµ_^ (ilŒ, yç™kÝî7Úš”ëFþ”ÏA­S©4 @•¤©ãü–êó¥Wœnþ¯(Ëylu–6[›’RŸ¼PõÕÕõ·>[‘ûôÁt4ø—1pÕük¹-Wz æ÷!­ Ðø§‡ã¨Ò“›“ZWB_×䯔¢`@­³0BšØ^•0Ba­÷,è+ðésÁZa¾¢HR$¹‚D®y‰»#›@Ø]—·ç"ôvÚÚùzJÛL¾õe•°IoÕðu¤wÕÉ”=ŸÚÌ|ÂJô>¡ ¤ª* v#Vnþøñh(òh$ŽvU8À†ƒ¸ÃÌ_dǺÐÞÛç,\ºöʃ‡†Ë7{Nmò¶1ëq”c06q×脎( Ôâw**a§™\ˆ–,Û^á[±Òˆs- Ô=F¿R{ˆå´z¡M  {s!ÙdÂѸqÇ­±Ò—à ¬wa1î&çÀutu è€ÔÊ" žð)ˆœ^ÃáûGéM4HÐ`°Šõ«@XfµE?§´—èª{þ\‡¶.¤úzÔ³–r)†çhx8ªy"Ï(êB‡u2è W×ÔÃà òGyôL ¬I:–x|zÀEpcÏÑÒÓ{î‚; 9±Ô»dX ¼À2°4qc²¯B5P¯»舵|%ÎË"SAìoWû#o~£mbreºx ªêÊZ.ÌêùsvNf7·È¨{´Ì7Ú¤x´µýYl€ifuI1·té4®\pàõ§Ož,~вHõ®Ž ºÚ„BBr*‡ßÉ燖mÚä¿l?“Ä\‚s¾9} n¼Ä3˜ê^Ë> ¾H§ HÍÇZ›dÊãRP òÀžü¢zusJ3 žoþÜ’ÒWÇÖì)Ï)ÓDêRËp«WU©¯W5oTîH—±ÒÊ1 &º{L* «T°)ñÉ‘ øé¤9YËüv­jjú¿¼ 3öGÏÏpZ $Ì(¤}vvuwwu>ݵÓÛ{çNV‹Ó |°dç豇ºÚ[Îc_ß­Òûæu®z³B÷ªþÿ7Æ$ƒ·µ'†ûãaã{Îø ž¥Ï´6_S÷çÿõgвÿ]_""Oß"õ@ŸÝYƒWàÖ€Ðʰª°Æøý€ºP±«M R0x¡ÙlzV°ZŽŸ¼ RôŒ³FÓ*©ÍÌ¥Ó~z)]%Ÿt®Ý¾Cä5‰}MÐï~ç™ycàÎÑ ÊZ©T©”Jk• µµ òB.¶; nÜLÙàé¶qñcx‡4ƒÙ—[g®ÁÖk|nÝëû_Š&"ñî\›+ÇšÄ[0o¦wcPq"{hGSÚ­¸â]WãsÁ¥è*BmÚù¥»@Ñ^³­!óPvUöÞìj±µ[F´¹]®)*m*dŽ…’NãBIÝøùQKJgøAVt|kIðî¨| MÞö’ààuòøñ+PX>Iž‡;®Šì½¶®Ù¢nuF8ÔôXÛ­¡o¹¼G†¤¤ŠÙ¾™n8´WåcÇÅÿqK°$¿'?¥ó0,¤á@è Øo×–N±%b+‰& Qø«Åá [¾ŸèUùÚeÿ»{Þ-òÎM|$ca ë‡èh3þF/i­ès;¢¹à&ÒÅnüÀn.& ):®ÙÀ«äÔ|n†§ÍT$ ýزùZÐÆ.AíšMª)þ#²É¬š´Öôº‰Ü{®mµÖÒõ±eûz¼ï--Uã~bDî ‹ôÉ$ït$MŸÛ¿¦kt˜–ì 6û3Yy1Ǽ1éCS%‘™Ñ·¡– ×€ý,êö}CzdûÀ %cpmúêtx¸¯¶ýÀËàW s9¡þsç~Ð’\^]WѤK-ÌÈg*Ž©Ã¹þ½qÛÌ%Þ^¡Öko¦n2ðn>5o> endobj 130 0 obj <>stream xœ½XyxSe¾>!%±Ö5Ð8Î9UAYEGË"*RA ….éÚ¦Kº¤Ù—“ü²ïk›®¡¡;…B‘Uveæ*ŠëŒƒzÕ™qæKçô™{¿¤u»3÷:wžûÜ?Ú§mzNÎ÷¾ïï}ß_8DÊ‚Ãáð2Wd-,ñÓŒøÏ8ñ»&Äγ–»R¤#ª‰Ê…Ԕλҗ߆Îߊä7£õ·\gG…*³´¬V\X ¬Ì¸ûÌŒ=¶hvƃóç?–ñ´(O\¸=gGÆŠœJaž(§ÿR’±¦t{a^emÆýO++ËŸ7O"‘ÌÍUÌ-üræì Ia¥0㥼ŠìT^Ö™Òn°YýQ4ýSÞEG}¹dÚ Ú 1¨!e^°ºm¦Fua]›À"ð%¥¥¯ÕQ5¿ª–üȇy§‘ÑÙí„] @é<”ÈÖåL9mÔð?“ÒÄYMö™jA«&ú1hÔè^=Væ†à Ð*ô`ÐKiöÎÑ•P«yõ ü¢‚t¼ž×ŒOâ“iñÅŠHüLÐÂk\D»ùfǺù#°C"R‘RWrR7¶·4Çö¼Ò²våö‚ J±OضíŸ?“@Abýö˜“Jyƒ;Cû»9èMô6ÿÞE[}yƒ¾†iHœñ[¤°˜‚Vê*5Ù̶ï‘ÂCXûLEͯ€|”wy¿Eꌔ{Û -ˆuE´Q>ñ¡”óÓ(©z'={-»a 3C m:ƵI«y™àôÙÀl à¹]¤h;zÍ}ýU<»óN ©'¹ñ»â<~¾JÀ@ªì5­Í‘P߾탙ì [æf=y¡¡SC +÷)a=¹£â,§|c¸ž¶Á –VG¥]¡Ý¬ZsdÛ{hÎJÛU¶K"Ty{¥-Û%r8`/^þ¨³W.tc{ªbH‹OŸñ #OòM“,ßÎxÁ©¬ŽçðŒ²Ål5+eç~ÍNBsN~>sœ¶×6åúÀ&»-äêµ·8bŽŽà%»ÏöC¯‰ôØ\.»Þ¡¤‹¡€)‚­mÉI ¡‘ëÈÅ â«Ã†6Æj¨jë¥âYlJÕË@ÎYxeœé@OŽ&Ð×>û¤ù0_?zïßÙºŽoJ eâ,I=ÇEáø4þ‡¼£­Ähÿ‚‡­O‰¬‚ÌS_¦¨ªÓS¹ìü‰ðêc<Òïð³`ÔÕ‚TÛ|òëchºÛ#Ffd´Té’œµ›€TÔ™\–fl*iqb#œ'þ³ø_øÎ]V÷›@6º!ìÒXÕt.ä0ÛaäX¶'Ž«k{—ž(ÔA›PËÏFûÔEÕrT)¡–1)}ãj„=ÌîÄEöqµ¬‡ÇŠ¥âÿÅO¸Ä«ã“ùc§"§’U©Kq¬4•÷bèØö&v:ûÀô“Y¯Ÿ:i¤=[ză°"»¡pŸï8¦7FR£¾FOÕ-¯]_d&Ø6vºçùªÂ~‰*‹¹8Ô‰&úéö³yÚµH£#£¤ÓF:Ç1pÄâ£Uhv´åÒkgì—Ém‚ éÐÙÕ”4ÌjB¥(q*-f^î1ZéVÈA R©NÇŒF£gŒF½žý»/ýtÙÙewžA³h1ºetlgrkÉûö> 21€ HþëöÃnË À ÓŸ ÿ˜$VƒÝcwî²…én”îG©h"Ûmo=0QžQ¡ÆÓm…ŸÂåÁÒ ¸ƒD.*:ߤtÉcØûDc„½†Na÷û#ºÈ½ÑÝÕûIXíЊÕr Ô|o~[[6m(Ú&n $rÂù@NËb§Vʽ`ÃBö[éæ+‡^²+°£¨Z[)Ë¢…ì]uKEù¹ («óÝæô4Cˆlª÷ÖVˆ%EÙ${^íêïRÁܾòý@~s "cC/ÓÓ¥ ² ñ›J£=«?øÖOIòqQþ^štU\â¢#³ø¿ 'øTæ:ýªti¢„Õ‘X°¡aP«pä4ÔŒÑ{µŒê‹†ÿÛx–Îø"ëÔ’uÙ[5jÊ0šÆEv¼¿ßÝ×x•¶5¹{Í–}—‡Zb@‡GµŠYRVB ÝXT˜hSÇ…#ˆÿ‰ïêq¸¯éJN¬GiÖÒ[ ›ÉÆã³ul|~’ë±HZ†#Édr„ƒòÒm‰œ5'sVfÔ×k©Âù9,É.ò¡,™Äõ\+NÂ÷¹ñê¯ùzŸÊ®Åê44ª—žy¼j3/—ô¿¾§é«ÞsôÎC‡ö/ì5„r·è y8¹vtè±À¾á­ËØ;Ø)ì=ìô‡Ž<ùÕ§<ÓO%Ënâ¸#Êø~ðÌ€g¯™txM!ãTÒ%PÄã ZJ’^16 .zØà©ÅBkÔ4lÊèútvC¼I6šª°§~ë\û!PãÇ‘Mm¯þm¾Q —ëÔ6‹î„nË.œk=cíh¼Dkèµf]3„Á vkÝw¤#ñè'v) €Éb #S܆ahÈËÈ8ÈER\a~ ‡½þKQ×k!÷å .›ÎΚÃ.gSÎ.ÿ`ì¼ÿ½eÊßôà| ž£ímüýhá—?®›‘hû<‡$ZÕ9² ÊA³~¯ú€;2_ÁGó@Ü\·³Bœ:2ö¡¯§£Ÿ£mHˆ$HAÎÃ}ý©'^C3ßjE\C)ôéw߯&|õU,Í®Ã_ìJ: ]`sÚBoÇkchîÛ¡6ŽøºŒGµgÄûc‘Hä'xvöYî}îý=X:-¬/P2% %%Ay¸¹ðæHî†Â¥†*6,c;)}Ù ùå-%äσ¡v©@SÖ°V f¯!Øë¶ÄÀžÚª²ºü-{ªv_B³ÐmÔX;좳X÷}ÌE—Ñ>šÃÃŽt;â"Î{Ë.°“höøwoò/›5Y5 >Äwõ:ñRE^ç]8YµX­™¹1‹VȲ·&º§€‡9Çh¡gÛâwaÒSpʨ~œ2’ziŽ’·”Çp²›ÆRìÌŒó›NíîkŽvÒÕ‹äu’âBAiq‰BˆûK¹Mfµ˜Úü°“ŒH=5µ¢†¼œ=õï"Þ•Ëo„¨´ çÌŠ§“9óV`x'â†èÎ7†ú€<ë|'cP—{Ißú}r!ûiÛJæ,ÅN}+Yõ©GÖ³·u:(ï^0»={}‡=žÁ¦þÎÎÿ³Í-k‹8_ˆ‰UT5cjµ¡CØäŒ¿õ·Üx3ú”RÚ¿x>&¯=ú:{ ÅFþIfû0³ýIfû¾k?bö<òMD<Þû5Å2£÷ ée>”‘Óþ¤oü0ög7Qd Œœ¡j^,)Ýd¥Â¿7lÝcÐ8ï÷Aœ(ì{¹™œàgðΣÀ˜Hy»`@­ëcªƒm5OmÉß”·F•-]ãäΫ4åÔài.zo„ËÊCÕÕâÒ­§­¹¥•òŽVòÿ!v!{‹'FûûÀÚÓ}=ÝÕâé„FòÕ®ìÙùìtÕX*Ú¼VÊÑÞñï't{ åIÝ+´p®¶¶>‡Q ÔÕª |Ï^¯àmu>¶‘ÍçQéyîÈ”ïˬ ÜrѨTS›_*:¶Ö·»è-¸'ÝÈ’÷| òéitSQD;T ™‚ÙÌ~ð©'»ÿÜbk¶)¼Ê™p”$ÖXc¨ÕSØ­ Y‚A ±éœ³Åå Z£áV«}ÿsïéðl¡[‰÷ì;p p.ÕÚo~>œžë«êÅÝûýw?úøËöÅ™¥F†©¤ð}°{'T‹[^b£Ã7Äâl'~<ŽøŽ‹Ëä0ïÄfM~Þ£^V®ÙlTÓFSŸX˜ü`ñZÍ*Š–‚ÙŒ{¸À¯„:j4«Æþ£­]É>›F½ŒÉUÈŠ÷ eÁÑèj=ˆîmkBwBcÂìP$¶˜Ä“®j €làÕ'r¿}ŽXÁ!8ÊLèÏ9®?ZÊ“‚Ä$5UZÔ¸ïA²¥âp·`¦âubÛ¯¹c‰wnÐ5øƒÄA!vÖb(üoûé"6íî™3€\·ºë³¨-†ëÚ—ñ»»ì®ÿU/œ=z«®Z/†j;éݧÿ€‰™„ š¼ï EÛÈm{9×ÏŠÏdþIC¹uT?¾&lêÞzl_S_£‹ ÷úNþ¨PWΫ)ÿ°P§\kŠ#÷&ü+Nÿÿ~ ´tcÞ&!¥>±5º²à劜uªÃyÿòúý÷kv´è‹¶w{;ì K6×jEŒŒNû«»*2rwŒóWwü àR»oÈê6Yà"Z›†ÒA ³þ{!|·¸{ PrU½NźG ÒËãjcȽhx¼ã¼ !—)À× -¢Äµz)æÝ îÝ­ÂB›´– -0Z«]o 46;.àùðŒïhBÈ¿Áw*Äx‡Lš2½k”5Õ€6 ‚ØœvêŠÛÒÛG“4ø.Üݸ"EЛ‘øMœøŒ¸“ÿÛ‡ÝJ“Ñ‚Æ`cÀe°68i6å<šù†Ûp@£ ¹;{Öa4o¬Ÿ ¼*§¬ZQWÃPbvþün£I ‰TÒ ²ê¼M|޽™\+ÕB * Íþb;ߨg4˜ ¹[íu7Yc¶„ó%kΕä"<íödÑùã¹£ãUmþÁ~›îþÈî“úéMð×èˆÉn¶‚?+ÔS,Ãóœñ½Ó¸·éÀPè.Á§ S¬1Ë¡¬(›vw_aoÑÓì$5ûx1U3câJRæèdÅ*0Ô='P—ÉÖý7%)gwÅÞO÷£ÐT\’â\´âçCäã¢Óh¿ ì`õšö°‘‰îF±y¼ºé ]5ž(™‚x¸/"𚃸\T}ŽßR)-Š*CÕÑÞÎîÎ䇋–È_×4q"ñ?qGˆ‘|§7Ùsr‡J¦W+µÔèá¿=ƒwÁd{ðj\>«Ãc§Òªšã™Ti 6óØϤØäK7R“S5¥ÞÐfOM%ˆÿýÝ' endstream endobj 36 0 obj <> endobj 131 0 obj <>stream xœ¥W TTW¶}eÁ{O…ÒP¾ š¼BEqB1jçgp0*Îj¡C@‘¹E@¬ªS2*NŒ*‚Paž#m%±Û¡®¤“¥’Á ?†Ž}¹ôúÿ“tò×ÿkýuWÕ«á¬{Ï={ß}öU0vƒ…BÁ-ò]è7ÃÓöq‚úõéÓ§é"â¦EņÎ4Õ5q»>ÌuMH\HlBH°«wT¤Þu…."Äu »iEQÑñúXWߨàØH†aÆG.ŒZ½8Ö;NÿV¢.pyropÈÛ¡aÛ×…ïŒpØ5mÆ+3g½Î0+™qÌ*ÆYÍŒgÖ2îÌ:f=³™Ìø1 ™EŒ³™YÌLc¼oƇY¼Å,ef3Ë_fÁD1Ã'FÍŒ`f43V±c™ÅrE× ƒN*”;ìFØùÙIv}öÇÙ©l%ûÊ]åuügƒ— ®’>äë¡s‡æ;¸;h•ŽÅ޵Ž]*Aeæ1,cX»lPõ:„O:C­NÈÒ€¬³º~rÍ[Ë2_µ4@#\1ž2w'yc‡Š×ëÊ扤âCr?®otŸ²a_Œ¨¾‡ GægÚk9uÛµ|Ö¨z¯Ð%Û¬xTrBwtÆ‹8–pè±F*àQ\Ê=9ö¦ÿÜ-¾“5ȦÈÿà*Ü㿜õ1™-öyk‘éëfÕ?F+³øúg¾ûfö 2´P3›t d9¶á¶$¨ 8£ƒµÁ§AÜD•|;«IV[µ8óq„RnÄHGMB^%ÿá9ž¸áÜñ |óá&’²\ j@æa¼{´Nsü–²h–]åaeÛalágaˆZTõÞÊäŸ$EzȆeo~ï á8&ï5÷eŠo­ò=¿ä˜¸ ñ “ˆŽè>Ñ‚+ч!WºÏœ’¶RLš}dq\1æÀ«•ÿ¬½œ~>‡K9È\ÿðƒ_ ÙÀ×óʉ:'Él¬þ„Ùr‚ÖÔ‰lpŒUVt59=¥ÀÎêO0ÿ.Àq³¹¤¤©ùB^9ð7.­ NdŒ×Æ¥»µpq«&ã˜á8?Ç®5ììžfàqòŸ£]<·ùv&ë5êo;8âeCâ¢é3ÿèœê'{änIA1}IvFw%º÷ª…¾nJ‹8Ü„“éFw`4™ŒÙ¬é[¨eÑÐ×-ÈÝ8û>Mêðª÷+ði@é·nñ™¹kð*9‚ÒåŽ[×I÷Ű6±ºº¶¬é½õÕEu›mÒ/çU½¡t• Ëß³m`,N—ðeIÙ;²÷M¡ïá>¥û`ržÀYèTÀÙþÈh¬8Ï}S°@#a–]0YÜ„åèÊâl¨˜{˜ æ%V%oʲʣkZt·0¾9ÓsŠ’ðvþÒbøk_Áñ» ‘ëˆæTsvð•p Bó1gcÐ~#$‹1‡Âò‚€ ´<ÎA¥Ñ¥)𦰆¬{»yu·5ënÚªQó§Cü˜˜;­ébvI6ì>²ô¢à’`ï±| .ÍP~8ÇÒ~J¯Ái€ZëÃNiÔ÷‚«Ãóæ¢Õ^›Õ„ÿ%á¼REeÑIÙ#ÈIÎõaü­Ú.ßßÓúq>áqQ«¡«BÄjœ ‘ ¸VË™Ü7OœhàC9JÆ,kè{TU~¥)IòÒÛ½òì%Îw4jÔm2U†e¿¸–{Íoù†ª‹">þÍ?»9×OâÿST'€ÛÐ~Ÿf¹ä9ׯ*±…ò Y‰ 4L:&A`G‹,e«åšs¾ƒv:¾ƒæÐXšã­ýeòpIQÕ[¦ì—„‡r ®/qzc„)¢Ak‰7Ûfá ;LC–É K ‹gì/Il¸i£1t ³ìêºÂ•m#˜`¿-òM²näX,¶M°¶Y¶? D¾!ù)¹{ªÀ¥ r‹ò>Ń#Ÿ’ƒ¿ùîñR–5B•§ÑÃêT‹ƒçâ 8ËVÊyÈ=a'øÿC<Ç–„ÊŠ4HÓ¬0Ã!¨à1œë^ü™´†¨öÏÜVŸt²¦¶¬åtÒQƒE<•Wk>üÝzÝ<ÍvN--6ü½dü¨)8<ù¯¢:ácšË[øœ!Lå¦LO‹õ ª?‹ ¾Rr>GìÇ4¢L~ÙŠ«;Ñ—TÜ!°ý}Öô}+q—ìÕ™ë»G㤞~=ñxLÆkÔ© aSd\"ŸG:ÌåNÖŸ«î¤š£â襅u1ÁšÈ@ÿŒpð‚à‹{Ócéó Ðx•Hg<)hÙLïò ñÞªÇh‰Ýf Ø Û`„ @Ï ÏMN%÷­U~_R”#§”s(Ôù%9ù]6¨ã(Ô± [- P[Ú Ý´ɤ!15VØ_”ØÆ&DѰÀþ°.WöÑo‰ßî³\vƒÑœ™S˜[Qõü™¸ÊíQ‘IÁ~RàÕ{ï_»|’6Út†5)hÓYˆ/(±Ož"$ï2&À^þgˆ>o5ñY@—å‰Ëã©8 ÿtùü’ݰ'ÙdLËc–oIòžhÝÛ/¾ˆBýQƒáFõÓGÏj4ñ=ù_t~¹G dŸ|"£*âiωµ•ã* ñ&S”!Î`¤[ácmbv™*x \xv,b¹dH1'["sLT(xY2sXÕ÷]aâÁìbp)…‚ù…X+“‘æþÚ²Öœ¯ ™ŽÇÏÄ–0 F"1\Rf)6³{!‹=š|âÄÑã•)õþ©ZCØ61ù ®lݯۺ9^¥µ´ù÷2QaY;FAjîæ¦ð4ÃÂXÎûuÎG-zÝ¿rótæõ%uâÚS+a ÄPíÍ6oËÏh€cP”{8¯€¿FÖ 8˜­A{ð ^O^$›ÛÛ¯^‡M¿õà†âç>¡¤2.Њýl§ßê ½ˆ_ÿšQ*¼Ýïr»ÑÓé>z’!È8«¿B½¼A mQWž;ˆs‡¥NûFkÿ´¾œúI‘|C8Z§  ¨km±Ö¥ŠØLÓ¿ÿ¾¢EÂ}Tœ2©8é{_þ5›M Yö[ˆöEŸ ð÷úî-{1‡Bv…ú¸8p`<äûq8ŠÞ("l¿Oè`ÒÆNõ:Jj—ö²ÿoÔõ)).Ì¿.mˆ¥FÃR‹~@ + ÇPÉ÷Oî¦ ñ¶”ô½K…ϧÖ|ÎÒ ­Ðn¬{î×üæ^¡x9«;þ·»ÅÃŽkuå‰sÿ'ÿ!¹¿f7Ï›ücÄį¦ç„À,X³5|9Oíðó»Hdz»ˆSÁµ—»P}Üj3˜¸ ÇÙøq^©ó©Ìƒ0 ùËmRžÂ‘ÅY´3˜Àè¢þ”¸Ç~ö—†/«Ë²Ó*Ä”¬è⃫c¬ïTW5_ØÖE‘áÄ-˜ ÝŸ Ãï§ÄÚ¯nc¡Uò-¥| kß-j©(è©ø=•¸ç¾ÐVð3[ëë[mA1ʒΖ*0‡*ñŸ½J¡Šb2Œ°o¯8w$Ÿ¨-e@§ùÊq¾¯„h´ÜÙœ§ÔÌvÀӟݬ«my Fã2Ži—Ñ ½QTÊ%K»®!qï²Ýû2²æÃ.ªî¬Ôx¡µí ²ŸuIð5ܸ¿Q­vôð±ê\jemSùù º#©¹bueC±øí>ó½C|¼kˆ?Ñ¥¥S·”è’,/°-™ÑZ‹hßx_nht:GïFŽÔ3ˆø2}z8« ƒ?âÂ_Ëî\†ü½y×è:Cç,{# &º¡­ªö÷×ï7‹õ§ÎÔÿiβi&â<.Kh4š²M{LÆ=TíÔ}ÉEpL<ËR÷>ÉO ãÇÅlÌ=½Es¦°ª šù¶ðšmº°h¿ß®D}î|ÿ…H†ÎÈd| ß_aTH²-ñ[—]žÂ·Òdù5ö¤ñ@T‚É”š.’úÞ²×b3Q;-×ó· B}y'sÔ=z X¼n?*Ž|¬<è÷È’f»ß£Q,¯*Ä­eEÅ,ñÏç¤!ȇؽZê0¸)ßÁÙSŽfÃü7ić7 endstream endobj 34 0 obj <> endobj 132 0 obj <>stream xœcd`ab`dddsö Ž´±T~H3þaú!ËÜÝý#æGk7s7ËÊï]Bߣ¿‡ó``fdÌ+nrÎ/¨,ÊLÏ(QÐHÖT0´´4×Q020°TpÌM-ÊLNÌSðM,ÉHÍM,rr‚ó“3SK*4l2JJ ¬ôõËËËõs‹õò‹Òí4uÊ3K2‚R‹S‹ÊRSÜòóJüsSÀNÓ“Îù¹¥%©E ¾ù)©Ey Œü % LŒŒ,Ú?:ø~LÝ·àû¯ùŒG~(3ÿˆùÞ'úEÿ±ÂoV=Åß,Ï¿}g}ôâ«_ñâŸö Ù~ËLc߯µ[Ž‹E,­ž‡sÛ æe` 2^2 endstream endobj 125 0 obj <> endobj 133 0 obj <>stream xœ­W TTg–~ÅCÞS%é: IæU‘AbܺMÀØA% ²ˆPÈ^,žïUÜ‚* û¾X”(*ЍAmbÓlL&fŒÇ1i“éŽñ>úwΙ¿ Ig¦»'ÓçÌ©:ïTºÿ—ï»ß½%a¬­‰D2Çk×~wˇ%â‹ñ%+ñŸX ÁS§Ì[l­û^Z8ñØ£j!z/bX‰$&>×K—–q<\%w q•¯òðx}™|õÊ•ò 1Š„ˆàXù®`U¸"&XE¿D˽•! UšÜe]¸J·vÅŠ”””åÁ1‰Ë• Çßt]&O‰P…Ë÷+ ÉŠPùfe¬J¾;8F!·Ä¶ÜòðRÆÄ%© ò]ÊPEB,Ã0²X¥W\BâÕÖ¤ä”àÔ´PEØÞãáQÑ1ë—½º|-Ãìaö2ÎÌ>Æ›9À¸0>Œ+sñeü˜Ì!æ0ó³‰ÙÌlaV1[™mÌvf'³‹ÙÍ81 ;f!ó"#§Õa¬™,æ¾ä€dÂê «I6—½aa}eÎê9“6¡Üîÿ¯å¿™ë3÷ú¼óíæ‡Úò¶›lÉ‚ìlì^´{ÃN%ªíÄû`%8wc&X1¯KÿU1ò²K WbŽPúµ Yœ;'’»õváaiàs`‡É/„.è†sp^}ÙöŸMÜŽ¸ ÃmÜ“¾y³þèN¤ýï¶v¢1¯Wt2Jz&ñÂ$+ª1BŠöÎÈâàLbO쟺âÏPúýc´H9 õ`C’9á¬z.Ãix·÷¼Á|®e®Âù„öð®`­„@€æ€28.$0-x»©·“MSKM’ÑïÄŠ>vÊwj­´ª² KK³ó¿ ÇÏl~IYGÖÐg ¾AÖ`®C+tD»*¨ÌÈUç•Ê Èr²ÈË ø×Èþ«Ø‹m¸õݯ!¿•¬7È´ÚÂ:à¡¢™¦uŸ4á+Fñ¥^ ²Ø;ÉbY#)7äw¥à$ðøáìÄy­âÏMq~.í¸ÞWÛ¯åM\8Måäƒ?DO§Â™5•Iyšâ’|*+z2;Šjá”9vž‚FJƒ£jH…d8Q3gn‚¾¨>ÝÈ7™'hs×AÅÛú‹žÌøœrÁ/¤•탣Ÿ‘ÔçQˆ‚¸ÙóƒšêxHƒu‘¦p)spFCq-”ƒÎÑpRÛA=†ªB$ÑHcf=–7\AÀÁkJu%ÕÔ¶ë44MGH£K?ˆ±½ U%ÕJ|}¶.·@W¥«æ-2kÄ„.ÓCƒQ2xc'Æ{YѯH/»¼Ò}CÔ¶˜Ö4ƒ±¹¥«#³1I/ôwŽíë×C=dÑÜ>õVõ¦Ø_(Ò÷A$¿æ?â?¿pv MÐ+ ŠAà«îéþMv-úw,3#9 .V žW¤nñ!¾AæK¾w WêŠ# %çMÌ–ÍÝ}=&“ÙlxßR·PZ·@(†½³X5kt9 ÙÅ99Y;78¬{”C Oq‚Šõ–!joȮşëv ´¥Wwÿ‘Ø;¬”'(ÃŽyj#¹þò *—epNÎLœì²Ü h‚¦šºr}gOW¡û®«C‹Šò½ ³Ky‹Î^€fjtzfí‚<}|/­à rÔ(þÖ$iý’¥\ûBÚy£¿Ê4˵`(ƒ³Ètkê2@E¥…Å9rRì@x¬/¬§‘è;zµmÌ@õQ û¨vê4 \Mþäè³ið 5 «(k¯†nÞ˜\Ÿ”¢ÊŽ:62yéi•Ž4:¯O?h'1ü+Z‹NRe~‰ rø¸æ£¡µ©ç½-=¯Ù«„%óÉóß¹àsèdÆy55Ù .,.ÍS …ÉÊuKßµúº óí‘ñÊw ÍüçF•Q1h¹½oœÅ»Sž?´êq.ü´‹/Us{º)Yøíb|ntØh6Évr¸ì‡öÿÀy>ûHJ*ÉLQ†$úC„t$öÇ)†!øuåÙvsGÿ㸗{|ù™´B è>½TÜbÅUtlµ€öÉÃß'²ÈÍ™,"Rd–Òlž¿ü´]§®ÊÎÕidÇÝÖ¨Ó(‘Zc.Æ\„ ‡×¤•(¿×Ñ8tÄI«âíðÎ4QC—yã_?`ÑÛ"¶¶&²çØÜ¾0ØPYRªÒò‹Ó!›oN5t55Îw\¿ÚG.kÈ»dü§&ãTä“=x“r~é$N|ÇbŽIq» .ÄùŸ=yì4IœeÏØÈ6›ÿ£Èª±NŠ-\_YÅEá;ô" bE<-[ îÆ­cŸvcn·¤g >ëeqÃÇÒèò„.8'*+*Ï%œ)îþ›ñ?=~2Ñ ««1µkKÔÅÅÁ§Õf7Õ5R5Ëî J?R $4…6úï²qó¯ü á­)²¤„‚(H„c-Ñmé¾YÇB!€÷ú£7: =Z]ùl$ê\d£°·÷0¸_ñTº¾në×ê[díÆš.àÿ^I +ŽÏ¤)£ Ó€"ë¥]øsxÃçÍ—¥žGZFïÊf—Q ýþç>ú‹ï¨4¡ÙÌlIÓŒ|Vûÿ¸â¥éµ m‘µ„E_ñ™´[՝РïN6˜[» q#»iC|PYD¢ñ/d¸õPK±3Ï\¹½DF&2ÜŒþýçô2ÆâvJïÝúðê9}§ÖÑÄ%ª³è8 YÚ ²ý+ÕeC$§¤gÂ;ˆqÜßL÷LùUýºùžùQ ¿çn”ƒ!¼!Õ±>¹!¥!¥.¥52ùôTuŽ0£pton™ 2ÒtLJø™Ì-1Z²öžÚ.ý;>¯Oûùo>íþ4÷/ b-ovªböyø "Y°36CHûdËvpƒ€ÍÙqü?þâ³á÷Ǫýü$€ÿˆ­ÝÔGt,JŒâÏ,OÉh¯eUï˜@¶—²ý¥P¦ÂmÇö6[–W77²,úý+hsm¨ëì)Yí¾±<º>hûZ£’¬Gg²"«èÂçGvãb≑è/¼ÓtV¦+Óé@Ï×äB¦o“I‡Nz™ï'/ô¡7ûp%nÀ¸— þ_§â±$ËcWtÉ@»ÌsHJ‡¿&+5Aåü[Û?GÙ>ÿäÊ`´¢SVŸBïKµ@H¶Ò{(u÷YÜS/…ðð|K­¦3ªˆÏ¯,Ò×~ñ)Ú^K¹z$2)>6¦5ÞÜVWS^.ØáSÜ1&©A3‹C¸C:FÌÛ9 %è]‘e1èš´/®M‘§ŒèJ2öµu…™ßQñƒ8ÿ¯È¸õ_Ln½êQYõv« ®æLó&æ ó¬_o±kÔÛÚN4Ø.`˜ÿ*¹Ÿ endstream endobj 103 0 obj <> endobj 134 0 obj <>stream xœcd`ab`dddwöõõ441U~H3þaú!ËÜüÓëÇÖnæn–•ß7 }üÅÿ=\€™‘1¿´Å9¿ ²(3=£DA#YSÁÐÒÒ\GÁÈÀÀRÁ17µ(391OÁ7±$#57±ÈÉQÎOÎL-©TаÉ())°Ò×///×KÌ-ÖË/J·ÓÔQ(Ï,ÉPJ-N-*KMQpËÏ+QðKÌMU€¸MB9çç”–¤)øæ§¤å1000Ú10È3012²þèàû97eÁµóïýøÎüÓü{…è´ “'tOïžÞ<¡aŸ}ßgJÔMêìîèæhhjjhšÐ:³EþÇÂß=€¸¶¥­µ»I²aJÓ´¾ÞîI3äøJþpž6mÆ÷Ü…l¿§±¯âºÌ-ÇÅb>Ÿ‡sÉDt¦vÌ endstream endobj 22 0 obj <> endobj 135 0 obj <>stream xœT PTç¾—…{¯ë+×ÄÆîÝL4ƒE4FkP³ÄàX•H1CÍ [ÃËeaayìƒÝ=»¸ YD|¬ —×F0;ƒblÒN1 ³1Ú´NCk§Ó™N´ÓœûÓN¯`;v&霙{þ;sΜÇw¾eâã–eÝ]žnCÆ£÷Zò4KVÇ‘oª &æ‰å'@’ ’â‡WóÞåèX†Ç–àÁ¥ŒŠe«,N]eU©´ÄhÖ¦¥j7lݺevcFÆVíŽrƒ©´H_¡Ý£7 åz³òS¦Í«,*5˜ë´)/Íæªï¬_o±XÒõåÕ镦’¬ÔuZK©Ù¨Ýo¨6˜j ÅÚ•fí^}¹Aû¸»ôÇ^WY^Uc6˜´{*‹ ¦ †a’+*uUÙ¦ê}Q½ÁÈ0û˜\f ó*³–Éc¾Ï¤2/1ÙÌAf'³‹Q+ó2ñŒù”Ía/Ç=7­²Å§Æ$|#¡*á>w’¸Ô$2)–Yäñ—ƒ*Ì'n±µÛ '@ I&®!dæ–ñf8 Ó˜ø‹Þq_zàšGvßHzVæuð~¯„ãƒM85—ÓÙÜXu:.HäI¾Þjd¾ÖsØm(ôš|J’‰Â³DoðêØ’Æ~bíg'fñ³*r;EL¥‹q)M¡©4‘.U¾i˜Lñ9Å’1Ó44DÛÄl÷!`.r×§~Ž t- qû³%ul &ûV„þ™t¨bj2'Ùûã5Ê@ôEº‰¡o âñuÌü+®ÆÅAè°6ƒ£Å#ÙèZºè»4„çiîM¼„ï¡þÊô—_|›¦÷J¾F¯«„³Ð~QÂþt4·µA“M£&·@FC/6(k\4M³*¼‹Vñá¯oßn›¦¼DûLÜ”ßqTšãø£NG޲Ç!0„á÷°g~9ÎÀU 7ó.4ŠcþöQÍ4‡Ëa[Q1dÑåe9ul"16Ââ¦Y’þPõ«˜V¼çk.‘æúøws–¦ºŒ¨9ÌÆµ˜¢ì%>‹t§4§.ã°õï¬xÈÝqI"WøK¾Ži0û~Qÿ“¬ñÜ®M° ž«ÓÊ?Z¸ûÍLÔäO!‡ŒÇÃx\^þh¢ü»…³ŸÈO®¨Ç½d¿²/ôw´Àyî|îÒ;ut¥ô<‡/[Å™ó“ãð3afãÇ4YCíÿ3÷°÷=ß ÁMwÿÎýÒïø7dè÷DÊ.Ö@5<¨{»ì|ÝXÃ8õL†ü´6{ZÛ$ûÞ,ÐÚíè²u Z?²¶LlRú.l”‰-ÌNL`Ç„Šþ¿`çFÛïÀÅ>…Q—©æ³Ü]—%ìÁ(íùº(ÒÇM¥y‘À52΄ØòCÞ'ÑqÖh†Fp;œVúÂ܆§š«êÏ-˜ø°oȆspÍZ€XïsÀ[Ð ¾‘qá¼NKw)8VU–@½rÞŸ*š2ïºûò Õoè2Eºû:Ôä· ¸Í²¢dIŸŠTƒX~ýêv…ÖiT¤‹é:ºi¸ò³¿üæ­“ÚþÌ û¶€P@Ó°M¸¾oü“Ï_£+.H>»×|Œfò ·ânyÄh ½RŒ¤¨H.±ˆAh‡SÂ;œÐÐ/9ÍL¹ÆÝy.áèäÜ!{ ¸À¹ª!! ‰ãNca‚‰shëwÑg”&Wr :qBÆâAEn£˜!«Héç^ýKTYB ù!< d×Óäêƒô %áŒÎö1 ÷ÌðwN[r$š¸œ&ËÍ˸•›Œ/8 ßØEYAæ0«WtIž/f‹ªH^© 7sWý)E–+<ûÝ5Py¾rï¼,ÿµmt÷WÇŽÿÊêš0é:ƒš®@˜‹$Fkã·„’ɤ¤è¹¤d†ù'+›î endstream endobj 91 0 obj <> endobj 136 0 obj <>stream xœ­V PSg!Ÿ–ªµ“.¨}/õ¨Zñê¡kkÛ­¬ZP¥]±h8…`!$@Î. $$$ Q¹(^ËV*ݶRíníV«í´Ýí±½¾GÝÙDZÝî5Óít2¹f¾™÷ÿÿÎ……‡a,‹»=)î—㿤汨ùaÔýìlÚòíüQuD²!2üÈü»»ç À=¨pÚ;c³XEêXa¡L”“•-æ-ÍXÆ[³~ýºÞëW¯ç=“/ådð xÛùâlA>_Ìü9ÀÛ-ÌȈe¼¥²ÅâÂÇW­*))YÉÏ/Z)e=µ,†W’#Îæí DÁ‹¼ÍÂ1/Ÿ/àM ·râ3V˜_X,ˆxÛ…/ D†ElÆŠŠÄ’x~ú6AVvNnÒüå+WaØl!–ˆ-Âvb»±$l–Œ-Ç6b±Ø l3ö,‡Åc[±Ç°íX‰ÍÂfcÑ X8vе“ ‹ ûÎ~/<9üÕˆ-or^à|4më´›¸yúœéŽ{g Þu2ò¾Èu‘…”~&õ™*H‘AsÉy…‘Ÿkkhj;ÜÖÚî>xWP°“Os¤Ï“U2MÈðý¡Ì3Ÿ@¤Û¥m™QWª%d[s÷¦.Õ»½M¿ÝGúÎõ Îã·IkSv‰¥„¦?óèo Ф%Ù²ùÐâJT7˜,ÍÕDý÷ìQÀƒ­VÊt r#ÝgPõ .s•{Ú«›;k{‹³Çæ³ùÁ\{Ÿ9ª…ºDGC¬ÑÈ;l´ã:W£Q'^\RE4èZ‚f!Îo&üî'ù…ïókð!þÇØ!:Œ ßâ”–Oô´A®óØzZϽ€Œ5ÇìÐÑh>aæÕå¯}ˆžIÒ)ô®T 6›jÁbq½ŽÚ£ÐNbÙ–È—®ZA‡“3©¾I0Ñ´k(xMu î—›.¯¡¹ô|z½„»–ø.Šf^ZDÐ^ÚΤz»ÏÿQû yòêPÂ@gÖ¦<ùCé[ȼ¤=™û€YµF]b¡Õ·Ù£>Î5Y̰à6]¥ÓB…šˆ:írb`DÓù´ˆ.¤åô“húB´MC¬‘‡È#Î`Ã]ÌðUÌ "™~’ž¿ýQÀWƼ‚nFKßEùû[9uð¯N?¶è N zrœ!—|6‚YÞBË'µ’=Âþ”žÅ­ÌÕh€W(Aª3«êȰY®ÂàÑ;àtäB›ÝJ(JÀm³·ZÈãhq@Ð.ëd°@÷ Zް¸³qIû2„Éòt_ÖPˆÜPeÔ’¯¼ÀµzLf·¯o¨ÇüH[Ñ–½¼>™—’ x¼ê¶Ýb¶™l -Ï©üÔƒÌÜo²‘µr-î—Ð=ïC ò¼rÃA¨Ä…«±ÍÝs>¶6g'?/SH¨;sÛöýDÉM VµxUðô ´üj#Ї‡ÑýÃlj15›­†|0à2w¹ÇÚ ƒC‰­»èyy4Kp°Vè/%ÒZÃ2 ;WÏáùE‡I-ý¢Ï ñ ·¤PTÂß=˜~­éA3î<â͵©59vèÁƒ-çÿÐ~´â@1QŒ g‡ÐF ÍaìÝL-à~ÀñÔ1Ä”C¹Žs-²ÖƒlÑM%6u^e¾Ú@¼H¯ŠXÑ»Ãõ仜MtH[PE'öæžúê<â¹ë “õJ-‘º8¥äà"] `§¥Ž[5å‚õ¯¢äØ”— ç^ÌwÊ%¡Â^U­!|» qA2­¤#6Ákõ'ëϽC8škƒàÃÓƒüåé4O9…¶×Jx‡Cƒ½€{­J™¸R¢“ùëEÏ2Ø,)¼€žDoŸa°’_þ„’‡Xß|Φ†¨¯¸5Ç««O^ϬkÕ;+H5hô«! ^°ðÇõY©`6t3Öp<௡Iï0‚’9¤# ¢J6ìØ¶ Í­ì;grôƒ”yªŸ×lÙvvÿõ¿Þyçz#ñO×GŒ°)5k²Yj»5(ëJÅj¡–+ðó§gÐwÓKé…Ë_ÞzmèTo³Ÿ¬É €ãÐð´ù»]çÁŒ§j)èEBú”$·p!´×M"»ã·2;î‰DÀSägº_:Œf´ô“Ý#½>FÿkתH½"âè#A E£²6º4º‚k²ší`…ú2c…q¡:JÁ|1YÎÄŸ{4j­¾Â¨!–Í5êÕ™½òìÖkg²sZ6aÑý‚Â"!Q=†sS¤§ºjOú„´·ù››uÎБŽÿâ¿™£Bˆú.Ä¢PŸqk:ª7wp¼µÐ謲ªÉ4دO…%Pf©'C£ø÷0¦çŽŒôèï#Jâ4Éd÷¼…Q6³‰I5³ZaÔK*‰œ‡Óh½ð΃ŸÀeц¤»ÞDö^6ò )·í4çtjÇ£cVЛV}äk´èÆŸÝ¥«Jc4¨Ô䞸 ¢$À7—½Ö×d?i?B:‚Üšý^ˆ‘ã±4c½2Ç5O§ѯƒw<ýÿS%¥ò-QáMft€3:x€^°äÂΫžP')YWÁ×äEóSSAr8…Ž&·ù#ŸÂ],Ir“/k†Ñ½oŒ\n d(ƒ«ÎŠŠQBš´·¿÷Ð×~²íâKÇ;v=Q®3 êïëhB ßLÔûU½xìºQg¨]´Â)÷7Ô׺m„ÅÖò…÷ [ Úϼ›‹îc*ïqæ1qIGHŸûI÷ƒ=ϤòEELT½39ìÜ?±Ð¼KÙèýQ6·Eæ,-.,y*¼V_xž~ëXS9ó¯9Q¶íòÀTNTI•Ùä&:A§ª’,zb¬ô@ÝÆŠÏMæOUíi8A2C04R·&¦È¾…„WØÔôñ)¤Î2aq¡¤´NÖÜÒÜÔBЩ߭å*“S7&@¨lzSS­\ŠÅù™Å§nܼt;@|@…Ù|LºØ£3:ö.L¤yŠr7ØêM—èýúLC àWeÖd«1]Ϙæ›n5B}Éu´ÙÍv“ÝÜ€Ò¥U«Œj²2>B; Œ&½ÑÈð¬ðƒ˜Cî ÚerG0+'ÆNpŠAY½9J«S6LÔÙ¬Õ`±3˜kZÏ EGÐ\ðA ÔŒ Ðëäô/ÆQª MÅjÀ•À{}g—ºÈN7œÐwnwOÕ‡’S e¦RS‘¥Ê 'cÇ™¨Uìc}úÿèmöXåTÅ$ôè÷·ÙZïq÷y°âS|•éEri\Öd VCíxÕ|ËšŒÞѧ'ä=Þí&8‡Hx§[”^ ÒÊ|rm52Ïíÿ¸M6\Ž²Ô´÷vyëC¾žŸCÓ›’É¢òêNo <ûvIÅ?×ý—ÉÕ‹ü¨³u1¾xt›*G%\ä¸ÐÔT J’nà\A«L`v©œJ™®T¥'6Óíôa޲Äâ¸HäáÄÑŒŒË•N•Ëkõ8-ãFÄf¡»Q)¯pˆëŲ„‚ü€¼¹ýØáމ« Åÿín«e4Œ=zïh2×ÁlÂP_§ªU*5jµ–»ô·§+™&ct¹³Â媮©aî?ëDb“ÇϡӜÓB3Fî"f„¯óENÚ"#1ìï>ÜÁü endstream endobj 15 0 obj <> endobj 137 0 obj <>stream xœµyyXS×Öþ‰‘œSTâ© ö«už‡¢­Ö:Ï¢â,2O2O‘I $+ ó<„@ ¨ BU«ÕZ‡«V­bµN·µZ­vÜÜï~;‰´½Ïwï×ßßOŸÇ‡à9{ïõ®w­÷];ªgJ ˆ¬Z7e²é§‘ü?´ÿÐkßÊ;“¬ úôÜ;tø`þ£¨¤ÚØŸ ÁI BBcÂwøúEÚöc?eÖ,‡ñöS'Ože?/È;|‡§{°ý*÷H?ï ÷Hò!ÐÞ)Äs‡wdŒýèÙ~‘‘¡ŸLš5Ñ=(bbH¸ïgcÆÛGíˆô³_çá¾ÓÛË~qHp¤ýj÷ o{óá&šÿ]*ô·_âåLQÔÂyÁóC„. [¾8"r©tÙÎåQîÑ+cv˜9ë“‘½)êCÊ‘N­¡FPk©¨uÔHʉE­§6Pc¨ÔXj5ŽÚLͧ¶P ¨ ÔVj!5‘ÚF-¢&Q‹©ÉÔj µ”ZFM£–SÓ©Ô j%õ1µŠr VS3)†zêEõ¡‚¨¾”5ÕêO  l(15b©÷©A”-eG ¦†P´ µˆäƒêI©ƒE‚ÿê'ì+” ùžA=ïY­±ú§h‘èGz]ưŒô½)ï]î•Ù{HïÈ>½û„÷íÛ×§ïkëDëûÍéWÓ`ÿÛ,°)o·œ0ð»’U¾/xÿü Å ë¶“mU¶×ííÎÚݱ{;xÚàÆÁo‡„ í?Ôÿƒ!Ôqý¹"É$‰·ý {Ì+¬;“Àˆ¶ùe:A]çãKüuka>8»…¬bÄ7_Óx˜Ì*¾’²Ubݹ™ rQöm¤y6ÿÅ 1Âù,RÑõš¬6õ=køx㊭X(yœÄ>+»|®3&ÝÅïs]=+E752_IW%-~í«”}ÆEòCEÈîÑÿ?˜u ó%«ðm9+³ê%¨ ­¡Ÿ·L\ºpÓ¬k^!3ð“õ‚š´§CÈ  õ÷ÅÆb€Ù_Ç¡÷Pß_~Fb‡agÖ \ËC[ÃÁ9h„ýp¢òPuk[ù8¥UnUn°¼Á6H]¥.®Á[€±îô‘;'mN½â ƒÄOO¡Yì‰>ÆSÐjäð3’ &²d ß­â’ñpûYXÌj¼y/:&ÿ‚ÚѦ½çàád Ô˜ù«"õ¾Òqý»–é »gvŸ5¢ú½4ô!Új@ã Zƒ ½ÅvÇy]Ô‚ò¬ÂEáxbä|ü90ØîQuègyK ¨4\4C8–›‚RD–’`EhT¯/ÆÆ AR«®³Ýu`Íé.ð7ßÜ$¾‰>Eß³¨%¦l›ëN|ør߯nÓÔÀhƒ ;éyʼF šHÊäá·YPi8…**˜ò]úRC~]]`­'¾9|—Æ»‘ŒÚ“0ÛŒ¨Õæznò·;g³]­¿—gywjE Ú[¤pšá14š7ô§ÇCAƒ©îÓ?åvì°Û7e¾ ¸ƒS1æHÀÖ<'Óó—ÙÔ¿@1†È/‰"/´‘է݃Ìf?Ï9¾§¿æªôÝÀ$@JŒÛÒ±’—¡V—•q hJ˹V•:Ó­ßüíxОÄ|‰W¶{6éTNyK Î n¨j¾zdL Ôpê¤ÐSe’_Ìe—ª„ÄN‘¶;)Má]ã»Hö¬½—:ù‡TK%â‡ua5ò¿Å&ÚÊ h”…ÑLà×Ëh0áÀ<~‹†ñp´2\¤šd?&‘~kiÜïibãÕš«¸Óáëiâ|–ÂãÎ" _Ñ^£åö‡B¾“É6jònr•F‘Ÿbi<Þð9øi ªÝ%…p;J ÿâ©? dç:‘‘}pÌÙ‰ ?3Ó¡µã¢¿zŠ´™^ÚBè÷»ºDóCn³Sh4"ÏÊH/JÎ:BȇGýNF¼˜ž¾mÉ|‡´¶v}ÿînbª¥çÀd4žGŸ‚C5µ_1ÖèïºÇЇB$5ůͻÍU™"›Mâò‚Ùï"«¢okßE¦ÍæÂLg¾MN¼n¿;s=[a>s¥¬œl”ññB~:ºÏæT”¼¨fŒt¤2X °]«6­I7©ò"!’”ii²p¶-î‰êä„»ªýPÊé •“2BÁS¤1¿rÒåhF¶™ñšÔ(€ôœô\Š\©þ êÉï4 šQO4æ¾D£ÙI[œ6Ê—À_®=OUcˆ.Dº#ÞuÞULJ/¯]¹‘'Qg“íö2üº¹Γ]•Þ*gp‡iàm¼‘þüHóñ±„UjrÿDÙңƂSXR–‚ÁEm «Q¥!Ÿå LM˜ŒslG£º´|•2ìª÷ƒŽì¬Ú¬Œ€  Š•¹ ò¼ ¬è8Õv<ҥ擃¥w¿aÁ! 6ª}-o…|E~²Á¿ÙfÄk“M8h23 A¶/qSºÌô+»ÐZ°QÈô±F ¯z4åI«Þ¦åæ¶'Èáò5"žAÇÑýoÙtÏj÷6`ÊÏÞ‘œ w¢×†Ëeþi‡38äLC ì÷mòÚ¿¥x0³;/ ÒÅVÕ”êªòSë·«%Õ Gòê€9rÚkªÄ‡<¾Y±H±2èóá›À•ùäYøyŽlrZ”µ1)h&;Š¿`‡ËV†£'[:ЬLŽ0ÆÔb‚|^-DP"»gß¾#•UÆÆæ¢6ÀaÊ Uk£&Áp¹2;ø¼¸Ý ©òUslçü’”KÀÊ´ƒ¢¢ù Õ2eìgu¨®+ Vµ9>ǬíÜ{ÛÚ5Ê`HWiŒê*¨…e¥E¯¤Ú”(}mý¹¿};Ê6[VGÒ˜”´+Ôä"÷¨OiôDÞö«ö˜-!½b4‘µŒ¹L ;†ë‘OK·)ØELA_]yç Ì¥ÙõÔ@«ÕÙ…ÕmŒøHdQË–ëCº¥Ìs,’ˆwÍ7ç¸"ýÅ,ò ¡ ÔyÅûOÌ®„ÃÐVé]å¡]à£t vÙèí¿\À·2¢‰¸-”í°"]ÍSÇs–®ö½I8P.’}Oì×B’A‹ò{è½Pø#Woù*&“%½ˆâÿ‡&Æ—ŠLòï®/½ÇKIaßòÓHT?¦.†ßë:œ5RK~ŒªâXb\w«”©‰#±Ê ‘>-W™Nø\Õeœ%A±®ë/H¬…~hl—À65!Þ_ž ]²x¤i¥Æôl=3UÑÅ‘QÒ„ —ߣç›OŸ®$ÔYC´ þI“ÁäH6=‰7˜ìî{(˜Ew[ŽçœWù6p y$0a¥Q5Uº’=—æîÿ ˜„)ÜŸ¿ÆŸF \‡úäæîéEr%Gø_ÿLqH7ºUm0­ñáÌbñÏ£‘‰Ùàð^CƒÊ{bwšE)‹ Úæ"u3¸*b_X³â411M𳵇ËûêO@´ì2ºäÅ’sÆ0f¹¶U ?«FˆvuNe“òUêh²Ñgµ¢"ЩŠT µ ¢™®²¿ÈD ‘ªV¥Ëùñ]ÏlsÕª,` !«L¡«¡ía¨Ÿj«Òüa«ÆÏBêWà*éšK[8TŽæëmÈœ“t1ÜLºž(ƒÍDcîöó*ñ’à¤,ªéµPþ|Ã3R}̤x€„pnðë±ÄØZF²ÜdMj’Rž¬äüFLݰ<÷D6}¡‘D]*­êt¨YÇõ•°Ó=a‘GFåx ž€§cìŽ&âÉh1ZŽÆ¡iÈ…ÃßãØqxð¨壑—: á q.Å8L’X£3æf‹¦ßËÖ PÏ‹OÑ~‹ú‡/¾8¤-‚”".1-&™Èâ¨êÚ"]e“OýÆEoÆazvàm|ó¯¼î $2Ò»¾¯ 7 'QÛ+!ŠB—Y4G„ú ê΋ŸGÿ€?à79ÿÂ)P ‹*,ÃÊCšö:)äi¦É{T ugîU ¨°©iºæßhhw=3Hü› …£ÏÙéð¢¢Z]WddçWÔæŒŠ Uì —$'F†x"1^,¤CE‰nH³¢ ˜§—/ßlŠk ¯4îmÌ(%U•Z•,-U‰LlAbqnYVEIbW”«ÜÃs¯w×J™¸xñg®zoÃNI®ðcÄx£cÜÀ“Yð|=²F½~=v«!þØæncÍZXMú¥¤¨Òw”É|™¹øØñÖ}M‡´’/E÷QO˜±aá–1Ë•ƒ¹,W(D=¾eÿÿÝ68€«c¬7ƒ^ý¹Î­;#¥z’ßãzÔn´!Ã'R!«¹¯~ª$~‹"ÑåÓPùzm®¦tÀÁ£%/Øg•·ÎÁ-æ',º‡Gqø›C‚FíUs'¼ún°é¶Î™ˆ¦Åÿ(&¾¤aÇ>_„¥°<›½›}OÊ÷s«änM&ä‘ñ?)E%‘/ô‹ ‡­|,þiÂw¶1¶Ö¯/#¾wyªC}ߨÜx³èâ ñS´ˆ_Íb{S€_çÈI#ÓwÃT§>¡©$í¨¡¦eiû%â_Òù}l]xyH 44,Tf¬1”×Ej—;'רœª »€.]ØH¹†^ò¶,h\UäuÎØ]9qîúTgºdrj9ÈóÞAh»yJQ©S8¿uAµÍSÁ ¦ ›y|þ­PI^Ú±Ä+±ŒøiuÊž”Ÿò°\Ò¡˜…[8ÏÍ8²‘[{BqAÕ¨ÊME÷ælÒ²Ôš¼,ÔZmýq㎠¾‰¼÷ÝϨ‡D| ^,»ë #œ! _üaFÅóIûëåMÉô1á2Þ„ËÍ“‡±§]’f¬H„‚0®(]WÕLUŒ.$$&*lÓ©Ó7¾ºð˜èjçÄžµ•ÁÁÁÁ•µµ••µdæò!¨Ï*Góš”ýe„;g±]H¥D¥ ÑŒ¢z4J -s•åi ƒH†pbÄÈyŠšµ/¡•ü}ÍfNxÒBá^“:Ž–¦çB—Y È¿Ï0·s‰ÂZo. ßü^(õ¤wÕÂ8 : ü£P^ÑNÞÖâ1vѱiÑä¹õ—šrâkUµ–ç|@ ÞDZ-±UiR3‰ïJ¿z67ûü±M¹É{+ |a•&Þ"eª\$@T|br †­mùÈ­¤$˜AÃÖi4¶88öÓñθ—­ãø9oö¥ñ0Ä`²¢=E¢N«ƒ8À kt=6陯j›røÁ6ïŸôÌ\ÒI„…hQçröÏvµ„þ¬ãˆŒ6ý©«˜N^Þ9Œ8ÂÎmÂN—-lª®½d!Péi¶ìk5a–ÝÚUåaÄ.%+äJ9^ѵÓ;ñy¡yÖ«= Ó ‹IhÛÀ­û„_›<¡7ÚÕõÖ6+:CQ% ÉÈ($²xý_/]Í“ñ‘ÿË{×ÿ«®ÿ`^žËï÷µw~¿¯=bIýÛ| €¥o#„o‡KOÌÝoòÔAÊ@aE7€ß¨tþdV–+’ €c»A•®Ì$cåž3Pep‰™nË;§¡ò}õ‹l±¤kžÁËTZât´ÿñùžšïƒœ»:mµIÚÝ@ò“•^€fñ¶è“®LË/í,¿55Q^R¾µ{csõ‘êM6ȃ¿Ïž8ìæVÚ¨+ÌÍ$]N£V«Ñ@|Z@Ê‚•«$‰‰ÄÖ)˜”Œ´Œ¼ŽoQ/Ò7m±¶ü­“NðüŒÝÃ),),Ml €lÐZ@Í߇æ£~h@i4Ö2YiZùî)K°x ·÷HÄB‚ùœ<Ü÷$¶:‹ûÝ_ž Lfº6KòÇÒ(Ž¬Ý‚´,Ü’¡¾ë‘•#ê7ãëÝÀÈÓÒä P–ÅH~}Oì x®^ˆûc›ËQåéi™¹.!ñ—Ü1Ô# ážÉŸÍ,G‡ V€·: ä' X“å+,.â%¸Õ‹ ¡,* ¢ã9\ëéøhˆŠ"¼– òIÑ:”rï¾H0DôÃFÓe#ZùÄÔ€¢~Ûš•à!Áÿ{=òBÛ$ũȰw¨”Jˆ‚{!+Ñóû¾ÚÓ¸;RÇy(å!ÇøW%”UTïùr}˼‰¸÷f,à°è_¼Ý¿ßݤIÚñsÚËIÚß³¤ÝUÍ^ˆhöìÎzq~fv.§ÑX©Õªø!«]%r99Uš9ãù·o#š³F÷‘ãA*¢ZäÈžÁ¥kM‹ÃÁý7B´þ8û?„¸}2÷Õ 1¦ÐAôš½[}æ Aèî´SãFÎuœë¯®5êôµGagÛµƒ´fd0²X!B þ=+sè¨ÇÏh¥ ê°9ú|›E?$¿mgQïY/0µÍ-ÎÏ—C›h¼>¥Žøª~Wd*2RT¤k¤J¢’¶F-OØžå\ž¬U¤™Ý'ÁGèH.ÌÒh3Ó¹¼â¦w  Û³cŠ}4^°…¿%Zíááå¶Ⱥã±_jIû&^±¾ÄPYkð÷KÙ>ãòXÔS"þ 1/Bb‰ùÀü‡<=B^O–?$îB¶è[IçÜ¿ñXe‹|‡žÛå .•»ôÅ{röŸuýb&ˆ‡i=L"~‹uˆYø ü;yO<õ',äÄ]KÀgsÔ6õÆ7Ø•tV^ÓßA)s«îÅ£âVXeäJ}`3qÚÛ`K¬oãvâÍÜ)翾)8eøñ‰åß°9¦æ]Îà4¶eAZ.òÇÄûi‹sÎägeÞ‚£§H7 ¤þSð,n.­­p8—;FÃIíÉìé…÷}e!(úæ4*!1<„ªE5}+çÀog·ïIÛ %̹¯[®^»°iÁ:¯mŽ~œ~û·¦#íp‘y2õôäQŸÌ›£qiqæò›Â Ä_¿Z<Ãiôàa/—¾FV?vüÖ(;ìÝÂE—Çå®8ÀŒrgQ¿95ÑmA°ÚnÞç›fÍXðUÇ™º ß·™ÛLMã“{üüËŸ ¯G&¶ÑU6€Æ ÷¯Ý ÙÊÊ®-1FIã‚’¼–žðø±d ŠúHéKS×oqqã<\"Ýásøa êɉ;Í-gÜÿ36¶Càù˜&8 ¦6ÕVÞT}t_A±Æõ;J\òÒWÂvf掱Ó8sKE!ïº*oý?Û*¾õï¼z©ÔÈ1¢b½ ¥cßy4Ä€ÎÖ;W¢¾¬bö Ø›Žìk=~àRëíýËš|ŸrƒJNL»C÷Åk«!:|wjŠJ!Y?Öe‰ÛÆ„"âR?pEô‰³—¾% hëX¸jÞúaî™ ¦r“Ǻl … vÓï®|þý—뛸ˎ_Æ}ßÂùÓšûL—7jfC¿Sœ#sï@]ÃY®\öÉôˆ0ÎíSVï\tpUYHã¦&ŸëV¥„33òÙ‰;{O´“ÊøÎ2dèÉ€|.>} ä×›¾4¢D"ÑÃ/ÚÿÛËF¿½Nk\½ÓR¹à&§ŒP`Æcf¦$ÿz‰|þò¾„¸2/[ÑÏî¶|}¤&ÔœŠŽUF™Æ¹:¼:‰ IÈ`š¶–êù%(8/S/Âù´±×åÞ\¯žº>ïésúô¹¬ëÓ—¢þyüC) endstream endobj 89 0 obj <> endobj 138 0 obj <>stream xœ%‘L”uÇ¿Ïwσ^"è“™ùÜÓ„ÂBN°8 r%IC² ¹¸8î¸;Ž!"‹îÃüp‚@Çýp>¹X.À!rs¹r+r¢–ÚdM[Ú¾}Ýê°}¶Ï>Ÿ>Ÿ×ûý¦PˆQ%KIÏJX"ÅM”øœDÜ,›8ÿH-…!¾>ŒÀEá87 ï[‹¤e¨lH1šjÌúâ+]¸•KJRÇðñÛ·'ñotf}¡¦‚O×XKt5¸”óÙÆB½ÎZÃG¿^bµš’UªêêêXÁk4ïÜÃWë­%|–΢3ÛtZ>ÕXaå34¿B»ÒRŒS•UgæÓZ¹!$‹ßñÊ« E uh=bÑÓh¢ƒ‚PÊD3Ô>j\ò®äºØ¼FÄ ˆ.aÂEá‘›RL…±n¸´½QP Œ–K07Ưò*(¾À’ÉýD§Èxpؾ`PËUýºGà͘ù‡c¹êa÷äÚLeÜÿ„ažÅe¯—Zø û‚|j|ml[ò_œøé’{†àǰ±¨©©j™Ê*·ûøññù¼É(¢"1dÑ–Åàg„ï;¿›ç<á+ø |Ž@Æl‰ç ?vCN±þ=G’Ë,yð›ÂÍÙk·§Ý¶²aå˜òáHmÑë -†²ÚÀ¬± Š)ŸccÏÑA9ÑôÒª¥ÕܪµKêéR(–úO!ôp†Òy endstream endobj 13 0 obj <> endobj 139 0 obj <>stream xœ­y \×ÚþÄHfj«t*Øv‚î{­K]‹û.î¢("‹²ï; {’7a‡¶(‹U\êBëÖÚÛZïUëµµ­-®-µõ<Ü~ÿ“`mï½ííw¿ßŸáB2sæ¼ïyÞç}ž3¦gF"‘ظ,wfyã,¾*_ë!¾.ÝI2Ÿ;“mÀV ¶=^ÁõWöź>¸æ%F*‘„(]‚‚cBwùø†; ÷á4aÚ´)£&Ž?Íin€Wè.O@§åá¾^áô§5Až»¼Âcœ†Ïð ž>n\TTÔX€°±A¡>³FŒvŠÚîëäêæéµÓiAP`¸Ó /'ËÜÆZ^\‚‚#½B–íô dfÍÜÀ·ƒ6¹Ï ™º laø¢ˆÅ‘K¢<¢w,‹ñ\»s…×JïU>«}]w­Ù½Öoÿú€ 3‡ 1g¤Û(…íèÞ[ÇÄ7~ÂÄIo̘ü攩ÓÏšnÿ¢à bV2ƒ™UÌtf³šʸ2ÎÌf³–άcF0뙑Ìf³‘y›Ùĸ0c˜ÍÌÌKL_¦cϼÌðÌvæ¦?ãÀ82˜žLó*“ é%y‘YKWŽ~)q”$]=4=ˆT)mïéÞó²Í4›ZÙJÙWì0öCn—Ê‘Ü{9õ:ú¢ÚVf»ÅöûÞËzß³s±;ßgAŸš>/y¼t¹oq¿Åý>±/°ïxÙÈKùÈW^z%õ•Óý§90ç{9º:î põÕݯª^½òÚ ¯Õ¿öÕëq¯^o|ýìë_ ¯ áKùjùC''8bໃ^T3xúnHÆSCî mp®Uv…`F7³¸°\ÒÐé*Çt.åÓ‹Tyqê´´8â×õƒbw¸ï, çÏîϬfh„ ÍYõ ÛÁfÖUk†2È×eë²[‘w@½ì4••¤UAºcÀüÙ#™ïÂQ8™pKe¹(–]Êü¤ZŽLÁuŠ}[UØLC›HCk5ãÑîÐ6ÓÐî[B{ïßC“ɼ@kò |ÖêðcÇgè›å¨¾Ã>(ô{³;°7•~#… ˜ý,°~2¦5%D°6BiÇWHNbâI)>§ó$§«A‘(¨ÕÉÉiéþþ9»hÖv¿½ÑÏR!oðߟz2ùdÒUElAŠ)¼¸IÎ04ä‹Ó AU ÉQ—)1rò2 Éú­¶¬TÈÊ),ÊÎ>¼ã¨ÊDÞ§åÊå#Q5•ò]û|rçB²ß.‚6noåáoɪ´ H£f€Ü2š•Ö3&šÅ!Ö:^xGÚ9§ó-þ×¢Û8§»¦Ÿ×ôvœBÞÀw¯4¯•ï nò-®òKä8‡=˜•}™’ЕÖÃN˜ ¾VÚ˶g*¼åËXbGFCâ4²ê86ÿ¶è…ß½8˜2©½§–K~ºŠj¥x]›ÉP\Äj¦ø©âB¿$u,éy3üÔåÆKŸmAëØ¹þ>>‹à«RëÙîyÁŒ fëj_¼#›E–'1AÖ¬+¼&Tšeîª5”)·Âp·N³’ýWú?’y–âà(œ…#ÏXr–šb x‘þì,±‚ý“;QFSšhþµ}ŠNø?qÓR—©é-§üœ%£, ¿ª‰r2’…%àqÔ·.êPêAxŽWÖã죵Se8¼ÐÆÌ.LÎ=.G|vµ0ìDÙ3Ârº#ÅXñ{¾I§ÿL0™e;T i«Ø a‡uR&ö3ÂǾZñ–ê/;”ù´Ðã#8d ,”}K­o¢CPÅfI¹¨–â"D^•£Î\®º ÊèòoW‡k¶Ñ¦>ÖÙVª6Š½Ñ™ CN\ž*ò!O—»_ÛÆ“úF-gfTî † ð×u·š:õžx$:C9˜d;؉¦S2b´Yr %8Ž6ÁÁ´»*†óô®‹U Xž0éèØ{Ðu¹±ã6¬ßàéV¶?T8QYf®>¢ÊÏ?,Ò÷íW|ûÅ×ïÞ7Ú¦º»¦~-×ÝÚñ­«WjûÛ»)ñÞ>ۣΧ8ÓÅâÏägƒÖ²JØäãÇJta©òhp?ä½Ï­xpSæ{,õ7ÆV×”•W·lËÖÈkªå×w²Ík’|7k_ͬSÏI_äçâ±<¹i‚/ ô·`ÿC-—ü~䜀m[¶5œø°íc“C»÷+ÕK b¡ßÃ>5´ôÐ]¿——gnh¨:oIs *˜îE›Ô³4«‹Rhšã’•éiKg8Ì|”š¯ÖA®#è õ•–+¼Ô! r\ag÷úèªï²~qD覕®êH B¸Ž á:Ø {5{»ûbh¦jÐ53—V™«ëMõ7œÊ"è`i LJ ³¨çú*m ]ž68`­Ö ¢–ë®]£èdBïô{¡‰Š‘}TŒ\á)Úµ…% G—ì§Ås0¬Ú£z»nøÁ–´õ!ž~;ü׃;xU…5'iʸ䵼yÛ‰ Ó¿ ”¾Ã¿'¶ ·ø‡É©Â¹üL¡X º«½–ÒÛ+Ï‹â=,äƒdJçÒ,îîF,Ö²ÍYúo„½f™¯j<­­°ü¸N¬“Y4‡‡©äs1œÀR\‚?ñiÈWÝF ÍÍê(ïó\2µ>'v±¡«"Ö.\Ž¡[¤Òåikó «Ž. ‰ v?ìýî-ï©p±øVaué¡K:ª/ýTþøÛ¢?ªÈeFRFŠ3I¦E¿EY‹MßÔYUжv©Èˆ¯ó‘Q È…”GUW÷˜/Ìß?‰¼<ʉô%üãÔ™È÷bï|½hRǦ á Ö„lné´w©(ÿYë¹¢ÓêP* žÎ}–Å¡f±é¦´Ó½S൛®ËÏ©ý\æeZm9p.þ>µ“²HH…ÔÞuÉ„‹çRÊ5º`Ú/g<×él0¸ ¥ÒäŒÎ =N…Y±æt7‡Â±¹¸—ÕjQó&;1+YŽ…Ÿ•O¶jE;“¤ÅŒçéóù…¢àŠ“ V —)ÉTêNs:J›Ñ†b§§Œ4vqÉ4fêãâòvÂvÙt¥-‰H7’¾Tm¼ û¥ë¼bE.ͪéŠ\Ñm-ÚPéï¾5Ú“6ϪÃ!-ê÷iɴ未>X±÷ù†ƒ‘5^ú8Ð@4—yžOÏq?5“ÜÇiáIßïœñÅO´K)p—²8êy[ÿÅ¿z'³8Ç,Eeç$>E¯‚h:Ô ÿZÙ10¥jëjú“ä±âÌ®'y êÀ±òÊäb+[Ç:(\שã5n°q/à,ïšÍÚ‰[)ª|«p–Õ¯©>²ˆë¾"Œ?¬¹GÍší˜Áä%ÒÿÇah‡vÇŸTæ¦ç$'©R34ò]C'ªãÁ vÔ„7ì>®9‡9mŸcï”ÔÂ8ç¡%/Ó>r0¢®sBES…wH;cð[·“qø&YIqd ÙF¶áxjŽVÐcç‰ü+,D¾ñàžAT¤È'9Ëí°Ûj£Î$A›OÚ¿–â)«*zmØoŽi)(PgIT1‡r!e1¦šÒ²êý^ûÖΜ¶j˜@Øþ7ÈßþD$ãU¶Û4ÕâE‹Ç¹ƒç:h—ÅË<:u|yÿÑ/‰\NÈï8å?’J V…'ºø}NÒÃݾér2„B±€ì¨Áe?«ÁÔIÝYŒ¿ÖpVŠ}q!oŠ3ÇîÞ•njH4È6µ‚ÒU)éÃ)s£+ %Ʋ³g »ÒÇW®Øi &y´ËÂë}Jâåju/e¼]%>51ã<½a 7ï‘+¾Œ}~fÄÜÖ3%Þ¦ˆ>HÖw|\‹½L¢©VÒö'™ðÌ#©X—Ë?y§ûNãþûss«„ÒáÅo´÷؈Næƒ>15#-šå7¦ÅQiÙ~–#EüÈæ¹?.äP‹ò;£|"ÑÏ“W Q'üÏ.n³Ïέa…ÑZ'çòñ»ÒBè‡I‡Kê+êœ2z¬-’woÝX9@Ò->¥¸´s ÿÛNSòŸ%.aÿïû<‹`³¯ÿN#³ëTE˜TfGþÝQÎ!3Z›®·z:£×±å§HÕh©BbLAÑî ±åNŒ±ÿ”ñCg¶ºe§Ël+MǃnFç«÷íÒj¼a·póœñ³íÓR íz‰V·%'ëØ(HÑçjµú\¡¨4)qß»VÞH:N[ŽÝÍïž´E¾V/ß~ƽpI1MÅeª!ÄkݹØÙ~™y4?b %ã-Ùø›[r60cØBUèĽP 9T+”ÆDox/¨íÆÅ¾ìÛ;G÷´d$ ,,  *¬¾;#±4Û¤YÒlÆÂ;X`¶xÖiü?XY‰ ýЀÓÊëp$UauP .ÍÐ&QB¤hØñƒ„þ²¦Lìaµ5ôO“uv²ƒ ¸ÁÒÕ¡Z›_žU «R C”È4«·ˆWY=†–<ùDŠ 0€CØß­•wt&ía8&Í‘ßÔÊ÷ì¥ÓHÿ’ˆ<$8&©þV TiX%i]7vC˜Öç„ë~qôÀG™œe N ÞTs†h×u7±b>•‹è¸ÄäËž …G«¤Ý¡Ûáý™ÁíÅgì=ö9¾þ€]l=´þqÇ$ß±äµo[Mlq‘`…{§ä°¥IqÙ"£Ð {4Çÿi­0ÂØ9Ðb±¥è'~ÇSàæ€–«? utîªtƯ×=ƒO¡0Ãà‹é]9ñ™©%´p2s² /~î`íoS"ÎÍÎÊ•ÿ:2*èÐ'1‹‡¿+°Ç”®Â>c?U—¤NQ¥ëT¹©ò÷6`òý@‡72”¼ªVedЩªt)ú;WPrZ8v¿Šv~[Kö”&´1‰,¯’¶Z”\Åâ«(©•Šß‹[yhƒ„]²à–‡SÚgF¦Ö¨ïýÑÈ||äHe©Üàz^IM»%?`4™™m•$ɲÈÜy_(oÅò¼¬läq…)'$Ë⩹HHì5.ÂÒOV“W¨tu¡E4‡áltÆ„#1C§¯LÛ·O>·Åj)"w¹möÎeåm” äÜí+Çb64ÊõÑVAe ^1Šh¢¢Þ—Šrq:_”DM>p¥…%†REvR¶œ ¼„?(ÈÖgC©£AY“žÉ ôoÀ1º"›"…!629N)è „†ûubšâØ1F—£O/H—ãÀ¥dà’¤tÕŽ …q¥ÙÙ¯°ï7 dŒ:Ñ&QŸ°Ç˜_R(¨‹p´ ÅÉlyêÜ"AÛ)“L¾eøSçG-dÐÏñT&gÄS-xº\"ÚµH;×Sÿ`0RGCœœìDz(‹ˆ„È Øú6¢ JäHÿ“Qú® '<@ÍHøA‡ä§ŽRÜ)þ_^T^[[YY+ Û+ÿöÙ/Þ°ïÝzmJ¸›rñmq§¡? ÖÐu¢+d‡=dï6¶UîO 3 ;3ÒüAÁTÅVÖËjÛÖyk±]ç$›²¿OÝø7œÌ¶æ$ÿ|¦Øƒµ¤oݳò\BËsI »aÚl—Œtêï5Ö,¼y {ý%¤yç/5k*.Öþ™î—¸ÄYóxh´)™þz/mKF˜•Îòÿí´wÿÙ9â?XrˆŒáÞ:ô±Ñ¨N«R“-SrãJ’9*ըߢ7ÄT ˆ§ñdÐöG?;ßN¿½‡Ë/H ±FŠûq9Ô,·,-æš$ H-ïxSWA¨e Yù )n<Í×…™¨¾ üUßPS”i|º¦\Ò&–Š:ÝøÌ|]–Å÷+r“ã2”Š tüËra„©³ŸIrð6nKÅü”‡ËªÛ¾ÝvwvÕjX ³Ã¶ò[>fÃÝÈ–­o^; ÀÕÚÃßÖ_Îù+|Æò1.†h´IznC|7ôgÊ¿¾TÚûábTÙØÂµ0–Ár˜’´*’Èæ&…ZXÐUk¦B$êšÛ:íy“F*,_:ŽvΟ-ƒópºšë2°Þ*ÅXÁϢþ¦2éÜy¦Âüر*}³åA*|†;Ì’“Ñï[©¸çóA2ubʪĸ´äÔ¯qdìÑ]œŠƒÎŸ‚GdGFúvæøñ›ZÒó+êKšê#+üÓ)d2„ªO.í= \GãèCgMuÛ 'KÉf¥e“$ÜQ´·XЈZªÙqP5öúî‚©_ e¨Mís;úÛÿŒïá|{ã;ŸÂ_¸kož¾rÜÄÖ'›ÓÍ–'\W¾.ÊOËJ§INO–o‰ÞšâA•Ÿ{ÞÖ²¤l5í'œ’båÖÙ‰rÓ­oÒ5ýÚ—|Óß¾ P¥…m5ï–:þÞUªoŽfTúpÞqÑÁ!¥Qµµe¥õg=O'<HìI˜Üþ)©B»EwQú];: ý¸ûÄF°ïZ Û}ƒVrø¹Î»ÂîVE]ôÍ-(á.›‘¹_r–ïʼ¨’v£Çæho×m©ÁÖ*‰0Š>“´™ï¶KÅDñI÷žž‘#:éª"U$ÛM¼¨‘ɪÌ;[¤Ï͹¶·ÌòÀ÷²PA¦€«£ܶÂ;EÂqpXr§®t¯HgïécX{,ätûk8GÜÌ”…×@3÷ÁÇ>¼vaÝüù+·z† ¦8þDÕ§'à&wwÌ™ ƒ¦Íçeð© öDçd¼çÍÙ=ÉcÕŠiþ¸ˆ–÷ðïÈ<˜{,´DPæ–*r¹¡Ûyì7³2þ„¬pœñ–ÛŒ7Þ¾pëʉs7Y™¨¶ùÛÏMâ@Kò—´cMþ±~ÄG°DE¤Û]Ã7fí ²dyêyp«Ž) ŠŽ X|jûäéá€A‚ýS¬"¶N ìб–§ÝߎBšü'ŸÂÁS¥-áçñq4Å~¢÷Ãñn‡oÜ_ò@Q嬚YIאּ{{÷à1Ô6> ë­-{r ž¢äÚ#oS4à<ÙséI&É®ã¾,½õyLQr~b|†B¡¦’ã6Äõ¿ŠþU°b°l™lCæýªTq’l&iÈPPÊÉpLÌO.*ÎÒë3…[xÂ]ÿø«hÙsÝK‚ed NæqM÷àk(mÅPŸ}ñ.^¶”q¿¶Ûv k¿mïoOp7æñ0b«ËŠñ ß@XÎ-=àBÓ)ûâÌõÆ0CxHTt°·YY.¸Ï‹YÜdÍÙcå°ßX/?zqïÀ—¹z6ò 5F°ÿñ#|ãßÉ¡»‡¡ß¯ ÒûùIU¡ô$S@þÖó÷š›˜®ôÅ5R±_§Œ/*È˃b®2ª$&6=UIÉÊŽŒ*‹´±ïÿ³ ¸ûµT¼fÝò´Eöα£G2õVü¯[žÍ> «Ã·¦ùx ‘&Ï=k€LØ5ƒþ/Rá7IÉ!È{ÿúM\½¬ K¢].)3ª’:{H¦‹°ÅðÌsbß{uÏ‚°Ê™Ÿÿ{™¶rU¬÷f!ªÞ³jpÎä…µÿÿ‰ŸÿJ×u}üÿéî¾3úÚ@³àž^TÎÅåG—¥Ðz´ÄQ!ºìÁÀœ Ù¡gͽ®¾(ôê9¥ÜöSŽ­íÕÛÞ óÿCY¾ endstream endobj 87 0 obj <> endobj 140 0 obj <>stream xœ}LwÇïzÐ;µ .s×33‚‹ãEÃâ"p`6<á(ÊÕ¾Pa㵊=j¯‹ÀÊ{[²6f`˜„è–aŒÌ¸,aHF¦²ß¹ãþyò<ÿ|ŸÏç‹c> Çq߄䴘íå°ô.THo`•ú^Gû‚Š•ÏàI(oÊÜ‹R0ÇõW«xC©Q§Í73¡9G™ÈØØ˜cÌñˆˆX挞3êrØb&™5çszÖì=Š˜ |ŽŽ3—2¡ä›Í†¸ðp«ÕÆêMa¼Q{úè1ƪ3ç3iœ‰3–p¹ÌY¾ØÌ¤°zŽÙ& Û ¼Þ`1sF&™ÏåŒÅ†)#Ÿˆ:aXŒ©±7°ýéÂ|°TlOÁ]Š¿JviD©Wsâ¨á7ýñ:@Ý/Ôóô¹¤ˆº+@iɘ‡)µÕ@@EÍi•õhï­ah瀞P½#rd|uO³ö­o®ŠøÃMd['$JTë”vKõùŠjÛÓP”œ¤|µ:äš_˜~ü¬QÈïЂ,ÄD…2ZÛÜãn;®]¤~yÔ5ÔÆýø¸¨ä³…Z|C®©®ø7¥¥÷—õîψ@‡\ˆ|1åÆŸ¾@ü¿êCÏÔ‹?¦3r@B^jΉ–iV3îh¹Ô]SwÏ—]yïe òCšç«‹çeE7ýjdä ÌRKÓ2!Ñé§t]×<În—ÛÚY䠇Ʒ õíCK[þéÕ"MÇ ™v£ @m%Ø„ªò&hß‘Q°(ey«\]$¤>ô¾Z” )ì„KåM(¯¦åß·.ûjÑx,©ƒÊ8Ú UN8æ" Ü0!lWi ã uP³BÆKGÔ[ ¹Ü1ýg}èBAÏp´GDk —¦Ô?Tx  (t`ñÏ;-×oÕz‰ì75¦š ëà!ÑØ[}[€: * êsü=Y•mMõŽÖfztj¶qf ÿÒm[GÁ—¤‚Îë³Ú˦,H„Eãüˆýë^è§Fó+„K¹‰T(ù¬¡@ä{ò¥}±ŠË¦wø$µkymÈOþ:žè]´¬†•†…‘ÙÁÉÉá9ðÀ76§Á(””A1el·x<N÷ö~¨|X‘È…r+òG 俹Šö£ #É»Neg|f¡ÑAù‘:rÝ%c_xl0C­?x²üÝ@i^/ÝÃÕ³^ð4` ¹¦üÂkY@ù[RÂTÜÜäTÊl )î^ÚCïö‰qªv¹Uª¥6•†ýgˆËH endstream endobj 11 0 obj <> endobj 141 0 obj <>stream xœX TgÖ­¶¡«Pĵ&N7.*.¸oÑ(n¨(*"¢²È*;‚ì`w?hÙAYDVµP[Q"âgÍâh¢ÑüFc4û+ü:óÿ_7šq&™ÿÌ™S‡>ÝtuÕ[î»÷¾1‘H$±µ_î¼@÷n¢ðŽH3@ø³ˆêÕ•¾dC0ƒ±ÁÉ1¦/†£0 3‡ ÓPF,…%ۇĄúùø†›[yN2·Y°`žµùÌ3˜/ ôõóô2·÷÷õô§Ì·{úy‡Ç˜[-ö Y8}zTTÔ4À°iÁ¡>K&Y›Gù…ûšoöóôö2_n¾Á#ÐÛ\Ü4ý«mp`HD¸w¨¹}°—whÃ0s–-¶ Y±oe誰Õák"ì"×Fyì^ãiïµÁ{ãßÍ~[ý·8ÆN·™9köœ¹ó0Ì8f#3žq`&0› f33‘ÙÂX2ŽŒ³•™Ä81“™mÌÆ™YÎØ2Sf3YÉLgV13˜ÕŒ ³†±cf1k™ÙÌf=3—±gæ1˜`f(3œÁŒdxf3š1eþÄÌ¥%f ˜ýÌW"'QåÙ€Òߊ½Ä]c ¢ [ „I®²CØpöçÃ=2ZkŒ4dP¢ñ;ÆIÆ/o|Ü$ÂäË!éC>š0ôƒažÃ 7=bôëÞ#NŒ?òÄÈ_ùÂQ£þ“ 7y548^#¬« ñ}søÄº8ˆ¡G$†í·¦©±  •ïWD+÷é"y?³(㜄F¸*?g<^Æ€t£©)“ô’ñ†S]$-ªï  NÁ8¡?i2K¾x4"M†$AbÒgAïú«Z„Ñ÷ ‘X¸Œ=<²­M†¸ØÄ¥J•?IȲC¶÷xÉHÏjöŽªÔô²ùð‰þ¢«ÑƒEƒ'½'*"ß“’Ãt kÒwÞªMENF3¼‰bœÜ7Œ×> Œ‹ÌâÒ‡Ÿ¹ìCbV"ÃåׯÂî‰ÍßÈ©ÖÁE‚i¤ˆÇ"ÜÌâ ¬ QË]ÖYÊÈ|rÇ6teKá4{Öûäìn•çJÂHM„Gi킱ZÔDoVˆfb¡ƒx=ýG²„¬˜MDd8ú•%¾‡«¿ø II ±ãÉ(øéË/à%ò8 ,çͱ„—™ô=KЂFtm„Âsâ¾ú>þ0D%))ÉR»M›O/¯Zf¤€L#Öĸ ±ÁÃ考Ñ«’ 61b•²bA̶YÃV˜\°æŽSoê×p иº·íô™ ÷ê>‡G€œS-™•_%ÀÕ©2ëèí-ˆ“ejÁ¨]„"Ú¨š ž!üj\/¹ìÚ åÀ¡ÍwÏh¢¦3¾!S:úˆ–eÉj]ã* ŠäårH„HN+ÿ}wV ­üáª3ê[ÀýµÛž˜ÙŠívÎîõm!2“WRÐô-“ pÊÛ-ÛÀâ´¡9¢/±Ä1dLkO;Ú¼ð­Ù»p'´Ã±cKî ˜ÎMâH@jÒgðlNê[CQ×)8ñ®çw=5Ûëíh%m,­‰1ûƧ\è*oUˈÓ¢Šˆñ4Ñ LˆöqÜåÜšM½8¢Qu¡¾Cv¼»;³¸{g¹Ð"–Qø5j0·[—‹.·X•{ 8 ,…`Ò_ƒ= yéy•A‘žBŒI¦)5†]‰"J¹| ôg^£aj¹¼èCÉ5`V‡òòÊ9á—u N4¢#8ÍQ&ÜiÀ÷4’ÝòwÁ \HÀ»?\sm;ßÓÛ>joVA°´©,¿ŽpŸcƒ·-ûÄ‡âø§½ßSr{Öz_¦`Äç–fæô¼ =„៩½Ž@E²"”òÔ±$×”pØhxQ#Ù¡ˆTºC¸€»þÆ=lQ(râf“=¦æ˜§;e 5>{Àùõ)8C;°`_)‚Ydä–Q*2E))ØWE`VH  –¦üí¹K3ZªE·qÎ×u=Ïól? Ó6“‘Šé®Í‘ Í ÕmõûËä*i~fuÖqà>jóY,ógÉB²Øˆ­pXôGŸt5©“탿H5’òb¨©Ž…$Ùº :ÆÕ1êæÇ:{4u6þ ·åIõx£bŒ_Ód™NÂBúÖòý¥—öÙyöÌ¥FMÀ‡`†3¾ŠÂw&M¬9éô,g _Óx¶ñ Õº¡@Œí<`[¤lï– £Àj<¦ V)3 ŠNe°xLû4+ùÐþ*0;¹¥ÙùØ*übš¡ý¢_­¾¡"®†ç¿±m £!al$ÄCB(÷6Vtu(ÐáÔ oùoì´•ukÜY´ƒÖažµá‰ÙSk´¾v®º¶Q¶EûßIø%FÚû|„ïOÚ~2”Z­›=íµÇeµê³…-pÚ"¼8=÷£æ’sIŒ½:ÿ]¤ UàHìW…BVÈÖ~ZŸÅ`VU2á#ª22ŽªªU™ôg\­F²VLÍ^ÒN•Z¶2¡Z~Tž¡„N;‘2êI*6«Zqn¿U|+BП¯,„£UŠGk/Ê\oÌs¡q.GÊ‚£_Xâ\pêçÒŠ(H‹Q¤H“…oÛ²^‡òY«Aæélä4‚,b’éI `œpºOÔ®WÜ h#Oxô&cq2I"ÉÄœL!^Äed¦ÐC†Vè&ÕšÞVÔ¹¸ûÖÁGpç}¬¹^ÛtIý7úáZÈI'ÍÚ¬9°f&¯ ذgÕŠ=Ë3Á_©ö½Ð`];£ø‰Î0Åét† {!AÑg‡jTù  £¥PHãÓPÿäÑQßÔP­îôêxwa\‰Ôj‰Ë§äÅ¿qMzUžéw®x–&E_ºxj˜q<ºMuoÀćd©L»ôÍøKþ@'qŒð€Ç©°tÅJXB¦ÉhEÎPßôˆìR£å‹[j ¤}yŒ/‹1àï`Q\QJµ>¹ùÇ£;R;(aMíúüF[tSd¥¬®¸"³(SyP‘I\HeLuÕ‘ÒcµQ-»\<ÂDK=jvåê=uÛüµŽÍ>‡ãd‘á ~”uÜ+ý*£—F&¹S`lüËjÜŠ¶º?i‰¿ºªQº©Ö ¬€“#ÃÛÀõŽN¸þÕW°ÎÍÖÙÈ.O¾9Øè¿Ç‘Œ!¦çNö\‡Ù›ÕOÏÈ¿ßþ¬¶îÞ'Å'ìÛü|ú¿^þ^ LPk°NušáúŽt¢ÍèqÂ- ´Õ÷/ÀÜOdà=²Iª5û­!­ª—ú†|­oLM;BƒC$mP—\x4Â` ¬‡½¾¡×R»û¥ì˪ª¸ÌÄpå$¥,Ý% *6BJoÂCnD\âÔ‹VÇ92³š'C±‡KpžjÉÆÍŠEd¡Ìïémü#´Ñ­M,ÆTAËwyÔùìÚëååѼ§ó„úØY)±':&êÉ}ãÙ? {ø)Ð@‘ò}….È ‚…Î^ÑQÛ)ºùï¾c•°‰ŸX%ÿй3 =ßáÌ“„±+ªb!ýÈkã‹kõv4Y©LLº¹oéX[°•’ðì•-mÛvå%ɺ›RŒ(•—ÊK^N(“7ùe(jCÀ‹J›BødiÎH‘*CNØkCNìôŽüP&äåIs²ªjÊK¯¸=N¢UÂw¯£ÁÈ,üܺ‚"á:¥¿ÛWDøD'šŠ¾¹ü¯kèVtÐð¼$ÅyŸ£%pwµ·ÉTI‡ŠîÅ]ô@:ú{2U¸}—¥§š›ODº­¢Ï ¾·öK½¡2Œc¾/ÊË?tÌ4¬¿<ˆRë>ðÊØÙ/¤å ’ç¤Ðõp¢©°ówˆ»–YB ÜðÁkÄ f¯tªâHbéfɱ(ua/gÖe4ÃIʬêþÇ!±T3âT³’ (Ùӆ<ï7‚ÕeqŸRø‰ÿW>¶§íO€5ÈÇÆ,ù³å&*¨khvQ*ØüG>™%¦8€î¦~èü˜Ríp©\ƒK¯‘û/ÆG—æ-:5:E©U^T¼™š¡É•}†ÔMªÂçeåÝî°F²UNƒÜaÛúëW -P›H|µ>¦$P5|¢óÜ–4&X^ú¨ž°Ø¬ýßÂb(³r*J…u´(Ao=ýñéÿ¿¢ã€+êfw^-øjV–Pñt±IãþÓÇAâ'½'*£–þFøN¡Ú÷sÕ"‰uïxµö‘§îŸDUùjK…è¦à&JûÖó9Å™\y\ÑþÈ´qiR­éß'¥ NKa]_V™S\’£{D;¬é¨a:šˆ¦OÌWAAP‚R“¥K6›S¼pQ.’j¸¨z¿ŒÓZÚ* ºÝzà›ÝÚBàH¼ˆ5¢Ë8 íp¼X¨Çê6’WĥƧ/ƒý”ÆÇK.´÷ž9×òÅåO/·™L,ÈÐÉÓ·©ÃZOéªJ>îV(m9Ú™UÜý® ómÝ휶ÊH IL%D™E twLèlÆé?·ßÀñÇÕ¢û8gé4­ïñh“¶»‚…yª̦]²ÓEù'ézrfoã.wŸ ç©/7R½î“—Oînü 1¬–~×rò/p…ûø½ëd²Èn¡kc°º½¾¡­)ºÞ3Oz(·íØu྄µþ["gÏI—Éa¯"Q«€DHå¢ àp-Ö«h-Ÿ!'\û øzyv`˜BŸ$%‚v¡ žKXÝŠ×ÏáḾ|–?¿ÔX²tá¹Î“ë$»?³Ktÿ2W‰#(c\Æ`Ýò¸X¾9­*á(\‡ÏU÷h –Ë‚ÒX…Ò¥Î1ŽÉÛ¨ñw.t/‰ÏVP÷ÅÅA|œŒœ¥¬w º(3£¨@Úv¦ûÐIً྆mÁŠ sÜQÛ*;•UU­œfO¥€W´Óì{óq8.}öŒÎdá3b½Ë=eŸ‡T¾h;…|Z¤¡¶a3uäôåWpX:¿¬þô…º‹pÕážÉñÊy4†7Õ(;wu÷ b@[½`ÉpQMn·•v,ý«ïÿPê÷ò>¾s1©Û¡KæÜ±-ßÖ÷®Ø@Žnù×yéL-‹o„¿Q‹þcû¿~¶–aù}4•BŽ¡‹n1¸*<áó 2rèyõ$šzgbž“¨ŠÊVæ* 8g‰/ɧô]ð $'Jr>¡~„Ã… bŠÈ€dh ]nWs+»ùu‡K³³¥%• —(­âà·9}îÈ··ájÑ]º-:âX±`­<Ø¥®öˆßçéô.¤PûPÙ\PTK[sÊÿÈÞïýÛWŸw œ'C›Ç˜Ý%ÿÑù3©ŸfSõ'dÂøEÔ‚ {`ƒ“:Ú«.6ÈëËOÛ/žÃ=];²%Y%+Ü ŽàÇíŠ!FS¤& …‚CºUäJÈ®\VC‰jt Á¼ c#už±15œalÂ0ÿa–yi endstream endobj 80 0 obj <> endobj 142 0 obj <>stream xœcd`ab`dddwö Ž441U~H3þaú!ËÜÝý#àGk7s7ËÊïÝBßc¿Gñ``fdÌ/mqÎ/¨,ÊLÏ(QÐHÖT0´´4×Q020°TpÌM-ÊLNÌSðM,ÉHÍM,rr‚ó“3SK*4l2JJ ¬ôõËËËõs‹õò‹Òí4uÊ3K2‚R‹S‹ÊRSÜòóJüsS nÓƒPÎù¹¥%©E ¾ù)©Ey Œü % LŒŒ,š?:ø~t^ðýý|ÆÃ?Ä™|ïýfôHé7ƒ‰‘’â#ãï _ž<ú&ÇW¼ø§ýB¶ßÒÓØ7smæ–ãbK«çáÜ<›‡ˆyô$]} endstream endobj 9 0 obj <> endobj 143 0 obj <>stream xœW TSW·¾1{EÀ¡½U:Ü€(Î"jE­Ô*Š¢R±¨ ¨eY™‡$›€@˜eF E‚¢Å©Ò:UëÔAm}­Öÿ¯Tûë£ûâáu½°µïo»Ö¿Þ:°BÈÎÙ÷ìýíïûŽ„1ÂH$ÖÑe±‡ÝLß6âñÍ!â[R YÏÇ÷%ƒ©LZß|uì(¼;ӇㆌT" Ju Ýèi9që$K»yóì§ZΜ1cžå¢`¿ðÀ­Þ!–.Þ‘~ÁÞ‘ôM¥[èÖ@¿ÈXˉ "#w絉‰™î1=4ÜÿÝIS-c#,?ð‹ð öóµt ‰´|ß;ØÏrð馾8†ô ·t õõ afJÈâPÇaáN‘Ë£œ£c¼WÅnõõ[½ÍÕM@ ÛÚAÁ¦ÓmífΚýö{†YÍX3®Ì8f óãÆL`Ö2ë˜IÌzf2ãÎx0‹™iÌFf ³”qbf0Ë;f93“qfV0³™·™UŒ ó>Ì gF0£˜W˜WžyÍŒa¦Ò:2FL(sSb+i2vˆzÈ}©ƒô#+££Ÿgkeódm²§l {‡sáÚ‡Žš8ô+“Êa^Ã.›Ž1í2fÖ`v×<Îü×áÂp÷áe#FŒ¨ñËÈìQæ£öŠJó>cЋ&: JQ‚[P"b7ÿ£Ï 2ÄÑ%à½@ACdÄ!ÅXÁžÏ_9ùÜIÁVk®ÃAºn@µê#Sk½²ÈÜ>uñpeÄBÔýUkÞwôø‘«õÃñ¿ðMikßb^ÑÛßc¥=Xœwçþ£ç^%fZ9Ž«;x:¹‡ö·Él¬#—y¬Fgöi¥Ã†¥¾Žd¨œL"ßðøz²8t?a¶¬ œOX¹¹ØÖ,¾®“4¢)¢©T¬ÃPß°}LìˆýlkòýpÚ¡ýwq”@4d O^z·>*o–W9Z¦‡¡yçþÐ pOn.Žð‚yß©=ºWàŠJôÑKΣ•˜Ù.íKê›ÍWCV”ðž£Ûñå5‹À‚¤éd<ÙF|p™„*tBÍÑdZf\R$ªåÉd*áÝí`Ì*s»Ð²ã  ?•Üè<{ñÖ“üãp ÐÌ»,Ñ$k¡¸jÐÔÈi«Èz=Ž×‰£›%Ïh·rèéðC2…wµ²Ú¨ŽðO€Ã·~ùmP˜~Ÿ¼áê³c«ü$KýÞ½þ¼?·ÆIlã?UÚ Ü¥nW2†ŒwôX©PTuÑb>x™²…4Çýâz~›lýÜ€®‡œéqë·ÉXbýdŽiéÊ;qRN¶ü%¬±š÷^࿸•«»ñ ´ù¢³û«£ó7Ó<^ƒ(|öì)rRôÅ(^—‹³p¨°71u7Är>ºÝµµºým]î=:y兩”ÊÈÜÇå-š±î@Í@ÎÙtîtõôç¸ÇáœE[fÒçÀ÷ß§°{h¥ÕkP‡á܇_"X†}”çµXÞŽ Þ²Å)^S„µXÖ2œµ‹‹‰×.3W§éDËIËÜsE*š‰ ùrÈKSArœ¡LLMW†–nËñ.˜LòÚXÕ˜.¯K×¥eÑä#áàͽ;¢=V•ö„ iêÌÝÀEƒ2RNXv¤–äj ´B8P~4à4”ÅYˆÇÃt1erŸ¦Àœuù+ VÀqîÒ}¨DiÎÒpŸg€K%dUÓš:ÓA`õ¸°Bò/гv)ú‹ãy§'ãÐÍ[¦žè9q¢’Û~‡4²Vw#¯ßì8{S8åíÎ:‡­†ÏªóçRZ¼£z,Óï6Ž‘öEôæ{õ²•%øÓe !Z6E/)#·±¬WÏþéÃx³õš_ ™®_ ~ ÌVxo“£õ íš1-.×õ’•°W|Ÿÿ­ÕìÂ-ï;¼—Q{FÀG,qz ‚$vÂg!¿ÔÜ„;z!s¾ åëY—Th•‹F¬¹8‡¢¬‡žÅšžÒs ‘^毚ÞtMÿÇE£þb¤`›5O ®'Ð<ˆ ÃÒ+E^/SDs>·$;ïpzÖ_¥Ø *ø``¶®*=U êô$9Jò MÆgô²HÕRk l ì‹KúGiwiÒ«Á¢ò4Ú Ž’Ì`†>_ÑŒÏÝŸ•{Î!DO êñ/ž‘Õž€xš!#I>–[Œ?ÖË"T®4}Ž QÝlVʾøì䬴üH•2U­\HÖŒ! –â#UËhüð„àñ8­dnlvjXP$åUôbÙ˜^Rª2¼µ¨‚¬œÜ2Î\Ô§éЧgë$M´E>VPàIþáâóÄʘ¤Û{Š­k¨¯l)O-Û] è´5PÜ•6¿yò­,™Ifyé äb®~y¢½£B¾ ? ]²Ê<¨ªL†½òU™P Õ‘œå§ÙÇîØè£;ö2?í£$lÿ¢‡ã Xä ”"KuÚC÷\œ¥ØƒzÙFÕLXÛ€Èþˆ@ñœ¡d“N¼¤—T9EÎçgç]4”8P•ñ›˜Ù ñJešZihâ>ò*6šAkJ›èú¢‰Yt韞°7$=Á"z˧¥ ˜£Él(„NQ¸©Ãû“»§ovT梒æ B]†&R1‡ò…‰´G­NHRwí\n ±œz´;GãèÜnUºZ­V©åJe|„sÞM»k+[Š:ï6gqZJŠ%oþh‹Ю¹\ap‚^×Ắ߉ŸÄöŤla£Ê½êhž±6³ˆ%±~<-Ît–ëZåî,:½œ‘%’þ¼÷ûñ”ËÈÀW.S©¬j‘7žíΩ†6èˆÕyQLä§5£[=¾;(½É¥¢†ñÕ9PÛzks§Ü»Ý­h ÝaÆœñd±|:§à”£½ûKâ mZŸ&[áíI#Æ«ñ³òz#M[fkesù¡«ô”´Ä4s{ -}#šôwZIûªñ<mH8‰ o‘ ÄŸø£%±ÂtY¢ú ¤Ÿ|Ư€U~{ÞHÿ'U¥O³¾m»ÒñùõÚn*Ÿ(ê·^SèBI`bâÜ NákÀ™ã#J€ÏõA ’ñ³ûm 6p¨LO†=•=»\ª+ШU9B\Rònˆæ¶Š=PÕ\ÒÑæß¾d‘úN¿Hq“<ÿmÒÒÝKZðÔœ_ÁNzª3çx|W†ïüãÞSd¦Þ#óäýS,û3Sâëb¶0o™3Ø[9‘ã)ªMÝdó!œùðÖ!Œo’4Þňޜ»R| WðÇÃÎB õ ™/?ï iNÈ—×—Ödï×(Ó•ÏEï:p ¸¼²&ö·Â':6Zð©ñÕzЦkß]”ïÓ(ß½+6€²‘¢z[垈4—Hø€s½´WáüoOßú~M}x¡àY³fA8xAz¦"7¡…N^fIA‡ÃrøÙpõØ1¸úÝwà´y38Í–Ÿ%žüÏãÝÖPû1ÆÿlËÅ PB Ï=²­Úš{tâ>CÃßD^‡­Ô5Š×Jx|û|'Ž4áþ®ùÚ6Èïãò?÷´‡Ÿ×BI\¼:1E-OóY› Q”ý|®p$½ž'¯Ÿt†n¸¯ý¢ýró™KÍ×áÜŒì\о4ËVÓ‰'“lœ|®øU{çá°iwVš&]ŽK”¼|wo¦ÿLÔ•Ô×W4¯Ü¾©Tþ›µ6Œà_¸k›K‚ .æ'ÙýÙ¹ÿ·»ÆKLb×Ï8ÎU)FôIù¶í¾>A~~m­ºÆ6,!Δºÿà˜®BÝèâ TºˆS ê› ïcHÎ?À¤˜+®â'V)¯C1×¥ëîéùn])dEƒºü…×@WÖà}R•ê¤dA±1¼rCëdj ­ÚÉòæMÅ{å'ݦ=‹|U¨ªŠ.НN½€Í"ò´IÔeó›ÿqô?™™Ú|¡ @[T[{nóÝxƒ»q¹·÷Ÿ.ˆ¤––·š–÷û“üÊ ¾}óøÿ™ ‹!IÆí2-Jòîá8àîôO¦(d·5O¡ >…/àö ”O¿¿ÍÒ€<{-2àæ ºgõ R¼‡:Gý«0¿@{,ôl˜*†êI¸Aä 8Ö(S2Ò2T*9YAlŒEûç.*[WïâëliaIQUš‘crS¨Ò¨¹¤Ø+(ØÍeÚÅÐ>ÌîHÌÜ›•‘•XÌ ôVìéllpß þÏÉ® $»öÏþp±óü•öÝ£ð{è{’ÙlZ¶c°çÞ²’•0Ü]¢=¹ÿø¦'¹sòÂáª(‡¿Áâ >?yM+ ¶}éÉžˆkù 2î ‹Æh’¤ b„ ¤øã¶ÕE4éV·œÙrΆÈÈÔ@b&ؼäÖ;>>Ç¥lmŽ:@NnýÕçâô¡³ò-Ž“â®ë£â»=ÈÇGÔ:0*ͪ|îV!9/:KÅä¾µü¾BÈ W¶7?~WFÂÞ4¡ßô×Ùé TðU±ÅIEåÙ%9†/ÒÊgé;*$¸¥ø¸åëU°CX´’H)åp»å²áTΑ"®¿ŠÈl»æ¿¡“®Þí'o±†]Ð/¢E—^r-Ð_•ŠÜAýŽ2:Õ5.)%Õâ(1ÛÊZýðEIJ¿¹Ò84±¼FiÔxòÊ©ëõqÕÍ•ÇÚƒ*ƒ²…#ÇNeW÷°ã=G‡õŽ> 9 &1Iɇ±»Å¹†” GZQÀQ~‹¯¶7K¾Â!èbФbü–Ze°öÜV„‰vÎjò”ëµ%ÐÀµ…Ôûx‡„xÛ>YG¯ôó¾þáɉð‰mð}ݧçákî–ã"'Fó\çohÝs þÃòcÕIM›r…ö¶+Ü}p ÎØ¼ÃG¦òS%¨cÔª4%¤B·;*ËIW\Aëù¥B—¢ߣŸ,.’Õª³ÃcU— žþÕÆ (LP« =Iؼgc¢|ž›ö§j”%p ´[N:(a%Väk2óó„ÂâæŽ{´Ê0m#X“áÛV(?Ut¤ª9¬n[ðöØM³¿¶Ça8½ç>Ž@ó¹ß‘·¶z¦ìPÈ ‰î4šl–t"þøŠã¯<5+çž®jïj½D•´YYî—±'vrþu‘‡èöw|²õÓ±d$qp ÅË”`Žùé+j},'ß$ÃbVœ­JÈ'üJ?‘·W·AËáðS'»Ã;&Â;Ö†:'TŠÅhb(‰›Á–êÄG¼64 ãˆ¿,•Êß¾Mx¶ª@•Ïy˶ LKOüùþmÎ7Ô°sè,£FÔ*~O«+á’í`#·¼ òj‹‹rs…¢RzƒèœVŒFnqæ …¢«½*ò eds.«7AÉ0ÁÄȾÂth“ÖÔ%Õ¦f™¦æ ó¿ Î endstream endobj 73 0 obj <> endobj 144 0 obj <>stream xœ­VypSuiJy@§%B„}/`Ëi9äEa;ˆ¥Ê)”¦i(iÚ$”ô¾’¼¤MòÍ&é݆ÞB¹)…RÀb=V@pE…qVÜÕ/þúǾPwGggwgçý‘÷fò;>ßïçøòˆð0‚ÇãŽOH~mA\èu&;•ÇN cÇ,~Ü: "ùÞ5-R7UO@ʧÐÎñŸÇSæê㕪ÂYÆ~µ(V2K´`ùò¥sE ãâ–‹VgKsd±B” Vï—f‹ÕÜG–h‹R"“ª E±دV«^|þùüüüùâìƒó•9/Íš+Ê—©÷‹6KJsò¤é¢W” µh£8[*¹Ýü‘Ÿxe¶*W-Í%(Ó¥9 ‚ &)”ñªƒê×6¦o”&fÈ’·feÏ'ˆD"‰ˆ!6ÉÄVb61ØE¬!ž'^!âˆW‰uÄ Ä"ØHëDÁä‹ñx,À3ð̘·>Cã‘Í@ÏQ؉›éû\lCü×鞡¾®@^èØ›”š#O¤É;RvܛΠðÐìÏùÁþàJÅnq‚´šÝZShtÔ†Õ©76Õí!NÃrœ‹Ëñ²c…¶#Êìóh¡Â ÆHïÀ+ñ„õË€\ºè*šñV+Zp…Ñ׿ü²÷# ›³ø@…Œt¶×f©·‡ám4÷1*6ñ=þx’€ÉbŒéfRWzG…‹n‡N[†nc.F>묆FŸJw€ÓãtµÙëèch¦«¨5í¹ûŒC±hÖ‰w¥fÈtù`Š/ç?¨ºŠõJúšZàî~ëã+@žól–‹Uxœb=]ž“ºf›´÷Ü6‹ÍꦣعÿwÐüëýoßÓ_Eߨýáä蟠‚³ÚsZØJÊU+br79ú‹©~œ+ÙXV§V¥lÌxÍ>Ž¢z?_ÙVEE?R:3Ügžii¾~§½G›î¥ä•Œ ´¤ÆYÔRßæ;Ó›vâ5<&mÎv*ú'xéÝÒ…îqLP|‡øM>ªfc÷"ê½\itPL¯ˆèA±ö°‚CØ\äÐæhó8’¦ãE£–Di  ¼ êè;ñø¤¹²²J…;H.ý½ÿ ¥ËÁ\ÈP…¯KVmR­u.¨sup°ò¼7Ø$>;™E÷agÕ ›=;RIK@lLƒ4Hµ¥…:ÅmTX悦îN(2šÊÌFO>Ådê˜WA˜§ƒBËä¢OÂiÛ)8gŒ'C‹\¡ö2Ÿ.¯œöZ:*8zäÜ·Øk|öiö{AÕQ§ç =#€5ÜÉ)°Û¸‡;Yl“„61”qÝÐhçNSe)§Ÿddf-‹.»*‹³þ6’O‹Ý ÒWÆr³±@OɦbÇùbDØ\N›ÇâäjPˆÅµwzýlL“Æ?ñ›{Š¡Ú«“£¡`›@Š—¯Þ»È×K;,‹ËB¾v¨#›‹½…åé†-ÛOÉ®|ÿ»oZ©¿±”Åiu€Mèejó³õ ÆDýŸýµB/ILšš¢;{dèÈ­×iw³£É‹™Ôùûq¬a„½Ö;å´?Òë58¨U•¦ÓÖX ÛÉŃŠË«z!ÐR]Mþlhßi"®£—‡øìåàAˆÉ+« 6ƨ5›T,SnÖ˜¡@¨ñ@MŸU¯5ËÀLmÂe%U»˜?ÅsñÌ%½kn;Û|á$íÝÕ“wz ¹µ6ÐpÜ7Èí÷˜?fs®*ÝR°Aäh¯qA­³…Nj᤽qE2»™k]hLÃiºu¨÷â)pÃ!sƒÒSìQ@Í•&ŽâÁâ']øA5û‰ î«¶N ióYêÝ•™F9ÈAfË õ¼‚빦Ê\E_2¹ó!t&½‰ÁaÃë§àD¶ÞPg¶äq&D½¥œÞl5µA-Ø8fÖ!뛂äÃ%S ½`·8¹Š§jüHåG+8§Ž¸*ŽóƒŠ]ðž­¯ñãÃð.¸ÈÞ}'ÖÏÀÏÎÄkô-yˆ&}öm­ƒñ2•f³–¡VÏ[XYä:Íû'Ž{ιÚi§_p-ûÎæòä!•l:^™œ.\¹mÁ¥m<û+½Çv²I´ì÷űK°—à9DhÚö¡\d †ŸÞ ˆÛò)×[ƒD7Q=ðàþ‡Ÿùçñ3‹2°p[½ó&­‚ ,öû>zàg£ü&ÿÄ»ªë“£@÷yKËwò”2¡d·J  ²@åmrûš¡ž¬Ö5(Ì*M—ôÞýáöŸn7RˆÇ®³×r^dìEåjFQIE?ì,Uu¤NÅáx4ŽÅÓ—œ_{‹Žþ¡ΜòùÈwQ ¯cäW&ƒp«é¶·¯ i>O·^>{Ž ±7«–2t p$üd"štõüñ§“£Yt=+ø§`V¨æpÁÌ”ZÚÛªT÷Ðï —=õ…W¤­ûæÉð¬Š_$Uu¤í«Ç’ªPÔ(ôtö²²Ìrî–J+5O¦·¤]zpͶSÑ©`Õ‚Ö|wiž*_™ÓÄÔ4u4vR\šB€Å=¼ ¦‡Ï^àLÒÕ嶺-nk;Ôùý¡Ò.×´I´I&.ŒÊBg[m 6ª ­µØÁÁU)dáÔ°'"Œ`(LÂk§pÜýYã›Ý6eµZ,ž¶óhzG3Ùq*õz“Îd ñ3Ãݺý:í"ÎéFÌÞºlýp .ûC|®òA“W %tID1dY ´UØ¡†ãµÕ^Ò7LæF‚”[¿­½lN{Yœö2ÿöbvŠ ¦ÇÍr{r÷}¿ã°ÃOËÎtv»ßas4xõV=-…4c:H Í–þÛæ=gøiF¹ âÈ»k hÄGO£°v* qæœæ=à2ðêájxÂ0g3ùP"Üvl_ßñ¦öÖjªþhÍ;`{la¨0Rúœ¢5b%1±¨àà/SãÆ!´í_Ç `õ5w^<3ÈÅb/ì(Qé&'©ê_ s'Ñâ‘5Â_-úß§Í»›šv¯Ù¹wo6ÅÜØÞ˜‰°+S¶çÿ0y¢kðˆ‡F!å¼-ð7+å™Ù™ŠÚºGº¨¨\?ïE­uþ,öŽŒ½>޾´)rŒ¿*2’ þJß*i endstream endobj 71 0 obj <> endobj 145 0 obj <>stream xœX X×Úž˜L7ÒPï U«­û^¥Öº[TÔ*jÝPTd !a ûbr@Ö@Â&«ë®X­T jÛX­·¶ÚE±µ­Ýíÿ=ôþ$Þzÿ{1>pfNÎòž÷{¿÷;"Ê¡%‰$‹¼}|¦N±ü9F.Fôþ!α‚ñÉrGä,FÎ #þ1ÝEà‡€~lL‰E¢ˆèôE{ceAr—v½ì1uΜW&xL›2eŽÇ‚0YÐ.¿po?y ˜Ÿœ4B=ÖEì ò—Çz¼47P.ßë9y²R©œä5)B0ïå Ê y ÇZÿ(™Â·ÇÒˆp¹Ç*¿0ëê&Y-ŠÛ-÷—yxGìö—…Sµ`Aø[ #6-Ú»x‰liÔ2ùÑ^ ¿+cwyÇí^å¿zÏš€ÀµAë‚}BBÃ^›÷ÒËã¶l°mâ¤í“ã§NSÍš=g”ç«5’ZMÍ¡FQk(Oj4õ&õ"5†ZG¥|¨—¨õÔËÔjµ‘ZH-¢&R›©ÅÔ$j µ„šL-¥¦P˨©Ô”5ZNÍ VP3©•”7µŠâ(žzŽêO9Qs©×¨Ô>À}@â€Ïž4qÐÍÁSß²zH“ËT—(é?¤¾Ò&©ðüÒç²£Ù­l{›ýß¡üÐ…Cã\Å®ë\ßu[àö©»·ûgÃr‡u ÷* •Èô» ÌwD…`1˜…;lêa•6…£x”êtÝTHŽ2ÔÉ)(‘ «EzîWº¼54*Q_õ»#Ì¢«F9(QhX5*ç¥õµ¨¡8ó@Ò~>#'% /¢Y-} ›±Ý=)t˜|L.Ìàcv•~ žÂól*ÝÅ-¤ãed ZTŸÄÛm-˜N—qe(žßKhéÉŸ?9üîù’ˆÕVî–t÷;hé7Ѿ_ýË[ÇçrÒOß@¾A11L÷Ü‚Ê$:,øŠá|Æ‚#È+éRËw"Q?ŠN¡°Ð*TÅ/ÆcæÁGCjlY_E’Wµ¨”¯¢ÁGcw¬wŒ¦ã£ÈÜ5äéïÖa¢œÿ6ü„78Ê£Ÿ~e™AÞƒ€Â¾&—oÌ`ÞB@`†pš…!ôW•ÞÁ;C¼Æñ£iXÁ^­!† °†,ÙH—Ötï:¾¼JTÍÄɪw=avŠÑ½ºÒ åu5Y¼‘†—ð%G¼B&é{N¶‘d°ÂS²IÈ7‰Ž˜á£Ëb!F¸Í–¡š°ØÌ”ôLN…Ô‰²àºm†·ÃX²…ax9^ä7 æëÎÍQ(9UŽÂÕ|úËžQ;3eæ0^¾÷Gçå Û¹¸pÆø%Ë—¼xÿ ‡Ç8õ;žÚ„=ú¤0hÚ/lñ â¥êÕ%þOñ¸«îßñ˜îCó®ÊÍâ˰==KùÊ.U4Ýׂ4¸Þ˜ 3fÂ8ìÎcI×iVPý ÇvÂD?÷&„ÅÖ‚hlïÞ†«ù¤y+ÙÊŸLl˜m<§›ó šøNIª D %·$Ò.ˆWÉNßrUVp{^Çïä°+lõ:E²@ÆÝ”4f⺞³ÅEƒ}tÃD3,½ç*= 2XÅ~wéÀi£ôÊÄTÊ’ŽÍ~kEìJ^úé!ëP¸Ÿ!wp‡§­%¶ÂâžY‚-ѯfAö(†×¡Ž…ô3×>‚!çkbC¤¹Kl‡÷$7Ò½ãrÃI¦P“«ôxòYy®2G¶?)­H[áùÈô›Ad9ôiä0dÍÂl†xö]ºisfXÛ¢Œ÷ñ>züG7?¹s¼³ƒ5Š8Nã½6EŽ˜yè\ o§–¢{f$;ô"²Sc7¶Ýk°/ß§ßö)tM—Jfk=-8 Ä ýl9²2ÀÇÂìÞ¬6±Ú#*GÌMº¬¦pï wénn=•Ê‚Hšê™257qP%ù{z¼9ê&'9ŠŽh­cžZ8kÉ ”] ¶P]*LÙµÛõ£,+Ï:·L¢ja¯XXHÎ¥Áœçl®£±ßÂ"¸åX÷T>Àhà‡EAdDî¨ 63½ÀL5ýlr¹`ÞÑ Þ…Я‰­ =£9Œ˜ºý÷KÙŸ“ÆC¨äãõ_âÑ;^D ÃŒñÕ¥u­Zåkµ†ìm1*@Ì?Ï….楧ñ’}xЦñÖ^Yþ+'U´¢Ž¼ÓL2Ñ’W$Ä“(vÇÄù¢4Äxï<ôNÛ×­ðb®5ÃùLàØ§â Ä_¸±°üï¨wéh%Rj8i›ßQ¢éÃí$—&lA¾±A¡ ÞäpSò·<`;#‘2È1-%ÇÔN—ìE– »Ö.Õ[Kpî•_‚% ¥‚Èo†Ä’…bLÂ!“èø½ÿpV‹pP➌ØôPw Y‘jL¯˜én5Ï>¸FFâ'¹)H4îH-›“( ÷ P'hv>*fjbËe{ãb#ýíjûù$¸ær}^ᦢ:űuá(#>E­Lç2c¶.@̬E׿9Sn|¥òÚÀ U5bªúú›£/ž¿˜Ž¿{\€?ô£¾'–G™¡Á$ºÞ5íb8.8²I©áጆN9=ŠÔº”jR!fu¿FÔÄw©$!ŠžÍܵîQBx!R+)Üvûä&æË‹ý÷§ëÒŠÒ‹P1*ÉÏ/ÉÑ}º¢óŒ¶+’~æ—U’&c5YGÒF–*5’éÍ_¢63íÓ'¬Ñ ÍAzæP4ŠáðC:8--˜ß&éË%µ-Á×p›B©Ù‡â܃*Q' ¢+uÈ€J™‹¶ë+%½áòQ7Aßî%èŸgÙ¤:ÂÙ ‰ {†L£¥mõÁ;Ëv Ç¢ñ°~0îÂÓvtì`]=!‹%ë|gÏ[¼úãή_»~µm§ÛAA0_+Ü`“šrö"f™tZı¯õ‡ú ZVví+,ÓÔ"÷†¢œÃ¼ «‘ôõxÁ^b#4=ùrÄexÞ$º`†jä\XÇ+P+Ð+~ÄC±Óø±Ä­ üe °àvúA…Z±iûbÒùè·Ö§F ùhþÙø¯íe¶äæ¥ ×ñÀ²‚ÑLŸ'l7ÃA2j \dᘢ{coÅ^|3îoXYyŽqx'Îg§#™1élһ躀:ÐG…§Š/5ÝE·PKj©OÑV2Ó*ä'¯O^©˜†úCH\¯4?º'%™ ´ ­§éÛ¢.«`w‹¡ª¬îò«(þÕyÛfpÆÚ2Û/¸cŒ*WÛTyLYi‚}&Q)5ÑOP[ì?07<|¸à–ðXn笺Tvî XÛ`a´ røƒþáøÒ v,O΢"±—aÁû.öË.õc,ë‹oÞp•þO2¨`1»Þïôù÷Oœ8÷Þ±­Önß¾‘ŸÈæ¨ËÛóíÍ ©õqu¼±¨:·X«Û[•~1úª¢úª˜ÆõÉ›5AÛøøÂÀŠmˆ™¸xþ¬úàÒ^Š©äøÔè°a(°DV´À-CÉÌÌÇ«àyxþqÇW­±gß:È%æùUNEÌ: %¢´ì”’J’K4”r³Kr0à„¯°cç?Q^ÐÔdàkÊ ÐMÄt‚#š¹}þޱ= Ò=¢îD,^‡S¬¥Ì{ÃRâq°ê2¯ú*Éÿ¢Ž´–"›z§ q!^f?³DnM½'.:å§VqIõr£ª°ºw~vÿŸ—’õ=„ak5×#íÈèˆ;ð;>±ñi$-ýEP;ÔEWFDDGGDTF×ÕUVÖq½¡çrî”]ó¿f¼ ²u_(Ñ fãŽ5s#6çÜÅùÌ:¦)×è5å!=>»uÙJ]ISw$Ì•YæÆýΫÇ’ŠùGöæ½VÎHñ,÷+òoA§Ýßm;ó1ô/ªãr¢ 3 ½ÆÔÍj¦3ãÂÒ¸-ë‹|‰1ÏŸ;ëS^_D3«y$/ÙÇô¥QÄ™Npí†â±àÐÅ4º/Jah×DÅ!ÿÈÀ½þ¡ÄW„£¤ì„l¢øÙ(©“ëòè¸ð×DGáÅ·Áù*'}(üöLt¬[kw3¸õz6·gí)d¡-…œ÷.ÕF»RxÁ¿TVEr"ŠÔè÷RzÀ 8¶Ø9½Iv^ƒÆ³ðGxlp¹MÕÛºT›í,®]‘³ùýù'$ú&[¯rº¡éo>”þWCúáÓXv‡ÖPâDY»ö];Íj_žo'ËÇRb‹„YuƒÅ"&ÄJQ#z›Ç’EO0Þ·®CxX&‘¶u=}´ª$n9‡U’˜Þˆ½õT§ÿØ%“8/ §…íLÜÁ%Š(FŒôN SEE[¯ß½.:,øˆoø™-jF--{HZÆ?Ѫ=(0°ñðO`KZÉ›`”Äã?é¤`ò¦•ÌDh7 Û ¢vaŠXX µl®8U â´Â”<ü5ø»© öiS“$!OÓy8Bê+ò?9=1 ŸË+’Ê r´%nÍ1>‰"ÅÕKñ³žE¥é¹±Exð—ÛÀúù0ð0웲¼\â8ò3 ‘áxvÃØéÔÔ–MÜù…·Ö_V»ßÏÛ{›ãc¸Ä"pÚö ð솛óÛ£#ËP¦%¦ïßÇÃl,*Å3‰݃y<|JBJZ&J`ÒtÊšzØnP`YÚ£BX„^AW>6¸|$¸aå®Òÿ…“ cMA{ ×ýÆg£|ÄŠËKõIj-/Ó/kŽ,ê’[Q^qª`rQý.^”]«ýÕ» æà`œ®õÊŽä0uEU FéÈ]™›S˜QL°­ÁÔš¤ôÄ ¤tÏBáG8|C©ñBáî©(¸¹5Ôk>P×ZV8Ûôd¡­Œ€·úÉÖFI/:8=5„ÿk…$T—rˆ/;ºNx2ÊBØÙÆ'rƒè¢0A Ï?™ÌfHÓG#F™›–›’“Á×-ÛŸ’W‰Ü ¥úòü¬ûtÝ—I¼Qz<Äè[aÌŠ«– ¾–6Á{k|RVʾØL¤dJãôM¿¾ýL»ßÙ¾Kâ_/kÖåi³óìV­"§táÉ =Áæe¼þ…'ص½¬%……»Õ×­Ä›ÕlQ ág …ŸÓI„Ÿ-„¹–P„!"²¶!b¸ÝÁ¶†Õ†øËBC÷4D6®il´,`Bï þí6tß'ƒØ¼2-BùLy‚^ž˜Áá/þZš¯A(Í=¶4ÎP™WZ¬³î ÎZ>½Z¢gQ :’“_~ø~v bt]59…Ø%X”8=Ž×d M(‚™*A(! > a“FŽ˜ eFTXµæ_«Ѿìõ ö” 0ä{.ü˜üBúÄ”W£Æz™6•Ç#rÐÛ¨‘™T³ï¨OñšÒfmMO‰=Ðô+ †L²Ž«=Œ1II™œÿ¬É1êxBMæ–•g–VÕ>ÁuyN‘Øx®1Sz’8ºs· Þ,þð"›š–‘‰TŒå¾–ƒo­çSÛSÄDp8•¾ôî·Ž¹Ò~ê*úœç1·ð@ÜîœY{ê’õÆ*}]QfqjWzêtãÄÜýtÛô%›ßôòáŸ! ä:trcý–Ú•¹ˆ‰#¢Y‘ED˜SÜ‚Lv¿«4ä¸|]ˆz+ÊbðR ÉuøEu7”dú{ßî”òZ:‹ê˜ZéÛeo—žÑV[Ϥ!J›ÂGiq¿lu{ÏÍSkÌ!rþ¨:7vßb†oØxá»»÷Ñ!T–¼?“üd X&ª\Y[cÐ7´¼7#ÿ`_Nú§€ÃŸ@ôã—à ôôNÜ“ ÑÆ8ß xà£ìr´»MiRë4:µŽAH“‹È¶¡³Î£4yj=IÒ—ÏþóÎù7ÌôZ»ÈjS ÛÛL.'Ì>f¨2[nkA)t± ½O¶Ÿk?óÙí÷·l\ë½}!ÿY(ûùÁ“mè}æî¬ÛØ ;¿2×sí©MŸErÒßæ+V¬™?lÜÃé0\¾½ÿèÖòK ŒÜ\ÜÄÎöj7›.^ùæÛ÷W®Zêµn6otN´,Ì;!ñ6™RMt?~í¥ñ(he¹û÷ëH%Ykˆ”)ãÂBÊ{ìFRùØLÀ€ ,6OÀâ1³ :ôýi@ÀxtÓŸ<Êàѹ¬ç†?¹÷qûãure_\ô1Ðje¢ÌÜx”Êø¬_;»ÛŠaäusFD-Âf±Ð^aÿI÷…±]cÏØøÓ% Ùßu ¹‡¢¬pMRà6ú™OçÙ$àC:qÜl{ð¡,¤abKâŒ9õEÙ\ tüíÏñPB•ߺGM[ ¼l¢$8ü]•ð%‡g)[èoý¶En‡¬¹d¹ }æÒ‡kºØÄõþ1 iûTé(¾[†+x>kòˆŒŠÐ¶q“ …Eðz!có$¦þf'®¿Cl„ós&gg³óŠú?øïfM endstream endobj 64 0 obj <> endobj 146 0 obj <>stream xœ¥X TSgÚ¾1ps«¸Ò«ÐÖ{éèX·Z[»¹ U[E«¸’°'$la /‹,d ;*‹h•)¨µV­©Öª±uÆÎÔZg~=c;íÌwžÿÿ’I§zÎÿŸÿœÈÇýîû½Ëó>ïó!¢œÆP"‘ˆööݲåuË·YÂó"á…1ÂtqŽú¯s1¸8µ¿à~gŠ0~2*ˆü'Qb‘H©I÷VE%¨ÃBBµ³¥s<^~ã¥ó</Zô†‡—B®“*=|µ¡rE –,"=ÞWIÃäÚÙo‡jµQo.\· P¡Y R‡,Ÿ3Ï#.Lê±Y®‘«cå25*¥ÖcC Bîaunõ§·J£•«=|U2¹ZIQÔÛ^ÊU*ï¨w¢W«×hÖjßy/6.0È'Aê«“mo  Ýöþ–­‘þŠe³çìš0Áž…‹_^œ¼dÆ›oQÔï¨Ô ÊšIm¢~Om¦fQïS/Q[¨ÙÔVjåOÍ¥¶QÛ©U”75ŸÚI½C- vQ«©…Ôjµ–z—zz…ZG-¡^¥^£|©¥ÔŠ£ž¡ÆRoSã©åÔj"µ’šDM¦> ¦P®ÔnŠ¥œ¨ç©¨e$ï䫆º+ò•ˆ†Æ(ÇœÏ7;99iÇ8ïs¾K‡ÑW$ÏJ¢™1L óÍ3 Ÿ¹>váXÓ8Ïqe.¬‹Òå‹ñKÇÿ8!dâĉ¡“&L Ÿti²Ëdå”qS|¦¦|ãú¼ë6×b×®·\ñ³ ŸMb)ÖíŸê=µmÚ®i†i÷…Ö B+˜¾7 ®u¢VA)Ffá6½'¢ t.Ã.C5naÑÞùÒÛ¡³3 ”|Ý÷Îh1]·ÈYõë‡ÑÆc½ÌbWº´{i N0yt~lQt‘б‡Î™DÿeF~f±°`íøð ¯]R½žkÏ®”r^t¢Åb TñÇð`}EŽ«j±žžÈ¡•ôƒ[G?:YãÇaM¸$IEvµB%æ:ì¢mç©LÈß$ºgFZ³Ø$ 6Y1ìrãFC®ЈþôÞW7ß¿à]Å_0ž€KÌMŸ?â1vÅ,òG%ªõUî ñ{ƒw³H…¦J~8¸8zw˜ßž–eB—M¢³fd$Á©P$‹&Ìÿ3˜™? OÀ“x"răh2‡ƒñBÖÛ÷Ú÷ß^ºtíÚ%Ÿ%‹|ßñ¶˜Ð›„ý&Ñ13ê¿%’…›l%´†Çîωãövì-»a1žŽ×àµh žŽžCô½?ÿíˆ ôÉ1ûµ9ü>LÏÚ—Ì·…^D³îüt÷“Ó++ø‚¸‚ÄN`º¡±ÖrV›çH1òÍbŠÕ¬C†wÒ‡=ºÀ ñ£¿!W4~ñß±ÓA:Uß±¿*ÔPc¡žØOÎÿáÂç×¾ºhíúÕ^Áw>⬥4&Ñm3*7‹/:袇ߨÒÄÛÞo†jÉhäþq} zåUä‰_à±óP+hîKÓY<ÓX²»à1Q\4‰ºÌ¨Ždýa:[ r9Ĩ8UKPƒ?ɘˬ¹xžð`¢ÿØ?PXÈã Ý’$åHáߤ+ÛHÜ HæwÓ+Ð?Øþ«Vx­¿ò—{_^6ß<±Ò׿=R˜Ðvkº¦˜Ï“„­@GY4…¸nKR¹ûÛÁq!ž‚¶£Œít¤Ê­é³åãœéu"4ÏLj,Fñ‚ˆEKèÊVâ„ ’x¼ä6mË¿:{ëul-T÷ ާ1eûâžéÒ—‡•¦Wçr9A!Qr`¼àlïÈ6# p“ÐÇm%QZ¬¥­ÛˆA#öÇ2äÿ´§CšXû µïŠ%<(ê§=¥G‚e}Áµ¢æW\L¿½*I¾ÚÚ8T/ùíó|zá%å7§»+k›¸ÊF¨æÆo¸ÞB0(ŽdñcæOväá.z´ÝÒ̰¯P—}× ««Fô£IÔ$h-ŽŠØ‡J0vèøÂ tÁ¹Áîy>:‡Zhä„ÿ\!o#¸¡*º™QãUB–Xã ­#þµ¿zŠÀÝιtvSÒ ¾#éLVU0Èa¿.i»úÕ}v"“KïB=Χ.S+4ðçñbymN#¸‡ÂòÊÓMßæ•ç×’œ—Zn\upGaRÔ@÷ cÏÏî›D§Í(–”Æaכּ§0–GÕÆ´×¶”Íç $/¯"¿,¯ÊùÓñà-¼Þ¦Æ½®®ÿáöGí¥¼1²/»˜–f«KÉòô‚B=¿â bA+‹Må¦ãt¤ë4ÓŽ˜¼áiyÑ„D£h…pù·¸Ê¥@m!›î© ?ëôôó/3J%Ö×D :@ûU;:‡4áö•0~„‰Po™#±„‰S-LŒãLBƒItœ$j ©^5´@Q~Y¡¡jbTÇa1­#f²óâ«3øâì&¨†Ôpí;‰I1ïeªIå²fÖ!jzÉ­ÒR„‚ÒƒªõzV~\m&_”ÓJ^Gøg·‚Œ¼lÈìè·ÒtaÑÚàìÒZ·ÜŽ˜J 0Qq iÇžÁ¯o}Þ`× _šQøC±Ž(¶^W›œ Út.a40Ò뫯|;ÐñOäÚV“{€/ÈÍË…ô|¥Q×L{m}Ë­€×øaî5ìò`zý®ãA5?šÏ«‘ñ¢ ê†Ü¨73#IX™YU©]ï¡Ýné­R`6ÙòÙÍüF="oÛ Ѽ Ë“P¤×p4 ±4²J¡ö€¡¶¨âj3ôä5’æ–á¾ÙDÇRåÌèœüÈŒ‘ú!ÌV„¨`ºÔÀá¿Ò‘)™Áü’ÑÑÕˆÒ$øs|2)2 Å=¸ j8ô‹­öŸØ§p(.•8‚õ°¬„žV<—8x а¾xö|¢'|?9Ý×ØÚÆ« þ8÷+ÆZ¦±›Þ^ùîÓÝïL¦ëç¶o±ÃöþE¤&iþ@¸Â&÷j!˜ÕO#ãŸØVΣ>S÷>znHâvPZÍÀ´ÖäõñB®Q2ºq†£±à\:öäÇ}ÌØ"u½Œ\'|*¾ +[ÛÝÈeí_1‹'Î}‰hÙqf¢Ðôw›,ðÒéscô|ÜîúX«ú¿fò.³•_œÿÈ÷ auÑfTÚž³ Zú„E}±-x#Þ…á>cÚˆ6Ô· c–á|ö5ÐÓN¦ÀŸàøΗõWœ;l¸w %¹bSénX [a¬ÔïHÛ¯^£@ãÈXOZ¾Ü2JÇ9ð专ô¥~CWÑœ\Œ±¹ªã³¥¸üõÀùüNOûh}ˆç:H¦ÛÕÆ¸¹–ã/£×/÷_F[.‹.›Ñ&ó¡Kb¢ 8¶Zß™Ü ÌÃ7¾=’r(µ–¯+#¤™_¤©I«¦±¶¶ñºu{ÔÞŒèP>½HÞ°˜¹^^K"ÊBÑ|FJj¨@Y®*O Ô(wÝó ¢6¦sEÔ§w¿]1èQÈ)ò¼r”…Ì8•W^Pœ€¿wŒÝ±§ïÌ™} ßë¿-p?Ÿ×°w‘¼äøÒ¬wŽ÷ö=v:¹} Sîo/`hÝoçîæÿÓ_Ü6,2§²Ê|Ì<Í5 èûaK×|ÊüeÙ<–ÃkþwjCJ»ܤÐíÑ ñD1Ja-„¶„6Dvf’4ÖrñÃà ÈÈPBD.¿/'$Y 'û/AqF=皢oL¬­bð”#ìt•¾×·9 póËüz®#J„öô\βíšF…B£Q(5íííöÅ®¬]<ˆð ~ÆALœ²#eºI[³9ŠüÓ×БkbÁøR§KÙJ8¹boÛr¢eËo¦óÇÛ2oèzõnçSʳcª+Émœñß»ue —þ=“Ë­Í­ ÖÀØÕ*‚Ë« º Ü©H“þd>Žýò»ïúO„áå=‘ůÕ—(‹3óäeÒ8ÅôŸ:yI.Ž<Àˆjƒ] Ûx§ÅŒ&Y>6 …&=Aì»Û¸ÔËÎ¥hÒf—Õjå¨~’d¢úÍ(‰ .€nqÐMS.Eøý’Ï6ŸÁGº×"yÊ®û4~öþ+Ýÿ±ÜJ¿afÆ‹*3yHƒ';¬¿v‡“­…C&Q­F.Ä¿CÍÃx›iSflü;¸+ekìÒ¬½î¹tV_ì”AotÌ­½i˜^fÚÌ7Ã!Mª0Èê‰@poz0ôØÔÀED[>bAŽÎ° €œ^J ‹æâª*”D/…gFFe¶j! ˜ÛÙÐÁãAI„f¸ÁîÚ(M<ò–Ü9~²×hÐnç°N¢a°kÿ§-Ä9ôþ­›·DÝÂN±à‡°†nèî‘Z’ów:Y 2y7xô3žÇì…žn9èyüoZ/¹¬—¤“xÝøXKn1+I}}·±PVœYˆç=Ò 9pz‹n3w]=Ñ3p¸¼$¿Š˜ŠôM8ÞƒŸÃŸ‘ߥ5œÝÐRÊ[†D Þƒž ×êuÉiEúÒL®[=(ï[vȯò]ðÏP<»-JHÉÈ‚D&Ù kèDd;*¶Z2=v' P—6?fXûð¡Ãõ¡ü/k%a†ôNù8ÌÏÇîVŽçh,z^„v¢EbԕϦÈ5jYJzv|&Ä0º*]ÍážE’ Òã»öª#B"B?4äåp8×¢:?{̃ÑÇ®ð‘ç/îØÓaícS–2ÔÝ–ˆ…·P[ÖCŠ ‡T_¥Ód$ÕÝPnmT›_Ï‹Ñ_>g{#ZC¥ªˆPi‡êHokÇ‹³GŒÌ~ª [–éãqlqU@ ÓW™ ÎÐ¥eqø¿¬Ú—˜ ᮩKªi*©.;`§±~³¥6B¬¥6¾3Ð4ìŒé™Ø¯Ã¾?áiÈÑÿ@îh‡dˆ/óA š‰~wåáõëW<ñ œ^ÆEÒjÈÌM‰eð’!šE‘è{gü½õ_`FÄÝB<ùÈÎƱ'éQ\‡Òÿ:Ы)÷0Øž›–Œ%nžOúã*{\¢u˜w Så„Úz Œ?BçèRçC:S­«ï,lî*ä ŒÅŸäW3žúäºÝ ¿Œxö¡Õ¬U#’E¯Úûý÷oÿÁéIÍ;Ì<#o{<åí÷ð³©2µV•’™¸€TW©«m|ô1bΩ?Ü%S)eI%;.äpôÁ»­4Ð8¾HbkÇuJP¹>stream 2011-06-16T14:28:28+02:00 2011-06-16T14:28:28+02:00 dvips(k) 5.99 Copyright 2010 Radical Eye Software manual.dvi endstream endobj 2 0 obj <>endobj xref 0 157 0000000000 65535 f 0000088399 00000 n 0000198172 00000 n 0000088231 00000 n 0000085521 00000 n 0000000015 00000 n 0000001677 00000 n 0000088465 00000 n 0000125804 00000 n 0000177693 00000 n 0000125074 00000 n 0000171523 00000 n 0000124042 00000 n 0000161498 00000 n 0000123263 00000 n 0000152538 00000 n 0000088506 00000 n 0000088536 00000 n 0000085681 00000 n 0000001697 00000 n 0000002982 00000 n 0000122621 00000 n 0000147372 00000 n 0000088599 00000 n 0000088629 00000 n 0000085843 00000 n 0000003003 00000 n 0000005431 00000 n 0000088694 00000 n 0000088724 00000 n 0000086005 00000 n 0000005452 00000 n 0000011829 00000 n 0000121859 00000 n 0000142577 00000 n 0000121253 00000 n 0000138549 00000 n 0000088787 00000 n 0000088817 00000 n 0000086167 00000 n 0000011850 00000 n 0000018698 00000 n 0000120730 00000 n 0000133420 00000 n 0000088891 00000 n 0000088921 00000 n 0000086329 00000 n 0000018719 00000 n 0000026081 00000 n 0000089006 00000 n 0000089036 00000 n 0000086499 00000 n 0000026102 00000 n 0000032959 00000 n 0000120299 00000 n 0000128416 00000 n 0000089121 00000 n 0000089151 00000 n 0000086661 00000 n 0000032980 00000 n 0000039753 00000 n 0000120145 00000 n 0000127669 00000 n 0000127216 00000 n 0000191435 00000 n 0000089247 00000 n 0000089277 00000 n 0000086831 00000 n 0000039774 00000 n 0000044155 00000 n 0000126681 00000 n 0000185358 00000 n 0000126337 00000 n 0000182323 00000 n 0000089373 00000 n 0000089403 00000 n 0000087001 00000 n 0000044176 00000 n 0000049895 00000 n 0000125568 00000 n 0000177087 00000 n 0000089488 00000 n 0000089518 00000 n 0000087171 00000 n 0000049916 00000 n 0000056187 00000 n 0000124901 00000 n 0000170222 00000 n 0000123869 00000 n 0000160183 00000 n 0000122912 00000 n 0000149356 00000 n 0000089594 00000 n 0000089624 00000 n 0000087341 00000 n 0000056208 00000 n 0000062258 00000 n 0000089742 00000 n 0000089772 00000 n 0000087511 00000 n 0000062279 00000 n 0000067779 00000 n 0000122464 00000 n 0000146744 00000 n 0000089848 00000 n 0000089879 00000 n 0000087684 00000 n 0000067801 00000 n 0000074281 00000 n 0000090000 00000 n 0000090031 00000 n 0000087858 00000 n 0000074303 00000 n 0000078124 00000 n 0000124757 00000 n 0000127145 00000 n 0000121792 00000 n 0000090161 00000 n 0000090095 00000 n 0000090126 00000 n 0000119923 00000 n 0000088057 00000 n 0000078146 00000 n 0000085499 00000 n 0000122094 00000 n 0000143156 00000 n 0000120015 00000 n 0000120046 00000 n 0000127887 00000 n 0000128832 00000 n 0000133744 00000 n 0000138874 00000 n 0000142791 00000 n 0000143461 00000 n 0000146966 00000 n 0000147626 00000 n 0000149642 00000 n 0000152978 00000 n 0000160421 00000 n 0000162040 00000 n 0000170460 00000 n 0000171885 00000 n 0000177330 00000 n 0000178032 00000 n 0000182593 00000 n 0000185883 00000 n 0000191925 00000 n 0000121168 00000 n 0000121696 00000 n 0000122005 00000 n 0000123767 00000 n 0000124585 00000 n 0000124842 00000 n 0000125478 00000 n 0000125715 00000 n 0000126252 00000 n 0000196742 00000 n trailer << /Size 157 /Root 1 0 R /Info 2 0 R /ID [<165A89C7738B96598377D457967293E9><165A89C7738B96598377D457967293E9>] >> startxref 198376 %%EOF LogService-2.7.0/README000644 000765 000765 00000000411 11576373445 016071 0ustar00bdepardobdepardo000000 000000 LogService - a CORBA based monitoring tool Read the INSTALL file for detailed install instructions. A basic install just consists of cmake, make and make install. You can find a manual in the docs/ directory. It contains all relevant information on this package. LogService-2.7.0/src/000755 000765 000765 00000000000 11576373461 016002 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/VERSION000644 000765 000765 00000000033 11576373445 016261 0ustar00bdepardobdepardo000000 000000 LOGSERVICE_VERSION = 2.7.0 LogService-2.7.0/src/CMakeLists.txt000644 000765 000765 00000003057 11576373446 020552 0ustar00bdepardobdepardo000000 000000 set (binary) ADD_SUBDIRECTORY( idl ) ADD_SUBDIRECTORY( utils ) ADD_SUBDIRECTORY( monitor ) ADD_SUBDIRECTORY( libraries ) ADD_SUBDIRECTORY( examples ) # Directories for includes (-I) include_directories( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_BINARY_DIR}/src/idl ${LOGSERVICE_SOURCE_DIR}/src/utils ) # List of all sources files for forwarder set(Forwarder_SOURCES SSHTunnel.cc Options.cc NetConfig.cc LogForwarder.cc LogORBMgr.cc ) ## Compile CorbaCommon static library add_library(CorbaCommon STATIC LogORBMgr.cc ) install( FILES LogORBMgr.hh DESTINATION include/ ) # Creation de l'executable logForwarder add_executable(logForwarder logFwdr.cc ) # CorbaCommon library depends on CORBA files add_dependencies(CorbaCommon CORBAFiles) ## Creation d'une librairie LogForwarder add_library(LogForwarderUtils ${Forwarder_SOURCES} ) set_target_properties (LogForwarderUtils PROPERTIES VERSION ${LOGSERVICE_VERSION}) find_package (AR) # If building a static lib, gathering all the objects with ar (cannot link .a together) if (NOT BUILD_SHARED_LIBS) get_target_property (AR_RES LogForwarderUtils LOCATION) ADD_CUSTOM_COMMAND( TARGET LogForwarderUtils COMMAND ${CMAKE_AR} ARGS ${AR_ARGS} ${AR_RES} ${binary} ) endif (NOT BUILD_SHARED_LIBS) target_link_libraries(LogForwarderUtils ${OMNIORB4_LIBRARIES} CorbaCommon LogServiceMonitor pthread ) install(TARGETS LogForwarderUtils DESTINATION lib) target_link_libraries(logForwarder ${OMNIORB4_LIBRARIES} LogForwarderUtils ) install(TARGETS logForwarder DESTINATION bin) LogService-2.7.0/src/examples/000755 000765 000765 00000000000 11576373462 017621 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/idl/000755 000765 000765 00000000000 11576373450 016550 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/libraries/000755 000765 000765 00000000000 11576373456 017762 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/LogForwarder.cc000644 000765 000765 00000067742 11576373446 020731 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.5 2011/02/04 15:35:00 bdepardo * Code indentation. * Removed unused variables. * * Revision 1.4 2010/12/17 15:18:20 kcoulomb * update log * * Revision 1.3 2010/12/13 12:21:13 kcoulomb * Clean types * * Revision 1.2 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.9 2010/07/27 16:16:48 glemahec * Forwarders robustness * * Revision 1.8 2010/07/27 13:25:01 glemahec * Forwarders robustness improvements * * Revision 1.7 2010/07/27 10:24:31 glemahec * Improve robustness & general performance * * Revision 1.6 2010/07/20 14:31:45 glemahec * Forwarder robustness + bug corrections * * Revision 1.5 2010/07/20 08:56:22 bisnard * Updated WfLogService IDL * * Revision 1.4 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.3 2010/07/14 22:43:26 glemahec * Remove WAITPEERINIT macro * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:03 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application ****************************************************************************/ #include "LogForwarder.hh" #include "CorbaLogForwarder.hh" #include "LogORBMgr.hh" #include "commonLogTypes.hh" #include "monitor/LogCentralComponent_impl.hh" #include "monitor/LogCentralTool_impl.hh" #include #include #include #include #include using namespace std; bool LogForwarder::remoteCall(string& objName) { if (objName.find("remote:")!=0) { /* Local network call: need to be forwarded to * the peer forwarder. Add the prefix. */ objName = "remote:"+objName; return false; } /* Remote network call. Remove the prefix. */ objName = objName.substr(strlen("remote:")); return true; } ::CORBA::Object_ptr LogForwarder::getObjectCache(const std::string& name) { map::iterator it; cachesMutex.lock(); if ((it=objectCache.find(name))!=objectCache.end()) { cachesMutex.unlock(); return CORBA::Object::_duplicate(it->second); } cachesMutex.unlock(); return ::CORBA::Object::_nil(); } LogForwarder::~LogForwarder(){ } LogForwarder::LogForwarder(const string& name, const string& cfgPath) : netCfg(cfgPath) { this->name = name; // Wait for the peer init. The unlock will be done on setPeer(). peerMutex.lock(); } LogCentralComponent_ptr LogForwarder::getLogCentralComponent(const char* name) { string nm(name); ::CORBA::Object_ptr object; if (nm.find('/') == string::npos) { nm = string(LOGCOMPCTXT)+"/"+nm; } object = getObjectCache(nm); if (!CORBA::is_nil(object)) { if (object->_non_existent()) { removeObjectFromCache(name); } else return LogCentralComponent::_duplicate(LogCentralComponent::_narrow(object)); } LogCentralComponentFwdrImpl * comp = new LogCentralComponentFwdrImpl(this->_this(), nm.c_str()); LogORBMgr::getMgr()->activate(comp); cachesMutex.lock(); servants[nm] = comp; objectCache[name] = CORBA::Object::_duplicate(comp->_this()); cachesMutex.unlock(); return LogCentralComponent::_duplicate(comp->_this()); } LogCentralTool_ptr LogForwarder::getLogCentralTool(const char* name) { string nm(name); ::CORBA::Object_ptr object; if (nm.find('/') == string::npos) { nm = string(LOGTOOLCTXT)+"/"+nm; } object = getObjectCache(nm); if (!CORBA::is_nil(object)) { if (object->_non_existent()) { removeObjectFromCache(name); } else return LogCentralTool::_duplicate(LogCentralTool::_narrow(object)); } LogCentralToolFwdr_impl * comp = new LogCentralToolFwdr_impl(this->_this(), nm.c_str()); LogORBMgr::getMgr()->activate(comp); cachesMutex.lock(); servants[nm] = comp; objectCache[name] = CORBA::Object::_duplicate(comp->_this()); cachesMutex.unlock(); return LogCentralTool::_duplicate(comp->_this()); } ComponentConfigurator_ptr LogForwarder::getCompoConf(const char* name) { string nm(name); ::CORBA::Object_ptr object; if (nm.find('/') == string::npos) { nm = string(LOGCOMPCTXT)+"/"+nm; } object = getObjectCache(nm); if (!CORBA::is_nil(object)) { if (object->_non_existent()) { removeObjectFromCache(name); } else return ComponentConfigurator::_duplicate(ComponentConfigurator::_narrow(object)); } ComponentConfiguratorFwdr_impl * comp = new ComponentConfiguratorFwdr_impl(this->_this(), nm.c_str()); LogORBMgr::getMgr()->activate(comp); cachesMutex.lock(); servants[nm] = comp; objectCache[name] = CORBA::Object::_duplicate(comp->_this()); cachesMutex.unlock(); return ComponentConfigurator::_duplicate(comp->_this()); } ToolMsgReceiver_ptr LogForwarder::getToolMsgReceiver(const char* name) { string nm(name); ::CORBA::Object_ptr object; if (nm.find('/') == string::npos) { nm = string(LOGTOOLCTXT)+"/"+nm; } object = getObjectCache(nm); if (!CORBA::is_nil(object)) { if (object->_non_existent()) { removeObjectFromCache(name); } else return ToolMsgReceiver::_duplicate(ToolMsgReceiver::_narrow(object)); } ToolMsgReceiverFwdr_impl * comp = new ToolMsgReceiverFwdr_impl(this->_this(), nm.c_str()); LogORBMgr::getMgr()->activate(comp); cachesMutex.lock(); servants[nm] = comp; objectCache[name] = CORBA::Object::_duplicate(comp->_this()); cachesMutex.unlock(); return ToolMsgReceiver::_duplicate(comp->_this()); } /* Common methods implementations. */ void LogForwarder::ping( const char* compoName, const char* objName) { string objString(objName); string name; string ctxt; if (!remoteCall(objString)) { return getPeer()->ping(compoName, objString.c_str()); } name = getName(objString); ctxt = getCtxt(objString); if (ctxt==string(LOGCOMPCTXT)) { LogCentralComponent_var logCentral = LogORBMgr::getMgr()->resolve (LOGCOMPCTXT, name, this->name); return logCentral->ping(compoName); } if (ctxt==string(LOGTOOLCTXT)) { return; } throw LogBadNameException(objString.c_str(), __FUNCTION__, getName()); } void LogForwarder::bind(const char* objName, const char* ior) { /* To avoid crashes when the peer forwarder is not ready: */ /* If the peer was not initialized, the following call is blocking. */ peerMutex.lock(); peerMutex.unlock(); string objString(objName); string name; string ctxt; if (!remoteCall(objString)) { std::cout << "Forward bind to peer" << std::endl; return getPeer()->bind(objString.c_str(), ior); } ctxt = getCtxt(objString); name = getName(objString); std::cout << "Bind locally" << std::endl; LogORBMgr::getMgr()->bind(ctxt, name, ior, true); // Broadcast the binding to all forwarders. LogORBMgr::getMgr()->fwdsBind(ctxt, name, ior, this->name); cout << "Binded !" << endl; } /* Return the local bindings. Result is a set of couple * (object name, object ior) */ LogSeqString* LogForwarder::getBindings(const char* ctxt) { list objects; list::iterator it; LogSeqString* result = new LogSeqString(); unsigned int cmpt = 0; objects = LogORBMgr::getMgr()->list(ctxt); result->length(objects.size()*2); for (it=objects.begin(); it!=objects.end(); ++it) { try { CORBA::Object_ptr obj = LogORBMgr::getMgr()->resolveObject(ctxt, it->c_str(), "no-Forwarder"); (*result)[cmpt++]=it->c_str(); (*result)[cmpt++]=LogORBMgr::getMgr()->getIOR(obj).c_str(); } catch (const runtime_error& err) { continue; } } result->length(cmpt); return result; } void LogForwarder::unbind(const char* objName) { string objString(objName); string name; string ctxt; if (!remoteCall(objString)) { return getPeer()->unbind(objString.c_str()); } name = objString; if (name.find('/')==string::npos) return; ctxt = getCtxt(objString); name = getName(objString); removeObjectFromCache(name); LogORBMgr::getMgr()->unbind(ctxt, name); // Broadcast the unbinding to all forwarders. LogORBMgr::getMgr()->fwdsUnbind(ctxt, name, this->name); } void LogForwarder::removeObjectFromCache(const string& name) { map::iterator it; map::iterator jt; /* If the object is in the servant cache. */ cachesMutex.lock(); if ((jt=servants.find(name))!=servants.end()) { /* - Deactivate object. */ try { LogORBMgr::getMgr()->deactivate(jt->second); } catch (...) { /* There was a problem with the servant. But we want * to remove it... */ } /* - Remove activated servants. */ servants.erase(jt); } /* Remove the object from the cache. */ if ((it=objectCache.find(name))!=objectCache.end()) objectCache.erase(it); cachesMutex.unlock(); } /* Remove non existing objects from the caches. */ void LogForwarder::cleanCaches() { map::iterator it; list invalidObjects; list::const_iterator jt; cachesMutex.lock(); for (it=objectCache.begin(); it!=objectCache.end(); ++it) { try { CorbaLogForwarder_var object = CorbaLogForwarder::_narrow(it->second); object->getName(); } catch (const CORBA::TRANSIENT& err) { invalidObjects.push_back(it->first); } } cachesMutex.unlock(); for (jt=invalidObjects.begin(); jt!=invalidObjects.end(); ++jt) removeObjectFromCache(*jt); } void LogForwarder::connectPeer(const char* ior, const char* host, const ::CORBA::Long port) { string converted = LogORBMgr::convertIOR(ior, host, port); setPeer(LogORBMgr::getMgr()->resolve(converted)); } void LogForwarder::setPeer(CorbaLogForwarder_ptr peer) { this->peer = CorbaLogForwarder::_duplicate(CorbaLogForwarder::_narrow(peer)); // Peer was init. The lock was done on the constructor. peerMutex.unlock(); } CorbaLogForwarder_var LogForwarder::getPeer() { // Wait for setPeer peerMutex.lock(); peerMutex.unlock(); try { // Check if peer is still alive peer->getName(); } catch (const CORBA::COMM_FAILURE& err) { // Lock peerMutex, then wait for setPeer // (setPeer() unlock the mutex peerMutex.lock(); peerMutex.lock(); peerMutex.unlock(); } catch (const CORBA::TRANSIENT& err) { // Lock peerMutex, then wait for setPeer // (setPeer() unlock the mutex peerMutex.lock(); peerMutex.lock(); peerMutex.unlock(); } return peer; } char* LogForwarder::getIOR() { return CORBA::string_dup(LogORBMgr::getMgr()->getIOR(_this()).c_str()); } char* LogForwarder::getName() { return CORBA::string_dup(name.c_str()); } LogSeqString* LogForwarder::acceptList() { LogSeqString* result = new LogSeqString; list::const_iterator it; result->length(netCfg.getAcceptList().size()); unsigned int i=0; for (it=netCfg.getAcceptList().begin(); it!=netCfg.getAcceptList().end(); ++it, ++i) { (*result)[i] = it->c_str(); } return result; } LogSeqString* LogForwarder::rejectList() { LogSeqString* result = new LogSeqString; list::const_iterator it; result->length(netCfg.getRejectList().size()); unsigned int i=0; for (it=netCfg.getRejectList().begin(); it!=netCfg.getRejectList().end(); ++it, ++i) { (*result)[i] = it->c_str(); } return result; } ::CORBA::Boolean LogForwarder::manage(const char* hostname) { bool toto = netCfg.manage(hostname); cout << "Is this forwarder managing " << hostname << "?" << toto << endl; return toto; } LogSeqString* LogForwarder::routeTree() { LogSeqString* result = new LogSeqString(); /*std::list forwarders = LogORBMgr::list(FWRDCTXT); std::list::const_iterator it; result->length(1); (*result)[0]=CORBA::string_dup(name.c_str()) for (it=forwarders.begin(); it!=forwarders.end(); ++it) { if (*it==name) continue; Forwarder_var fwd = resolve(FWRDCTXT, *it, this->name); SeqString* tmp = fwd->routeTree(); unsigned int curLgth = result->length(); unsigned int tmpLgth = tmp->lgth(); result->length(lgth+tmpLgth); for (unsigned int i=lgth; isetTagFilter(tagList, objString.c_str()); } name = getName(objString); ComponentConfigurator_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->setTagFilter(tagList); } void LogForwarder::addTagFilter(const ::tag_list_t& tagList, const char* objName) { string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->addTagFilter(tagList, objString.c_str()); } name = getName(objString); ComponentConfigurator_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->addTagFilter(tagList); } void LogForwarder::removeTagFilter(const ::tag_list_t& tagList, const char* objName) { string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->removeTagFilter(tagList, objString.c_str()); } name = getName(objString); ComponentConfigurator_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->removeTagFilter(tagList); } void LogForwarder::test(const char* objName) { string objString(objName); string name; name = getName(objString); ComponentConfigurator_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->test(); } void LogForwarder::sendMsg(const log_msg_buf_t& msgBuf, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->sendMsg(msgBuf, objString.c_str()); } name = getName(objString); ToolMsgReceiver_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->sendMsg(msgBuf); } /** * Connect a Tool with its toolName, which must be unique among all * tools. The return value indicates the success of the connection. * If ALREADYEXISTS is returned, the tool could not be attached, as * the specified toolName already exists. In this case the tool must * reconnect with another name before specifying any filters. If the * tool sends an empty toolName, the LogCentral will provide a unique * toolName and pass it back to the tool. */ short LogForwarder::connectTool(char*& toolName, const char* msgReceiver, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { getPeer()->connectTool(toolName, msgReceiver, objString.c_str()); return 1; } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->connectTool(toolName, msgReceiver); } /** * Disconnects a connected tool from the monitor. No further * filterconfigurations should be sent after this call. The * toolMsgReceiver will not be used by the monitor any more * after this call. Returns NOTCONNECTED if the calling tool * was not connected. */ short LogForwarder::disconnectTool(const char* toolName, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->disconnectTool(toolName, objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->disconnectTool(toolName); } /** * Returns a list of possible tags. This is just a convenience * functions and returns the values that are specified in a * configuration file. If the file is not up to date, the * application may generate more tags than defined in this * list. */ tag_list_t* LogForwarder::getDefinedTags(const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->getDefinedTags(objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->getDefinedTags(); } /** * Returns a list of actually connected Components. This is just * a convenience function, as the whole state of the system will * be sent to the tool right after connection (in the form of * messages) */ component_list_t* LogForwarder::getDefinedComponents(const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->getDefinedComponents(objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->getDefinedComponents(); } /** * Create a filter for this tool on the monitor. Messages matching * this filter will be forwarded to the tool. The filter will be * identified by its name, which is a part of filter_t. A tool * can have as much filters as it wants. Returns ALREADYEXISTS if * another filter with this name is already registered. */ short LogForwarder::addFilter(const char* toolName, const filter_t& filter, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->addFilter(toolName, filter, objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->addFilter(toolName, filter); } /** * Removes a existing filter from the tools filterList. The filter * will be identified by its name in the filter_t. If the specified * filter does not exist, NOTEXISTS is returned. */ short LogForwarder::removeFilter(const char* toolName, const char* filterName, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->removeFilter(toolName, filterName, objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->removeFilter(toolName, filterName); } /** * Removes all defined filters. */ short LogForwarder::flushAllFilters(const char* toolName, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->flushAllFilters(toolName, objString.c_str()); } name = getName(objString); LogCentralTool_var cfg = LogORBMgr::getMgr()->resolve(LOGTOOLCTXT, name, this->name); return cfg->flushAllFilters(toolName); } short LogForwarder::connectComponent(char*& componentName, const char* componentHostname, const char* message, const char* compConfigurator, const log_time_t& componentTime, tag_list_t& initialConfig, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->connectComponent(componentName, componentHostname, message, compConfigurator, componentTime, initialConfig, objString.c_str()); } name = getName(objString); LogCentralComponent_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->connectComponent(componentName, componentHostname, message, compConfigurator, componentTime, initialConfig); } short LogForwarder::disconnectComponent(const char* componentName, const char* message, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->disconnectComponent(componentName, message, objString.c_str()); } name = getName(objString); LogCentralComponent_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->disconnectComponent(componentName, message); } void LogForwarder::sendBuffer(const log_msg_buf_t &buffer, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->sendBuffer(buffer, objString.c_str()); } name = getName(objString); LogCentralComponent_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->sendBuffer(buffer); } void LogForwarder::synchronize(const char* componentName, const log_time_t& componentTime, const char* objName){ string objString(objName); string name; if (!remoteCall(objString)) { return getPeer()->synchronize(componentName, componentTime, objString.c_str()); } name = getName(objString); LogCentralComponent_var cfg = LogORBMgr::getMgr()->resolve(LOGCOMPCTXT, name, this->name); return cfg->synchronize(componentName, componentTime); } LogService-2.7.0/src/LogForwarder.hh000644 000765 000765 00000024361 11576373446 020731 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/17 15:18:20 kcoulomb * update log * * Revision 1.3 2010/12/13 12:21:13 kcoulomb * Clean types * * Revision 1.2 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.8 2010/08/04 09:06:18 glemahec * Parallel compilation * * Revision 1.7 2010/07/27 16:16:48 glemahec * Forwarders robustness * * Revision 1.6 2010/07/27 13:25:01 glemahec * Forwarders robustness improvements * * Revision 1.5 2010/07/27 10:24:31 glemahec * Improve robustness & general performance * * Revision 1.4 2010/07/20 08:56:22 bisnard * Updated WfLogService IDL * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:03 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application ****************************************************************************/ #ifndef LOGFORWARDER_HH #define LOGFORWARDER_HH #include #include #include #include "NetConfig.hh" #include "CorbaLogForwarder.hh" #include "commonLogTypes.hh" class LogForwarder : public POA_CorbaLogForwarder, public PortableServer::RefCountServantBase { private: /* When a new forwarder object is created, we cache it. * Because this kind of object contains only the object * name and a reference to this forwarder, there is no * risk to cache it, even if the object is restarted or * disappear. */ std::map objectCache; /* We also maintain a list of activated servant objects. */ std::map servants; ::CORBA::Object_ptr getObjectCache(const std::string& name); /* The forwarder associated to this one. */ CorbaLogForwarder_var peer; /* Mutexes */ omni_mutex peerMutex; // To wait for the peer initialization omni_mutex cachesMutex; // Protect access to caches std::string peerName; std::string name; /* To determine if the call is from another forwarder and * modify the object name. */ static bool remoteCall(std::string& objName); /* Network configuration for this forwarder. */ NetConfig netCfg; public: ~LogForwarder(); LogForwarder(const std::string& name, const std::string& cfgPath); /* DIET object factory methods. */ ComponentConfigurator_ptr getCompoConf(const char* name); ToolMsgReceiver_ptr getToolMsgReceiver(const char* name); LogCentralComponent_ptr getLogCentralComponent(const char* name); LogCentralTool_ptr getLogCentralTool(const char* name); /* Common methods implementations. */ void ping(const char* compoName, const char* objName); /* CORBA remote management implementation. */ void bind(const char* objName, const char* ior); void unbind(const char* objName); LogSeqString* getBindings(const char* ctxt); /* Connect the peer forwarder. */ void connectPeer(const char* ior, const char* host, const ::CORBA::Long port); /* Set this forwarder peer object (not CORBA). */ void setPeer(CorbaLogForwarder_ptr peer); CorbaLogForwarder_var getPeer(); char* getIOR(); /* Object caches management functions. */ void removeObjectFromCache(const std::string& name); void cleanCaches(); char* getName(); LogSeqString* acceptList(); LogSeqString* rejectList(); ::CORBA::Boolean manage(const char* hostname); LogSeqString* routeTree(); /* LogComponentFwdr implementation. */ void setTagFilter(const ::tag_list_t& tagList, const char* objName); void addTagFilter(const ::tag_list_t& tagList, const char* objName); void removeTagFilter(const ::tag_list_t& tagList, const char* objName); void test(const char* objName); /** * Disconnects a connected tool from the monitor. No further * filterconfigurations should be sent after this call. The * toolMsgReceiver will not be used by the monitor any more * after this call. Returns NOTCONNECTED if the calling tool * was not connected. */ short disconnectTool(const char* toolName, const char* objName); /** * Returns a list of possible tags. This is just a convenience * functions and returns the values that are specified in a * configuration file. If the file is not up to date, the * application may generate more tags than defined in this * list. */ tag_list_t* getDefinedTags(const char* objName); /** * Returns a list of actually connected Components. This is just * a convenience function, as the whole state of the system will * be sent to the tool right after connection (in the form of * messages) */ component_list_t* getDefinedComponents(const char* objName); /** * Create a filter for this tool on the monitor. Messages matching * this filter will be forwarded to the tool. The filter will be * identified by its name, which is a part of filter_t. A tool * can have as much filters as it wants. Returns ALREADYEXISTS if * another filter with this name is already registered. */ short addFilter(const char* toolName, const filter_t& filter, const char* objName); void sendMsg(const log_msg_buf_t& msgBuf, const char* objName); /** * Connect a Tool with its toolName, which must be unique among all * tools. The return value indicates the success of the connection. * If ALREADYEXISTS is returned, the tool could not be attached, as * the specified toolName already exists. In this case the tool must * reconnect with another name before specifying any filters. If the * tool sends an empty toolName, the LogCentral will provide a unique * toolName and pass it back to the tool. */ short connectTool(char*& toolName, const char* msgReceiver, const char* objName); short flushAllFilters(const char* toolName, const char* objName); short removeFilter(const char* toolName, const char* filterName, const char* objName); /* Utility fonctions to extract name & context from context/name. */ static std::string getName(const std::string& namectxt); static std::string getCtxt(const std::string& namectxt); short connectComponent(char*&, const char*, const char*, const char*, const log_time_t&, tag_list_t&, const char*); short disconnectComponent(const char* componentName, const char* message, const char* objName); void sendBuffer(const log_msg_buf_t &buffer, const char* objName); void synchronize(const char* componentName, const log_time_t& componentTime, const char* objName); }; #endif LogService-2.7.0/src/logFwdr.cc000644 000765 000765 00000041334 11576373447 017726 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation - Forwarder executable */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2011/05/13 08:17:51 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.3 2011/05/11 16:27:25 bdepardo * Updated forwarder files: bug correction and optimization coming from DIET * * Revision 1.2 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 02:56:32 kcoulomb * Add missing file * * Revision 1.4 2010/07/27 16:16:48 glemahec * Forwarders robustness * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; logForwarder application ****************************************************************************/ #include "LogForwarder.hh" #include "LogORBMgr.hh" #include "SSHTunnel.hh" #include "Options.hh" #include "logFwdr.hh" #include #include #include #include #include #include #include #include #include // For sleep function using namespace std; int main(int argc, char* argv[], char* envp[]) { /* Forwarder configuration. */ FwrdConfig cfg(argv[0]); Options opt(&cfg, argc, argv, envp); /* Mandatory parameter. */ opt.setOptCallback("--name", name); /* Mandatory when creating tunnels. */ opt.setOptCallback("--peer-name", peer_name); opt.setOptCallback("--ssh-host", ssh_host); /* Optionnal, set to "localhost" by default. */ opt.setOptCallback("--remote-host", remote_host); /* Optionnal, we try to determine it automatically. */ opt.setOptCallback("--remote-port", remote_port_from); /* Optionnal - default values are set to port 22, * current user login and $HOME/.ssh/id_[rsa|dsa]. */ opt.setOptCallback("--ssh-port", ssh_port); opt.setOptCallback("--ssh-login", ssh_login); opt.setOptCallback("--ssh-key", key_path); /* Optionnal parameters/flags. */ opt.setOptCallback("--retry", nb_retry); opt.setOptCallback("--peer-ior", peer_ior); opt.setFlagCallback('C', create); //opt.setFlagCallback('f', create_from); opt.setOptCallback("--net-config", net_config); opt.processOptions(); if (cfg.getName()=="") { std::ostringstream name; char host[256]; gethostname(host, 256); host[255]='\0'; std::transform(host, host+strlen(host), host, change); name << "Forwarder-" << host << "-" << getpid(); cerr << "Missing parameter: name (use --name to fix it)" << endl; cerr << "Use default name: " << name.str() << endl; cfg.setName(name.str()); } if (cfg.getCfgPath()=="") { cerr << "Missing parameter: net-config (use --net-config to fix it)" << endl; return EXIT_FAILURE; } if (cfg.createFrom()) { if (cfg.getPeerName()=="" || cfg.getSshHost()=="") { cerr << "Missing parameter(s) to create tunnel."; cerr << " Mandatory parameters:" << endl; cerr << '\t' << "- Peer name (--peer-name )" << endl; cerr << '\t' << "- SSH host (--ssh-host )" << endl; return EXIT_FAILURE; } } SSHTunnel tunnel; LogForwarder* forwarder; try { forwarder = new LogForwarder(cfg.getName(), cfg.getCfgPath()); } catch (exception &e) { cerr << "Error: " << e.what() << endl; return EXIT_FAILURE; } LogORBMgr::init(argc, argv); LogORBMgr* mgr = LogORBMgr::getMgr(); string ior; int count = 0; mgr->activate(forwarder); do { try { mgr->bind(LOGFWRDCTXT, cfg.getName(), forwarder->_this(), true); break; } catch (CORBA::TRANSIENT& err) { cerr << "Error when binding the forwarder " << cfg.getName() << endl; if (count++deactivate(forwarder); return EXIT_FAILURE; } } while (true); /* Write the IOR to a file on /tmp. */ ior = mgr->getIOR(forwarder->_this()); string iorFilename("/tmp/LOG-forwarder-ior-"); iorFilename+=cfg.getName()+".tmp"; ofstream of(iorFilename.c_str(), ios_base::trunc); if (!of.is_open()) { cerr << "Warning: cannot open file " << iorFilename << " to store the IOR" << endl; } else { cout << "Write IOR to " << iorFilename << endl; if (cfg.createFrom()) { // Creating tunnel(s) istringstream is(cfg.getRemotePortFrom()); int port; is >> port; of << LogORBMgr::convertIOR(ior, cfg.getRemoteHost(), port); } else {// Waiting for connexion. of << ior; } of << std::endl; of << freeTCPport(); // also write a free port of.close(); } cout << "Forwarder: " << ior << endl; tunnel.setSshHost(cfg.getSshHost()); tunnel.setRemoteHost(cfg.getRemoteHost()); tunnel.setSshPath(cfg.getSshPath()); tunnel.setSshPort(cfg.getSshPort()); tunnel.setSshLogin(cfg.getSshLogin()); tunnel.setSshKeyPath(cfg.getSshKeyPath()); /* Manage the peer IOR. */ if (cfg.getPeerIOR()=="" && cfg.createFrom()) { /* Try to retrieve the peer IOR. */ SSHCopy copy(cfg.getSshHost(), "/tmp/LOG-forwarder-ior-"+cfg.getPeerName()+".tmp", "/tmp/LOG-forwarder-ior-"+cfg.getPeerName()+".tmp"); copy.setSshPath("/usr/bin/scp"); copy.setSshPort(cfg.getSshPort()); copy.setSshLogin(cfg.getSshLogin()); copy.setSshKeyPath(cfg.getSshKeyPath()); try { if (copy.getFile()) { std::cout << "Got remote IOR file" << std::endl; cfg.setPeerIOR("/tmp/LOG-forwarder-ior-"+cfg.getPeerName()+".tmp"); } } catch (...) { std::cout << "Got an exception while retrieving IOR file" << std::endl; } } if (cfg.getPeerIOR()!="" && cfg.getPeerIOR().find("IOR:")!=0) { /* Extract the IOR from a file. */ ifstream file(cfg.getPeerIOR().c_str()); string peerIOR; string peerPort; if (!file.is_open()) { cerr << "Error: Invalid peer-ior parameter" << endl; return EXIT_FAILURE; } file >> peerIOR; cfg.setPeerIOR(peerIOR); if (!file.eof() && cfg.getRemotePortFrom() == "") { file >> peerPort; cfg.setRemotePortFrom(peerPort); } } if (cfg.getPeerIOR() != "") { tunnel.setRemotePortTo(LogORBMgr::getPort(cfg.getPeerIOR())); } else { tunnel.setRemotePortTo(cfg.getRemotePortTo()); } if (cfg.getRemoteHost() == "") { if (cfg.getPeerIOR() != "") { tunnel.setRemoteHost(LogORBMgr::getHost(cfg.getPeerIOR())); } else { tunnel.setRemoteHost("127.0.0.1"); } } else { tunnel.setRemoteHost(cfg.getRemoteHost()); } tunnel.setRemotePortFrom(cfg.getRemotePortFrom()); // tunnel.setLocalPortFrom(cfg.getLocalPortFrom()); if (cfg.createFrom()) { if (cfg.getRemotePortFrom() == "") { cerr << "Failed to automatically determine a remote free port." << endl; cerr << " You need to specify the remote port:" << endl; cerr << '\t' << "- Remote port (--remote-port )" << endl; return EXIT_FAILURE; } } tunnel.setLocalPortTo(LogORBMgr::getPort(ior)); tunnel.createTunnelTo(cfg.createTo()); tunnel.createTunnelFrom(cfg.createFrom()); tunnel.open(); /* Try to find the peer. */ bool canLaunch = true; if (cfg.getPeerIOR()!="") { try { if (connectPeer(ior, cfg.getPeerIOR(), "localhost", tunnel.getRemoteHost(), tunnel.getLocalPortFrom(), tunnel.getRemotePortFrom(), forwarder, mgr)) { /* In this case it seems that there is a problem with the alias 'localhost', thus we * try to use 127.0.0.1 */ if (tunnel.getRemoteHost() == "localhost") { tunnel.setRemoteHost("127.0.0.1"); } if (connectPeer(ior, cfg.getPeerIOR(), "127.0.0.1", tunnel.getRemoteHost(), tunnel.getLocalPortFrom(), tunnel.getRemotePortFrom(), forwarder, mgr)) { cout << "Unable to contact remote peer. Waiting for connection..." << endl; } } } catch (...) { cerr << "Error while connecting to remote peer" << endl; canLaunch = false; } } if (canLaunch) { mgr->wait(); } std::cout << "Forwarder is now terminated" << std::endl; return EXIT_SUCCESS; } int connectPeer(const std::string &ior, const std::string &peerIOR, const std::string &newHost, const std::string &remoteHost, int localPortFrom, int remotePortFrom, LogForwarder *forwarder, LogORBMgr* mgr) { std::string newPeerIOR = LogORBMgr::convertIOR(peerIOR, newHost, localPortFrom); CorbaLogForwarder_var peer; peer = mgr->resolve(newPeerIOR); try { peer->connectPeer(ior.c_str(), remoteHost.c_str(), remotePortFrom); forwarder->setPeer(peer); } catch (CORBA::TRANSIENT& err) { cout << "Unable to contact remote peer using '" << newHost <<"' as a \"new remote host\"" << endl; return 1; } cout << "Contacted remote peer using '" << newHost << "' as new remote host" << endl; return 0; } void name(const string& name, Configuration* cfg) { static_cast(cfg)->setName(name); } void peer_name(const string& name, Configuration* cfg) { static_cast(cfg)->setPeerName(name); } void peer_ior(const string& ior, Configuration* cfg) { static_cast(cfg)->setPeerIOR(ior); } void net_config(const string& path, Configuration* cfg) { static_cast(cfg)->setCfgPath(path); } void ssh_host(const string& host, Configuration* cfg) { static_cast(cfg)->setSshHost(host); } void remote_host(const string& host, Configuration* cfg) { static_cast(cfg)->setRemoteHost(host); } void remote_port_to(const string& port, Configuration* cfg) { static_cast(cfg)->setRemotePortTo(port); } void remote_port_from(const string& port, Configuration* cfg) { static_cast(cfg)->setRemotePortFrom(port); } void local_port_from(const string& port, Configuration* cfg) { static_cast(cfg)->setLocalPortFrom(port); } void ssh_path(const string& path, Configuration* cfg) { static_cast(cfg)->setSshPath(path); } void ssh_port(const string& port, Configuration* cfg) { static_cast(cfg)->setSshPort(port); } void ssh_login(const string& login, Configuration* cfg) { static_cast(cfg)->setSshLogin(login); } void key_path(const string& path, Configuration* cfg) { static_cast(cfg)->setSshKeyPath(path); } void create(const string& create, Configuration* cfg) { (void) create; static_cast(cfg)->createTo(true); static_cast(cfg)->createFrom(true); } void nb_retry(const string& nb, Configuration* cfg) { istringstream is(nb); int n; is >> n; static_cast(cfg)->setNbRetry(n); } /* Fwdr configuration implementation. */ FwrdConfig::FwrdConfig(const string& pgName) : Configuration(pgName) { createTunnelTo = false; createTunnelFrom = false; nbRetry = 3; } const string& FwrdConfig::getName() const { return name; } const string& FwrdConfig::getPeerName() const { return peerName; } const string& FwrdConfig::getPeerIOR() const { return peerIOR; } const string& FwrdConfig::getSshHost() const { return sshHost; } const string& FwrdConfig::getRemoteHost() const { return remoteHost; } const string& FwrdConfig::getRemotePortTo() const { return remotePortTo; } const string& FwrdConfig::getRemotePortFrom() const { return remotePortFrom; } const string& FwrdConfig::getLocalPortFrom() const { return localPortFrom; } bool FwrdConfig::createTo() const { return createTunnelTo; } bool FwrdConfig::createFrom() const { return createTunnelFrom; } const string& FwrdConfig::getSshPath() const { return sshPath; } const string& FwrdConfig::getSshPort() const { return sshPort; } const string& FwrdConfig::getSshLogin() const { return sshLogin; } const string& FwrdConfig::getSshKeyPath() const { return sshKeyPath; } int FwrdConfig::getNbRetry() const { return nbRetry; } const string& FwrdConfig::getCfgPath() const { return cfgPath; } void FwrdConfig::setName(const string& name) { this->name = name; } void FwrdConfig::setPeerName(const string& name) { this->peerName = name; } void FwrdConfig::setPeerIOR(const string& ior) { this->peerIOR = ior; } void FwrdConfig::setSshHost(const string& host) { this->sshHost = host; } void FwrdConfig::setRemoteHost(const string& host) { this->remoteHost = host; } void FwrdConfig::setRemotePortTo(const string& port) { this->remotePortTo = port; } void FwrdConfig::setRemotePortFrom(const string& port) { this->remotePortFrom = port; } void FwrdConfig::setLocalPortFrom(const string& port) { this->localPortFrom = port; } void FwrdConfig::createTo(bool create) { this->createTunnelTo = create; } void FwrdConfig::createFrom(bool create) { this->createTunnelFrom = create; } void FwrdConfig::setSshPath(const string& path) { this->sshPath = path; } void FwrdConfig::setSshPort(const string& port) { this->sshPort = port; } void FwrdConfig::setSshLogin(const string& login) { this->sshLogin = login; } void FwrdConfig::setSshKeyPath(const string& path) { this->sshKeyPath = path; } void FwrdConfig::setNbRetry(const int nb) { this->nbRetry = nb; } void FwrdConfig::setCfgPath(const string& path) { this->cfgPath = path; } int change(int c) { if (c=='.') return '-'; return c; } LogService-2.7.0/src/logFwdr.hh000644 000765 000765 00000016333 11576373447 017741 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation - Forwarder executable */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2011/05/11 16:27:25 bdepardo * Updated forwarder files: bug correction and optimization coming from DIET * * Revision 1.1 2010/11/10 02:58:03 kcoulomb * *** empty log message *** * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; logForwarder application ****************************************************************************/ #ifndef _LOGFWDR_HH_ #define _LOGFWDR_HH_ #include #include "Options.hh" class FwrdConfig : public Configuration { private: std::string name; std::string peerName; std::string peerHost; std::string peerPort; std::string peerIOR; std::string sshHost; std::string remoteHost; std::string localPortFrom; std::string remotePortTo; std::string remotePortFrom; bool createTunnelTo; bool createTunnelFrom; std::string sshPath; std::string sshPort; std::string sshLogin; std::string sshKeyPath; int nbRetry; std::string cfgPath; public: FwrdConfig(const std::string& pgName); const std::string& getName() const; const std::string& getPeerName() const; const std::string& getPeerIOR() const; const std::string& getSshHost() const; const std::string& getRemoteHost() const; const std::string& getRemotePortTo() const; const std::string& getRemotePortFrom() const; const std::string& getLocalPortFrom() const; bool createTo() const; bool createFrom() const; const std::string& getSshPath() const; const std::string& getSshPort() const; const std::string& getSshLogin() const; const std::string& getSshKeyPath() const; int getNbRetry() const; const std::string& getCfgPath() const; void setName(const std::string& name); void setPeerName(const std::string& name); void setPeerIOR(const std::string& ior); void setSshHost(const std::string& host); void setRemoteHost(const std::string& host); void setRemotePortTo(const std::string& port); void setRemotePortFrom(const std::string& port); void setLocalPortFrom(const std::string& port); void createTo(bool create); void createFrom(bool create); void setSshPath(const std::string& path); void setSshPort(const std::string& port); void setSshLogin(const std::string& login); void setSshKeyPath(const std::string& path); void setNbRetry(const int nb); void setCfgPath(const std::string& path); }; int connectPeer(const std::string &ior, const std::string &peerIOR, const std::string &newHost, const std::string &remoteHost, int localPortFrom, int remotePortFrom, LogForwarder *forwarder, LogORBMgr* mgr); void name(const std::string& name, Configuration* cfg); void peer_name(const std::string& name, Configuration* cfg); void peer_ior(const std::string& ior, Configuration* cfg); void net_config(const std::string& path, Configuration* cfg); void ssh_host(const std::string& host, Configuration* cfg); void remote_host(const std::string& host, Configuration* cfg); void remote_port_to(const std::string& port, Configuration* cfg); void remote_port_from(const std::string& port, Configuration* cfg); void local_port_from(const std::string& port, Configuration* cfg); void create(const std::string& create, Configuration* cfg); void ssh_path(const std::string& path, Configuration* cfg); void ssh_port(const std::string& port, Configuration* cfg); void ssh_login(const std::string& login, Configuration* cfg); void key_path(const std::string& path, Configuration* cfg); void nb_retry(const std::string& nb, Configuration* cfg); /* Transformation function for the host name. */ int change(int c); #endif // _LOGFWDR_HH_ LogService-2.7.0/src/LogORBMgr.cc000644 000765 000765 00000057506 11576373446 020063 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ORB manager v. 2.0 - CORBA management with Log forwarders */ /* */ /* Author(s): */ /* - Gaël Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.9 2011/05/13 12:39:36 bdepardo * Fixed a bug with multiple initialization * * Revision 1.8 2011/05/13 08:17:51 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.7 2011/05/13 06:42:44 bdepardo * Const methods whenever possible * * Revision 1.6 2011/04/28 07:45:30 bdepardo * Change POA name so that DIET and LogService do not use the same one. * * Revision 1.5 2011/04/22 14:08:57 kcoulomb * Fix bug if POA name already exist, use it instead of throwing an exception * * Revision 1.4 2011/04/22 11:44:21 bdepardo * Use a signal handler to handle background option. * This handler catches SIGINT and SIGTERM. * * Revision 1.3 2011/02/04 15:35:00 bdepardo * Code indentation. * Removed unused variables. * * Revision 1.2 2010/12/17 15:18:20 kcoulomb * update log * * Revision 1.1 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.29 2010/07/27 16:16:48 glemahec * Forwarders robustness * * Revision 1.28 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.27 2010/07/14 23:45:30 bdepardo * Header corrections * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "LogORBMgr.hh" #include "CorbaLogForwarder.hh" using namespace std; LogORBMgr* LogORBMgr::theMgr = NULL; #ifndef __cygwin__ omni_mutex LogORBMgr::waitLock; #else sem_t LogORBMgr::waitLock; #endif /* Manager initialization. */ void LogORBMgr::init(CORBA::ORB_ptr ORB) { CORBA::Object_var object; PortableServer::POA_var initPOA; PortableServer::POAManager_var manager; CORBA::PolicyList policies; CORBA::Any policy; CosNaming::NamingContext_var rootContext, context; CosNaming::Name cosName; if (CORBA::is_nil(ORB)) { throw runtime_error("ORB not initialized"); } object = ORB->resolve_initial_references("RootPOA"); initPOA = PortableServer::POA::_narrow(object); manager = initPOA->the_POAManager(); policies.length(1); policy <<= BiDirPolicy::BOTH; policies[0] = ORB->create_policy(BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE, policy); // If poa already exist, use the same try { POA = initPOA->create_POA("bidirLogService", manager, policies); } catch (PortableServer::POA::AdapterAlreadyExists &e) { POA = initPOA->find_POA("bidirLogService", false); } manager->activate(); } LogORBMgr::LogORBMgr(int argc, char* argv[]) { const char* opts[][2]= {{0,0}}; ORB = CORBA::ORB_init(argc, argv, "omniORB4", opts); init(ORB); down = false; } LogORBMgr::LogORBMgr(CORBA::ORB_ptr ORB) { this->ORB = ORB; init(ORB); down = false; } LogORBMgr::LogORBMgr(CORBA::ORB_ptr ORB, PortableServer::POA_var POA) { this->ORB=ORB; this->POA=POA; down = false; } LogORBMgr::~LogORBMgr() { shutdown(true); ORB->destroy(); theMgr = NULL; } void LogORBMgr::bind(const string& ctxt, const string& name, CORBA::Object_ptr object, const bool rebind) const { CORBA::Object_var obj; CosNaming::NamingContext_var rootContext, context; CosNaming::Name cosName; obj = ORB->resolve_initial_references("NameService"); if (CORBA::is_nil(obj)) { throw runtime_error("Error resolving initial references"); } rootContext = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(rootContext)) { throw runtime_error("Error initializing root context"); } cosName.length(1); cosName[0].id = ctxt.c_str(); cosName[0].kind = ""; try { context = rootContext->bind_new_context(cosName); } catch (CosNaming::NamingContext::AlreadyBound& err) { obj = rootContext->resolve(cosName); context = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(context)) { throw runtime_error(string("Error creating context ")+ctxt); } } cosName[0].id = name.c_str(); cosName[0].kind = ""; try { context->bind(cosName, object); } catch (CosNaming::NamingContext::AlreadyBound& err) { if (rebind) { context->rebind(cosName, object); } else{ throw runtime_error("Already bound!"); } } } void LogORBMgr::bind(const string& ctxt, const string& name, const string& IOR, const bool rebind) const { CORBA::Object_ptr object = ORB->string_to_object(IOR.c_str()); bind(ctxt, name, object, rebind); } void LogORBMgr::rebind(const string& ctxt, const string& name, CORBA::Object_ptr object) const { bind(ctxt, name, object, true); } void LogORBMgr::rebind(const string& ctxt, const string& name, const string& IOR) const { CORBA::Object_ptr object = ORB->string_to_object(IOR.c_str()); rebind(ctxt, name, object); } void LogORBMgr::unbind(const string& ctxt, const string& name) const { CORBA::Object_var obj; CosNaming::NamingContext_var rootContext, context; CosNaming::Name cosName; std::list >::iterator it; obj = ORB->resolve_initial_references("NameService"); rootContext = CosNaming::NamingContext::_narrow(obj); cosName.length(1); cosName[0].id = ctxt.c_str(); cosName[0].kind = ""; obj = rootContext->resolve(cosName); context = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(context)) throw runtime_error(string("Error retrieving context ")+ctxt); cosName[0].id = name.c_str(); cosName[0].kind = ""; try { removeObjectFromCache(ctxt, name); context->unbind(cosName); } catch (CosNaming::NamingContext::NotFound& err) { throw runtime_error("Object "+name+" not found in " + ctxt +" context"); } } void LogORBMgr::fwdsBind(const string& ctxt, const string& name, const string& ior, const string& fwName) const { std::list forwarders = LogORBMgr::list(LOGFWRDCTXT); std::list::const_iterator it; for (it=forwarders.begin(); it!=forwarders.end(); ++it) { if (fwName==*it) continue; CorbaLogForwarder_var fwd = resolve(LOGFWRDCTXT, *it); string objName = ctxt+"/"+name; try { fwd->bind(objName.c_str(), ior.c_str()); } catch (const CORBA::TRANSIENT& err) { continue; } catch (LogBadNameException& err) { } } } void LogORBMgr::fwdsUnbind(const string& ctxt, const string& name, const string& fwName) const { std::list forwarders = LogORBMgr::list(LOGFWRDCTXT); std::list::const_iterator it; for (it=forwarders.begin(); it!=forwarders.end(); ++it) { if (fwName==*it) continue; CorbaLogForwarder_var fwd = resolve(LOGFWRDCTXT, *it); string objName = ctxt+"/"+name; try { fwd->unbind(objName.c_str()); } catch (const CORBA::TRANSIENT& err) { cerr << "Unable to contact LOG forwarder " << *it << endl; continue; } } } CORBA::Object_ptr LogORBMgr::resolveObject(const string& IOR) const { return ORB->string_to_object(IOR.c_str()); } CORBA::Object_ptr LogORBMgr::resolveObject(const string& context, const string& name, const string& fwdName) const { string ctxt = context; string ctxt2 = context; if (ctxt2 == LOGCOMPCONFCTXT) { ctxt = LOGCOMPCTXT; } else if (ctxt2==LOGTOOLMSGCTXT) { ctxt = LOGTOOLCTXT; } cacheMutex.lock(); /* Use object cache. */ if (cache.find(ctxt+"/"+name)!=cache.end()) { CORBA::Object_ptr ptr = cache[ctxt+"/"+name]; cacheMutex.unlock(); try { cout << "Check if the object is still present" << endl; if (ptr->_non_existent()) { cout << "Remove non existing object from cache (" << ctxt << "/" << name << ")" << endl; removeObjectFromCache(name); } else { cout << "Use object from cache (" << ctxt << "/" << name << ")" << endl; return CORBA::Object::_duplicate(ptr); } } catch (const CORBA::OBJECT_NOT_EXIST& err) { cout << "Remove non existing object from cache (" << ctxt << "/" << name << ")" << endl; removeObjectFromCache(name); } catch (const CORBA::TRANSIENT& err) { cout << "Remove unreachable object from cache (" << ctxt << "/" << name << ")" << endl; removeObjectFromCache(name); } catch (const CORBA::COMM_FAILURE& err) { cout << "Remove unreachable object from cache (" << ctxt << "/" << name << ")" << endl; removeObjectFromCache(name); } catch (...) { cout << "Remove unreachable object from cache (" << ctxt << "/" << name << ")" << endl; removeObjectFromCache(name); } } cacheMutex.unlock(); CORBA::Object_ptr object = ORB->resolve_initial_references("NameService"); CosNaming::NamingContext_var rootContext = CosNaming::NamingContext::_narrow(object); CosNaming::Name cosName; cosName.length(2); cosName[0].id = ctxt.c_str(); cosName[0].kind = ""; cosName[1].id = name.c_str(); cosName[1].kind = ""; try { object = rootContext->resolve(cosName); /* If the object is not a forwarder object, then * search if we need to use a forwarder to reach it. */ if (ctxt!=LOGFWRDCTXT && fwdName!="no-Forwarder") { // MODIF string objIOR = getIOR(object); IOP::IOR ior; makeIOR(objIOR, ior); std::list forwarders = LogORBMgr::list(LOGFWRDCTXT); std::list::const_iterator it; for (it=forwarders.begin(); it!=forwarders.end(); ++it) { // This is the same forwarder... if (*it==fwdName) continue; CorbaLogForwarder_var fwd = LogORBMgr::getMgr()->resolve(LOGFWRDCTXT, *it); string objName = ctxt+"/"+name; string ior = getIOR(object); string objHost = getHost(ior); try { if (fwd->manage(objHost.c_str())) { cout << "Object " << ctxt << "/" << name << "." << "is reachable through forwarder " << *it << endl; if (ctxt2==LOGCOMPCTXT) { object = fwd->getLogCentralComponent(name.c_str()); string objIOR = getIOR(object); break; } if (ctxt2==LOGTOOLCTXT) { object = fwd->getLogCentralTool(name.c_str()); break; } if (ctxt2==LOGTOOLMSGCTXT) { object = fwd->getToolMsgReceiver(name.c_str()); break; } if (ctxt2==LOGCOMPCONFCTXT) { object = fwd->getCompoConf(name.c_str()); break; } } else { cout << "Direct access to object " << ctxt << "/" << name << endl; } } catch (const CORBA::TRANSIENT& err) { cerr << "Unable to contact LOG forwarder \"" << *it << "\"" << endl; continue; } } } } catch (CosNaming::NamingContext::NotFound& err) { cerr << "Error resolving " << ctxt << "/" << name << endl; throw runtime_error("Error resolving "+ctxt+"/"+name); } cacheMutex.lock(); cache[ctxt+"/"+name] = CORBA::Object::_duplicate(object); cacheMutex.unlock(); return CORBA::Object::_duplicate(object); } std::list LogORBMgr::list(CosNaming::NamingContext_var& ctxt) const { std::list result; CosNaming::BindingList_var ctxtList; CosNaming::BindingIterator_var it; CosNaming::Binding_var bv; ctxt->list(256, ctxtList, it); for (unsigned int i=0; ilength(); ++i) if (ctxtList[i].binding_type==CosNaming::nobject) for (unsigned int j=0; jnext_one(bv)) { if (bv->binding_type==CosNaming::nobject) for (unsigned int j=0; jbinding_name.length(); ++j) { result.push_back(string(bv->binding_name[j].id)); } } return result; } std::list LogORBMgr::list(const std::string& ctxtName) const { std::list result; CORBA::Object_ptr object = ORB->resolve_initial_references("NameService"); CosNaming::NamingContext_var rootContext = CosNaming::NamingContext::_narrow(object); CosNaming::BindingList_var bindingList; CosNaming::BindingIterator_var it; rootContext->list(256, bindingList, it); for (unsigned int i=0; ilength(); ++i) { if (bindingList[i].binding_type==CosNaming::ncontext) if (string(bindingList[i].binding_name[0].id)==ctxtName) { std::list tmpRes; CORBA::Object_ptr ctxtObj = rootContext->resolve(bindingList[i].binding_name); CosNaming::NamingContext_var ctxt = CosNaming::NamingContext::_narrow(ctxtObj); tmpRes = list(ctxt); result.insert(result.end(), tmpRes.begin(), tmpRes.end()); } } if (CORBA::is_nil(it)) return result; CosNaming::Binding_var bv; while (it->next_one(bv)) if (bv->binding_type==CosNaming::ncontext) if (string(bv->binding_name[0].id)==ctxtName) { std::list tmpRes; CORBA::Object_ptr ctxtObj = rootContext->resolve(bv->binding_name); CosNaming::NamingContext_var ctxt = CosNaming::NamingContext::_narrow(ctxtObj); tmpRes = list(ctxt); result.insert(result.end(), tmpRes.begin(), tmpRes.end()); } return result; } string LogORBMgr::getIOR(CORBA::Object_ptr object) const { return ORB->object_to_string(object); } string LogORBMgr::getIOR(const string& ctxt, const string& name) const { return ORB->object_to_string(resolveObject(ctxt, name)); } void LogORBMgr::activate(PortableServer::ServantBase* object) const { POA->activate_object(object); object->_remove_ref(); } void LogORBMgr::deactivate(PortableServer::ServantBase* object) const { PortableServer::ObjectId* id = POA->servant_to_id(object); POA->deactivate_object(*id); } void LogORBMgr::shutdown(bool waitForCompletion) { if (!down) { ORB->shutdown(waitForCompletion); down = true; } } void LogORBMgr::sigIntHandler(int sig) { /* Prevent from raising a new SIGINT handler */ signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); #ifndef __cygwin__ LogORBMgr::getMgr()->waitLock.unlock(); #else sem_post(&(LogORBMgr::getMgr()->waitLock)); #endif signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); } void LogORBMgr::wait() const { /* FIXME: this is pretty ugly, * but currently I do not see how to do so properly */ signal(SIGINT, LogORBMgr::sigIntHandler); signal(SIGTERM, LogORBMgr::sigIntHandler); try { cout << "Press CTRL+C to exit" << std::endl; #ifdef __cygwin__ sem_init(&waitLock,0,1); sem_wait(&waitLock); sem_wait(&waitLock); sem_post(&waitLock); #else waitLock.lock(); waitLock.lock(); waitLock.unlock(); #endif } catch (...) { } } LogORBMgr* LogORBMgr::getMgr() { if (theMgr==NULL) { throw runtime_error("ORB manager not initialized!"); } else { return theMgr; } } void LogORBMgr::init(int argc, char* argv[]) { if (!theMgr) { //delete theMgr; theMgr = new LogORBMgr(argc, argv); } } /* Translate the string passed as first argument in bytes and * record them into the buffer. */ void LogORBMgr::hexStringToBuffer(const char* ptr, const size_t size, cdrMemoryStream& buffer) { stringstream ss; int value; CORBA::Octet c; for (unsigned int i=0; i> hex >> value; c = value; buffer.marshalOctet(c); ss.flush(); ss.clear(); } } /* Make an IOP::IOR object using a stringified IOR. */ void LogORBMgr::makeIOR(const string& strIOR, IOP::IOR& ior) { /* An IOR must start with "IOR:" or "ior:" */ if (strIOR.find("IOR:")!=0 && strIOR.find("ior:")!=0) throw runtime_error("Bad IOR: "+strIOR); const char* tab = strIOR.c_str(); size_t size = (strIOR.length()-4); cdrMemoryStream buffer(size, false); CORBA::Boolean byteOrder; /* Convert the hex bytes string into buffer. */ hexStringToBuffer(tab+4, size, buffer); buffer.rewindInputPtr(); /* Get the endianness and init the buffer flag. */ byteOrder = buffer.unmarshalBoolean(); buffer.setByteSwapFlag(byteOrder); /* Get the object type id. */ ior.type_id = IOP::IOR::unmarshaltype_id(buffer); /* Get the IOR profiles. */ ior.profiles <<= buffer; } /* Convert IOP::IOR to a stringified IOR. */ void LogORBMgr::makeString(const IOP::IOR& ior, string& strIOR) { strIOR = "IOR:"; cdrMemoryStream buffer(0, true); stringstream ss; unsigned char* ptr; buffer.marshalBoolean(omni::myByteOrder); buffer.marshalRawString(ior.type_id); ior.profiles >>= buffer; buffer.rewindInputPtr(); ptr = static_cast(buffer.bufPtr()); for (unsigned long i=0; i < buffer.bufSize(); ++ptr, ++i) { string str; unsigned char c = *ptr; if (c<16) ss << '0'; ss << (unsigned short) c; ss >> hex >> str; ss.flush(); ss.clear(); strIOR+=str; } } /* Get the hostname of the first profile in this IOR. */ string LogORBMgr::getHost(IOP::IOR& ior) { IIOP::ProfileBody body; if (ior.profiles.length()==0) return "nohost"; IIOP::unmarshalProfile(ior.profiles[0], body); return string(body.address.host); } /* Get the hostname of the first profile in IOR passed * as a string. */ string LogORBMgr::getHost(const string& strIOR) { IOP::IOR ior; makeIOR(strIOR, ior); return getHost(ior); } /* Get the port of the first profile in this IOR. */ unsigned int LogORBMgr::getPort(IOP::IOR& ior) { IIOP::ProfileBody body; if (ior.profiles.length()==0) return 0; IIOP::unmarshalProfile(ior.profiles[0], body); return body.address.port; } /* Get the port of the first profile in IOR passed * as a string. */ unsigned int LogORBMgr::getPort(const string& strIOR) { IOP::IOR ior; makeIOR(strIOR, ior); return getPort(ior); } /* Get the type id of the IOR. */ string LogORBMgr::getTypeID(IOP::IOR& ior) { return string(ior.type_id); } /* Get the type id of the IOR passed as a string. */ std::string LogORBMgr::getTypeID(const string& strIOR) { IOP::IOR ior; makeIOR(strIOR, ior); return getTypeID(ior); } std::string LogORBMgr::convertIOR(IOP::IOR& ior, const std::string& host, const unsigned int port) { IIOP::ProfileBody body; IOP::TaggedProfile profile; CORBA::ULong max_data; CORBA::ULong nb_data; CORBA::Octet* buffer; std::string result; if (ior.profiles.length()==0) throw runtime_error("Invalid IOR"); for (unsigned int i=0; i::iterator it; cacheMutex.lock(); if ((it=cache.find(name))!=cache.end()) cache.erase(it); cacheMutex.unlock(); } void LogORBMgr::removeObjectFromCache(const string& ctxt, const string& name) const { removeObjectFromCache(ctxt+"/"+name); } void LogORBMgr::cleanCache() const { map::iterator it; std::list toRemove; std::list::const_iterator jt; cacheMutex.lock(); for (it = cache.begin(); it != cache.end(); ++it) { try { if (it->second->_non_existent()) { toRemove.push_back(it->first); } } catch (const CORBA::OBJECT_NOT_EXIST& err) { toRemove.push_back(it->first); } catch (...) { toRemove.push_back(it->first); } } cacheMutex.unlock(); for (jt = toRemove.begin(); jt != toRemove.end(); ++jt) { removeObjectFromCache(*jt); } } LogService-2.7.0/src/LogORBMgr.hh000644 000765 000765 00000022703 11576373446 020064 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ORB manager v. 2.0 - CORBA management with DIET forwarders */ /* */ /* Author(s): */ /* - Gaël Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2011/05/13 08:17:51 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.3 2011/05/13 06:42:44 bdepardo * Const methods whenever possible * * Revision 1.2 2011/04/22 11:44:21 bdepardo * Use a signal handler to handle background option. * This handler catches SIGINT and SIGTERM. * * Revision 1.1 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.2 2010/11/10 04:06:07 bdepardo * New compilation organization * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.23 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.22 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.21 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application * ****************************************************************************/ #ifndef LOGORBMGR_HH #define LOGORBMGR_HH #include #include #include #include #include #include #include "CorbaLogForwarder.hh" //#define LOGTOOLCTXT "LogTool" #define LOGCOMPCTXT "LogServiceC" //"LogService component" #define LOGTOOLCTXT "LogServiceT" //"LogService tool" #define LOGCOMPCONFCTXT "LogServiceC2" //"LogService component" #define LOGTOOLMSGCTXT "LogServiceT2" //"LogService tool" #define LOGFWRDCTXT "LogForwarder" #define DIETFWRD "DietForwarder" class LogORBMgr { public: /* Constructors. */ LogORBMgr(int argc, char* argv[]); LogORBMgr(CORBA::ORB_ptr ORB); LogORBMgr(CORBA::ORB_ptr ORB, PortableServer::POA_var POA); /* Destructor. */ ~LogORBMgr(); /* Bind the object using its ctxt/name */ void bind(const std::string& ctxt, const std::string& name, CORBA::Object_ptr object, const bool rebind = false) const; /* Bind an object using its IOR. */ void bind(const std::string& ctxt, const std::string& name, const std::string& IOR, const bool rebind = false) const; /* Rebind objects. */ void rebind(const std::string& ctxt, const std::string& name, CORBA::Object_ptr object) const; void rebind(const std::string& ctxt, const std::string& name, const std::string& IOR) const; /* Unbind an object. */ void unbind(const std::string& ctxt, const std::string& name) const; /* Forwarders binding. */ void fwdsBind(const std::string& ctxt, const std::string& name, const std::string& ior, const std::string& fwName = "") const; /* Forwarders unbinding. */ void fwdsUnbind(const std::string& ctxt, const std::string& name, const std::string& fwName = "") const; /* Resolve an object using its IOR or ctxt/name. */ CORBA::Object_ptr resolveObject(const std::string& IOR) const; CORBA::Object_ptr resolveObject(const std::string& ctxt, const std::string& name, const std::string& fwdName = "") const; /* Get the list of the objects id binded in the omniNames server for a given context. */ std::list list(CosNaming::NamingContext_var& ctxt) const; std::list list(const std::string& ctxtName) const; template CORBA_ptr resolve(const std::string& ctxt, const std::string& name, const std::string& fwdName = "") const { return CORBA_object::_duplicate(CORBA_object::_narrow(resolveObject(ctxt, name, fwdName))); } template CORBA_ptr resolve(const std::string& IOR) const { return CORBA_object::_duplicate(CORBA_object::_narrow(resolveObject(IOR))); } /* Return the IOR of the passed object. */ std::string getIOR(CORBA::Object_ptr object) const; std::string getIOR(const std::string& ctxt, const std::string& name) const; /* Activate an object. */ void activate(PortableServer::ServantBase* object) const; /* Deactivate an object. */ void deactivate(PortableServer::ServantBase* object) const; /* Wait for the request on activated objects. */ void wait() const; void shutdown(bool waitForCompletion); static void init(int argc, char* argv[]); static LogORBMgr* getMgr(); /* IOR management functions. */ static void makeIOR(const std::string& strIOR, IOP::IOR& ior); static void makeString(const IOP::IOR& ior, std::string& strIOR); static std::string getHost(IOP::IOR& ior); static std::string getHost(const std::string& strIOR); static unsigned int getPort(IOP::IOR& ior); static unsigned int getPort(const std::string& strIOR); static std::string getTypeID(IOP::IOR& ior); static std::string getTypeID(const std::string& strIOR); static std::string convertIOR(IOP::IOR& ior, const std::string& host, const unsigned int port); static std::string convertIOR(const std::string& ior, const std::string& host, const unsigned int port); /* Object cache management functions. */ void resetCache() const; void removeObjectFromCache(const std::string& name) const; void removeObjectFromCache(const std::string& ctxt, const std::string& name) const; void cleanCache() const; static void hexStringToBuffer(const char* ptr, const size_t size, cdrMemoryStream& buffer); private: /* The omniORB Object Request Broker for this manager. */ CORBA::ORB_ptr ORB; /* The Portable Object Adaptor. */ PortableServer::POA_var POA; /* Is the ORB down? */ bool down; /* CORBA initialization. */ void init(CORBA::ORB_ptr ORB); /* Object cache to avoid to contact OmniNames too many times. */ mutable std::map cache; /* Cache mutex. */ mutable omni_mutex cacheMutex; /* The manager instance. */ static LogORBMgr* theMgr; static void sigIntHandler(int sig); #ifndef __cygwin__ static omni_mutex waitLock; #else static sem_t waitLock; #endif }; #endif LogService-2.7.0/src/monitor/000755 000765 000765 00000000000 11576373453 017472 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/NetConfig.cc000644 000765 000765 00000032656 11576373446 020204 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation - Network configuration */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2011/05/11 16:27:25 bdepardo * Updated forwarder files: bug correction and optimization coming from DIET * * Revision 1.2 2011/02/04 15:35:22 bdepardo * Code indentation * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.4 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:03 glemahec * DIET 2.5 beta 1 - New ORB manager; logForwarder application ****************************************************************************/ #include "NetConfig.hh" #include #include #include #include #include #include #include #include #include // For gethostname() #include // For gethostent() /* For local address management. */ #include #include #include #include /* For netmask retrieving. */ #include #include // for opendir #include #include #include #include #if defined __darwin__ || defined __freebsd__ // required for getifaddrs #include #endif //#include "debug.hh" #ifndef HOST_NAME_MAX #ifdef APPLE #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #else #define HOST_NAME_MAX 255 #endif #endif using namespace std; NetConfig::NetConfig() { char hostname[HOST_NAME_MAX+1]; gethostname(hostname, HOST_NAME_MAX); hostname[HOST_NAME_MAX]='\0'; myHostname = hostname; } NetConfig::NetConfig(const list& accept, const list& reject, const string& hostname) { this->accept = accept; this->reject = reject; this->myHostname = hostname; } NetConfig::NetConfig(const string& filePath) { char hostname[HOST_NAME_MAX+1]; gethostname(hostname, HOST_NAME_MAX); hostname[HOST_NAME_MAX]='\0'; myHostname = hostname; this->filePath = filePath; parseFile(); } NetConfig::NetConfig(const NetConfig& cfg) { operator=(cfg); } NetConfig& NetConfig::operator=(const NetConfig& cfg) { filePath = cfg.filePath; accept = cfg.accept; reject = cfg.reject; myHostname = cfg.myHostname; return *this; } void NetConfig::addLocalHost(std::list& l) const { struct hostent* hp; char** it; char buffer[INET6_ADDRSTRLEN+1]; string hostname = myHostname; size_t sp=0; while ((sp=hostname.find('.', sp))!=string::npos) { hostname.insert(sp,"\\"); sp+=2; } l.push_back(myHostname); l.push_back("localhost"); l.push_back("127\\.0\\.0\\.1"); hp = gethostbyname(myHostname.c_str()); if (hp != NULL) { for (it=hp->h_aliases; *it!=NULL; ++it) { string hostname = *it; size_t sp=0; while ((sp=hostname.find('.', sp))!=string::npos) { hostname.insert(sp,"\\"); sp+=2; } l.push_back(hostname); cout << "## " << hostname << endl; } for (it=hp->h_addr_list; *it!=NULL; ++it) { if (inet_ntop(hp->h_addrtype, *it, buffer, INET6_ADDRSTRLEN)!=NULL) { string hostname = buffer; size_t sp=0; while ((sp=hostname.find('.', sp))!=string::npos) { hostname.insert(sp,"\\"); sp+=2; } l.push_back(hostname); } } } #ifdef __linux__ /* FIXME: Dirty hack for getting all IP addresses of the machine * Currently this has only been tested on linux * TODO: test on other systems * TODO: add ipv6 addresses, currently only ipv4 addresses are handled */ int sock; static struct ifreq ifreqs[100]; // 100 should be enough struct ifconf ifconf; ifconf.ifc_buf = (char*) (ifreqs); ifconf.ifc_len = sizeof(ifreqs); sock = socket(AF_INET, SOCK_STREAM, 0); if(sock >= 0) { ioctl(sock, SIOCGIFCONF, (char*) &ifconf); unsigned int nifaces = ifconf.ifc_len / sizeof(struct ifreq); for (unsigned int i = 0; i < nifaces; ++ i) { string eth = ifreqs[i].ifr_name; struct ifreq ifr; int sock2 = socket(AF_INET, SOCK_DGRAM, 0); if (sock2 >= 0) { strncpy(ifr.ifr_name, eth.c_str(), IFNAMSIZ-1); ioctl(sock2, SIOCGIFADDR, &ifr); /* Get IP, and insert backslashes before '.' */ hostname = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); size_t sp=0; while ((sp=hostname.find('.', sp))!=string::npos) { hostname.insert(sp,"\\"); sp+=2; } /* Only add addresses that are not yet in the list */ if (find(l.begin(), l.end(), hostname) == l.end()) { l.push_back(hostname); } } // end if (sock2 >= 0) close(sock2); } // end for (...) } // end if (sock >= 0) close(sock); #elif defined __darwin__ || defined __freebsd__ /* Works only if getifaddrs exists */ struct ifaddrs *if_addrs = NULL; struct ifaddrs *if_addr = NULL; void *tmp = NULL; char buf[INET6_ADDRSTRLEN]; if (0 == getifaddrs(&if_addrs)) { for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next) { // Address if (if_addr->ifa_addr->sa_family == AF_INET) { tmp = &((struct sockaddr_in *)if_addr->ifa_addr)->sin_addr; } else { tmp = &((struct sockaddr_in6 *)if_addr->ifa_addr)->sin6_addr; } /* Get IP, and insert backslashes before '.' */ const char * hostname_c = inet_ntop(if_addr->ifa_addr->sa_family, tmp, buf, sizeof(buf)); if (hostname_c) { hostname = hostname_c; size_t sp = 0; while ((sp=hostname.find('.', sp))!=string::npos) { hostname.insert(sp,"\\"); sp+=2; } /* Only add addresses that are not yet in the list */ if (find(l.begin(), l.end(), hostname) == l.end()) { l.push_back(hostname); } } } freeifaddrs(if_addrs); } // end: if (0 == getifaddrs(&if_addrs)) #endif // __linux__ } void NetConfig::parseFile() { DIR *dp = opendir(filePath.c_str()); if(dp != NULL) { closedir(dp); throw runtime_error("Unable to open "+filePath+", this is a directory, not a configuration file."); } ifstream file(filePath.c_str()); if (!file.is_open()) { throw runtime_error("Unable to open "+filePath); } while (!file.eof()) { char buffer[1024]; size_t pos; file.getline(buffer, 1024); string line(buffer); /* Remove comments. */ if ((pos = line.find('#')) != string::npos) line = line.substr(0, pos); /* Remove blank characters. */ if ((pos = line.find_last_not_of(' ')) != string::npos) { line.erase(pos+1); } if ((pos = line.find_last_not_of('\t')) != string::npos) { line.erase(pos+1); } /* Void line. */ if (line == "") { continue; } /* Manage accepted networks. */ if (line.find("accept = ") == 0) { string network = line.substr(10); if (network=="localhost") { addLocalHost(accept); } else { addAcceptNetwork(network); } } if (line.find("accept:") == 0) { string network = line.substr(7); if (network=="localhost") { addLocalHost(accept); } else { addAcceptNetwork(network); } } if (line.find("reject = ") == 0) { string network = line.substr(10); if (network=="localhost") { addLocalHost(reject); } else { addRejectNetwork(network); } } if (line.find("reject:") == 0) { string network = line.substr(7); if (network=="localhost") { addLocalHost(reject); } else { addRejectNetwork(network); } } } } void NetConfig::reset() { accept.clear(); reject.clear(); } void NetConfig::addAcceptNetwork(const std::string& pattern) { accept.push_back(pattern); } void NetConfig::remAcceptNetwork(const std::string& pattern) { accept.remove(pattern); } void NetConfig::addRejectNetwork(const std::string& pattern) { reject.push_back(pattern); } void NetConfig::remRejectNetwork(const std::string& pattern) { reject.remove(pattern); } bool match(const string& hostname, const list l) { list::const_iterator it; for (it=l.begin(); it!=l.end(); ++it) { regex_t reg; if (regcomp(®, it->c_str(), REG_EXTENDED | REG_ICASE)) { regfree(®); continue; } if (!regexec(®, hostname.c_str(), 0, NULL, 0)) { regfree(®); return true; } regfree(®); } return false; } bool NetConfig::manage(const std::string& hostname) const { if (!match(hostname, accept)) { //cout << "The hostname " << hostname << " does not match " // << "any element of the accept list" << endl; return false; } if (match(hostname, reject)) { //cout << "The hostname " << hostname << "matches " // << "an element of the reject list" << endl; return false; } return true; } void NetConfig::updateConfig() { reset(); parseFile(); } const list& NetConfig::getAcceptList() const { return accept; } const list& NetConfig::getRejectList() const { return reject; } /*int main(int argc, char* argv[]) { if (argc<2) { cerr << "Usage: " << argv[0] << " " << endl; return EXIT_FAILURE; } NetConfig net(argv[1]); cout << "reach(localhost): " << net.canReach("localhost") << endl; cout << "reach(192.168.0.1): " << net.canReach("192.168.0.1") << endl; cout << "reach(graal.ens-lyon.fr): " << net.canReach("graal.ens-lyon.fr") << endl; cout << "reach(capricorne-25.lyon.grid5000.fr): " << net.canReach("capricorne-25.lyon.grid5000.fr") << endl; cout << "reach(dhcp-34-29.incubateur.ens-lyon.fr): " << net.canReach("dhcp-34-29.incubateur.ens-lyon.fr") << endl; cout << "reach(127.0.0.1): " << net.canReach("127.0.0.1") << endl; cout << "reach(140.77.34.29): " << net.canReach("140.77.34.29") << endl; } */ LogService-2.7.0/src/NetConfig.hh000644 000765 000765 00000012236 11576373446 020206 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Log forwarder implementation - Network configuration */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2011/02/04 15:35:22 bdepardo * Code indentation * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:03 glemahec * DIET 2.5 beta 1 - New ORB manager; LogForwarder application ****************************************************************************/ #ifndef NETCONFIG_HH #define NETCONFIG_HH #include #include #include class NetConfig { public: NetConfig(); NetConfig(const std::list& accept, const std::list& reject, const std::string& hostname); NetConfig(const std::string& path); NetConfig(const NetConfig& cfg); NetConfig& operator=(const NetConfig& cfg); void addAcceptNetwork(const std::string& pattern); void remAcceptNetwork(const std::string& pattern); void addRejectNetwork(const std::string& pattern); void remRejectNetwork(const std::string& pattern); bool manage(const std::string& hostname) const; void updateConfig(); const std::list& getAcceptList() const; const std::list& getRejectList() const; private: std::string filePath; std::list accept; std::list reject; void parseFile(); void reset(); std::string myHostname; void addLocalHost(std::list& l) const; }; #endif LogService-2.7.0/src/Options.cc000644 000765 000765 00000024531 11576373447 017755 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET forwarder implementation - Executable options */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application ****************************************************************************/ #include "Options.hh" #include #include #include #include #include #include #include #include using namespace std; /* Default constructor. */ Configuration::Configuration() { pgName = "unknown"; } /* Standard constructor. Get the program name as parameter. */ Configuration::Configuration(const std::string& pgName) { this->pgName = pgName; } /* Generic program configuration accessors. */ const string& Configuration::getConfigFile() const { return configFile; } const std::string& Configuration::getPgName() const { return pgName; } void Configuration::setConfigFile(const string& configFile) { this->configFile = configFile; } /* Standard Options constructor. Get a pointer on a config object, and * the command line arguments. */ Options::Options(Configuration* config, int argc, char* argv[], char* envp[]) { unsigned int j = 0; this->config = config; for (int i=1; i::const_iterator i; list::const_iterator j; unsigned int k; list::const_iterator l; optCallback callback; for (l=flags.begin(); l!=flags.end(); ++l) { if (flagCallbacks.find(*l)!=flagCallbacks.end()) { string flag; flag+=*l; callback = flagCallbacks.find(*l)->second; callback(flag, config); } else { if (*l!='-') cerr << "Warning: -" << *l << " flag unknown" << endl; } } for (i=arguments.begin(); i!=arguments.end(); ++i) { if (optCallbacks.find(i->first)!=optCallbacks.end()) { callback = optCallbacks.find(i->first)->second; callback(i->second, config); } else { cerr << "Warning: " << i->first << " unknown option" << endl; } } for (j=singleArgs.begin(); j!=singleArgs.end(); ++j) { if (optCallbacks.find(*j)!=optCallbacks.end()) { callback = optCallbacks.find(*j)->second; callback("", config); } else { cerr << "Warning: " << *j << " unknown option" << endl; } } for (k=0;k::const_iterator i; list::const_iterator j; optCallback callback; for (i=environment.begin(); i!=environment.end(); ++i) { if (envCallbacks.find(i->first)!=envCallbacks.end()) { callback = envCallbacks.find(i->first)->second; callback(i->second, config); } } for (j=singleEnvs.begin(); j!=singleEnvs.end(); ++j) { if (envCallbacks.find(*j)!=envCallbacks.end()) { callback = envCallbacks.find(*j)->second; callback(*j, config); } } } /* Simple utility function: * Replace the '=' character with a white space. * Used to extract information with istringstream. */ int cut(int c) { if (c == '=') return ' '; return c; } ConfigFile::ConfigFile() {} ConfigFile::ConfigFile(const string& path) { parseFile(path); } void ConfigFile::parseFile(const std::string& path) { ifstream file(path.c_str()); unsigned int l = 0; if (!file.is_open()) throw runtime_error("Can't open "+path); while (!file.eof()) { char buffer[1024]; string line, key, value; string::iterator it; istringstream is; size_t pos; l++; file.getline(buffer, 1024); line = buffer; /* Remove comments. */ pos = line.find('#'); line = line.substr(0, pos); /* Remove white spaces. */ while ((pos=line.find(' '))!=string::npos) line.erase(pos, 1); while ((pos=line.find('\t'))!=string::npos) line.erase(pos, 1); /* Empty line => continue. */ if (line=="") continue; /* Cut the line on '=' chararcter. */ transform(line.begin(), line.end(), line.begin(), cut); /* Extract key,value */ is.str(line); is >> key >> value; if (value=="") cerr << "Warning: \"" << key << "\" has no value! (l." << l << ")" << endl; if (attributes.find(key)!=attributes.end()) cerr << "Warning: Multiple values for the attribute " << key << " (l." << l << ")" << endl; /* Transform to lower case. */ transform(key.begin(), key.end(), key.begin(), ::tolower); attributes[key]=value; } } const string& ConfigFile::getAttr(const string& key) { return attributes[key]; } LogService-2.7.0/src/Options.hh000644 000765 000765 00000014045 11576373447 017766 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET forwarder implementation - Executable options */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application ****************************************************************************/ #ifndef OPTIONS_HH #define OPTIONS_HH #include #include #include class Options; /* Standard configuration class. Used as an abstract class for parameters * processing. */ class Configuration { private: std::string pgName; std::string configFile; public: Configuration(); Configuration(const std::string& pgName); const std::string& getPgName() const; const std::string& getConfigFile() const; void setConfigFile(const std::string& configFile); }; /* Callback function type definition. */ typedef void (*optCallback)(const std::string&, Configuration*); /* Options class. Used to process the users command line parameters. */ /* This class is a generic command line parameters processing tool. */ class Options { private: Configuration* config; std::map arguments; std::map environment; std::map params; std::list singleArgs; std::list singleEnvs; std::list flags; std::map optCallbacks; std::map envCallbacks; std::map paramCallbacks; std::map flagCallbacks; public: Options(Configuration* config, int argc, char* argv[], char* envp[]=NULL); void setOptCallback(const std::string& arg, optCallback callBack); void setEnvCallback(const std::string& arg, optCallback callBack); void setParamCallback(unsigned int idx, optCallback callBack); void setFlagCallback(const char flag, optCallback callBack); void processOptions(); void processEnv(); }; /* A simple configuration file class. * The file must respect the format: * = */ class ConfigFile { private: std::map attributes; public: ConfigFile(); explicit ConfigFile(const std::string& path); void parseFile(const std::string& path); const std::string& getAttr(const std::string& key); }; #endif LogService-2.7.0/src/SSHTunnel.cc000644 000765 000765 00000036563 11576373447 020155 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET forwarder implementation - SSH Tunnel implementation */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2011/05/11 16:27:25 bdepardo * Updated forwarder files: bug correction and optimization coming from DIET * * Revision 1.2 2010/12/03 12:40:25 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.3 2010/07/14 23:45:30 bdepardo * Header corrections * * Revision 1.2 2010/07/13 15:24:13 glemahec * Warnings corrections and some robustness improvements * * Revision 1.1 2010/07/12 16:11:04 glemahec * DIET 2.5 beta 1 - New ORB manager; dietForwarder application ****************************************************************************/ #include "SSHTunnel.hh" #include #include #include #include #include #include #include #include #include #include #include // For sleep & fork functions #include // For waitpid function /* To find a free tcp port. */ #include #include #include /**/ using namespace std; string SSHTunnel::cmdFormat = "%p -l %u %s -p %P -N"; string SSHTunnel::localFormat = "-L%l:%h:%R"; string SSHTunnel::remoteFormat = "-R%r:%h:%L"; string SSHTunnel::keyFormat = "-i %k"; /* Return the current session login. */ string SSHConnection::userLogin() { char* result = getlogin(); if (result==NULL) { //throw runtime_error("Unable to determine the user login."); cerr << "Unable to determine the user login." << endl; return ""; } return result; } /* Get the default path to user SSH key. If the user does not use * a private key for connection, return empty string. */ string SSHConnection::userKey() { char* home = getenv("HOME"); string path; /* Try the RSA key default path. */ path = ((home == NULL) ? string(""):string(home)) + "/.ssh/id_rsa"; ifstream f(path.c_str()); if (f.is_open()) { f.close(); return path; } /* Try the DSA key default path. */ path = ((home == NULL) ? string(""):string(home)) + "/.ssh/id_dsa"; f.open(path.c_str()); if (f.is_open()) { f.close(); return path; } /* None of the two default keys were found */ return ""; } SSHConnection::SSHConnection() { setSshPath("/usr/bin/ssh"); setSshPort("22"); setSshLogin(userLogin()); setSshKeyPath(userKey()); } SSHConnection::SSHConnection(const std::string& sshHost, const std::string& sshPort, const std::string& login, const std::string& keyPath, const std::string& sshPath) { setSshHost(sshHost); setSshPort(sshPort); setSshLogin(login); setSshKeyPath(keyPath); setSshPath(sshPath); } const std::string& SSHConnection::getSshHost() const { return sshHost; } const std::string& SSHConnection::getSshPath() const { return sshPath; } const std::string& SSHConnection::getSshPort() const { return sshPort; } const std::string& SSHConnection::getSshLogin() const { return login; } const std::string& SSHConnection::getSshKeyPath() const { return keyPath; } const std::string& SSHConnection::getSshOptions() const { return options; } void SSHConnection::setSshHost(const std::string& host) { if (host != "") { this->sshHost = host; } } void SSHConnection::setSshPath(const std::string& path) { if (path != "") { this->sshPath = path; } } void SSHConnection::setSshPort(const std::string& port) { if (port != "") { this->sshPort = port; } } void SSHConnection::setSshPort(const int port) { ostringstream os; os << port; this->sshPort = os.str(); } void SSHConnection::setSshLogin(const std::string& login) { if (login != "") { this->login = login; } } void SSHConnection::setSshKeyPath(const std::string& path) { this->keyPath = path; } void SSHConnection::setSshOptions(const std::string& options) { this->options = options; } /* Replace "s" by "r" in "str". */ void replace(const string& s, const string& r, string& str) { size_t pos; if ((pos=str.find(s))!=string::npos) { str.erase(pos, s.length()); str.insert(pos, r); } } /* Try to find a free TCP port. "sfd" is * the socket file descriptor used to find * the port. */ string freeTCPport() { ostringstream os; struct sockaddr_in sck; int sfd = socket(AF_INET, SOCK_STREAM, 0); sck.sin_family = AF_INET; sck.sin_addr.s_addr = INADDR_ANY; sck.sin_port = 0; bind(sfd, (struct sockaddr*) &sck, sizeof(sck)); socklen_t len = sizeof(sck); getsockname(sfd, (struct sockaddr*) &sck, &len); os << sck.sin_port; close(sfd); return os.str(); } string SSHTunnel::makeCmd() { string result; result = cmdFormat; replace("%p", getSshPath(), result); replace("%u", getSshLogin(), result); replace("%P", getSshPort(), result); replace("%s", getSshHost(), result); if (createTo) { result+=" "; result+=localFormat; if (localPortFrom=="") { localPortFrom = freeTCPport(); replace("%l", localPortFrom, result); } replace("%h", remoteHost, result); replace("%R", remotePortTo, result); } if (getSshKeyPath()!="") { result+=" "; result+= keyFormat; replace("%k", getSshKeyPath(), result); } if (createFrom) { result+=" "; result+=remoteFormat; replace("%L", localPortTo, result); replace("%h", remoteHost, result); replace("%r", remotePortFrom, result); } if (getSshOptions()!="") { result+=" "+getSshOptions(); } return result; } SSHTunnel::SSHTunnel() : SSHConnection() { createTo = false; createFrom = false; } /* Constructor for bi-directionnal SSH tunnel. */ SSHTunnel::SSHTunnel(const string& sshHost, const string& remoteHost, const string& localPortFrom, const string& remotePortTo, const string& remotePortFrom, const string& localPortTo, const bool createTo, const bool createFrom, const string& sshPath, const string& sshPort, const string& login, const string& keyPath) : SSHConnection(sshHost, sshPort, login, keyPath, sshPath) { this->remoteHost = remoteHost; this->localPortFrom = localPortFrom; this->remotePortTo = remotePortTo; this->remotePortFrom = remotePortFrom; this->localPortTo = localPortTo; this->createTo = createTo; this->createFrom = createFrom; } /* Constructor for unidirectionnal SSH tunnel. */ SSHTunnel::SSHTunnel(const string& sshHost, const string& remoteHost, const string& localPortFrom, const string& remotePortTo, const bool createTo, const string& sshPath, const string& sshPort, const string& login, const string& keyPath) : SSHConnection(sshHost, sshPort, login, keyPath, sshPath) { this->remoteHost = remoteHost; this->localPortFrom = localPortFrom; this->remotePortTo = remotePortTo; this->createTo = createTo; this->createFrom = false; } SSHTunnel::~SSHTunnel() { close(); } void SSHTunnel::open() { if (!createTo && !createFrom) { return; } vector tokens; string command = makeCmd(); istringstream is(command); copy(istream_iterator(is), istream_iterator(), back_inserter >(tokens)); char* argv[tokens.size()+1]; argv[tokens.size()]=NULL; for (unsigned int i=0; i> res; return res; } int SSHTunnel::getLocalPortTo() const { int res; istringstream is(localPortTo); is >> res; return res; } int SSHTunnel::getRemotePortFrom() const { int res; istringstream is(remotePortFrom); is >> res; return res; } int SSHTunnel::getRemotePortTo() const { int res; istringstream is(remotePortTo); is >> res; return res; } void SSHTunnel::setRemoteHost(const std::string& host) { this->remoteHost = host; } void SSHTunnel::setLocalPortFrom(const std::string& port) { this->localPortFrom = port; } void SSHTunnel::setLocalPortFrom(const int port) { ostringstream os; os << port; this->localPortFrom = os.str(); } void SSHTunnel::setRemotePortTo(const std::string& port) { this->remotePortTo = port; } void SSHTunnel::setRemotePortTo(const int port) { ostringstream os; os << port; this->remotePortTo = os.str(); } void SSHTunnel::setRemotePortFrom(const std::string& port) { this->remotePortFrom = port; } void SSHTunnel::setRemotePortFrom(const int port) { ostringstream os; os << port; this->remotePortFrom = os.str(); } void SSHTunnel::setLocalPortTo(const std::string& port) { this->localPortTo = port; } void SSHTunnel::setLocalPortTo(const int port) { ostringstream os; os << port; this->localPortTo = os.str(); } void SSHTunnel::createTunnelTo(const bool create) { this->createTo = create; } void SSHTunnel::createTunnelFrom(const bool create) { this->createFrom = create; } SSHCopy::SSHCopy(const string& sshHost, const string& remoteFilename, const string& localFilename) { setSshHost(sshHost); this->remoteFilename = remoteFilename; this->localFilename = localFilename; } bool SSHCopy::getFile() const { vector tokens; int status; string command = getSshPath()+" -P "+getSshPort(); if (getSshKeyPath()!="") { command += " -i "+getSshKeyPath(); } command += " "+getSshLogin()+"@"+getSshHost()+":"+remoteFilename; command += " "+localFilename; istringstream is(command); copy(istream_iterator(is), istream_iterator(), back_inserter >(tokens)); char* argv[tokens.size()+1]; argv[tokens.size()]=NULL; for (unsigned int i=0; i tokens; int status; string command = getSshPath()+" -P "+getSshPort()+" -i "+getSshKeyPath(); command += " "+localFilename; command += getSshLogin()+"@"+getSshHost()+":"+remoteFilename; istringstream is(command); copy(istream_iterator(is), istream_iterator(), back_inserter >(tokens)); char* argv[tokens.size()+1]; argv[tokens.size()]=NULL; for (unsigned int i=0; i #include #include class SSHConnection { private: /* SSH executable path. */ std::string sshPath; /* SSH connection params. */ std::string login; std::string keyPath; std::string sshHost; std::string sshPort; std::string options; protected: /* Get the default user login and private key. */ static std::string userLogin(); static std::string userKey(); public: SSHConnection(); SSHConnection(const std::string& sshHost, const std::string& sshPort, const std::string& login, const std::string& keyPath, const std::string& sshPath); const std::string& getSshHost() const; const std::string& getSshPath() const; const std::string& getSshPort() const; const std::string& getSshLogin() const; const std::string& getSshKeyPath() const; const std::string& getSshOptions() const; void setSshHost(const std::string& host); void setSshPath(const std::string& path); void setSshPort(const std::string& port); void setSshPort(const int port); void setSshLogin(const std::string& login); void setSshKeyPath(const std::string& path); void setSshOptions(const std::string& options); }; class SSHTunnel : public SSHConnection { private: /* Format strings for ssh commands. */ static std::string cmdFormat; static std::string localFormat; static std::string remoteFormat; static std::string keyFormat; /* Tunnel configuration. */ bool createFrom; bool createTo; std::string localPortTo; std::string localPortFrom; std::string remoteHost; std::string remotePortTo; std::string remotePortFrom; /* Process pid. */ pid_t pid; std::string makeCmd(); public: SSHTunnel(); /* Constructor for bi-directionnal SSH tunnel. */ SSHTunnel(const std::string& sshHost, const std::string& remoteHost, const std::string& localPortFrom, const std::string& remotePortTo, const std::string& remotePortFrom, const std::string& localPortTo, const bool createTo = true, const bool createFrom = true, const std::string& sshPath = "/usr/bin/ssh", const std::string& sshPort = "22", const std::string& login = userLogin(), const std::string& keyPath = userKey()); /* Constructor for unidirectionnal SSH tunnel. */ SSHTunnel(const std::string& sshHost, const std::string& remoteHost, const std::string& localPortFrom, const std::string& remotePortTo, const bool createTo = true, const std::string& sshPath = "/usr/bin/ssh", const std::string& serverPort = "22", const std::string& login = userLogin(), const std::string& keyPath = userKey()); ~SSHTunnel(); void open(); void close(); const std::string& getRemoteHost() const; int getLocalPortFrom() const; int getLocalPortTo() const; int getRemotePortFrom() const; int getRemotePortTo() const; void setRemoteHost(const std::string& host); void setLocalPortFrom(const std::string& port); void setLocalPortFrom(const int port); void setRemotePortTo(const std::string& port); void setRemotePortTo(const int port); void setRemotePortFrom(const std::string& port); void setRemotePortFrom(const int port); void setLocalPortTo(const std::string& port); void setLocalPortTo(const int port); void createTunnelTo(const bool create); void createTunnelFrom(const bool create); }; /* Copy a file using scp. */ class SSHCopy : public SSHConnection { private: std::string remoteFilename; std::string localFilename; /* Process pid. */ mutable pid_t pid; public: SSHCopy(const std::string& sshHost, const std::string& remoteFilename, const std::string& localFilename); bool getFile() const; bool putFile() const; }; std::string freeTCPport(); #endif LogService-2.7.0/src/tester/000755 000765 000765 00000000000 11576373455 017313 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/utils/000755 000765 000765 00000000000 11576373454 017144 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/utils/CMakeLists.txt000644 000765 000765 00000000767 11576373453 021715 0ustar00bdepardobdepardo000000 000000 INCLUDE_DIRECTORIES( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_BINARY_DIR}/src/idl ) ADD_LIBRARY( LogServiceUtils STATIC ORBTools.cc LocalTime.cc ) ADD_DEPENDENCIES( LogServiceUtils LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ) TARGET_LINK_LIBRARIES( LogServiceUtils LogCorba ${OMNIORB4_LIBRARIES} ) set (binary ${binary} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceUtils.dir/ORBTools.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceUtils.dir/LocalTime.cc.o PARENT_SCOPE )LogService-2.7.0/src/utils/FullLinkedList.cc000644 000765 000765 00000045571 11576373454 022354 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Thread safe generic Double linked list with full access - implementation */ /* This file will be included in the FullLinkedList.hh file. */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2006/06/01 16:13:47 rbolze * change to be able to compile with gcc-4 * Thanks to Abdelkader Amar who has done the work. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ template FullLinkedList::FullLinkedList() { this->first = NULL; this->last = NULL; this->counter = 0; readerCount = 0; } template FullLinkedList::FullLinkedList(FullLinkedList& newFLL) { this->first = NULL; this->last = NULL; this->counter = 0; lockReadWrite(); newFLL.lockRead(); if (newFLL.first != NULL) { // if the new list is not empty // creation of the first element this->first = new Node(); this->counter++; Node* ownNode = this->first; Node* newListNode = newFLL.first; ownNode->previous = NULL; // call the copy constructor of T ownNode->element = new T(*(newListNode->element)); while (newListNode->next != NULL) { ownNode->next = new Node(); // create a new node ownNode->next->previous = ownNode; // fix the previous of the new node ownNode = ownNode->next; // go to the new node newListNode = newListNode->next; // got to the new node ownNode->element = new T(*(newListNode->element)); // copy the element this->counter++; } ownNode->next = NULL; this->last = ownNode; } newFLL.unlockRead(); unlockReadWrite(); } template FullLinkedList::~FullLinkedList() { this->emptyIt(); } template FullLinkedList& FullLinkedList::operator =(FullLinkedList& newFLL) { lockReadWrite(); newFLL.lockRead(); this->operatorEqualPrivate(newFLL); newFLL.unlockRead(); unlockReadWrite(); return *this; } template void FullLinkedList::emptyIt() { lockReadWrite(); this->emptyItPrivate(); unlockReadWrite(); } template void FullLinkedList::push(T* element) { Iterator* it; it = getIterator(); it->resetToLast(); it->insertAfter(element); delete it; } template void FullLinkedList::pushRef(T* element) { Iterator* it; it = getIterator(); it->resetToLast(); it->insertAfterRef(element); delete it; } template void FullLinkedList::shift(T* element) { Iterator* it; it = getIterator(); it->insertBefore(element); delete it; } template void FullLinkedList::shiftRef(T* element) { Iterator* it; it = getIterator(); it->insertBeforeRef(element); delete it; } template T* FullLinkedList::pop() { T* ret; Iterator* it = getIterator(); it->resetToLast(); if (it->hasCurrent()) { ret = it->removeAndGetCurrent(); } else { ret = NULL; } delete it; return ret; } template T* FullLinkedList::unshift() { T* ret; Iterator* it = getIterator(); if (it->hasCurrent()) { ret = it->removeAndGetCurrent(); } else { ret = NULL; } delete it; return ret; } template void FullLinkedList::appendList(FullLinkedList* list) { lockReadWrite(); list->lockRead(); this->appendListPrivate(list); list->unlockRead(); unlockReadWrite(); } template typename FullLinkedList::Iterator* FullLinkedList::getIterator() { lockReadWrite(); Iterator* it = new Iterator(this); return it; } template typename FullLinkedList::ReadIterator* FullLinkedList::getReadIterator() { lockRead(); ReadIterator* it = new ReadIterator(this); return it; } template typename FullLinkedList::ReadIterator* FullLinkedList::reduceWriteIterator(Iterator* rwIterator) { rwIterator->noReadRelease = true; delete rwIterator; // no need to lock the ReadMutex, it is still locked ReadIterator* it = new ReadIterator(this); return it; } template void FullLinkedList::operatorEqualPrivate(FullLinkedList& newFLL) { this->emptyItPrivate(); if (newFLL.first != NULL) { // if the new list is not empty // creation of the first element this->first = new Node(); this->counter++; Node* ownNode = this->first; Node* newListNode = newFLL.first; ownNode->previous = NULL; // call the copy constructor of T ownNode->element = new T(*(newListNode->element)); while (newListNode->next != NULL) { ownNode->next = new Node(); // create a new node ownNode->next->previous = ownNode; // fix the previous of the new node ownNode = ownNode->next; // go to the new node newListNode = newListNode->next; // got to the new node ownNode->element = new T(*(newListNode->element)); // copy the element this->counter++; } ownNode->next = NULL; this->last = ownNode; } } template void FullLinkedList::emptyItPrivate() { if (this->first != NULL) { Node* node; while (this->first != NULL) { delete this->first->element; node = this->first; this->first = this->first->next; delete node; } } this->first = NULL; this->last = NULL; this->counter = 0; } template void FullLinkedList::appendListPrivate(FullLinkedList* list) { if (list == NULL) { // avoid SegFault return; } if (list->first != NULL) { // if the new list is not empty if (this->first == NULL) { // if this list is empty this->operatorEqualPrivate(*list); } else { // really append the list this->last->next = new Node(); Node* ownNode = this->last->next; Node* newListNode = list->first; ownNode->previous = this->last; ownNode->element = new T(*(newListNode->element)); // copy the element while (newListNode->next != NULL) { ownNode->next = new Node(); // create a new node ownNode->next->previous = ownNode; // fix the previous of the new node ownNode = ownNode->next; // go to the new node newListNode = newListNode->next; // got to the new node ownNode->element = new T(*(newListNode->element)); // copy the element this->counter++; } ownNode->next = NULL; this->last = ownNode; } } } template void FullLinkedList::lockReadWrite() { // new R / RW locks will block here. // this call also guarantes that all active readers // are registered in the readerCount writerMutex.lock(); // make sure that all readers are gone: readersExistMutex.lock(); // normally we should use: /* readersExistMutex.unlock(); * readerCountMutex.lock(); * if readerCount == 0 * readersExistMutex.lock(); * readerCount ++; * readerCountMutex.unlock(); */ // but as we are the only user we can reduce it to: readerCount = 1; // there exists a reader after this operation, but that's us } template void FullLinkedList::lockRead() { // make sure that we // - do not disturb writers // - no new writer/reader interrupts our acquire writerMutex.lock(); // now make sure we access the readerCount synchronised readerCountMutex.lock(); if (readerCount == 0) { // there exist readers now readersExistMutex.lock(); // this must not block ! } readerCount++; readerCountMutex.unlock(); // okay, we're finished. open this lock to allow // - other readers to connect // - other writers to connect (and block) writerMutex.unlock(); } template void FullLinkedList::unlockWrite() { writerMutex.unlock(); // we're still registered as a reader // nothing more to do... /** * Note: If there are several Readers and Writers waiting, it * would be best to first wake the Writers and then the Readers, * but we cannot guarantee this. */ } template void FullLinkedList::unlockRead() { // access readerCount synchronised readerCountMutex.lock(); readerCount--; if (readerCount == 0) { readersExistMutex.unlock(); // this should not block } readerCountMutex.unlock(); // thats it } template void FullLinkedList::unlockReadWrite() { unlockWrite(); unlockRead(); } /*************** ReadIterator implementation *****************/ template FullLinkedList::ReadIterator::ReadIterator(FullLinkedList* controledList) { linkedList = controledList; currentNode = linkedList->first; noReadRelease = false; } template FullLinkedList::ReadIterator::~ReadIterator() { if (noReadRelease == false) { linkedList->unlockRead(); } // else: keep lock to allow construction of other Iterators // without loosing synchronisation } template inline void FullLinkedList::ReadIterator::reset() { currentNode = linkedList->first; } template inline void FullLinkedList::ReadIterator::resetToLast() { currentNode = linkedList->last; } template inline bool FullLinkedList::ReadIterator::hasCurrent() { return (currentNode != NULL); } template inline bool FullLinkedList::ReadIterator::hasNext() { if (currentNode == NULL) { return false; } else { return (currentNode->next != NULL); } } template inline bool FullLinkedList::ReadIterator::hasPrevious() { if (currentNode == NULL) { return false; } else { return (currentNode->previous != NULL); } } template inline T* FullLinkedList::ReadIterator::getCurrent() { if (!FullLinkedList::ReadIterator::hasCurrent()) { return NULL; } T* ret = new T(*(currentNode->element)); return ret; } template inline T* FullLinkedList::ReadIterator::getCurrentRef() { if (!hasCurrent()) { return NULL; } return currentNode->element; } template inline T* FullLinkedList::ReadIterator::next() { if (!hasCurrent()) { return NULL; } T* ret = new T(*(currentNode->element)); currentNode = currentNode->next; return ret; } template inline T* FullLinkedList::ReadIterator::nextRef() { if (!hasCurrent()) { return NULL; } T* ret = currentNode->element; currentNode = currentNode->next; return ret; } template inline T* FullLinkedList::ReadIterator::previous() { if (!hasCurrent()) { return NULL; } T* ret = new T(*(currentNode->element)); currentNode = currentNode->previous; return ret; } template inline T* FullLinkedList::ReadIterator::previousRef() { if (!hasCurrent()) { return NULL; } T* ret = currentNode->element; currentNode = currentNode->previous; return ret; } template inline unsigned int FullLinkedList::ReadIterator::length() { return linkedList->counter; } /*************** (write)Iterator implementation *****************/ template FullLinkedList::Iterator::Iterator(FullLinkedList* controledList): ReadIterator(controledList) { // nothing to do } template FullLinkedList::Iterator::~Iterator() { // unlockRead() is called by parent FullLinkedList::ReadIterator::linkedList->unlockWrite(); } template void FullLinkedList::Iterator::removeCurrent() { T* el; el = removeAndGetCurrent(); if (el != NULL) { delete el; } } template T* FullLinkedList::Iterator::removeAndGetCurrent() { Node* node = FullLinkedList::ReadIterator::currentNode; // make sure we have a current element to remove if (!FullLinkedList::ReadIterator::hasCurrent()) { return NULL; } // Is this the only element ? if (FullLinkedList::ReadIterator::linkedList->counter == 1) { FullLinkedList::ReadIterator::linkedList->first = NULL; FullLinkedList::ReadIterator::linkedList->last = NULL; FullLinkedList::ReadIterator::linkedList->counter = 0; FullLinkedList::ReadIterator::currentNode = NULL; return node->element; // node is already initialised } // there are remaining elements // set internal links for list correctly if (node->previous == NULL) { // we are removing the first element FullLinkedList::ReadIterator::linkedList->first = node->next; // this one works, as there are more than two // node in the list and we are the first one: node->next->previous = NULL; FullLinkedList::ReadIterator::currentNode = node->next; } else if (node->next == NULL) { // we are removing the last element FullLinkedList::ReadIterator::linkedList->last = node->previous; // this works as there are more than two // nodes in the list and we are the last one: node->previous->next = NULL; FullLinkedList::ReadIterator::currentNode = node->previous; } else { // we are removing a middle element node->previous->next = node->next; node->next->previous = node->previous; FullLinkedList::ReadIterator::currentNode = node->next; } FullLinkedList::ReadIterator::linkedList->counter--; return node->element; } template void FullLinkedList::Iterator::insertAfter(T* element) { // copy element on the fly and insert as reference insertAfterRef(new T(*element)); } template void FullLinkedList::Iterator::insertAfterRef(T* element) { Node* node = new Node(); node->element = element; node->next = NULL; node->previous = NULL; FullLinkedList::ReadIterator::linkedList->counter++; if (FullLinkedList::ReadIterator::linkedList->first == NULL) { // build up new list ? FullLinkedList::ReadIterator::linkedList->first = node; FullLinkedList::ReadIterator::linkedList->last = node; FullLinkedList::ReadIterator::currentNode = node; } else { // insert in existing list if (FullLinkedList::ReadIterator::currentNode->next == NULL) { // insert at the end ? FullLinkedList::ReadIterator::currentNode->next = node; node->previous = FullLinkedList::ReadIterator::currentNode; FullLinkedList::ReadIterator::linkedList->last = node; } else { // insert in the middle node->next = FullLinkedList::ReadIterator::currentNode->next; node->previous = FullLinkedList::ReadIterator::currentNode; node->next->previous = node; node->previous->next = node; } } } template void FullLinkedList::Iterator::insertBefore(T* element) { // copy on the fly and insert as Ref insertBeforeRef(new T(*element)); } template void FullLinkedList::Iterator::insertBeforeRef(T* element) { Node* node = new Node(); node->element = element; node->next = NULL; node->previous = NULL; FullLinkedList::ReadIterator::linkedList->counter++; if (FullLinkedList::ReadIterator::linkedList->first == NULL) { // build up new list ? FullLinkedList::ReadIterator::linkedList->first = node; FullLinkedList::ReadIterator::linkedList->last = node; FullLinkedList::ReadIterator::currentNode = node; } else { // insert in existing list if (FullLinkedList::ReadIterator::currentNode->previous == NULL) { // insert at the beginning ? FullLinkedList::ReadIterator::currentNode->previous = node; node->next = FullLinkedList::ReadIterator::currentNode; FullLinkedList::ReadIterator::linkedList->first = node; } else { // insert in the middle node->next = FullLinkedList::ReadIterator::currentNode; node->previous = FullLinkedList::ReadIterator::currentNode->previous; node->next->previous = node; node->previous->next = node; } } } LogService-2.7.0/src/utils/FullLinkedList.hh000644 000765 000765 00000046643 11576373454 022367 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Thread safe generic Double linked list with full access */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2006/06/01 16:13:47 rbolze * change to be able to compile with gcc-4 * Thanks to Abdelkader Amar who has done the work. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _FULLLINKEDLIST_HH_ #define _FULLLINKEDLIST_HH_ #include #include #include /**************************************************************************** * This is a thread safe generic double linked list. It offers ReadWrite * and Readonly access to the list with the two iterators Iterator and * ReadIterator. Several Readers can exist at a time, while writers have * exclusive access to the list. Other iterators created in this time * will be blocked until the active iterator is deleted, so don't keep * your iterators to long. Write iterators have the possibility to * release their write-rights and become a read iterator without * releasing their read lock. * * The current implementation of this list does not distinguish between * readers and writers, but the behaviour can be implemented by changing * the functions lockReadWrite, lockRead, unlockRead and unlockWrite. * * This list deals with a copy of all the elements (T) but you can also use * some special functions to deal with references, but use them carrefully. */ templateclass FullLinkedList { friend class ReadIterator; friend class Iterator; /***************************************************************************** * PRIVATE FIELDS ****************************************************************************/ private: /** * This structure defines a node of the list. */ struct Node { /** * next node or \c NULL if it's the last one. */ Node* next; /** * previous node or \c NULL if it's the first one. */ Node* previous; /** * a pointer on the element. */ T* element; }; /** * indicates the number of element in the list. */ long counter; /** * the first element of the list or \c NULL if the list is empty. */ Node* first; /** * the last element of the list or NULL if the list is * empty. */ Node* last; /** * Reader/Writer synchronisation. Will be locked by writers till * the writeLock is released. */ mutable omni_mutex writerMutex; /** * Reader/Writer synchronisation. This variable contains the number * of active readers. */ int readerCount; /** * Reader/Writer synchronisation. Controls the access to readCount; */ mutable omni_mutex readerCountMutex; /** * Reader/Writer synchronisation. This Mutex is locked if there are * readers and can be used to wait for the readerCount to be empty. */ mutable omni_mutex readersExistMutex; /***************************************************************************** * PUBLIC METHODS ****************************************************************************/ public: class ReadIterator; class Iterator; /** * creates an new empty list. */ FullLinkedList(); /** * Copy constructor * Element T must be have a copy constructor */ FullLinkedList(FullLinkedList& newFLL); /** * Destroyes the list. The list will be emptied. * All elements will be freed. */ ~FullLinkedList(); /** * For affecting a list */ FullLinkedList& operator =(FullLinkedList& newFLL); /** * destroyes all the element of the list. The list becomes an empty * list. The Elements of the nodes are freed. * Acquires write lock. */ void emptyIt(); /** * Push an element on the list. The Element is stored at the * end of the list. * A copy of the element is done using the copy constructor * * @param element a pointer on the element to be added */ void push(T* element); /** * Push an element on the list. The Element is stored at the * end of the list. * !! Only the reference to the element is stored !! * Be very carrefull when using this function ! * * @param element a pointer on the element to be added */ void pushRef(T* element); /** * Shift an element in the list. The Element is stored at the * begin of the list. * A copy of the element is done using the copy constructor * * @param element a pointer on the element to be added */ void shift(T* element); /** * Shift an element in the list. The Element is stored at the * begin of the list. * !! Only the reference to the element is stored !! * Be very carrefull when using this function ! * * @param element a pointer on the element to be added */ void shiftRef(T* element); /** * pop an element from the list. The element is removed from * the end of the list and is returned. Returns NULL if the list * is empty * * @returns The element that has been removed */ T* pop(); /** * unshift an element from the list. The element is removed from * the begin of the list and is returned. Returns NULL if the list * is empty * * @returns The element that has been removed */ T* unshift(); /** * Append the list given in argument to the end of the list. The * list given in argument is copied using the defaut construcotr * by copy of its element T. * * @param list The list which is append to the end of the current * list. The list will be consumed by the call */ void appendList(FullLinkedList* list); /** * Creates an iterator which controls the linked list. All the access * on the list is blocked until the iterator is destroyed. Provides * read and write access. Can be reduced to a ReadIterator * * @returns an iterator that exclusively accesses the list until * it is destroyed */ Iterator* getIterator(); /** * Creates a iterator which has only readaccess to the list. All * write access to the list is blocked until the iterator is * destroyed. * * @returns an iterator that provides readaccess to the list until * it is destroyed */ ReadIterator* getReadIterator(); /** * Releases the write lock of an readWrite iterator, making it an * ReadIterator. The read lock stays all the time. The original * iterator will be destroyed and cannot be used any more after this * operation. * * @param rwIterator the iterator to release * @returns an iterator with readonly access to the list */ ReadIterator* reduceWriteIterator(Iterator* rwIterator); /***************************************************************************** * PRIVATE METHODS ****************************************************************************/ private: void operatorEqualPrivate(FullLinkedList& newFLL); void emptyItPrivate(); void appendListPrivate(FullLinkedList* list); /** * Locks the List for ReadWrite access. * Unlock with unlockWrite() and unlockRead() (in this * order) or with unlockReadWrite(). */ void lockReadWrite(); /** * Locks the list for Read access. * Unlock with unlockRead(); */ void lockRead(); /** * Unlocks the write mutex only. Read access is * still given. */ void unlockWrite(); /** * Unlocks the read access. The write lock must already * be released. */ void unlockRead(); /** * Completely unlocks the write access. Composition of * functions unlockWrite() and unlockRead(). */ void unlockReadWrite(); /***************************************************************************** * ITERATOR SECTION - INNER CLASSES ****************************************************************************/ public: /** * Allows readaccess to the linked list. Several readers * can exist parallel, but no writer will disturb the * reading. The iterators lock on the list will be removed * when the iterator is deleted. */ class ReadIterator { // these two are necessary for the private constructors friend class FullLinkedList; /*************************************************************************** * PUBLIC METHODS **************************************************************************/ public: /** * Releases all locks that this mutex has acquired. * If the internal variable noReadRelease is set to true, the * readLock is not releases. This allows the reduceWriteIterator * in the FullLinkedList to delete an Iterator without loosing * the readLock. */ virtual ~ReadIterator(); /** * Set the currentElement of the iterator to the first element * of the list */ inline void reset(); /** * Set the currentElement of the iterator to the last element * of the list */ inline void resetToLast(); /** * returns true if there is a current element */ inline bool hasCurrent(); /** * returns true if there is a next element. If the * current element does not exist, false is returned. */ inline bool hasNext(); /** * returns true if there is a previous element. If the * current element does not exist, false is returned. */ inline bool hasPrevious(); /** * Gets the current element. * Return NULL if there is no current element. * A copy of the current element is returned. */ inline T* getCurrent(); /** * Gets the current element. * Return NULL if there is no current element. * A reference of the current element is returned. * This reference is only valid while the iterator exists. * !! Be very carrefull when using this method !! */ inline T* getCurrentRef(); /** * Iterates to the next element if the possible. * A copy of the current element is returned. */ inline T* next(); /** * Iterates to the next element if the possible. * A reference of the current element is returned. * !! Be very carrefull when using this method !! */ inline T* nextRef(); /** * Iterates to the previous element if the possible. * A copy of the current element is returned. */ inline T* previous(); /** * Iterates to the previous element if the possible. * A reference of the current element is returned. * !! Be very carrefull when using this method !! */ inline T* previousRef(); /** * Gets the current length of the list. */ inline unsigned int length(); /*************************************************************************** * PROTECTED METHODS **************************************************************************/ protected: /** * Creates a new ReadIterator. Can only be invoked by * functions of FullLinkedList. Assumes the readMutex is * already locked. Does not lock the readMutex itself */ ReadIterator(FullLinkedList* controlledList); /*************************************************************************** * PROTECTED FIELDS **************************************************************************/ protected: /** * contains the linked list this iterator controlls */ FullLinkedList* linkedList; /** * the current Node of the iterator */ // FullLinkedList::Node* currentNode; Node* currentNode; /** * Controlls the behaviour of unlocking the blocked * mutexes when releaseLocks() is called. This is * initialized to false, as usually all locks should * be released. This value is set to true by the * reduceWriteIterator() to allow the creation of a * new Iterator without releasing the readlock */ bool noReadRelease; }; // End inner class ReadIterator /** * Allows full access on the linked list. This includes write * access as specified in the parentclass ReadIterator as well * as functions to add and remove elements. Can be reduced to * a ReadIterator by the FullLinkedList.reduceWriteIterator() to * release its writeLock. */ class Iterator: public FullLinkedList::ReadIterator { friend class FullLinkedList; /*************************************************************************** * PUBLIC METHODS **************************************************************************/ public: /** * Releases the read- and writeLock of this list. If noReadRelease * in the parent class is set to true, only the writeLock is released. * This allows the construction of a ReadIterator without loosing * synchronisation. */ virtual ~Iterator(); /** * removes the current element from the list. * If the current element doesn't exist, nothing is done. * The new current Element will be the next element in the list, * and NULL if the removed element was the last element of the * list. */ void removeCurrent(); /** * removes the current element from the list and return the current * element. If the current element doesn't exist, nothing is done * and NULL is return. * The new current Element will be the next element in the list, * and NULL if the removed element was the last element of the * list. * * @returns A pointer to a copy of the element that has been removed */ T* removeAndGetCurrent(); /** * inserts a new element after the current element. The * current element is unchanged. If the list is empty, a * new list is created. The current element will be the * new element. * If there is no current element, nothing is done. * A copy of the element is done through the copy constructor of the * element T. * * @param element A pointer to the element that is added */ void insertAfter(T* element); /** * inserts a new element after the current element. The * current element is unchanged. If the list is empty, a * new list is created. The current element will be the * new element. * If there is no current element, nothing is done. * !! Only a reference is copied, use it with special care !! * * @param element A pointer to the element that is added */ void insertAfterRef(T* element); /** * inserts a new element before the current element. * The current element is unchanged. If the list is empty, * a new list is created, the current element is set to the * new element. * If there is no current element, nothing is done. * A copy of the element is done through the copy constructor of the * element T. * * @param element A pointer to the element that is added */ void insertBefore(T* element); /** * inserts a new element before the current element. * The current element is unchanged. If the list is empty, * a new list is created, the current element is set to the * new element. * If there is no current element, nothing is done. * !! Only a reference is copied, use it with special care !! * * @param element A pointer to the element that is added */ void insertBeforeRef(T* element); /*************************************************************************** * PRIVATE METHODS **************************************************************************/ private: /** * Creates a new Iterator. Can only be invoked by * functions of FullLinkedList. Assumes the readWriteMutex is * already locked. Does not lock the readWriteMutex itself */ Iterator(FullLinkedList* controlledList); }; // end of inner class Iterator }; // end of class FullLinkedList /** * Include the implementation for this template. This seems to * work only like this. */ #include "FullLinkedList.cc" #endif // _FULLLINKEDLIST_HH_ LogService-2.7.0/src/utils/LocalTime.cc000644 000765 000765 00000010165 11576373454 021327 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* For getting the current local time in ms since Jan. 1 1970 */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LocalTime.hh" log_time_t getLocalTime() { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); log_time_t ret; ret.sec = tv.tv_sec; ret.msec = tv.tv_usec / 1000; return ret; } LogService-2.7.0/src/utils/LocalTime.hh000644 000765 000765 00000010137 11576373454 021340 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* For getting the current local time in ms since Jan. 1 1970 */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOCALTIME_HH_ #define _LOCALTIME_HH_ #include "LogTypes.hh" #include /** * Gets back the local time in the log_time_t format */ log_time_t getLocalTime(); #endif LogService-2.7.0/src/utils/ORBTools.cc000644 000765 000765 00000042764 11576373454 021133 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A class for putting some ORB functions together - IMPLEMENTATION */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.5 2011/02/07 12:27:42 bdepardo * Correctly declare tracelevel option * * Revision 1.4 2008/07/17 01:03:12 rbolze * make some change to avoid gcc warning * * Revision 1.3 2006/02/17 14:46:55 ecaron * Bug fix: uncompatible syntax with new(char*) * * Revision 1.2 2004/06/01 21:45:58 hdail * Tracking down seg fault in LogService: * - Several strings were created in this file using malloc that are later cleaned * up by omniORB code using delete[]. Since creation and deletion approaches must * match for some non-linux systems, I removed old method of strdup and added new * method of allocation with new char[...] and then copied the data with strcpy. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "ORBTools.hh" #include "omnithread.h" #include #include #include #include using namespace std; #include #include CORBA::ORB_var ORBTools::orb = CORBA::ORB::_nil(); PortableServer::POA_var ORBTools::poa = PortableServer::POA::_nil(); bool ORBTools::init(int argc, char** argv) { ORBTools::orb = CORBA::ORB_init(argc, argv); if (CORBA::is_nil(ORBTools::orb)) { return false; } CORBA::Object_var obj = ORBTools::orb->resolve_initial_references("RootPOA"); if (CORBA::is_nil(obj)) { return false; } ORBTools::poa = PortableServer::POA::_narrow(obj); if (CORBA::is_nil(ORBTools::poa)) { return false; } return true; } bool ORBTools::init(int argc, char** argv, unsigned int tracelevel, unsigned int port) { int myargc = argc; char** myargv = NULL; if (port == 0) { myargc += 2; myargv = new char*[myargc]; for (int i = 0 ; i < myargc - 2 ; i++) { myargv[i] = strdup(argv[i]); } myargv[myargc - 2] = strdup("-ORBtraceLevel"); char* s = new char[6]; sprintf(s, "%u", tracelevel); myargv[myargc - 1] = s; } else { myargc += 4; myargv = new char*[myargc]; for (int i = 0 ; i < myargc - 4 ; i++) { myargv[i] = strdup(argv[i]); } myargv[myargc - 4] = strdup("-ORBtraceLevel"); char* s1 = new char[6]; sprintf(s1, "%u", tracelevel); myargv[myargc - 3] = s1; myargv[myargc - 2] = strdup("-ORBendPoint"); char* s2 = new char[6]; sprintf(s2, "%u", port); myargv[myargc - 1] = s2; } ORBTools::orb = CORBA::ORB_init(myargc, myargv); if (CORBA::is_nil(ORBTools::orb)) { return false; } CORBA::Object_var obj = ORBTools::orb->resolve_initial_references("RootPOA"); if (CORBA::is_nil(obj)) { return false; } ORBTools::poa = PortableServer::POA::_narrow(obj); if (CORBA::is_nil(ORBTools::poa)) { return false; } return true; } bool ORBTools::init() { int myargc = 0; char** myargv = new char*[1]; myargv[0] = strdup(""); ORBTools::orb = CORBA::ORB_init(myargc, myargv); if (CORBA::is_nil(ORBTools::orb)) { return false; } CORBA::Object_var obj = ORBTools::orb->resolve_initial_references("RootPOA"); if (CORBA::is_nil(obj)) { return false; } ORBTools::poa = PortableServer::POA::_narrow(obj); if (CORBA::is_nil(ORBTools::poa)) { return false; } return true; } bool ORBTools::registerServant(const char* contextName, const char* contextKind, const char* name, const char* kind, CORBA::Object* objref) { if (CORBA::is_nil(ORBTools::orb)) { return false; } if (objref == NULL) { return false; } CosNaming::NamingContext_var rootContext; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "The NamingService could not be resolved (InvalidName)\n"; return false; } catch (CORBA::SystemException& ex) { cerr << "The NamingService could not be resolved (SystemException)\n"; return false; } try { CosNaming::Name context; context.length(1); context[0].id = new char[strlen(contextName) + 1]; strcpy(context[0].id,contextName); context[0].kind = new char[strlen(contextKind) + 1]; strcpy(context[0].kind,contextKind); CosNaming::NamingContext_var testContext; try { testContext = rootContext->bind_new_context(context); } catch (CosNaming::NamingContext::AlreadyBound& ex) { CORBA::Object_var obj; obj = rootContext->resolve(context); testContext = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(testContext)) { cerr << "Failed to narrow naming context.\n"; return false; } } CosNaming::Name object; object.length(1); object[0].id = new char[strlen(name) + 1]; strcpy(object[0].id,name); object[0].kind = new char[strlen(kind) + 1]; strcpy(object[0].kind,kind); try { testContext->bind(object, objref); } catch (CosNaming::NamingContext::AlreadyBound& ex) { testContext->rebind(object, objref); } } catch (CORBA::COMM_FAILURE& ex) { cerr << "Caught system exception COMM_FAILURE -- unable to contact the " << "naming service.\n"; return false; } catch (CORBA::SystemException& ex) { cerr << "Caught a CORBA::SystemException while using the naming service.\n"; return false; } return true; } bool ORBTools::registerServant(const char* name, const char* kind, CORBA::Object* objref) { if (CORBA::is_nil(ORBTools::orb)) { return false; } if (objref == NULL) { return false; } CosNaming::NamingContext_var rootContext; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "The NamingService could not be resolved (InvalidName)\n"; return false; } catch (CORBA::SystemException& ex) { cerr << "The NamingService could not be resolved (SystemException)\n"; return false; } try { CosNaming::Name objectName; objectName.length(1); objectName[0].id = strdup(name); objectName[0].kind = strdup(kind); try { rootContext->bind(objectName, objref); } catch (CosNaming::NamingContext::AlreadyBound& ex) { rootContext->rebind(objectName, objref); } } catch (CORBA::COMM_FAILURE& ex) { cerr << "Caught system exception COMM_FAILURE -- unable to contact the " << "naming service.\n"; return false; } catch (CORBA::SystemException& ex) { cerr << "Caught a CORBA::SystemException while using the naming service.\n"; return false; } return true; } bool ORBTools::activateServant(PortableServer::ServantBase* object) { if (CORBA::is_nil(ORBTools::orb)) { return false; } ORBTools::poa->activate_object(object); object->_remove_ref(); return true; } bool ORBTools::activatePOA() { if (CORBA::is_nil(ORBTools::orb)) { return false; } PortableServer::POAManager_var pman = ORBTools::poa->the_POAManager(); pman->activate(); return true; } bool ORBTools::unregisterServant(const char* contextName, const char* contextKind, const char* name, const char* kind) { if (CORBA::is_nil(ORBTools::orb)) { return false; } CosNaming::NamingContext_var rootContext, context; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "Service required is invalid [does not exist].\n"; return false; } CosNaming::Name cosName; cosName.length(1); cosName[0].id = strdup(contextName); cosName[0].kind = strdup(contextKind); try { try { CORBA::Object_var tmpobj; tmpobj = rootContext->resolve(cosName); context = CosNaming::NamingContext::_narrow(tmpobj); if (CORBA::is_nil(context)) { cerr << "Failed to narrow the naming context.\n"; return false; } } catch(CosNaming::NamingContext::NotFound& ex) { cerr << "Cannot find object\n"; return false; } catch (...) { cerr << "System exception caught while using the naming service\n"; return false; } cosName[0].id = strdup(name); cosName[0].kind = strdup(kind); context->unbind(cosName); } catch (CORBA::COMM_FAILURE& ex) { cerr << "System exception caught (COMM_FAILURE), unable to connect to " << "the CORBA name server\n"; return false; } catch (omniORB::fatalException& ex) { throw; } catch (...) { cerr << "System exception caught while using the naming service\n"; return false; } return true; } bool ORBTools::unregisterServant(const char* name, const char* kind) { if (CORBA::is_nil(ORBTools::orb)) { return false; } CosNaming::NamingContext_var rootContext, context; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "Service required is invalid [does not exist].\n"; return false; } CosNaming::Name cosName; cosName.length(1); cosName[0].id = strdup(name); cosName[0].kind = strdup(kind); try { rootContext->unbind(cosName); } catch (CORBA::COMM_FAILURE& ex) { cerr << "System exception caught (COMM_FAILURE), unable to connect to " << "the CORBA name server\n"; return false; } catch (omniORB::fatalException& ex) { throw; } catch (...) { cerr << "System exception caught while using the naming service\n"; return false; } return true; } bool ORBTools::findServant(const char* contextName, const char* contextKind, const char* name, const char* kind, CORBA::Object*& objref) { if (CORBA::is_nil(ORBTools::orb)) { return false; } objref = NULL; CosNaming::NamingContext_var rootContext; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "Service required is invalid [does not exist].\n"; return false; } CosNaming::Name cosName; cosName.length(2); cosName[0].id = contextName; cosName[0].kind = contextKind; cosName[1].id = name; cosName[1].kind = kind; try { objref = rootContext->resolve(cosName); } catch(CosNaming::NamingContext::NotFound& ex) { cerr << "Context for " << name << " not found\n"; return false; } catch (CORBA::COMM_FAILURE& ex) { cerr << "System exception caught (COMM_FAILURE): unable to connect to " << "the CORBA name server.\n"; return false; } catch(omniORB::fatalException& ex) { throw; } catch (...) { cerr << "System exception caught while using the naming service\n"; return false; } return true; } bool ORBTools::findServant(const char* name, const char* kind, CORBA::Object*& objref) { if (CORBA::is_nil(ORBTools::orb)) { return false; } objref = NULL; CosNaming::NamingContext_var rootContext; try { CORBA::Object_var obj; obj = ORBTools::orb->resolve_initial_references("NameService"); try { rootContext = CosNaming::NamingContext::_narrow(obj); } catch(CORBA::SystemException& ex) { cerr << "Failed to narrow the root naming context.\n"; return false; } } catch (CORBA::ORB::InvalidName& ex) { cerr << "Service required is invalid [does not exist].\n"; return false; } CosNaming::Name cosName; cosName.length(1); cosName[0].id = strdup(name); cosName[0].kind = strdup(kind); try { objref = rootContext->resolve(cosName); } catch(CosNaming::NamingContext::NotFound& ex) { cerr << "Context for " << name << " not found\n"; return false; } catch (CORBA::COMM_FAILURE& ex) { cerr << "System exception caught (COMM_FAILURE): unable to connect to " << "the CORBA name server.\n"; return false; } catch(omniORB::fatalException& ex) { throw; } catch (...) { cerr << "System exception caught while using the naming service\n"; return false; } return true; } static void make_read_block() { long file_flags; fd_set fs; FD_SET(STDIN_FILENO, &fs); file_flags = 0; fcntl(STDIN_FILENO, F_SETFL, file_flags); } static void make_read_nonblock() { long file_flags; fd_set fs; FD_ZERO(&fs); FD_SET(STDIN_FILENO, &fs); file_flags = fcntl(STDIN_FILENO, F_GETFL); if (file_flags == -1) file_flags = 0; fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK|file_flags); } bool ORBTools::listen(char stopLowercase, char stopUppercase) { if (CORBA::is_nil(ORBTools::orb)) { return false; } bool again = true; char c = '\0'; make_read_nonblock(); while (again) { omni_thread::sleep(0, 500000000); // sleep 500ms c = fgetc(stdin); again = (c != stopLowercase && c != stopUppercase); } make_read_block(); return true; } bool ORBTools::kill() { if (CORBA::is_nil(ORBTools::orb)) { return false; } ORBTools::orb->shutdown(true); ORBTools::orb->destroy(); return true; } LogService-2.7.0/src/utils/ORBTools.hh000644 000765 000765 00000021621 11576373454 021132 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A class for putting some ORB functions together - HEADER */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _ORBTOOLS_HH_ #define _ORBTOOLS_HH_ #include "LogTypes.hh" class ORBTools { public: /** * Initialize the CORBA ORB. * See CORBA documentation for all possibles parameters. * @param argc Number of parameters to pass to the ORB * @param argv Array of parameters to pass to the ORB * @return true if the operation succeed */ static bool init(int argc, char** argv); /** * Initialize the CORBA ORB. * @param argc Number of parameters to pass to the ORB * @param argv Array of parameters to pass to the ORB * @param tracelevel The tracelevel of the ORB (from 0 to 50) * @param port the port to use for listenning servants (0 = default random) * @return true if the operation succeed */ static bool init(int argc, char** argv, unsigned int tracelevel, unsigned int port = 0); /** * Initialize the CORBA ORB. * None argument is set, usefull for tests * @return true if the operation succeed */ static bool init(); /** * Register a servant to the Namming Service within a specific context and * name. Do not activate the servant. * @param contextName Name of the new context * @param contextKind Kind of the new context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the _this() * function) * @return true if the operation succeed */ static bool registerServant(const char* contextName, const char* contextKind, const char* name, const char* kind, CORBA::Object* objref); /** * Register a servant to the Namming Service within the default context and * with a specific name. Do not activate the servant. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the _this() * function) * @return true if the operation succeed */ static bool registerServant(const char* name, const char* kind, CORBA::Object* objref); /** * Activate a servant. * After this, the IOR of the servant is known by the POA. * @param object The implementation of a servant * @return true if the operation succeed */ static bool activateServant(PortableServer::ServantBase* object); /** * Activate the POA (Portable Object Adaptor). * After this, all servants registered are accessible * @return true if the operation succeed */ static bool activatePOA(); /** * Unregister a servant to the Namming Service within a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ static bool unregisterServant(const char* contextName, const char* contextKind, const char* name, const char* kind); /** * Unregister a servant to the Namming Service within the default context and * with a specific name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ static bool unregisterServant(const char* name, const char* kind); /** * Find a servant by asking the Namming Service with a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The new servant found (check the return value to be sure * that the reference is correct) * @return true if the operation succeed */ static bool findServant(const char* contextName, const char* contextKind, const char* name, const char* kind, CORBA::Object*& objref); /** * Find a servant by asking the Namming Service with the default context and * name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The new servant found (check the return value to be sure * that the reference is correct) * @return true if the operation succeed */ static bool findServant(const char* name, const char* kind, CORBA::Object*& objref); /** * Make the thread to listen for a incomming connection to a servant. * This function will return if the user enters a specific key. * @param stopLowercase character to hit for stopping the listen function * @param stopUppercase character to hit for stopping the listen function * @return true if the operation succeed */ static bool listen(char stopLowercase, char stopUppercase); /** * Shutdown and destroy the ORB * @return true if the operation succeed */ static bool kill(); static CORBA::ORB_var orb; static PortableServer::POA_var poa; }; #endif LogService-2.7.0/src/tester/CMakeLists.txt000644 000765 000765 00000000720 11576373454 022051 0ustar00bdepardobdepardo000000 000000 INCLUDE_DIRECTORIES( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_BINARY_DIR}/src/idl ${LOGSERVICE_SOURCE_DIR}/src/utils ${LOGSERVICE_SOURCE_DIR}/src/monitor ) ADD_EXECUTABLE( testSystem ComponentConfigurator_impl.cc PassiveComponent.cc PassiveTool.cc ToolMsgReceiver_impl.cc testSystem.cc ) TARGET_LINK_LIBRARIES( testSystem LogServiceIDL LogServiceUtils LogServiceMonitor ${OMNIORB4_LIBRARIES} ) INSTALL( TARGETS testSystem DESTINATION bin ) LogService-2.7.0/src/tester/ComponentConfigurator_impl.cc000644 000765 000765 00000012017 11576373454 025170 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ComponentConfigurator implementation that stores actual filter */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2007/08/31 16:41:18 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "ComponentConfigurator_impl.hh" #include "stdio.h" ComponentConfigurator_impl::ComponentConfigurator_impl(tag_list_t* currentCfg) { currentConfig = currentCfg; } ComponentConfigurator_impl::~ComponentConfigurator_impl() { } void ComponentConfigurator_impl::setTagFilter(const tag_list_t& tagList) { (*currentConfig) = tagList; } void ComponentConfigurator_impl::addTagFilter(const tag_list_t& tagList) { printf("ERROR: the ComponentConfigurator_impl is not sufficiently implemented\n"); } void ComponentConfigurator_impl::removeTagFilter(const tag_list_t& tagList) { printf("ERROR: the ComponentConfigurator_impl is not sufficiently implemented\n"); } void ComponentConfigurator_impl::test() { } LogService-2.7.0/src/tester/ComponentConfigurator_impl.hh000644 000765 000765 00000011644 11576373455 025210 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ComponentConfigurator implementation that stores actual filter */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2007/08/31 16:41:18 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _COMPONENTCONFIGURATOR_IMPL_HH_ #define _COMPONENTCONFIGURATOR_IMPL_HH_ #include "LogComponent.hh" class ComponentConfigurator_impl: public POA_ComponentConfigurator, public PortableServer::RefCountServantBase { public: ComponentConfigurator_impl(tag_list_t* currentConfig); virtual ~ComponentConfigurator_impl(); virtual void setTagFilter(const tag_list_t& tagList); virtual void addTagFilter(const tag_list_t& tagList); virtual void removeTagFilter(const tag_list_t& tagList); virtual void test(); tag_list_t* currentConfig; }; #endif LogService-2.7.0/src/tester/config.cfg000644 000765 000765 00000000217 11576373454 021240 0ustar00bdepardobdepardo000000 000000 [General] [DynamicTagList] DYNAMIC [StaticTagList] STATIC [UniqueTagList] UNIQUE1 UNIQUE2 [VolatileTagList] VOLATILE1 VOLATILE2 VOLATILE3 LogService-2.7.0/src/tester/PassiveComponent.cc000644 000765 000765 00000021011 11576373454 023111 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Encapsulates Component functionality for testing */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2008/07/17 01:03:12 rbolze * make some change to avoid gcc warning * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "PassiveComponent.hh" #include "LocalTime.hh" #include #include /** * Some little helpers */ bool isIncludedTagList(tag_list_t* t1, tag_list_t* t2) { bool found; for(unsigned int i=0; i < t1->length(); i++) { // find a corresponding tag for each tag in list 1 found = false; for (unsigned int j=0; j < t2->length(); j++) { if (strcmp((*t1)[i],(*t2)[j]) == 0) found = true; } if (!found) return false; } return true; } bool isEqualTagList(tag_list_t* t1, tag_list_t* t2) { if (!isIncludedTagList(t1,t2)) return false; if (!isIncludedTagList(t2,t1)) return false; return true; } void printTagList(const char* s, tag_list_t* t) { printf("%s",s); for (unsigned int i=0; i < t->length(); i++) { printf("<%s>",(char*)(*t)[i]); } printf("\n"); } PassiveComponent::PassiveComponent() { myCC = new ComponentConfigurator_impl(¤tConfig); } PassiveComponent::~PassiveComponent() { } void PassiveComponent::activate(PortableServer::POA_var poa, LogCentralComponent_var aLCCref) { myCCid = poa->activate_object(myCC); aCCref = myCC->_this(); myCC->_remove_ref(); myCC = NULL; this->aLCCref = aLCCref; } void PassiveComponent::checkConnect(const char* componentName,const char* hostName,const char* msg, int retValExpected, tag_list_t expectedConfig, bool* success) { int retVal; bool retCorrect = true; bool icfgCorrect = true; tag_list_t initialConfig; this->componentName = CORBA::string_dup(componentName); retVal = aLCCref->connectComponent(this->componentName, hostName, msg, aCCref, getLocalTime(), initialConfig); if (retVal != retValExpected) { retCorrect = false; } if (!isEqualTagList(&expectedConfig,&initialConfig)) { icfgCorrect = false; } if (!(retCorrect && icfgCorrect)) { printf("ERROR: ConnectComponent('%s') did not meet expectations\n", (char*)this->componentName); if (!retCorrect) { printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); } if (!icfgCorrect) { printf(" Initial Config is not correct\n"); printTagList(" returned config: ", &initialConfig); printTagList(" expected config: ", &expectedConfig); } *success = false; } // dont forget to set initial config if everything is correct currentConfig = initialConfig; this->expectedConfig = expectedConfig; } void PassiveComponent::checkDisconnect(const char* msg, bool* success) { checkDisconnect(this->componentName, msg, LS_OK, success); } void PassiveComponent::checkDisconnect(const char* componentName,const char* msg, int retValExpected, bool* success) { int retVal; retVal = aLCCref->disconnectComponent(componentName, msg); if (retVal != retValExpected) { printf("ERROR: DisconnectComponent('%s') did not meet expectations\n", componentName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveComponent::addMessage(const char* tag,const char* msg) { log_msg_t logMsg; logMsg.componentName = CORBA::string_dup(componentName); logMsg.tag = CORBA::string_dup(tag); logMsg.msg = CORBA::string_dup(msg); logMsg.time = getLocalTime(); addMessage(logMsg); } void PassiveComponent::addMessage(const log_msg_t logMsg) { CORBA::Long len; len = logMsgBuf.length(); logMsgBuf.length(len+1); logMsgBuf[len] = logMsg; } void PassiveComponent::sendMsgBuf() { aLCCref->sendBuffer(logMsgBuf); logMsgBuf.length(0); } void PassiveComponent::setExpectedConfig(tag_list_t expectedConfig) { this->expectedConfig = expectedConfig; } void PassiveComponent::addExpectedConfig(const char* tag) { CORBA::ULong i; i=expectedConfig.length(); expectedConfig.length(i+1); expectedConfig[i]=CORBA::string_dup(tag); } void PassiveComponent::checkConfig(bool* success) { if (!isEqualTagList(¤tConfig, &expectedConfig)) { printf("ERROR: component '%s' does not meet expectations\n",(char*)componentName); printf(" TagFilter is not correct\n"); printTagList(" current config: ",¤tConfig); printTagList(" expected config: ",&expectedConfig); *success = false; } } LogService-2.7.0/src/tester/PassiveComponent.hh000644 000765 000765 00000013041 11576373455 023130 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Provides functionality to test the complete LogCentral system */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2008/07/17 01:03:12 rbolze * make some change to avoid gcc warning * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _PASSIVECOMPONENT_HH_ #define _PASSIVECOMPONENT_HH_ #include "ComponentConfigurator_impl.hh" #include "LogTypes.hh" #include "LogComponent.hh" #include "LocalTime.hh" /** * Encapsulates all component operations. Each operation has an expected * result. Any other result will be treated as error. A message will * be printed and the function will set the provided bool to false. * Results of methods that will be called by the Monitor are stored and * can be verified with the same mechanism from the main programm. */ class PassiveComponent { public: PassiveComponent(); ~PassiveComponent(); void activate(PortableServer::POA_var poa, LogCentralComponent_var aLCCref); void checkConnect(const char* componentName,const char* hostName,const char* msg, int retValExpected, tag_list_t expectedConfig, bool* success); void checkDisconnect(const char* msg, bool* success); void checkDisconnect(const char* componentName,const char* msg, int retValExpected, bool* success); void addMessage(const char* tag,const char* msg); void addMessage(log_msg_t logMsg); void sendMsgBuf(); void setExpectedConfig(tag_list_t expectedConfig); void addExpectedConfig(const char* tag); void checkConfig(bool* success); private: CORBA::String_var componentName; ComponentConfigurator_impl* myCC; PortableServer::ObjectId_var myCCid; ComponentConfigurator_var aCCref; LogCentralComponent_var aLCCref; tag_list_t currentConfig; tag_list_t expectedConfig; log_msg_buf_t logMsgBuf; }; #endif LogService-2.7.0/src/tester/PassiveTool.cc000644 000765 000765 00000023011 11576373455 022067 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Encapsulates Tool functionality for testing */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2011/02/04 15:37:52 bdepardo * Reduce variable scope * * Revision 1.2 2008/07/17 01:03:12 rbolze * make some change to avoid gcc warning * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "PassiveTool.hh" #include /** * some little helpers */ void printMsg(const char* s, log_msg_t msg) { printf("%s",s); printf("msg from '%s': %s (%s)\n", (char*)msg.componentName, (char*)msg.msg, (char*)msg.tag); } void printMsgBuf(const char* s, log_msg_buf_t msgBuf) { if (msgBuf.length()==0) { printf("%s\n",s); } for (CORBA::ULong i=0; iactivate_object(myTMR); aTMRref = myTMR->_this(); myTMR->_remove_ref(); myTMR = NULL; this->aLCTref = aLCTref; } void PassiveTool::checkConnect(const char* toolName, int retValExpected, bool* success) { int retVal; this->toolName = CORBA::string_dup(toolName); retVal = aLCTref->connectTool(this->toolName, aTMRref); if (retVal != retValExpected) { printf("ERROR: ConnectTool('%s') did not meet expectations\n", (char*)this->toolName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveTool::checkDisconnect(bool* success) { checkDisconnect(toolName, LS_OK, success); } void PassiveTool::checkDisconnect(const char* toolName, int retValExpected, bool* success) { int retVal; retVal = aLCTref->disconnectTool(toolName); if (retVal != retValExpected) { printf("ERROR: DisconnectTool('%s') did not meet expectations\n", toolName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveTool::checkAddFilter(filter_t filter, bool* success) { checkAddFilter(toolName, filter, LS_OK, success); } void PassiveTool::checkAddFilter(const char* toolName, filter_t filter, int retValExpected, bool* success) { int retVal; retVal = aLCTref->addFilter(toolName, filter); if (retVal != retValExpected) { printf("ERROR: addFilter '%s' for tool '%s' did not meet expectations\n", (char*)filter.filterName, toolName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveTool::checkRemoveFilter(const char* filterName, bool* success) { checkRemoveFilter(toolName, filterName, LS_OK, success); } void PassiveTool::checkRemoveFilter(const char* toolName,const char* filterName, int retValExpected, bool* success) { int retVal; retVal = aLCTref->removeFilter(toolName, filterName); if (retVal != retValExpected) { printf("ERROR: removeFilter '%s' for tool '%s' did not meet expectations\n", filterName, toolName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveTool::checkFlushAllFilters(bool* success) { checkFlushAllFilters(toolName, LS_OK, success); } void PassiveTool::checkFlushAllFilters(const char* toolName, int retValExpected, bool* success) { int retVal; retVal = aLCTref->flushAllFilters(toolName); if (retVal != retValExpected) { printf("ERROR: flushAllFilters for tool '%s' did not meet expectations\n", toolName); printf(" Errorcode is not correct\n"); printf(" returned value: %d\n", retVal); printf(" expected value: %d\n", retValExpected); *success = false; } } void PassiveTool::setExpectedMsgBuf(log_msg_buf_t expectedMsgBuf) { this->expectedMsgBuf = expectedMsgBuf; } void PassiveTool::addExpectedMsg(const char* componentName,const char* msg,const char* tag) { log_msg_t logMsg; logMsg.componentName = CORBA::string_dup(componentName); logMsg.msg = CORBA::string_dup(msg); logMsg.tag = CORBA::string_dup(tag); addExpectedMsg(logMsg); } void PassiveTool::addExpectedMsg(log_msg_t msg) { CORBA::ULong i; i = expectedMsgBuf.length(); expectedMsgBuf.length(i+1); expectedMsgBuf[i] = msg; } void PassiveTool::checkMsgBuf(bool* success) { bool bufCorrect; bufCorrect = true; if (receivedMsgBuf.length() != expectedMsgBuf.length()) { bufCorrect = false; } else { // buffers have equal length, we can compare each element bool msgCorrect; for (CORBA::ULong i=0; i < receivedMsgBuf.length(); i++) { msgCorrect = true; if (strcmp(receivedMsgBuf[i].componentName,expectedMsgBuf[i].componentName) != 0) { msgCorrect = false; } if (strcmp(receivedMsgBuf[i].tag, expectedMsgBuf[i].tag) != 0) { msgCorrect = false; } if (strcmp(receivedMsgBuf[i].msg, expectedMsgBuf[i].msg) != 0) { msgCorrect = false; } // dont check for the time if (msgCorrect == false) { bufCorrect = false; break; } } } if (!bufCorrect) { printf("ERROR: tool '%s' does not meet expectations\n", (char*)toolName); printf(" MsgBuffer is not correct\n"); printf(" received msgBuf:\n"); printMsgBuf(" ",receivedMsgBuf); printf(" expected msgBuf:\n"); printMsgBuf(" ",expectedMsgBuf); *success = false; } // reset the buffers expectedMsgBuf.length(0); receivedMsgBuf.length(0); } LogService-2.7.0/src/tester/PassiveTool.hh000644 000765 000765 00000013416 11576373455 022111 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Provides functionality to test the complete LogCentral system */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2008/07/17 01:03:12 rbolze * make some change to avoid gcc warning * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _PASSIVETOOL_HH_ #define _PASSIVETOOL_HH_ #include "ToolMsgReceiver_impl.hh" #include "LogTypes.hh" #include "LogTool.hh" /** * Encapsulates all tool operations. Each operation has an expected * result. Any other result will be treated as error. A message will * be printed and the function will set the provided bool to false. * Results of methods that will be called by the Monitor are stored and * can be verified with the same mechanism from the main programm. */ class PassiveTool { public: PassiveTool(); ~PassiveTool(); void activate(PortableServer::POA_var poa, LogCentralTool_var aLCTref); void checkConnect(const char* toolName, int retValExpected, bool* success); void checkDisconnect(bool* success); void checkDisconnect(const char* toolName, int retValExpected, bool* success); void checkAddFilter(filter_t filter, bool* success); void checkAddFilter(const char* toolName, filter_t filter, int retValExpected, bool* success); void checkRemoveFilter(const char* filterName, bool* success); void checkRemoveFilter(const char* toolName,const char* filterName, int retValExpected, bool* success); void checkFlushAllFilters(bool* success); void checkFlushAllFilters(const char* toolName, int retValExpected, bool* success); void setExpectedMsgBuf(log_msg_buf_t expectedMsgBuf); void addExpectedMsg(const char* componentName,const char* msg,const char* tag); void addExpectedMsg(log_msg_t msg); void checkMsgBuf(bool* success); private: CORBA::String_var toolName; ToolMsgReceiver_impl* myTMR; PortableServer::ObjectId_var myTMRid; ToolMsgReceiver_var aTMRref; LogCentralTool_var aLCTref; log_msg_buf_t expectedMsgBuf; log_msg_buf_t receivedMsgBuf; }; #endif LogService-2.7.0/src/tester/testSystem.cc000644 000765 000765 00000102531 11576373455 022010 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Tests the LogCentral internal functionality */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include #include #include #include using namespace std; // "extern" servants #include "PassiveTool.hh" #include "PassiveComponent.hh" // idl #include "LogTypes.hh" #include "LogTool.hh" #include "LogComponent.hh" // monitor components #include "LogCentralTool_impl.hh" #include "LogCentralComponent_impl.hh" #include "ToolList.hh" #include "ComponentList.hh" #include "SimpleFilterManager.hh" #include "FilterManagerInterface.hh" #include "StateManager.hh" #include "Options.hh" #include "ReadConfig.hh" #include "LocalTime.hh" #include "TimeBuffer.hh" // threads #include "SendThread.hh" #include "CoreThread.hh" #define COMP_COUNT 5 #define TOOL_COUNT 5 #define TEST_COUNT 10 int main(int argc, char** argv) { printf("\n"); printf("LogCentral Test\n"); printf("===============================================================\n"); printf("This programm tests the complete LogCentral system by creating \n"); printf("and connecting all components properly. It then launches \n"); printf("certain tests and assures the results match the expectations. \n"); printf("\n"); /** * Systemcomponents */ ToolList* toolList; ComponentList* componentList; ReadConfig* readConfig; tag_list_t* stateTags; tag_list_t* allTags; StateManager* stateManager; SimpleFilterManager* simpleFilterManager; TimeBuffer* timeBuffer; LogCentralTool_impl* myLCT; PortableServer::ObjectId_var myLCTid; LogCentralTool_var aLCTref; LogCentralComponent_impl* myLCC; PortableServer::ObjectId_var myLCCid; LogCentralComponent_var aLCCref; SendThread* sendThread; CoreThread* coreThread; // build system bool success; toolList = new ToolList; componentList = new ComponentList; readConfig = new ReadConfig("config.cfg",&success); readConfig->parse(); stateTags = readConfig->getStateTags(); allTags = readConfig->getAllTags(); stateManager = new StateManager(readConfig,&success); simpleFilterManager = new SimpleFilterManager(toolList, componentList, stateTags); timeBuffer = new TimeBuffer(); sendThread = new SendThread(toolList); coreThread = new CoreThread(timeBuffer, stateManager, simpleFilterManager, toolList); myLCT = new LogCentralTool_impl(toolList, componentList, simpleFilterManager, stateManager, allTags); myLCC = new LogCentralComponent_impl(componentList, simpleFilterManager, timeBuffer); delete allTags; delete stateTags; delete readConfig; /** * Testcomponents */ PassiveTool testTool[TOOL_COUNT]; PassiveComponent testComp[COMP_COUNT]; /** * Start ORB and initialize Servants */ CORBA::ORB_ptr orb = CORBA::ORB_init(argc , argv, "omniORB4"); CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow(obj); // LogCentralTool_impl myLCTid = poa->activate_object(myLCT); aLCTref = myLCT->_this(); myLCT->_remove_ref(); myLCT = NULL; // LogCentralComponent_impl myLCCid = poa->activate_object(myLCC); aLCCref = myLCC->_this(); myLCC->_remove_ref(); myLCC = NULL; for (int i=0; ithe_POAManager(); pman->activate(); // start our threads coreThread->startThread(); sendThread->startThread(); /************************************** * Do Tests here... **************************************/ // create some basic tagLists and configs for all tests char strBuf[50]; char strBuf2[50]; tag_list_t initialConfig; initialConfig.length(5); initialConfig[0] = CORBA::string_dup("DYNAMIC_START"); initialConfig[1] = CORBA::string_dup("DYNAMIC_STOP"); initialConfig[2] = CORBA::string_dup("STATIC"); initialConfig[3] = CORBA::string_dup("UNIQUE1"); initialConfig[4] = CORBA::string_dup("UNIQUE2"); tag_list_t allConfig; allConfig.length(1); allConfig[0] = CORBA::string_dup("*"); filter_t filterAll; filterAll.filterName = CORBA::string_dup("filterAll"); filterAll.tagList.length(1); filterAll.tagList[0] = CORBA::string_dup("*"); filterAll.componentList.length(1); filterAll.componentList[0] = CORBA::string_dup("*"); filter_t filterComponent[COMP_COUNT]; for (int i=0; istopThread(); printf("Stop sendThread\n"); sendThread->stopThread(); /** * Shutdown and delete the orb */ printf("Shutdown the ORB\n"); orb->shutdown(true); printf("Destroy the ORB\n"); orb->destroy(); /** * Delete internal components (Servants are deleted by the ORB) */ printf("Delete the TimeBuffer\n"); delete timeBuffer; printf("Delete the SimpleFilterManager\n"); delete simpleFilterManager; printf("Delete the StateManager\n"); delete stateManager; printf("Delete the ComponentList\n"); delete componentList; printf("Delete the ToolList\n"); delete toolList; printf("All done\n"); } LogService-2.7.0/src/tester/ToolMsgReceiver_impl.cc000644 000765 000765 00000010607 11576373455 023720 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ToolMsgReceiver implementation that stores incoming messages */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "ToolMsgReceiver_impl.hh" #include "stdio.h" ToolMsgReceiver_impl::ToolMsgReceiver_impl(log_msg_buf_t* rcvdBuf) { receivedBuf = rcvdBuf; } ToolMsgReceiver_impl::~ToolMsgReceiver_impl() { } void ToolMsgReceiver_impl::sendMsg(const log_msg_buf_t& msgBuf) { int offset; offset = receivedBuf->length(); receivedBuf->length(receivedBuf->length() + msgBuf.length()); for (unsigned int i=0; i < msgBuf.length(); i++) { (*receivedBuf)[i+offset] = msgBuf[i]; } } LogService-2.7.0/src/tester/ToolMsgReceiver_impl.hh000644 000765 000765 00000010462 11576373455 023731 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ToolMsgReceiver implementation that stores incoming messages */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _TOOLMSGRECEIVER_IMPL_HH_ #define _TOOLMSGRECEIVER_IMPL_HH_ #include "LogTool.hh" class ToolMsgReceiver_impl: public POA_ToolMsgReceiver, public PortableServer::RefCountServantBase { public: ToolMsgReceiver_impl(log_msg_buf_t* receivedBuf); ~ToolMsgReceiver_impl(); void sendMsg(const log_msg_buf_t& msgBuf); log_msg_buf_t* receivedBuf; }; #endif LogService-2.7.0/src/monitor/CMakeLists.txt000644 000765 000765 00000003531 11576373450 022231 0ustar00bdepardobdepardo000000 000000 ######### First the LogServiceMonitor library: INCLUDE_DIRECTORIES( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_BINARY_DIR}/src/idl ${LOGSERVICE_SOURCE_DIR}/src/utils ) add_library(LogServiceMonitor STATIC ${LOGSERVICE_SOURCE_DIR}/src/monitor/CoreThread.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/LogCentralComponent_impl.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/LogCentralTool_impl.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/LogOptions.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/ReadConfig.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/SendThread.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/SimpleFilterManager.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/StateManager.cc ${LOGSERVICE_SOURCE_DIR}/src/monitor/TimeBuffer.cc ) set (binary ${binary} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/CoreThread.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/LogCentralComponent_impl.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/LogCentralTool_impl.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/LogOptions.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/ReadConfig.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/SendThread.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/SimpleFilterManager.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/StateManager.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogServiceMonitor.dir/TimeBuffer.cc.o PARENT_SCOPE ) add_dependencies (LogServiceMonitor LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ) TARGET_LINK_LIBRARIES( LogServiceMonitor LogServiceUtils LogCorba ${OMNIORB4_LIBRARIES} ) ######### Then the LogCentral executable: ADD_EXECUTABLE( LogCentral LogCentral.cc ) TARGET_LINK_LIBRARIES( LogCentral LogForwarderUtils ) INSTALL( TARGETS LogCentral DESTINATION bin ) LogService-2.7.0/src/monitor/ComponentList.hh000644 000765 000765 00000012277 11576373452 022621 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* defines a list that holds all information on componentes connected to */ /* the new Logservice */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2007/09/03 06:33:24 bdepardo * Removed IOR, it was useless. * * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _COMPONENTLIST_HH_ #define _COMPONENTLIST_HH_ #include "FullLinkedList.hh" #include "LogComponent.hh" /** * All information that is stored for each client. * (In the Moment just the Proxy to make calls to client) */ struct ComponentElement { ComponentConfigurator_var componentConfigurator; CORBA::String_var componentName; }; /** * Define a ComponentList for the Componentelements. * No Elements should be changed without * having a writeLock(Iterator) on the whole * List. */ typedef FullLinkedList ComponentList; // Eventually define a function that takes an iterator // and a componentName as input and sets the iterators // currentElement to the component with the given name ? #endif LogService-2.7.0/src/monitor/config.cfg000644 000765 000765 00000000173 11576373450 021416 0ustar00bdepardobdepardo000000 000000 # an empty configuration file for LogService [General] [DynamicTagList] [StaticTagList] [UniqueTagList] [VolatileTagList] LogService-2.7.0/src/monitor/CoreThread.cc000644 000765 000765 00000014155 11576373450 022024 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implementation for the Core thread */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.2 2004/01/13 15:07:15 ghoesch * speeded up message processing after poor results in tests * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "CoreThread.hh" #include "LogTypes.hh" #include "LocalTime.hh" #include "LogOptions.hh" #include using namespace std; CoreThread::CoreThread(TimeBuffer* timeBuffer, StateManager* stateManager, FilterManagerInterface* filterManager, ToolList* toolList): timeBuffer(timeBuffer), stateManager(stateManager), filterManager(filterManager), toolList(toolList), threadRunning(false) { } CoreThread::~CoreThread() { if (this->threadRunning) { this->threadRunning = false; join(NULL); } } void CoreThread::startThread() { if (this->threadRunning) { return; } this->threadRunning = true; start_undetached(); } void CoreThread::stopThread() { if (!this->threadRunning) { return; } this->threadRunning = false; join(NULL); } void* CoreThread::run_undetached(void* params) { log_time_t minAge; log_msg_t* msg = NULL; ToolList::ReadIterator* it = NULL; bool haveMsgs; while (this->threadRunning) { minAge = getLocalTime(); minAge.sec -= LogOptions::CORETHREAD_MINAGE_TIME_SEC; minAge.msec -= LogOptions::CORETHREAD_MINAGE_TIME_MSEC; if (minAge.msec < 0) { minAge.sec--; minAge.msec += 1000; } haveMsgs=true; while (haveMsgs) { msg = this->timeBuffer->get(minAge); if (msg != NULL) { // we have a message if (this->stateManager->check(msg)) { // directly sent it = this->toolList->getReadIterator(); while (it->hasCurrent()) { it->getCurrentRef()->outBuffer.push(msg); it->nextRef(); } delete it; } else { // send to the FilterManager this->filterManager->sendMessageWithFilters(msg); } delete msg; } else { haveMsgs=false; } } sleep(LogOptions::CORETHREAD_SLEEP_TIME_SEC, LogOptions::CORETHREAD_SLEEP_TIME_NSEC); } return NULL; } LogService-2.7.0/src/monitor/CoreThread.hh000644 000765 000765 00000011247 11576373452 022037 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Header for the Core thread */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _CORETHREAD_HH_ #define _CORETHREAD_HH_ #include #include "TimeBuffer.hh" #include "StateManager.hh" #include "FilterManagerInterface.hh" #include "ToolList.hh" class CoreThread:public omni_thread { public: CoreThread(TimeBuffer* timeBuffer, StateManager* stateManager, FilterManagerInterface* filterManager, ToolList* toolList); ~CoreThread(); /** * Start the thread. Return immediately. */ void startThread(); /** * Stop the thread. Return when the thread is stopped. */ void stopThread(); private: void* run_undetached(void* params); private: TimeBuffer* timeBuffer; StateManager* stateManager; FilterManagerInterface* filterManager; ToolList* toolList; bool threadRunning; }; #endif LogService-2.7.0/src/monitor/FilterManagerInterface.hh000644 000765 000765 00000015777 11576373452 024374 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* interface that defines functions that an implementation of a */ /* FilterManager must offer to be notified correctly on systemchanges */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _FILTERMANAGERINTERFACE_HH_ #define _FILTERMANAGERINTERFACE_HH_ #include "LogTypes.hh" #include "ToolList.hh" #include "ComponentList.hh" /** * Interface to the Filtermanager (Abstract class) * The FilterManager keeps track of all attached Components * and of all configured filters. Based on this information, * it can be used to filter incoming Messages and forward * them to the appropriate tools. If tools change their * filters, the FilterManager adjusts the Components output. */ class FilterManagerInterface { public: /** * Notify the manager that a new tool has connected. * The Tool must already exist in the toolList. iter must * be an ReadIterator to the toolList. It should be the * same iterator that was used for inserting the tool. */ virtual void toolConnect(const char* toolName, ToolList::ReadIterator* iter) = 0; /** * Notify the manager that a tool is about disconnects. * This function must be called right before deleting the * tool from the list, as Filtermanager will delete all its * internal data on this tool (including remaining filters). * The iterator passed should be the iterator used for * deleting the tool. */ virtual void toolDisconnect(const char* toolName, ToolList::ReadIterator* iter) = 0; /** * Notify the manager that a new filter has been added. * the filter must already exist in the toollist. A * iterator used for inserting should be passed. */ virtual void addFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter) = 0; /** * Notify the manager that a filter will be removed. * This function should be called right before deleting * the filter. The iterator for deleting the filter should * be passed. */ virtual void removeFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter) = 0; /** * Notify the manager that all filters for a certain * tool will be removed. The filtermanager might implement * this more efficient that removing each filter one by * one. */ virtual void flushAllFilters(const char* toolName, ToolList::ReadIterator* iter) = 0; /** * Notify the manager that a component connected. * The component should be already in the list, the * corresponding iterator should be passed. */ virtual tag_list_t* componentConnect(const char* componentName, ComponentList::ReadIterator* iter) = 0; /** * Notify the manager that a component will disconnects. * This must happen right before the deletion of the * component. The iterator passed should be the same * iterator used for deleting. */ virtual void componentDisconnect(const char* componentName, ComponentList::ReadIterator* iter) = 0; /** * Forwards a message to all interested Tools. * The message will be checked and stored in the outBuffer * of all tools with a matching filter. */ virtual void sendMessageWithFilters(log_msg_t* message) = 0; }; #endif LogService-2.7.0/src/monitor/LogCentral.cc000644 000765 000765 00000027100 11576373451 022031 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogCentral */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.9 2011/05/13 08:17:52 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.8 2011/04/22 11:44:22 bdepardo * Use a signal handler to handle background option. * This handler catches SIGINT and SIGTERM. * * Revision 1.7 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.6 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.5 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.4 2008/07/17 01:03:11 rbolze * make some change to avoid gcc warning * * Revision 1.3 2004/05/12 12:39:04 hdail * Add support for running services in the background (at a loss of clean * exit with interactive 'Q'). Behavior can be controlled via configure. * * Revision 1.2 2004/01/13 15:11:28 ghoesch * added stdlib.h to compile with omniORB3 * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include #include #include #include #include using namespace std; // idl #include "LogTypes.hh" #include "LogTool.hh" #include "LogComponent.hh" // monitor components #include "LogCentralTool_impl.hh" #include "LogCentralComponent_impl.hh" #include "ToolList.hh" #include "ComponentList.hh" #include "SimpleFilterManager.hh" #include "FilterManagerInterface.hh" #include "StateManager.hh" #include "LogOptions.hh" #include "ReadConfig.hh" #include "LocalTime.hh" #include "TimeBuffer.hh" // threads #include "SendThread.hh" #include "CoreThread.hh" // helpers #include "ORBTools.hh" #include "../LogORBMgr.hh" int main(int argc, char** argv) { printf("\n"); printf("LogCentral system\n"); printf("\n"); /** * Acquire configFileName * - check the environment and the arguments to find the name * of the configfile for ReadConfig */ char* configFileNameDefault = strdup("config.cfg"); char* configFileName; configFileName = NULL; for (int i=0; i < argc; i++) { if (strcmp(argv[i], "-config") == 0) { // user tries to specify -config if ((i+1) < argc) { configFileName = argv[i+1]; } else { printf("Cannot parse parameter of -config. Please use -help\n"); } } if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) { // any idea how to write this better ? printf(" -config FILENAME Reads the config file specified in FILENAME. "); printf("Overrides\n the filename specified in "); printf("$LOGCENTRAL_CONFIG\n"); printf(" -ORBparameter Sets parameters of omniORB as specified "); printf("in the manual\n"); printf(" -help or --help Display this message and exit\n"); printf("\n"); exit(0); } } if (configFileName == NULL) { configFileName = getenv("LOGCENTRAL_CONFIG"); } if (configFileName == NULL) { configFileName = configFileNameDefault; } else { // just print this, if we use a non-default configFile printf("Using config file '%s'\n", configFileName); } // Note: configFileName must not be deleted /** * Systemcomponents */ ToolList* toolList; ComponentList* componentList; ReadConfig* readConfig; tag_list_t* stateTags; tag_list_t* allTags; StateManager* stateManager; SimpleFilterManager* simpleFilterManager; TimeBuffer* timeBuffer; LogCentralTool_impl* myLCT; LogCentralComponent_impl* myLCC; SendThread* sendThread; CoreThread* coreThread; // build system bool success=true; toolList = new ToolList; componentList = new ComponentList; readConfig = new ReadConfig(configFileName, &success); if (!success) { printf("Could not read the config file\n"); exit(1); } if (readConfig->parse() != 0) { printf("Could not parse the config file\n"); exit(1); } stateTags = readConfig->getStateTags(); allTags = readConfig->getAllTags(); // and we need those two for the ORB-initialization unsigned int tracelevel = readConfig->getTracelevel(); unsigned int port = readConfig->getPort(); stateManager = new StateManager(readConfig, &success); if (!success) { printf("Could not initialize the StateManager.\n"); printf("Please check the config file to correct this problem.\n"); exit(1); } simpleFilterManager = new SimpleFilterManager(toolList, componentList, stateTags); timeBuffer = new TimeBuffer(); sendThread = new SendThread(toolList); coreThread = new CoreThread(timeBuffer, stateManager, simpleFilterManager, toolList); myLCT = new LogCentralTool_impl(toolList, componentList, simpleFilterManager, stateManager, allTags); myLCC = new LogCentralComponent_impl(componentList, simpleFilterManager, timeBuffer); delete allTags; delete stateTags; delete readConfig; // ADD ******* LogORBMgr::init(argc, argv); /** * Start ORB and initialize Servants * - check if port/tracelevel are set and initialize ORB correctly */ if (!ORBTools::init(argc, argv, tracelevel, port)) { printf("Could not initialize ORB\n"); exit(1); } if (!ORBTools::activateServant(myLCT)) { printf("Could not activate servants\n"); exit(1); } CORBA::Object* myLCTref = myLCT->_this(); if (!ORBTools::registerServant("LogServiceT", "", "LCT", "", myLCT->_this())) { printf("Could not register the servants at the NamingService\n"); exit(1); } // // Inscription in the naming service // LogORBMgr::getMgr()->bind("LogServiceT", "LCT", // LogORBMgr::getMgr()->getIOR(myLCT->_this()), true); // // Inscription in the others fwdr LogORBMgr::getMgr()->fwdsBind("LogServiceT", "LCT", LogORBMgr::getMgr()->getIOR(myLCT->_this())); if (!ORBTools::activateServant(myLCC)) { printf("Could not activate servants\n"); exit(1); } CORBA::Object* myLCCref = myLCC->_this(); if (!ORBTools::registerServant("LogServiceC", "", "LCC", "", myLCCref)) { printf("Could not register the servants at the NamingService\n"); exit(1); } // // Inscription in the nameing service // LogORBMgr::getMgr()->bind("LogServiceC", "LCC", // LogORBMgr::getMgr()->getIOR(myLCC->_this()), true); // Inscription in the others fwdr LogORBMgr::getMgr()->fwdsBind("LogServiceC", "LCC", LogORBMgr::getMgr()->getIOR(myLCC->_this())); if (!ORBTools::activatePOA()) { printf("Could not activate the POA\n"); exit(1); } coreThread->startThread(); sendThread->startThread(); /** * Run */ printf("LogCentral is running\n"); /* The code to support interactive quit via user input of q or Q is * incompatible with backgrounding the LogCentral process. Use * configure option --enable-background to select which you prefer. */ #ifdef HAVE_BACKGROUND printf("Got background option.\n"); try { LogORBMgr::getMgr()->wait(); } catch (...) { cerr << "Error while exiting the ORBMgr::wait() function" << endl; } # else // HAVE_BACKGROUND printf("Q to quit\n\n"); ORBTools::listen('q', 'Q'); /** * Unregister Servants */ printf("Shutting down...\n\n"); ORBTools::unregisterServant("LogService", "", "LCT", ""); ORBTools::unregisterServant("LogService", "", "LCC", ""); /** * Stop threads */ coreThread->stopThread(); sendThread->stopThread(); /** * Shutdown and delete the orb */ ORBTools::kill(); /** * Delete internal components (Servants are deleted by the ORB) */ delete timeBuffer; delete simpleFilterManager; delete stateManager; delete componentList; delete toolList; # endif // HAVE_BACKGROUND } LogService-2.7.0/src/monitor/LogCentralComponent_impl.cc000644 000765 000765 00000047170 11576373451 024746 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implementation corresponding to the LogComponentComponent interface */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.10 2011/02/04 15:14:26 bdepardo * Initialize members in constructor. * Reduce variable scope. * * Revision 1.9 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.8 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.7 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.6 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.5 2007/09/03 06:33:24 bdepardo * Removed IOR, it was useless. * * Revision 1.4 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.3 2004/06/01 21:39:57 hdail * Tracking down seg fault of LogService: * - Corrected mis-matched malloc / delete * - Corrected error in size of string allocation, and terminated string with \0 * * Revision 1.2 2004/03/02 08:38:16 rbolze * add some information in the IN and OUT messages * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #include "LogCentralComponent_impl.hh" #include "ComponentList.hh" #include "FilterManagerInterface.hh" #include "TimeBuffer.hh" #include "LocalTime.hh" #include "LogOptions.hh" #include "../LogORBMgr.hh" // helpers #include "ORBTools.hh" #include #include #include #include using namespace std; LastPing::LastPing() { this->name = NULL; this->time.sec = 0; this->time.msec = 0; this->timeDifference.sec = 0; this->timeDifference.msec = 0; } LastPing::LastPing(LastPing& newLastPing) { this->name = strdup(newLastPing.name); this->time = newLastPing.time; this->timeDifference = newLastPing.timeDifference; } LastPing::~LastPing() { if (this->name != NULL) { free(this->name); } } LastPing& LastPing::operator=(LastPing& newLastPing) { if (this->name != NULL) { delete this->name; } this->name = strdup(newLastPing.name); this->time = newLastPing.time; this->timeDifference = newLastPing.timeDifference; return *this; } /**************************************************************************** * LogCentralComponent_impl inplementation ****************************************************************************/ LogCentralComponent_impl::LogCentralComponent_impl( ComponentList* componentList, FilterManagerInterface* filterManager, TimeBuffer* timeBuffer) { this->componentList = componentList; this->filterManager = filterManager; this->timeBuffer = timeBuffer; this->lastPings = new LastPings(); this->aliveCheckThread = new AliveCheckThread(this); this->aliveCheckThread->startThread(); } LogCentralComponent_impl::~LogCentralComponent_impl() { delete this->lastPings; this->aliveCheckThread->stopThread(); // stop and (automatically) delete the thread } CORBA::Short LogCentralComponent_impl::connectComponent( char*& componentName, const char* componentHostname, const char* message, const char* compConfigurator, const log_time_t& componentTime, tag_list_t& initialConfig) { if (strcmp(componentName, "*") == 0) { fprintf (stderr, "Bad name componnent. Cannot connect component. \n"); return LS_COMPONENT_CONNECT_BADNAME; } ComponentConfigurator_ptr compoConf = LogORBMgr::getMgr()->resolve (LOGCOMPCONFCTXT, compConfigurator); if (CORBA::is_nil(compoConf)) { fprintf (stderr, "Bad component configurator **** \n"); return LS_COMPONENT_CONNECT_BADCOMPONENTCONFIGURATOR; } // Put this here to be synchronised ComponentList::Iterator* it = componentList->getIterator(); // Generate a unique name if the name is empty if (componentName == NULL || strcmp(componentName, "") == 0) { const char* s = getGeneratedName(componentHostname, it); componentName = CORBA::string_dup(s); } // Check for the previous existence of the component bool lost = false; if (isComponentExists((const char*)componentName, it)) { // check if component is still alive try { it->getCurrentRef()->componentConfigurator->test(); } catch (...) { lost = true; } if (!lost) { cout << "Connection of component '" << componentName << "' failed, " << "component already exists" << endl; delete(it); return LS_COMPONENT_CONNECT_ALREADYEXISTS; } } // Add the component ComponentElement* ce = new ComponentElement(); ce->componentConfigurator = ComponentConfigurator::_narrow(compoConf); ce->componentName = CORBA::string_dup(componentName); delete it; if (lost) { char* msg; msg = (char*) malloc(sizeof(char)*(63 + strlen(componentName))); sprintf(msg, "Component name %s already exists, but component seems to be down", componentName); disconnectComponent(componentName, msg); } it = componentList->getIterator(); it->reset(); it->insertBeforeRef(ce); // Add the last ping log_time_t localTime = getLocalTime(); LastPing lp; lp.name = strdup(componentName); lp.time = localTime; lp.timeDifference.sec = localTime.sec - componentTime.sec; lp.timeDifference.msec = localTime.msec - componentTime.msec; this->lastPings->push(&lp); // Notify the FilterManager tag_list_t* tl = this->filterManager->componentConnect( (const char*)componentName, it); if (tl == NULL) { fprintf (stderr, "Connecting component failed after filter \n"); delete(it); return LS_COMPONENT_CONNECT_INTERNALERROR; } delete it; // Create a new IN message char* msg; msg = (char*) malloc(strlen(message) + strlen(componentHostname) + 2); sprintf(msg, "%s %s\0", message , componentHostname); log_msg_t* inmsg = new log_msg_t(); inmsg->componentName = CORBA::string_dup(componentName); inmsg->time = localTime; inmsg->tag = CORBA::string_dup("IN"); inmsg->msg = CORBA::string_dup(msg); this->timeBuffer->put(inmsg); delete inmsg; // Return the initialConfig // update the tag_list_t& initialConfig = *tl; cout << "Connection of component '" << componentName << "' with message" << " '" << message << "'" << endl; return LS_OK; } CORBA::Short LogCentralComponent_impl::disconnectComponent(const char* componentName, const char* message) { // Find the component to delete it ComponentList::Iterator* it = this->componentList->getIterator(); bool found = false; while (it->hasCurrent()) { if (strcmp(it->getCurrentRef()->componentName, componentName) == 0) { found = true; break; } it->nextRef(); } if (!found) { delete it; cout << "Disconnection of component '" << componentName << "' failed," << " component not exists" << endl; return LS_COMPONENT_DISCONNECT_NOTEXISTS; } // Remove the component it->removeCurrent(); // Migrate it to a ReadItarator ComponentList::ReadIterator* readIterator = this->componentList->reduceWriteIterator(it); // Notify the FilterManager this->filterManager->componentDisconnect(componentName, readIterator); // Remove the last ping LastPings::Iterator* it2 = this->lastPings->getIterator(); while (it2->hasCurrent()) { if (strcmp(it2->getCurrentRef()->name, componentName) == 0) { it2->removeCurrent(); break; } it2->nextRef(); } delete it2; delete readIterator; // Create a new OUT message log_time_t localTime = getLocalTime(); log_msg_t* inmsg = new log_msg_t(); inmsg->componentName = CORBA::string_dup(componentName); inmsg->time = localTime; inmsg->tag = CORBA::string_dup("OUT"); inmsg->msg = CORBA::string_dup(message); this->timeBuffer->put(inmsg); delete inmsg; cout << "Disconnection of '" << componentName << "' with message" << " '" << message << "'" << endl; return LS_OK; } void LogCentralComponent_impl::sendBuffer(const log_msg_buf_t& buffer) { // for each message, correction of its time and the message is sent to the // TimeBuffer. log_time_t td; LastPing* lp = NULL; if (buffer.length() != 0) { const char* name = buffer[0].componentName; LastPings::ReadIterator* it = this->lastPings->getReadIterator(); bool compExists = false; while (it->hasCurrent()) { lp = it->nextRef(); if (strcmp(lp->name, name) == 0) { td = lp->timeDifference; compExists = true; break; } } delete it; if (compExists == false) { cout << "Discarded messageBuffer from unknown component " << name << endl; return; } for (unsigned int i = 0 ; i < buffer.length() ; i++) { log_msg_t msg = buffer[i]; // Correct the time derivation msg.time.sec += td.sec; msg.time.msec += td.msec; while (msg.time.msec < 0) { msg.time.msec += 1000; msg.time.sec -= 1; } while (msg.time.msec >= 1000) { msg.time.msec -= 1000; msg.time.sec += 1; } // FIXME: manage overflows here this->timeBuffer->put(&msg); } } } bool LogCentralComponent_impl::isComponentExists(const char* name, ComponentList::ReadIterator* it) { it->reset(); bool found = false; while (it->hasCurrent()) { if (strcmp(it->getCurrentRef()->componentName, name) == 0) { found = true; break; } it->nextRef(); } return found; } void LogCentralComponent_impl::ping(const char* componentName) { // Find the component LastPings::Iterator* it = this->lastPings->getIterator(); while (it->hasCurrent()) { if (strcmp(it->getCurrentRef()->name, componentName) == 0) { it->getCurrentRef()->time = getLocalTime(); break; } it->nextRef(); } delete it; } void LogCentralComponent_impl::synchronize(const char* componentName, const log_time_t& componentTime) { log_time_t localTime = getLocalTime(); // Find the component LastPings::Iterator* it = this->lastPings->getIterator(); while (it->hasCurrent()) { if (strcmp(it->getCurrentRef()->name, componentName) == 0) { it->getCurrentRef()->timeDifference.sec = localTime.sec - componentTime.sec; it->getCurrentRef()->timeDifference.msec = localTime.msec - componentTime.msec; break; } it->nextRef(); } delete it; } char* LogCentralComponent_impl::getGeneratedName(const char* hostname, ComponentList::ReadIterator* it) { unsigned int num = 1; char* ret = new char[strlen(hostname) + 10]; // I think it's sufficient sprintf(ret, "%s_%u", hostname, num); while (isComponentExists(ret, it)) { num++; sprintf(ret, "%s_%u", hostname, num); } return strdup(ret); } /**************************************************************************** * AliveCheckThread implementation ****************************************************************************/ LogCentralComponent_impl::AliveCheckThread::AliveCheckThread( LogCentralComponent_impl* LCC): LCC(LCC), threadRunning(false) { } LogCentralComponent_impl::AliveCheckThread::~AliveCheckThread() { if (this->threadRunning) { this->stopThread(); } } void LogCentralComponent_impl::AliveCheckThread::startThread() { if (this->threadRunning) { return; } this->threadRunning = true; start_undetached(); } void LogCentralComponent_impl::AliveCheckThread::stopThread() { if (!this->threadRunning) { return; } this->threadRunning = false; join(NULL); } void* LogCentralComponent_impl::AliveCheckThread::run_undetached(void* params) { LastPing* lp = NULL; log_time_t checkTime; FullLinkedList* componentsToDisconnect = NULL; bool somePingTimeout = false; while (this->threadRunning) { checkTime = getLocalTime(); checkTime.sec -= LogOptions::ALIVECHECKTHREAD_DEAD_TIME_SEC; checkTime.msec -= LogOptions::ALIVECHECKTHREAD_DEAD_TIME_MSEC; componentsToDisconnect = new FullLinkedList(); somePingTimeout = false; // Check for all in the LastPings buffer LastPings::ReadIterator* it = this->LCC->lastPings->getReadIterator(); while (it->hasCurrent()) { lp = it->nextRef(); if ((lp->time.sec < checkTime.sec) || ((lp->time.sec == checkTime.sec) && (lp->time.msec < checkTime.msec))) { // ping too old componentsToDisconnect->pushRef(strdup(lp->name)); somePingTimeout = true; } } delete it; char* s; if (somePingTimeout) { FullLinkedList::ReadIterator* it2 = componentsToDisconnect->getReadIterator(); while (it2->hasCurrent()) { char* msg; s = it2->nextRef(); msg = (char*) malloc(strlen(s) + strlen("Ping Timeout")); cout << "Ping Timeout of '" << s << "' : disconnect the component.\n"; sprintf(msg,"%s Ping Timeout",s); this->LCC->disconnectComponent(s, msg); } delete it2; } delete componentsToDisconnect; sleep(LogOptions::ALIVECHECKTHREAD_SLEEP_TIME_SEC, LogOptions::ALIVECHECKTHREAD_SLEEP_TIME_NSEC); } return NULL; } void LogCentralComponent_impl::test (){ return; } ////////////////////////////////// FORWARDER IMPL /**************************************************************************** * LogCentralComponent_impl inplementation ****************************************************************************/ LogCentralComponentFwdrImpl::LogCentralComponentFwdrImpl(CorbaLogForwarder_ptr fwdr, const char* objName) { this->forwarder = CorbaLogForwarder::_duplicate(fwdr); this->objName = CORBA::string_dup(objName); this->componentList = NULL; this->filterManager = NULL; this->timeBuffer = NULL; this->lastPings = NULL; } LogCentralComponentFwdrImpl::~LogCentralComponentFwdrImpl() { } CORBA::Short LogCentralComponentFwdrImpl::connectComponent( char*& componentName, const char* componentHostname, const char* message, const char* compConfigurator, const log_time_t& componentTime, tag_list_t& initialConfig) { return forwarder->connectComponent(componentName, componentHostname, message, compConfigurator, componentTime, initialConfig, objName); } CORBA::Short LogCentralComponentFwdrImpl::disconnectComponent(const char* componentName, const char* message) { return forwarder->disconnectComponent(componentName, message, objName); } void LogCentralComponentFwdrImpl::sendBuffer(const log_msg_buf_t& buffer) { return forwarder->sendBuffer(buffer, objName); } void LogCentralComponentFwdrImpl::ping(const char* componentName) { return forwarder->ping(componentName, objName); } void LogCentralComponentFwdrImpl::synchronize(const char* componentName, const log_time_t& componentTime) { return forwarder->synchronize(componentName, componentTime, objName); } void LogCentralComponentFwdrImpl::test(){ return forwarder->test(objName); } ComponentConfiguratorFwdr_impl::ComponentConfiguratorFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName){ this->forwarder = CorbaLogForwarder::_duplicate(fwdr); this->objName = CORBA::string_dup(objName); } ComponentConfiguratorFwdr_impl::~ComponentConfiguratorFwdr_impl(){ } void ComponentConfiguratorFwdr_impl::setTagFilter(const tag_list_t& tagList){ return forwarder->setTagFilter (tagList, objName); } void ComponentConfiguratorFwdr_impl::addTagFilter(const tag_list_t& tagList){ return forwarder->addTagFilter (tagList, objName); } void ComponentConfiguratorFwdr_impl::removeTagFilter(const tag_list_t& tagList){ return forwarder->removeTagFilter (tagList, objName); } void ComponentConfiguratorFwdr_impl::test(){ return forwarder->test (objName); } LogService-2.7.0/src/monitor/LogCentralComponent_impl.hh000644 000765 000765 00000026543 11576373452 024762 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Header corresponding to the LogComponentComponent interface */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.3 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.2 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _LOGCENTRALCOMPONENT_IMPL_HH_ #define _LOGCENTRALCOMPONENT_IMPL_HH_ #include "LogTypes.hh" #include "LogComponent.hh" #include "ComponentList.hh" #include "FilterManagerInterface.hh" #include "TimeBuffer.hh" #include "FullLinkedList.hh" #include "CorbaLogForwarder.hh" /** * Errorlevel constants for connectComponent (defined in the idl) const short LS_OK const short LS_COMPONENT_CONNECT_BADNAME const short LS_COMPONENT_CONNECT_ALREADYEXISTS const short LS_COMPONENT_CONNECT_BADCOMPONENTCONFIGURATOR const short LS_COMPONENT_CONNECT_INTERNALERROR const short LS_COMPONENT_DISCONNECT_NOTEXISTS */ /** * Implements the Component-Servant on the LogCentral. * The Servant is responsible for connection and deconnection components, * forwarding messages and synchronisation. This includes: * - store components in internal list * - correct time for incoming messages * and forward them to the timebuffer * - synchronize with components */ class LastPing { public: LastPing(); LastPing(LastPing& newLastPing); ~LastPing(); LastPing& operator=(LastPing& newLastPing); char* name; log_time_t time; log_time_t timeDifference; }; typedef FullLinkedList LastPings; class LogCentralComponent_impl: public POA_LogCentralComponent, public PortableServer::RefCountServantBase { public: LogCentralComponent_impl(ComponentList* componentList, FilterManagerInterface* filterManager, TimeBuffer* timeBuffer); ~LogCentralComponent_impl(); void test(); /** * Connect a component to the LogCentral. The component attaches with its * name, which must be unique (among all components) and its hostname (no * need to be unique). If the name is an empty string, a name is generated. * The return value indicates if the component could be connected. * If ALREADYEXISTS is returned, another component with the given name is * registered. In this case, the connection was not successful, and the tool * must connect with a diferent name before invoking other functions of the * LogCentralComponent interface. * @param componentName unique name of the component(cannot be *) or the * empty string "" for automatic naming. * @param componentHostname hostname of the component * @param message message to pass to the tools at the connection * @param compConfigurator component servant which can process * configuration changes for the component * @param componentTime localtime on the component side * @param initialConfig holds configuration for the components * tag filter after the call. * @returns value indicating if the component could be connected */ CORBA::Short connectComponent(char*& componentName, const char* componentHostname, const char* message, const char* compConfigurator, const log_time_t& componentTime, tag_list_t& initialConfig); /** * Disconnect a connected component from the LogCentral. * No further messages should be sent after disconnection. * The componentConfigurator will no longer be used by the LogCentral after * this call. Returns NOTCONNECTED if the calling component was not * registered. * @param componentName name of the component * @param message message to pass to the tools at the disconnection * @returns value indicating if the component could be disconnected */ CORBA::Short disconnectComponent(const char* componentName, const char* message); /** * Send a buffer of log_msg_t to the LogCentral. * @param buffer sequence of log_msg_t to be sent */ void sendBuffer(const log_msg_buf_t& buffer); /** * Tell if a component exists or not. * @param name name of the component to find * @return true if the component exists */ bool isComponentExists(const char* name, ComponentList::ReadIterator* it); /** * To be called by a thread for saying that the component is still alive. * If the last ping is too old, the component is considered dead and * generate a disconnect message (OUT). * @param componentName the name of the component who send the ping */ void ping(const char* componentName); /** * To be called by a thread for clock synchronisation. * @param componentTime localtime on the component side * @param componentName the name of the component who send the synchro */ void synchronize(const char* componentName, const log_time_t& componentTime); /** * Uselessbut to have the same idl as in log */ // char* // getHostnameOf(const char* toto); private: /** * Generate an unique name based on the hostname * @param hostname the hostname to base to form the name * @return a unique name */ char* getGeneratedName(const char* hostname, ComponentList::ReadIterator* it); private: class AliveCheckThread:public omni_thread { public: AliveCheckThread(LogCentralComponent_impl* LCC); ~AliveCheckThread(); /** * Start the thread. Return immediately. */ void startThread(); /** * Stop the thread. Return when the thread is stopped. */ void stopThread(); private: void* run_undetached(void* params); private: LogCentralComponent_impl* LCC; bool threadRunning; }; friend class LogCentralComponent_impl::AliveCheckThread; private: ComponentList* componentList; FilterManagerInterface* filterManager; TimeBuffer* timeBuffer; LastPings* lastPings; AliveCheckThread* aliveCheckThread; }; // end class LogCentralComponen_impl class LogCentralComponentFwdrImpl: public POA_LogCentralComponentFwdr, public PortableServer::RefCountServantBase { public: LogCentralComponentFwdrImpl(CorbaLogForwarder_ptr fwdr, const char *objName); ~LogCentralComponentFwdrImpl(); CORBA::Short connectComponent(char*& componentName, const char* componentHostname, const char* message, const char* compConfigurator, const log_time_t& componentTime, tag_list_t& initialConfig); CORBA::Short disconnectComponent(const char* componentName, const char* message); void sendBuffer(const log_msg_buf_t& buffer); void ping(const char* componentName); void synchronize(const char* componentName, const log_time_t& componentTime); void test(); protected: CorbaLogForwarder_ptr forwarder; char* objName; private: ComponentList* componentList; FilterManagerInterface* filterManager; TimeBuffer* timeBuffer; LastPings* lastPings; }; // end class LogCentralComponentFwdr_impl class ComponentConfiguratorFwdr_impl: public POA_ComponentConfiguratorFwdr, public PortableServer::RefCountServantBase { public: ComponentConfiguratorFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName); ~ComponentConfiguratorFwdr_impl(); void setTagFilter(const tag_list_t& tagList); void addTagFilter(const tag_list_t& tagList); void removeTagFilter(const tag_list_t& tagList); void test(); protected: CorbaLogForwarder_ptr forwarder; char* objName; }; // end class LogCentralComponentFwdr_impl #endif LogService-2.7.0/src/monitor/LogCentralTool_impl.cc000644 000765 000765 00000037422 11576373451 023720 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implements the object LogCentralTool defined in the LogTool.idl */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.3 2010/11/10 04:23:44 bdepardo * Correctly generate random number * * Revision 1.2 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogCentralTool_impl.hh" #include #include #include #include #include #include "../LogORBMgr.hh" using namespace std; LogCentralTool_impl::LogCentralTool_impl(ToolList* toolList, ComponentList* compList, FilterManagerInterface* filterMan, StateManager* stateMan, tag_list_t* allTags) { this->toolList = toolList; componentList = compList; filterManager = filterMan; stateManager = stateMan; this->allTags = (*allTags); srand(time(NULL)); } LogCentralTool_impl::~LogCentralTool_impl() { // nothing to do } void LogCentralTool_impl::test() { } CORBA::Short LogCentralTool_impl::connectTool(char*& toolName, const char* msgRec) { ToolList::Iterator* it; char tmpName[6]; it = toolList->getIterator(); // MODIF *** ToolMsgReceiver_ptr msgReceiver = LogORBMgr::getMgr()->resolve (LOGTOOLMSGCTXT, msgRec); // LogCentralTool_ptr msgReceiver = LogORBMgr::getMgr()->resolve // (LOGTOOLCTXT, msgRec); if (CORBA::is_nil(msgReceiver)){ fprintf (stderr, "Failed to resolve LCT. Nil receiver \n"); } // Check if toolName must be created. while (strcmp(toolName,"")==0) { sprintf(tmpName,"%ld",(rand() % 99999)); toolName = CORBA::string_dup(tmpName); // check if new name is valid if (getToolByName(toolName,it)==true) { // repeat this loop toolName = CORBA::string_dup(""); } } // Check if tool exists if (getToolByName(toolName,it)) { // tool already exists and cannot be connected a second time delete(it); printf("Connection of tool: '%s' failed, tool already exists\n", toolName); return LS_TOOL_CONNECT_ALREADYEXISTS; } // create ToolElement and insert it ToolElement* tElem; tElem = new ToolElement(); tElem->toolName = CORBA::string_dup(toolName); tElem->msgReceiver = ToolMsgReceiver::_narrow(msgReceiver); // filterList and outBuffer are static it->reset(); it->insertBeforeRef(tElem); // FIXME: can we reduce the iterator here or do we have to keep it // to allow a synchronised askForSystemState ? // notify FilterManager filterManager->toolConnect(toolName,it); // "produce" Initial Config for tool stateManager->askForSystemState(&(tElem->outBuffer)); delete(it); printf("Connection of tool '%s'\n", toolName); return LS_OK; } CORBA::Short LogCentralTool_impl::disconnectTool(const char* toolName) { ToolList::Iterator* it; it = toolList->getIterator(); // Check if tool exists if (getToolByName(toolName,it)==false) { // tool does not exist and cannot be disconnected delete(it); printf("Disconnection of tool: '%s' failed, tool does not exist\n", toolName); return LS_TOOL_DISCONNECT_NOTEXISTS; } // notify FilterManager filterManager->toolDisconnect(toolName, it); // remove Tool getToolByName(toolName, it); it->removeCurrent(); // element and all its lists, buffers, etc are // deleted automatically delete(it); printf("Disconnection of tool '%s'\n",toolName); return LS_OK; } tag_list_t* LogCentralTool_impl::getDefinedTags() { tag_list_t* tagList; tagList = new tag_list_t(); (*tagList) = allTags; return tagList; } component_list_t* LogCentralTool_impl::getDefinedComponents() { ComponentList::ReadIterator* it; ComponentElement* compElem; component_list_t* compList; compList = new component_list_t(); it = componentList->getReadIterator(); compList->length(it->length()); for (unsigned int i=0; i < (it->length()); i++) { compElem = it->nextRef(); (*compList)[i] = CORBA::string_dup(compElem->componentName); } delete(it); return compList; } CORBA::Short LogCentralTool_impl::addFilter(const char* toolName, const filter_t& filter) { ToolList::Iterator* toolIt; ToolList::ReadIterator* toolRIt; FilterList::Iterator* filterIt; ToolElement* actTool; // Make sure tool exists toolIt = toolList->getIterator(); // get a writeIterator as we want to change // the filters if (getToolByName(toolName, toolIt)==false) { // tool does not exist, so filter cannot be added delete (toolIt); return LS_TOOL_ADDFILTER_TOOLNOTEXISTS; } actTool = toolIt->getCurrentRef(); // Make sure this filter for this tool does not exist filterIt = actTool->filterList.getIterator(); if (getFilterByName(filter.filterName, filterIt)==true) { // filter exists, so we cannot add it delete (filterIt); delete (toolIt); return LS_TOOL_ADDFILTER_ALREADYEXISTS; } // okay, we can copy this filter and insert it filter_t* filterTmp = new filter_t; (*filterTmp) = filter; filterIt->reset(); filterIt->insertBeforeRef(filterTmp); delete(filterIt); // notify FilterManager toolRIt = toolList->reduceWriteIterator(toolIt); filterManager->addFilter(toolName, filter.filterName, toolRIt); // dont forget: release the iterator for the ToolList at the End ! delete(toolRIt); return LS_OK; } CORBA::Short LogCentralTool_impl::removeFilter(const char* toolName, const char* filterName) { ToolList::Iterator* toolIt; FilterList::Iterator* filterIt; ToolElement* actTool; // Make sure tool exists toolIt = toolList->getIterator(); // get a writeIterator as we want to change // the filters if (getToolByName(toolName, toolIt)==false) { // tool does not exist, so filter cannot be removed delete (toolIt); return LS_TOOL_REMOVEFILTER_TOOLNOTEXISTS; } actTool = toolIt->getCurrentRef(); // Make sure this filter for this tool exists filterIt = actTool->filterList.getIterator(); if (getFilterByName(filterName, filterIt)==false) { // filter does not exist, so we cannot delete it delete (filterIt); delete (toolIt); return LS_TOOL_REMOVEFILTER_NOTEXISTS; } delete(filterIt); // delete the filterIterator, as the Filtermanager will // open its own. List is still locked by toolIt // notify FilterManager filterManager->removeFilter(toolName, filterName, toolIt); // retrieve filter from list and delete it filterIt = actTool->filterList.getIterator(); getFilterByName(filterName, filterIt); filterIt->removeCurrent(); // filterElement is deleted automatically delete(filterIt); // dont forget: release the iterator for the ToolList at the End ! delete(toolIt); return LS_OK; } CORBA::Short LogCentralTool_impl::flushAllFilters(const char* toolName) { ToolList::Iterator* toolIt; ToolElement* actTool; // Make sure tool exists toolIt = toolList->getIterator(); // get a writeIterator as we want to change // the filters if (getToolByName(toolName, toolIt)==false) { // tool does not exist, so filters cannot be removed delete (toolIt); return LS_TOOL_REMOVEFILTER_TOOLNOTEXISTS; } actTool = toolIt->getCurrentRef(); // notify FilterManager filterManager->flushAllFilters(toolName, toolIt); // now delete all Filters actTool->filterList.emptyIt(); delete(toolIt); return LS_OK; } bool LogCentralTool_impl::getToolByName(const char* toolName, ToolList::ReadIterator* it) { bool exists = false; it->reset(); while (it->hasCurrent()) { if (strcmp((char*)(it->getCurrentRef()->toolName),toolName)==0) { exists=true; break; } it->nextRef(); } return exists; } bool LogCentralTool_impl::getFilterByName(const char* filterName, FilterList::ReadIterator* it) { bool exists = false; it->reset(); while(it->hasCurrent()) { if (strcmp((char*)(it->getCurrentRef()->filterName),filterName)==0) { exists=true; break; } it->nextRef(); } return exists; } //////////////////////////////////// FWDR LogCentralToolFwdr_impl::LogCentralToolFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName){ this->forwarder = CorbaLogForwarder::_duplicate(fwdr); this->objName = CORBA::string_dup(objName); } LogCentralToolFwdr_impl::~LogCentralToolFwdr_impl() { } void LogCentralToolFwdr_impl::test(){ return forwarder->test(objName); } /** * Connects a new Tool to the monitor. * Registers the tool internally with its unique toolName * and creates all necessary outbuffers, ... * Provides a unique name for the tool if the given toolName * is the empty string. * (Attention: the omniidl is buggy for string INOUT. The * String_INOUT_arg of the LogTool.hh must be replaced by * char*&) * * @param toolName the unique name of the tool * @param msgReceiver messageConsumer of the tool, which processes * incoming messages for the tool * @returns if the connection was successful */ CORBA::Short LogCentralToolFwdr_impl::connectTool(char*& toolName, const char* msgReceiver){ return forwarder->connectTool (toolName, msgReceiver, objName); } /** * Disconnect a tool from the monitor. * Remove the tools filters and deregister tool. * * @param toolName the unique name of the tool * @returns if the deconnection was successful */ CORBA::Short LogCentralToolFwdr_impl::disconnectTool(const char* toolName){ return forwarder->disconnectTool(toolName, objName); } /** * Returns a list of configured tags. This is just a * convenience function. It relies on the configuration of * the monitor and must not reflect the real system. */ tag_list_t* LogCentralToolFwdr_impl::getDefinedTags(){ return forwarder->getDefinedTags(objName); } /** * Returns a list of currently attached components. This is * just a convenience function, as all the whole systemstate * including all components are sent to the tool upon connection * in form of messages. */ component_list_t* LogCentralToolFwdr_impl::getDefinedComponents(){ return forwarder->getDefinedComponents(objName); } /** * Add a (posivive) filter for this tool. * Messages matching this filter will be forwarded to the tool. * * @param toolName the name of the tool, which adds the filter * @param filter the filterconfiguration containing the filtername, * a list of tags and a list of components * @returns if the filter could be added properly */ CORBA::Short LogCentralToolFwdr_impl::addFilter(const char* toolName, const filter_t& filter){ return forwarder->addFilter(toolName, filter, objName); } /** * Remove a existing filter from the list. * * @param toolName the name of the tool who added the filter * @param filterName the name of the filter * @returns if the filter could be removed properly */ CORBA::Short LogCentralToolFwdr_impl::removeFilter(const char* toolName, const char* filterName){ return forwarder->removeFilter(toolName, filterName, objName); } /** * Remove all existing filters of the tool. * * @param toolName the name of the tool whose filterlist will be cleared */ CORBA::Short LogCentralToolFwdr_impl::flushAllFilters(const char* toolName){ return forwarder->flushAllFilters(toolName, objName); } ToolMsgReceiverFwdr_impl::ToolMsgReceiverFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName){ this->forwarder = CorbaLogForwarder::_duplicate(fwdr); this->objName = CORBA::string_dup(objName); } ToolMsgReceiverFwdr_impl::~ToolMsgReceiverFwdr_impl(){ } void ToolMsgReceiverFwdr_impl::sendMsg(const log_msg_buf_t& msgBuf){ return forwarder->sendMsg(msgBuf, objName); } LogService-2.7.0/src/monitor/LogCentralTool_impl.hh000644 000765 000765 00000027207 11576373452 023733 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Defines an object implementing the interface LogCentralTool defined in */ /* the LogCentralTool.idl */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.2 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _LOGCENTRALTOOL_IMPL_HH_ #define _LOGCENTRALTOOL_IMPL_HH_ #include "ToolList.hh" #include "ComponentList.hh" #include "FilterManagerInterface.hh" #include "StateManager.hh" #include "CorbaLogForwarder.hh" /** * Errorlevel constants for connectComponent (defined in the idl) const short LS_OK const short LS_TOOL_CONNECT_ALREADYEXISTS const short LS_TOOL_DISCONNECT_NOTEXISTS const short LS_TOOL_ADDFILTER_ALREADYEXISTS const short LS_TOOL_REMOVEFILTER_NOTEXISTS */ /** * Implements the tool servant for the logCentral. * Attaches and detaches tools and forwards their * filter-configurations to the FilterManager */ class LogCentralTool_impl: public POA_LogCentralTool, public PortableServer::RefCountServantBase { public: LogCentralTool_impl(ToolList* toolList, ComponentList* compList, FilterManagerInterface* filterMan, StateManager* stateMan, tag_list_t* allTags); ~LogCentralTool_impl(); void test(); /** * Connects a new Tool to the monitor. * Registers the tool internally with its unique toolName * and creates all necessary outbuffers, ... * Provides a unique name for the tool if the given toolName * is the empty string. * (Attention: the omniidl is buggy for string INOUT. The * String_INOUT_arg of the LogTool.hh must be replaced by * char*&) * * @param toolName the unique name of the tool * @param msgReceiver messageConsumer of the tool, which processes * incoming messages for the tool * @returns if the connection was successful */ CORBA::Short connectTool(char*& toolName, const char* msgReceiver); /** * Disconnect a tool from the monitor. * Remove the tools filters and deregister tool. * * @param toolName the unique name of the tool * @returns if the deconnection was successful */ CORBA::Short disconnectTool(const char* toolName); /** * Returns a list of configured tags. This is just a * convenience function. It relies on the configuration of * the monitor and must not reflect the real system. */ tag_list_t* getDefinedTags(); /** * Returns a list of currently attached components. This is * just a convenience function, as all the whole systemstate * including all components are sent to the tool upon connection * in form of messages. */ component_list_t* getDefinedComponents(); /** * Add a (posivive) filter for this tool. * Messages matching this filter will be forwarded to the tool. * * @param toolName the name of the tool, which adds the filter * @param filter the filterconfiguration containing the filtername, * a list of tags and a list of components * @returns if the filter could be added properly */ CORBA::Short addFilter(const char* toolName, const filter_t& filter); /** * Remove a existing filter from the list. * * @param toolName the name of the tool who added the filter * @param filterName the name of the filter * @returns if the filter could be removed properly */ CORBA::Short removeFilter(const char* toolName, const char* filterName); /** * Remove all existing filters of the tool. * * @param toolName the name of the tool whose filterlist will be cleared */ CORBA::Short flushAllFilters(const char* toolName); private: FilterManagerInterface* filterManager; StateManager* stateManager; ToolList* toolList; ComponentList* componentList; tag_list_t allTags; /** * sets the currentElement() of the ReadIterator to the * toolElement named "toolName", to NULL if no tool with * the given name exists. Returns true if the tool was * found. * * @param toolName the name of the tool to look for * @param it the iterator that will be changed * @returns bool indicating if the tool with the given * name was found */ bool getToolByName(const char* toolName, ToolList::ReadIterator* it); /** * sets the currentElement() of the ReadIterator to the * filter_t named "filterName", to NULL if no filter with * the given name exists. Returns true if the filter was * found. * * @param filterName the name of the filter to look for * @param it the iterator that will be changed * @returns bool indicating if the filter with the given * name was found */ bool getFilterByName(const char* filterName, FilterList::ReadIterator* it); }; class LogCentralToolFwdr_impl: public POA_LogCentralToolFwdr, public PortableServer::RefCountServantBase { public: LogCentralToolFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName); ~LogCentralToolFwdr_impl(); void test(); /** * Connects a new Tool to the monitor. * Registers the tool internally with its unique toolName * and creates all necessary outbuffers, ... * Provides a unique name for the tool if the given toolName * is the empty string. * (Attention: the omniidl is buggy for string INOUT. The * String_INOUT_arg of the LogTool.hh must be replaced by * char*&) * * @param toolName the unique name of the tool * @param msgReceiver messageConsumer of the tool, which processes * incoming messages for the tool * @returns if the connection was successful */ CORBA::Short connectTool(char*& toolName, const char* msgReceiver); /** * Disconnect a tool from the monitor. * Remove the tools filters and deregister tool. * * @param toolName the unique name of the tool * @returns if the deconnection was successful */ CORBA::Short disconnectTool(const char* toolName); /** * Returns a list of configured tags. This is just a * convenience function. It relies on the configuration of * the monitor and must not reflect the real system. */ tag_list_t* getDefinedTags(); /** * Returns a list of currently attached components. This is * just a convenience function, as all the whole systemstate * including all components are sent to the tool upon connection * in form of messages. */ component_list_t* getDefinedComponents(); /** * Add a (posivive) filter for this tool. * Messages matching this filter will be forwarded to the tool. * * @param toolName the name of the tool, which adds the filter * @param filter the filterconfiguration containing the filtername, * a list of tags and a list of components * @returns if the filter could be added properly */ CORBA::Short addFilter(const char* toolName, const filter_t& filter); /** * Remove a existing filter from the list. * * @param toolName the name of the tool who added the filter * @param filterName the name of the filter * @returns if the filter could be removed properly */ CORBA::Short removeFilter(const char* toolName, const char* filterName); /** * Remove all existing filters of the tool. * * @param toolName the name of the tool whose filterlist will be cleared */ CORBA::Short flushAllFilters(const char* toolName); protected : CorbaLogForwarder_ptr forwarder; char* objName; }; class ToolMsgReceiverFwdr_impl: public POA_ToolMsgReceiverFwdr, public PortableServer::RefCountServantBase { public: ToolMsgReceiverFwdr_impl(CorbaLogForwarder_ptr fwdr, const char* objName); ~ToolMsgReceiverFwdr_impl(); void sendMsg (const log_msg_buf_t& msgBuf); protected : CorbaLogForwarder_ptr forwarder; char* objName; }; #endif LogService-2.7.0/src/monitor/LogOptions.cc000644 000765 000765 00000012032 11576373451 022072 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A static class for having access to some options from everywhere */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogOptions.hh" /** * Very weired main. * Just initialize all static variables. * * We need the .cc to get an object file, and we need the .o to prevent * multiple definitions of the static variables in other object files. */ long unsigned int LogOptions::CORETHREAD_SLEEP_TIME_SEC = 0; long unsigned int LogOptions::CORETHREAD_SLEEP_TIME_NSEC = 1000000; long unsigned int LogOptions::CORETHREAD_MINAGE_TIME_SEC = 0; long unsigned int LogOptions::CORETHREAD_MINAGE_TIME_MSEC = 200; long unsigned int LogOptions::ALIVECHECKTHREAD_SLEEP_TIME_SEC = 3; long unsigned int LogOptions::ALIVECHECKTHREAD_SLEEP_TIME_NSEC = 0; long unsigned int LogOptions::ALIVECHECKTHREAD_DEAD_TIME_SEC = 60; long unsigned int LogOptions::ALIVECHECKTHREAD_DEAD_TIME_MSEC = 0; long unsigned int LogOptions::SENDTHREAD_SLEEP_TIME_SEC = 0; long unsigned int LogOptions::SENDTHREAD_SLEEP_TIME_NSEC = 1000000; LogService-2.7.0/src/monitor/LogOptions.hh000644 000765 000765 00000011326 11576373453 022113 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A static class for having access to some options from everywhere */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _LOGOPTIONS_HH_ #define _LOGOPTIONS_HH_ class LogOptions { public: static unsigned long CORETHREAD_SLEEP_TIME_SEC; static unsigned long CORETHREAD_SLEEP_TIME_NSEC; static unsigned long CORETHREAD_MINAGE_TIME_SEC; static unsigned long CORETHREAD_MINAGE_TIME_MSEC; static unsigned long ALIVECHECKTHREAD_SLEEP_TIME_SEC; static unsigned long ALIVECHECKTHREAD_SLEEP_TIME_NSEC; static unsigned long ALIVECHECKTHREAD_DEAD_TIME_SEC; static unsigned long ALIVECHECKTHREAD_DEAD_TIME_MSEC; static unsigned long SENDTHREAD_SLEEP_TIME_SEC; static unsigned long SENDTHREAD_SLEEP_TIME_NSEC; }; #endif LogService-2.7.0/src/monitor/ReadConfig.cc000644 000765 000765 00000031262 11576373451 022004 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implementation of the ReadConfig class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2011/02/04 15:13:40 bdepardo * Remove memleak. * Initialize members in constructor. * * Revision 1.2 2004/06/01 21:43:00 hdail * Tracking down seg fault in LogService: * - corrected mismatched malloc / delete[] * - corrected getLine(...) to return NULL if no more characters are available * in the file (previous behavior tried to process the line) * - changed logic in all code in this file that calls getLine in order to * properly check for NULL. Also corrected apparent bug that last line of * file may not have been processed under certain circumstances * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "ReadConfig.hh" #include #include #include using namespace std; ReadConfig::ReadConfig(const char* configFilename, bool* success) { *success = false; this->filename = NULL; if (configFilename == NULL) { return; } FILE* file = fopen(configFilename, "r"); if (file == NULL) { return; } fclose(file); this->filename = strdup(configFilename); this->alreadyParsed = false; this->tracelevel = 0; this->port = 0; this->startSuffix = NULL; this->stopSuffix = NULL; this->dynamicTags = new tag_list_t(); this->staticTags = new tag_list_t(); this->uniqueTags = new tag_list_t(); this->volatileTags = new tag_list_t(); *success = true; } ReadConfig::~ReadConfig() { if (this->filename != NULL) { free(this->filename); } delete this->dynamicTags; delete this->staticTags; delete this->uniqueTags; delete this->volatileTags; } char* ReadConfig::readLine(FILE* file) { char* buff = NULL; int nextChar; // check for file content before trying to read line nextChar = fgetc(file); if(nextChar == EOF){ return NULL; } ungetc(nextChar, file); buff = new char[256]; fgets(buff, 255, file); if(buff == NULL){ return NULL; } int len = strlen(buff); // remove \n if (buff[len - 1] == '\n') { len--; buff[len] = '\0'; } // remove comments for (int i=0; i=0; i--) { if (buff[i] == ' ') { buff[i]='\0'; len=i+1; } else { break; } } char* ret = new char[len + 1]; sprintf(ret, "%s", buff); delete[] buff; return ret; } short ReadConfig::parseTagSection(FILE* file, const char* sectionName, tag_list_t* taglist) { rewind(file); int i = 0; int n = 0; bool found = false; char* s; // Find the section while (i == 0) { s = this->readLine(file); if (s == NULL){ i = 2; // stop if end of file } else if (strcmp(s, sectionName) == 0) { i = 1; } else if (feof(file)) { i = 2; // stop if end of file } delete[] s; } if (i == 2) { return LS_PARSE_SECTIONNOTFOUND; } // Parse the section i = 0; while (i == 0) { s = this->readLine(file); // stop if new section or end of file if ((s == NULL) || s[0] == '[') { i = 1; // avoid empty lines and commented lines } else if (strcmp(s, "") != 0) { n = taglist->length(); found = false; for (CORBA::Long j = 0 ; j < n ; j++) { if (strcmp(s, (*taglist)[j]) == 0) { found = true; break; } } if (!found) { // increase the length of the list taglist->length(n + 1); // add the tag (*taglist)[n] = CORBA::string_dup(s); } } delete[] s; } return LS_OK; } short ReadConfig::parse() { if (this->alreadyParsed) { return LS_PARSE_ALREADYPARSED; } FILE* file = fopen(filename, "r"); if (file == NULL) { return LS_PARSE_FILEERROR; } short i = 0; int ltracelevel = 0; int lport = 0; int lstart = 0; int lstop = 0; char* s; char* s2; // First find the General section while (i == 0) { s = this->readLine(file); if(s == NULL) { i = 2; // stop if end of file } else if (strcmp(s, "[General]") == 0) { i = 1; } else if (feof(file)) { i = 2; // stop if end of file } delete[] s; } if (i == 2) { return LS_PARSE_SECTIONNOTFOUND; } // Parse the General section i = 0; ltracelevel = strlen("Tracelevel="); lport = strlen("Port="); lstart = strlen("DynamicStartSuffix="); lstop = strlen("DynamicStopSuffix="); this->tracelevel = 0; this->port = 0; this->startSuffix = NULL; this->stopSuffix = NULL; while (i == 0) { s = this->readLine(file); if((s == NULL) || (s[0] == '[')){ i = 1; // stop if new section or end of file } else if (strncmp(s, "Tracelevel=", ltracelevel) == 0) { sscanf(s, "Tracelevel=%u", &(this->tracelevel)); } else if (strncmp(s, "Port=", lport) == 0) { sscanf(s, "Port=%u", &(this->port)); } else if (strncmp(s, "DynamicStartSuffix=", lstart) == 0) { s2 = new char[strlen(s) - lstart + 1]; sscanf(s, "DynamicStartSuffix=%s", s2); this->startSuffix = strdup(s2); delete[] s2; } else if (strncmp(s, "DynamicStopSuffix=", lstop) == 0) { s2 = new char[strlen(s) - lstop + 1]; sscanf(s, "DynamicStopSuffix=%s", s2); this->stopSuffix = strdup(s2); delete[] s2; } else if (feof(file)){ i = 1; // stop if new section or end of file } delete[] s; } if (this->startSuffix == NULL) { this->startSuffix = new char[6]; strncpy(this->startSuffix, "START", 6); } if (this->stopSuffix == NULL) { this->stopSuffix = new char[5]; strncpy(this->stopSuffix, "STOP", 5); } // Find the DynamicTagList section i = this->parseTagSection(file, "[DynamicTagList]", this->dynamicTags); if (i != LS_OK) { return i; } // Find the StaticTagList section i = this->parseTagSection(file, "[StaticTagList]", this->staticTags); if (i != LS_OK) { return i; } // Find the UniqueTagList section i = this->parseTagSection(file, "[UniqueTagList]", this->uniqueTags); if (i != LS_OK) { return i; } // Find the VolatileTagList section i = this->parseTagSection(file, "[VolatileTagList]", this->volatileTags); if (i != LS_OK) { return i; } fclose(file); this->alreadyParsed = true; return LS_OK; } unsigned int ReadConfig::getTracelevel() { unsigned int ret = 0; if (this->alreadyParsed) { ret = this->tracelevel; } return ret; } unsigned int ReadConfig::getPort() { unsigned int ret = 0; if (this->alreadyParsed) { ret = this->port; } return ret; } char* ReadConfig::getDynamicStartSuffix() { char* ret = NULL; if (this->alreadyParsed) { ret = strdup(this->startSuffix); } return ret; } char* ReadConfig::getDynamicStopSuffix() { char* ret = NULL; if (this->alreadyParsed) { ret = strdup(this->stopSuffix); } return ret; } tag_list_t* ReadConfig::getDynamicTags() { tag_list_t* ret = NULL; if (this->alreadyParsed) { ret = new tag_list_t(*(this->dynamicTags)); } return ret; } tag_list_t* ReadConfig::getStaticTags() { tag_list_t* ret = NULL; if (this->alreadyParsed) { ret = new tag_list_t(*(this->staticTags)); } return ret; } tag_list_t* ReadConfig::getUniqueTags() { tag_list_t* ret = NULL; if (this->alreadyParsed) { ret = new tag_list_t(*(this->uniqueTags)); } return ret; } tag_list_t* ReadConfig::getVolatileTags() { tag_list_t* ret = NULL; if (this->alreadyParsed) { ret = new tag_list_t(*(this->volatileTags)); } return ret; } void ReadConfig::appendToList(tag_list_t* list, tag_list_t* appendlist) { bool b = false; CORBA::ULong n1 = list->length(); CORBA::ULong n2 = appendlist->length(); for (CORBA::ULong i = 0 ; i < n2 ; i++) { b = false; for (CORBA::ULong j = 0 ; j < n1 ; j++) { if (strcmp((*appendlist)[i], (*list)[j]) == 0) { b = true; break; } } if (!b) { n1++; list->length(n1); (*list)[n1 - 1] = CORBA::string_dup((*appendlist)[i]); } } } tag_list_t* ReadConfig::getStateTags() { tag_list_t* ret = NULL; if (this->alreadyParsed) { CORBA::ULong n = this->dynamicTags->length(); ret = new tag_list_t(); ret->length(2 * n); char* s1; char* s2; for (CORBA::ULong i = 0 ; i < n ; i++) { s1 = (*this->dynamicTags)[i]; s2 = new char[strlen(s1) + strlen(this->startSuffix) + 2]; sprintf(s2, "%s_%s", s1, this->startSuffix); (*ret)[2 * i] = CORBA::string_dup(s2); delete[] s2; s2 = new char[strlen(s1) + strlen(this->stopSuffix) + 2]; sprintf(s2, "%s_%s", s1, this->stopSuffix); (*ret)[2 * i + 1] = CORBA::string_dup(s2); delete[] s2; } this->appendToList(ret, this->staticTags); this->appendToList(ret, this->uniqueTags); } return ret; } tag_list_t* ReadConfig::getAllTags() { tag_list_t* ret = this->getStateTags(); if (ret != NULL) { this->appendToList(ret, this->volatileTags); } return ret; } LogService-2.7.0/src/monitor/ReadConfig.hh000644 000765 000765 00000014552 11576373453 022023 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Header of the ReadConfig class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _READCONFIG_HH_ #define _READCONFIG_HH_ #include "LogTypes.hh" #include const short LS_PARSE_ALREADYPARSED = 1; const short LS_PARSE_FILEERROR = 2; const short LS_PARSE_SECTIONNOTFOUND = 3; class ReadConfig { public: ReadConfig(const char* configFilename, bool* success); ~ReadConfig(); /** * Parse the config file. * @return an error level */ short parse(); /** * Get the tracelevel to use for CORBA communication. * @return the tracelevel or 0 if no tracelevel specified */ unsigned int getTracelevel(); /** * Get the Port to use for CORBA communication. * @return the port or 0 if no port specified */ unsigned int getPort(); /** * Get the dynamic start suffix, by default it's "START". * @return the dynmaic start suffix */ char* getDynamicStartSuffix(); /** * Get the dynamic stop suffix, by default it's "STOP". * @return the dynmaic stop suffix */ char* getDynamicStopSuffix(); /** * Get all dynamic system state tags. * If a tag name is "TAG1" then a pair of tags is expected : TAG1_START and * TAG1_STOP. START and STOP names are get from getDynamicStart-StopSuffix. * @return NULL if the file was not already parsed */ tag_list_t* getDynamicTags(); /** * Get all static system state tags. * @return NULL if the file was not already parsed */ tag_list_t* getStaticTags(); /** * Get all unique system state tags. * Only one information is keeped at a time. A new tag overwrite the * previous. * @return NULL if the file was not already parsed */ tag_list_t* getUniqueTags(); /** * Get all other tags (volatile tags). * @return NULL if the file was not already parsed */ tag_list_t* getVolatileTags(); /** * Get all the System state tags. * @return NULL if the file was not already parsed */ tag_list_t* getStateTags(); /** * Get all the possible tags. * @return NULL if the file was not already parsed */ tag_list_t* getAllTags(); private: char* readLine(FILE* file); short parseTagSection(FILE* file, const char* sectionName, tag_list_t* taglist); void appendToList(tag_list_t* list, tag_list_t* appendlist); private: char* filename; bool alreadyParsed; unsigned int tracelevel; unsigned int port; char* startSuffix; char* stopSuffix; tag_list_t* dynamicTags; tag_list_t* staticTags; tag_list_t* uniqueTags; tag_list_t* volatileTags; }; #endif LogService-2.7.0/src/monitor/SendThread.cc000644 000765 000765 00000015352 11576373451 022026 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A thread that continously empties the tools outbuffers by sending them */ /* to the corresponding toolMsgReceiver. */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/08 11:37:54 kcoulomb * Refix the static library problem. * Renamed the monitor/Options to monitor/LogOptions due to conflict creating the static lib (2 files called Options) * * Revision 1.3 2010/12/03 12:40:27 kcoulomb * MAJ log to use forwarders * * Revision 1.2 2004/01/13 15:10:49 ghoesch * explicity initialize runThread bool * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "SendThread.hh" #include "LogOptions.hh" #include #include #include #include #include SendThread::SendThread(ToolList* toolList) { this->toolList = toolList; runSendThread=false; } void SendThread::startThread() { if (runSendThread == false) { runSendThread = true; start_undetached(); } // else thread is already running } void SendThread::stopThread() { if (runSendThread == true) { runSendThread = false; join(NULL); } // else thread is not running } void* SendThread::run_undetached(void* arg) { ToolList::Iterator* toolIt; ToolElement* toolEl; OutBuffer::Iterator* bufIt; log_msg_t* message; log_msg_buf_t msgBuf; int bufIndex; bool removeTool; int tCnt; int mCnt; while (runSendThread) { // main loop toolIt = toolList->getIterator(); tCnt=0; mCnt=0; // check every tool while (toolIt->hasCurrent()) { toolEl = toolIt->getCurrentRef(); // check if the current tool has messages that have to be sent bufIt = toolEl->outBuffer.getIterator(); removeTool = false; if (bufIt->length() > 0) { // msgs exist, copy them into buffer msgBuf.length(bufIt->length()); bufIndex = 0; while (bufIt->hasCurrent()) { // Attention: we need no next() here, as the remove() will proceed // to the next element in the list message = bufIt->removeAndGetCurrent(); msgBuf[bufIndex] = (*message); // copy message delete(message); mCnt++; bufIndex++; } // send the buffer try { toolEl->msgReceiver->sendMsg(msgBuf); } catch(CORBA::SystemException& e) { printf("NETWORK WARNING: Could not forward messages to tool '%s'. Disconnecting it.\n", (const char*)(toolEl->toolName)); removeTool = true; } } delete(bufIt); if (removeTool) { toolIt->removeCurrent(); // FIXME: we should update the Filtermanager here ... } else { tCnt++; toolIt->nextRef(); } } delete(toolIt); sleep(LogOptions::SENDTHREAD_SLEEP_TIME_SEC, LogOptions::SENDTHREAD_SLEEP_TIME_NSEC); } // leaving main loop return NULL; } SendThread::~SendThread() { if (runSendThread == true) { runSendThread = false; join(NULL); } } LogService-2.7.0/src/monitor/SendThread.hh000644 000765 000765 00000012646 11576373453 022045 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A thread that continously empties the tools outbuffers by sending them */ /* to the corresponding toolMsgReceiver. Based on omni_thread and the orb. */ /* Attention: causes memory leaks if the orb does not exist !! */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _SENDTHREAD_HH_ #define _SENDTHREAD_HH_ #include "omnithread.h" #include "ToolList.hh" #include "LogTool.hh" class SendThread: public omni_thread { public: /** * Creates a SendThread. The thread can be started with runThread(). * Use stopThread() to stop and delete the thread. * * @param toolList. The toolList that the thread will work on. */ SendThread(ToolList* toolList); /** * Start the thread */ void startThread(); /** * Stops the thread. Waits for the thread to terminate properly. * Deletes the threadobject if the orb is running. A missing orb * results in memory leaks. */ void stopThread(); protected: /** * Main function of thread * Contains main loop of thread, which has to end if * runSendThread is set to false */ void* run_undetached(void* arg); /** * Destructor of function. Stops the thread if still running. * This function should not be called directly. The object is * implicitly deleted by the orb when join() is called. The * orb must exist to make this work. */ ~SendThread(); private: /** * Shared variable that indicates if the thread is running or not. * stopThread will set this to false to stop the main loop of this * thread. */ bool runSendThread; /** * Stores the toolList the thread uses */ ToolList* toolList; }; #endif LogService-2.7.0/src/monitor/SimpleFilterManager.cc000644 000765 000765 00000036153 11576373451 023701 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Simple implementation of the FilterManagerInterface. The implementation */ /* is complete, but not very efficient. */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "SimpleFilterManager.hh" #include #include using namespace std; SimpleFilterManager::SimpleFilterManager(ToolList* toolList, ComponentList* compList, tag_list_t* stateTags) { this->toolList = toolList; this->componentList = compList; if (stateTags != NULL) { this->systemStateTags = *stateTags; } } SimpleFilterManager::~SimpleFilterManager() { } void SimpleFilterManager::toolConnect(const char* toolName, ToolList::ReadIterator* iter) { // nothing to do here } void SimpleFilterManager::toolDisconnect(const char* toolName, ToolList::ReadIterator* iter) { // nothing to do here } void SimpleFilterManager::addFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter) { ToolElement* toolEl; FilterList::ReadIterator* filterIt; // find tool iter->reset(); while(iter->hasCurrent()) { if (strcmp(toolName, (char*)(iter->getCurrentRef()->toolName)) == 0) { break; } iter->nextRef(); } toolEl = iter->getCurrentRef(); // find filter filterIt = toolEl->filterList.getReadIterator(); while(filterIt->hasCurrent()) { if (strcmp(filterName, (char*)(filterIt->getCurrentRef()->filterName)) == 0) { break; } filterIt->nextRef(); } // add the new filter to the existing configs addFilter(filterIt->getCurrentRef()); delete(filterIt); // Activate the new configuration updateComponentConfigs(); } void SimpleFilterManager::removeFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter) { ToolElement* toolEl; FilterList::ReadIterator* filterIt; ConfigList::Iterator* configIt; bool toolMatches; // rebuild all configs // clear configs first... configIt = configList.getIterator(); while (configIt->hasCurrent()) { // reset config to core tags configIt->getCurrentRef()->config = systemStateTags; configIt->nextRef(); } delete(configIt); // for each tool and each filter iter->reset(); while(iter->hasCurrent()) { if (strcmp(toolName, (char*)(iter->getCurrentRef()->toolName)) == 0) { toolMatches = true; } else { toolMatches = false; } toolEl = iter->getCurrentRef(); filterIt = toolEl->filterList.getReadIterator(); while (filterIt->hasCurrent()) { // add this filter if it is not the one that will be removed if (!toolMatches || (!strcmp(filterName, (char*)(filterIt->getCurrentRef()->filterName)) == 0)) { addFilter(filterIt->getCurrentRef()); } filterIt->nextRef(); } delete(filterIt); iter->nextRef(); } // Activate the new configuration updateComponentConfigs(); } void SimpleFilterManager::flushAllFilters(const char* toolName, ToolList::ReadIterator* iter) { ToolElement* toolEl; FilterList::ReadIterator* filterIt; ConfigList::Iterator* configIt; // rebuild all configs // clear configs first... configIt = configList.getIterator(); while (configIt->hasCurrent()) { // reset config to core tags configIt->getCurrentRef()->config = systemStateTags; configIt->nextRef(); } delete(configIt); // for each tool and each filter iter->reset(); while(iter->hasCurrent()) { toolEl = iter->getCurrentRef(); if (strcmp(toolName, (char*)(iter->getCurrentRef()->toolName)) != 0) { // this is not the tool whose filters are flushed, so add its filters filterIt = toolEl->filterList.getReadIterator(); while (filterIt->hasCurrent()) { addFilter(filterIt->getCurrentRef()); filterIt->nextRef(); } delete(filterIt); } iter->nextRef(); } // Activate the new configuration updateComponentConfigs(); } tag_list_t* SimpleFilterManager::componentConnect(const char* componentName, ComponentList::ReadIterator* iter) { ConfigList::Iterator* cfgIt; ToolList::ReadIterator* toolIt; FilterList::ReadIterator* filterIt; ConfigElement* cfgEl; ToolElement* toolEl; // add a configuration for the new component cfgEl = new ConfigElement(); cfgEl->componentName = CORBA::string_dup(componentName); // "empty" configs always include the systemState tags cfgEl->config = systemStateTags; cfgEl->oldConfig = systemStateTags; cfgIt = configList.getIterator(); cfgIt->insertBeforeRef(cfgEl); // now iterate through each Filter // if it matches add it to the new config toolIt = toolList->getReadIterator(); while (toolIt->hasCurrent()) { toolEl = toolIt->getCurrentRef(); filterIt = toolEl->filterList.getReadIterator(); while (filterIt->hasCurrent()) { if (containsComponent(&(filterIt->getCurrentRef()->componentList), componentName)) { addTagList(&(cfgEl->config), &(filterIt->getCurrentRef()->tagList)); } filterIt->nextRef(); } delete(filterIt); toolIt->nextRef(); } delete(toolIt); // send config back tag_list_t* tl = new tag_list_t(); (*tl) = cfgEl->config; delete(cfgIt); return tl; } void SimpleFilterManager::componentDisconnect(const char* componentName, ComponentList::ReadIterator* iter) { // remove the components configuration ConfigList::Iterator* it; it = configList.getIterator(); while (it->hasCurrent()) { if (strcmp((char*)(it->getCurrentRef()->componentName),componentName)==0) { break; } it->nextRef(); } it->removeCurrent(); // Element will be deleted automatically delete it; } void SimpleFilterManager::sendMessageWithFilters(log_msg_t* message) { ToolList::ReadIterator* toolIt; FilterList::ReadIterator* filterIt; filter_t* filter; toolIt = toolList->getReadIterator(); while (toolIt->hasCurrent()) { filterIt = toolIt->getCurrentRef()->filterList.getReadIterator(); while (filterIt->hasCurrent()) { filter = filterIt->getCurrentRef(); if (containsComponent(&(filter->componentList),message->componentName)) { if (containsTag(&(filter->tagList),message->tag)) { // okay, this filter fits // ush the element on the list, it will be copied automatically toolIt->getCurrentRef()->outBuffer.push(message); // DEBUG: printf("shifted message in outBuffer\n"); break; // no need to check the remaining filters of this tool ... } } filterIt->nextRef(); } delete(filterIt); toolIt->nextRef(); } delete(toolIt); } // Private Helpers // component_list_t helpers bool SimpleFilterManager::containsComponent(component_list_t* list, const char* name) { if (containsComponentStar(list)) { return true; } else if (containsComponentName(list, name)) { return true; } return false; } bool SimpleFilterManager::containsComponentName(component_list_t* list, const char* name) { for (unsigned int i=0; i < list->length(); i++) { if (strcmp((*list)[i], name) == 0) { // if found: break by returning return true; } } return false; } bool SimpleFilterManager::containsComponentStar(component_list_t* list) { for(unsigned int i=0; i< list->length(); i++) { if(strcmp((*list)[0], "*") == 0) { // if found: break by returning return true; } } return false; } // tag_list_t helpers (copy and paste of component_list_t) bool SimpleFilterManager::containsTag(tag_list_t* list, const char* name) { if (containsTagStar(list)) { return true; } else if (containsTagName(list, name)) { return true; } return false; } bool SimpleFilterManager::containsTagName(tag_list_t* list, const char* name) { for (unsigned int i=0; i < list->length(); i++) { if (strcmp((*list)[i], name) == 0) { // if found: break by returning return true; } } return false; } bool SimpleFilterManager::containsTagStar(tag_list_t* list) { for(unsigned int i=0; i< list->length(); i++) { if(strcmp((*list)[0], "*") == 0) { // if found: break by returning return true; } } return false; } void SimpleFilterManager::addTagList(tag_list_t* destList, tag_list_t* srcList) { unsigned int i_src; int len; if (containsTagStar(destList)) { // no need to add up, break and return return; } if (containsTagStar(srcList)) { // no need to add up, set destList and return destList->length(1); (*destList)[0]=CORBA::string_dup("*"); return; } // no stars, we need a complete merge for (i_src=0; i_src < srcList->length(); i_src++) { if (!containsTagName(destList, (*srcList)[i_src])) { len = destList->length(); destList->length(len+1); (*destList)[len] = CORBA::string_dup((*srcList)[i_src]); } } } void SimpleFilterManager::addFilter(filter_t* filter) { ConfigList::Iterator* configIt; configIt = configList.getIterator(); while(configIt->hasCurrent()) { if (containsComponent(&(filter->componentList), (const char*)(configIt->getCurrentRef()->componentName))) { // this component is part of the filter and must be altered addTagList(&(configIt->getCurrentRef()->config), &(filter->tagList)); } configIt->nextRef(); } delete(configIt); } void SimpleFilterManager::updateComponentConfigs() { ConfigList::Iterator* configIt; ConfigElement* cfgEl; ComponentList::ReadIterator* compIt; ComponentElement* compEl; unsigned int i; bool listsEqual; configIt = configList.getIterator(); compIt = componentList->getIterator(); while(configIt->hasCurrent()) { cfgEl = configIt->getCurrentRef(); // Check if configuration has changed and really must be sent // FIXME: Is this really performant ? listsEqual = true; // assume they are equal if (cfgEl->config.length() == cfgEl->oldConfig.length()) { for (i=0; i < cfgEl->config.length(); i++) { if (!containsTagName(&(cfgEl->oldConfig), cfgEl->config[i])) { listsEqual=false; break; } } } else { // the length does not match, so the lists never match listsEqual=false; } // no need to inform component if config stays the same if (!listsEqual) { compIt->reset(); while (compIt->hasCurrent()) { if (strcmp(compIt->getCurrentRef()->componentName, cfgEl->componentName) == 0) { compEl = compIt->getCurrentRef(); break; // we have found our tool ... } compIt->nextRef(); } try { compEl->componentConfigurator->setTagFilter(cfgEl->config); } catch (CORBA::SystemException& e) { printf("NETWORK WARNING: Could not configure the component '%s'.\n", (const char*)(compEl->componentName)); } } cfgEl->oldConfig = cfgEl->config; configIt->nextRef(); } delete(compIt); delete(configIt); } LogService-2.7.0/src/monitor/SimpleFilterManager.hh000644 000765 000765 00000022540 11576373453 023710 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* The SimpleFilterManager implements the FilterManagerInterface. This */ /* Implementation is complete, but it is not very efficient. */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _SIMPLEFILTERMANAGER_HH_ #define _SIMPLEFILTERMANAGER_HH_ #include "LogTypes.hh" #include "ToolList.hh" #include "ComponentList.hh" #include "FilterManagerInterface.hh" #include "FullLinkedList.hh" /** * Define an internal datastructure */ struct ConfigElement { CORBA::String_var componentName; tag_list_t config; tag_list_t oldConfig; }; /** * A list to hold the configuration of components */ typedef FullLinkedList ConfigList; /** * Simple implementation of the FilterManagerInterface * Mainly offers empty functions to make testers compile/run */ class SimpleFilterManager:public FilterManagerInterface { public: /** * Create a SimpleFilterManager. * * @param toolList The ToolList to use * @param compList The ComponentList to use * @param stateTags A list of all Tags that are important * for the system state and must always be sent. The * FilterManager copies this list and does not take its * ownership. */ SimpleFilterManager(ToolList* toolList, ComponentList* compList, tag_list_t* stateTags); virtual ~SimpleFilterManager(); /** * Notify the manager that a new tool has connected. * The Tool must already exist in the toolList. iter must * be an ReadIterator to the toolList. It should be the * same iterator that was used for inserting the tool. */ void toolConnect(const char* toolName, ToolList::ReadIterator* iter); /** * Notify the manager that a tool is about to disconnect. * This function must be called right before deleting the * tool from the list, as Filtermanager will delete all its * internal data on this tool (including remaining filters). * The iterator passed should be the iterator used for * deleting the tool. */ void toolDisconnect(const char* toolName, ToolList::ReadIterator* iter); /** * Notify the manager that a new filter has been added. * the filter must already exist in the toollist. A * iterator used for inserting should be passed. */ void addFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter); /** * Notify the manager that a filter will be removed. * This function should be called right before deleting * the filter. The iterator for deleting the filter should * be passed. */ void removeFilter(const char* toolName, const char* filterName, ToolList::ReadIterator* iter); /** * Notify the manager that all filters for a certain * tool will be removed. The filtermanager might implement * this more efficient that removing each filter one by * one. */ virtual void flushAllFilters(const char* toolName, ToolList::ReadIterator* iter); /** * Notify the manager that a component has connected * The component should be already in the list, the * corresponding iterator should be passed. */ tag_list_t* componentConnect(const char* componentName, ComponentList::ReadIterator* iter); /** * Notify the manager that a component will disconnect. * This must happen right before the deletion of the * component. The iterator passed should be the same * iterator used for deleting. */ void componentDisconnect(const char* componentName, ComponentList::ReadIterator* iter); /** * Forwards a message to all interested Tools. * The message will be checked and stored in the outBuffer * of all tools with a matching filter. */ void sendMessageWithFilters(log_msg_t* message); private: ToolList* toolList; ComponentList* componentList; /** * hold current configuration for each component */ ConfigList configList; /** * taglist that contains stateChanging tags that must always be sent */ tag_list_t systemStateTags; /** * Checks if a given component_list_t contains the * value given in name. list may contain the star */ bool containsComponent(component_list_t* list, const char* name); /** * Checks if a given component_list_t contains the * value given in componentName. Stars ('*') are not treated * as special characters */ bool containsComponentName(component_list_t* list, const char* name); /** * Checks if a given component_list_t contains the '*' */ bool containsComponentStar(component_list_t* list); /** * Checks if a given tag_list_t contains the * value given in name. list may contain the star */ bool containsTag(tag_list_t* list, const char* name); /** * Checks if a given tag_list_t contains the * value given in name. Stars ('*') are not treated * as special characters */ bool containsTagName(tag_list_t* list, const char* name); /** * Checks if a given component_list_t contains the '*' */ bool containsTagStar(tag_list_t* list); /** * Adds the tags in the srcList to the destList. If the tags * already exist in the destList, they are not copied. The * destList will not contain duplicates */ void addTagList(tag_list_t* destList, tag_list_t* srcList); /** * Add a filter to the system. The tags of this filter will * be added to all applying components. */ void addFilter(filter_t* filter); /** * Forward the configuration of the components (as stored in the * configList to the ComponentConfigurators. */ void updateComponentConfigs(); }; #endif LogService-2.7.0/src/monitor/StateManager.cc000644 000765 000765 00000022100 11576373452 022346 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implementation for the StateManager class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "StateManager.hh" #include #include #include using namespace std; StateManager::StateManager(ReadConfig* readConfig, bool* success) { *success = false; this->dynamicTagsList = readConfig->getDynamicTags(); if (this->dynamicTagsList == NULL) { cout << "Internal Error (StateManager)\n"; } else { char* s; this->start = readConfig->getDynamicStartSuffix(); unsigned int l1 = strlen(start); this->stop = readConfig->getDynamicStopSuffix(); unsigned int l2 = strlen(stop); this->dynamicStarts = new tag_list_t(); this->dynamicStarts->length(this->dynamicTagsList->length()); this->dynamicStops = new tag_list_t(); this->dynamicStops->length(this->dynamicTagsList->length()); for (CORBA::ULong i = 0 ; i < this->dynamicTagsList->length() ; i++) { s = new char[strlen((*(this->dynamicTagsList))[i]) + l1 + 2]; sprintf(s, "%s_%s", (const char*)(*(this->dynamicTagsList))[i], this->start); (*(this->dynamicStarts))[i] = CORBA::string_dup(s); delete[] s; s = new char[strlen((*(this->dynamicTagsList))[i]) + l2 + 2]; sprintf(s, "%s_%s", (const char*)(*(this->dynamicTagsList))[i], this->stop); (*(this->dynamicStops))[i] = CORBA::string_dup(s); delete[] s; } } this->staticTagsList = readConfig->getStaticTags(); if (this->staticTagsList == NULL) { cout << "Internal Error (StateManager)\n"; } this->uniqueTagsList = readConfig->getUniqueTags(); if (this->uniqueTagsList == NULL) { cout << "Internal Error (StateManager)\n"; } this->stateList = new StateList(); *success = true; } StateManager::~StateManager() { if (this->dynamicTagsList != NULL) { delete this->dynamicTagsList; delete this->dynamicStarts; delete this->dynamicStops; delete[] this->start; delete[] this->stop; } if (this->staticTagsList != NULL) { delete this->staticTagsList; } if (this->uniqueTagsList != NULL) { delete this->uniqueTagsList; } delete this->stateList; } bool StateManager::check(log_msg_t* msg) { if (this->dynamicTagsList == NULL) { return false; } char* tag = msg->tag; char* name = msg->componentName; StateList::Iterator* it = NULL; bool found = false; log_msg_t* state = NULL; // Check if this tag belongs to the unique tag list for (CORBA::ULong i = 0 ; i < this->uniqueTagsList->length() ; i++) { if (strcmp(tag, (*(this->uniqueTagsList))[i]) == 0) { found = true; it = this->stateList->getIterator(); it->resetToLast(); while (it->hasCurrent()) { state = it->getCurrentRef(); if (strcmp(name, state->componentName) == 0 && strcmp(tag, state->tag) == 0) { it->removeCurrent(); break; } else { it->previousRef(); } } delete it; this->stateList->push(msg); } } if (!found) { found = false; // Check if this tag belongs to the dynamic starts tag list for (CORBA::ULong i = 0 ; i < this->dynamicStarts->length() ; i++) { if (strcmp(tag, (*(this->dynamicStarts))[i]) == 0) { found = true; this->stateList->push(msg); break; } } } if (!found) { found = false; // Check if this tag belongs to the dynamic stops tag list for (CORBA::ULong i = 0 ; i < this->dynamicStops->length() ; i++) { if (strcmp(tag, (*(this->dynamicStops))[i]) == 0) { found = true; unsigned int l1 = strlen(tag); unsigned int l2 = strlen(this->start); unsigned int l3 = strlen(this->stop); *(tag + l1 - l3) = '\0'; // trunc after the '_' char* s = new char[l1 + l2 - l3 + 1]; sprintf(s, "%s%s", tag, this->start); *(tag + l1 - l3) = *(this->stop); // restore the string it = this->stateList->getIterator(); it->resetToLast(); while (it->hasCurrent()) { state = it->getCurrentRef(); if (strcmp(name, state->componentName) == 0 && strcmp(s, state->tag) == 0) { it->removeCurrent(); break; } else { it->previousRef(); } } delete it; delete[] s; break; } } } if (!found) { found = false; // Check if this tag belongs to the static tag list for (CORBA::ULong i = 0 ; i < this->staticTagsList->length() ; i++) { if (strcmp(tag, (*(this->staticTagsList))[i]) == 0) { found = true; this->stateList->push(msg); break; } } } if (!found) { found = false; // Check if this tag is an IN or OUT tag if (strcmp(tag, "IN") == 0 ) { found = true; this->stateList->push(msg); } else if (strcmp(tag, "OUT") == 0) { found = true; it = this->stateList->getIterator(); while (it->hasCurrent()) { state = it->getCurrentRef(); if (strcmp(name, state->componentName) == 0) { it->removeCurrent(); } else { it->nextRef(); } } delete it; } } return found; } void StateManager::askForSystemState(OutBuffer* outBuffer) { if (outBuffer != NULL) { outBuffer->appendList(this->stateList); } } LogService-2.7.0/src/monitor/StateManager.hh000644 000765 000765 00000012213 11576373453 022365 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Header for the StateManager class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _STATEMANAGER_HH_ #define _STATEMANAGER_HH_ #include "LogTypes.hh" #include "ReadConfig.hh" #include "ToolList.hh" #include "FullLinkedList.hh" #include typedef FullLinkedList StateList; class StateManager { public: /** * Initialize the StateManager * The tags IN and OUT are always important. * @param readConfig ReadConfig reference * @param success used to indicated if the initialisation was successfull. */ StateManager(ReadConfig* readConfig, bool* success); ~StateManager(); /** * To know if a message must be broadcast to all Tools * By the same time register it if necessary (Important Tag) * @param msg Message to check and/or register * @return true if the message must be boradcast */ bool check(log_msg_t* msg); /** * Call by the LogCentraTool_impl to send the current SystemState * to a new tool. * @param toolName name of the tool to send the SystemState */ void askForSystemState(OutBuffer* outBuffer); private: tag_list_t* dynamicTagsList; tag_list_t* dynamicStarts; tag_list_t* dynamicStops; tag_list_t* staticTagsList; tag_list_t* uniqueTagsList; char* start; char* stop; ToolList* toolList; StateList* stateList; }; #endif LogService-2.7.0/src/monitor/TimeBuffer.cc000644 000765 000765 00000013141 11576373452 022030 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Implementation for the TimeBuffer class */ /* */ /* Author(s): */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2011/02/04 15:13:02 bdepardo * isOlder is now const * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "TimeBuffer.hh" #include using namespace std; TimeBuffer::TimeBuffer() { this->msgList = new MsgLinkedList(); this->lastTime.sec = 0; this->lastTime.msec = 0; } TimeBuffer::~TimeBuffer() { delete this->msgList; } void TimeBuffer::put(log_msg_t* msg) { msg->warning = false; // To get an read/write iterator for the messages list MsgLinkedList::Iterator* it = this->msgList->getIterator(); // find the good place to insert the message (according to its timestamp) // Messages are order from older messages to newer messages (e.g. newer // messages are on the top of the list) it->resetToLast(); // go at the end of the list while (it->hasCurrent()) { if (!isOlder(it->getCurrentRef()->time, msg->time)) { break; } it->previousRef(); } if (it->hasCurrent()) { it->insertAfter(msg); } else { // must insert in the first position if (this->isOlder(msg->time, this->lastTime)) { msg->warning = true; } it->reset(); it->insertBefore(msg); } delete it; } log_msg_t* TimeBuffer::get(log_time_t minAge) { log_msg_t* msg = NULL; MsgLinkedList::Iterator* it = this->msgList->getIterator(); if (it->hasCurrent()) { // check the age limit if (this->isOlder(minAge, it->getCurrentRef()->time)) { msg = it->removeAndGetCurrent(); // get and delete the current element this->lastTime = msg->time; } } delete it; return msg; } // true if t2 older than t1 bool TimeBuffer::isOlder(log_time_t t1, log_time_t t2) const { // important not to use <= return ((t2.sec < t1.sec) || ((t2.sec == t1.sec) && (t2.msec < t1.msec))); } LogService-2.7.0/src/monitor/TimeBuffer.hh000644 000765 000765 00000011541 11576373453 022045 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Header for the TimeBuffer class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2011/02/04 15:13:02 bdepardo * isOlder is now const * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _TIMEBUFFER_HH_ #define _TIMEBUFFER_HH_ #include "LogTypes.hh" #include "FullLinkedList.hh" class TimeBuffer { public: TimeBuffer(); ~TimeBuffer(); /** * Put a new message in the buffer * @param msg the new message to add */ void put(log_msg_t* msg); /** * Get the older msg if its age is older than the minAge, * else get NULL * @param minAge the mininum age that messages must have to return one * @return a message or NULL */ log_msg_t* get(log_time_t minAge); private: typedef FullLinkedList MsgLinkedList; MsgLinkedList* msgList; log_time_t lastTime; /** * Compares the two log_time_t t1 and t2 * @param t1 the first time to compare * @param t2 the time for comparing t1 to * @returns true if t2 is older than t1, else false */ bool isOlder(log_time_t t1, log_time_t t2) const; }; #endif LogService-2.7.0/src/monitor/ToolList.hh000644 000765 000765 00000011527 11576373453 021572 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* defines a list that holds all information an tools connected to the */ /* new Logservice */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ***************************************************************************/ #ifndef _TOOLLIST_HH_ #define _TOOLLIST_HH_ #include "FullLinkedList.hh" #include "LogTool.hh" typedef FullLinkedList OutBuffer; typedef FullLinkedList FilterList; /** * All information that is stored for each Tool * (filterlist, output buffer, proxy) */ struct ToolElement { ToolMsgReceiver_var msgReceiver; OutBuffer outBuffer; FilterList filterList; CORBA::String_var toolName; }; /** * Define a ToolList for the ToolElements * No Elements should be changed without * having a writeLock(Iterator) on the whole * List. * * Attention: This also applies to the nested * list filterList. If the filterlist is to be * changed, please also acquire a writelock on * the surrounding toolList. Only the outBuf * may be changed with a readOnly iterator * on the toolList. */ typedef FullLinkedList ToolList; #endif LogService-2.7.0/src/libraries/CMakeLists.txt000644 000765 000765 00000000234 11576373456 022521 0ustar00bdepardobdepardo000000 000000 ADD_SUBDIRECTORY( LogComponentBaseC++ ) ADD_SUBDIRECTORY( LogToolBaseC++ ) #ADD_SUBDIRECTORY( LogComponentBaseJava ) #ADD_SUBDIRECTORY( LogToolBaseJava ) LogService-2.7.0/src/libraries/LogComponentBaseC++/000755 000765 000765 00000000000 11576373457 023413 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/libraries/LogComponentBaseJava/000755 000765 000765 00000000000 11576373460 023756 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/libraries/LogToolBaseC++/000755 000765 000765 00000000000 11576373461 022361 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/libraries/LogToolBaseJava/000755 000765 000765 00000000000 11576373461 022732 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/src/libraries/LogToolBaseJava/boolean_out.java000644 000765 000765 00000007511 11576373461 026107 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* boolean_out class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $@Id * $@Log * ****************************************************************************/ /** * For using a boolean as an out argument */ public class boolean_out { boolean value; } LogService-2.7.0/src/libraries/LogToolBaseJava/CMakeLists.txt000644 000765 000765 00000000374 11576373456 025502 0ustar00bdepardobdepardo000000 000000 FILE( GLOB LOGSERVICE_LOGTOOLBASEJAVA_SOURCES_GLOB "*.java" ) FOREACH(file ${LOGSERVICE_LOGTOOLBASEJAVA_SOURCES_GLOB} ) INSTALL( FILES ${file} DESTINATION lib/LogServiceLogToolBaseJava ) ENDFOREACH(file ${LOGSERVICE_LOGTOOLBASEJAVA_SOURCES_GLOB} ) LogService-2.7.0/src/libraries/LogToolBaseJava/LogToolBase.java000644 000765 000765 00000022026 11576373461 025751 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogToolBase class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.7 2003/12/12 19:36:13 cpontvie * New version of ORBTools (using the POA bidir in C++) and fully handle the * servants activation. * * Revision 1.6 2003/11/21 11:02:27 cpontvie * Catch more exceptions, that allow the component/tool to not crash if the * LogCentral crash. * * Revision 1.5 2003/11/19 18:54:47 cpontvie * Fix some bugs (out args) * * Revision 1.4 2003/11/18 10:53:01 cpontvie * Change the constructor * * Revision 1.3 2003/11/17 15:26:15 cpontvie * Modify constructors to fit the new ORBTools class * * Revision 1.2 2003/11/17 14:21:52 cpontvie * Implementation done. * * Revision 1.1 2003/11/12 21:23:48 cpontvie * Add a structure for the LCT and LTB. Add a new ORBTools class for Java. Make * servant for Java from the idls. The 'lib' directory contains static C++ * libraries and Java jar files. * ****************************************************************************/ import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; public class LogToolBase { public LogToolBase(boolean_out success, String[] args, int tracelevel, int port) { success.value = false; this.partialInit = false; this.name = ""; if (!ORBTools.init(args, tracelevel, port)) { return; } CORBA_Object_out objout = new CORBA_Object_out(); if (!ORBTools.findServant("LogService", "", "LogTool", "", objout)) { System.out.println("Cannot contact the LogTool servant of " + "LogService !"); return; } this.LCTref = LogCentralToolHelper.narrow(objout.value); this.TMRimpl = new ToolMsgReceiverImpl(this); if (!ORBTools.activateServant(this.TMRimpl, this.id)) { System.out.println("Cannot activate the ToolMsgReceiver servant !"); return; } if (!ORBTools.activatePOA()) { return; } this.TMRref = this.TMRimpl._this(); success.value = true; } public LogToolBase(boolean_out success, org.omg.CORBA.ORB orb) { success.value = false; this.partialInit = true; this.name = ""; //find the POA try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("RootPOA"); try { ORBTools.poa = org.omg.PortableServer.POAHelper.narrow(objRef); ORBTools.pman = ORBTools.poa.the_POAManager(); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to find the POA."); return; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return; } // Activate the POA if it is not already activate ORBTools.activatePOA(); CORBA_Object_out objout = new CORBA_Object_out(); if (!ORBTools.findServant("LogService", "", "LogTool", "", objout)) { System.out.println("Cannot contact the LogTool servant of " + "LogService !"); return; } this.LCTref = LogCentralToolHelper.narrow(objout.value); this.TMRimpl = new ToolMsgReceiverImpl(this); if (!ORBTools.activateServant(this.TMRimpl, this.id)) { System.out.println("Cannot activate the ToolMsgReceiver servant !"); return; } this.TMRref = this.TMRimpl._this(); success.value = true; } // kind of destructor public void finalize() { this.TMRimpl = null; this.name = null; ORBTools.deactivateServant(this.id); if (!this.partialInit) { ORBTools.kill(); } } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public short connect() { short ret; StringHolder s = new StringHolder(this.name); try { ret = this.LCTref.connectTool(s, this.TMRref); } catch (Exception ex) { ret = 1; } this.name = s.value; return ret; } public short disconnect() { short ret; try { ret = this.LCTref.disconnectTool(this.name); } catch (Exception ex) { ret = 1; } return ret; } public short addFilter(filter_t filter) { short ret; try { ret = this.LCTref.addFilter(this.name, filter); } catch (Exception ex) { ret = 1; } return ret; } public short removeFilter(String filterName) { short ret; try { ret = this.LCTref.removeFilter(this.name, filterName); } catch (Exception ex) { ret = 1; } return ret; } public short flushAllFilters() { short ret; try { ret = this.LCTref.flushAllFilters(this.name); } catch (Exception ex) { ret = 1; } return ret; } public String[] getDefinedTags() { String[] ret; try { ret = this.LCTref.getDefinedTags(); } catch (Exception ex) { ret = null; } return ret; } public String[] getDefinedComponents() { String[] ret; try { ret = this.LCTref.getDefinedComponents(); } catch (Exception ex) { ret = null; } return ret; } public void sendMsg(log_msg_t msg) { } private LogCentralTool LCTref; private ToolMsgReceiverImpl TMRimpl; private ToolMsgReceiver TMRref; private boolean partialInit; private String name; private byte[] id; } LogService-2.7.0/src/libraries/LogToolBaseJava/ORBTools.java000644 000765 000765 00000052300 11576373461 025240 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ORBTools class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $@Id * $@Log * ****************************************************************************/ import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; final public class ORBTools { /** * Initialize the CORBA ORB. * See CORBA documentation for all possibles parameters. * @param args Array of parameters to pass to the ORB * @return true if the operation succeed */ public static boolean init(String args[]) { try { orb = org.omg.CORBA.ORB.init(args, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Initialize the CORBA ORB. * @param args Array of parameters to pass to the ORB * @param tracelevel The tracelevel of the ORB (from 0 to 50) * @param port the port to use for listenning servants (0 = default random) * @return true if the operation succeed */ public static boolean init(String args[], int tracelevel, int port) { String[] orbargs; if (port == 0) { orbargs = new String[args.length + 2]; System.arraycopy(args, 0, orbargs, 0, args.length); orbargs[orbargs.length - 2] = "-ORBtraceLevel"; orbargs[orbargs.length - 1] = new Integer(tracelevel).toString(); } else { orbargs = new String[args.length + 4]; System.arraycopy(args, 0, orbargs, 0, args.length); orbargs[orbargs.length - 4] = "-ORBtraceLevel"; orbargs[orbargs.length - 3] = new Integer(tracelevel).toString(); orbargs[orbargs.length - 2] = "-ORBendPoint"; orbargs[orbargs.length - 1] = new Integer(port).toString(); } try { orb = org.omg.CORBA.ORB.init(orbargs, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Initialize the CORBA ORB. * None argument is set, usefull for tests * @return true if the operation succeed */ public static boolean init() { try { orb = org.omg.CORBA.ORB.init((String[])null, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Register a servant to the Namming Service within a specific context and * name. Do not activate the servant. * @param contextName Name of the new context * @param contextKind Kind of the new context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the * rootpoa.servant_to_reference function) * @return true if the operation succeed */ public static boolean registerServant(final String contextName, final String contextKind, final String name, final String kind, org.omg.CORBA.Object objref) { if (orb == null) { return false; } if (objref == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] context = new NameComponent[1]; context[0] = new NameComponent(contextName, contextKind); NamingContext newcontext; try { newcontext = rootContext.bind_new_context(context); } catch(org.omg.CORBA.UserException ex2) { try { newcontext = NamingContextHelper.narrow(rootContext.resolve(context)); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Failed to narrow naming context."); return false; } } NameComponent[] servant = new NameComponent[1]; servant[0] = new NameComponent(name, kind); try { newcontext.bind(servant, objref); } catch(org.omg.CORBA.UserException ex4) { try { newcontext.rebind(servant, objref); } catch(org.omg.CORBA.UserException ex5) { System.out.println("Failed to bind the name."); return false; } } } catch(org.omg.CORBA.COMM_FAILURE ex6) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex7) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Register a servant to the Namming Service within the default context and * with a specific name. Do not activate the servant. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the * rootpoa.servant_to_reference function) * @return true if the operation succeed */ public static boolean registerServant(final String name, final String kind, org.omg.CORBA.Object objref) { if (orb == null) { return false; } if (objref == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] servant = new NameComponent[1]; servant[0] = new NameComponent(name, kind); try { rootContext.bind(servant, objref); } catch(org.omg.CORBA.UserException ex4) { try { rootContext.rebind(servant, objref); } catch(org.omg.CORBA.UserException ex5) { System.out.println("Failed to bind the name."); return false; } } } catch(org.omg.CORBA.COMM_FAILURE ex6) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex7) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Activate a servant. * After the IOR of the servant is known by the POA. * @param object The implementation of a servant * @param id the id correspounding to the activating object * @return true if the operation succeed */ public static boolean activateServant(org.omg.PortableServer.Servant object, byte[] id) { if (orb == null) { return false; } if (object == null) { return false; } try { if (poa != null) { id = poa.activate_object(object); } else { return false; } } catch(org.omg.CORBA.UserException ex) { return false; } return true; } /** * Deactivate a servant. * After this, the correspounding object cannot be called. * @param id the id correspounding to the activating object * @return true if the operation succeed */ public static boolean deactivateServant(byte[] id) { if (orb == null) { return false; } try { if (poa != null) { poa.deactivate_object(id); } else { return false; } } catch(org.omg.CORBA.UserException ex) { return false; } return true; } /** * Activate the POA (Portable Object Adaptor). * After all servants registered are accessible * @return true if the operation succeed */ public static boolean activatePOA() { if (orb == null) { return false; } if (poa != null) { return true; } try { pman = poa.the_POAManager(); pman.activate(); } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) { return false; } return true; } /** * Deactivate the POA (Portable Object Adaptor). * After this, all servants registered are inaccessible * @return true if the operation succeed */ static boolean deactivatePOA() { if (orb == null) { return false; } if (poa == null) { return false; } try { pman.deactivate(true, true); } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) { return false; } poa.destroy(true, true); pman = null; poa = null; return true; } /** * Unregister a servant to the Namming Service within a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ public static boolean unregisterServant(final String contextName, final String contextKind, final String name, final String kind) { if (orb == null) { return false; } NamingContext rootContext, context; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } NameComponent[] context2find = new NameComponent[1]; context2find[0] = new NameComponent(contextName, contextKind); try { try { context = NamingContextHelper.narrow( rootContext.resolve(context2find)); } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find servant."); return false; } NameComponent[] servant2find = new NameComponent[1]; servant2find[0] = new NameComponent(name, kind); try { context.unbind(servant2find); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Cannot unbind servant."); return false; } } catch(org.omg.CORBA.COMM_FAILURE ex4) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex5) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Unregister a servant to the Namming Service within the default context and * with a specific name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ public static boolean unregisterServant(final String name, final String kind) { if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] servant2find = new NameComponent[1]; servant2find[0] = new NameComponent(name, kind); try { rootContext.unbind(servant2find); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Cannot unbind servant."); return false; } } catch(org.omg.CORBA.COMM_FAILURE ex4) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex5) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Find a servant by asking the Namming Service with a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objout The new servant found (the obj returned is in the class) * @return true if the operation succeed */ public static boolean findServant(final String contextName, final String contextKind, final String name, final String kind, CORBA_Object_out objout) { objout.value = null; if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { System.out.println("Failed to narrow the root naming context."); return false; } NameComponent nc1 = new NameComponent(contextName, contextKind); NameComponent nc2 = new NameComponent(name, kind); NameComponent path[] = {nc1, nc2}; try { org.omg.CORBA.Object objref = rootContext.resolve(path); objout.value = objref; } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find the servant."); return false; } catch(org.omg.CORBA.SystemException ex3) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Find a servant by asking the Namming Service with the default context and * name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objout The new servant found (the obj returned is in the class) * @return true if the operation succeed */ public static boolean findServant(final String name, final String kind, CORBA_Object_out objout) { objout.value = null; if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } NameComponent nc = new NameComponent(name, kind); NameComponent path[] = {nc}; try { org.omg.CORBA.Object objref = rootContext.resolve(path); objout.value = objref; } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find the servant."); return false; } catch(org.omg.CORBA.SystemException ex3) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Make the thread to listen for a incomming connection to a servant * @param stopString String that make the listen function to stop * @return true if the operation succeed */ public static boolean listen(String stopString) { if (orb == null) { return false; } String c = ""; java.io.BufferedReader inr = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); while (c.equals("")) { if (orb.work_pending()) { orb.perform_work(); } c =""; try { c = inr.readLine(); } catch(Exception ex) { c = ""; } } inr = null; return true; } /** * Destroy the ORB * @return true if the operation succeed */ public static boolean kill() { if (orb == null) { return false; } if (poa != null) { deactivatePOA(); } try { orb.shutdown(true); } catch(org.omg.CORBA.SystemException ex) { return false; } orb = null; poa = null; return true; } public static org.omg.CORBA.ORB orb = null; public static org.omg.PortableServer.POA poa = null; public static org.omg.PortableServer.POAManager pman = null; } LogService-2.7.0/src/libraries/LogToolBaseJava/ToolMsgReceiverImpl.java000644 000765 000765 00000010707 11576373461 027475 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ToolMsgReceiverImpl.java class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.1 2003/11/12 21:23:48 cpontvie * Add a structure for the LCT and LTB. Add a new ORBTools class for Java. Make * servant for Java from the idls. The 'lib' directory contains static C++ * libraries and Java jar files. * ****************************************************************************/ public class ToolMsgReceiverImpl extends ToolMsgReceiverPOA { public ToolMsgReceiverImpl(LogToolBase LTB) { this.LTB = LTB; } public void sendMsg(log_msg_t[] msgBuf) { for (int i = 0 ; i < msgBuf.length ; i++) { this.LTB.sendMsg(msgBuf[i]); } } private LogToolBase LTB; } LogService-2.7.0/src/libraries/LogToolBaseC++/CMakeLists.txt000644 000765 000765 00000001102 11576373456 025117 0ustar00bdepardobdepardo000000 000000 include_directories( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_SOURCE_DIR}/src/utils # For e.g. ORBTools.hh ${LOGSERVICE_BINARY_DIR}/src/idl ) add_library( LogServiceToolBase LogToolBase.cc) add_dependencies( LogServiceToolBase LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ) set_target_properties(LogServiceToolBase PROPERTIES VERSION ${LOGSERVICE_VERSION}) target_link_libraries( LogServiceToolBase LogForwarderUtils ${OMNIORB4_LIBRARIES} ) install( TARGETS LogServiceToolBase DESTINATION lib ) install( FILES LogToolBase.hh DESTINATION include ) include(CPack)LogService-2.7.0/src/libraries/LogToolBaseC++/LogToolBase.cc000644 000765 000765 00000016115 11576373461 025046 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogToolBase implementation class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.3 2010/11/10 04:24:41 bdepardo * LogServiceT instead of LogService * * Revision 1.2 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogToolBase.hh" #include "ORBTools.hh" #include using namespace std; ToolMsgReceiver_impl::ToolMsgReceiver_impl(LogToolBase* LTB) { this->LTB = LTB; } ToolMsgReceiver_impl::~ToolMsgReceiver_impl() { } void ToolMsgReceiver_impl::sendMsg(const log_msg_buf_t& msgBuf) { log_msg_t m; for (CORBA::ULong i = 0; i < msgBuf.length(); i++) { m = msgBuf[i]; this->LTB->sendMsg(m); } } /****************************************************************************/ LogToolBase::LogToolBase(bool* success, int argc, char** argv, unsigned int tracelevel, unsigned int port) { *success = false; this->name = new char[1]; *(this->name) = '\0'; if (!ORBTools::init(argc, argv, tracelevel, port)) { return; } CORBA::Object* object; if (!ORBTools::findServant("LogServiceT", "", "LCT", "", object)) { cout << "Cannot contact the LogTool servant of LogService!\n"; return; } this->LCTref = LogCentralTool::_narrow(object); this->TMRimpl = new ToolMsgReceiver_impl(this); if (!ORBTools::activateServant(this->TMRimpl)) { cout << "Cannot activate the ToolMsgReceiver servant !\n"; return; } if (!ORBTools::activatePOA()) { return; } this->TMRref = this->TMRimpl->_this(); // this->TMRimpl = NULL; try { // To make sure that the object is callable this->LCTref->test(); } catch (...) { return; } *success = true; } LogToolBase::~LogToolBase() { delete this->name; ORBTools::kill(); } void LogToolBase::setName(const char* name) { delete this->name; this->name = strdup(name); } char* LogToolBase::getName() { return strdup(this->name); } short LogToolBase::connect() { short ret; try { ret = this->LCTref->connectTool(this->name, this->getName()); // Modif TMRref } catch (...) { ret = 1; } return ret; } short LogToolBase::disconnect() { short ret; try { ret = this->LCTref->disconnectTool(this->name); } catch (...) { ret = 1; } return ret; } short LogToolBase::addFilter(const filter_t& filter) { short ret; try { ret = this->LCTref->addFilter(this->name, filter); } catch (...) { ret = 1; } return ret; } short LogToolBase::removeFilter(const char* filterName) { short ret; try { ret = this->LCTref->removeFilter(this->name, filterName); } catch (...) { ret = 1; } return ret; } short LogToolBase::flushAllFilters() { short ret; try { ret = this->LCTref->flushAllFilters(this->name); } catch (...) { ret = 1; } return ret; } tag_list_t* LogToolBase::getDefinedTags() { tag_list_t* ret; try { ret = this->LCTref->getDefinedTags(); } catch (...) { ret = NULL; } return ret; } component_list_t* LogToolBase::getDefinedComponents() { component_list_t* ret; try { ret = this->LCTref->getDefinedComponents(); } catch (...) { ret = NULL; } return ret; } LogService-2.7.0/src/libraries/LogToolBaseC++/LogToolBase.hh000644 000765 000765 00000011722 11576373461 025057 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogToolBase header class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGTOOLBASE_HH_ #define _LOGTOOLBASE_HH_ #include "LogTypes.hh" #include "LogTool.hh" class LogToolBase; class ToolMsgReceiver_impl: public POA_ToolMsgReceiver, public PortableServer::RefCountServantBase { public: ToolMsgReceiver_impl(LogToolBase* LTB); ~ToolMsgReceiver_impl(); void sendMsg(const log_msg_buf_t& msgBuf); private: LogToolBase* LTB; }; class LogToolBase { public: LogToolBase(bool* succes, int argc, char** argv, unsigned int tracelevel, unsigned int port = 0); virtual ~LogToolBase(); void setName(const char* name); char* getName(); short connect(); short disconnect(); short addFilter(const filter_t& filter); short removeFilter(const char* filterName); short flushAllFilters(); tag_list_t* getDefinedTags(); component_list_t* getDefinedComponents(); virtual void sendMsg(const log_msg_t& msg) = 0; private: LogCentralTool_var LCTref; ToolMsgReceiver_impl* TMRimpl; ToolMsgReceiver_var TMRref; char* name; }; #endif LogService-2.7.0/src/libraries/LogComponentBaseJava/boolean_out.java000644 000765 000765 00000007510 11576373457 027140 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* boolean_out class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $@Id * $@Log * ****************************************************************************/ /** * For using a boolean as an out argument */ public class boolean_out { boolean value; } LogService-2.7.0/src/libraries/LogComponentBaseJava/CMakeLists.txt000644 000765 000765 00000000415 11576373456 026523 0ustar00bdepardobdepardo000000 000000 FILE( GLOB LOGSERVICE_LOGCOMPONENTBASEJAVA_SOURCES_GLOB "*.java" ) FOREACH(file ${LOGSERVICE_LOGCOMPONENTBASEJAVA_SOURCES_GLOB} ) INSTALL( FILES ${file} DESTINATION lib/LogServiceComponentBaseJava ) ENDFOREACH(file ${LOGSERVICE_LOGCOMPONENTBASEJAVA_SOURCES_GLOB} ) LogService-2.7.0/src/libraries/LogComponentBaseJava/ComponentConfiguratorImpl.java000644 000765 000765 00000012415 11576373460 031773 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ComponentConfiguratorImpl.java class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.1 2003/11/18 10:51:32 cpontvie * Add the LogComponentBase libraries * ****************************************************************************/ import java.util.*; public class ComponentConfiguratorImpl extends ComponentConfiguratorPOA { public ComponentConfiguratorImpl(LogComponentBase LCB) { this.LCB = LCB; } public void setTagFilter(String[] tagList) { this.LCB.currentTagList = tagList; } public void addTagFilter(String[] tagList) { HashSet list = new HashSet(Arrays.asList(this.LCB.currentTagList)); for (int i = 0 ; i < tagList.length ; i++) { list.add(tagList[i]); } this.LCB.currentTagList = (String[])list.toArray(); } public void removeTagFilter(String[] tagList) { HashSet list = new HashSet(Arrays.asList(this.LCB.currentTagList)); for (int i = 0 ; i < tagList.length ; i++) { list.remove(tagList[i]); } this.LCB.currentTagList = (String[])list.toArray(); } public void test() { } private LogComponentBase LCB; } LogService-2.7.0/src/libraries/LogComponentBaseJava/FlushBufferThread.java000644 000765 000765 00000013214 11576373460 030165 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* FlushBuffer thread */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.4 2003/11/21 11:02:27 cpontvie * Catch more exceptions, that allow the component/tool to not crash if the * LogCentral crash. * * Revision 1.3 2003/11/20 09:18:16 cpontvie * Remove some debug messages * * Revision 1.2 2003/11/19 17:50:32 cpontvie * Now the threads are running properly (non blocant) * * Revision 1.1 2003/11/18 10:51:32 cpontvie * Add the LogComponentBase libraries * ****************************************************************************/ import java.lang.Thread; import java.util.*; public class FlushBufferThread extends Thread { final long FLUSHBUFFERTHREAD_SLEEP_TIME_MSEC = 50; final int FLUSHBUFFERTHREAD_SLEEP_TIME_NSEC = 0; public FlushBufferThread(LogComponentBase LCB) { this.LCB = LCB; this.name = this.LCB.getName(); this.threadRunning = false; } public void startThread() { this.threadRunning = true; try { this.start(); } catch (Exception ex) { System.out.println("Exception raised while runnning the FlushBuffer " + "thread !"); } } public void stopThread() { this.threadRunning = false; try { join(); } catch (Exception ex) { System.out.println("Exception raised while stopping the FlushBuffer " + "thread !"); } } public void run() { while (this.threadRunning) { try { this.LCB.LCCref.sendBuffer(this.LCB.buffer); this.LCB.buffer = new log_msg_t[0]; } catch (Exception ex1) { } try { sleep(FLUSHBUFFERTHREAD_SLEEP_TIME_MSEC, FLUSHBUFFERTHREAD_SLEEP_TIME_NSEC); } catch (Exception ex2) { System.out.println("Sleep problem in FlushBuffer thread"); } } } private LogComponentBase LCB; private String name; private boolean threadRunning; } LogService-2.7.0/src/libraries/LogComponentBaseJava/LogComponentBase.java000644 000765 000765 00000027706 11576373460 030034 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogComponentBase class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.6 2003/12/12 19:36:13 cpontvie * New version of ORBTools (using the POA bidir in C++) and fully handle the * servants activation. * * Revision 1.5 2003/11/21 11:02:27 cpontvie * Catch more exceptions, that allow the component/tool to not crash if the * LogCentral crash. * * Revision 1.4 2003/11/20 09:15:54 cpontvie * Remove a debug message * * Revision 1.3 2003/11/19 17:51:44 cpontvie * New version of the LogComponentBase in Java that correct some bugs in the * initalization and in the sendMsg method. * * Revision 1.2 2003/11/18 18:41:14 cpontvie * Catch more exceptions * * Revision 1.1 2003/11/18 10:51:32 cpontvie * Add the LogComponentBase libraries * ****************************************************************************/ import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.*; import java.net.InetAddress; public class LogComponentBase { public LogComponentBase(boolean_out success, String[] args, int tracelevel, int port) { success.value = false; this.partialInit = false; this.name = ""; try { InetAddress ia[] = InetAddress.getAllByName( InetAddress.getLocalHost().getHostName() ); if (ia.length != 0) { this.hostname = ia[0].getHostName(); } else { this.hostname = "unknownhost"; } } catch (java.net.UnknownHostException ex) { this.hostname = "unknownhost"; } if (!ORBTools.init(args, tracelevel, port)) { System.out.println("Cannot initialize the ORB !"); return; } CORBA_Object_out objout = new CORBA_Object_out(); if (!ORBTools.findServant("LogService", "", "LogComponent", "", objout)) { System.out.println("Cannot contact the LogComponent servant of " + "LogService (not found) !"); return; } this.LCCref = LogCentralComponentHelper.narrow(objout.value); this.CCimpl = new ComponentConfiguratorImpl(this); if (!ORBTools.activateServant(this.CCimpl, this.id)) { System.out.println("Cannot activate the ComponentConfigurator servant !"); return; } if (!ORBTools.activatePOA()) { System.out.println("Cannot activate the POA !"); return; } this.CCref = this.CCimpl._this(); this.pingThread = null; this.flushBufferThread = null; try { // To make sure that the object is callable this.LCCref.test(); } catch (Exception ex2) { System.out.println("Cannot contact the LogComponent servant of " + "LogService, even if it was found !"); return; } this.currentTagList = new String[0]; this.buffer = new log_msg_t[0]; success.value = true; } public LogComponentBase(boolean_out success, org.omg.CORBA.ORB orb) { success.value = false; this.partialInit = true; this.name = ""; try { InetAddress ia[] = InetAddress.getAllByName( InetAddress.getLocalHost().getHostName() ); if (ia.length != 0) { this.hostname = ia[0].getHostName(); } else { this.hostname = "unknownhost"; } } catch (java.net.UnknownHostException ex) { this.hostname = "unknownhost"; } ORBTools.orb = orb; //find the POA try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("RootPOA"); try { ORBTools.poa = org.omg.PortableServer.POAHelper.narrow(objRef); ORBTools.pman = ORBTools.poa.the_POAManager(); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to find the POA."); return; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return; } // Activate the POA if it is not already activate ORBTools.activatePOA(); CORBA_Object_out objout = new CORBA_Object_out(); if (!ORBTools.findServant("LogService", "", "LogComponent", "", objout)) { System.out.println("Cannot contact the LogComponent servant of " + "LogService (not found) !"); return; } this.LCCref = LogCentralComponentHelper.narrow(objout.value); this.CCimpl = new ComponentConfiguratorImpl(this); if (!ORBTools.activateServant(this.CCimpl, this.id)) { System.out.println("Cannot activate the ComponentConfigurator servant !"); return; } this.CCref = this.CCimpl._this(); this.pingThread = null; this.flushBufferThread = null; try { // To make sure that the object is callable this.LCCref.test(); } catch (Exception ex2) { System.out.println("Cannot contact the LogComponent servant of " + "LogService, even if it was found !"); return; } this.currentTagList = new String[0]; this.buffer = new log_msg_t[0]; success.value = true; } // kind of destructor public void finalize() { if (this.pingThread != null) { this.pingThread.stopThread(); this.pingThread = null; } if (this.flushBufferThread != null) { this.flushBufferThread.stopThread(); this.flushBufferThread = null; } this.name = null; this.hostname = null; this.CCimpl = null; ORBTools.deactivateServant(this.id); if (!this.partialInit) { ORBTools.kill(); } } public void setName(String name) { if (this.pingThread != null) { this.disconnect("change of name"); } this.name = name; } public String getName() { return this.name; } public String getHostname() { return this.hostname; } public short connect(String message) { if (this.pingThread != null) { this.disconnect("for immediate reconnection"); } short ret; StringHolder s = new StringHolder(this.name); long epoch = System.currentTimeMillis(); long sec = epoch / 1000; long msec = epoch - (sec * 1000); log_time_t lt = new log_time_t(sec, (int)msec); String[] initialConfigValue = new String[0]; tag_list_tHolder initialConfig = new tag_list_tHolder(initialConfigValue); try { ret = this.LCCref.connectComponent( s, this.hostname, message, this.CCref, lt, initialConfig ); } catch (Exception ex) { return 1; } this.name = s.value; this.currentTagList = initialConfig.value; this.pingThread = new PingThread(this); this.flushBufferThread = new FlushBufferThread(this); this.pingThread.startThread(); this.flushBufferThread.startThread(); return ret; } public short disconnect(String message) { if (this.pingThread == null) { return LS_OK.value; } this.pingThread.stopThread(); this.flushBufferThread.stopThread(); this.pingThread = null; this.flushBufferThread = null; short ret; try { ret = this.LCCref.disconnectComponent(this.name, message); } catch (Exception ex) { ret = 1; } return 1; } public void sendMsg(String tag, String msg) { long epoch = System.currentTimeMillis(); long sec = epoch / 1000; long msec = epoch - (sec * 1000); log_time_t lt = new log_time_t(sec, (int)msec); log_msg_t logmsg = new log_msg_t( this.name, lt, false, tag, msg ); log_msg_t[] list = new log_msg_t[this.buffer.length + 1]; System.arraycopy(this.buffer, 0, list, 0, this.buffer.length); list[this.buffer.length] = logmsg; this.buffer = list; } public String getHostnameOf(String componentName) { String ret; try { ret = this.LCCref.getHostnameOf(componentName); } catch (Exception ex) { ret = null; } return ret; } public boolean isLog(String tagname) { ArrayList list = new ArrayList(Arrays.asList(this.currentTagList)); return list.contains(tagname); } public LogCentralComponent LCCref; public String[] currentTagList; public log_msg_t[] buffer; private ComponentConfiguratorImpl CCimpl; private ComponentConfigurator CCref; private boolean partialInit; private String name; private String hostname; private PingThread pingThread; private FlushBufferThread flushBufferThread; private byte[] id; } LogService-2.7.0/src/libraries/LogComponentBaseJava/ORBTools.java000644 000765 000765 00000052300 11576373460 026264 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ORBTools class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $@Id * $@Log * ****************************************************************************/ import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; final public class ORBTools { /** * Initialize the CORBA ORB. * See CORBA documentation for all possibles parameters. * @param args Array of parameters to pass to the ORB * @return true if the operation succeed */ public static boolean init(String args[]) { try { orb = org.omg.CORBA.ORB.init(args, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Initialize the CORBA ORB. * @param args Array of parameters to pass to the ORB * @param tracelevel The tracelevel of the ORB (from 0 to 50) * @param port the port to use for listenning servants (0 = default random) * @return true if the operation succeed */ public static boolean init(String args[], int tracelevel, int port) { String[] orbargs; if (port == 0) { orbargs = new String[args.length + 2]; System.arraycopy(args, 0, orbargs, 0, args.length); orbargs[orbargs.length - 2] = "-ORBtraceLevel"; orbargs[orbargs.length - 1] = new Integer(tracelevel).toString(); } else { orbargs = new String[args.length + 4]; System.arraycopy(args, 0, orbargs, 0, args.length); orbargs[orbargs.length - 4] = "-ORBtraceLevel"; orbargs[orbargs.length - 3] = new Integer(tracelevel).toString(); orbargs[orbargs.length - 2] = "-ORBendPoint"; orbargs[orbargs.length - 1] = new Integer(port).toString(); } try { orb = org.omg.CORBA.ORB.init(orbargs, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Initialize the CORBA ORB. * None argument is set, usefull for tests * @return true if the operation succeed */ public static boolean init() { try { orb = org.omg.CORBA.ORB.init((String[])null, null); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } org.omg.CORBA.Object obj; try { obj = orb.resolve_initial_references("RootPOA"); } catch(org.omg.CORBA.ORBPackage.InvalidName ex) { orb = null; return false; } try { poa = POAHelper.narrow(obj); } catch(org.omg.CORBA.SystemException ex) { orb = null; return false; } return true; } /** * Register a servant to the Namming Service within a specific context and * name. Do not activate the servant. * @param contextName Name of the new context * @param contextKind Kind of the new context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the * rootpoa.servant_to_reference function) * @return true if the operation succeed */ public static boolean registerServant(final String contextName, final String contextKind, final String name, final String kind, org.omg.CORBA.Object objref) { if (orb == null) { return false; } if (objref == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] context = new NameComponent[1]; context[0] = new NameComponent(contextName, contextKind); NamingContext newcontext; try { newcontext = rootContext.bind_new_context(context); } catch(org.omg.CORBA.UserException ex2) { try { newcontext = NamingContextHelper.narrow(rootContext.resolve(context)); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Failed to narrow naming context."); return false; } } NameComponent[] servant = new NameComponent[1]; servant[0] = new NameComponent(name, kind); try { newcontext.bind(servant, objref); } catch(org.omg.CORBA.UserException ex4) { try { newcontext.rebind(servant, objref); } catch(org.omg.CORBA.UserException ex5) { System.out.println("Failed to bind the name."); return false; } } } catch(org.omg.CORBA.COMM_FAILURE ex6) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex7) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Register a servant to the Namming Service within the default context and * with a specific name. Do not activate the servant. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objref The implementation of a servant (result of the * rootpoa.servant_to_reference function) * @return true if the operation succeed */ public static boolean registerServant(final String name, final String kind, org.omg.CORBA.Object objref) { if (orb == null) { return false; } if (objref == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] servant = new NameComponent[1]; servant[0] = new NameComponent(name, kind); try { rootContext.bind(servant, objref); } catch(org.omg.CORBA.UserException ex4) { try { rootContext.rebind(servant, objref); } catch(org.omg.CORBA.UserException ex5) { System.out.println("Failed to bind the name."); return false; } } } catch(org.omg.CORBA.COMM_FAILURE ex6) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex7) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Activate a servant. * After the IOR of the servant is known by the POA. * @param object The implementation of a servant * @param id the id correspounding to the activating object * @return true if the operation succeed */ public static boolean activateServant(org.omg.PortableServer.Servant object, byte[] id) { if (orb == null) { return false; } if (object == null) { return false; } try { if (poa != null) { id = poa.activate_object(object); } else { return false; } } catch(org.omg.CORBA.UserException ex) { return false; } return true; } /** * Deactivate a servant. * After this, the correspounding object cannot be called. * @param id the id correspounding to the activating object * @return true if the operation succeed */ public static boolean deactivateServant(byte[] id) { if (orb == null) { return false; } try { if (poa != null) { poa.deactivate_object(id); } else { return false; } } catch(org.omg.CORBA.UserException ex) { return false; } return true; } /** * Activate the POA (Portable Object Adaptor). * After all servants registered are accessible * @return true if the operation succeed */ public static boolean activatePOA() { if (orb == null) { return false; } if (poa != null) { return true; } try { pman = poa.the_POAManager(); pman.activate(); } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) { return false; } return true; } /** * Deactivate the POA (Portable Object Adaptor). * After this, all servants registered are inaccessible * @return true if the operation succeed */ static boolean deactivatePOA() { if (orb == null) { return false; } if (poa == null) { return false; } try { pman.deactivate(true, true); } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) { return false; } poa.destroy(true, true); pman = null; poa = null; return true; } /** * Unregister a servant to the Namming Service within a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ public static boolean unregisterServant(final String contextName, final String contextKind, final String name, final String kind) { if (orb == null) { return false; } NamingContext rootContext, context; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } NameComponent[] context2find = new NameComponent[1]; context2find[0] = new NameComponent(contextName, contextKind); try { try { context = NamingContextHelper.narrow( rootContext.resolve(context2find)); } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find servant."); return false; } NameComponent[] servant2find = new NameComponent[1]; servant2find[0] = new NameComponent(name, kind); try { context.unbind(servant2find); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Cannot unbind servant."); return false; } } catch(org.omg.CORBA.COMM_FAILURE ex4) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex5) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Unregister a servant to the Namming Service within the default context and * with a specific name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @return true if the operation succeed */ public static boolean unregisterServant(final String name, final String kind) { if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } try { NameComponent[] servant2find = new NameComponent[1]; servant2find[0] = new NameComponent(name, kind); try { rootContext.unbind(servant2find); } catch(org.omg.CORBA.UserException ex3) { System.out.println("Cannot unbind servant."); return false; } } catch(org.omg.CORBA.COMM_FAILURE ex4) { System.out.println("Caught system exception COMM_FAILURE -- unable to " + "contact the naming service."); return false; } catch(org.omg.CORBA.SystemException ex5) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Find a servant by asking the Namming Service with a specific context and * name. * @param contextName Name of the context * @param contextKind Kind of the context (extra information) * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objout The new servant found (the obj returned is in the class) * @return true if the operation succeed */ public static boolean findServant(final String contextName, final String contextKind, final String name, final String kind, CORBA_Object_out objout) { objout.value = null; if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { System.out.println("Failed to narrow the root naming context."); return false; } NameComponent nc1 = new NameComponent(contextName, contextKind); NameComponent nc2 = new NameComponent(name, kind); NameComponent path[] = {nc1, nc2}; try { org.omg.CORBA.Object objref = rootContext.resolve(path); objout.value = objref; } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find the servant."); return false; } catch(org.omg.CORBA.SystemException ex3) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Find a servant by asking the Namming Service with the default context and * name. * @param name Name of the servant * @param kind Kind of the servant (extra information) * @param objout The new servant found (the obj returned is in the class) * @return true if the operation succeed */ public static boolean findServant(final String name, final String kind, CORBA_Object_out objout) { objout.value = null; if (orb == null) { return false; } NamingContext rootContext; try { org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); try { rootContext = NamingContextHelper.narrow(objRef); } catch(org.omg.CORBA.SystemException ex) { System.out.println("Failed to narrow the root naming context."); return false; } } catch(org.omg.CORBA.ORBPackage.InvalidName ex1) { return false; } NameComponent nc = new NameComponent(name, kind); NameComponent path[] = {nc}; try { org.omg.CORBA.Object objref = rootContext.resolve(path); objout.value = objref; } catch(org.omg.CORBA.UserException ex2) { System.out.println("Cannot find the servant."); return false; } catch(org.omg.CORBA.SystemException ex3) { System.out.println("Caught a CORBA::SystemException while using the " + "naming service."); return false; } return true; } /** * Make the thread to listen for a incomming connection to a servant * @param stopString String that make the listen function to stop * @return true if the operation succeed */ public static boolean listen(String stopString) { if (orb == null) { return false; } String c = ""; java.io.BufferedReader inr = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); while (c.equals("")) { if (orb.work_pending()) { orb.perform_work(); } c =""; try { c = inr.readLine(); } catch(Exception ex) { c = ""; } } inr = null; return true; } /** * Destroy the ORB * @return true if the operation succeed */ public static boolean kill() { if (orb == null) { return false; } if (poa != null) { deactivatePOA(); } try { orb.shutdown(true); } catch(org.omg.CORBA.SystemException ex) { return false; } orb = null; poa = null; return true; } public static org.omg.CORBA.ORB orb = null; public static org.omg.PortableServer.POA poa = null; public static org.omg.PortableServer.POAManager pman = null; } LogService-2.7.0/src/libraries/LogComponentBaseJava/PingThread.java000644 000765 000765 00000014060 11576373460 026647 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Ping thread */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * * Revision 1.4 2003/11/21 11:02:27 cpontvie * Catch more exceptions, that allow the component/tool to not crash if the * LogCentral crash. * * Revision 1.3 2003/11/20 09:18:16 cpontvie * Remove some debug messages * * Revision 1.2 2003/11/19 17:50:32 cpontvie * Now the threads are running properly (non blocant) * * Revision 1.1 2003/11/18 10:51:32 cpontvie * Add the LogComponentBase libraries * ****************************************************************************/ import java.lang.Thread; import java.util.*; public class PingThread extends Thread { final long PINGTHREAD_SLEEP_TIME_MSEC = 1000; final int PINGTHREAD_SLEEP_TIME_NSEC = 0; final int PINGTHREAD_SYNCHRO_FREQUENCY = 60; public PingThread(LogComponentBase LCB) { this.LCB = LCB; this.name = this.LCB.getName(); this.threadRunning = false; } public void startThread() { this.threadRunning = true; try { this.start(); } catch (Exception ex) { System.out.println("Exception raised while runnning the Ping thread !"); } } public void stopThread() { this.threadRunning = false; try { join(); } catch (Exception ex) { System.out.println("Exception raised while stopping the Ping thread !"); } } public void run() { int counter = 0; log_time_t lt; while (this.threadRunning) { try { this.LCB.LCCref.ping(this.name); } catch (Exception ex1) { } if (counter == PINGTHREAD_SYNCHRO_FREQUENCY) { lt = this.getLocalTime(); try { this.LCB.LCCref.synchronize(this.name, lt); } catch (Exception ex2) { } counter = 0; } counter++; try { sleep(PINGTHREAD_SLEEP_TIME_MSEC, PINGTHREAD_SLEEP_TIME_NSEC); } catch (Exception ex3) { System.out.println("Sleep problem in Ping thread"); } } } private log_time_t getLocalTime() { long epoch = System.currentTimeMillis(); long sec = epoch / 1000; long msec = epoch - (sec * 1000); log_time_t ret = new log_time_t(sec, (int)msec); return ret; } private LogComponentBase LCB; private String name; private boolean threadRunning; } LogService-2.7.0/src/libraries/LogComponentBaseC++/CMakeLists.txt000644 000765 000765 00000001374 11576373456 026157 0ustar00bdepardobdepardo000000 000000 include_directories( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_SOURCE_DIR}/src/utils # For e.g. ORBTools.hh ${LOGSERVICE_BINARY_DIR}/src/idl ) add_library( LogServiceComponentBase LogComponentBase.cc ComponentConfigurator_impl.cc PingThread.cc FlushBufferThread.cc ) add_dependencies( LogServiceComponentBase LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ) set_target_properties(LogServiceComponentBase PROPERTIES VERSION ${LOGSERVICE_VERSION}) target_link_libraries( LogServiceComponentBase LogForwarderUtils ${OMNIORB4_LIBRARIES} ) install( TARGETS LogServiceComponentBase DESTINATION lib ) install( FILES LogComponentBase.hh ComponentConfigurator_impl.hh FlushBufferThread.hh PingThread.hh DESTINATION include ) include(CPack)LogService-2.7.0/src/libraries/LogComponentBaseC++/ComponentConfigurator_impl.cc000644 000765 000765 00000014021 11576373456 031265 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ComponentConfigurator_impl implementation class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogComponentBase.hh" #include "ORBTools.hh" #include #include #include using namespace std; ComponentConfigurator_impl::ComponentConfigurator_impl(LogComponentBase* LCB) { this->LCB = LCB; } ComponentConfigurator_impl::~ComponentConfigurator_impl() { } void ComponentConfigurator_impl::setTagFilter(const tag_list_t& tagList) { this->LCB->currentTagList = tagList; } void ComponentConfigurator_impl::addTagFilter(const tag_list_t& tagList) { CORBA::ULong l1 = this->LCB->currentTagList.length(); CORBA::ULong l2 = tagList.length(); bool found = false; for (CORBA::ULong i = 0 ; i < l2 ; i++) { found = false; for (CORBA::ULong j = 0 ; j < l1 + i ; j++) { if (strcmp(tagList[i], this->LCB->currentTagList[j]) == 0) { found = true; break; } } if (!found) { this->LCB->currentTagList.length(l1 + i + 1); this->LCB->currentTagList[l1 + i] = tagList[i]; } } } void ComponentConfigurator_impl::removeTagFilter(const tag_list_t& tagList) { tag_list_t oldtaglist = this->LCB->currentTagList; this->LCB->currentTagList.length(0); CORBA::ULong l1 = oldtaglist.length(); CORBA::ULong l2 = tagList.length(); CORBA::ULong l3 = 0; bool found = false; for (CORBA::ULong i = 0 ; i < l1 ; i++) { found = false; for (CORBA::ULong j = 0 ; j < l2 ; j++) { if (strcmp(oldtaglist[i], tagList[j]) == 0) { found = true; break; } } if (!found) { this->LCB->currentTagList.length(l3 + 1); this->LCB->currentTagList[l3++] = oldtaglist[i]; } } } void ComponentConfigurator_impl::test() { return; } LogService-2.7.0/src/libraries/LogComponentBaseC++/ComponentConfigurator_impl.hh000644 000765 000765 00000012046 11576373457 031305 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* ComponentConfigurator_impl header class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _COMPONENTCONFIGURATOR_IMPL_HH #define _COMPONENTCONFIGURATOR_IMPL_HH #include "LogTypes.hh" #include "LogComponent.hh" #include "LogComponentBase.hh" #include class LogComponentBase; class ComponentConfigurator_impl: public POA_ComponentConfigurator, public PortableServer::RefCountServantBase { public: ComponentConfigurator_impl(LogComponentBase* LCB); ~ComponentConfigurator_impl(); void setTagFilter(const tag_list_t& tagList); void addTagFilter(const tag_list_t& tagList); void removeTagFilter(const tag_list_t& tagList); void test(); private: LogComponentBase* LCB; }; #endif LogService-2.7.0/src/libraries/LogComponentBaseC++/FlushBufferThread.cc000644 000765 000765 00000012603 11576373457 027267 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* FlushBufferThread implementation class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogComponentBase.hh" #include "ORBTools.hh" #include #include #include using namespace std; FlushBufferThread::FlushBufferThread(LogComponentBase* LCB): LCB(LCB), threadRunning(false) { this->name = this->LCB->getName(); } FlushBufferThread::~FlushBufferThread() { if (this->threadRunning) { this->threadRunning = false; join(NULL); } delete this->name; } void FlushBufferThread::startThread() { if (this->threadRunning) { return; } this->threadRunning = true; start_undetached(); } void FlushBufferThread::stopThread() { if (!this->threadRunning) { return; } this->threadRunning = false; join(NULL); } void* FlushBufferThread::run_undetached(void* params) { while (this->threadRunning) { try { this->LCB->LCCref->sendBuffer(this->LCB->buffer); this->LCB->buffer.length(0); } catch (...) { } sleep(FLUSHBUFFERTHREAD_SLEEP_TIME_SEC, FLUSHBUFFERTHREAD_SLEEP_TIME_NSEC); } return NULL; } LogService-2.7.0/src/libraries/LogComponentBaseC++/FlushBufferThread.hh000644 000765 000765 00000011502 11576373457 027276 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* FlushBufferThread header class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _FLUSHBUFFERTHREAD_HH_ #define _FLUSHBUFFERTHREAD_HH_ #include "LogTypes.hh" #include "LogComponent.hh" #include class FlushBufferThread:public omni_thread { public: FlushBufferThread(LogComponentBase* LCB); ~FlushBufferThread(); void startThread(); void stopThread(); private: void* run_undetached(void* params); private: LogComponentBase* LCB; char* name; bool threadRunning; }; #endif LogService-2.7.0/src/libraries/LogComponentBaseC++/LogComponentBase.cc000644 000765 000765 00000022361 11576373456 027124 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogComponentBase implementation class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.8 2011/02/04 15:56:03 bdepardo * Add missing include * * Revision 1.7 2011/02/04 15:53:55 bdepardo * Use a const char* name in constructor, then strdup the name. * Then use free instead of delete on this->name * * Revision 1.6 2011/02/04 15:21:50 bdepardo * delete [] hostname instead of delete hostname * * Revision 1.5 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.4 2010/11/10 04:24:50 bdepardo * LogServiceC instead of LogService * * Revision 1.3 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include #include #include #include #include "LogComponentBase.hh" #include "ORBTools.hh" #include "../LogORBMgr.hh" using namespace std; LogComponentBase::LogComponentBase(bool* success, int argc, char** argv, unsigned int tracelevel, const char* name, unsigned int port) { *success = false; this->name = strdup(name); this->hostname = new char[256]; if (gethostname(hostname, 255)) { return; } if (!ORBTools::init(argc, argv, tracelevel, port)) { return; } CORBA::Object* object; if (!ORBTools::findServant("LogServiceC", "", "LCC", "", object)) { cerr << "Cannot contact the LogComponent servant of LogService!\n"; return; } this->LCCref = LogCentralComponent::_narrow(object); this->CCimpl = new ComponentConfigurator_impl(this); if (!ORBTools::activateServant(this->CCimpl)) { cerr << "Cannot activate the ComponentConfigurator servant !\n"; return; } if (!ORBTools::activatePOA()) { return; } this->CCref = this->CCimpl->_this(); this->CCimpl = NULL; this->pingThread = NULL; this->flushBufferThread = NULL; LogORBMgr::getMgr()->bind("LogServiceC", getName(), this->CCref, true); LogORBMgr::getMgr()->fwdsBind("LogServiceC", getName(), LogORBMgr::getMgr()->getIOR(this->CCref)); // Comment because test is empty // try { // To make sure that the object is callable // // this->LCCref->test(); // } catch (...) { // return; // } *success = true; } LogComponentBase::~LogComponentBase() { if (this->pingThread != NULL) { this->pingThread->stopThread(); } if (this->flushBufferThread != NULL) { this->flushBufferThread->stopThread(); } free(this->name); delete [] this->hostname; ORBTools::kill(); } void LogComponentBase::setName(const char* name) { if (this->pingThread != NULL) { this->disconnect("change of name"); } free(this->name); this->name = strdup(name); } char* LogComponentBase::getName() { return strdup(this->name); } char* LogComponentBase::getHostname() { return strdup(this->hostname); } short LogComponentBase::connect(const char* message) { if (this->pingThread != NULL) { this->disconnect("for immediate reconnection"); } short ret; CORBA::String_var corbaname = CORBA::string_dup(this->name); struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); log_time_t lt; lt.sec = tv.tv_sec; lt.msec = tv.tv_usec / 1000; try { ret = this->LCCref->connectComponent( corbaname, this->hostname, message, this->name, // MODIF, avant 'this->CC' lt, this->currentTagList ); } catch (...) { return 1; } // delete this->name; this->name = CORBA::string_dup(corbaname); this->pingThread = new PingThread(this); this->flushBufferThread = new FlushBufferThread(this); this->pingThread->startThread(); this->flushBufferThread->startThread(); return ret; } short LogComponentBase::disconnect(const char* message) { if (this->pingThread == NULL) { return LS_OK; } this->pingThread->stopThread(); this->flushBufferThread->stopThread(); this->pingThread = NULL; this->flushBufferThread = NULL; short ret; try { ret = this->LCCref->disconnectComponent(this->name, message); } catch (...) { ret = 1; } return ret; } void LogComponentBase::sendMsg(const char* tag, const char* msg) { log_msg_t logmsg; logmsg.componentName = CORBA::string_dup(this->name); logmsg.time = this->getLocalTime(); logmsg.warning = false; logmsg.tag = CORBA::string_dup(tag); logmsg.msg = CORBA::string_dup(msg); CORBA::ULong l = this->buffer.length(); this->buffer.length(l + 1); this->buffer[l] = logmsg; } bool LogComponentBase::isLog(const char* tagname) { bool ret = false; CORBA::ULong l = this->currentTagList.length(); for (CORBA::ULong i = 0 ; i < l ; i++) { if (strcmp(tagname, this->currentTagList[i]) == 0) { ret = true; break; } if (strcmp("*", this->currentTagList[i]) == 0) { ret = true; break; } } return ret; } log_time_t LogComponentBase::getLocalTime() { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); log_time_t ret; ret.sec = tv.tv_sec; ret.msec = tv.tv_usec / 1000; return ret; } LogService-2.7.0/src/libraries/LogComponentBaseC++/LogComponentBase.hh000644 000765 000765 00000013752 11576373456 027142 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* LogComponentBase header class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.5 2011/02/04 15:53:55 bdepardo * Use a const char* name in constructor, then strdup the name. * Then use free instead of delete on this->name * * Revision 1.4 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.3 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGCOMPONENTBASE_HH_ #define _LOGCOMPONENTBASE_HH_ #include #include "LogTypes.hh" #include "ComponentConfigurator_impl.hh" #include "PingThread.hh" #include "FlushBufferThread.hh" #include "LogComponent.hh" #define PINGTHREAD_SLEEP_TIME_SEC 1 #define PINGTHREAD_SLEEP_TIME_NSEC 0 #define PINGTHREAD_SYNCHRO_FREQUENCY 60 #define FLUSHBUFFERTHREAD_SLEEP_TIME_SEC 0 #define FLUSHBUFFERTHREAD_SLEEP_TIME_NSEC 50000000 class LogComponentBase; class LogComponentBase { public: LogComponentBase(bool* success, int argc, char** argv, unsigned int tracelevel, const char* name, unsigned int port = 0); ~LogComponentBase(); void setName(const char* name); char* getName(); char* getHostname(); short connect(const char* message); short disconnect(const char* message); void sendMsg(const char* tag, const char* msg); bool isLog(const char* tagname); private: log_time_t getLocalTime(); public: LogCentralComponent_var LCCref; ComponentConfigurator_var CCref; log_msg_buf_t buffer; tag_list_t currentTagList; private: char* name; char* hostname; ComponentConfigurator_impl* CCimpl; PingThread* pingThread; FlushBufferThread* flushBufferThread; }; #endif LogService-2.7.0/src/libraries/LogComponentBaseC++/PingThread.cc000644 000765 000765 00000013345 11576373457 025755 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* PingThread implementation class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogComponentBase.hh" #include "ORBTools.hh" #include #include #include using namespace std; PingThread::PingThread(LogComponentBase* LCB): LCB(LCB), threadRunning(false) { this->name = this->LCB->getName(); } PingThread::~PingThread() { if (this->threadRunning) { this->threadRunning = false; join(NULL); } delete this->name; } void PingThread::startThread() { if (this->threadRunning) { return; } this->threadRunning = true; start_undetached(); } void PingThread::stopThread() { if (!this->threadRunning) { return; } this->threadRunning = false; join(NULL); } void* PingThread::run_undetached(void* params) { unsigned int counter = 0; log_time_t lt; while (this->threadRunning) { try { this->LCB->LCCref->ping(this->name); } catch (...) { } if (counter == PINGTHREAD_SYNCHRO_FREQUENCY) { lt = this->getLocalTime(); try { this->LCB->LCCref->synchronize(this->name, lt); } catch (...) { } counter = 0; } counter++; sleep(PINGTHREAD_SLEEP_TIME_SEC, PINGTHREAD_SLEEP_TIME_NSEC); } return NULL; } log_time_t PingThread::getLocalTime() { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); log_time_t ret; ret.sec = tv.tv_sec; ret.msec = tv.tv_usec / 1000; return ret; } LogService-2.7.0/src/libraries/LogComponentBaseC++/PingThread.hh000644 000765 000765 00000011475 11576373457 025771 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* PingThread header class */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 03:02:28 kcoulomb * Add missing files * * Revision 1.2 2007/08/31 16:41:17 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _PINGTHREAD_HH_ #define _PINGTHREAD_HH_ #include "LogTypes.hh" #include "LogComponent.hh" #include class PingThread:public omni_thread { public: PingThread(LogComponentBase* LCB); ~PingThread(); void startThread(); void stopThread(); private: void* run_undetached(void* params); log_time_t getLocalTime(); private: LogComponentBase* LCB; char* name; bool threadRunning; }; #endif LogService-2.7.0/src/idl/CMakeLists.txt000644 000765 000765 00000005471 11576373447 021325 0ustar00bdepardobdepardo000000 000000 # LogService cmake local file # Generate the code out of the IDL source files and build the ad-hoc libraries. # (idl is part of omniORB which is mandatory) INCLUDE_DIRECTORIES( ${OMNIORB4_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # Define the flags for the IDL compiler SET( LOGSERVICE_IDL_FLAGS "-bcxx -Wba -Wbtp" CACHE STRING "Idl compiler flags" FORCE ) MARK_AS_ADVANCED( LOGSERVICE_IDL_FLAGS ) # Transform LOGSERVICE_IDL_FLAGS from a string to a string list containing # the arguments for omniidl SEPARATE_ARGUMENTS( LOGSERVICE_IDL_FLAGS ) SET( IDL_SOURCES LogComponent LogTool LogTypes CorbaLogForwarder LogComponentFwdr LogToolFwdr commonLogTypes ) # The C/C++ callers of the idl generated interface will include the # idl generated header files. The following technical variable is a # commidity for expressing this dependency (refer below to the definition # of LOGSERVICE_TARGET_IDL_GENERATED_HEADERS): #SET( LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ) SET( LOGSERVICE_IDL_GENERATED_CXX_FILES "" ) FOREACH( loop_var ${IDL_SOURCES} ) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}SK.cc ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}DynSK.cc ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}.hh COMMAND ${OMNIORB4_IDL_COMPILER} ARGS ${LOGSERVICE_IDL_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}.idl DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}.idl IMPLICIT_DEPENDS CXX ${loop_var}.idl COMMENT "idl generated code: ${loop_var}SK.cc, ${loop_var}DynSK.cc and ${loop_var}.hh") set (LOGSERVICE_IDL_GENERATED_CXX_FILES ${LOGSERVICE_IDL_GENERATED_CXX_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}SK.cc ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}DynSK.cc ) set (LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES ${LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}.hh ) # To save all the generated files object set (OBJ_TMP ${OBJ_TMP} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogCorba.dir/${loop_var}SK.cc.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LogCorba.dir/${loop_var}DynSK.cc.o ) ENDFOREACH(loop_var) # Setting generated objects for the ar command set (binary ${binary} ${OBJ_TMP} PARENT_SCOPE ) install( FILES ${LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES} DESTINATION include/ ) # idl generated header files: ADD_CUSTOM_TARGET( LOGSERVICE_TARGET_IDL_GENERATED_HEADERS DEPENDS ${LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES} ) add_custom_target(CORBAFiles DEPENDS ${LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES} ${LOGSERVICE_IDL_GENERATED_CXX_FILES} ) add_library(LogCorba STATIC ${LOGSERVICE_IDL_GENERATED_CXX_FILES} ) add_dependencies(LogCorba ${LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES})LogService-2.7.0/src/idl/commonLogTypes.idl000644 000765 000765 00000024753 11576373450 022234 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET IDL types for SeD registration and client request (init steps) */ /* */ /* Author(s): */ /* - Philippe COMBES (Philippe.Combes@ens-lyon.fr) */ /* - Frederic LOMBARD (Frederic.Lombard@lifc.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2010/12/17 15:18:20 kcoulomb * update log * * Revision 1.1 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.1 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.34 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.33 2010/07/20 14:31:46 glemahec * Forwarder robustness + bug corrections * * Revision 1.32 2010/07/12 15:54:11 glemahec * DIET 2.5 beta 1 - Forwarder IDL files * * Revision 1.31 2008/09/09 10:05:56 bisnard * container mgmt using Dagda agent * * Revision 1.30 2008/06/25 09:52:46 bisnard * - Estimation vector sent with solve request to avoid storing it * for each submit request as it depends on the parameters value. The * estimation vector is used by SeD to updates internal Gantt chart and * provide earliest finish time to submitted requests. * ==> added parameter to diet_call_common & diet_call_async_common * * Revision 1.29 2008/04/07 15:33:41 ycaniou * This should remove all HAVE_BATCH occurences (still appears in the doc, which * must be updated.. soon :) * Add the definition of DIET_BATCH_JOBID wariable in batch scripts * * Revision 1.28 2008/04/06 15:53:10 glemahec * DIET_PERSISTENT_RETURN & DIET_STICKY_RETURN modes are now working. * Warning: The clients have to take into account that an out data declared as * DIET_PERSISTENT or DIET_STICKY is only stored on the SeDs and not returned * to the client. DTM doesn't manage the DIET_*_RETURN types it and always * returns the out data to the client: A client which uses this bug should not * work when activating DAGDA. * * Revision 1.27 2008/04/03 21:18:41 glemahec * Source cleaning, bug correction and headers. * * Revision 1.26 2008/01/19 01:40:35 glemahec * Reverting the previous commit for DTM. DTM doesn't seem to support the * bug correction... * Warning : When using DTM, undefined result may appear when using data of * size > 2GB... * DAGDA still uses the correction. * * Revision 1.25 2008/01/18 15:28:34 glemahec * Bug correction: * "long" => "unsigned long long" (<=> size_t) for all the data sizes * fields. * * Revision 1.24 2008/01/14 10:31:22 glemahec * Adds the "dataManager" field in the corba_data_desc_t object to differentiate * the replicas of a data. * * Revision 1.23 2007/07/13 16:44:40 ecaron * Remove deprecated code (ALTPREDICT part) * * Revision 1.22 2007/06/28 18:23:19 rbolze * add dietReqID in the profile. * and propagate this change to all functions that have both reqID and profile parameters. * TODO : look at the asynchronous mechanism (client->SED) to propage this change. * * Revision 1.21 2007/04/16 22:43:43 ycaniou * Make all necessary changes to have the new option HAVE_ALT_BATCH operational. * This is indented to replace HAVE_BATCH. * * First draw to manage batch systems with a new Cori plug-in. * * Revision 1.20 2007/03/26 13:25:17 glemahec * Adds the definition of corba_agg_user_t aggregator type and modification of the corba_agg_specific_t type. Conditioned to USERSCHED definition. * * Revision 1.19 2006/08/27 18:40:10 ycaniou * Modified parallel submission API * - client: diet_call_batch() -> diet_parallel_call() * - SeD: diet_profile_desc_set_batch() -> [...]_parallel() * - from now, internal fields are related to parallel not batch * and corrected a bug: * - 3 types of submission: request among only seq, only parallel, or all * available services (second wasn't implemented, third bug) * * Revision 1.18 2006/07/25 14:26:08 ycaniou * Changed dietJobID -> dietReqID * * Revision 1.17 2006/06/03 21:13:58 ycaniou * Batch: add nbprocess field to corba structures * * Revision 1.16 2006/04/14 14:14:06 aamar * Adding the IDL data structures for workflow support. * * Revision 1.15 2006/04/12 16:12:28 ycaniou * Put back the right common_types.idl and made C commentaries from C++ * (discard compilation warnings) * * Revision 1.12 2005/08/31 14:52:54 alsu * New plugin scheduling interface: new data model for the estimation * vector, with each data entry containing three elements: * - the data tag * - the data index (>=0 indicating an array value, <0 indicating a * scalar value) * - the data value * * Revision 1.11 2005/08/30 12:05:15 ycaniou * Added a field dietJobId to make the correspondance between batch ID and * diet job ID. * Added the corresponding management in marshalling. * * Revision 1.10 2005/05/15 15:33:30 alsu * CORBA versions of the aggregator (+ some cleanup) * * Revision 1.9 2005/04/27 01:04:55 ycaniou * Added solve_batch() to the SeD API * Modified corba profile structures * * Revision 1.8 2005/01/14 10:42:26 lphilipp * * correction bug 13 * * Revision 1.7 2004/12/08 15:02:51 alsu * plugin scheduler first-pass validation testing complete. merging into * main CVS trunk; ready for more rigorous testing. * * Revision 1.6.2.4 2004/11/24 09:32:38 alsu * adding CORBA support (new datatype in the IDL and corresponding * marshalling/unmarshalling functions) to deal with * DIET_PARAMSTRING-specific data description structure * * Revision 1.6.2.3 2004/11/02 00:29:35 alsu * removing all hard-coded fields from corba_estimation_t (code elsewhere * modified to use the estValues dynamic estimation value vector) * * Revision 1.6.2.2 2004/10/27 22:35:50 alsu * include * * Revision 1.6.2.1 2004/10/26 14:12:52 alsu * (Tag: AS-plugin-sched) * - branch created to avoid conflicting with release 1.2 (imminent) * - initial commit on branch, new dynamic performance info structure in * the profile * * Revision 1.6 2004/09/29 13:35:31 sdahan * Add the Multi-MAs feature. * * Revision 1.5 2003/09/24 09:07:52 pcombes * Merge corba_DataMgr_desc_t and corba_data_desc_t. * * Revision 1.4 2003/09/22 21:06:54 pcombes * Add the type corba_data_id_t for data persistency. * * Revision 1.3 2003/09/18 09:47:19 bdelfabr * adding data persistence * * Revision 1.2 2003/08/01 19:27:26 pcombes * Add the field nbCPU to the estimation (got from FAST 0.8) * * Revision 1.1 2003/04/10 12:17:45 pcombes * Replace common_types.idl : IDL structures for service, problem and * request description (inc. estimation). * ****************************************************************************/ #ifndef _COMMON_TYPES_IDL_ #define _COMMON_TYPES_IDL_ typedef sequence LogSeqAny; typedef sequence LogSeqDouble; typedef sequence LogSeqLong; typedef sequence LogSeqChar; typedef sequence LogSeqString; /* The object name is not valid. */ exception LogBadNameException { string name; string function; string forwarder_name; }; /* The name does not refer to a registered object. */ exception LogUnknownObject { string name; }; #endif // _COMMON_TYPES_IDL_ LogService-2.7.0/src/idl/CorbaLogForwarder.idl000644 000765 000765 00000012725 11576373447 022623 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET forwarder IDL description */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.3 2010/12/17 15:18:20 kcoulomb * update log * * Revision 1.2 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.1 2010/12/03 12:43:57 kcoulomb * Add a missing file for log forwarder * * Revision 1.1 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.5 2010/07/27 16:16:49 glemahec * Forwarders robustness * * Revision 1.4 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.3 2010/07/20 14:31:46 glemahec * Forwarder robustness + bug corrections * * Revision 1.2 2010/07/14 23:45:31 bdepardo * Header corrections * * Revision 1.1 2010/07/12 15:54:35 glemahec * DIET 2.5 beta 1 - Forwarder IDL files ****************************************************************************/ #ifndef CORBALOGFORWARDER_IDL #define CORBALOGFORWARDER_IDL #include "commonLogTypes.idl" #include "LogComponentFwdr.idl" #include "LogToolFwdr.idl" interface CorbaLogForwarder : ComponentConfiguratorForwarder , LogCentralComponentForwarder , ToolMsgReceiverForwarder , LogCentralToolForwarder { /* Get objects from the Forwarder. */ LogCentralComponent getLogCentralComponent (in string name); LogCentralTool getLogCentralTool(in string name); ComponentConfigurator getCompoConf (in string name); ToolMsgReceiver getToolMsgReceiver(in string name); /* CORBA remote management. */ void bind(in string objName, in string ior); oneway void unbind(in string objName); LogSeqString getBindings(in string ctxt); /* Peer connection. */ void connectPeer(in string ior, in string host, in long port); string getIOR(); /* Obtain informations about this forwarder. */ string getName(); LogSeqString acceptList(); LogSeqString rejectList(); boolean manage(in string hostname); LogSeqString routeTree(); }; #endif LogService-2.7.0/src/idl/Forwarder.idl000644 000765 000765 00000013052 11576373447 021204 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* DIET forwarder IDL description */ /* */ /* Author(s): */ /* - Gael Le Mahec (gael.le.mahec@ens-lyon.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.5 2010/07/27 16:16:49 glemahec * Forwarders robustness * * Revision 1.4 2010/07/27 10:24:32 glemahec * Improve robustness & general performance * * Revision 1.3 2010/07/20 14:31:46 glemahec * Forwarder robustness + bug corrections * * Revision 1.2 2010/07/14 23:45:31 bdepardo * Header corrections * * Revision 1.1 2010/07/12 15:54:35 glemahec * DIET 2.5 beta 1 - Forwarder IDL files ****************************************************************************/ #ifndef FORWARDER_IDL #define FORWARDER_IDL #include "common_types.idl" #include "LogComponentFwdr.idl" #include "LogToolFwdr.idl" interface Forwarder : ComponentConfiguratorForwarder , LogCentralComponentForwarder , ToolMsgReceiverForwarder , LogCentralToolForwarder { /* Get objects from the Forwarder. */ // ComponentConfigurator getComponentConfigurator (in string name); LogCentralComponent getLogCentralComponent (in string name); LogCentralTool getLogCentralTool(in string name); // ToolMsgReceiver getToolMsgReceiver (in string name); // LogCentralTool getLogCentralTool (in string name); /* Common methods. */ // long ping(in string objName) // raises(UnknownObject, BadNameException); oneway void getRequest(in corba_request_t req, in string objName); string getHostname(in string objName) raises(UnknownObject, BadNameException); /* CORBA remote management. */ void bind(in string objName, in string ior); oneway void unbind(in string objName); SeqString getBindings(in string ctxt); /* Peer connection. */ void connectPeer(in string ior, in string host, in long port); string getIOR(); /* Obtain informations about this forwarder. */ string getName(); SeqString acceptList(); SeqString rejectList(); boolean manage(in string hostname); SeqString routeTree(); /* Forwarders management. */ /* traceRoute, ping, topology, ... */ }; #endif LogService-2.7.0/src/idl/LogComponent.idl000644 000765 000765 00000017315 11576373450 021655 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Defines the componentside interfaces needed by the new LogService */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.4 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.3 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGCOMPONENT_IDL_ #define _LOGCOMPONENT_IDL_ #include "LogTypes.idl" #include "commonLogTypes.idl" /* This file defines everything that is needed to attach a component to the * LogCentral. */ /** * Errorlevel constants for connectComponent */ const short LS_COMPONENT_CONNECT_BADNAME = 1; const short LS_COMPONENT_CONNECT_ALREADYEXISTS = 2; const short LS_COMPONENT_CONNECT_BADCOMPONENTCONFIGURATOR = 3; const short LS_COMPONENT_CONNECT_INTERNALERROR = 4; const short LS_COMPONENT_DISCONNECT_NOTEXISTS = 1; /** * defines functions that the component has to implement * to allow dynamic configuration. */ interface ComponentConfigurator { /** * Set the component filter to the specified taglist. All tags * in the list have to be forwarded, all others not. */ void setTagFilter(in tag_list_t tagList); /** * Add the specified taglist to the internal filter and merge them. */ void addTagFilter(in tag_list_t tagList); /** * Remove all tags from the taglist from the internal filter. The * given tagList may contain tags that the internal filter does * not contain. */ void removeTagFilter(in tag_list_t tagList); /** * Do nothing. Useful to be sure that the object is reachable */ void test(); }; /** * defines the interface the core offers to components */ interface LogCentralComponent { /** * Do nothing. Useful to be sure that the object is reachable */ void test(); /** * Connect a component to the LogCentral. The component attaches with its * name, which must be unique (among all components) and its hostname (no * need to be unique). If the name is an empty string, a name is generated. * The return value indicates if the component could be connected. * If ALREADYEXISTS is returned, another component with the given name is * registered. In this case, the connection was not successful, and the tool * must connect with a diferent name before invoking other functions of the * LogCentralComponent interface. */ short connectComponent(inout string componentName, in string componentHostname, in string message, in string compConfigurator, in log_time_t componentTime, inout tag_list_t initialConfig); /** * Disconnect a connected component from the LogCentral. * No further messages should be sent after disconnection. * The componentConfigurator will no longer be used by the LogCentral after * this call. Returns NOTCONNECTED if the calling component was not * registered. */ short disconnectComponent(in string componentName, in string message); /** * Send a buffer of log_msg_t to the LogCentral. */ oneway void sendBuffer(in log_msg_buf_t buffer); /** * To be called by a thread for saying that the component is still alive. * If the last ping is too old, the component is considered dead and * generate a disconnect message (OUT). */ oneway void ping(in string componentName); /** * To be called by a thread for clock synchronisation. */ oneway void synchronize(in string componentName, in log_time_t componentTime); }; #endif LogService-2.7.0/src/idl/LogComponentFwdr.idl000644 000765 000765 00000017041 11576373450 022474 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Defines the componentside interfaces needed by the new LogService */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2010/12/13 12:21:14 kcoulomb * Clean types * * Revision 1.1 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.2 2007/08/31 16:41:16 bdepardo * When trying to add a new component, we check if the name of the component exists and if the component is reachable * - it the name already exists: * - if the component is reachable, then we do not connect the new component * - else we consider that the component is lost, and we delete the old component ant add the new one * - else add the component * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGCOMPONENTFWDR_IDL_ #define _LOGCOMPONENTFWDR_IDL_ #include "LogTypes.idl" #include "LogComponent.idl" /* This file defines everything that is needed to attach a component to the * LogCentral. */ interface ComponentConfiguratorFwdr : ComponentConfigurator { }; /** * defines functions that the component has to implement * to allow dynamic configuration. */ interface ComponentConfiguratorForwarder { /** * Set the component filter to the specified taglist. All tags * in the list have to be forwarded, all others not. */ void setTagFilter(in tag_list_t tagList, in string objName); /** * Add the specified taglist to the internal filter and merge them. */ void addTagFilter(in tag_list_t tagList, in string objName); /** * Remove all tags from the taglist from the internal filter. The * given tagList may contain tags that the internal filter does * not contain. */ void removeTagFilter(in tag_list_t tagList, in string objName); }; interface LogCentralComponentFwdr : LogCentralComponent { }; /** * defines the interface the core offers to components */ interface LogCentralComponentForwarder { /** * Connect a component to the LogCentral. The component attaches with its * name, which must be unique (among all components) and its hostname (no * need to be unique). If the name is an empty string, a name is generated. * The return value indicates if the component could be connected. * If ALREADYEXISTS is returned, another component with the given name is * registered. In this case, the connection was not successful, and the tool * must connect with a diferent name before invoking other functions of the * LogCentralComponent interface. */ short connectComponent(inout string componentName, in string componentHostname, in string message, in string compConfigurator, in log_time_t componentTime, inout tag_list_t initialConfig, in string objName); /** * Disconnect a connected component from the LogCentral. * No further messages should be sent after disconnection. * The componentConfigurator will no longer be used by the LogCentral after * this call. Returns NOTCONNECTED if the calling component was not * registered. */ short disconnectComponent(in string componentName, in string message, in string objName); /** * Send a buffer of log_msg_t to the LogCentral. */ oneway void sendBuffer(in log_msg_buf_t buffer, in string objName); /** * To be called by a thread for saying that the component is still alive. * If the last ping is too old, the component is considered dead and * generate a disconnect message (OUT). */ void ping(in string componentName, in string objName); /** * To be called by a thread for clock synchronisation. */ void synchronize(in string componentName, in log_time_t componentTime, in string objName); void test(in string objName); }; #endif LogService-2.7.0/src/idl/LogTool.idl000644 000765 000765 00000017320 11576373450 020624 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Defines the toolside interfaces needed by the new LogService */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGTOOL_IDL_ #define _LOGTOOL_IDL_ #include "LogTypes.idl" /** * This file defines everything needed to attach a tool * to the core */ /** * Errorlevel constants for connectTool, disconnectTool, * addFilter and removeFilter */ // const short LS_OK = 0; defined in the LogTypes.idl const short LS_TOOL_CONNECT_ALREADYEXISTS = 1; const short LS_TOOL_DISCONNECT_NOTEXISTS = 1; const short LS_TOOL_ADDFILTER_TOOLNOTEXISTS = 1; const short LS_TOOL_ADDFILTER_ALREADYEXISTS = 2; const short LS_TOOL_REMOVEFILTER_TOOLNOTEXISTS = 1; const short LS_TOOL_REMOVEFILTER_NOTEXISTS = 2; const short LS_TOOL_FLUSHFILTERS_TOOLNOTEXISTS = 1; /** * complete configuration of a filter */ struct filter_t { string filterName; tag_list_t tagList; component_list_t componentList; }; /** * define callback functions the tool has to implement so * that the monitor can actively forward messages to the * tool. Active MessagePulling from the tool is not possible * in the moment. */ interface ToolMsgReceiver { /** * Receive a buffer of messages. The messages are ordered in the * sequence. Older messages will be at the beginning of the sequence, * younger(newer) messages at the end. */ oneway void sendMsg(in log_msg_buf_t msgBuf); }; /** * methods offered by the core to allow tools to attach * and configure filters */ interface LogCentralTool { /** * Do nothing but usefull to be sure that the object is reachable */ void test(); /** * Connect a Tool with its toolName, which must be unique among all * tools. The return value indicates the success of the connection. * If ALREADYEXISTS is returned, the tool could not be attached, as * the specified toolName already exists. In this case the tool must * reconnect with another name before specifying any filters. If the * tool sends an empty toolName, the LogCentral will provide a unique * toolName and pass it back to the tool. */ short connectTool(inout string toolName, in string msgReceiver); /** * Disconnects a connected tool from the monitor. No further * filterconfigurations should be sent after this call. The * toolMsgReceiver will not be used by the monitor any more * after this call. Returns NOTCONNECTED if the calling tool * was not connected. */ short disconnectTool(in string toolName); /** * Returns a list of possible tags. This is just a convenience * functions and returns the values that are specified in a * configuration file. If the file is not up to date, the * application may generate more tags than defined in this * list. */ tag_list_t getDefinedTags(); /** * Returns a list of actually connected Components. This is just * a convenience function, as the whole state of the system will * be sent to the tool right after connection (in the form of * messages) */ component_list_t getDefinedComponents(); /** * Create a filter for this tool on the monitor. Messages matching * this filter will be forwarded to the tool. The filter will be * identified by its name, which is a part of filter_t. A tool * can have as much filters as it wants. Returns ALREADYEXISTS if * another filter with this name is already registered. */ short addFilter(in string toolName, in filter_t filter); /** * Removes a existing filter from the tools filterList. The filter * will be identified by its name in the filter_t. If the specified * filter does not exist, NOTEXISTS is returned. */ short removeFilter(in string toolName, in string filterName); /** * Removes all defined filters. */ short flushAllFilters(in string toolName); }; #endif LogService-2.7.0/src/idl/LogToolFwdr.idl000644 000765 000765 00000016576 11576373450 021463 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* Defines the toolside interfaces needed by the new LogService */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.1 2010/11/10 02:27:44 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGTOOLFWDR_IDL_ #define _LOGTOOLFWDR_IDL_ #include "LogTypes.idl" #include "LogTool.idl" /** * This file defines everything needed to attach a tool * to the core */ /** * Errorlevel constants for connectTool, disconnectTool, * addFilter and removeFilter */ interface ToolMsgReceiverFwdr : ToolMsgReceiver { }; /** * define callback functions the tool has to implement so * that the monitor can actively forward messages to the * tool. Active MessagePulling from the tool is not possible * in the moment. */ interface ToolMsgReceiverForwarder { /** * Receive a buffer of messages. The messages are ordered in the * sequence. Older messages will be at the beginning of the sequence, * younger(newer) messages at the end. */ oneway void sendMsg(in log_msg_buf_t msgBuf, in string objName); }; interface LogCentralToolFwdr : LogCentralTool{ }; /** * methods offered by the core to allow tools to attach * and configure filters */ interface LogCentralToolForwarder { /** * Connect a Tool with its toolName, which must be unique among all * tools. The return value indicates the success of the connection. * If ALREADYEXISTS is returned, the tool could not be attached, as * the specified toolName already exists. In this case the tool must * reconnect with another name before specifying any filters. If the * tool sends an empty toolName, the LogCentral will provide a unique * toolName and pass it back to the tool. */ short connectTool(inout string toolName, in string msgReceiver, in string objName); /** * Disconnects a connected tool from the monitor. No further * filterconfigurations should be sent after this call. The * toolMsgReceiver will not be used by the monitor any more * after this call. Returns NOTCONNECTED if the calling tool * was not connected. */ short disconnectTool(in string toolName, in string objName); /** * Returns a list of possible tags. This is just a convenience * functions and returns the values that are specified in a * configuration file. If the file is not up to date, the * application may generate more tags than defined in this * list. */ tag_list_t getDefinedTags(in string objName); /** * Returns a list of actually connected Components. This is just * a convenience function, as the whole state of the system will * be sent to the tool right after connection (in the form of * messages) */ component_list_t getDefinedComponents(in string objName); /** * Create a filter for this tool on the monitor. Messages matching * this filter will be forwarded to the tool. The filter will be * identified by its name, which is a part of filter_t. A tool * can have as much filters as it wants. Returns ALREADYEXISTS if * another filter with this name is already registered. */ short addFilter(in string toolName, in filter_t filter, in string objName); /** * Removes a existing filter from the tools filterList. The filter * will be identified by its name in the filter_t. If the specified * filter does not exist, NOTEXISTS is returned. */ short removeFilter(in string toolName, in string filterName, in string objName); /** * Removes all defined filters. */ short flushAllFilters(in string toolName, in string objName); }; #endif LogService-2.7.0/src/idl/LogTypes.idl000644 000765 000765 00000011423 11576373450 021011 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* General type definitions used by the new LogService */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.2 2004/01/13 15:09:39 ghoesch * changed type of logtime to be compatible with omniORB3 * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #ifndef _LOGTYPES_IDL_ #define _LOGTYPES_IDL_ /** This file defines important data structures that are * used in LogService **/ const short LS_OK = 0; // exact time definition with milliseconds struct log_time_t { long sec; // seconds since EPOCH long msec; // milliseconds since 'sec' }; // format for all messages struct log_msg_t { string componentName; // origin of message log_time_t time; // time of message boolean warning; // true if the message has not been ordered string tag; // type of message string msg; // message content }; // lists of important values typedef sequence log_msg_buf_t; typedef sequence tag_list_t; typedef sequence component_list_t; #endif LogService-2.7.0/src/examples/CMakeLists.txt000644 000765 000765 00000001342 11576373461 022360 0ustar00bdepardobdepardo000000 000000 INCLUDE_DIRECTORIES( ${OMNIORB4_INCLUDE_DIR} ${LOGSERVICE_BINARY_DIR}/src/idl ${LOGSERVICE_SOURCE_DIR}/src/ ${LOGSERVICE_SOURCE_DIR}/src/monitor ${LOGSERVICE_SOURCE_DIR}/src/utils ) ######### INCLUDE_DIRECTORIES( ${LOGSERVICE_SOURCE_DIR}/src/libraries/LogToolBaseC++ ) ADD_EXECUTABLE( DIETtestTool DIETtestTool.cc ) TARGET_LINK_LIBRARIES( DIETtestTool LogForwarderUtils LogServiceToolBase ) INSTALL( TARGETS DIETtestTool DESTINATION bin ) ######### INCLUDE_DIRECTORIES( ${LOGSERVICE_SOURCE_DIR}/src/libraries/LogComponentBaseC++ ) ADD_EXECUTABLE( testComponent testComponent.cc ) TARGET_LINK_LIBRARIES( testComponent LogForwarderUtils LogServiceComponentBase ) INSTALL_TARGETS( /bin/ testComponent ) ## ########### LogService-2.7.0/src/examples/DIETtestTool.cc000644 000765 000765 00000030672 11576373462 022423 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A test for the liblogtoolbase.a */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.7 2011/05/13 08:17:52 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.6 2011/04/22 11:44:22 bdepardo * Use a signal handler to handle background option. * This handler catches SIGINT and SIGTERM. * * Revision 1.5 2011/03/03 14:56:35 bdepardo * Fixed compilation warning * * Revision 1.4 2011/02/04 15:25:22 bdepardo * Removed unused variables. * Removed resource leak. * * Revision 1.3 2010/12/24 09:47:07 kcoulomb * Remove deprecated tools * tool gets generated name * * Revision 1.2 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2010/11/10 05:59:44 kcoulomb * Add a tool for DIET, the generated files can be used with VizDIET * * Revision 1.11 2010/11/10 04:32:51 kcoulomb * Fix the rebind problem * * Revision 1.10 2010/11/10 02:27:43 kcoulomb * Update the log to use the forwarder. * Programm run without launching forwarders but fails with forwarder. * * Revision 1.9 2008/11/04 08:21:05 bdepardo * Added #include . * Now compiles with gcc 4.3.2 * * Revision 1.8 2005/07/01 12:55:01 rbolze * message recieve from LogCentral can be bigger now ! * * Revision 1.7 2004/10/08 11:20:49 hdail * Corrected problem seen under 64-bit opteron: can not cast CORBA Long to * time_t directly. * * Revision 1.6 2004/07/08 20:32:15 rbolze * make som changes : * - create a tool named DIETLogTool that is specific for DIET and VizDIET * - create README to explain what is DIETLogTool * - modify testTool to be an example independant from DIET * - modify Makefile.am to take account of all this changes * * Revision 1.5 2004/05/25 12:02:39 hdail * Sleep isn't found on some systems with current inclusions. Added * inclusion of unistd.h when HAVE_BACKGROUND is true. * * Revision 1.4 2004/05/12 12:39:04 hdail * Add support for running services in the background (at a loss of clean * exit with interactive 'Q'). Behavior can be controlled via configure. * * Revision 1.3 2004/03/16 17:57:22 rbolze * Now you can tell to write log messages into a specific filname * the default filename is Dietlog.log * the command line to launch testTool should be >./testTool * * Revision 1.2 2004/03/02 08:41:21 rbolze * print message in VizDiet readable format, save in a file named logtest.log * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include "LogToolBase.hh" #include "stdio.h" #include #include #include #include "time.h" #include #include "LogORBMgr.hh" #include "LogCentralTool_impl.hh" #include "LogToolBase.hh" #ifdef HAVE_BACKGROUND #include #endif using namespace std; class MyMsgRecv : public POA_ToolMsgReceiver, public PortableServer::RefCountServantBase{ public : LogCentralTool_ptr myLCT; char* name; string filename; filter_t filter;//ADD MyMsgRecv(const char* name){ this->name = CORBA::string_dup(name); filter.filterName = CORBA::string_dup("allFilter");//ADD filter.tagList.length(1); //ADD filter.tagList[0] = CORBA::string_dup("*"); //ADD filter.componentList.length(1); //ADD filter.componentList[0] = CORBA::string_dup("*"); //ADD filename = "DIETLogTool.log"; // CORBA::Object_ptr myLCTptr; // // myLCT = LogORBMgr::getMgr()->resolve("LogServiceT", "LCT"); //// try { //// fprintf (stderr, "Recherche %s/%s \n", LOGCOMPCTXT, "LCT"), //// myLCTptr = LogORBMgr::getMgr()->resolveObject(LOGCOMPCTXT, "LCT"); //// } catch(CORBA::SystemException &e) { //// fprintf (stderr, "Could not resolve 'LogService./LogComponent (LCT).' from the NS"); //// } //// if (CORBA::is_nil(myLCTptr)) { //// fprintf (stderr, "Could not resolve 'LogService./LogComponent (LCT).' from the NS"); //// } //// try { //// myLCT = LogCentralTool::_narrow(myLCTptr); //// } catch(CORBA::SystemException &e) { //// fprintf (stderr, "Could not narrow the LogCentralComponent"); //// } // if (CORBA::is_nil(myLCT)){ // fprintf (stderr, "You failed ! Nil narrow ! \n"); // } // try{ // LogORBMgr::getMgr()->bind("LogServiceT", name, _this(), false); // LogORBMgr::getMgr()->fwdsBind("LogServiceT", name, // LogORBMgr::getMgr()->getIOR(_this())); // } // catch (...){ // fprintf (stderr, "Bind FAILED in the LogService context\n"); // } } int disconnect (){ return myLCT->disconnectTool (name); } void run (){ CORBA::Object_ptr myLCTptr; // Connexion to the LCT to get messages myLCT = LogORBMgr::getMgr()->resolve("LogServiceT", "LCT"); if (CORBA::is_nil(myLCT)){ fprintf (stderr, "Failed to narrow the LCT ! \n"); } try{ LogORBMgr::getMgr()->bind("LogServiceT", name, _this(), true); LogORBMgr::getMgr()->fwdsBind("LogServiceT", name, LogORBMgr::getMgr()->getIOR(_this())); } catch (...){ fprintf (stderr, "Bind failed in the LogService context\n"); } try{ myLCT->connectTool (name, name); myLCT->addFilter(name, filter); } catch (...){ fprintf (stderr, "Caught an unknown exception\n"); } } void sendMsg(const log_msg_buf_t& msg) { struct tm *m; for (CORBA::ULong i=0; itm_mday, m->tm_mon + 1, m->tm_year + 1900,m->tm_hour, m->tm_min, m->tm_sec,(int)msg[i].time.msec); log.append(s); // Channel : LOGCENTRAL log.append("LOGCENTRAL:"); // priority : 5 not important log.append("5:"); //tagtype log.append(msg[i].tag); log.append(":"); //msg log.append(msg[i].msg); ofstream dest(filename.c_str(),ios::app); dest << log << endl; dest.close(); cout << log << endl; } } void setFilter(char* description_file_name){ if (description_file_name == NULL){ return; } char** tags = NULL; FILE* filter_file; printf("filter_file_name = %s\n",description_file_name); filter_file = fopen(description_file_name, "r" ); int nb=0; if (filter_file != NULL){ char line[BUFSIZ]; while(fgets(line,BUFSIZ,filter_file)!=NULL){ if(line[0]!='#' & line[0]!='\n' & line[0]!=' '){ nb++; char tag[BUFSIZ]; sscanf(line,"%s",tag); tags=(char**)realloc(tags,(nb)*sizeof(char*)); tags[nb-1]=(char*)malloc(strlen(line)*sizeof(char)); sprintf(tags[nb-1],"%s",tag); } } fclose(filter_file); } filter.filterName = CORBA::string_dup("myfilter"); filter.componentList.length(1); filter.componentList[0] = CORBA::string_dup("*"); filter.tagList.length(nb); for (int i =0;i=2) myLTB->setFilename(argv[1]); if (argc>=3) myLTB->setFilter(argv[2]); LogORBMgr::getMgr()->activate((MyMsgRecv*)myLTB); myLTB->run (); /* The code to support interactive quit via user input of q or Q is * incompatible with backgrounding the LogCentral process. Use * configure option --enable-background to select which you prefer. */ #ifdef HAVE_BACKGROUND try { LogORBMgr::getMgr()->wait(); } catch (...) { cerr << "Error while exiting the ORBMgr::wait() function" << endl; } #else // HAVE_BACKGROUND printf("Press CRTL-D to exit\n"); char c; while(cin.get(c)) { if (c==10) printf("Press CRTL-D to exit\n"); } printf("Disconnecting from monitor\n"); if (myLTB->disconnect() != 0) { printf("failed\n"); exit(1); } printf("Done\n"); delete myLTB; return 0; #endif } LogService-2.7.0/src/examples/README000644 000765 000765 00000000614 11576373461 020501 0ustar00bdepardobdepardo000000 000000 DIETLogTool is an example of LogTool which can connect to LogCentral and receive messages from LogCentral. This tool retrieves log messages from LogCentral and then writes them in a file (filename can be defined on the command line). The log file is formatted for a visualization tool called VizDIET that is designed to show a DIET hierarchy. For more details see http://graal.ens-lyon.fr/DIET. LogService-2.7.0/src/examples/testComponent.cc000644 000765 000765 00000016043 11576373462 022776 0ustar00bdepardobdepardo000000 000000 /****************************************************************************/ /* A sample component based on libLogComponentBase.a */ /* */ /* Author(s): */ /* - Georg Hoesch (hoesch@in.tum.de) */ /* - Cyrille Pontvieux (cyrille.pontvieux@edu.univ-fcomte.fr) */ /* */ /* This file is part of DIET . */ /* */ /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ /* */ /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ /* - Tech@sysfera.com (Maintainer and Technical Support) */ /* */ /* This software is a computer program whose purpose is to provide an */ /* distributed logging services. */ /* */ /* */ /* This software is governed by the CeCILL license under French law and */ /* abiding by the rules of distribution of free software. You can use, */ /* modify and/ or redistribute the software under the terms of the CeCILL */ /* license as circulated by CEA, CNRS and INRIA at the following URL */ /* "http://www.cecill.info". */ /* */ /* As a counterpart to the access to the source code and rights to copy, */ /* modify and redistribute granted by the license, users are provided */ /* only with a limited warranty and the software's author, the holder */ /* of the economic rights, and the successive licensors have only */ /* limited liability. */ /* */ /* In this respect, the user's attention is drawn to the risks */ /* associated with loading, using, modifying and/or developing or */ /* reproducing the software by the user in light of its specific status */ /* of free software, that may mean that it is complicated to */ /* manipulate, and that also therefore means that it is reserved for */ /* developers and experienced professionals having in-depth computer */ /* knowledge. Users are therefore encouraged to load and test the */ /* software's suitability as regards their requirements in conditions */ /* enabling the security of their systems and/or data to be ensured and, */ /* more generally, to use and operate it in the same conditions as */ /* regards security. */ /* */ /* The fact that you are presently reading this means that you have had */ /* knowledge of the CeCILL license and that you accept its terms. */ /* */ /****************************************************************************/ /* $Id$ * $Log$ * Revision 1.5 2011/05/13 08:17:52 bdepardo * Update ORB manager with changes made in DIET ORB manager. * * Revision 1.4 2011/05/13 06:44:59 bdepardo * Add missing include * * Revision 1.3 2011/02/04 15:52:22 bdepardo * System headers before our own headers * * Revision 1.2 2010/12/03 12:40:26 kcoulomb * MAJ log to use forwarders * * Revision 1.1 2004/01/09 11:07:12 ghoesch * Restructured the whole LogService source tree. * Added autotools make process. Cleaned up code. * Removed some testers. Ready to release. * ****************************************************************************/ #include #include #include #include "LogComponentBase.hh" #include "LogORBMgr.hh" using namespace std; int main(int argc, char** argv) { cout << "Test of liblogcomponentbase.a\n\n"; bool success = false; cout << "Init \n" << endl; try { LogORBMgr::init(argc, argv); } catch (...) { fprintf (stderr, "ORB initialization failed"); } LogComponentBase* logComponentBase = new LogComponentBase(&success, argc, argv, 0, "testComponent"); cout << "Inited \n" << endl; if (!success) { cerr << "Cannot innitialize the LogComponentBase !\n" << "Are LogCentral or Omninames not running ?\n"; return 1; } short ret = 0; ret = logComponentBase->connect("testCompo connected \\o/"); if (ret == LS_COMPONENT_CONNECT_BADNAME) { cerr << "Component : bad name !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_ALREADYEXISTS) { cerr << "Component : already exist !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_BADCOMPONENTCONFIGURATOR) { cerr << "Component : bad component configurator !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_INTERNALERROR) { cerr << "Component : cannot connect !\n"; return ret; } char* s; s = logComponentBase->getName(); cout << "name:" << s << endl; delete s; s = logComponentBase->getHostname(); cout << "hostname:" << s << endl; delete s; ret = logComponentBase->connect("test connect 2"); if (ret == LS_COMPONENT_CONNECT_BADNAME) { cerr << "Component : bad name !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_ALREADYEXISTS) { cerr << "Component : already exists !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_BADCOMPONENTCONFIGURATOR) { cerr << "Component : bad component configurator !\n"; return ret; } if (ret == LS_COMPONENT_CONNECT_INTERNALERROR) { cerr << "Component : cannot connect !\n"; return ret; } logComponentBase->sendMsg("TEST", "test message"); sleep(1); // make sure the message is sent ret = logComponentBase->disconnect("test disconnection of component"); if (ret == LS_COMPONENT_DISCONNECT_NOTEXISTS) { cerr << "Component : cannot disconnect, not exists !\n"; return ret; } // logComponentBase->setName("testComponent_C++"); ret = logComponentBase->connect("test connect 3"); if (ret != LS_OK) { return ret; } logComponentBase->sendMsg("ANY", "another test message"); sleep(1); // make sure this message is sent cout << "'IN' tag wanted ? " << logComponentBase->isLog("IN") << endl; cout << "'TEST' tag wanted ? " << logComponentBase->isLog("TAG") << endl; ret = logComponentBase->disconnect("test disconnect 2"); if (ret != LS_OK) { return ret; } delete logComponentBase; cout << "All tests passed successfully !\n"; return ret; } LogService-2.7.0/docs/man/000755 000765 000765 00000000000 11576373446 016721 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/docs/manual/000755 000765 000765 00000000000 11576373445 017422 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/docs/manual/fig/000755 000765 000765 00000000000 11576373445 020167 5ustar00bdepardobdepardo000000 000000 LogService-2.7.0/docs/manual/Makefile000644 000765 000765 00000000375 11576373445 021067 0ustar00bdepardobdepardo000000 000000 manual.ps: manual.dvi dvips manual.dvi ps2pdf manual.ps manual.dvi: manual.tex fig latex manual.tex latex manual.tex fig: make -C fig clean: make -C fig clean rm -f manual.aux manual.dvi manual.log manual.ps manual.toc manual.pdf .PHONY: fig LogService-2.7.0/docs/manual/manual.tex000644 000765 000765 00000135017 11576373446 021431 0ustar00bdepardobdepardo000000 000000 %****************************************************************************% %* manual.tex - LogService manual *% %* *% %* Author(s): *% %* - Georg Hoesch (hoesch@in.tum.de) *% %* *% %* This file is part of DIET . *% %* *% %* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) *% %* *% %* - Frederic.Desprez@ens-lyon.fr (Project Manager) *% %* - Eddy.Caron@ens-lyon.fr (Technical Manager) *% %* - Tech@sysfera.com (Maintainer and Technical Support) *% %* *% %* This software is a computer program whose purpose is to provide an *% %* distributed logging services. *% %* *% %* *% %* This software is governed by the CeCILL license under French law and *% %* abiding by the rules of distribution of free software. You can use, *% %* modify and/ or redistribute the software under the terms of the CeCILL *% %* license as circulated by CEA, CNRS and INRIA at the following URL *% %* "http://www.cecill.info". *% %* *% %* As a counterpart to the access to the source code and rights to copy, *% %* modify and redistribute granted by the license, users are provided *% %* only with a limited warranty and the software's author, the holder *% %* of the economic rights, and the successive licensors have only *% %* limited liability. *% %* *% %* In this respect, the user's attention is drawn to the risks *% %* associated with loading, using, modifying and/or developing or *% %* reproducing the software by the user in light of its specific status *% %* of free software, that may mean that it is complicated to *% %* manipulate, and that also therefore means that it is reserved for *% %* developers and experienced professionals having in-depth computer *% %* knowledge. Users are therefore encouraged to load and test the *% %* software's suitability as regards their requirements in conditions *% %* enabling the security of their systems and/or data to be ensured and, *% %* more generally, to use and operate it in the same conditions as *% %* regards security. *% %* *% %* The fact that you are presently reading this means that you have had *% %* knowledge of the CeCILL license and that you accept its terms. *% %* *% %****************************************************************************% %* $ID$ %* $VERSION$ %* \documentclass{article} \usepackage{graphicx} \usepackage[latin1]{inputenc} \usepackage[left=2.5cm, right=2.5cm, bottom=2.5cm]{geometry} \usepackage{url} \usepackage{color} \usepackage{figlatex} \epstopdfsetup{suffix={}} \begin{document} ~\center{\vspace{5cm}\Huge \bf LogService manual} \vspace{3cm} \abstract{ LogService is a tool to monitor distributed applications. It provides services to collect messages from different components of the application, to filter this data and to offer it to interested clients. It thus acts as a common base between the application and it's monitoring programs, simplifying the development for both sides. This manual explains the concepts of LogService, the provided APIs and the installation and usage of the monitor. It further documents the supporting libraries which simplify the development of tools and instrumentation code. } \vspace{7cm} \noindent \small{ \begin{tabular}{ll} \textbf{VERSION} & 2.2.0 \\ \textbf{DATE} & March 2008 \\ \textbf{PROJECT MANAGER} & Fr\'ed\'eric \textsc{Desprez} (Frederic.Desprez@ens-lyon.fr).\\ \textbf{TECHNICAL MANAGER} & Eddy \textsc{Caron} (Eddy.Caron@ens-lyon.fr).\\ \textbf{EDITORIAL STAFF} & Georg \textsc{Hoesch}.\\ \textbf{AUTHORS STAFF} & \begin{minipage}[t]{12cm} Georg \textsc{Hoesch} (hoesch@in.tum.de)\\ Cyrille {Pontvieux} (cyrille.pontvieux@edu.univ-fcomte.fr)\\ Rapha\"el Bolze (raphael.bolze@ens-lyon.fr \end{minipage} \\ \textbf{Copyright} & INRIA \end{tabular}\\ } \newpage \tableofcontents \newpage \section{Overview} LogService is a tool that can monitor distributed applications. It acts as a common base with well defined interfaces between the application and it's components on the one side and the tools who monitor the application on the other side. LogService itself consists of two parts, the main program LogCentral (often referred as monitor) that implements the monitoring functionality and two libraries. These libraries are the LogToolBase and the LogComponentBase. They can be used to simplify the development of tools and the instrumentation of application code by providing APIs to communicate with the LogCentral in C++ or Java. Note that the usage of these libraries is optional, the connection to the core can also be implemented directly by the application using the provided idl interfaces. The features offered by the LogCentral include: \begin{itemize} \item Communications in CORBA \\ Both tools and application communicate with the LogCentral using CORBA. This is a very flexible approach since CORBA does not depend on certain platforms. Using the provided idls, almost any kind of application or tool can connect to LogCentral. \item Classification of messages \\ Each information processed by the core is exchanged as a 'message'. Besides their information, these messages provide two fields 'component' and 'tag'. These allow the introduction of a general filter system to classify the messages in two dimensions. \item Filtering of messages \\ Based on the possibility to classify messages, each connected tool can define it's own set of filters to define it's own view on the application. The monitor guarantees that each tool gets exactly the messages it wants. \item Prefiltering of messages \\ One problem when instrumenting an application is that a part of the information gathered is only needed by very few tools which are not always connected. As sending messages is costly, the core offers methods to allow a prefiltering of messages in the application, minimizing the number of messages that have to be sent. \item Message ordering \\ Ordering of messages is always complicated in distributed environments. LogService uses timestamps in conjunction with internal synchronisation mechanisms to allow proper message ordering. It also offers the possibility to hold back messages for a short period of time to compensate minor lags and deliver a sorted stream of messages to the tools. \item Hold system state \\ To allow tools to connect at any time, LogCentral holds the state of the monitored system. This does not only include which components are currently connected, it can also contain information on details of the system which are not directly known to LogCentral. \item Proxy forwarder \\ To monitor each diet component, even when they are on machines hidden behind firewall. A forwarder must be launched between the two sides to be usefull, multiple forwarders may be used to jump between various firewall. \end{itemize} \section{Basic concepts} \subsection{The filter system} As already mentioned in the overview, messages are classified by two properties, 'tag' and 'component'. This section explains what these properties are and how they can be used to filter messages on a very general base. \subsubsection{Components} Let's first look at the components. No distributed application consists of only one single program on one host, but of several parts running in different processes on different hosts. When monitoring the application one is usually interested in where exactly an event occured. The problem is that the different programs of the application can further be divided into distributed objects, logical objects, implemented objects and functions. The needed granularity of monitoring highly depends on the actual instrumentation of the application code and must not be restricted by the monitoring system. LogService solves this problem by just offering logical components. The user decides to which parts of the application each component corresponds. By doing so he defines a view on the application. Although it is not necessary, it is recommended that the application is monitored with constant granularity. Monitoring some parts of the application with higher granularity than other parts works, but may lead to confusion when building tools. It is also recommended to leave the granularity on a relatively coarse level as it can be refined further by the 'tag' field. In practice, each component is identified by it's name. This name can either be set by the programmer or generated automatically by the LogCentral. Each component connects and disconnects independently to the LogCentral and can send it's own messages and receive it's own set of prefilters. \subsubsection{Tags} Each component usually generates a number of different messages. These messages can be distinguished by the 'tag' field. It defines what kind of information this messages carries. For example a component that represents a server may generate two different tags to indicate the start and the end of a client request. Just like the components define a view based on the origin of a message, the tags define another view based on the type of the message. This type corresponds to the function of their origin. It can be used to monitor certain functionality of the application without explicitly choosing each necessary component. If we want to monitor all servants of the example above, we just filter for their tags and to get all relevant messages. Although tags and components are not completely independant, they can be used together to define a very granular and flexible way of filtering. The component denotes the coarse origin of a message and the tag further refines this information. \subsubsection{Messages} Based on this information we now define the messages. Each message contains the following fields: \begin{itemize} \item Tag \item Component \item Timestamp \item Content \end{itemize} In addition to 'tag' and 'component', each message contains a timestamp with a precision of milliseconds and the content, a string that can carry any data associated with the message. It can be left empty very often, as the generation of a message with this tag from a certain component already contains all necessary information. It is recommended to define a structure of the content field for each tag. In our example above this may be the name of the client for the 'beginRequest' tag and the empty string for the 'endRequest' tag. \subsubsection{Filters} Filters can be directly derived from the classification fields. Each filter consists of two sets. One set contains all tags that are of interest, the other one contains all components that are of interest. A special element (the character \emph{*}) that matches all components/tags exists for each set. Through the combination of several filters, almost any subset of messages can be selected, allowing tools to define exactly the view they want. \subsection{The statemanager} Many tools are interested in the state of the monitored system. This state is represented by a number of messages in LogService. The problem is that some of these messages are generated only once at the startup of the system. As tools can connect at any time, they will not necessarily receive these messages. A simple solution to this problem is to store all received messages and to resend them to connecting tools. This solution works, but it is not very efficient as most messages contain no information relevant for the system state. LogService refines this solution by identifying messages that affect the system state. These messages will be stored for resending while all other messages are just passed through. An advantage of this solution is that tools do not have to treat the system state separately. They always receive a stream of messages that represents the whole system after they connected. This concept is implemented in LogCentral's statemanager. It identifies important messages by their tag and stores them for connecting tools. To further increase the performance, the statemanager knows several classes of important messages. \begin{itemize} \item Administrative messages. \\ This group contains two tags \emph{IN} and \emph{OUT} which are automatically generated by the LogCentral if a component connects or disconnects. All messages with an \emph{IN} tag will be kept until an \emph{OUT} is received. This \emph{OUT} message will not be stored. Instead all messages concerning it's component will be removed from the statemanager. This group is fixed and cannot be changed. \item Static messages and unique messages. \\ Tags that are declared as unique or static will be stored until the component is disconnected with an \emph{OUT}. The difference between unique and static is that only one message can exist for each unique tag, while several messages can exist for each static tag. This means that all messages with static tags will be stored, but messages with unique tags will overwrite older messages with this tag. \item Dynamic messages. \\ Dynamic tags try to model processes that are started and stopped within a component. They always come in pairs. One tag indicates that the service identified by this tag is started, the second tag indicates that this service is stopped and will remove itself and the corresponding start message from the statemanager. This class can not reflect dynamic processes (yet) as only one process can exist for each tag. We hope that this problem will be solved in future versions of LogService. \end{itemize} \subsection{Forwarding} The forwarder system is based on the same idea as the DIET forwarder. The main idea is simple, the forwarder manage a SSH tunnel between the two sides of the firewall, and resolves using object names the naming service reference to use. Thus, the user/programmer does not see any difference, he keeps thinking he is using its object directly, whereas on one side he is just using its name, and on the other side the name is resolved and the object is manipulated. Here is a simple example of how to launch the forwarder between two machines:\\ \begin{itemize} \item On the distant machine graal (graal.ens-lyon.fr)\\ ./logForwarder --name --net-config /forwarder.cfg \item On the local machine \\ ./logForwarder -C --peer-name --ssh-host graal.ens-lyon.fr --remote-port 50005 --name --net-config /forwarder.cfg --remote-host localhost --ssh-login \end{itemize} Explanations \begin{itemize} \item logForwarder: Name of the forwarder programm \item --name /: Name of the forwarder (available in the omninames after). name\_d for distant name to give, name\_l for local name to give. \item --net-config: Configuration file for the forwarder, they are called /forwarder.cfg and /forwarder.cfg in the example. \item -C: Option to create the SSH tunnel between the forwarder. It requires 3 more arguments : \begin{itemize} \item --peer-name: Name of the corresponding forwarder on the other side (the name given to --name on the other side) \item --ssh-host: Host to establish the SSH tunnel \item --remote-port: A free port to create the SSH connection. He can be any free port (around 50000 may be a good idea to find a free one). \end{itemize} \item --remote-host localhost: Option to add for loopback (otherwise there might be ssh problems) \item --ssh-login: Option if the login name on the other machine is different of the local login \end{itemize} \section{Installation of LogService} \subsection{Compiling the sources} The LogService sources can be obtained at \url{http://graal.ens-lyon.fr/DIET/download.html}. In order to use and install the package, omniORB 4 must be installed. The OmniORB package can be downloaded at \url{http://omniORB.sourceforge.net}. Please unpack, compile and install omniORB before proceeding. After that please unzip and untar LogService. You will find the following directories: \vspace{1ex} \begin{tabular}{l l} src/ & All sources needed to compile LogService, the forwarder and the libraries. \\ src/idl/ & All idl interfaces used by LogService and forwarder. \\ src/utils/ & General classes that are not LogCentral specific. \\ src/monitor/ & The main monitor program. \\ src/tester/ & A small program that tests the monitor's internals. DEPRECATED\\ src/libraries/ & The supporting libraries in C++ and java. \\ src/examples/ & Two examples using the C++ libraries. The two tested tools are 'testTool' that creates a small tool displaying everything, and 'DIETtestTool', a tool that makes the log for VizDIET. The other codes are not tested.\\ \end{tabular} \vspace{2ex} \noindent LogService compilation process moved away from the traditional \verb+autotools+ way of things to a tool named \verb+cmake+. LogService requires using \verb+cmake+ at least version \verb+2.4.3+. For many popular distributions \verb+cmake+ is incorporated by default or at least \verb+apt-get+ (or whatever your distro package installer might be) is \verb+cmake+ aware. Still, in case you need to install an up-to-date version \verb+cmake+'s official site distributes many binary versions (alias packaged as tarballs) which are made available at \url{http://www.cmake.org/HTML/Download.html}. Optionally, you can download the sources and recompile them: this simple process (\verb+./bootstrap; make; make install+) is described at \url{http://www.cmake.org/HTML/Install.html} \paragraph{Compilation using cmake for the impatients :} Assume that \verb+LOGSERVICE_HOME+ represents a path to the top level directory of LogService sources. This LogService sources directories tree can be obtained by users by expanding the LogService current source level distribution tarball. Additionally, assume we created a build tree directory and \verb+cd+ to it (in the example below we chose \verb+LOGSERVICE_HOME/build+ as build tree, but feel free to follow your conventions): \begin{itemize} \item \verb+cd LOGSERVICE_HOME/build+ \item \verb+ccmake ..+ to enter the GUI \begin{itemize} \item press \verb+c+ (equivalent of bootstrap.sh of the autotools) \item specify the \verb+CMAKE_INSTALL_PREFIX+ parameter (if you wish to install in a directory different from \verb+/usr/local+, \item press \verb+c+ again, for checking required dependencies \item check all the parameters preceded with the * (star) character whose value was automatically retrieved by \verb+cmake+. \item provide the required information i.e. fill in the proper values for all parameters whose value is terminated by NOT-FOUND \item iterate the above process of parameter checking, toggle/specification and configuration until all configuration information is satisfied \item press \verb+g+ to generate the makefile \item press \verb+q+ to exit ccmake \end{itemize} \item \verb+make+ in order to classically launch the compilation process \item \verb+make install+ when installation is required \end{itemize} The main configuration flag is : \begin{itemize} \item\verb+OMNIORB4_DIR+ is the path to the omniORB4 installation directory (only relevant when omniORB4 was not installed in /usr/local). Example: \verb+cmake .. -DOMNIORB4_DIR:PATH=$HOME/local/omniORB-4.1.2+ \end{itemize} %\noindent LogService itself it a straightforward GNU package. You have to %call the \emph{configure} script to setup the package. Next %type \emph{make} and \emph{make install} to compile and install the program. The install directory will contain the following subdirectories: \vspace{1ex} \begin{tabular}{l l} bin/ & The LogCentral executable and a sample configuration file. \\ lib/ & The libraries and their headers for java. \\ \end{tabular} \vspace{2ex} \subsection{Quick start} To start a quick demonstration without forwarder, please run the following programs in the given order: \begin{itemize} \item \emph{omniNames}. The CORBA Namingservice is needed by LogService. Please make sure that the namingservice is declared as an initial reference in the omniORB configuration file. \item \emph{bin/LogCentral}. The \emph{config.cfg} file will be selected by default. \item \emph{examples/testTool}. This tool will display all messages. The connection of the tool should already be displayed by LogCentral. \item \emph{examples/testComponent}. This program simulates a (very simple) component that just sends two messages. These messages can be watched with the testTool. \end{itemize} \subsection{Configuration file} Before usage, several parts of the LogCentral should be configured by the user. This mainly includes the configuration of the statemanager and some internal parameters of LogCentral. All important options can be set in the mandatory configuration file that can be stored anywhere on your system. LogCentral knows two possibilities to define the location this file. \begin{enumerate} \item Add \emph{-config pathToConfig.file} when calling LogCentral. \item Set the environment variable \emph{\$LOGCENTRAL\_CONFIG}. \end{enumerate} If no config file is set, LogCentral tries to open the default config file \emph{./config.cfg}. \vspace{2ex} \noindent The configuration file is composed of five sections. Each section begins with its [sectionname] in square brackets, followed by it's parameters. The sections are mandatory, even if they contain no parameters. Parameters are optional and only one parameter can be specified per line. Empty lines are ignored and comments start with '\#' and stop at the end of the line. The first section is the [general] section which allows the configuration of parameters that control the behaviour of LogCentral. It offers the following parameters: \begin{itemize} \item port = xxx \\ Tells omniORB to use the port xxx for communication. \item MinAge = xxx (in milliseconds)\\ Defines the minimum period of time that messages will be stored in the LogCentral. Messages that arrive out of order during this period will be sorted by the LogCentral. A high value guarantees correct sorting even under bad circumstances while a low value does not slow down the flow of the messages through the core. \item DynamicStartSuffix=START\\ See [DynamicTagList] \item DynamicStopSuffix=STOP\\ See [DynamicTagList] \end{itemize} All remaining sections configure the statemanager. They are named [DynamicTagList], [StaticTagList], [UniqueTagList] and [VolatileTagList] and correspond directly to the classes of the statemanager. The [VolatileTagList] section should contain all existing tags are not important. It is not essential for operation, but it can be requested by tools that want to find out which tags can be monitored. All entries in the statemanager sections will be directly considered as tags. The only difference is the list of unique tags. The pairs cannot be defined freely but every tag in this list will be expanded with two suffixes to generate the pair. The default suffixes are \emph{START} and \emph{STOP}. So for example the tag \emph{WORK} will be expanded to \emph{WORK\_START} and \emph{WORK\_STOP}. The names of the suffixes can be configured in the [General] section. \vspace{2ex} \noindent A correct configuration file could look like the following example. \footnotesize \begin{verbatim} [General] port = 4242 # use a specific port MinAge = 100 # 100 ms buffer time. This is not much, but # it guarantes fast message forwarding [DynamicTagList] # we have no dynamic tags but the section is mandatory # (even if empty) [StaticTagList] DESCRIBE_DATA [UniqueTagList] DATA_COUNT # new DATA_COUNT messages will overwrite old ones [VolatileTagList] ADD_DATA REMOVE_DATA \end{verbatim} \normalsize \subsubsection{Forwarder configuration file} \begin{verbatim} # accept everything from everyone accept:.* # reject nothing reject:192\.168\.1\.6 \end{verbatim} The reject line corresponds to the IP of the machine on the network. It is safer than using reject:localhost which may make the messages to be misrouted. \subsection{Commandline arguments} LogCentral was designed to need as few commandline arguments as possible. Anyway it supports the full set of omniORB commandline options to change the behaviour of the ORB. Please read the omniORB manual for details. \section{How to connect to the LogCentral} \subsection{Connection of components} This section documents how components can connect to the LogService. It explains the various interfaces and data types defined in the LogCentral IDL files and it describes how to use the LogComponentBase libraries to instrument your application easily. \subsubsection{The IDL interface} Let's first look at the IDL files. \emph{LogTypes.idl} defines all data types that are used in the system, in particular the \texttt{log\_msg\_t}. All interfaces that must be known to connect a component to the LogCentral are define in \emph{LogComponent.idl}. It's two big interfaces \texttt{ComponentConfigurator} and \texttt{LogCentralComponent} will now be described in detail. \footnotesize \begin{verbatim} interface ComponentConfigurator { void setTagFilter(in tag_list_t tagList); void addTagFilter(in tag_list_t tagList); void removeTagFilter(in tag_list_t tagList); } \end{verbatim} \normalsize The \texttt{ComponentConfigurator} is an interface that must be offered by the component. This is necessary to allow the prefiltering of messages on the component. The filter on the component will be updated actively by the LogCentral whenever necessary by using this interface. A filter on the level of the component (also called the component's configuration) is just a set of tags. It is represented by a list of strings in LogService that has the type \texttt{tag\_list\_t}. A new configuration for the component is passed with every call to the \texttt{ComponentConfigurator}. Depending on which method is called, the component must change it's filters accordingly. \texttt{SetTagFilter()} defines the whole filter. Each tag in it's list must be sent, all other tags must not be sent. \texttt{AddTagFilter()} and \texttt{removeTagFilter()} just modify the existing filter by adding or removing tags, leaving the status of all other tags untouched. \footnotesize \begin{verbatim} interface LogCentralComponent { short connectComponent(inout string componentName, in string componentHostname, in string message, in string compConfigurator, in log_time_t componentTime, inout tag_list_t initialConfig); short disconnectComponent(in string componentName, in string message); oneway void sendBuffer(in log_msg_buf_t buffer); [...] \end{verbatim} \normalsize The connect, disconnect and send function are the essential parts of the LogCentralComponent. Each component must connect to the LogCentral with \texttt{connectComponent()} to register itself and negotiate it's name. The component can propose a unique name or completely rely on autogenerated names. If the connect is successful, the tool will receive a unique name that it must use directly or indirectly for all following calls. The name will be valid until \texttt{disconnectComponent()} is called. This unregisters the component and frees it's name. Do not use the name any more after the disconnection. The parameters of \texttt{disconnectComponent()} and \texttt{sendBuffer()} should be self explaing, but the signature of \texttt{connectComponent()} is complicated and will thus be explained in detail. \begin{itemize} \item \texttt{componentName} \\ The name of the component. If this name is empty, the LogCentral will create a unique name for this component and return it in this variable. Otherwise the LogCentral will check if this name is already connected. It will return with \texttt{LS\_COMPONENT\_CONNECT\_ALREADYEXISTS} immediately if the component could not be registered. \item \texttt{componentHostName} \\ The name of the component's host. Autogenerated names will be based on this name to allow rudimentary identification of autogenerated components. LogCentral does not rely on this parameter. \item \texttt{message}\\ The message that will be sent with the \emph{IN} message that will be generated by LogCentral. \item \texttt{compConfigurator} \\ A string corresponding to the name of the component to be called. It is a string and not a CORBA reference since the forwarders cannot use references directly. \item \texttt{time} \\ The actual time on the component right before connection. This value is used to determine the initial latency between component and monitor. \item \texttt{initialConfig} (OUT) \\ The initial filter configuration of this component. The LogCentral might also use the ComponentConfigurator, but passing this parameter as an out parameter guarantees synchronisation from the beginning. \end{itemize} \vspace{2ex} \footnotesize \begin{verbatim} [...] void ping(in string componentName); void synchronize(in string componentName, in log_time_t componentTime); void test(); } \end{verbatim} \normalsize The remaining functions of the interface deal with the time synchronisation and the heartbeat of components. The LogCentral automatically disconnects inactive components, so each component has to call \texttt{ping()} in regular intervals keep the connection alive. The \texttt{synchronize()} function recomputes the latency between the component and the monitor. It also should be called from time to time to react upon changes in the network connection. \texttt{Test()} exists to control the status of a LogCentralComponent reference. It does nothing and can be used to check if the reference is valid. % remark: we need these extra spaces '~ ' to get an acceptable layout: %%% Components~ that want~ to~ connect~ to~ the LogCentral need to obtain a reference to it's \texttt{LogCentralComponent} servant. This reference will be registered in the Naming Service by LogCentral. The name of the reference is 'LCC' in the context 'LogServiceC'. The kind of reference and context is empty. \subsubsection{The LogComponentBase library} \textcolor{red}{DEPRECATED (the library is out of date)}\\ All the interfaces described above are implemented in the LogComponentBase library. It hides many details of the connection and the ComponentConfigurator and can be used to easily create a component for a certain application. Using the LogComponentBase requires only the most essential parameters for each function. The name of the component can be set with \texttt{setName()}, connection and disconnection just require the message and all synchronisation is done internally. The application can use the \texttt{isLog()} function to find out if a certain tag is required in the moment or not. Messages can easily be generated by \texttt{sendmsg()}. As the LogComponentBase is available in C++ and Java, no exact description of the class is given here. Look at the C++ header file\footnote{\emph{libraries/LogComponentBaseC++/LogComponentBase.hh}} and the java source code\footnote{\emph{libraries/LogComponentBaseJava/LogComponentBase.java}} for details. The C++ library is based on omniORB and will be built together with the LogCentral. The java library relies on JAVAs built in ORB and is distributed in source code only. There is no compilation support through the makefiles, so you must compile the IDL files and all the java classes yourself. Please note that the LogComponentBase was not extensively tested yet and may still contain bugs. \subsection{Connection of tools} \subsubsection{The IDL interface} This section explains how tools can connect to the LogCentral. It presents the interfaces that can be used to define filters and to receive messages as well as the LogToolBase, a library that can be used to easily build tools. The essential interfaces to connect tools to the LogCentral are defined in \emph{LogTools.idl}. It relies on \emph{LogTypes.idl} just like \emph{LogComponent.idl} and it's main interfaces will be presented now. \footnotesize \begin{verbatim} interface ToolMsgReceiver { oneway void sendMsg(in log_msg_buf_t msgBuf); }; \end{verbatim} \normalsize Whenever the monitor receives a message that is of interest for a tool, it actively forwards this messages to the tool. This is done through the \texttt{ToolMsgReceiver}, an interface that must be implemented by each tool. It offers just one function that allows the receiving of messages. If several messages are sent at once, then the earliest message will be at the beginning of the buffer. \footnotesize \begin{verbatim} interface LogCentralTool { short connectTool(inout string toolName, in ToolMsgReceiver msgReceiver); short disconnectTool(in string toolName); short addFilter(in string toolName, in filter_t filter); short removeFilter(in string toolName, in string filterName); short flushAllFilters(in string toolName); [...] \end{verbatim} \normalsize The \texttt{LogCentralTool} interface is very close to the \texttt{LogCentralComponent} interface. Like components, tools receive a unique name upon connection. This name serves as an identifier for all future calls and can either be set by the tool or generated by the LogCentral. Upon connection, a tool must pass a reference to it's \texttt{ToolMsgReceiver} to be able to receive messages. After that, it can define it's filters using the \texttt{addFilter()} function. The \texttt{filter\_t} is composed of a list of tags, a list of components and a unique name for the filter. As this name must only be unique within the scope of this tool, no mechanism to automatically generate it is provided. Each tool must ensure itself that it does not define two filters with the same name. If this happens anyway, LogCental will deny to add this filter by returning \texttt{LS\_TOOL\_ADDFILTER\_ALREADYEXISTS}. \texttt{RemoveFilter()} and \texttt{flushAllFilters()} do exactly what their names propose. They remove one or all defined filters of this tool. \footnotesize \begin{verbatim} [...] tag_list_t getDefinedTags(); component_list_t getDefinedComponents(); void test(); \end{verbatim} \normalsize The remaining functions of the \texttt{LogCentralTool} interface mainly provide convenience services. \texttt{Test()} can be used to check the validity of a LogCentralTool reference. \texttt{GetDefinedTags()} returns the list of available tags as defined in the configuration file. Tools who are written to monitor a certain application usually don't need this information, but there may exist general purpose tools which are interested in which tags are available. \texttt{GetDefinedComponents()} returns a list of currently connected components. A tool can compute this list itself by processing the received \emph{IN} and \emph{OUT} messages, but very simple tools might want to use this function for convenience reasons. Tools that want to connect to the LogCentral need to obtain a reference to it's \texttt{LogToolComponent} servant. This reference will be registered by LogCentral in the Naming Service. The name of the reference is 'LCT' in the context 'LogServiceT'. The kind of reference and context is empty. \subsubsection{The LogToolBase library} \textcolor{red}{DEPRECATED (the library is out of date)}\\ Just like the LogComponentBase, the LogToolBase hides many details of the connection and the message receiving. In order to use the LogComponentBase, the user must inherit from it and overwrite the abstract function sendMsg(). This function will be called by the LogComponentBase's MsgReceiver if a message is received. A C++ and a Java implementation of the LogToolBase exist. Both follow the interface defined in the IDL quite straightforward and will not be explained here. Look at the C++ header file\footnote{\emph{libraries/LogToolBaseC++/LogToolBase.hh}} or the java source code\footnote{\emph{libraries/LogToolBaseJava/LogToolBase.java}} for detail. The C++ library is based on omniORB and will be built with the LogCentral. The java library relies on JAVAs built in ORB and is distributed in source code only. There is no compilation support through the makefiles, so you must compile the IDL files and all the java classes yourself. Please note that the LogToolBase was not extensively tested yet and may still contain bugs. \section{How to write a quick component/tool} \subsection{Component} An example of functionnal component can be found in DIET, in DIET\_HOME/src/utils/log/DIETLogComponent.cc. The defined component must inherit from the component configurator IDL (the POA\_ComponentConfigurator class) and have a Log Central Component attribute (type LogCentralComponent\_var). The class must redefine 3 main functions plus some useful functions: \begin{itemize} \item The 3 main \begin{itemize} \item void setTagFilter(const tag\_list\_t\& taglist) \item void addTagFilter(const tag\_list\_t\& taglist) \item void removeTagFilter(const tag\_list\_t\& taglist) \end{itemize} \item The useful (that are not to be called by the user) \begin{itemize} \item void synchronize() : synchronization with the log central \item void ping() : ping the log central \end{itemize} \end{itemize} Moreover, the class must provide log function(s). For example, it may offer \begin{verbatim} void log (char* tag, char* msg){ log_msg_t logM; log_msg_buf_t out; logMsg.componentName = CORBA::string_dup(name); // name is the name of the component stored as an attribute of the class logM.time = getLocalTime(); logM.tag = CORBA::string_dup(tag) logM.msg = CORBA::string_dup(msg) out[out.length()] = logM; LCC->sendBuffer (out); // LCC is the Log Central Component attribute } \end{verbatim} The initialisation of the LCC element is done with a LogORBMgr::getMgr()-$>$resolve('LogServiceC', 'LCC') call, then you must bind (and fwdsBind) using \_this() and the name as parameters. Finally you can connect the component with the connectComponent() call. \subsection{Tool} The examples testTool and DIETtestTool are 2 functionnal examples of how to make a tool. \\ First the tool must inherit from POA\_ToolMsgReceiver and have a LogCentralTool attribute. The initialisation of the log central tool attribute is made with a resolve ('LogServiceT', 'LCT'), then the tool is binded (with its name and \_this()). Finally the tool can be connected with a connectTool call. A filter can be created and added with a addFilter call. \\ The class must only redefine the sendMsg(const log\_msg\_buf\_t\& msg) function.\\ Nothing more is needed to have a functionnal tool (in fact you need a main and call the initialisation sequence to have a functionnal tool) \section{Technical details of LogCentral} By now you should know everything you need know to use LogService. It is not mandatory to read this section as it mainly contains technical information on how LogCentral is implemented. It also explains LogCentral's main components and the way they work together. This section mainly addresses developers who want to change the sourcecode and give them a short overview of LogCentral's internals. \subsection{Overview of the log} Before explaining detailed scenarios we present the component diagram of LogCentral (see figure \ref{fig:components}). Objects are denoted by boxes, fixed relationships by arrows and threads by circles. Please note that the the \texttt{LogCentralComponent\_impl} and the \texttt{LogCentralTool\_impl} are servants that can be called by the ORB while \texttt{SendMsgReceiver} and \texttt{ComponentConfigurator} are proxies for distant objects. A very important part of the system is the \texttt{FullLinkedList (FLL)} template. It offers a double linked list that guarantees synchronisation. If an object wants to access the list, it has to acquire an iterator. This iterator guarantees synchronous operation by locking the FLL's internal read/write mutex. This mutex won't be unlocked until the list is destroyed. All synchronisation in LogCentral is done by using this mutex in the FLL. \begin{figure}[htb] \center\includegraphics[width=14cm]{fig/LogCentral_component2.eps} \caption{LogCentral components} \label{fig:components} \end{figure} \vspace{2ex} The \texttt{ToolList} and the \texttt{ComponentList} contain data shared by all objects, the \texttt{Options} class acts as a central storage for all constants and the \texttt{ReadConfig} class is responsible for parsing the configuration file. All other classes will be explained in the following sections that represent the four major usecases of LogCentral. \subsection{Overview with the forwarders} The following image represent an overview of what needs to be running for the forwarder. \begin{itemize} \item In magenta, there are on each side of the network the omninames running. \item In yellow, there are the 2 forwarder, they communicate throught a ssh tunnel. Both of them are under the same naming context. \item In grey is the LogCentral, the 2 boxes inside represent its component and its tool he registers in the naming context. \item In orange are the tools, both of them are under the same context in the omninames and linked to the log central. The first one is direct (black link), the red one is virtual, in fact this tool is linked going through the forwarders, using the name saved in the omninames. \item In green are the components, both of them are under the same context in the omninames and linked to the log central. The first one is direct (black link), the red one is virtual, in fact this component is linked going through the forwarders, using the names saved in the omninames. \end{itemize} \begin{figure}[hu!] \center\includegraphics[scale=0.3]{fig/example_orga.eps} \caption{Example using the forwarders} \end{figure} \newpage \subsection{Connection of Components} A component connects through the appropriate methods in \texttt{LogCentralComponent\_impl}. After checking it's name and generating a unique name if necessary, the \texttt{LogCentralComponent\_impl} inserts the component in the \texttt{ComponentList}. It then notifies the filtermanager through the \texttt{FilterManagerInterface} and receives the components initial configuration. After that it inserts the component in it's internal list that stores the latency and the last ping from the component. The time of the last ping will be checked regularly by the \texttt{AliveCheckThread}, an internal thread of the \texttt{LogCentralComponent\_impl}. The Disconnection of components works just the same. \subsection{Connection of Tools} The connection of tools works like the connection of components. A tool connects through the \texttt{LogCentralTool\_impl}. It is inserted in the \texttt{ToolList} and the \texttt{FilterManagerInterface} is notified. After that the \texttt{LogCentralTool\_impl} asks the \texttt{StateManager} to copy the actual system state in the \texttt{OutBuffer} that has been assigned for the new tool. For disconnection, the \texttt{FilterManagerInterface} is notified and the corresponding \texttt{ToolElement} is removed from the list. Remaining messages and filters are deleted by this. \subsection{Configuration of filters} Filters will be configured through the \texttt{LogCentralTool\_impl}. It checks the name of the tool as well as the name of the filter, inserts the filter in the tool's \texttt{FilterList} and notifies the \texttt{FilteManagerInterface}. The filtermanager will calculate a new configuration for each component. It will check for each component if the configuration has changed and (if necessary) forward the new configuration through the \texttt{ComponentConfigurator} assigned to this component. \subsection{Processing messages} Messages enter the system at the \texttt{LogCentralComponent\_impl} where their timestamp is altered according to the internal latency list. Then the messages are stored in the \texttt{TimeBuffer} one by one. The timebuffer will sort the messages automatically in it's internal list. They remain there until the \texttt{CoreThread} checks the timebuffer to find messages that are older than a defined minimum age. It will remove the oldest message and check with the help of the \texttt{StateManager} if this message is important for the systemstate. If yes, the statemanager will keep a copy of this message in it's statebuffer and the corethread will broadcast this message to all tools. Otherwise the corethread passes the message to the \texttt{FilterManager} which will apply the necessary filters for each tool and forward the message to all interested tools. In both cases the message is not sent directly, but put in the tool's \texttt{OutBuffer}. The outbuffers are cleared regularly by the \texttt{SendThread}. It checks each tool's outbuffer and uses the \texttt{ToolMsgReceiver} to actually send the messages. \section{Future works} LogService was written to monitor the DIET system. As such the project is finished and will hopefully work properly the next years. Anyway some parts of LogService could be enhanced. First of all the \texttt{SimpleFilterManager} could be replaced by filtermanager with better reconfiguration algorithms to increase the overall performance of the system. Second the statemanager should eventually be changed to allow a more sophisticated description of corresponding messages that allow a better model of the systemstate. If you want to participate in this work or if you have any other questions concerning LogService, don't hesitate to mail the authors\footnote{ Georg Hoesch: hoesch@in.tum.de, Cyrille Pontvieux: cyrille.pontvieux@edu.univ-fcomte.fr } or the graal staff\footnote{ Please follow the links on \url{http://graal.ens-lyon.fr} }. Any kind of feedback will be appreciated to ensure the future development of this software. \end{document} LogService-2.7.0/docs/manual/fig/LogCentral_component.fig000644 000765 000765 00000016543 11576373445 025003 0ustar00bdepardobdepardo000000 000000 #FIG 3.2 Landscape Center Metric Letter 100.00 Single -2 1200 2 6 630 5445 2880 6390 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 662 5461 2880 5461 2880 6390 662 6390 662 5461 4 0 0 50 0 0 12 0.0000 4 180 2100 720 5760 LogCentralComponent_impl\001 -6 6 3600 7725 4725 8250 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 3600 7740 4725 7740 4725 8235 3600 8235 3600 7740 4 0 0 50 0 0 12 0.0000 4 135 855 3735 8010 TimeBuffer\001 -6 6 10200 8325 11250 8700 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 10260 8325 11205 8325 11205 8685 10260 8685 10260 8325 4 0 0 50 0 0 12 0.0000 4 135 705 10395 8550 StateList\001 -6 6 8100 7275 9450 7725 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8145 7290 9450 7290 9450 7695 8145 7695 8145 7290 4 0 0 50 0 0 12 0.0000 4 180 1080 8280 7515 StateManager\001 -6 6 8775 7650 10275 8550 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 8775 7695 8775 8505 10260 8505 4 0 0 50 0 0 12 0.0000 4 180 360 9270 8415 keep\001 -6 6 2925 4125 5325 4800 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 2970 4185 5265 4185 5265 4770 2970 4770 2970 4185 4 0 0 50 0 0 12 0.0000 4 180 1155 3465 4410 ComponentList\001 4 0 0 50 0 0 12 0.0000 4 180 2100 3060 4635 FLL*\001 -6 6 3150 3000 4950 3375 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 3195 3015 4950 3015 4950 3375 3195 3375 3195 3015 4 0 0 50 0 0 12 0.0000 4 180 1485 3330 3240 ComponentElement\001 -6 6 2880 1755 5265 2205 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 2880 1755 5265 1755 5265 2205 2880 2205 2880 1755 4 0 0 50 0 0 12 0.0000 4 180 1800 3150 2025 ComponentConfigurator\001 -6 6 2850 4725 4050 5775 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 2880 5760 3960 5760 3960 4725 4 0 0 50 0 0 12 0.0000 4 180 960 2970 5670 co/deco (W)\001 -6 6 5475 4800 7575 5850 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 2 5519 5493 7560 5490 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 5519 4850 7560 4850 7560 5850 5519 5850 5519 4850 4 0 0 50 0 0 12 0.0000 4 180 1080 5985 5040 FilterManager\001 4 0 0 50 0 0 12 0.0000 4 180 1770 5670 5715 FilterManagerInterface\001 -6 6 5175 7200 6225 7875 2 4 0 1 0 7 50 0 -1 5.000 0 0 20 0 0 5 6165 7830 6165 7200 5220 7200 5220 7830 6165 7830 4 0 0 50 0 0 12 0.0000 4 135 360 5535 7560 Core\001 -6 6 4050 7350 5250 7800 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 5220 7515 4140 7515 4140 7740 4 0 0 50 0 0 12 0.0000 4 150 240 4545 7470 get\001 -6 6 6150 7275 8175 7575 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 6165 7515 8145 7515 4 0 0 50 0 0 12 0.0000 4 135 450 7245 7470 check\001 -6 6 5625 5850 6975 7200 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 5625 7200 5625 6930 6930 6930 6930 5850 4 0 0 50 0 0 12 0.0000 4 180 1305 5625 6885 forward message\001 -6 6 7500 4725 8550 5775 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 7560 5760 8505 5760 8505 4770 4 0 0 50 0 0 12 0.0000 4 180 825 7650 5670 update (R)\001 -6 6 4125 4725 5550 5775 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 5490 5760 4185 5760 4185 4725 4 0 0 50 0 0 12 0.0000 4 180 825 4455 5670 update (R)\001 -6 6 2850 5850 5850 6225 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 2880 6165 5760 6165 5760 5850 4 0 0 50 0 0 12 0.0000 4 180 435 4050 6120 notify\001 -6 6 2850 5850 6000 6525 2 1 0 1 14 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 5940 5850 5940 6255 2880 6255 4 0 0 50 0 0 12 0.0000 4 180 930 4365 6435 initial config\001 -6 6 9450 6375 11325 7500 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 1 3 1 1 1.00 60.00 120.00 1 1 1.00 60.00 120.00 11250 6390 11250 7470 9450 7470 4 0 0 50 0 0 12 0.0000 4 180 1500 9675 7380 askForSystemState\001 -6 6 10125 5490 11880 6435 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 10148 5490 11866 5490 11866 6418 10148 6418 10148 5490 4 0 0 50 0 0 12 0.0000 4 180 1575 10215 5760 LogCentralTool_impl\001 -6 6 7125 5850 10125 6225 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 10125 6165 7155 6165 7155 5850 4 0 0 50 0 0 12 0.0000 4 180 435 7380 6120 notify\001 -6 6 9090 4770 10125 5760 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 10125 5760 9135 5760 9135 4770 4 0 0 50 0 0 12 0.0000 4 180 885 9225 5715 update (W)\001 -6 6 8250 3150 9525 3600 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8280 3195 9495 3195 9495 3600 8280 3600 8280 3195 4 0 0 50 0 0 12 0.0000 4 135 960 8415 3465 ToolElement\001 -6 6 5850 4725 8775 7200 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 5850 7200 5850 7065 8730 7065 8730 4770 4 0 0 50 0 0 12 0.0000 4 180 1560 7110 6975 broadcast messages\001 -6 6 8025 4125 9825 4800 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8055 4185 9810 4185 9810 4770 8055 4770 8055 4185 4 0 0 50 0 0 12 0.0000 4 135 630 8550 4410 ToolList\001 4 0 0 50 0 0 12 0.0000 4 135 1485 8235 4635 FLL\001 -6 6 6750 1650 8025 2325 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 6750 1710 7965 1710 7965 2295 6750 2295 6750 1710 4 0 0 50 0 0 12 0.0000 4 180 1035 6840 2160 FLL\001 4 0 0 50 0 0 12 0.0000 4 135 645 7020 1935 FilerList\001 -6 6 8100 1650 9675 2325 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8145 1710 9675 1710 9675 2295 8145 2295 8145 1710 4 0 0 50 0 0 12 0.0000 4 180 1305 8280 2160 FLL\001 4 0 0 50 0 0 12 0.0000 4 135 765 8550 1935 OutBuffer\001 -6 6 9975 1800 11625 2250 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 9990 1800 11565 1800 11565 2205 9990 2205 9990 1800 4 0 0 50 0 0 12 0.0000 4 180 1350 10125 2070 ToolMsgReceiver\001 -6 6 10650 3150 11850 4425 1 3 0 1 0 7 50 0 -1 5.000 1 0.0000 11250 3780 573 573 11250 3780 11655 4185 4 0 0 50 0 0 12 0.0000 4 135 885 10800 3825 sendThread\001 -6 6 8925 4725 10425 7350 2 1 1 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 8955 7290 8955 4770 4 0 0 50 0 0 12 0.0000 4 180 1335 9045 6885 sendSystemState\001 -6 6 9300 2175 10800 3525 2 1 1 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 10755 3465 9315 2295 2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9855 2745 10350 2205 -6 2 1 3 3 4 7 50 0 -1 10.000 0 0 -1 0 0 2 12285 450 12285 9270 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 4050 4185 4050 3375 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 4050 3015 4050 2205 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 1575 6390 1575 8010 3600 8010 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 8820 4185 8820 3600 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 8685 3195 8685 2970 7335 2970 7335 2295 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 8820 3195 8820 2295 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 8955 3195 8955 2970 10710 2970 10710 2205 2 1 0 1 0 7 50 0 -1 5.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 11250 4365 11250 4545 9810 4545 2 1 3 3 4 7 50 0 -1 10.000 0 0 -1 0 0 2 270 450 270 9270 2 1 0 2 10 7 50 0 -1 4.500 0 0 -1 1 0 2 1 1 2.00 90.00 180.00 2880 1980 0 1980 2 1 0 2 10 7 50 0 -1 4.500 0 0 -1 0 1 2 1 1 2.00 90.00 180.00 675 5940 0 5940 2 1 0 2 10 7 50 0 -1 4.500 0 0 -1 0 1 2 1 1 2.00 90.00 180.00 11880 5940 12600 5940 2 1 0 2 10 7 50 0 -1 4.500 0 0 -1 1 0 2 1 1 2.00 90.00 180.00 11565 1980 12600 1980 4 0 0 50 0 3 14 0.0000 4 150 2130 405 9585 * FLL = FullLinkedList\001 4 0 4 50 0 2 14 0.0000 4 195 1860 180 315 LogComponent API\001 4 2 4 50 0 2 14 0.0000 4 195 1215 12420 315 LogTool API\001 4 0 0 50 0 0 12 0.0000 4 150 240 2295 7875 put\001 4 1 24 50 0 18 20 0.0000 4 300 3465 6120 720 LogCentral components\001 LogService-2.7.0/docs/manual/fig/LogCentral_component2.fig000644 000765 000765 00000015074 11576373445 025063 0ustar00bdepardobdepardo000000 000000 #FIG 3.2 Landscape Center Metric Letter 100.00 Single -2 1200 2 6 6525 1125 7875 1845 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 6525 1125 7875 1125 7875 1845 6525 1845 6525 1125 4 0 0 50 -1 0 14 0.0000 4 150 750 6615 1395 filterList\001 4 0 0 50 -1 0 14 0.0000 4 135 390 6615 1665 FLL\001 -6 6 8685 1125 10035 1845 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8685 1125 10035 1125 10035 1845 8685 1845 8685 1125 4 0 0 50 -1 0 14 0.0000 4 180 915 8820 1440 MsgBuffer\001 4 0 0 50 -1 0 14 0.0000 4 135 390 8820 1710 FLL\001 -6 6 180 1170 1530 1890 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 180 1170 1530 1170 1530 1890 180 1890 180 1170 4 0 0 50 -1 0 14 0.0000 4 180 1050 270 1458 Component-\001 4 0 0 50 -1 0 14 0.0000 4 180 1095 270 1714 Configurator\001 -6 6 2565 2565 4455 2970 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 2565 2565 4455 2565 4455 2970 2565 2970 2565 2565 4 0 0 50 0 0 14 0.0000 4 195 1680 2655 2835 ComponentElement\001 -6 6 2205 3555 4770 4230 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 2205 3555 4770 3555 4770 4230 2205 4230 2205 3555 4 0 0 50 0 0 14 0.0000 4 180 1305 2835 3825 ComponentList\001 4 0 0 50 0 0 14 0.0000 4 195 2310 2340 4095 FLL\001 -6 6 1665 4860 3375 5535 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 1696 4860 3375 4860 3375 5535 1696 5535 1696 4860 4 0 0 50 -1 0 14 0.0000 4 195 1470 1800 5400 Component_impl\001 4 0 0 50 -1 0 14 0.0000 4 195 1035 1845 5130 LogCentral-\001 -6 6 3870 6300 5535 6975 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 3870 6300 5535 6300 5535 6975 3870 6975 3870 6300 4 0 0 50 -1 0 14 0.0000 4 135 1005 4140 6660 TimeBuffer\001 -6 6 6255 5985 7605 7245 1 1 0 1 0 7 50 -1 -1 0.000 1 0.0000 6930 6615 630 585 6930 6615 6300 6030 4 0 0 50 -1 0 14 0.0000 4 150 1005 6435 6660 CoreThread\001 -6 6 5490 4860 7155 5535 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 5490 4860 7155 4860 7155 5535 5490 5535 5490 4860 4 0 0 50 -1 0 14 0.0000 4 135 750 5580 5400 Interface\001 4 0 0 50 -1 0 14 0.0000 4 195 1260 5580 5130 Filtermanager-\001 -6 6 5490 3825 7155 4500 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 5490 3825 7155 3825 7155 4500 5490 4500 5490 3825 4 0 0 50 -1 0 14 0.0000 4 180 735 5625 4365 Manager\001 4 0 0 50 -1 0 14 0.0000 4 195 1140 5625 4095 SimpleFilter-\001 -6 6 7830 3555 10350 4230 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 7830 3555 10350 3555 10350 4230 7830 4230 7830 3555 4 0 0 50 -1 0 14 0.0000 4 150 735 8640 3825 ToolList\001 4 0 0 50 -1 0 14 0.0000 4 150 1740 8235 4095 FLL\001 -6 6 8145 2565 10035 2970 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8145 2565 10035 2565 10035 2970 8145 2970 8145 2565 4 0 0 50 -1 0 14 0.0000 4 150 1110 8550 2835 ToolElement\001 -6 6 10980 1170 12330 1890 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 10980 1170 12330 1170 12330 1890 10980 1890 10980 1170 4 0 0 50 -1 0 14 0.0000 4 135 735 11115 1710 Receiver\001 4 0 0 50 -1 0 14 0.0000 4 195 855 11115 1440 SendMsg-\001 -6 6 9090 4860 10800 5535 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 9121 4860 10800 4860 10800 5535 9121 5535 9121 4860 4 0 0 50 -1 0 14 0.0000 4 195 900 9225 5400 Tool_impl\001 4 0 0 50 -1 0 14 0.0000 4 195 1035 9225 5130 LogCentral-\001 -6 6 8460 6255 10125 6930 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8460 6255 10125 6255 10125 6930 8460 6930 8460 6255 4 0 0 50 -1 0 14 0.0000 4 180 1155 8685 6615 StateManager\001 -6 6 5580 2205 7020 3465 1 1 0 1 0 7 50 -1 -1 0.000 1 0.0000 6300 2835 675 585 6300 2835 5625 2250 4 0 0 50 -1 0 14 0.0000 4 150 1020 5760 2880 SendThread\001 -6 6 4005 7335 5355 8055 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 4005 7335 5355 7335 5355 8055 4005 8055 4005 7335 4 0 0 50 -1 0 14 0.0000 4 180 915 4140 7650 MsgBuffer\001 4 0 0 50 -1 0 14 0.0000 4 135 390 4140 7920 FLL\001 -6 6 8595 7335 9945 8055 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 8595 7335 9945 7335 9945 8055 8595 8055 8595 7335 4 0 0 50 -1 0 14 0.0000 4 180 915 8730 7650 MsgBuffer\001 4 0 0 50 -1 0 14 0.0000 4 135 390 8730 7920 FLL\001 -6 6 2025 7695 3555 8460 2 2 0 1 0 7 50 0 -1 5.000 0 0 -1 0 0 5 2025 7695 3555 7695 3555 8460 2025 8460 2025 7695 4 0 0 50 -1 0 14 0.0000 4 150 1275 2160 8010 FullLinkedList\001 4 0 0 50 -1 0 14 0.0000 4 195 1305 2115 8280 (FLL) template\001 -6 2 1 3 3 4 7 50 0 -1 10.000 0 0 -1 0 0 2 10890 810 10890 8550 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 3375 5220 5490 5220 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 7155 5220 9135 5220 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3 1 1 1.00 60.00 120.00 3375 5355 4680 5355 4680 6300 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 5535 6615 6300 6615 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 4680 6975 4680 7335 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 0 1.00 60.00 120.00 6300 4860 6300 4500 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 6930 6030 6930 5535 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 7560 6615 8460 6615 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9270 6930 9270 7335 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 9585 5535 9585 6255 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9765 4860 9765 4230 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2745 4860 2745 4230 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 3465 3555 3465 2970 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9090 3555 9090 2970 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9090 2565 9090 1845 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 7875 1845 8730 2565 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 9450 2565 10980 1890 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2565 2565 1530 1890 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 4 1 1 1.00 60.00 120.00 7830 3735 7515 3735 7515 2835 6975 2835 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 7155 4050 7830 4050 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 5490 4050 4770 4050 2 1 3 3 4 7 50 0 -1 10.000 0 0 -1 0 0 2 1620 720 1620 8550 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 1710 5220 1215 5220 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 10800 5220 11340 5220 4 1 0 50 0 18 20 0.0000 4 300 3450 5940 495 LogCentral components\001 4 0 4 50 0 2 14 0.0000 4 135 405 11385 1035 Tool\001 4 0 4 50 0 2 14 0.0000 4 180 1065 270 1035 Component\001 4 0 4 50 0 2 14 0.0000 4 180 1035 5265 1035 LogCentral\001 4 2 4 50 0 2 14 0.0000 4 180 1155 11430 675 LogTool API\001 4 0 4 50 0 2 14 0.0000 4 180 1815 765 585 LogComponent API\001 4 0 0 50 -1 0 12 0.0000 4 75 90 3555 3195 *\001 4 0 0 50 -1 0 12 0.0000 4 75 90 9180 3195 *\001 LogService-2.7.0/docs/manual/fig/Makefile000644 000765 000765 00000000140 11576373445 021622 0ustar00bdepardobdepardo000000 000000 all: LogCentral_component2.eps %.eps: %.fig fig2dev -L eps $*.fig $*.eps clean: rm -f *.eps LogService-2.7.0/docs/man/CMakeLists.txt000644 000765 000765 00000002266 11576373446 021467 0ustar00bdepardobdepardo000000 000000 ############################################################################## # man pages generation # we need rst2man for the generation # ############################################################################## find_program( RST2MAN_BIN rst2man ) if( RST2MAN_BIN ) # set man pages install dir set( MAN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Directory where man pages will be installed" FORCE ) add_custom_target( man ALL ) file( GLOB MAN_PAGES_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.rst" ) # create man output directory file( MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/man1" ) foreach( SRC ${MAN_PAGES_SRCS} ) string( REGEX REPLACE "(.*).rst$" "\\1" BASENAME ${SRC} ) add_custom_target( "man-${BASENAME}" ${RST2MAN_BIN} "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}" "man1/${BASENAME}.1" ) add_dependencies( man "man-${BASENAME}" ) endforeach() install( DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/man1" DESTINATION "${MAN_INSTALL_DIR}" ) else() message( WARNING " Man pages will not be built due to missing requirements." ) message( WARNING " Please install rst2man (usually included in python-docutils package)" ) endif() LogService-2.7.0/docs/man/DIETtestTool.1000644 000765 000765 00000007622 11576373446 021275 0ustar00bdepardobdepardo000000 000000 .\" Man page generated from reStructeredText. . .TH DIETTESTTOOL 1 "2011-05-16" "0.1" "" .SH NAME DIETTestTool \- Example of a tool for DIET using the LogCentral . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH NAME .sp DIETTestTool \- Example of a tool that connects to the LogCentral without any filter and that display all the messages published. It is used as an example for the DIET program. All received published messages are also stored in a log file. .SH SYNOPSYS .INDENT 0.0 .INDENT 3.5 .sp DIETTestTool [options] ... .UNINDENT .UNINDENT .SH DESCRIPTION .sp DIETTestTool connects to the LogCentral and get the messages (by default all, a file containing filters may be passed as an argument). The tool both display and save the messages in a log file. This log file may be given or will be created with a fix name "DIETLogTool.log". .sp Before starting the LogCentral, you must: .INDENT 0.0 .IP \(bu 2 . launch a CORBA Naming Service. .IP \(bu 2 . launch log forwarders \fIif needed\fP .IP \(bu 2 . launch LogCentral service .IP \(bu 2 . Launch the DIETTestTool .IP \(bu 2 . Use a component to publish messages .UNINDENT .SH OPTIONS .INDENT 0.0 .IP \(bu 2 . The first argument is the destination output file that will contain the displayed logs. .IP \(bu 2 . The second one is a filter to use in the tool .UNINDENT .sp [Remark: There is no option letter, the order is fixed] .SH EXAMPLE .INDENT 0.0 .IP \(bu 2 . Launching the LogCentral .UNINDENT .sp .nf .ft C LogCentral \-config ./LogCentral.cfg .ft P .fi .INDENT 0.0 .IP \(bu 2 . Launching the tool .UNINDENT .sp .nf .ft C DIETTestTool .ft P .fi .INDENT 0.0 .IP \(bu 2 . Launching the tool to store the logs in the toto.log file .UNINDENT .sp .nf .ft C DIETTestTool toto.log .ft P .fi .INDENT 0.0 .IP \(bu 2 . Launching the tool to store the logs in the toto.log file with the filter in the filter.txt file .UNINDENT .sp .nf .ft C DIETTestTool toto.log filter.txt .ft P .fi .SH RATIONALE .sp The LogTool uses CORBA as its communication layer. While it\(aqs a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. .SH LICENSE AND COPYRIGHT .SS Copyright .sp (C)2011, GRAAL, INRIA Rhone\-Alpes, 46 allee d\(aqItalie, 69364 Lyon cedex 07, France all right reserved <\fI\%diet\-dev@ens\-lyon.fr\fP> .SS License .sp This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub\- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <\fI\%http://www.gnu.org/licenses/\fP>. .SH AUTHORS .sp GRAAL INRIA Rhone\-Alpes 46 allee d\(aqItalie 69364 Lyon cedex 07, FRANCE Email: <\fI\%diet\-dev@ens\-lyon.fr\fP> WWW: \fI\%http://graal.ens\-lyon.fr/DIET\fP .SH SEE ALSO .sp omniNames(1), logForwarder(1), LogCentral(1), testComponent(1) .SH BUGS .SH AUTHOR haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com License: GPLv3 .SH COPYRIGHT DIET developers .\" Generated by docutils manpage writer. .\" . LogService-2.7.0/docs/man/DIETtestTool.rst000644 000765 000765 00000005732 11576373446 021745 0ustar00bdepardobdepardo000000 000000 ============= DIETTestTool ============= ----------------------------------------------- Example of a tool for DIET using the LogCentral ----------------------------------------------- :Authors: haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com :Date: 2011-05-16 :Copyright: DIET developers :License: GPLv3 :Version: 0.1 :Manual section: 1 NAME ==== DIETTestTool - Example of a tool that connects to the LogCentral without any filter and that display all the messages published. It is used as an example for the DIET program. All received published messages are also stored in a log file. SYNOPSYS ======== DIETTestTool [options] ... DESCRIPTION =========== DIETTestTool connects to the LogCentral and get the messages (by default all, a file containing filters may be passed as an argument). The tool both display and save the messages in a log file. This log file may be given or will be created with a fix name "DIETLogTool.log". Before starting the LogCentral, you must: * launch a CORBA Naming Service. * launch log forwarders *if needed* * launch LogCentral service * Launch the DIETTestTool * Use a component to publish messages OPTIONS ======= * The first argument is the destination output file that will contain the displayed logs. * The second one is a filter to use in the tool [Remark: There is no option letter, the order is fixed] EXAMPLE ======= * Launching the LogCentral :: LogCentral -config ./LogCentral.cfg * Launching the tool :: DIETTestTool * Launching the tool to store the logs in the toto.log file :: DIETTestTool toto.log * Launching the tool to store the logs in the toto.log file with the filter in the filter.txt file :: DIETTestTool toto.log filter.txt RATIONALE ========= The LogTool uses CORBA as its communication layer. While it's a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. LICENSE AND COPYRIGHT ===================== Copyright --------- (C)2011, GRAAL, INRIA Rhone-Alpes, 46 allee d'Italie, 69364 Lyon cedex 07, France all right reserved License ------- This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . AUTHORS ======= GRAAL INRIA Rhone-Alpes 46 allee d'Italie 69364 Lyon cedex 07, FRANCE Email: WWW: http://graal.ens-lyon.fr/DIET SEE ALSO ======== omniNames(1), logForwarder(1), LogCentral(1), testComponent(1) BUGS ==== LogService-2.7.0/docs/man/LogCentral.1000644 000765 000765 00000010672 11576373446 021043 0ustar00bdepardobdepardo000000 000000 .\" Man page generated from reStructeredText. . .TH LOGCENTRAL 1 "2011-05-11" "0.1" "" .SH NAME LogCentral \- Central loggin service for distributed applications . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH NAME .sp LogCentral \- service using the publisher/subscriber model, where components publish tagged messages and tools get back appropriate messages . .SH SYNOPSYS .INDENT 0.0 .INDENT 3.5 .sp LogCentral [options] ... .UNINDENT .UNINDENT .SH DESCRIPTION .sp LogCentral gathers and publishes the messages to the subscribers. Messages are tagged, the LogCentral service only sends suscribers filtered messages. .sp Before starting the LogCentral, you must: .INDENT 0.0 .IP \(bu 2 . launch a CORBA Naming Service. .IP \(bu 2 . launch log forwarders \fIif needed\fP .IP \(bu 2 . launch LogCentral service .UNINDENT .sp [Remark: LogCentral must be launched before the log tools/components] .SH OPTIONS .INDENT 0.0 .TP .B \fB\-config\fP [name] .sp The configuration file for the LogCentral service. First, LogCentral will use the file provided by command\-line, then read environment variable $LOGCENTRAL_CONFIG and in last resort, it will look for a file named "config.cfg" in current directory. .UNINDENT .SH CONFIGURATION FILE .sp You can pass a configuration file to LogCentral using command line options through the \-config option. Configuration file lists several classes of tags describing the messages. A minimal configuration will look like this: .sp [General] .sp [DynamicTagList] [StaticTagList] [UniqueTagList] [VolatileTagList] .sp The general tag accept the following parameters: * \(aqport=xxx\(aq, specifies the port to use .INDENT 0.0 .IP \(bu 2 . \(aqMinAge=xxx\(aq, defines the minimum period of time that messages will be stored in the LogCentral .IP \(bu 2 . \(aqDynamicStartSuffix=START\(aq, expands tags with START. See DynamicTagList. .IP \(bu 2 . \(aqDynamicStopSuffix=STOP\(aq, expands tags with STOP. See DynamicTagList. .UNINDENT .sp The other four categories configure the state manager of the LogCentral. It is important to know that all tags will be expanded with two suffixes to generate pairs of tags. .INDENT 0.0 .IP \(bu 2 . VolatileTagList, should contain all the monitored tags. Not essential but it may be requested by some tool. .IP \(bu 2 . UniqueTagList, should contain tags that will overwrite the previous messages of this tag .UNINDENT .SH EXAMPLE .INDENT 0.0 .IP \(bu 2 . Launching the LogCentral .UNINDENT .sp .nf .ft C LogCentral \-config ./LogCentral.cfg .ft P .fi .SH RATIONALE .sp The LogCentral uses CORBA as its communication layer. While it\(aqs a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. .SH LICENSE AND COPYRIGHT .SS Copyright .sp (C)2011, GRAAL, INRIA Rhone\-Alpes, 46 allee d\(aqItalie, 69364 Lyon cedex 07, France all right reserved <\fI\%diet\-dev@ens\-lyon.fr\fP> .SS License .sp This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub\- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <\fI\%http://www.gnu.org/licenses/\fP>. .SH AUTHORS .sp GRAAL INRIA Rhone\-Alpes 46 allee d\(aqItalie 69364 Lyon cedex 07, FRANCE Email: <\fI\%diet\-dev@ens\-lyon.fr\fP> WWW: \fI\%http://graal.ens\-lyon.fr/DIET\fP .SH SEE ALSO .sp omniNames(1), logForwarder(1) .SH BUGS .SH AUTHOR haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com License: GPLv3 .SH COPYRIGHT DIET developers .\" Generated by docutils manpage writer. .\" . LogService-2.7.0/docs/man/LogCentral.rst000644 000765 000765 00000007117 11576373446 021513 0ustar00bdepardobdepardo000000 000000 ============= LogCentral ============= --------------------------------------------------- Central loggin service for distributed applications --------------------------------------------------- :Authors: haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com :Date: 2011-05-11 :Copyright: DIET developers :License: GPLv3 :Version: 0.1 :Manual section: 1 NAME ==== LogCentral - service using the publisher/subscriber model, where components publish tagged messages and tools get back appropriate messages . SYNOPSYS ======== LogCentral [options] ... DESCRIPTION =========== LogCentral gathers and publishes the messages to the subscribers. Messages are tagged, the LogCentral service only sends suscribers filtered messages. Before starting the LogCentral, you must: * launch a CORBA Naming Service. * launch log forwarders *if needed* * launch LogCentral service [Remark: LogCentral must be launched before the log tools/components] OPTIONS ======= **-config** [name] The configuration file for the LogCentral service. First, LogCentral will use the file provided by command-line, then read environment variable $LOGCENTRAL_CONFIG and in last resort, it will look for a file named "config.cfg" in current directory. CONFIGURATION FILE ================== You can pass a configuration file to LogCentral using command line options through the -config option. Configuration file lists several classes of tags describing the messages. A minimal configuration will look like this: [General] [DynamicTagList] [StaticTagList] [UniqueTagList] [VolatileTagList] The general tag accept the following parameters: * 'port=xxx', specifies the port to use * 'MinAge=xxx', defines the minimum period of time that messages will be stored in the LogCentral * 'DynamicStartSuffix=START', expands tags with START. See DynamicTagList. * 'DynamicStopSuffix=STOP', expands tags with STOP. See DynamicTagList. The other four categories configure the state manager of the LogCentral. It is important to know that all tags will be expanded with two suffixes to generate pairs of tags. * VolatileTagList, should contain all the monitored tags. Not essential but it may be requested by some tool. * UniqueTagList, should contain tags that will overwrite the previous messages of this tag EXAMPLE ======= * Launching the LogCentral :: LogCentral -config ./LogCentral.cfg RATIONALE ========= The LogCentral uses CORBA as its communication layer. While it's a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. LICENSE AND COPYRIGHT ===================== Copyright --------- (C)2011, GRAAL, INRIA Rhone-Alpes, 46 allee d'Italie, 69364 Lyon cedex 07, France all right reserved License ------- This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . AUTHORS ======= GRAAL INRIA Rhone-Alpes 46 allee d'Italie 69364 Lyon cedex 07, FRANCE Email: WWW: http://graal.ens-lyon.fr/DIET SEE ALSO ======== omniNames(1), logForwarder(1) BUGS ==== LogService-2.7.0/docs/man/logForwarder.1000644 000765 000765 00000015447 11576373446 021453 0ustar00bdepardobdepardo000000 000000 .\" Man page generated from reStructeredText. . .TH LOGFORWARDER 1 "2011-05-11" "0.1" "" .SH NAME logForwarder \- Log item to manage ssh tunnels between log components and tools . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH NAME .sp logForwarder \- Tools for creating and maintaining ssh tunnels between log components in complex topologies .SH SYNOPSYS .INDENT 0.0 .INDENT 3.5 .sp logForwarder [options] ... .UNINDENT .UNINDENT .SH DESCRIPTION .sp logForwarder helps simplifying the maintenance of ssh tunnels between log components and tools, thus improving log scalability and configuration in complex network topologies. The components may be defined in a program to be monitored, they publish messages in the LogCentral. The tools get the messages subscribing to the LogCentral. .sp Before starting a log forwarder, you must: .INDENT 0.0 .IP \(bu 2 . launch omniNames on the local and remotes hosts. .IP \(bu 2 . launch the remote peer only defining its name and network configuration. .IP \(bu 2 . launch local peer and give him remote peer\(aqs name, ssh connection informations, remote port to use and pass \-C option to create the ssh tunnel. .UNINDENT .sp [Remark: forwarders must be launched before the log tools/components] .SH OPTIONS .INDENT 0.0 .TP .B \fB\-\-name\fP [name] .sp String identifying the forwarder .TP .B \fB\-\-peer\-name\fP [name] .sp String identifying its peer on the other network .TP .B \fB\-\-ssh\-host\fP [host] .sp Host hosting the ssh tunnel .TP .B \fB\-\-ssh\-login\fP [login] .sp Login used to establish the ssh connection (default: current user login). .TP .B \fB\-\-ssh\-key\fP [/path/to/ssh/key] .sp Path to the ssh key (the private one !) used to establish the ssh connection (default: $HOME/.ssh/id_rsa). .TP .B \fB\-\-remote\-port\fP [port] .sp Port listening on the ssh host. .TP .B \fB\-\-remote\-host\fP [host] .sp Host to which the connection is made by the tunnel (corresponds to ssh options \-L and \-R). .TP .B \fB\-\-nb\-retry\fP [nb] .sp Number of times that the local forwarder will try to bind itself to the remote forwarder (default: 3). .TP .B \fB\-\-peer\-ior\fP [IOR] .sp Pass remote forwarder\(aqs IOR. By default, the local forwarder will retrive its peer IOR. .TP .B \fB\-\-net\-config\fP [path/to/configuration/file] .sp Path to configuration file. .TP .B \fB\-C\fP .sp Create the tunnel from this forwarder. .UNINDENT .SH CONFIGURATION FILE .sp You can pass a configuration file to dietForwarder instead of using command line options through the \-\-net\-config option. Configuration file lists several rules describing networks reachable using this forwarder. .sp There\(aqs two category of rules: .INDENT 0.0 .TP .B \fBaccept rules\fP .sp describe which networks are accessible through the forwarder. .TP .B \fBreject rules\fP .sp describe which networks are not accessible through the forwarder. .UNINDENT .sp A rule always starts by either \fBaccept:\fP or \fBreject:\fP immediately followed by a regular expression (Posix) describing host concerned by the rule. Rules are evaluated in the following order: \fBaccept\fP then \fBreject\fP. For instance: .INDENT 0.0 .INDENT 3.5 .sp accept:.* reject:localhost .UNINDENT .UNINDENT .sp This fragment means that the forwarder will accept connections to every hosts but localhost. .SH EXAMPLE .sp Here\(aqs a simple configuration: .INDENT 0.0 .IP \(bu 2 . We have two domains: \fInet1\fP and \fInet2\fP, forwarders will be launched on hosts \fIfwd.net1\fP and \fIfwd.net2\fP. .IP \(bu 2 . There\(aqs no link between hosts \fIfwd.net1\fP and \fIfwd.net2\fP but user may access \fIfwd.net2\fP from \fIfwd.net1\fP using a ssh connection. .IP \(bu 2 . We\(aqll name \fIfwd.net1\fP forwarder Fwd1 and \fIfwd.net2\fP fowarder Fwd2. .IP \(bu 2 . One tool lives in \fIfwd.net2\fP while a component lives on the \fInet1\fP domain. .UNINDENT .sp \fBCommand line for launchind Fwd1\fP .sp .nf .ft C fwd.net1$ logForwarder \-\-name Fwd1 \-\-peer\-name Fwd2 \e \-\-ssh\-host fwd.net2 \-\-ssh\-login dietUser \e \-\-ssh\-key id rsa net2 \-\-remote\-port 50000 \e \-\-net\-config net1.cfg \-C .ft P .fi .sp \fBCommand line to launch Fwd2\fP .sp .nf .ft C fwd.net2$ logForwarder \-\-name Fwd2 \-\-net\-config net2.cfg .ft P .fi .sp \fBConfiguration file for Fwd1\fP .sp In this example, the forwarders Fwd1 accepts only the connections to fwd.net2. .sp .nf .ft C accept:fwd.net2 .ft P .fi .sp \fBConfiguration file for Fwd2\fP .sp In this example, the forwarders Fwd2 accepts all the connections except those which are for the localhost. .sp .nf .ft C accept:.* reject:localhost .ft P .fi .SH RATIONALE .sp The log service uses CORBA as its communication layer. While it\(aqs a flexible and robust middleware, it remains hard deploying the log on heterogeneous networks that are not reachable except through ssh tunnels. Log forwarders help administrator configuring their grid without manually set\-up ssh tunnels which arguably is neither simple nor scalable. Log forwarders make it very easy configuring such topologies. .SH LICENSE AND COPYRIGHT .SS Copyright .sp (C)2011, GRAAL, INRIA Rhone\-Alpes, 46 allee d\(aqItalie, 69364 Lyon cedex 07, France all right reserved <\fI\%diet\-dev@ens\-lyon.fr\fP> .SS License .sp This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub\- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <\fI\%http://www.gnu.org/licenses/\fP>. .SH AUTHORS .sp GRAAL INRIA Rhone\-Alpes 46 allee d\(aqItalie 69364 Lyon cedex 07, FRANCE Email: <\fI\%diet\-dev@ens\-lyon.fr\fP> WWW: \fI\%http://graal.ens\-lyon.fr/DIET\fP .SH SEE ALSO .sp omniNames(1), dietForwarder(1), LogCentral(1) .SH BUGS .sp On some systems, forwarder rules won\(aqt work unless you use IP addresses instead of hostnames .SH AUTHOR haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com License: GPLv3 .SH COPYRIGHT DIET developers .\" Generated by docutils manpage writer. .\" . LogService-2.7.0/docs/man/logForwarder.rst000644 000765 000765 00000013245 11576373446 022115 0ustar00bdepardobdepardo000000 000000 ============= logForwarder ============= --------------------------------------------------------------- Log item to manage ssh tunnels between log components and tools --------------------------------------------------------------- :Author: haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com :Date: 2011-05-11 :Copyright: DIET developers :License: GPLv3 :Version: 0.1 :Manual section: 1 NAME ==== logForwarder - Tools for creating and maintaining ssh tunnels between log components in complex topologies SYNOPSYS ======== logForwarder [options] ... DESCRIPTION =========== logForwarder helps simplifying the maintenance of ssh tunnels between log components and tools, thus improving log scalability and configuration in complex network topologies. The components may be defined in a program to be monitored, they publish messages in the LogCentral. The tools get the messages subscribing to the LogCentral. Before starting a log forwarder, you must: * launch omniNames on the local and remotes hosts. * launch the remote peer only defining its name and network configuration. * launch local peer and give him remote peer's name, ssh connection informations, remote port to use and pass -C option to create the ssh tunnel. [Remark: forwarders must be launched before the log tools/components] OPTIONS ======= **--name** [name] String identifying the forwarder **--peer-name** [name] String identifying its peer on the other network **--ssh-host** [host] Host hosting the ssh tunnel **--ssh-login** [login] Login used to establish the ssh connection (default: current user login). **--ssh-key** [/path/to/ssh/key] Path to the ssh key (the private one !) used to establish the ssh connection (default: $HOME/.ssh/id_rsa). **--remote-port** [port] Port listening on the ssh host. **--remote-host** [host] Host to which the connection is made by the tunnel (corresponds to ssh options -L and -R). **--nb-retry** [nb] Number of times that the local forwarder will try to bind itself to the remote forwarder (default: 3). **--peer-ior** [IOR] Pass remote forwarder's IOR. By default, the local forwarder will retrive its peer IOR. **--net-config** [path/to/configuration/file] Path to configuration file. **-C** Create the tunnel from this forwarder. CONFIGURATION FILE ================== You can pass a configuration file to dietForwarder instead of using command line options through the --net-config option. Configuration file lists several rules describing networks reachable using this forwarder. There's two category of rules: **accept rules** describe which networks are accessible through the forwarder. **reject rules** describe which networks are not accessible through the forwarder. A rule always starts by either **accept:** or **reject:** immediately followed by a regular expression (Posix) describing host concerned by the rule. Rules are evaluated in the following order: **accept** then **reject**. For instance: accept:.* reject:localhost This fragment means that the forwarder will accept connections to every hosts but localhost. EXAMPLE ======= Here's a simple configuration: * We have two domains: *net1* and *net2*, forwarders will be launched on hosts *fwd.net1* and *fwd.net2*. * There's no link between hosts *fwd.net1* and *fwd.net2* but user may access *fwd.net2* from *fwd.net1* using a ssh connection. * We'll name *fwd.net1* forwarder Fwd1 and *fwd.net2* fowarder Fwd2. * One tool lives in *fwd.net2* while a component lives on the *net1* domain. **Command line for launchind Fwd1** :: fwd.net1$ logForwarder --name Fwd1 --peer-name Fwd2 \ --ssh-host fwd.net2 --ssh-login dietUser \ --ssh-key id rsa net2 --remote-port 50000 \ --net-config net1.cfg -C **Command line to launch Fwd2** :: fwd.net2$ logForwarder --name Fwd2 --net-config net2.cfg **Configuration file for Fwd1** In this example, the forwarders Fwd1 accepts only the connections to fwd.net2. :: accept:fwd.net2 **Configuration file for Fwd2** In this example, the forwarders Fwd2 accepts all the connections except those which are for the localhost. :: accept:.* reject:localhost RATIONALE ========= The log service uses CORBA as its communication layer. While it's a flexible and robust middleware, it remains hard deploying the log on heterogeneous networks that are not reachable except through ssh tunnels. Log forwarders help administrator configuring their grid without manually set-up ssh tunnels which arguably is neither simple nor scalable. Log forwarders make it very easy configuring such topologies. LICENSE AND COPYRIGHT ===================== Copyright --------- (C)2011, GRAAL, INRIA Rhone-Alpes, 46 allee d'Italie, 69364 Lyon cedex 07, France all right reserved License ------- This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . AUTHORS ======= GRAAL INRIA Rhone-Alpes 46 allee d'Italie 69364 Lyon cedex 07, FRANCE Email: WWW: http://graal.ens-lyon.fr/DIET SEE ALSO ======== omniNames(1), dietForwarder(1), LogCentral(1) BUGS ==== On some systems, forwarder rules won't work unless you use IP addresses instead of hostnames LogService-2.7.0/docs/man/testComponent.1000644 000765 000765 00000006115 11576373446 021650 0ustar00bdepardobdepardo000000 000000 .\" Man page generated from reStructeredText. . .TH TESTCOMPONENT 1 "2011-05-16" "0.1" "" .SH NAME testComponent \- Example of a component for DIET using the LogCentral . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH NAME .sp testComponent \- Example of a component that connects to the LogCentral and publish some messages. It is used as an example for the DIET program. .SH SYNOPSYS .INDENT 0.0 .INDENT 3.5 .sp testComponent .UNINDENT .UNINDENT .SH DESCRIPTION .sp testComponent connects to the LogCentral, publishes some messages and then disconnects. .sp Before starting the LogCentral, you must: .INDENT 0.0 .IP \(bu 2 . launch a CORBA Naming Service. .IP \(bu 2 . launch log forwarders \fIif needed\fP .IP \(bu 2 . launch LogCentral service .IP \(bu 2 . launch a tool to visualize the message sent .IP \(bu 2 . Launch the testComponent .UNINDENT .SH OPTIONS .SH EXAMPLE .INDENT 0.0 .IP \(bu 2 . Launching the LogCentral .UNINDENT .sp .nf .ft C LogCentral \-config ./LogCentral.cfg .ft P .fi .INDENT 0.0 .IP \(bu 2 . Launching the component .UNINDENT .sp .nf .ft C testComponent .ft P .fi .SH RATIONALE .sp The testComponent uses CORBA as its communication layer. While it\(aqs a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. .SH LICENSE AND COPYRIGHT .SS Copyright .sp (C)2011, GRAAL, INRIA Rhone\-Alpes, 46 allee d\(aqItalie, 69364 Lyon cedex 07, France all right reserved <\fI\%diet\-dev@ens\-lyon.fr\fP> .SS License .sp This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub\- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <\fI\%http://www.gnu.org/licenses/\fP>. .SH AUTHORS .sp GRAAL INRIA Rhone\-Alpes 46 allee d\(aqItalie 69364 Lyon cedex 07, FRANCE Email: <\fI\%diet\-dev@ens\-lyon.fr\fP> WWW: \fI\%http://graal.ens\-lyon.fr/DIET\fP .SH SEE ALSO .sp omniNames(1), logForwarder(1), LogCentral(1), DIETTestTool(1) .SH BUGS .SH AUTHOR haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com License: GPLv3 .SH COPYRIGHT DIET developers .\" Generated by docutils manpage writer. .\" . LogService-2.7.0/docs/man/testComponent.rst000644 000765 000765 00000004456 11576373446 022326 0ustar00bdepardobdepardo000000 000000 ============= testComponent ============= ---------------------------------------------------- Example of a component for DIET using the LogCentral ---------------------------------------------------- :Authors: haikel.guemar@sysfera.com, kevin.coulomb@sysfera.com :Date: 2011-05-16 :Copyright: DIET developers :License: GPLv3 :Version: 0.1 :Manual section: 1 NAME ==== testComponent - Example of a component that connects to the LogCentral and publish some messages. It is used as an example for the DIET program. SYNOPSYS ======== testComponent DESCRIPTION =========== testComponent connects to the LogCentral, publishes some messages and then disconnects. Before starting the LogCentral, you must: * launch a CORBA Naming Service. * launch log forwarders *if needed* * launch LogCentral service * launch a tool to visualize the message sent * Launch the testComponent OPTIONS ======= EXAMPLE ======= * Launching the LogCentral :: LogCentral -config ./LogCentral.cfg * Launching the component :: testComponent RATIONALE ========= The testComponent uses CORBA as its communication layer. While it's a flexible and robust middleware, its deployement on heterogeneous networks still is delicate and may require using ssh tunnels. LICENSE AND COPYRIGHT ===================== Copyright --------- (C)2011, GRAAL, INRIA Rhone-Alpes, 46 allee d'Italie, 69364 Lyon cedex 07, France all right reserved License ------- This program is free software: you can redistribute it and/or mod†ify it under the terms of the GNU General Public License as pub†lished by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Pub- lic Li†cense for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . AUTHORS ======= GRAAL INRIA Rhone-Alpes 46 allee d'Italie 69364 Lyon cedex 07, FRANCE Email: WWW: http://graal.ens-lyon.fr/DIET SEE ALSO ======== omniNames(1), logForwarder(1), LogCentral(1), DIETTestTool(1) BUGS ==== LogService-2.7.0/Cmake/ARConfig.cmake000644 000765 000765 00000000172 11576373445 020667 0ustar00bdepardobdepardo000000 000000 ### # # Set the params for the CMAKE_AR used to create the static library # set (AR_ARGS -ruv) mark_as_advanced (AR_ARGS)LogService-2.7.0/Cmake/FindOmniORB.cmake000644 000765 000765 00000024642 11576373445 021315 0ustar00bdepardobdepardo000000 000000 # # Find the omniORB libraries and include dir # # The following variables are set: # OMNIORB4_FOUND - When false, don't try to use omniORB # OMNIORB4_INCLUDE_DIR - Directories to include to use omniORB # OMNIORB4_LIBRARIES_sh - Files to link against to use omniORB (shared libraries) # OMNIORB4_LIBRARIES_st - Files to link against to use omniORB (static libraries) # OMNIORB4_IDL_COMPILER - The idl compiler command (when found) # OMNIORB4_VERSION - A string of the form X.Y.Z representing the version # OMNIORB4_OMNINAMES_COMMAND - the omniNames ORB server command (when found) # OMNIORB4_DIR - (optional) Suggested installation directory to search # # # OMNIORB4_DIR can be used to make it simpler to find the various include # directories and compiled libraries when omniORB was not installed in the # usual/well-known directories (e.g. because you made an in tree-source # compilation or because you installed it in an "unusual" directory). # Just set OMNIORB4_DIR to point to your specific installation directory. # # $ENV{OMNIORB4_DIR} i.e. the environment variable (as opposed to OMNIORB4_DIR # which is the cmake variable with the same name) is also used to search for # an omniORB installation. # # WARNING: The order of precedence is the following # 1/ when set OMNIORB4_DIR (the cmake variable) # 2/ when set $ENV{OMNIORB4_DIR} (the environment variable) # 3/ the default system pathes ! # This precedence order goes against the usual pratice and default behavior # of cmake's FIND_* macros. For more on this debate see e.g. # http://www.mail-archive.com/kde-buildsystem@kde.org/msg00589.html # # #### The list of required libraries for omniORB is not so clear. See # http://www.omniorb-support.com/pipermail/omniorb-list/2005-May/026666.html # The answer should basically be in # - omniORB-4.0.X/README.* # - omniORB-4.0.X/readmes/* # but doesn't seem that obvious to newbies. # The logic we took is here to impose the detection of omniORB4, omnithread, # and omniDynamic4 libraries. Optionaly we search for libraries COS4 and # COSDynamic4 and when present we add them to list of required libraries. # [the logic is here: the installer of omniORB knows better...] # #### The minimum recommanded version of omniORB is 4.1.2 as 4.0.6 has known bugs # in marshalling/unmarshalling floats and doubles using CORBA::Any. SET( OMNIORB4_MINIMUM_VERSION "4.1.2" ) FIND_PATH( OMNIORB4_INCLUDE_DIR omniORB4/CORBA.h PATHS ${OMNIORB4_DIR}/include $ENV{OMNIORB4_DIR}/include NO_DEFAULT_PATH ) FIND_PATH( OMNIORB4_INCLUDE_DIR omniORB4/CORBA.h ) ### Search for static libraries ### FIND_LIBRARY(OMNIORB4_LIBRARY_omniORB4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omniORB4${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY(OMNIORB4_LIBRARY_omniORB4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omniORB4${CMAKE_STATIC_LIBRARY_SUFFIX} ) FIND_LIBRARY( OMNIORB4_LIBRARY_omnithread_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omnithread${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_omnithread_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omnithread${CMAKE_STATIC_LIBRARY_SUFFIX} ) FIND_LIBRARY( OMNIORB4_LIBRARY_omniDynamic4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omniDynamic4${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_omniDynamic4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}omniDynamic4${CMAKE_STATIC_LIBRARY_SUFFIX} ) ### Optional library FIND_LIBRARY( OMNIORB4_LIBRARY_COS4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}COS4${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_COS4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}COS4${CMAKE_STATIC_LIBRARY_SUFFIX} ) ### Additional optional library FIND_LIBRARY( OMNIORB4_LIBRARY_COSDynamic4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}COSDynamic4${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_COSDynamic4_st NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}COSDynamic4${CMAKE_STATIC_LIBRARY_SUFFIX} ) ### Search for shared libraries ### FIND_LIBRARY(OMNIORB4_LIBRARY_omniORB4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omniORB4${CMAKE_SHARED_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY(OMNIORB4_LIBRARY_omniORB4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omniORB4${CMAKE_SHARED_LIBRARY_SUFFIX} ) FIND_LIBRARY( OMNIORB4_LIBRARY_omnithread_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omnithread${CMAKE_SHARED_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_omnithread_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omnithread${CMAKE_SHARED_LIBRARY_SUFFIX} ) FIND_LIBRARY( OMNIORB4_LIBRARY_omniDynamic4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omniDynamic4${CMAKE_SHARED_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_omniDynamic4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}omniDynamic4${CMAKE_SHARED_LIBRARY_SUFFIX} ) ### Optional library FIND_LIBRARY( OMNIORB4_LIBRARY_COS4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}COS4${CMAKE_SHARED_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_COS4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}COS4${CMAKE_SHARED_LIBRARY_SUFFIX} ) ### Additional optional library FIND_LIBRARY( OMNIORB4_LIBRARY_COSDynamic4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}COSDynamic4${CMAKE_SHARED_LIBRARY_SUFFIX} PATHS ${OMNIORB4_DIR}/lib $ENV{OMNIORB4_DIR}/lib NO_DEFAULT_PATH ) FIND_LIBRARY( OMNIORB4_LIBRARY_COSDynamic4_sh NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}COSDynamic4${CMAKE_SHARED_LIBRARY_SUFFIX} ) ### Search for omniORB applications ### FIND_PROGRAM( OMNIORB4_IDL_COMPILER NAMES omniidl PATHS ${OMNIORB4_DIR}/bin $ENV{OMNIORB4_DIR}/bin DOC "What is the path where omniidl (the idl compiler) can be found" NO_DEFAULT_PATH ) FIND_PROGRAM( OMNIORB4_IDL_COMPILER NAMES omniidl DOC "What is the path where omniidl (the idl compiler) can be found" ) FIND_PROGRAM( OMNIORB4_OMNINAMES_COMMAND NAMES omniNames PATHS ${OMNIORB4_DIR}/bin $ENV{OMNIORB4_DIR}/bin DOC "What is the path where omniNames (the ORB server) can be found" NO_DEFAULT_PATH ) FIND_PROGRAM( OMNIORB4_OMNINAMES_COMMAND NAMES omniNames DOC "What is the path where omniNames (the ORB server) can be found" ) SET( OMNIORB4_FOUND "NO" ) IF( OMNIORB4_INCLUDE_DIR ) IF( OMNIORB4_LIBRARY_omniORB4_sh ) IF( OMNIORB4_LIBRARY_omnithread_sh ) IF( OMNIORB4_LIBRARY_omniDynamic4_sh ) IF( OMNIORB4_IDL_COMPILER ) SET( OMNIORB4_FOUND "YES" ) MARK_AS_ADVANCED( OMNIORB4_DIR ) MARK_AS_ADVANCED( OMNIORB4_INCLUDE_DIR ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omniORB4_st ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omnithread_st ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omniDynamic4_st ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omniORB4_sh ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omnithread_sh ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_omniDynamic4_sh ) MARK_AS_ADVANCED( OMNIORB4_IDL_COMPILER ) MARK_AS_ADVANCED( OMNIORB4_OMNINAMES_COMMAND ) # Note: when linking in static with g++ it looks like omniDynamic4 needs # to appear prior to omniORB4 in order to avoid some undefined references # to e.g. CORBA::Fixed::Fixed(int). SET( OMNIORB4_LIBRARIES_sh ${OMNIORB4_LIBRARY_omniDynamic4_sh} ${OMNIORB4_LIBRARY_omniORB4_sh} ${OMNIORB4_LIBRARY_omnithread_sh} ) SET( OMNIORB4_LIBRARIES_st ${OMNIORB4_LIBRARY_omniDynamic4_st} ${OMNIORB4_LIBRARY_omniORB4_st} ${OMNIORB4_LIBRARY_omnithread_st} ) # We do not require the existence of the libraries COS4 and COSDynamic4 # since they exist in some distribution packages (e.g. Fedora Core) and # not in others (e.g. Debian). When present we add them to the list of # libraries we link against. When absent we hide away (in the advanced # parameters) the NOT-FOUND associated variable in order not to deconcert # the newbie: IF( OMNIORB4_LIBRARY_COS4_sh ) SET( OMNIORB4_LIBRARIES_sh ${OMNIORB4_LIBRARIES_sh} ${OMNIORB4_LIBRARY_COS4_sh} ) ENDIF( OMNIORB4_LIBRARY_COS4_sh ) IF( OMNIORB4_LIBRARY_COS4_st ) SET( OMNIORB4_LIBRARIES_st ${OMNIORB4_LIBRARIES_st} ${OMNIORB4_LIBRARY_COS4_st} ) ENDIF( OMNIORB4_LIBRARY_COS4_st ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_COS4_sh ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_COS4_st ) IF( OMNIORB4_LIBRARY_COSDynamic4_sh ) SET( OMNIORB4_LIBRARIES_sh ${OMNIORB4_LIBRARIES_sh} ${OMNIORB4_LIBRARY_COSDynamic4_sh} ) ENDIF( OMNIORB4_LIBRARY_COSDynamic4_sh ) IF( OMNIORB4_LIBRARY_COSDynamic4_st ) SET( OMNIORB4_LIBRARIES_st ${OMNIORB4_LIBRARIES_st} ${OMNIORB4_LIBRARY_COSDynamic4_st} ) ENDIF( OMNIORB4_LIBRARY_COSDynamic4_st ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_COSDynamic4_sh ) MARK_AS_ADVANCED( OMNIORB4_LIBRARY_COSDynamic4_st ) # Optionaly, extract the the version number from the acconfig.h file: IF( EXISTS ${OMNIORB4_INCLUDE_DIR}/omniORB4/acconfig.h ) FILE( READ ${OMNIORB4_INCLUDE_DIR}/omniORB4/acconfig.h OMNIORB_ACCONFIG_H ) STRING( REGEX MATCH "#define[\t ]+PACKAGE_VERSION[\t ]+\"([0-9]+.[0-9]+.[0-9]+)\"" OMNIORB_ACCONFIG_H "${OMNIORB_ACCONFIG_H}" ) STRING( REGEX REPLACE ".*\"([0-9]+.[0-9]+.[0-9]+)\".*" "\\1" OMNIORB4_VERSION "${OMNIORB_ACCONFIG_H}" ) # TODO: when really switching to CMake 2.6, we should use VERSION_LESS instead of LESS IF( "${OMNIORB4_VERSION}" LESS "${OMNIORB4_MINIMUM_VERSION}" ) MESSAGE( "WARNING: your version of omniORB is older than the minimum required one (${OMNIORB4_MINIMUM_VERSION}), using DIET with this version may result in undetermined behaviors." ) ENDIF( "${OMNIORB4_VERSION}" LESS "${OMNIORB4_MINIMUM_VERSION}" ) ELSE( EXISTS ${OMNIORB4_INCLUDE_DIR}/omniORB4/acconfig.h ) SET( OMNIORB4_VERSION "NOT-FOUND" ) ENDIF( EXISTS ${OMNIORB4_INCLUDE_DIR}/omniORB4/acconfig.h ) SET( OMNIORB4_VERSION ${OMNIORB4_VERSION} CACHE STRING "OmniORB version number." ) MARK_AS_ADVANCED( OMNIORB4_VERSION ) ENDIF( OMNIORB4_IDL_COMPILER ) ENDIF( OMNIORB4_LIBRARY_omniDynamic4_sh ) ENDIF( OMNIORB4_LIBRARY_omnithread_sh ) ENDIF( OMNIORB4_LIBRARY_omniORB4_sh ) ENDIF( OMNIORB4_INCLUDE_DIR ) LogService-2.7.0/Cmake/README000644 000765 000765 00000000645 11576373445 017122 0ustar00bdepardobdepardo000000 000000 Notes: - A dependency expresses towards LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES (e.g. as encountered in src/utils/CMakeLists.txt for LogServiceUtils) indicates that before compiling the considered target one first needs to generate the header files with idl. Refer to the definition of the commidity target LOGSERVICE_TARGET_IDL_GENERATED_HEADER_FILES (see src/idl/CMakeLists.txt) for more details.